mirror of
https://github.com/jsiebens/ionscale.git
synced 2026-03-31 15:07:49 +01:00
59 lines
1.6 KiB
Go
59 lines
1.6 KiB
Go
package server
|
|
|
|
import (
|
|
"context"
|
|
"fmt"
|
|
"github.com/bufbuild/connect-go"
|
|
"github.com/jsiebens/ionscale/internal/key"
|
|
"github.com/jsiebens/ionscale/internal/token"
|
|
apiconnect "github.com/jsiebens/ionscale/pkg/gen/ionscale/v1/ionscalev1connect"
|
|
"net/http"
|
|
"strings"
|
|
)
|
|
|
|
var (
|
|
errInvalidToken = connect.NewError(connect.CodeUnauthenticated, fmt.Errorf("invalid token"))
|
|
)
|
|
|
|
func NewRpcHandler(systemAdminKey key.ServerPrivate, handler apiconnect.IonscaleServiceHandler) (string, http.Handler) {
|
|
interceptors := connect.WithInterceptors(authenticationInterceptor(systemAdminKey))
|
|
return apiconnect.NewIonscaleServiceHandler(handler, interceptors)
|
|
}
|
|
|
|
func authenticationInterceptor(systemAdminKey key.ServerPrivate) connect.UnaryInterceptorFunc {
|
|
return func(next connect.UnaryFunc) connect.UnaryFunc {
|
|
return func(ctx context.Context, req connect.AnyRequest) (connect.AnyResponse, error) {
|
|
name := req.Spec().Procedure
|
|
|
|
if strings.HasSuffix(name, "/GetVersion") {
|
|
return next(ctx, req)
|
|
}
|
|
|
|
authorizationHeader := req.Header().Get("Authorization")
|
|
|
|
valid := validateAuthorizationToken(systemAdminKey, authorizationHeader)
|
|
|
|
if valid {
|
|
return next(ctx, req)
|
|
}
|
|
|
|
return nil, errInvalidToken
|
|
}
|
|
}
|
|
}
|
|
|
|
func validateAuthorizationToken(systemAdminKey key.ServerPrivate, authorization string) bool {
|
|
if len(authorization) == 0 {
|
|
return false
|
|
}
|
|
|
|
bearerToken := strings.TrimPrefix(authorization, "Bearer ")
|
|
|
|
if token.IsSystemAdminToken(bearerToken) {
|
|
_, err := token.ParseSystemAdminToken(systemAdminKey, bearerToken)
|
|
return err == nil
|
|
}
|
|
|
|
return false
|
|
}
|