summaryrefslogtreecommitdiff
path: root/internal/api/client/auth/authorize.go
diff options
context:
space:
mode:
authorLibravatar Forest Johnson <forest.n.johnson@gmail.com>2022-02-07 11:04:31 +0000
committerLibravatar GitHub <noreply@github.com>2022-02-07 12:04:31 +0100
commit6ed368cbebcae087aec1f31ee8d69ac6c47ead9f (patch)
treeab3cd855aea308e2db719f2ac67a8e38cd6c920c /internal/api/client/auth/authorize.go
parentdon't bother negotiating Accept for webfinger (#381) (diff)
downloadgotosocial-6ed368cbebcae087aec1f31ee8d69ac6c47ead9f.tar.xz
[feature] add authorization to the already-existing authentication (#365)
* add ensureUserIsAuthorizedOrRedirect to /oauth/authorize * adding authorization (email confirm, account approve, etc) to TokenCheck * revert un-needed changes to signin.go * oops what happened here * error css * add account.SuspendedAt check * remove redundant checks from oauth util Authed function * wip tests * tests passing * stop stripping useful information from ErrAlreadyExists * that feeling of scraping the dryer LINT off the screen * oops I didn't mean to get rid of this NewTestRouter function * make tests work with recorder * re-add ConfigureTemplatesWithGin to handle template path err Co-authored-by: tsmethurst <tobi.smethurst@protonmail.com>
Diffstat (limited to 'internal/api/client/auth/authorize.go')
-rw-r--r--internal/api/client/auth/authorize.go73
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 := &gtsmodel.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 := &gtsmodel.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 := &gtsmodel.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
+}