e64f6f8569
enforces user admin role requirement for - creating / deleting / setting role for organization users - creating / deleting / setting role for project users - updating project name - deleting project hides action elements based on role for - admin console - team settings if team is only visible through project membership - add project tile if not team admin - project name text editor if not team / project admin - add redirect from team page if settings only visible through project membership - add redirect from admin console if not org admin role enforcement is handled on the api side through a custom GraphQL directive `hasRole`. on the client side, role information is fetched in the TopNavbar's `me` query and stored in the `UserContext`. there is a custom hook, `useCurrentUser`, that provides a user object with two functions, `isVisibile` & `isAdmin` which is used to check roles in order to render/hide relevant UI elements.
61 lines
1.5 KiB
Go
61 lines
1.5 KiB
Go
package route
|
|
|
|
import (
|
|
"context"
|
|
"net/http"
|
|
"strings"
|
|
|
|
"github.com/google/uuid"
|
|
"github.com/jordanknott/taskcafe/internal/auth"
|
|
log "github.com/sirupsen/logrus"
|
|
)
|
|
|
|
func AuthenticationMiddleware(next http.Handler) http.Handler {
|
|
return http.HandlerFunc(func(w http.ResponseWriter, r *http.Request) {
|
|
bearerTokenRaw := r.Header.Get("Authorization")
|
|
splitToken := strings.Split(bearerTokenRaw, "Bearer")
|
|
if len(splitToken) != 2 {
|
|
w.WriteHeader(http.StatusBadRequest)
|
|
return
|
|
}
|
|
accessTokenString := strings.TrimSpace(splitToken[1])
|
|
accessClaims, err := auth.ValidateAccessToken(accessTokenString)
|
|
if err != nil {
|
|
if _, ok := err.(*auth.ErrExpiredToken); ok {
|
|
w.WriteHeader(http.StatusUnauthorized)
|
|
w.Write([]byte(`{
|
|
"data": {},
|
|
"errors": [
|
|
{
|
|
"extensions": {
|
|
"code": "UNAUTHENTICATED"
|
|
}
|
|
}
|
|
]
|
|
}`))
|
|
return
|
|
}
|
|
log.Error(err)
|
|
w.WriteHeader(http.StatusBadRequest)
|
|
return
|
|
}
|
|
|
|
var userID uuid.UUID
|
|
if accessClaims.Restricted == auth.InstallOnly {
|
|
userID = uuid.New()
|
|
} else {
|
|
userID, err = uuid.Parse(accessClaims.UserID)
|
|
if err != nil {
|
|
log.WithError(err).Error("middleware access token userID parse")
|
|
w.WriteHeader(http.StatusBadRequest)
|
|
return
|
|
}
|
|
}
|
|
ctx := context.WithValue(r.Context(), "userID", userID)
|
|
ctx = context.WithValue(ctx, "restricted_mode", accessClaims.Restricted)
|
|
ctx = context.WithValue(ctx, "org_role", accessClaims.OrgRole)
|
|
|
|
next.ServeHTTP(w, r.WithContext(ctx))
|
|
})
|
|
}
|