pronounsfu/backend/server/auth.go

67 lines
1.4 KiB
Go

package server
import (
"context"
"net/http"
"codeberg.org/u1f320/pronouns.cc/backend/server/auth"
"github.com/go-chi/render"
)
// maybeAuth is a globally-used middleware.
func (s *Server) maybeAuth(next http.Handler) http.Handler {
fn := func(w http.ResponseWriter, r *http.Request) {
token := r.Header.Get("Authorization")
if token == "" {
next.ServeHTTP(w, r)
return
}
claims, err := s.Auth.Claims(token)
if err != nil {
render.Status(r, errCodeStatuses[ErrInvalidToken])
render.JSON(w, r, APIError{
Code: ErrInvalidToken,
Message: errCodeMessages[ErrInvalidToken],
})
return
}
ctx := context.WithValue(r.Context(), ctxKeyClaims, claims)
next.ServeHTTP(w, r.WithContext(ctx))
}
return http.HandlerFunc(fn)
}
// MustAuth makes a valid token required
func MustAuth(next http.Handler) http.Handler {
fn := func(w http.ResponseWriter, r *http.Request) {
_, ok := ClaimsFromContext(r.Context())
if !ok {
render.Status(r, errCodeStatuses[ErrForbidden])
render.JSON(w, r, APIError{
Code: ErrForbidden,
Message: errCodeMessages[ErrForbidden],
})
return
}
next.ServeHTTP(w, r)
}
return http.HandlerFunc(fn)
}
// ClaimsFromContext returns the auth.Claims in the context, if any.
func ClaimsFromContext(ctx context.Context) (auth.Claims, bool) {
v := ctx.Value(ctxKeyClaims)
if v == nil {
return auth.Claims{}, false
}
claims, ok := v.(auth.Claims)
return claims, ok
}