mirror of
https://github.com/zitadel/zitadel.git
synced 2025-08-12 01:37:31 +00:00
feat: add new api services (#5619)
* feat: add new services * improve demos and comments * remove unused field * add comment to demo proto calls * Apply suggestions from code review Co-authored-by: Silvan <silvan.reusser@gmail.com> --------- Co-authored-by: Silvan <silvan.reusser@gmail.com>
This commit is contained in:
@@ -78,8 +78,8 @@ func (s *Server) AuthMethods() authz.MethodMapping {
|
||||
return admin.AdminService_AuthMethods
|
||||
}
|
||||
|
||||
func (s *Server) RegisterGateway() server.GatewayFunc {
|
||||
return admin.RegisterAdminServiceHandlerFromEndpoint
|
||||
func (s *Server) RegisterGateway() server.RegisterGatewayFunc {
|
||||
return admin.RegisterAdminServiceHandler
|
||||
}
|
||||
|
||||
func (s *Server) GatewayPathPrefix() string {
|
||||
|
@@ -76,8 +76,8 @@ func (s *Server) AuthMethods() authz.MethodMapping {
|
||||
return auth.AuthService_AuthMethods
|
||||
}
|
||||
|
||||
func (s *Server) RegisterGateway() server.GatewayFunc {
|
||||
return auth.RegisterAuthServiceHandlerFromEndpoint
|
||||
func (s *Server) RegisterGateway() server.RegisterGatewayFunc {
|
||||
return auth.RegisterAuthServiceHandler
|
||||
}
|
||||
|
||||
func (s *Server) GatewayPathPrefix() string {
|
||||
|
@@ -70,8 +70,8 @@ func (s *Server) AuthMethods() authz.MethodMapping {
|
||||
return management.ManagementService_AuthMethods
|
||||
}
|
||||
|
||||
func (s *Server) RegisterGateway() server.GatewayFunc {
|
||||
return management.RegisterManagementServiceHandlerFromEndpoint
|
||||
func (s *Server) RegisterGateway() server.RegisterGatewayFunc {
|
||||
return management.RegisterManagementServiceHandler
|
||||
}
|
||||
|
||||
func (s *Server) GatewayPathPrefix() string {
|
||||
|
@@ -7,8 +7,10 @@ import (
|
||||
"strings"
|
||||
|
||||
"github.com/grpc-ecosystem/grpc-gateway/v2/runtime"
|
||||
"github.com/zitadel/logging"
|
||||
"google.golang.org/grpc"
|
||||
"google.golang.org/grpc/credentials/insecure"
|
||||
healthpb "google.golang.org/grpc/health/grpc_health_v1"
|
||||
"google.golang.org/protobuf/encoding/protojson"
|
||||
|
||||
client_middleware "github.com/zitadel/zitadel/internal/api/grpc/client/middleware"
|
||||
@@ -50,26 +52,84 @@ var (
|
||||
)
|
||||
)
|
||||
|
||||
type Gateway interface {
|
||||
RegisterGateway() GatewayFunc
|
||||
GatewayPathPrefix() string
|
||||
type Gateway struct {
|
||||
mux *runtime.ServeMux
|
||||
http1HostName string
|
||||
connection *grpc.ClientConn
|
||||
}
|
||||
|
||||
type GatewayFunc func(ctx context.Context, mux *runtime.ServeMux, endpoint string, opts []grpc.DialOption) error
|
||||
func (g *Gateway) Handler() http.Handler {
|
||||
return addInterceptors(g.mux, g.http1HostName)
|
||||
}
|
||||
|
||||
func CreateGateway(ctx context.Context, g Gateway, port uint16, http1HostName string) (http.Handler, string, error) {
|
||||
type RegisterGatewayFunc func(ctx context.Context, mux *runtime.ServeMux, conn *grpc.ClientConn) error
|
||||
|
||||
func CreateGatewayWithPrefix(ctx context.Context, g WithGatewayPrefix, port uint16, http1HostName string) (http.Handler, string, error) {
|
||||
runtimeMux := runtime.NewServeMux(serveMuxOptions...)
|
||||
opts := []grpc.DialOption{
|
||||
grpc.WithTransportCredentials(insecure.NewCredentials()),
|
||||
grpc.WithUnaryInterceptor(client_middleware.DefaultTracingClient()),
|
||||
}
|
||||
err := g.RegisterGateway()(ctx, runtimeMux, fmt.Sprintf("localhost:%d", port), opts)
|
||||
connection, err := dial(ctx, port, opts)
|
||||
if err != nil {
|
||||
return nil, "", err
|
||||
}
|
||||
err = g.RegisterGateway()(ctx, runtimeMux, connection)
|
||||
if err != nil {
|
||||
return nil, "", fmt.Errorf("failed to register grpc gateway: %w", err)
|
||||
}
|
||||
return addInterceptors(runtimeMux, http1HostName), g.GatewayPathPrefix(), nil
|
||||
}
|
||||
|
||||
func CreateGateway(ctx context.Context, port uint16, http1HostName string) (*Gateway, error) {
|
||||
connection, err := dial(ctx,
|
||||
port,
|
||||
[]grpc.DialOption{
|
||||
grpc.WithTransportCredentials(insecure.NewCredentials()),
|
||||
grpc.WithUnaryInterceptor(client_middleware.DefaultTracingClient()),
|
||||
})
|
||||
if err != nil {
|
||||
return nil, err
|
||||
}
|
||||
runtimeMux := runtime.NewServeMux(append(serveMuxOptions, runtime.WithHealthzEndpoint(healthpb.NewHealthClient(connection)))...)
|
||||
return &Gateway{
|
||||
mux: runtimeMux,
|
||||
http1HostName: http1HostName,
|
||||
connection: connection,
|
||||
}, nil
|
||||
}
|
||||
|
||||
func RegisterGateway(ctx context.Context, gateway *Gateway, server Server) error {
|
||||
err := server.RegisterGateway()(ctx, gateway.mux, gateway.connection)
|
||||
if err != nil {
|
||||
return fmt.Errorf("failed to register grpc gateway: %w", err)
|
||||
}
|
||||
return nil
|
||||
}
|
||||
|
||||
func dial(ctx context.Context, port uint16, opts []grpc.DialOption) (*grpc.ClientConn, error) {
|
||||
endpoint := fmt.Sprintf("localhost:%d", port)
|
||||
conn, err := grpc.Dial(endpoint, opts...)
|
||||
if err != nil {
|
||||
return nil, err
|
||||
}
|
||||
defer func() {
|
||||
if err != nil {
|
||||
if cerr := conn.Close(); cerr != nil {
|
||||
logging.Infof("Failed to close conn to %s: %v", endpoint, cerr)
|
||||
}
|
||||
return
|
||||
}
|
||||
go func() {
|
||||
<-ctx.Done()
|
||||
if cerr := conn.Close(); cerr != nil {
|
||||
logging.Infof("Failed to close conn to %s: %v", endpoint, cerr)
|
||||
}
|
||||
}()
|
||||
}()
|
||||
return conn, nil
|
||||
}
|
||||
|
||||
func addInterceptors(handler http.Handler, http1HostName string) http.Handler {
|
||||
handler = http_mw.CallDurationHandler(handler)
|
||||
handler = http1Host(handler, http1HostName)
|
||||
|
@@ -3,14 +3,18 @@ package middleware
|
||||
import (
|
||||
"context"
|
||||
|
||||
"google.golang.org/grpc"
|
||||
|
||||
"github.com/zitadel/zitadel/internal/api/service"
|
||||
_ "github.com/zitadel/zitadel/internal/statik"
|
||||
"google.golang.org/grpc"
|
||||
)
|
||||
|
||||
func ServiceHandler() grpc.UnaryServerInterceptor {
|
||||
return func(ctx context.Context, req interface{}, info *grpc.UnaryServerInfo, handler grpc.UnaryHandler) (interface{}, error) {
|
||||
namer := info.Server.(interface{ AppName() string })
|
||||
namer, ok := info.Server.(interface{ AppName() string })
|
||||
if !ok {
|
||||
return handler(ctx, req)
|
||||
}
|
||||
ctx = service.WithService(ctx, namer.AppName())
|
||||
return handler(ctx, req)
|
||||
}
|
||||
|
@@ -2,9 +2,11 @@ package server
|
||||
|
||||
import (
|
||||
"crypto/tls"
|
||||
|
||||
grpc_middleware "github.com/grpc-ecosystem/go-grpc-middleware"
|
||||
"google.golang.org/grpc"
|
||||
"google.golang.org/grpc/credentials"
|
||||
healthpb "google.golang.org/grpc/health/grpc_health_v1"
|
||||
|
||||
"github.com/zitadel/zitadel/internal/api/authz"
|
||||
grpc_api "github.com/zitadel/zitadel/internal/api/grpc"
|
||||
@@ -16,13 +18,21 @@ import (
|
||||
)
|
||||
|
||||
type Server interface {
|
||||
Gateway
|
||||
RegisterServer(*grpc.Server)
|
||||
RegisterGateway() RegisterGatewayFunc
|
||||
AppName() string
|
||||
MethodPrefix() string
|
||||
AuthMethods() authz.MethodMapping
|
||||
}
|
||||
|
||||
// WithGatewayPrefix extends the server interface with a prefix for the grpc gateway
|
||||
//
|
||||
// it's used for the System, Admin, Mgmt and Auth API
|
||||
type WithGatewayPrefix interface {
|
||||
Server
|
||||
GatewayPathPrefix() string
|
||||
}
|
||||
|
||||
func CreateServer(
|
||||
verifier *authz.TokenVerifier,
|
||||
authConfig authz.Config,
|
||||
@@ -40,7 +50,7 @@ func CreateServer(
|
||||
middleware.MetricsHandler(metricTypes, grpc_api.Probes...),
|
||||
middleware.NoCacheInterceptor(),
|
||||
middleware.ErrorHandler(),
|
||||
middleware.InstanceInterceptor(queries, hostHeaderName, system_pb.SystemService_MethodPrefix),
|
||||
middleware.InstanceInterceptor(queries, hostHeaderName, system_pb.SystemService_MethodPrefix, healthpb.Health_ServiceDesc.ServiceName),
|
||||
middleware.AccessStorageInterceptor(accessSvc),
|
||||
middleware.AuthorizationInterceptor(verifier, authConfig),
|
||||
middleware.TranslationHandler(),
|
||||
|
51
internal/api/grpc/session/v2/server.go
Normal file
51
internal/api/grpc/session/v2/server.go
Normal file
@@ -0,0 +1,51 @@
|
||||
package session
|
||||
|
||||
import (
|
||||
"google.golang.org/grpc"
|
||||
|
||||
"github.com/zitadel/zitadel/internal/api/authz"
|
||||
"github.com/zitadel/zitadel/internal/api/grpc/server"
|
||||
"github.com/zitadel/zitadel/internal/command"
|
||||
"github.com/zitadel/zitadel/internal/query"
|
||||
"github.com/zitadel/zitadel/pkg/grpc/session/v2alpha"
|
||||
)
|
||||
|
||||
var _ session.SessionServiceServer = (*Server)(nil)
|
||||
|
||||
type Server struct {
|
||||
session.UnimplementedSessionServiceServer
|
||||
command *command.Commands
|
||||
query *query.Queries
|
||||
}
|
||||
|
||||
type Config struct{}
|
||||
|
||||
func CreateServer(
|
||||
command *command.Commands,
|
||||
query *query.Queries,
|
||||
) *Server {
|
||||
return &Server{
|
||||
command: command,
|
||||
query: query,
|
||||
}
|
||||
}
|
||||
|
||||
func (s *Server) RegisterServer(grpcServer *grpc.Server) {
|
||||
session.RegisterSessionServiceServer(grpcServer, s)
|
||||
}
|
||||
|
||||
func (s *Server) AppName() string {
|
||||
return session.SessionService_ServiceDesc.ServiceName
|
||||
}
|
||||
|
||||
func (s *Server) MethodPrefix() string {
|
||||
return session.SessionService_ServiceDesc.ServiceName
|
||||
}
|
||||
|
||||
func (s *Server) AuthMethods() authz.MethodMapping {
|
||||
return session.SessionService_AuthMethods
|
||||
}
|
||||
|
||||
func (s *Server) RegisterGateway() server.RegisterGatewayFunc {
|
||||
return session.RegisterSessionServiceHandler
|
||||
}
|
18
internal/api/grpc/session/v2/session.go
Normal file
18
internal/api/grpc/session/v2/session.go
Normal file
@@ -0,0 +1,18 @@
|
||||
package session
|
||||
|
||||
import (
|
||||
"context"
|
||||
|
||||
"github.com/zitadel/zitadel/internal/api/authz"
|
||||
"github.com/zitadel/zitadel/pkg/grpc/session/v2alpha"
|
||||
"github.com/zitadel/zitadel/pkg/grpc/user/v2alpha"
|
||||
)
|
||||
|
||||
func (s *Server) GetSession(ctx context.Context, req *session.GetSessionRequest) (*session.GetSessionResponse, error) {
|
||||
return &session.GetSessionResponse{
|
||||
Session: &session.Session{
|
||||
Id: req.Id,
|
||||
User: &user.User{Id: authz.GetCtxData(ctx).UserID},
|
||||
},
|
||||
}, nil
|
||||
}
|
@@ -67,8 +67,8 @@ func (s *Server) AuthMethods() authz.MethodMapping {
|
||||
return system.SystemService_AuthMethods
|
||||
}
|
||||
|
||||
func (s *Server) RegisterGateway() server.GatewayFunc {
|
||||
return system.RegisterSystemServiceHandlerFromEndpoint
|
||||
func (s *Server) RegisterGateway() server.RegisterGatewayFunc {
|
||||
return system.RegisterSystemServiceHandler
|
||||
}
|
||||
|
||||
func (s *Server) GatewayPathPrefix() string {
|
||||
|
51
internal/api/grpc/user/v2/server.go
Normal file
51
internal/api/grpc/user/v2/server.go
Normal file
@@ -0,0 +1,51 @@
|
||||
package user
|
||||
|
||||
import (
|
||||
"google.golang.org/grpc"
|
||||
|
||||
"github.com/zitadel/zitadel/internal/api/authz"
|
||||
"github.com/zitadel/zitadel/internal/api/grpc/server"
|
||||
"github.com/zitadel/zitadel/internal/command"
|
||||
"github.com/zitadel/zitadel/internal/query"
|
||||
"github.com/zitadel/zitadel/pkg/grpc/user/v2alpha"
|
||||
)
|
||||
|
||||
var _ user.UserServiceServer = (*Server)(nil)
|
||||
|
||||
type Server struct {
|
||||
user.UnimplementedUserServiceServer
|
||||
command *command.Commands
|
||||
query *query.Queries
|
||||
}
|
||||
|
||||
type Config struct{}
|
||||
|
||||
func CreateServer(
|
||||
command *command.Commands,
|
||||
query *query.Queries,
|
||||
) *Server {
|
||||
return &Server{
|
||||
command: command,
|
||||
query: query,
|
||||
}
|
||||
}
|
||||
|
||||
func (s *Server) RegisterServer(grpcServer *grpc.Server) {
|
||||
user.RegisterUserServiceServer(grpcServer, s)
|
||||
}
|
||||
|
||||
func (s *Server) AppName() string {
|
||||
return user.UserService_ServiceDesc.ServiceName
|
||||
}
|
||||
|
||||
func (s *Server) MethodPrefix() string {
|
||||
return user.UserService_ServiceDesc.ServiceName
|
||||
}
|
||||
|
||||
func (s *Server) AuthMethods() authz.MethodMapping {
|
||||
return user.UserService_AuthMethods
|
||||
}
|
||||
|
||||
func (s *Server) RegisterGateway() server.RegisterGatewayFunc {
|
||||
return user.RegisterUserServiceHandler
|
||||
}
|
55
internal/api/grpc/user/v2/test.go
Normal file
55
internal/api/grpc/user/v2/test.go
Normal file
@@ -0,0 +1,55 @@
|
||||
package user
|
||||
|
||||
import (
|
||||
"context"
|
||||
|
||||
"github.com/zitadel/zitadel/internal/api/authz"
|
||||
"github.com/zitadel/zitadel/internal/errors"
|
||||
"github.com/zitadel/zitadel/pkg/grpc/user/v2alpha"
|
||||
)
|
||||
|
||||
func (s *Server) TestGet(ctx context.Context, req *user.TestGetRequest) (*user.TestGetResponse, error) {
|
||||
return &user.TestGetResponse{
|
||||
Ctx: req.Ctx.String(),
|
||||
}, nil
|
||||
}
|
||||
|
||||
func (s *Server) TestPost(ctx context.Context, req *user.TestPostRequest) (*user.TestPostResponse, error) {
|
||||
return &user.TestPostResponse{
|
||||
Ctx: req.Ctx.String(),
|
||||
}, nil
|
||||
}
|
||||
|
||||
func (s *Server) TestAuth(ctx context.Context, req *user.TestAuthRequest) (*user.TestAuthResponse, error) {
|
||||
reqCtx, err := authDemo(ctx, req.Ctx)
|
||||
if err != nil {
|
||||
return nil, err
|
||||
}
|
||||
return &user.TestAuthResponse{
|
||||
User: &user.User{Id: authz.GetCtxData(ctx).UserID},
|
||||
Ctx: reqCtx,
|
||||
}, nil
|
||||
}
|
||||
|
||||
func authDemo(ctx context.Context, reqCtx *user.Context) (*user.Context, error) {
|
||||
ro := authz.GetCtxData(ctx).ResourceOwner
|
||||
if reqCtx == nil {
|
||||
return &user.Context{Ctx: &user.Context_OrgId{OrgId: ro}}, nil
|
||||
}
|
||||
switch c := reqCtx.Ctx.(type) {
|
||||
case *user.Context_OrgId:
|
||||
if c.OrgId == ro {
|
||||
return reqCtx, nil
|
||||
}
|
||||
return nil, errors.ThrowPermissionDenied(nil, "USER-dg4g", "Errors.User.NotAllowedOrg")
|
||||
case *user.Context_OrgDomain:
|
||||
if c.OrgDomain == "forbidden.com" {
|
||||
return nil, errors.ThrowPermissionDenied(nil, "USER-SDg4g", "Errors.User.NotAllowedOrg")
|
||||
}
|
||||
return reqCtx, nil
|
||||
case *user.Context_Instance:
|
||||
return reqCtx, nil
|
||||
default:
|
||||
return reqCtx, nil
|
||||
}
|
||||
}
|
Reference in New Issue
Block a user