Пример #1
0
// ArchiveView shows a list of posts arranged by its date
func ArchiveView(c *echo.Context) error {
	id := c.Param("id")
	var err error

	// Get archive data
	var archive models.Archive
	err = database.Current.Get(&archive, database.Queries.ArchiveBySignature, id)
	if err != nil {
		log.Println("Cannot get archive by signature", err)
		return echo.NewHTTPError(http.StatusInternalServerError)
	}

	// Get related posts
	var posts []models.AuthoredPost
	err = database.Current.Select(&posts, database.Queries.ArchiveAuthoredPosts, id)
	if err != nil {
		log.Println("Cannot select posts", err)
		return echo.NewHTTPError(http.StatusInternalServerError)
	}

	// Create our render context and fill base data
	ac := archiveContext{
		Archive:      archive,
		RelatedPosts: posts,
	}

	err = fillBlogContext(c, &ac.blogContext)
	if err != nil {
		log.Println("Cannot fill blog context", err)
		return echo.NewHTTPError(http.StatusInternalServerError)
	}

	return c.Render(200, "archive", ac)
}
Пример #2
0
// putPlace изменяет определение уже существующего места.
func putPlace(c *echo.Context) error {
	groupID := c.Get("GroupID").(string)
	placeID := c.Query("place-id")
	if !bson.IsObjectIdHex(placeID) {
		return echo.NewHTTPError(http.StatusNotFound)
	}
	var place places.Place // описание места
	err := c.Bind(&place)  // разбираем описание места из запроса
	if err != nil {
		return echo.NewHTTPError(http.StatusBadRequest, err.Error())
	}
	if place.Circle == nil && place.Polygon == nil {
		return echo.NewHTTPError(http.StatusBadRequest)
	}
	place.ID = bson.ObjectIdHex(placeID)
	place.GroupID = groupID
	_, err = placesDB.Save(place)
	if err == mgo.ErrNotFound {
		return echo.NewHTTPError(http.StatusNotFound)
	}
	if err != nil {
		llog.Error("placesDB error: %v", err)
		return err
	}
	return c.NoContent(http.StatusOK)
}
Пример #3
0
// auth является вспомогательной функцией, проверяющей и разбирающей токен с авторизационной
// информацией в HTTP-заголовке. Разобранная информация сохраняется в контексте запроса.
func auth(h echo.HandlerFunc) echo.HandlerFunc {
	return func(c *echo.Context) error {
		req := c.Request()                                  // получаем доступ к HTTP-запросу
		if req.Header.Get(echo.Upgrade) == echo.WebSocket { // пропускаем запросы WebSocket
			return nil
		}
		data, err := tokenEngine.ParseRequest(req) // разбираем токен из запроса
		if err != nil {
			llog.Warn("Bad token: %v", err)
			return echo.NewHTTPError(http.StatusForbidden)
		}
		groupID := data["group"].(string)
		userID := data["id"].(string)
		if !bson.IsObjectIdHex(userID) {
			llog.Warn("Bad user Object ID: %v", userID)
			return echo.NewHTTPError(http.StatusForbidden)
		}
		userObjectId := bson.ObjectIdHex(userID)
		// проверяем, что пользователь есть и входит в эту группу
		exists, err := usersDB.Check(groupID, userObjectId)
		if err != nil {
			llog.Error("usersDB error: %v", err)
			return err
		}
		if !exists {
			llog.Debug("Auth not exist: %v (%v)", userID, groupID)
			return echo.NewHTTPError(http.StatusForbidden)
		}
		c.Set("GroupID", groupID) // сохраняем данные в контексте запроса
		c.Set("ID", userObjectId)
		llog.Debug("Auth: %v (%v)", userID, groupID)
		return h(c) // выполняем основной обработчик
	}
}
Пример #4
0
func postDevicePairing(c *echo.Context) error {
	groupID := c.Get("GroupID").(string)
	deviceID := c.Param("device-id")
	_, _ = groupID, deviceID
	var pairingKey struct {
		Key string
	}
	err := c.Bind(&pairingKey) // читаем ключ из запроса
	if err != nil || len(pairingKey.Key) < 4 {
		return echo.NewHTTPError(http.StatusBadRequest)
	}
	var deviceIDResp string
	err = nce.Request(serviceNamePairingKey, pairingKey.Key, &deviceIDResp, natsRequestTimeout)
	if err != nil {
		llog.Error("NATS Pairing Key response error: %v", err)
		return err
	}
	if deviceIDResp == "" {
		return echo.NewHTTPError(http.StatusNotFound)
	}
	if deviceIDResp == deviceID {
		// TODO: реально связать в базе
		return echo.NewHTTPError(http.StatusOK)
	}
	if deviceID == "" {
		return c.JSON(http.StatusOK, map[string]string{"ID": deviceIDResp})
	}
	return echo.NewHTTPError(http.StatusBadRequest)
}
Пример #5
0
// Authentication middleware using Session Tokens, every request handled is checked
// for the X-Session-Token Header, decodes the session and authenticates the user to
// it's resources in the store. Returns [400] for a bad token, [401] for non valid
// sessions, and proceeds with request otherwise.
func Auth(app *App) echo.HandlerFunc {

	return func(c *echo.Context) error {
		//Check for session token
		header := c.Request().Header.Get("X-Session-Token")

		// If no token [401], should login
		if header == "" {
			return echo.NewHTTPError(http.StatusUnauthorized)
		}

		// Token cannot be decoded or mismatch token length [400]
		// Session Tokens are 32 bytes long (64 hexadecimal characters)
		token, err := hex.DecodeString(header)
		if err != nil || len(token) != 32 {
			return echo.NewHTTPError(http.StatusBadRequest)
		}

		// If Session Token is not found (maybe no longer valid due to logout)
		// client gets [401] should login again
		session := app.System.Get("session", c.Param("user"))
		if session == nil {
			return echo.NewHTTPError(http.StatusUnauthorized)
		}

		// Finally if tokens don't match [401]
		if string(token) != string(session) {
			return echo.NewHTTPError(http.StatusUnauthorized)
		}

		return nil
	}

}
Пример #6
0
// ApiNextTaskHandler implements method for getting next task from the queue
func (h *handler) ApiNextTaskHandler(c *echo.Context) error {

	enc := json.NewDecoder(c.Request().Body)

	var taskReq common.TaskRequest
	if err := enc.Decode(&taskReq); err != nil {
		c.Request().Body.Close()
		return echo.NewHTTPError(http.StatusBadRequest, "Wrong JSON. Expected gobench.common.TaskRequest")
	}

	c.Request().Body.Close()

	// checks existing test environment by authKey received by client
	ok, err := h.back.Model.TestEnvironment.Exist(taskReq.AuthKey)
	if err != nil {
		return echo.NewHTTPError(http.StatusInternalServerError)
	}

	if !ok {
		return echo.NewHTTPError(http.StatusBadRequest, "Wrong authKey!")
	}

	// retrives single task
	taskRow, err := h.back.Model.Task.Next(taskReq.AuthKey)
	if err != nil {
		if err == model.ErrNotFound {
			return echo.NewHTTPError(http.StatusNoContent)
		}
		return echo.NewHTTPError(http.StatusInternalServerError, err.Error())
	}

	task := common.TaskResponse{Id: taskRow.Id.Hex(), PackageName: taskRow.PackageName, Type: []string{"benchmark"}}

	return c.JSON(http.StatusOK, task)
}
Пример #7
0
// CategoryView shows a list of posts arranged by its category
func CategoryView(c *echo.Context) error {
	// Parse pagination attributes
	pn, ps := utils.GetPage(c)
	id, _ := strconv.Atoi(c.Param("id"))

	// Get category using id
	var category models.Category
	err := database.Current.Get(&category, database.Queries.CategoryByID, id)
	if err != nil {
		log.Println("Cannot select category:", err)
		return echo.NewHTTPError(http.StatusInternalServerError)
	}

	// Query the posts
	var posts []models.AuthoredPost
	err = database.Current.Select(&posts, database.Queries.AuthoredPostsByCategory, id, ps, ps*(pn-1))
	if err != nil {
		log.Println("Cannot select posts:", err)
		return echo.NewHTTPError(http.StatusInternalServerError)
	}

	var count int
	err = database.Current.Get(&count, database.Queries.PostByCategoryCount, id)
	if err != nil {
		log.Println("Cannot count posts:", err)
	}

	pc := int(math.Floor(float64(count/ps))) + 1

	// Generate preview for all posts
	for _, p := range posts {
		p.Preview = createPreview(p.TextContent)
	}

	// Create our context and fill base data
	cc := categoryContext{
		Category: category,
		RelatedPosts: models.Paginated{
			TotalObjects:  count,
			PageCount:     pc,
			PageNumber:    pn,
			PageSize:      ps,
			NextAvailable: pn < pc,
			Results:       posts,
		},
	}

	err = fillBlogContext(c, &cc.blogContext)
	if err != nil {
		log.Println("Cannot fill blog context", err)
		return echo.NewHTTPError(http.StatusInternalServerError)
	}

	// Render the results
	return c.Render(200, "category", cc)
}
Пример #8
0
// Error forwards to echo.Error
func (e *echoHandler) Error(c server.Context, code int, d ...interface{}) error {
	switch v := d[0].(type) {
	case error:
		return echo.NewHTTPError(code, v.Error())
	case string:
		return echo.NewHTTPError(code, v)
	default:
		return echo.NewHTTPError(code)
	}
}
Пример #9
0
func (s *FilesService) Upload(params url.Values) *Responder {

	var (
		err error
	)
	body := &bytes.Buffer{}
	writer := multipart.NewWriter(body)
	for k, values := range params {
		switch k {
		default:
			err = writer.WriteField(k, values[0])
			if err != nil {
				return &Responder{
					Error: echo.NewHTTPError(http.StatusBadRequest, err.Error()),
				}
			}
		case "file":
			for _, path := range values {
				file, err := os.Open(path)
				if err != nil {
					return &Responder{
						Error: echo.NewHTTPError(http.StatusBadRequest, err.Error()),
					}
				}
				defer file.Close()
				part, err := writer.CreateFormFile("file", filepath.Base(path))
				if err != nil {
					return &Responder{
						Error: echo.NewHTTPError(http.StatusBadRequest, err.Error()),
					}
				}
				_, err = io.Copy(part, file)
				if err != nil {
					return &Responder{
						Error: echo.NewHTTPError(http.StatusBadRequest, err.Error()),
					}
				}
			}
		}
	}
	defer writer.Close()
	return &Responder{
		Body: body,
		Headers: map[string]string{
			"Content-Type": writer.FormDataContentType(),
		},
		Method:  "MULTIPART",
		Params:  params,
		Rpc:     "upload",
		Service: s,
	}
}
Пример #10
0
func HMACAuth(o *HmacOpts) echo.HandlerFunc {
	return func(c *echo.Context) error {
		auth, err := newAuth(c.Request(), o)
		if nil != err {
			return echo.NewHTTPError(http.StatusUnauthorized, err.Error())
		}
		if err := auth.Authentic(c.Request()); nil != err {
			return echo.NewHTTPError(http.StatusUnauthorized, err.Error())
		}
		c.Set(API_KEY, auth.ApiKey)
		return nil
	}
}
Пример #11
0
// Login route (/login), credentials are given as Basic Authentication, so be sure to do it over SSL or private networking.
// If authentication is successful, it returns [200] and a 32 byte X-Session-Token in a hex encoded string.
// All authenticated requests should include the X-Session-Token header with this value, if the token is no longer
// valid due to logout or expiration, a [401] usually means you have to call this login endpoint again and obtain a new token.
func (app *App) Login(c *echo.Context) error {
	//Check for Basic Authentication Header
	user, pass, ok := c.Request().BasicAuth()
	if !ok {
		return echo.NewHTTPError(http.StatusBadRequest)
	}
	// If credentials don't match
	if !app.Authenticate(user, pass) {
		return echo.NewHTTPError(http.StatusUnauthorized)
	}
	// Return either a new Session Token or an existing one
	return c.String(http.StatusOK, app.NewSession(user))
}
Пример #12
0
func (s *yovpnServer) deleteEndpoint(c *echo.Context) error {
	id := c.Param("id")
	if len(id) == 0 {
		return echo.NewHTTPError(http.StatusBadRequest, "ID not provided!")
	}

	_, err := s.provisioner.DestroyEndpoint(id)
	if err != nil {
		return echo.NewHTTPError(http.StatusNotFound, "Endpoint not found!")
	}

	c.NoContent(http.StatusNoContent)
	return nil
}
Пример #13
0
func (s *yovpnServer) getEndpoint(c *echo.Context) error {
	id := c.Param("id")
	if len(id) == 0 {
		return echo.NewHTTPError(http.StatusBadRequest, "ID not provided!")
	}

	endpoint, err := s.provisioner.GetEndpoint(id)
	if err != nil {
		return echo.NewHTTPError(http.StatusNotFound, "Endpoint not found!")
	}

	c.JSON(http.StatusOK, endpoint)
	return nil
}
Пример #14
0
// ProfileView renders the profile data with the fancy portfolio template
func ProfileView(c *echo.Context) error {
	id := c.Param("id") // ID in this case applies to username
	var err error

	var profile models.Profile
	err = database.Current.Get(&profile, database.Queries.ProfileByUsername, id)
	if err != nil {
		log.Println("Cannot get profile:", err)
		return echo.NewHTTPError(http.StatusInternalServerError)
	}

	var skills []models.ResumeSkill
	err = database.Current.Select(&skills, database.Queries.ResumeSkillsByProfileID, profile.ID)
	if err != nil {
		log.Println("Cannot get skills:", err)
		return echo.NewHTTPError(http.StatusInternalServerError)
	}

	var jobs []models.ResumeJob
	err = database.Current.Select(&jobs, database.Queries.ResumeJobsByProfileID, profile.ID)
	if err != nil {
		log.Println("Cannot select jobs:", err)
		return echo.NewHTTPError(http.StatusInternalServerError)
	}

	var education []models.ResumeEducation
	err = database.Current.Select(&education, database.Queries.ResumeEducationByProfileID, profile.ID)
	if err != nil {
		log.Println("Cannot select education:", err)
		return echo.NewHTTPError(http.StatusInternalServerError)
	}

	var projects []models.ResumeProject
	err = database.Current.Select(&projects, database.Queries.ResumeProjectsByProfileID, profile.ID)
	if err != nil {
		log.Println("Cannot select projects:", err)
		return echo.NewHTTPError(http.StatusInternalServerError)
	}

	pc := profileContext{
		Profile:   profile,
		Skills:    skills,
		Jobs:      jobs,
		Education: education,
		Projects:  projects,
	}

	return c.Render(200, "profile", pc)
}
Пример #15
0
// Index serves blog index view
func Index(c *echo.Context) error {

	// Parse pagination attributes
	pn, ps := utils.GetPage(c)

	// Query the posts
	var posts []models.AuthoredPost
	err := database.Current.Select(&posts, database.Queries.AuthoredPosts, ps, ps*(pn-1))
	if err != nil {
		log.Println("Cannot select posts:", err)
		return echo.NewHTTPError(http.StatusInternalServerError)
	}

	var count int
	err = database.Current.Get(&count, database.Queries.PostCount)
	if err != nil {
		log.Println("Cannot count posts:", err)
		return echo.NewHTTPError(http.StatusInternalServerError)
	}

	pc := int(math.Floor(float64(count/ps))) + 1

	// Generate preview for all posts
	for _, p := range posts {
		p.Preview = createPreview(p.TextContent)
	}

	// Create our render context and fill base data
	ic := indexContext{
		PostResults: models.Paginated{
			TotalObjects:  count,
			PageCount:     pc,
			PageNumber:    pn,
			PageSize:      ps,
			NextAvailable: pn < pc,
			Results:       posts,
		},
	}

	err = fillBlogContext(c, &ic.blogContext)
	if err != nil {
		log.Println("Cannot fill blog context", err)
		return echo.NewHTTPError(http.StatusInternalServerError)
	}

	// Render the results
	return c.Render(200, "index", ic)
}
Пример #16
0
// JobsNewPost process the new job form.
//
//		Method           POST
//
//		Route            /dash/jobs/new
//
//		Restrictions     Yes
//
// 		Template         None
func JobsNewPost(ctx *echo.Context) error {
	var flashMessages = flash.New()
	f := forms.New(utils.GetLang(ctx))
	jf := f.JobForm()(ctx.Request())
	if !jf.IsValid() {
		// TODO: improve flash message ?
		flashMessages.Err(msgInvalidorm)
		flashMessages.Save(ctx)
		ctx.Redirect(http.StatusFound, "/dash/jobs/new")
		return nil
	}

	if isLoged := ctx.Get("IsLoged"); isLoged != nil {
		person := ctx.Get("User").(*models.Person)
		if jerr := query.PersonCreateJob(person, jf.GetModel().(forms.JobForm)); jerr != nil {
			// TODO: improve flash message ?
			flashMessages.Err("some really bad fish happened")
			flashMessages.Save(ctx)
			ctx.Redirect(http.StatusFound, "/dash/jobs/new")
			return nil
		}
		// add flash message
		flashMessages.Success("new job was created successful")
		flashMessages.Save(ctx)

		ctx.Redirect(http.StatusFound, "/dash/")
		return nil
	}
	he := echo.NewHTTPError(http.StatusUnauthorized)
	ctx.Error(he)
	return nil
}
Пример #17
0
func BasicAuth() echo.HandlerFunc {
	return func(c *echo.Context) error {
		// Skip WebSocket
		if (c.Request().Header.Get(echo.Upgrade)) == echo.WebSocket {
			return nil
		}

		auth := c.Request().Header.Get(echo.Authorization)
		l := len(Basic)

		if len(auth) > l+1 && auth[:l] == Basic {
			b, err := base64.StdEncoding.DecodeString(auth[l+1:])
			if err == nil {
				cred := string(b)
				for i := 0; i < len(cred); i++ {
					if cred[i] == ':' {
						// Verify credentials
						for _, d := range conf.Domains {
							if cred[:i] == d.Name && bcrypt.CompareHashAndPassword([]byte(d.PassHash), []byte(cred[i+1:])) == nil {
								c.Set("domain", d)
								return nil
							}
						}
					}
				}
			}
		}
		c.Response().Header().Set(echo.WWWAuthenticate, Basic+" realm=Restricted")
		return echo.NewHTTPError(http.StatusUnauthorized)
	}
}
Пример #18
0
// JWTAuth returns a JWT authentication middleware.
//
// For valid token it sets JWT claims in the context with key `_claims` and calls
// the next handler.
// For invalid Authorization header it sends "404 - Bad Request" response.
// For invalid credentials, it sends "401 - Unauthorized" response.
func JWTAuth(fn JWTValidateFunc) echo.HandlerFunc {
	return func(c *echo.Context) error {
		// Skip WebSocket
		if (c.Request().Header.Get(echo.Upgrade)) == echo.WebSocket {
			return nil
		}

		auth := c.Request().Header.Get("Authorization")
		l := len(Bearer)
		he := echo.NewHTTPError(http.StatusBadRequest)

		if len(auth) > l+1 && auth[:l] == Bearer {
			t, err := jwt.Parse(auth[l+1:], func(token *jwt.Token) (interface{}, error) {
				// Lookup key and verify method
				if kid := token.Header["kid"]; kid != nil {
					return fn(kid.(string), token.Method)
				}
				return fn("", token.Method)
			})
			if err == nil && t.Valid {
				c.Set("_claims", t.Claims)
				return nil
			} else {
				he.SetCode(http.StatusUnauthorized)
			}
		}
		return he
	}
}
Пример #19
0
func JWTAuth(key string) echo.HandlerFunc {
	return func(c *echo.Context) error {

		// Skip WebSocket
		if (c.Request().Header.Get(echo.Upgrade)) == echo.WebSocket {
			return nil
		}

		auth := c.Request().Header.Get("Authorization")
		l := len(Bearer)
		halt := echo.NewHTTPError(http.StatusUnauthorized)

		if len(auth) > l+1 && auth[:l] == Bearer {
			t, err := jwt.Parse(auth[l+1:], func(token *jwt.Token) (interface{}, error) {

				// Always check the signing method
				if _, ok := token.Method.(*jwt.SigningMethodHMAC); !ok {
					return nil, fmt.Errorf("Unexpected signing method: %v", token.Header["alg"])
				}

				// Return the key for validation
				return []byte(key), nil
			})
			if err == nil && t.Valid {
				// Store token claims in echo.Context
				c.Set("claims", t.Claims)
				return nil
			}
		}
		return halt
	}
}
Пример #20
0
// deletePlace удаляет определение места.
func deletePlace(c *echo.Context) error {
	groupID := c.Get("GroupID").(string)
	placeID := c.Query("place-id")
	if !bson.IsObjectIdHex(placeID) {
		return echo.NewHTTPError(http.StatusNotFound)
	}
	err := placesDB.Delete(groupID, bson.ObjectIdHex(placeID))
	if err == mgo.ErrNotFound {
		return echo.NewHTTPError(http.StatusNotFound)
	}
	if err != nil {
		llog.Error("placesDB error: %v", err)
		return err
	}
	return c.NoContent(http.StatusOK)
}
Пример #21
0
func JWTAuth(key string) echo.HandlerFunc {
	return func(c *echo.Context) error {

		// If this is a WS upgrade request, skip Auth
		if (c.Request().Header.Get(echo.Upgrade)) == echo.WebSocket {
			return nil
		}

		auth := c.Request().Header.Get("Authorization")
		l := len(Bearer)

		unauthorized := echo.NewHTTPError(http.StatusUnauthorized)

		if len(auth) > l+1 && auth[:l] == Bearer {
			t, err := jwt.Parse(auth[l+1:], func(token *jwt.Token) (interface{}, error) {

				// Check the signing method
				// https://auth0.com/blog/2015/03/31/critical-vulnerabilities-in-json-web-token-libraries/
				if _, ok := token.Method.(*jwt.SigningMethodHMAC); !ok {
					return nil, fmt.Errorf("Unexpected signing method: %v", token.Header["alg"])
				}

				return []byte(key), nil
			})
			if err == nil && t.Valid {
				// Store claims in echo.Context
				c.Set("claims", t.Claims)
				return nil
			}
		}

		return unauthorized
	}
}
Пример #22
0
// BasicAuth returns an HTTP basic authentication middleware.
//
// For valid credentials it calls the next handler.
// For invalid Authorization header it sends "404 - Bad Request" response.
// For invalid credentials, it sends "401 - Unauthorized" response.
func BasicAuth(fn BasicValidateFunc) echo.HandlerFunc {
	return func(c *echo.Context) error {
		// Skip WebSocket
		if (c.Request().Header.Get(echo.Upgrade)) == echo.WebSocket {
			return nil
		}

		auth := c.Request().Header.Get(echo.Authorization)
		l := len(Basic)
		he := echo.NewHTTPError(http.StatusBadRequest)

		if len(auth) > l+1 && auth[:l] == Basic {
			b, err := base64.StdEncoding.DecodeString(auth[l+1:])
			if err == nil {
				cred := string(b)
				for i := 0; i < len(cred); i++ {
					if cred[i] == ':' {
						// Verify credentials
						if fn(cred[:i], cred[i+1:]) {
							return nil
						}
						he.SetCode(http.StatusUnauthorized)
					}
				}
			}
		}
		return he
	}
}
Пример #23
0
// Must ensures that any route is authorized to access the next handler
// otherwise an error is returned.
//
// TODO custom not authorized handler?
func Must() echo.HandlerFunc {
	return func(ctx *echo.Context) error {
		// If this is called somewhere on the middleware chain, if we find the user
		// we check the context if is set.
		if v := ctx.Get("IsLoged"); v != nil && v.(bool) == true {
			return nil
		}
		ss, err := store.Get(ctx.Request(), settings.App.Session.Name)
		if err != nil {
			// TODO: log this?
		}
		if v, ok := ss.Values["userID"]; ok {
			person, err := query.GetPersonByUserID(v.(int))
			if err != nil {
				// TODO: log this?
			}
			if person != nil {

				// set in main context
				ctx.Set("IsLoged", true)
				ctx.Set("User", person)

				// for templates
				utils.SetData(ctx, "IsLoged", true)
				utils.SetData(ctx, "User", person)
				return nil
			}
		}
		return echo.NewHTTPError(http.StatusUnauthorized)
	}
}
Пример #24
0
func main() {

	demoData := Data{
		Id:   5,
		Name: "User name",
		Tags: []string{"people", "customer", "developer"},
	}

	e := echo.New()
	e.SetDebug(true)
	e.Use(middleware.Logger())
	e.Use(middleware.Recover())

	s := stats.New()
	e.Use(standard.WrapMiddleware(s.Handler))

	e.GET("/xml", func(c echo.Context) error {
		return c.XML(200, demoData)
	})

	e.GET("/json", func(c echo.Context) error {
		return c.JSON(200, demoData)
	})

	e.GET("/error", func(c echo.Context) error {
		return echo.NewHTTPError(500, "Error here")
	})

	e.Run(standard.New(":8888"))

}
Пример #25
0
// Logout route (/logout), destroys the X-Session-Token for a given user making it no longer valid.
// To logout the route expects the user credentials as Basic Authentication header to destroy the session.
// All subsecuent requests using the previous X-Session-Token will receive [401] and needs to login again.
func (app *App) Logout(c *echo.Context) error {
	//Check for Basic Authentication Header
	user, pass, ok := c.Request().BasicAuth()
	if !ok {
		return echo.NewHTTPError(http.StatusBadRequest)
	}
	// If credentials don't match
	if !app.Authenticate(user, pass) {
		return echo.NewHTTPError(http.StatusUnauthorized)
	}
	// Destroy session
	err := app.DestroySession(user)
	if err != nil {
		return echo.NewHTTPError(http.StatusInternalServerError)
	}
	return c.String(http.StatusOK, "")
}
Пример #26
0
// JWTFromHeader is a `JWTExtractor` that extracts token from the `Authorization` request
// header.
func JWTFromHeader(c echo.Context) (string, error) {
	auth := c.Request().Header().Get(echo.HeaderAuthorization)
	l := len(bearer)
	if len(auth) > l+1 && auth[:l] == bearer {
		return auth[l+1:], nil
	}
	return "", echo.NewHTTPError(http.StatusBadRequest, "empty or invalid authorization header="+auth)
}
Пример #27
0
func getPlatformName(c *echo.Context) (string, error) {

	if value, ok := c.Get("platformName").(string); ok {
		return value, nil
	} else {
		return "", echo.NewHTTPError(http.StatusExpectationFailed, "Unable to identify platform.")
	}
}
Пример #28
0
// JWTWithConfig returns a JWT auth middleware with config.
// See: `JWT()`.
func JWTWithConfig(config JWTConfig) echo.MiddlewareFunc {
	// Defaults
	if config.Skipper == nil {
		config.Skipper = DefaultJWTConfig.Skipper
	}
	if config.SigningKey == nil {
		panic("jwt middleware requires signing key")
	}
	if config.SigningMethod == "" {
		config.SigningMethod = DefaultJWTConfig.SigningMethod
	}
	if config.ContextKey == "" {
		config.ContextKey = DefaultJWTConfig.ContextKey
	}
	if config.Claims == nil {
		config.Claims = jwt.MapClaims{}
	}
	if config.TokenLookup == "" {
		config.TokenLookup = DefaultJWTConfig.TokenLookup
	}

	// Initialize
	parts := strings.Split(config.TokenLookup, ":")
	extractor := jwtFromHeader(parts[1])
	switch parts[0] {
	case "query":
		extractor = jwtFromQuery(parts[1])
	case "cookie":
		extractor = jwtFromCookie(parts[1])
	}

	return func(next echo.HandlerFunc) echo.HandlerFunc {
		return func(c echo.Context) error {
			if config.Skipper(c) {
				return next(c)
			}

			auth, err := extractor(c)
			if err != nil {
				return echo.NewHTTPError(http.StatusBadRequest, err.Error())
			}
			token, err := jwt.ParseWithClaims(auth, config.Claims, func(t *jwt.Token) (interface{}, error) {
				// Check the signing method
				if t.Method.Alg() != config.SigningMethod {
					return nil, fmt.Errorf("unexpected jwt signing method=%v", t.Header["alg"])
				}
				return config.SigningKey, nil

			})
			if err == nil && token.Valid {
				// Store user information from token into context.
				c.Set(config.ContextKey, token)
				return next(c)
			}
			return echo.ErrUnauthorized
		}
	}
}
Пример #29
0
func init() {
	Errors[sql.ErrNoRows] = func(err error, c *echo.Context) {
		if c.Request().Header.Get("Content-Type") == imt.Application.JSON {
			JSONErrorHandler(echo.NewHTTPError(404, "Record not found"), c)
		} else {
			c.Render(404, "404", err)
		}
	}
}
Пример #30
0
func assertContentTypeJSON(r *http.Request) *echo.HTTPError {
	ct := r.Header.Get(echo.ContentType)

	if !strings.HasPrefix(ct, echo.ApplicationJSON) {
		return echo.NewHTTPError(http.StatusBadRequest, "request: allowed Content-Type is 'application/json' only")
	}

	return nil
}