// 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) } }
// LoginPost handlers login form, and logs in the user. If the form is valid, the user is // redirected to "/auth/login" with the form validation errors. When the user is validated // redirection is made to "/". // // Method POST // // Route /auth/login // // Restrictions None // // Template None (All actions redirect to other routes ) // // Flash messages may be set before redirection. func LoginPost(ctx *echo.Context) error { var flashMessages = flash.New() f := forms.New(utils.GetLang(ctx)) lf := f.LoginForm()(ctx.Request()) if !lf.IsValid() { utils.SetData(ctx, authForm, lf) ctx.Redirect(http.StatusFound, "/auth/login") return nil } // Check email and password user, err := query.AuthenticateUserByEmail(lf.GetModel().(forms.Login)) if err != nil { log.Error(ctx, err) // We want the user to try again, but rather than rendering the form right // away, we redirect him/her to /auth/login route(where the login process with // start aflsesh albeit with a flash message) flashMessages.Err(msgLoginErr) flashMessages.Save(ctx) ctx.Redirect(http.StatusFound, "/auth/login") return nil } // create a session for the user after the validation has passed. The info stored // in the session is the user ID, where as the key is userID. ss, err := sessStore.Get(ctx.Request(), settings.App.Session.Name) if err != nil { log.Error(ctx, err) } ss.Values["userID"] = user.ID err = ss.Save(ctx.Request(), ctx.Response()) if err != nil { log.Error(ctx, err) } person, err := query.GetPersonByUserID(user.ID) if err != nil { log.Error(ctx, err) flashMessages.Err(msgLoginErr) flashMessages.Save(ctx) ctx.Redirect(http.StatusFound, "/auth/login") return nil } // add context data. IsLoged is just a conveniece in template rendering. the User // contains a models.Person object, where the PersonName is already loaded. utils.SetData(ctx, "IsLoged", true) utils.SetData(ctx, "User", person) flashMessages.Success(msgLoginSuccess) flashMessages.Save(ctx) ctx.Redirect(http.StatusFound, "/") log.Info(ctx, "login success") return nil }