2023-08-21 00:26:22 +01:00
|
|
|
package api
|
|
|
|
|
|
|
|
import (
|
2023-09-11 17:23:44 +01:00
|
|
|
"errors"
|
2023-11-19 23:36:45 +00:00
|
|
|
"github.com/1f349/mjwt"
|
|
|
|
"github.com/1f349/mjwt/auth"
|
2023-08-21 00:26:22 +01:00
|
|
|
"github.com/1f349/violet/utils"
|
|
|
|
"github.com/julienschmidt/httprouter"
|
|
|
|
"net/http"
|
|
|
|
)
|
|
|
|
|
2023-11-20 07:37:25 +00:00
|
|
|
var ErrInvalidToken = errors.New("invalid token")
|
2023-09-11 17:23:44 +01:00
|
|
|
|
2023-08-21 00:26:22 +01:00
|
|
|
type AuthClaims mjwt.BaseTypeClaims[auth.AccessTokenClaims]
|
|
|
|
|
|
|
|
type AuthCallback func(rw http.ResponseWriter, req *http.Request, params httprouter.Params, b AuthClaims)
|
|
|
|
|
2023-09-11 17:23:44 +01:00
|
|
|
// AuthChecker validates the bearer token against a mjwt.Verifier and returns an
|
|
|
|
// error message or continues to the next handler
|
|
|
|
type AuthChecker struct {
|
|
|
|
Verify mjwt.Verifier
|
2023-08-21 00:26:22 +01:00
|
|
|
}
|
|
|
|
|
2023-09-11 17:23:44 +01:00
|
|
|
// Middleware is a httprouter.Handle layer to authenticate requests
|
|
|
|
func (a *AuthChecker) Middleware(cb AuthCallback) httprouter.Handle {
|
|
|
|
return func(rw http.ResponseWriter, req *http.Request, params httprouter.Params) {
|
|
|
|
// Get bearer token
|
|
|
|
bearer := utils.GetBearer(req)
|
|
|
|
if bearer == "" {
|
|
|
|
apiError(rw, http.StatusForbidden, "Missing bearer token")
|
|
|
|
return
|
|
|
|
}
|
|
|
|
|
|
|
|
b, err := a.Check(bearer)
|
|
|
|
switch {
|
|
|
|
case errors.Is(err, ErrInvalidToken):
|
|
|
|
apiError(rw, http.StatusForbidden, "Invalid token")
|
|
|
|
return
|
|
|
|
case err != nil:
|
|
|
|
apiError(rw, http.StatusForbidden, "Unknown error")
|
|
|
|
return
|
|
|
|
}
|
|
|
|
|
|
|
|
cb(rw, req, params, b)
|
2023-08-21 00:26:22 +01:00
|
|
|
}
|
2023-09-11 17:23:44 +01:00
|
|
|
}
|
2023-08-21 00:26:22 +01:00
|
|
|
|
2023-11-20 07:37:25 +00:00
|
|
|
// Check takes a token and validates whether it is verified
|
2023-09-11 17:23:44 +01:00
|
|
|
func (a *AuthChecker) Check(token string) (AuthClaims, error) {
|
2023-08-21 00:26:22 +01:00
|
|
|
// Read claims from mjwt
|
2023-09-11 17:23:44 +01:00
|
|
|
_, b, err := mjwt.ExtractClaims[auth.AccessTokenClaims](a.Verify, token)
|
2023-08-21 00:26:22 +01:00
|
|
|
if err != nil {
|
2023-09-11 17:23:44 +01:00
|
|
|
return AuthClaims{}, ErrInvalidToken
|
2023-08-21 00:26:22 +01:00
|
|
|
}
|
|
|
|
|
2023-09-11 17:23:44 +01:00
|
|
|
return AuthClaims(b), nil
|
2023-08-21 00:26:22 +01:00
|
|
|
}
|