diff options
Diffstat (limited to 'internal/api/client/auth/authorize.go')
-rw-r--r-- | internal/api/client/auth/authorize.go | 73 |
1 files changed, 60 insertions, 13 deletions
diff --git a/internal/api/client/auth/authorize.go b/internal/api/client/auth/authorize.go index 99f3cca68..387b83c1e 100644 --- a/internal/api/client/auth/authorize.go +++ b/internal/api/client/auth/authorize.go @@ -44,7 +44,7 @@ func (m *Module) AuthorizeGETHandler(c *gin.Context) { s := sessions.Default(c) if _, err := api.NegotiateAccept(c, api.HTMLAcceptHeaders...); err != nil { - c.JSON(http.StatusNotAcceptable, gin.H{"error": err.Error()}) + c.HTML(http.StatusNotAcceptable, "error.tmpl", gin.H{"error": err.Error()}) return } @@ -57,7 +57,7 @@ func (m *Module) AuthorizeGETHandler(c *gin.Context) { if err := c.Bind(form); err != nil { l.Debugf("invalid auth form: %s", err) m.clearSession(s) - c.JSON(http.StatusBadRequest, gin.H{"error": err.Error()}) + c.HTML(http.StatusBadRequest, "error.tmpl", gin.H{"error": err.Error()}) return } l.Debugf("parsed auth form: %+v", form) @@ -65,7 +65,7 @@ func (m *Module) AuthorizeGETHandler(c *gin.Context) { if err := extractAuthForm(s, form); err != nil { l.Debugf(fmt.Sprintf("error parsing form at /oauth/authorize: %s", err)) m.clearSession(s) - c.JSON(http.StatusBadRequest, gin.H{"error": err.Error()}) + c.HTML(http.StatusBadRequest, "error.tmpl", gin.H{"error": err.Error()}) return } c.Redirect(http.StatusSeeOther, AuthSignInPath) @@ -75,28 +75,33 @@ func (m *Module) AuthorizeGETHandler(c *gin.Context) { // We can use the client_id on the session to retrieve info about the app associated with the client_id clientID, ok := s.Get(sessionClientID).(string) if !ok || clientID == "" { - c.JSON(http.StatusInternalServerError, gin.H{"error": "no client_id found in session"}) + c.HTML(http.StatusInternalServerError, "error.tmpl", gin.H{"error": "no client_id found in session"}) return } app := >smodel.Application{} if err := m.db.GetWhere(c.Request.Context(), []db.Where{{Key: sessionClientID, Value: clientID}}, app); err != nil { m.clearSession(s) - c.JSON(http.StatusInternalServerError, gin.H{"error": fmt.Sprintf("no application found for client id %s", clientID)}) + c.HTML(http.StatusInternalServerError, "error.tmpl", gin.H{ + "error": fmt.Sprintf("no application found for client id %s", clientID), + }) return } - // we can also use the userid of the user to fetch their username from the db to greet them nicely <3 + // redirect the user if they have not confirmed their email yet, thier account has not been approved yet, + // or thier account has been disabled. user := >smodel.User{} if err := m.db.GetByID(c.Request.Context(), userID, user); err != nil { m.clearSession(s) - c.JSON(http.StatusInternalServerError, gin.H{"error": err.Error()}) + c.HTML(http.StatusInternalServerError, "error.tmpl", gin.H{"error": err.Error()}) return } - acct, err := m.db.GetAccountByID(c.Request.Context(), user.AccountID) if err != nil { m.clearSession(s) - c.JSON(http.StatusInternalServerError, gin.H{"error": err.Error()}) + c.HTML(http.StatusInternalServerError, "error.tmpl", gin.H{"error": err.Error()}) + return + } + if !ensureUserIsAuthorizedOrRedirect(c, user, acct) { return } @@ -104,13 +109,13 @@ func (m *Module) AuthorizeGETHandler(c *gin.Context) { redirect, ok := s.Get(sessionRedirectURI).(string) if !ok || redirect == "" { m.clearSession(s) - c.JSON(http.StatusInternalServerError, gin.H{"error": "no redirect_uri found in session"}) + c.HTML(http.StatusInternalServerError, "error.tmpl", gin.H{"error": "no redirect_uri found in session"}) return } scope, ok := s.Get(sessionScope).(string) if !ok || scope == "" { m.clearSession(s) - c.JSON(http.StatusInternalServerError, gin.H{"error": "no scope found in session"}) + c.HTML(http.StatusInternalServerError, "error.tmpl", gin.H{"error": "no scope found in session"}) return } @@ -170,10 +175,28 @@ func (m *Module) AuthorizePOSTHandler(c *gin.Context) { errs = append(errs, "session missing userid") } + // redirect the user if they have not confirmed their email yet, thier account has not been approved yet, + // or thier account has been disabled. + user := >smodel.User{} + if err := m.db.GetByID(c.Request.Context(), userID, user); err != nil { + m.clearSession(s) + c.HTML(http.StatusInternalServerError, "error.tmpl", gin.H{"error": err.Error()}) + return + } + acct, err := m.db.GetAccountByID(c.Request.Context(), user.AccountID) + if err != nil { + m.clearSession(s) + c.HTML(http.StatusInternalServerError, "error.tmpl", gin.H{"error": err.Error()}) + return + } + if !ensureUserIsAuthorizedOrRedirect(c, user, acct) { + return + } + m.clearSession(s) if len(errs) != 0 { - c.JSON(http.StatusBadRequest, gin.H{"error": strings.Join(errs, ": ")}) + c.HTML(http.StatusBadRequest, "error.tmpl", gin.H{"error": strings.Join(errs, ": ")}) return } @@ -190,7 +213,7 @@ func (m *Module) AuthorizePOSTHandler(c *gin.Context) { // and proceed with authorization using the oauth2 library if err := m.server.HandleAuthorizeRequest(c.Writer, c.Request); err != nil { - c.JSON(http.StatusBadRequest, gin.H{"error": err.Error()}) + c.HTML(http.StatusBadRequest, "error.tmpl", gin.H{"error": err.Error()}) } } @@ -216,3 +239,27 @@ func extractAuthForm(s sessions.Session, form *model.OAuthAuthorize) error { s.Set(sessionState, uuid.NewString()) return s.Save() } + +func ensureUserIsAuthorizedOrRedirect(ctx *gin.Context, user *gtsmodel.User, account *gtsmodel.Account) bool { + if user.ConfirmedAt.IsZero() { + ctx.Redirect(http.StatusSeeOther, CheckYourEmailPath) + return false + } + + if !user.Approved { + ctx.Redirect(http.StatusSeeOther, WaitForApprovalPath) + return false + } + + if user.Disabled { + ctx.Redirect(http.StatusSeeOther, AccountDisabledPath) + return false + } + + if !account.SuspendedAt.IsZero() { + ctx.Redirect(http.StatusSeeOther, AccountDisabledPath) + return false + } + + return true +} |