generated from PenaSide/GolangTemplate
72 lines
1.9 KiB
Go
72 lines
1.9 KiB
Go
package utils
|
|
|
|
import (
|
|
"context"
|
|
"fmt"
|
|
"net/http"
|
|
"strings"
|
|
|
|
"github.com/deepmap/oapi-codegen/pkg/middleware"
|
|
"github.com/getkin/kin-openapi/openapi3filter"
|
|
"penahub.gitlab.yandexcloud.net/pena-services/customer/internal/errors"
|
|
"penahub.gitlab.yandexcloud.net/pena-services/customer/internal/models"
|
|
)
|
|
|
|
const (
|
|
prefix = "Bearer "
|
|
)
|
|
|
|
func NewAuthenticator(jwtUtil *JWT) openapi3filter.AuthenticationFunc {
|
|
return func(ctx context.Context, input *openapi3filter.AuthenticationInput) error {
|
|
if jwtUtil == nil {
|
|
return errors.New(
|
|
fmt.Errorf("jwt util is nil: %w", errors.ErrInvalidArgs),
|
|
errors.ErrInvalidArgs,
|
|
)
|
|
}
|
|
|
|
return authenticate(ctx, jwtUtil, input)
|
|
}
|
|
}
|
|
|
|
func authenticate(ctx context.Context, jwtUtil *JWT, input *openapi3filter.AuthenticationInput) error {
|
|
if input.SecuritySchemeName != "Bearer" {
|
|
return fmt.Errorf("security scheme %s != 'Bearer'", input.SecuritySchemeName)
|
|
}
|
|
|
|
// Now, we need to get the JWS from the request, to match the request expectations
|
|
// against request contents.
|
|
jws, err := parseJWSFromRequest(input.RequestValidationInput.Request)
|
|
if err != nil {
|
|
return err
|
|
}
|
|
|
|
// if the JWS is valid, we have a JWT, which will contain a bunch of claims.
|
|
token, validateErr := jwtUtil.Validate(jws)
|
|
if validateErr != nil {
|
|
return validateErr
|
|
}
|
|
|
|
// Set the property on the echo context so the handler is able to
|
|
// access the claims data we generate in here.
|
|
echoCtx := middleware.GetEchoContext(ctx)
|
|
|
|
echoCtx.Set(models.AuthJWTDecodedUserIDKey, token)
|
|
|
|
return nil
|
|
}
|
|
|
|
// extracts a JWS string from an Authorization: Bearer <jws> header.
|
|
func parseJWSFromRequest(request *http.Request) (string, errors.Error) {
|
|
header := request.Header.Get("Authorization")
|
|
|
|
if header == "" || !strings.HasPrefix(header, prefix) {
|
|
return "", errors.New(
|
|
fmt.Errorf("failed to parse jws from request header: %s", header),
|
|
errors.ErrNoAccess,
|
|
)
|
|
}
|
|
|
|
return strings.TrimPrefix(header, prefix), nil
|
|
}
|