Exemple #1
0
func echoServer() {
	e := echo.New()
	e.Use(middleware.Logger())
	e.Post("/rsvp", echo.HandlerFunc(requestAddRsvp))

	admin := e.Group("/rsvp")
	admin.Use(middleware.BasicAuth(checkAuth))
	admin.Get("/list", echo.HandlerFunc(requestListRsvp))
	admin.Get("/backup", echo.HandlerFunc(requestBoltBackup))

	e.Static("/", *rootDir)

	fmt.Println("Starting Server:", *httpServ)
	e.Run(standard.New(*httpServ))
}
Exemple #2
0
func main() {
	// 支持根据参数打印版本信息
	global.PrintVersion(os.Stdout)

	savePid()

	logger.Init(ROOT+"/log", ConfigFile.MustValue("global", "log_level", "DEBUG"))

	go ServeBackGround()

	e := echo.New()

	serveStatic(e)

	e.Use(thirdmw.EchoLogger())
	e.Use(mw.Recover())
	e.Use(pwm.Installed(filterPrefixs))
	e.Use(pwm.HTTPError())
	e.Use(pwm.AutoLogin())

	frontG := e.Group("", thirdmw.EchoCache())
	controller.RegisterRoutes(frontG)

	frontG.GET("/admin", echo.HandlerFunc(admin.AdminIndex), pwm.NeedLogin(), pwm.AdminAuth())
	adminG := e.Group("/admin", pwm.NeedLogin(), pwm.AdminAuth())
	admin.RegisterRoutes(adminG)

	std := standard.New(getAddr())
	std.SetHandler(e)

	gracefulRun(std)
}
Exemple #3
0
// BasicAuthFromConfig returns an HTTP basic auth middleware from config.
// See `BasicAuth()`.
func BasicAuthFromConfig(config BasicAuthConfig) echo.MiddlewareFunc {
	return func(next echo.Handler) echo.Handler {
		return echo.HandlerFunc(func(c echo.Context) error {
			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
							if config.AuthFunc(cred[:i], cred[i+1:]) {
								return next.Handle(c)
							}
						}
					}
				}
			}
			c.Response().Header().Set(echo.WWWAuthenticate, basic+" realm=Restricted")
			return echo.ErrUnauthorized
		})
	}
}
Exemple #4
0
// authorization is the authorization middleware for users.
// It checks the access_token in the Authorization header or the access_token query parameter
// On success sets "me" = *User (current logged user) and "accessData" = current access data
// into the context. Sets even the scopes variable, the sorted slice of scopes in accessData
func authorization() echo.MiddlewareFunc {
	return func(next echo.HandlerFunc) echo.HandlerFunc {
		return echo.HandlerFunc(func(c echo.Context) error {
			var accessToken string
			auth := c.Request().Header.Get("Authorization")
			if auth == "" {
				// Check if there's the parameter access_token in the URL
				// this makes the bearer authentication with websockets compatible with OAuth2
				accessToken = c.QueryParam("access_token")
				if accessToken == "" {
					return c.String(http.StatusUnauthorized, "access_token required")
				}
			} else {
				if !strings.HasPrefix(auth, "Bearer ") {
					return echo.ErrUnauthorized
				}
				ss := strings.Split(auth, " ")
				if len(ss) != 2 {
					return echo.ErrUnauthorized
				}
				accessToken = ss[1]
			}

			accessData, err := (&nerdz.OAuth2Storage{}).LoadAccess(accessToken)
			if err != nil {
				return c.String(http.StatusUnauthorized, err.Error())
			}

			// fetch current logged user and store it into the context
			me, err := nerdz.NewUser(accessData.UserData.(uint64))
			if err != nil {
				return c.String(http.StatusInternalServerError, err.Error())
			}
			c.Set("me", me)

			// store the Access Data into the context
			c.Set("accessData", accessData)
			scopes := strings.Split(accessData.Scope, " ")
			sort.Strings(scopes)

			// store the sorted Scopes using the full format
			// eg: if accepted scope is profile:read,write
			// save 2 entries: profile:read and profile:write
			// each saved scope is always in the format <name>:<read|,write>
			var fullScopes []string
			for _, s := range scopes {
				//parts[0] = <scope>, parts[1] = <rw>
				parts := strings.Split(s, ":")
				rw := strings.Split(parts[1], ",")
				for _, perm := range rw {
					fullScopes = append(fullScopes, parts[0]+":"+perm)
				}
			}
			c.Set("scopes", fullScopes)

			// let next handler handle the context
			return next(c)
		})
	}
}
Exemple #5
0
// GzipFromConfig return gzip middleware from config.
// See `Gzip()`.
func GzipFromConfig(config GzipConfig) echo.MiddlewareFunc {
	pool := gzipPool(config)
	scheme := "gzip"

	return func(next echo.Handler) echo.Handler {
		return echo.HandlerFunc(func(c echo.Context) error {
			c.Response().Header().Add(echo.Vary, echo.AcceptEncoding)
			if strings.Contains(c.Request().Header().Get(echo.AcceptEncoding), scheme) {
				rw := c.Response().Writer()
				gw := pool.Get().(*gzip.Writer)
				gw.Reset(rw)
				defer func() {
					if c.Response().Size() == 0 {
						// We have to reset response to it's pristine state when
						// nothing is written to body or error is returned.
						// See issue #424, #407.
						c.Response().SetWriter(rw)
						c.Response().Header().Del(echo.ContentEncoding)
						gw.Reset(ioutil.Discard)
					}
					gw.Close()
					pool.Put(gw)
				}()
				g := gzipResponseWriter{Response: c.Response(), Writer: gw}
				c.Response().Header().Set(echo.ContentEncoding, scheme)
				c.Response().SetWriter(g)
			}
			return next.Handle(c)
		})
	}
}
Exemple #6
0
// SetPost is the middleware that checks if the required post, on the project board, exists.
// If it exists, set the "post" = *ProjectPost in the current context
func SetPost() echo.MiddlewareFunc {
	return func(next echo.HandlerFunc) echo.HandlerFunc {
		return echo.HandlerFunc(func(c echo.Context) error {
			var e error
			var pid uint64

			if pid, e = strconv.ParseUint(c.Param("pid"), 10, 64); e != nil {
				c.JSON(http.StatusBadRequest, &rest.Response{
					HumanMessage: "Invalid post identifier specified",
					Message:      e.Error(),
					Status:       http.StatusBadRequest,
					Success:      false,
				})
				return e
			}

			projectID := c.Get("project").(*nerdz.Project).ID()
			var post *nerdz.ProjectPost

			if post, e = nerdz.NewProjectPostWhere(&nerdz.ProjectPost{nerdz.Post{To: projectID, Pid: pid}}); e != nil {
				c.JSON(http.StatusBadRequest, &rest.Response{
					HumanMessage: "Required post does not exists",
					Message:      e.Error(),
					Status:       http.StatusBadRequest,
					Success:      false,
				})
				return e
			}

			c.Set("post", post)
			return next(c)
		})
	}
}
Exemple #7
0
// SetOther is the middleware that sets the context variable "other" to "me"
// therfore we can use the package user methods in the me package
func SetOther() echo.MiddlewareFunc {
	return func(next echo.HandlerFunc) echo.HandlerFunc {
		return echo.HandlerFunc(func(c echo.Context) error {
			c.Set("other", c.Get("me"))
			return next(c)
		})
	}
}
Exemple #8
0
// SetPm is the middleware that check if the required pm exists.
// If it exists, set the "pm" = *Pm in the current context
func SetPm() echo.MiddlewareFunc {
	return func(next echo.HandlerFunc) echo.HandlerFunc {
		return echo.HandlerFunc(func(c echo.Context) error {

			// other is the owner of the pm list
			other := c.Get("other").(*nerdz.User)
			// otherID is the ID of the second actor in the conversation
			var otherID, pmID uint64
			var e error
			if otherID, e = strconv.ParseUint(c.Param("other"), 10, 64); e != nil {
				errstr := "Invalid user identifier specified"
				c.JSON(http.StatusBadRequest, &rest.Response{
					HumanMessage: errstr,
					Message:      e.Error(),
					Status:       http.StatusBadRequest,
					Success:      false,
				})
				return e
			}

			if pmID, e = strconv.ParseUint(c.Param("pmid"), 10, 64); e != nil {
				errstr := "Invalid PM identifier specified"
				c.JSON(http.StatusBadRequest, &rest.Response{
					HumanMessage: errstr,
					Message:      e.Error(),
					Status:       http.StatusBadRequest,
					Success:      false,
				})
				return e
			}

			var pm *nerdz.Pm
			if pm, e = nerdz.NewPm(pmID); e != nil {
				c.JSON(http.StatusBadRequest, &rest.Response{
					HumanMessage: e.Error(),
					Message:      e.Error(),
					Status:       http.StatusBadRequest,
					Success:      false,
				})
				return e
			}

			if (pm.From == otherID && pm.To == other.ID()) || (pm.From == other.ID() && pm.To == otherID) {
				c.Set("pm", pm)
				return next(c)
			}

			errstr := "You're not autorized to see the requested PM"
			c.JSON(http.StatusUnauthorized, &rest.Response{
				HumanMessage: errstr,
				Message:      errstr,
				Status:       http.StatusUnauthorized,
				Success:      false,
			})
			return errors.New(errstr)
		})
	}
}
Exemple #9
0
// Mgo returns a middleware which connect to mongo and set the session in the context
func Mgo(mgodb *mgo.Database) echo.MiddlewareFunc {
	return func(next echo.HandlerFunc) echo.HandlerFunc {
		return echo.HandlerFunc(func(c echo.Context) error {
			sc := mgodb.Session.Clone()
			defer sc.Close()
			c.Set("mgok", sc.DB(mgodb.Name))
			return next(c)
		})
	}
}
Exemple #10
0
// WrapMiddleware wraps `fasthttp.RequestHandler` into `echo.MiddlewareFunc`
func WrapMiddleware(h fasthttp.RequestHandler) echo.MiddlewareFunc {
	return func(next echo.Handler) echo.Handler {
		return echo.HandlerFunc(func(c echo.Context) error {
			rq := c.Request().(*Request)
			rs := c.Response().(*Response)
			ctx := rq.RequestCtx
			h(ctx)
			rs.status = ctx.Response.StatusCode()
			rs.size = int64(ctx.Response.Header.ContentLength())
			return next.Handle(c)
		})
	}
}
Exemple #11
0
func TestRecover(t *testing.T) {
	e := echo.New()
	buf := new(bytes.Buffer)
	e.SetLogOutput(buf)
	rq := test.NewRequest(echo.GET, "/", nil)
	rc := test.NewResponseRecorder()
	c := e.NewContext(rq, rc)
	h := Recover()(echo.HandlerFunc(func(c echo.Context) error {
		panic("test")
	}))
	h(c)
	assert.Equal(t, http.StatusInternalServerError, rc.Status())
	assert.Contains(t, buf.String(), "PANIC RECOVER")
}
Exemple #12
0
func TestRecover(t *testing.T) {
	e := echo.New()
	buf := new(bytes.Buffer)
	e.Logger.SetOutput(buf)
	req, _ := http.NewRequest(echo.GET, "/", nil)
	rec := httptest.NewRecorder()
	c := e.NewContext(req, rec)
	h := Recover()(echo.HandlerFunc(func(c echo.Context) error {
		panic("test")
	}))
	h(c)
	assert.Equal(t, http.StatusInternalServerError, rec.Code)
	assert.Contains(t, buf.String(), "PANIC RECOVER")
}
Exemple #13
0
// SetProject is the middleware that checks if the current logged user can see the required project
// and if the required project exists. On success sets the "project" = *Project variable in the context
func SetProject() echo.MiddlewareFunc {
	return func(next echo.HandlerFunc) echo.HandlerFunc {
		return echo.HandlerFunc(func(c echo.Context) error {
			var project *nerdz.Project
			var err error
			if project, err = rest.Project("id", c); err != nil {
				return err
			}
			// store the project Project into the context
			c.Set("project", project)
			// pass context to the next handler
			return next(c)
		})
	}
}
Exemple #14
0
// SetOther is the middleware that checks if the current logged user can see the required profile
// and if the required profile exists. On success sets the "other" = *User variable in the context
func SetOther() echo.MiddlewareFunc {
	return func(next echo.HandlerFunc) echo.HandlerFunc {
		return echo.HandlerFunc(func(c echo.Context) error {
			var other *nerdz.User
			var err error
			if other, err = rest.User("id", c); err != nil {
				return err
			}
			// store the other User into the context
			c.Set("other", other)
			// pass context to the next handler
			return next(c)
		})
	}
}
Exemple #15
0
// WrapMiddleware wraps `func(http.Handler) http.Handler` into `echo.MiddlewareFunc`
func WrapMiddleware(m func(http.Handler) http.Handler) echo.MiddlewareFunc {
	return func(next echo.Handler) echo.Handler {
		return echo.HandlerFunc(func(c echo.Context) (err error) {
			rq := c.Request().(*Request)
			rs := c.Response().(*Response)
			w := &responseAdapter{
				ResponseWriter: rs.ResponseWriter,
				Response:       rs,
			}
			m(http.HandlerFunc(func(w http.ResponseWriter, r *http.Request) {
				err = next.Handle(c)
			})).ServeHTTP(w, rq.Request)
			return
		})
	}
}
Exemple #16
0
// SetComment is the middleware that check if the required comment, on the user board, exists.
// If it exists, set the "comment" =  *UserPostComment in the current context
func SetComment() echo.MiddlewareFunc {
	return func(next echo.HandlerFunc) echo.HandlerFunc {
		return echo.HandlerFunc(func(c echo.Context) error {

			var cid uint64
			var e error
			if cid, e = strconv.ParseUint(c.Param("cid"), 10, 64); e != nil {
				errstr := "Invalid comment identifier specified"
				c.JSON(http.StatusBadRequest, &rest.Response{
					HumanMessage: errstr,
					Message:      e.Error(),
					Status:       http.StatusBadRequest,
					Success:      false,
				})
				return e
			}

			var comment *nerdz.UserPostComment
			if comment, e = nerdz.NewUserPostComment(cid); e != nil {
				errstr := "Invalid comment identifier specified"
				c.JSON(http.StatusBadRequest, &rest.Response{
					HumanMessage: errstr,
					Message:      e.Error(),
					Status:       http.StatusBadRequest,
					Success:      false,
				})
				return e
			}

			post := c.Get("post").(*nerdz.UserPost)
			if comment.Hpid != post.Hpid {
				errstr := "Mismatch between comment ID and post ID. Comment not related to the post"
				c.JSON(http.StatusBadRequest, &rest.Response{
					HumanMessage: errstr,
					Message:      errstr,
					Status:       http.StatusBadRequest,
					Success:      false,
				})
				return e
			}
			c.Set("comment", comment)
			return next(c)
		})
	}
}
Exemple #17
0
// setPmsOptions is the middleware that sets the "pmsOptions" = *nerdz.PmsOptions into the current context
// handle GET parameters:
func setPmsOptions() echo.MiddlewareFunc {
	return func(next echo.HandlerFunc) echo.HandlerFunc {
		return echo.HandlerFunc(func(c echo.Context) error {
			old := c.QueryParam("older")
			new := c.QueryParam("newer")

			older, _ := strconv.ParseUint(old, 10, 64)
			newer, _ := strconv.ParseUint(new, 10, 64)

			n, _ := strconv.ParseUint(c.QueryParam("n"), 10, 8)

			c.Set("pmsOptions", &nerdz.PmsOptions{
				N:     nerdz.AtMostComments(n),
				Older: older,
				Newer: newer,
			})
			return next(c)
		})
	}
}
Exemple #18
0
func TransactionHandler(db *dbr.Session) echo.MiddlewareFunc {
	return func(next echo.HandlerFunc) echo.HandlerFunc {
		return echo.HandlerFunc(func(c echo.Context) error {
			tx, _ := db.Begin()

			c.Set(TxKey, tx)

			if err := next(c); err != nil {
				tx.Rollback()
				logrus.Debug("Transction Rollback: ", err)
				return err
			}

			logrus.Debug("Transction Commit")
			tx.Commit()

			return nil
		})
	}
}
Exemple #19
0
// StoreHeaders get header values and set to context
func StoreHeaders(options ...*StoreHeaderOptions) echo.MiddlewareFunc {
	return func(next echo.Handler) echo.Handler {
		return echo.HandlerFunc(func(c echo.Context) error {
			request := c.Request()
			header := request.Header()
			url := request.URL()

			//application/vnd.get3w.v3+json
			version := VersionV1
			accept := header.Get("Accept")
			if accept == "" || accept == "application/vnd.get3w.v1+json" {
				version = VersionV1
			}
			c.Set("Version", version)

			auth := header.Get("Authorization")
			l := len(Bearer)
			accessToken := ""

			if len(auth) > l+1 && auth[:l] == Bearer {
				accessToken = auth[l+1:]
			} else if len(header.Get(TokenNameOfHeader)) > 0 {
				accessToken = header.Get(TokenNameOfHeader)
			} else if len(url.QueryValue(TokenNameOfQuery)) > 0 {
				accessToken = url.QueryValue(TokenNameOfQuery)
			}

			c.Set("AccessToken", accessToken)

			config, _ := home.LoadConfig()
			c.Set("Config", config)

			if err := next.Handle(c); err != nil {
				c.Error(err)
			}

			return nil
		})
	}
}
Exemple #20
0
// Modify 编辑规则
func (self RuleController) Modify(ctx echo.Context) error {
	var data = make(map[string]interface{})

	if ctx.FormValue("submit") == "1" {
		user := ctx.Get("user").(*model.Me)

		errMsg, err := logic.DefaultRule.Save(ctx, ctx.FormParams(), user.Username)
		if err != nil {
			return fail(ctx, 1, errMsg)
		}
		return success(ctx, nil)
	}

	rule := logic.DefaultRule.FindById(ctx, ctx.QueryParam("id"))
	if rule == nil {
		return ctx.Redirect(http.StatusSeeOther, ctx.Echo().URI(echo.HandlerFunc(self.RuleList)))
	}

	data["rule"] = rule

	return render(ctx, "rule/modify.html", data)
}
Exemple #21
0
// Modify
func (self ArticleController) Modify(ctx echo.Context) error {
	var data = make(map[string]interface{})

	if ctx.FormValue("submit") == "1" {
		user := ctx.Get("user").(*model.Me)
		errMsg, err := logic.DefaultArticle.Modify(ctx, user, ctx.FormParams())
		if err != nil {
			return fail(ctx, 1, errMsg)
		}
		return success(ctx, nil)
	}
	article, err := logic.DefaultArticle.FindById(ctx, ctx.QueryParam("id"))
	if err != nil {
		return ctx.Redirect(http.StatusSeeOther, ctx.Echo().URI(echo.HandlerFunc(self.ArticleList)))
	}

	data["article"] = article
	data["statusSlice"] = model.ArticleStatusSlice
	data["langSlice"] = model.LangSlice

	return render(ctx, "article/modify.html", data)

}
Exemple #22
0
// RecoverFromConfig returns a recover middleware from config.
// See `Recover()`.
func RecoverFromConfig(config RecoverConfig) echo.MiddlewareFunc {
	return func(next echo.Handler) echo.Handler {
		return echo.HandlerFunc(func(c echo.Context) error {
			defer func() {
				if r := recover(); r != nil {
					var err error
					switch r := r.(type) {
					case error:
						err = r
					default:
						err = fmt.Errorf("%v", r)
					}
					stack := make([]byte, config.StackSize)
					length := runtime.Stack(stack, config.StackAll)
					if config.PrintStack {
						c.Logger().Printf("[%s] %s %s", color.Red("PANIC RECOVER"), err, stack[:length])
					}
					c.Error(err)
				}
			}()
			return next.Handle(c)
		})
	}
}
Exemple #23
0
// StaticFromConfig returns a static middleware from config.
// See `Static()`.
func StaticFromConfig(config StaticConfig) echo.MiddlewareFunc {
	return func(next echo.Handler) echo.Handler {
		return echo.HandlerFunc(func(c echo.Context) error {
			fs := http.Dir(config.Root)
			file := path.Clean(c.Request().URL().Path())
			f, err := fs.Open(file)
			if err != nil {
				return next.Handle(c)
			}
			defer f.Close()

			fi, err := f.Stat()
			if err != nil {
				return err
			}

			if fi.IsDir() {
				/* NOTE:
				Not checking the Last-Modified header as it caches the response `304` when
				changing different directories for the same path.
				*/
				d := f

				// Index file
				file = path.Join(file, config.Index)
				f, err = fs.Open(file)
				if err != nil {
					if config.Browse {
						dirs, err := d.Readdir(-1)
						if err != nil {
							return err
						}

						// Create a directory index
						rs := c.Response()
						rs.Header().Set(echo.ContentType, echo.TextHTMLCharsetUTF8)
						if _, err = fmt.Fprintf(rs, "<pre>\n"); err != nil {
							return err
						}
						for _, d := range dirs {
							name := d.Name()
							color := "#212121"
							if d.IsDir() {
								color = "#e91e63"
								name += "/"
							}
							if _, err = fmt.Fprintf(rs, "<a href=\"%s\" style=\"color: %s;\">%s</a>\n", name, color, name); err != nil {
								return err
							}
						}
						_, err = fmt.Fprintf(rs, "</pre>\n")
						return err
					}
					return next.Handle(c)
				}
				fi, _ = f.Stat() // Index file stat
			}
			return c.ServeContent(f, fi.Name(), fi.ModTime())
		})
	}
}
Exemple #24
0
// setPostlist is the middleware that sets "postlistOptions" = *nerdz.PostlistOptions into the current Context
// handle GET parameters:
// following: if setted, requires posts from following users
// followers: if setted, requires posts from followers users
// lang: if setted to a supported language (nerdz.Configuration.Languages), requires
//       posts in that language
// older: if setted to an existing hpid, requires posts older than the "older" value
// olderType: if setted can be only "user" or "project". Represents a reference to the older hpid type
//		used when fetching from a view, where hpid can be from posts or groups_posts
// newer: if setted to an existing hpid, requires posts newer than the "newer" value7
// newerType: if setted can be only "user" or "project". Represents a reference to the newer hpid type
//		used when fetching from a view, where hpid can be from posts or groups_posts
// n: if setted, define the number of posts to retrieve. Follows the nerdz.atMostPost rules
func setPostlist() echo.MiddlewareFunc {
	return func(next echo.HandlerFunc) echo.HandlerFunc {
		return echo.HandlerFunc(func(c echo.Context) error {
			var following, followers bool
			if c.QueryParam("following") != "" {
				following = true
			}

			if c.QueryParam("followers") != "" {
				followers = true
			}

			for _, t := range []string{"olderType", "newerType"} {
				tValue := c.QueryParam(t)
				if tValue != "" {
					if tValue != "user" && tValue != "project" {
						message := fmt.Sprintf(`Unsupported %s %s. Only "user" or "project" are allowed`, t, tValue)
						return c.JSON(http.StatusBadRequest, &rest.Response{
							HumanMessage: message,
							Message:      message,
							Status:       http.StatusBadRequest,
							Success:      false,
						})
					}
				}
			}

			var olderModel, newerModel igor.DBModel
			if c.QueryParam("olderType") == "user" {
				olderModel = nerdz.UserPost{}
			} else {
				olderModel = nerdz.ProjectPost{}
			}

			if c.QueryParam("newerType") == "user" {
				newerModel = nerdz.UserPost{}
			} else {
				newerModel = nerdz.ProjectPost{}
			}

			var language string
			lang := c.QueryParam("lang")
			if lang == "" {
				language = ""
			} else {
				if !utils.InSlice(lang, nerdz.Configuration.Languages) {
					message := "Not supported language: " + lang
					return c.JSON(http.StatusBadRequest, &rest.Response{
						HumanMessage: message,
						Message:      message,
						Status:       http.StatusBadRequest,
						Success:      false,
					})
				}
				language = lang
			}

			old := c.QueryParam("older")
			new := c.QueryParam("newer")

			older, _ := strconv.ParseUint(old, 10, 64)
			newer, _ := strconv.ParseUint(new, 10, 64)

			n, _ := strconv.ParseUint(c.QueryParam("n"), 10, 8)

			c.Set("postlistOptions", &nerdz.PostlistOptions{
				Following:  following,
				Followers:  followers,
				Language:   language,
				N:          nerdz.AtMostPosts(n),
				Older:      older,
				OlderModel: olderModel,
				Newer:      newer,
				NewerModel: newerModel,
			})

			return next(c)
		})
	}
}
Exemple #25
0
func main() {
	e := echo.New()

	// New permissions middleware
	perm, err := permissionHSTORE.New()
	if err != nil {
		log.Fatalln(err)
	}

	// Blank slate, no default permissions
	//perm.Clear()

	// Set up a middleware handler for Echo, with a custom "permission denied" message.
	permissionHandler := echo.MiddlewareFunc(func(next echo.HandlerFunc) echo.HandlerFunc {
		return echo.HandlerFunc(func(c echo.Context) error {
			// Check if the user has the right admin/user rights
			if perm.Rejected(w(c), req(c)) {
				// Deny the request
				return echo.NewHTTPError(http.StatusForbidden, "Permission denied!")
			}
			// Continue the chain of middleware
			return next(c)
		})
	})

	// Logging middleware
	e.Use(middleware.Logger())

	// Enable the permissions middleware, must come before recovery
	e.Use(permissionHandler)

	// Recovery middleware
	e.Use(middleware.Recover())

	// Get the userstate, used in the handlers below
	userstate := perm.UserState()

	e.Get("/", echo.HandlerFunc(func(c echo.Context) error {
		var buf bytes.Buffer
		b2s := map[bool]string{false: "false", true: "true"}
		buf.WriteString("Has user bob: " + b2s[userstate.HasUser("bob")] + "\n")
		buf.WriteString("Logged in on server: " + b2s[userstate.IsLoggedIn("bob")] + "\n")
		buf.WriteString("Is confirmed: " + b2s[userstate.IsConfirmed("bob")] + "\n")
		buf.WriteString("Username stored in cookies (or blank): " + userstate.Username(req(c)) + "\n")
		buf.WriteString("Current user is logged in, has a valid cookie and *user rights*: " + b2s[userstate.UserRights(req(c))] + "\n")
		buf.WriteString("Current user is logged in, has a valid cookie and *admin rights*: " + b2s[userstate.AdminRights(req(c))] + "\n")
		buf.WriteString("\nTry: /register, /confirm, /remove, /login, /logout, /makeadmin, /clear, /data and /admin")
		return c.String(http.StatusOK, buf.String())
	}))

	e.Get("/register", echo.HandlerFunc(func(c echo.Context) error {
		userstate.AddUser("bob", "hunter1", "*****@*****.**")
		return c.String(http.StatusOK, fmt.Sprintf("User bob was created: %v\n", userstate.HasUser("bob")))
	}))

	e.Get("/confirm", echo.HandlerFunc(func(c echo.Context) error {
		userstate.MarkConfirmed("bob")
		return c.String(http.StatusOK, fmt.Sprintf("User bob was confirmed: %v\n", userstate.IsConfirmed("bob")))
	}))

	e.Get("/remove", echo.HandlerFunc(func(c echo.Context) error {
		userstate.RemoveUser("bob")
		return c.String(http.StatusOK, fmt.Sprintf("User bob was removed: %v\n", !userstate.HasUser("bob")))
	}))

	e.Get("/login", echo.HandlerFunc(func(c echo.Context) error {
		// Headers will be written, for storing a cookie
		userstate.Login(w(c), "bob")
		return c.String(http.StatusOK, fmt.Sprintf("bob is now logged in: %v\n", userstate.IsLoggedIn("bob")))
	}))

	e.Get("/logout", echo.HandlerFunc(func(c echo.Context) error {
		userstate.Logout("bob")
		return c.String(http.StatusOK, fmt.Sprintf("bob is now logged out: %v\n", !userstate.IsLoggedIn("bob")))
	}))

	e.Get("/makeadmin", echo.HandlerFunc(func(c echo.Context) error {
		userstate.SetAdminStatus("bob")
		return c.String(http.StatusOK, fmt.Sprintf("bob is now administrator: %v\n", userstate.IsAdmin("bob")))
	}))

	e.Get("/clear", echo.HandlerFunc(func(c echo.Context) error {
		userstate.ClearCookie(w(c))
		return c.String(http.StatusOK, "Clearing cookie")
	}))

	e.Get("/data", echo.HandlerFunc(func(c echo.Context) error {
		return c.String(http.StatusOK, "user page that only logged in users must see!")
	}))

	e.Get("/admin", echo.HandlerFunc(func(c echo.Context) error {
		var buf bytes.Buffer
		buf.WriteString("super secret information that only logged in administrators must see!\n\n")
		if usernames, err := userstate.AllUsernames(); err == nil {
			buf.WriteString("list of all users: " + strings.Join(usernames, ", "))
		}
		return c.String(http.StatusOK, buf.String())
	}))

	// Serve
	e.Run(standard.New(":3000"))
}
Exemple #26
0
// LoggerFromConfig returns a logger middleware from config.
// See `Logger()`.
func LoggerFromConfig(config LoggerConfig) echo.MiddlewareFunc {
	config.template = fasttemplate.New(config.Format, "${", "}")
	config.color = color.New()
	if w, ok := config.Output.(*os.File); ok && !isatty.IsTerminal(w.Fd()) {
		config.color.Disable()
	}

	return func(next echo.Handler) echo.Handler {
		return echo.HandlerFunc(func(c echo.Context) (err error) {
			rq := c.Request()
			rs := c.Response()
			start := time.Now()
			if err = next.Handle(c); err != nil {
				c.Error(err)
			}
			stop := time.Now()

			_, err = config.template.ExecuteFunc(config.Output, func(w io.Writer, tag string) (int, error) {
				switch tag {
				case "time_rfc3339":
					return w.Write([]byte(time.Now().Format(time.RFC3339)))
				case "remote_ip":
					ra := rq.RemoteAddress()
					if ip := rq.Header().Get(echo.XRealIP); ip != "" {
						ra = ip
					} else if ip = rq.Header().Get(echo.XForwardedFor); ip != "" {
						ra = ip
					} else {
						ra, _, _ = net.SplitHostPort(ra)
					}
					return w.Write([]byte(ra))
				case "uri":
					return w.Write([]byte(rq.URI()))
				case "method":
					return w.Write([]byte(rq.Method()))
				case "path":
					p := rq.URL().Path()
					if p == "" {
						p = "/"
					}
					return w.Write([]byte(p))
				case "status":
					n := rs.Status()
					s := color.Green(n)
					switch {
					case n >= 500:
						s = color.Red(n)
					case n >= 400:
						s = color.Yellow(n)
					case n >= 300:
						s = color.Cyan(n)
					}
					return w.Write([]byte(s))
				case "response_time":
					return w.Write([]byte(stop.Sub(start).String()))
				case "response_size":
					return w.Write([]byte(strconv.FormatInt(rs.Size(), 10)))
				default:
					return w.Write([]byte(fmt.Sprintf("[unknown tag %s]", tag)))
				}
			})
			return
		})
	}
}
Exemple #27
0
func main() {
	// Echo instance
	e := echo.New()

	// Middleware echo
	e.Use(middleware.Logger())
	logg := e.Logger()

	e.Use(middleware.Recover())
	e.Use(middleware.Gzip())
	e.Use(middleware.Secure())
	e.Use(middleware.CORS())
	e.Use(middleware.BodyLimit("200M"))

	// gopkg.in/mgo.v2
	db := midd.NewMgo(viper.GetString("db.url"), viper.GetString("db.name"))
	defer db.Session.Close()
	e.Use(midd.Mgo(db))

	// github.com/thoas/stats
	middStat := stats.New()
	e.Use(standard.WrapMiddleware(middStat.Handler))
	// Route for stats
	e.Get("/stats", echo.HandlerFunc(func(c echo.Context) error {
		return c.JSON(http.StatusOK, middStat.Data())
	}))

	// API v1 Restricted group Token in header
	api := e.Group("/apiv1")
	api.Use(middleware.JWTWithConfig(middleware.JWTConfig{
		SigningKey:  []byte(midd.SigningKey),
		TokenLookup: "header:Authorization"}))
	api.Post("/user", handler.PostUser)
	api.Get("/user/:id", handler.GetUser)

	// API v1 Token as first param
	apit := e.Group("/apiv1token")
	apit.Use(middleware.JWTWithConfig(middleware.JWTConfig{
		SigningKey:  []byte(midd.SigningKey),
		TokenLookup: "query:token"}))
	apit.Post("/user", handler.PostUser)
	apit.Get("/user/:id", handler.GetUser)

	// Serve index file
	e.File("/", "public/index.html")
	// Serve favicon
	e.File("/favicon.ico", "public/favicon.ico")
	// Serve static files
	e.Static("/scripts", "public/scripts")

	midd.GenerateToken()

	// Get server info
	var svrHostname string

	if runtime.GOOS == "windows" {
		svrHostname = fmt.Sprintf("%s.%s", os.Getenv("COMPUTERNAME"), os.Getenv("USERDNSDOMAIN"))
	} else {
		svrHostname, _ = os.Hostname()
	}
	webInterfacePort := viper.GetString("web.interface")

	logg.Printf("%s for %s %s on %d cores\n%s%s\n",
		runtime.Version(), runtime.GOOS, runtime.GOARCH, runtime.NumCPU(), svrHostname, webInterfacePort)

	mgoInfo, _ := db.Session.BuildInfo()
	logg.Printf("MongoDB %s %d bits\n", mgoInfo.Version, mgoInfo.Bits)

	// github.com/tylerb/graceful
	std := standard.New(webInterfacePort)
	std.SetHandler(e)
	graceful.ListenAndServe(std.Server, 5*time.Second)
}