80 lines
2.2 KiB
Go
80 lines
2.2 KiB
Go
package site
|
|
|
|
import (
|
|
"context"
|
|
"errors"
|
|
"fmt"
|
|
"net/http"
|
|
"time"
|
|
|
|
"ruben/inventory2/internal/consts"
|
|
"ruben/inventory2/internal/domains/authentication"
|
|
"ruben/inventory2/internal/site/response"
|
|
)
|
|
|
|
// just keep this around long enough for testing auth middleware..
|
|
func (s *Server) testAuthEndpoint(r *http.Request) (response.Response, error) {
|
|
fmt.Println("AUTH TEST SUCCESS:", getAccessTokenClaims(r.Context()))
|
|
|
|
return response.TemporaryRedirect("/"), nil
|
|
}
|
|
|
|
type customClaimsKey struct{}
|
|
|
|
// auth middleware to verify access_token cookie and set custom claims in the request context
|
|
func (s *Server) authenticate(f response.HandlerFunc) response.HandlerFunc {
|
|
return func(r *http.Request) (response.Response, error) {
|
|
ck, err := r.Cookie("access_token")
|
|
if err != nil {
|
|
return response.TemporaryRedirect("/"), nil
|
|
}
|
|
|
|
ctx := r.Context()
|
|
|
|
claims, expiration, err := s.auth.GetAccessTokenClaimsAndExpiration(ctx, ck.Value)
|
|
if err != nil {
|
|
if errors.Is(err, consts.ErrNotFound) {
|
|
return response.TemporaryRedirect("/"), nil
|
|
}
|
|
|
|
return nil, response.Errorf("failed to authenticate: %w", err)
|
|
}
|
|
|
|
if expiration.Before(time.Now()) {
|
|
return response.TemporaryRedirect("/").Cookie(getExpiredCookie("access_token")), nil
|
|
}
|
|
|
|
return f(r.WithContext(setAccessTokenClaims(ctx, claims)))
|
|
}
|
|
}
|
|
|
|
func (s *Server) getAccessTokenClaims(r *http.Request) (authentication.AccessTokenClaims, bool) {
|
|
ck, err := r.Cookie("access_token")
|
|
if err != nil {
|
|
return authentication.AccessTokenClaims{}, false
|
|
}
|
|
|
|
ctx := r.Context()
|
|
|
|
claims, expiration, err := s.auth.GetAccessTokenClaimsAndExpiration(ctx, ck.Value)
|
|
if err != nil {
|
|
return authentication.AccessTokenClaims{}, false
|
|
}
|
|
if expiration.Before(time.Now()) {
|
|
return authentication.AccessTokenClaims{}, false
|
|
}
|
|
|
|
return claims, true
|
|
}
|
|
|
|
// stores custom claims in request context
|
|
func setAccessTokenClaims(ctx context.Context, claims authentication.AccessTokenClaims) context.Context {
|
|
return context.WithValue(ctx, customClaimsKey{}, claims)
|
|
}
|
|
|
|
// get custom claims from request context
|
|
func getAccessTokenClaims(ctx context.Context) authentication.AccessTokenClaims {
|
|
c, _ := ctx.Value(customClaimsKey{}).(authentication.AccessTokenClaims)
|
|
return c
|
|
}
|