mirror of
https://github.com/zitadel/zitadel.git
synced 2025-08-11 21:47:32 +00:00
feat: add some api packages
This commit is contained in:
34
internal/api/grpc/auth_interceptor.go
Normal file
34
internal/api/grpc/auth_interceptor.go
Normal file
@@ -0,0 +1,34 @@
|
||||
package grpc
|
||||
|
||||
import (
|
||||
"context"
|
||||
|
||||
"google.golang.org/grpc"
|
||||
"google.golang.org/grpc/codes"
|
||||
"google.golang.org/grpc/status"
|
||||
|
||||
"github.com/caos/zitadel/internal/api/auth"
|
||||
)
|
||||
|
||||
func AuthorizationInterceptor(verifier auth.TokenVerifier, authConfig *auth.Config, authMethods auth.MethodMapping) func(ctx context.Context, req interface{}, info *grpc.UnaryServerInfo, handler grpc.UnaryHandler) (interface{}, error) {
|
||||
return func(ctx context.Context, req interface{}, info *grpc.UnaryServerInfo, handler grpc.UnaryHandler) (interface{}, error) {
|
||||
authOpt, needsToken := authMethods[info.FullMethod]
|
||||
if !needsToken {
|
||||
return handler(ctx, req)
|
||||
}
|
||||
|
||||
authToken := GetAuthorizationHeader(ctx)
|
||||
if authToken == "" {
|
||||
return nil, status.Error(codes.Unauthenticated, "auth header missing")
|
||||
}
|
||||
|
||||
orgID := GetHeader(ctx, ZitadelOrgID)
|
||||
|
||||
ctx, err := auth.CheckUserAuthorization(ctx, req, authToken, orgID, verifier, authConfig, authOpt)
|
||||
if err != nil {
|
||||
return nil, err
|
||||
}
|
||||
|
||||
return handler(ctx, req)
|
||||
}
|
||||
}
|
46
internal/api/grpc/caos_errors.go
Normal file
46
internal/api/grpc/caos_errors.go
Normal file
@@ -0,0 +1,46 @@
|
||||
package grpc
|
||||
|
||||
import (
|
||||
"google.golang.org/grpc/codes"
|
||||
"google.golang.org/grpc/status"
|
||||
|
||||
caos_errs "github.com/caos/zitadel/internal/errors"
|
||||
)
|
||||
|
||||
func CaosToGRPCError(err error) error {
|
||||
if err == nil {
|
||||
return nil
|
||||
}
|
||||
code, msg, ok := extract(err)
|
||||
if !ok {
|
||||
return status.Convert(err).Err()
|
||||
}
|
||||
return status.Error(code, msg)
|
||||
}
|
||||
|
||||
func extract(err error) (c codes.Code, msg string, ok bool) {
|
||||
switch caosErr := err.(type) {
|
||||
case *caos_errs.AlreadyExistsError:
|
||||
return codes.AlreadyExists, caosErr.GetMessage(), true
|
||||
case *caos_errs.DeadlineExceededError:
|
||||
return codes.DeadlineExceeded, caosErr.GetMessage(), true
|
||||
case caos_errs.InternalError:
|
||||
return codes.Internal, caosErr.GetMessage(), true
|
||||
case *caos_errs.InvalidArgumentError:
|
||||
return codes.InvalidArgument, caosErr.GetMessage(), true
|
||||
case *caos_errs.NotFoundError:
|
||||
return codes.NotFound, caosErr.GetMessage(), true
|
||||
case *caos_errs.PermissionDeniedError:
|
||||
return codes.PermissionDenied, caosErr.GetMessage(), true
|
||||
case *caos_errs.PreconditionFailedError:
|
||||
return codes.FailedPrecondition, caosErr.GetMessage(), true
|
||||
case *caos_errs.UnauthenticatedError:
|
||||
return codes.Unauthenticated, caosErr.GetMessage(), true
|
||||
case *caos_errs.UnavailableError:
|
||||
return codes.Unavailable, caosErr.GetMessage(), true
|
||||
case *caos_errs.UnimplementedError:
|
||||
return codes.Unimplemented, caosErr.GetMessage(), true
|
||||
default:
|
||||
return codes.Unknown, err.Error(), false
|
||||
}
|
||||
}
|
14
internal/api/grpc/error_interceptor.go
Normal file
14
internal/api/grpc/error_interceptor.go
Normal file
@@ -0,0 +1,14 @@
|
||||
package grpc
|
||||
|
||||
import (
|
||||
"context"
|
||||
|
||||
"google.golang.org/grpc"
|
||||
)
|
||||
|
||||
func ErrorHandler() func(ctx context.Context, req interface{}, info *grpc.UnaryServerInfo, handler grpc.UnaryHandler) (interface{}, error) {
|
||||
return func(ctx context.Context, req interface{}, info *grpc.UnaryServerInfo, handler grpc.UnaryHandler) (interface{}, error) {
|
||||
resp, err := handler(ctx, req)
|
||||
return resp, CaosToGRPCError(err)
|
||||
}
|
||||
}
|
21
internal/api/grpc/header.go
Normal file
21
internal/api/grpc/header.go
Normal file
@@ -0,0 +1,21 @@
|
||||
package grpc
|
||||
|
||||
import (
|
||||
"context"
|
||||
|
||||
"github.com/grpc-ecosystem/go-grpc-middleware/util/metautils"
|
||||
)
|
||||
|
||||
const (
|
||||
Authorization = "authorization"
|
||||
|
||||
ZitadelOrgID = "x-zitadel-orgid"
|
||||
)
|
||||
|
||||
func GetHeader(ctx context.Context, headername string) string {
|
||||
return metautils.ExtractIncoming(ctx).Get(headername)
|
||||
}
|
||||
|
||||
func GetAuthorizationHeader(ctx context.Context) string {
|
||||
return GetHeader(ctx, Authorization)
|
||||
}
|
53
internal/api/grpc/probes.go
Normal file
53
internal/api/grpc/probes.go
Normal file
@@ -0,0 +1,53 @@
|
||||
package grpc
|
||||
|
||||
import (
|
||||
"context"
|
||||
|
||||
"github.com/caos/logging"
|
||||
"github.com/golang/protobuf/ptypes/empty"
|
||||
structpb "github.com/golang/protobuf/ptypes/struct"
|
||||
|
||||
"github.com/caos/zitadel/internal/errors"
|
||||
"github.com/caos/zitadel/internal/proto"
|
||||
)
|
||||
|
||||
type ValidationFunction func(ctx context.Context) error
|
||||
|
||||
type Validator struct {
|
||||
validations map[string]ValidationFunction
|
||||
}
|
||||
|
||||
func NewValidator(validations map[string]ValidationFunction) *Validator {
|
||||
return &Validator{validations: validations}
|
||||
}
|
||||
|
||||
func (v *Validator) Healthz(_ context.Context, e *empty.Empty) (*empty.Empty, error) {
|
||||
return e, nil
|
||||
}
|
||||
|
||||
func (v *Validator) Ready(ctx context.Context, e *empty.Empty) (*empty.Empty, error) {
|
||||
return e, ready(ctx, v.validations)
|
||||
}
|
||||
|
||||
func (v *Validator) Validate(ctx context.Context, _ *empty.Empty) (*structpb.Struct, error) {
|
||||
validations := validate(ctx, v.validations)
|
||||
return proto.ToPBStruct(validations)
|
||||
}
|
||||
|
||||
func ready(ctx context.Context, validations map[string]ValidationFunction) error {
|
||||
if len(validate(ctx, validations)) == 0 {
|
||||
return nil
|
||||
}
|
||||
return errors.ThrowInternal(nil, "API-2jD9a", "not ready")
|
||||
}
|
||||
|
||||
func validate(ctx context.Context, validations map[string]ValidationFunction) map[string]error {
|
||||
errors := make(map[string]error)
|
||||
for id, validation := range validations {
|
||||
if err := validation(ctx); err != nil {
|
||||
logging.Log("API-vf823").WithError(err).Error("validation failed")
|
||||
errors[id] = err
|
||||
}
|
||||
}
|
||||
return errors
|
||||
}
|
Reference in New Issue
Block a user