lotus/api/auth.go

62 lines
1.5 KiB
Go

package api
import (
"crypto/subtle"
"github.com/1f349/violet/utils"
"github.com/MrMelon54/mjwt"
"github.com/MrMelon54/mjwt/auth"
"github.com/julienschmidt/httprouter"
"net/http"
)
type AuthClaims mjwt.BaseTypeClaims[auth.AccessTokenClaims]
type AuthCallback func(rw http.ResponseWriter, req *http.Request, params httprouter.Params, b AuthClaims)
type authChecker struct {
verify mjwt.Verifier
aud string
cb AuthCallback
}
func (a *authChecker) Handle(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
}
// Read claims from mjwt
_, b, err := mjwt.ExtractClaims[auth.AccessTokenClaims](a.verify, bearer)
if err != nil {
apiError(rw, http.StatusForbidden, "Invalid token")
return
}
var validAud bool
for _, i := range b.Audience {
if subtle.ConstantTimeCompare([]byte(i), []byte(a.aud)) == 1 {
validAud = true
}
}
if !validAud {
apiError(rw, http.StatusForbidden, "Invalid audience claim")
return
}
a.cb(rw, req, params, AuthClaims(b))
}
// CheckAuth validates the bearer token against a mjwt.Verifier and returns an
// error message or continues to the next handler
func CheckAuth(verify mjwt.Verifier, aud string) func(cb AuthCallback) httprouter.Handle {
return func(cb AuthCallback) httprouter.Handle {
return (&authChecker{
verify: verify,
aud: aud,
cb: cb,
}).Handle
}
}