sessions/internal/router/rest/mw_auth.go
Dawid Wysokiński 8e8e7e1f94
All checks were successful
continuous-integration/drone/push Build is passing
feat: add a new REST endpoint - PUT /api/v1/user/sessions/:server (#8)
Reviewed-on: #8
2022-11-24 05:17:32 +00:00

56 lines
1.4 KiB
Go

package rest
import (
"context"
"net/http"
"gitea.dwysokinski.me/twhelp/sessions/internal/domain"
"gitea.dwysokinski.me/twhelp/sessions/internal/router/rest/internal/model"
)
type authCtxKey struct{}
//counterfeiter:generate -o internal/mock/api_key_verifier.gen.go . APIKeyVerifier
type APIKeyVerifier interface {
Verify(ctx context.Context, key string) (domain.User, error)
}
func authMiddleware(verifier APIKeyVerifier) func(http.Handler) http.Handler {
return func(next http.Handler) http.Handler {
return http.HandlerFunc(func(w http.ResponseWriter, r *http.Request) {
key := r.Header.Get("X-API-Key")
if key == "" {
renderJSON(w, http.StatusUnauthorized, model.ErrorResp{
Error: model.APIError{
Code: "unauthorized",
Message: "invalid API key",
},
})
return
}
u, err := verifier.Verify(r.Context(), key)
if err != nil {
renderJSON(w, http.StatusUnauthorized, model.ErrorResp{
Error: model.APIError{
Code: "unauthorized",
Message: "invalid API key",
},
})
return
}
next.ServeHTTP(w, r.WithContext(userToContext(r.Context(), u)))
})
}
}
func userToContext(ctx context.Context, u domain.User) context.Context {
return context.WithValue(ctx, authCtxKey{}, u)
}
func userFromContext(ctx context.Context) (domain.User, bool) {
u, ok := ctx.Value(authCtxKey{}).(domain.User)
return u, ok
}