mirror of
https://github.com/zitadel/zitadel.git
synced 2025-08-12 03:47:33 +00:00
feat: protos refactoring
* start with user * user first try done in all services * user, org, idp for discussion * remove unused stuff * bla * dockerbuild * rename search, get multiple to list... * add annotation * update proto dependencies * update proto dependencies * change proto imports * replace all old imports * fix go out * remove unused lines * correct protoc flags * grpc and openapi flags * go out source path relative * -p * remove dead code * sourcepath relative * ls * is onenapi the problem? * hobla * authoption output * wrong field name * gopf * correct option, add correct flags * small improvments * SIMPLYFY * relative path * gopf bin ich en tubel * correct path * default policies in admin * grpc generation in one file * remove non ascii * metadata on manipulations * correct auth_option import * fixes * larry * idp provider to idp * fix generate * admin and auth nearly done * admin and auth nearly done * gen * healthz * imports * deleted too much imports * fix org * add import * imports * import * naming * auth_opt * gopf * management * imports * _TYPE_UNSPECIFIED * improts * auth opts * management policies * imports * passwordlessType to MFAType * auth_opt * add user grant calls * add missing messages * result * fix option * improvements * ids * fix http * imports * fixes * fields * body * add fields * remove wrong member query * fix request response * fixes * add copy files * variable versions * generate all files * improvements * add dependencies * factors * user session * oidc information, iam * remove unused file * changes * enums * dockerfile * fix build * remove unused folder * update readme for build * move old server impl * add event type to change * some changes * start admin * remove wrong field * admin only list calls missing * fix proto numbers * surprisingly it compiles * service ts changes * admin mgmt * mgmt * auth manipulation and gets done, lists missing * validations and some field changes * validations * enum validations * remove todo * move proto files to proto/zitadel * change proto path in dockerfile * it compiles! * add validate import * remove duplicate import * fix protos * fix import * tests * cleanup * remove unimplemented methods * iam member multiple queries * all auth and admin calls * add initial password on crate human * message names * management user server * machine done * fix: todos (#1346) * fix: pub sub in new eventstore * fix: todos * fix: todos * fix: todos * fix: todos * fix: todos * fix tests * fix: search method domain * admin service, user import type typescript * admin changes * admin changes * fix: search method domain * more user grpc and begin org, fix configs * fix: return object details * org grpc * remove creation date add details * app * fix: return object details * fix: return object details * mgmt service, project members * app * fix: convert policies * project, members, granted projects, searches * fix: convert usergrants * fix: convert usergrants * auth user detail, user detail, mfa, second factor, auth * fix: convert usergrants * mfa, memberships, password, owned proj detail * fix: convert usergrants * project grant * missing details * changes, userview * idp table, keys * org list and user table filter * unify rest paths (#1381) * unify rest paths * post for all searches, mfa to multi_factor, secondfactor to second_factor * remove v1 * fix tests * rename api client key to app key * machine keys, age policy * user list, machine keys, changes * fix: org states * add default flag to policy * second factor to type * idp id * app type * unify ListQuery, ListDetails, ObjectDetails field names * user grants, apps, memberships * fix type params * metadata to detail, linke idps * api create, membership, app detail, create * idp, app, policy * queries, multi -> auth factors and missing fields * update converters * provider to user, remove old mgmt refs * temp remove authfactor dialog, build finish Co-authored-by: Max Peintner <max@caos.ch> Co-authored-by: Fabi <38692350+fgerschwiler@users.noreply.github.com> Co-authored-by: Livio Amstutz <livio.a@gmail.com> Co-authored-by: Fabiennne <fabienne.gerschwiler@gmail.com>
This commit is contained in:
61
internal/api/grpc/auth/email.go
Normal file
61
internal/api/grpc/auth/email.go
Normal file
@@ -0,0 +1,61 @@
|
||||
package auth
|
||||
|
||||
import (
|
||||
"context"
|
||||
|
||||
"github.com/caos/zitadel/internal/api/authz"
|
||||
"github.com/caos/zitadel/internal/api/grpc/object"
|
||||
"github.com/caos/zitadel/internal/api/grpc/user"
|
||||
auth_pb "github.com/caos/zitadel/pkg/grpc/auth"
|
||||
)
|
||||
|
||||
func (s *Server) GetMyEmail(ctx context.Context, _ *auth_pb.GetMyEmailRequest) (*auth_pb.GetMyEmailResponse, error) {
|
||||
email, err := s.repo.MyEmail(ctx)
|
||||
if err != nil {
|
||||
return nil, err
|
||||
}
|
||||
return &auth_pb.GetMyEmailResponse{
|
||||
Email: user.ModelEmailToPb(email),
|
||||
Details: object.ToDetailsPb(
|
||||
email.Sequence,
|
||||
email.ChangeDate,
|
||||
email.ResourceOwner,
|
||||
),
|
||||
}, nil
|
||||
}
|
||||
|
||||
func (s *Server) SetMyEmail(ctx context.Context, req *auth_pb.SetMyEmailRequest) (*auth_pb.SetMyEmailResponse, error) {
|
||||
email, err := s.command.ChangeHumanEmail(ctx, UpdateMyEmailToDomain(ctx, req))
|
||||
if err != nil {
|
||||
return nil, err
|
||||
}
|
||||
return &auth_pb.SetMyEmailResponse{
|
||||
Details: object.ToDetailsPb(
|
||||
email.Sequence,
|
||||
email.ChangeDate,
|
||||
email.ResourceOwner,
|
||||
),
|
||||
}, nil
|
||||
}
|
||||
|
||||
func (s *Server) VerifyMyEmail(ctx context.Context, req *auth_pb.VerifyMyEmailRequest) (*auth_pb.VerifyMyEmailResponse, error) {
|
||||
ctxData := authz.GetCtxData(ctx)
|
||||
objectDetails, err := s.command.VerifyHumanEmail(ctx, ctxData.UserID, req.Code, ctxData.OrgID)
|
||||
if err != nil {
|
||||
return nil, err
|
||||
}
|
||||
return &auth_pb.VerifyMyEmailResponse{
|
||||
Details: object.DomainToDetailsPb(objectDetails),
|
||||
}, nil
|
||||
}
|
||||
|
||||
func (s *Server) ResendMyEmailVerification(ctx context.Context, _ *auth_pb.ResendMyEmailVerificationRequest) (*auth_pb.ResendMyEmailVerificationResponse, error) {
|
||||
ctxData := authz.GetCtxData(ctx)
|
||||
objectDetails, err := s.command.CreateHumanEmailVerificationCode(ctx, ctxData.UserID, ctxData.ResourceOwner)
|
||||
if err != nil {
|
||||
return nil, err
|
||||
}
|
||||
return &auth_pb.ResendMyEmailVerificationResponse{
|
||||
Details: object.DomainToDetailsPb(objectDetails),
|
||||
}, nil
|
||||
}
|
15
internal/api/grpc/auth/email_converter.go
Normal file
15
internal/api/grpc/auth/email_converter.go
Normal file
@@ -0,0 +1,15 @@
|
||||
package auth
|
||||
|
||||
import (
|
||||
"context"
|
||||
|
||||
"github.com/caos/zitadel/internal/domain"
|
||||
"github.com/caos/zitadel/pkg/grpc/auth"
|
||||
)
|
||||
|
||||
func UpdateMyEmailToDomain(ctx context.Context, email *auth.SetMyEmailRequest) *domain.Email {
|
||||
return &domain.Email{
|
||||
ObjectRoot: ctxToObjectRoot(ctx),
|
||||
EmailAddress: email.Email,
|
||||
}
|
||||
}
|
@@ -1,50 +0,0 @@
|
||||
package auth
|
||||
|
||||
import (
|
||||
"strings"
|
||||
|
||||
"github.com/grpc-ecosystem/grpc-gateway/runtime"
|
||||
|
||||
grpc_util "github.com/caos/zitadel/internal/api/grpc"
|
||||
"github.com/caos/zitadel/internal/api/grpc/server"
|
||||
"github.com/caos/zitadel/pkg/grpc/auth"
|
||||
)
|
||||
|
||||
type Gateway struct {
|
||||
grpcEndpoint string
|
||||
port string
|
||||
cutomHeaders []string
|
||||
}
|
||||
|
||||
func StartGateway(conf grpc_util.GatewayConfig) *Gateway {
|
||||
return &Gateway{
|
||||
grpcEndpoint: conf.GRPCEndpoint,
|
||||
port: conf.Port,
|
||||
cutomHeaders: conf.CustomHeaders,
|
||||
}
|
||||
}
|
||||
|
||||
func (gw *Gateway) Gateway() server.GatewayFunc {
|
||||
return auth.RegisterAuthServiceHandlerFromEndpoint
|
||||
}
|
||||
|
||||
func (gw *Gateway) GRPCEndpoint() string {
|
||||
return ":" + gw.grpcEndpoint
|
||||
}
|
||||
|
||||
func (gw *Gateway) GatewayPort() string {
|
||||
return gw.port
|
||||
}
|
||||
|
||||
func (gw *Gateway) GatewayServeMuxOptions() []runtime.ServeMuxOption {
|
||||
return []runtime.ServeMuxOption{
|
||||
runtime.WithIncomingHeaderMatcher(func(header string) (string, bool) {
|
||||
for _, customHeader := range gw.cutomHeaders {
|
||||
if strings.HasPrefix(strings.ToLower(header), customHeader) {
|
||||
return header, true
|
||||
}
|
||||
}
|
||||
return runtime.DefaultHeaderMatcher(header)
|
||||
}),
|
||||
}
|
||||
}
|
34
internal/api/grpc/auth/idp.go
Normal file
34
internal/api/grpc/auth/idp.go
Normal file
@@ -0,0 +1,34 @@
|
||||
package auth
|
||||
|
||||
import (
|
||||
"context"
|
||||
|
||||
idp_grpc "github.com/caos/zitadel/internal/api/grpc/idp"
|
||||
"github.com/caos/zitadel/internal/api/grpc/object"
|
||||
auth_pb "github.com/caos/zitadel/pkg/grpc/auth"
|
||||
)
|
||||
|
||||
func (s *Server) ListMyLinkedIDPs(ctx context.Context, req *auth_pb.ListMyLinkedIDPsRequest) (*auth_pb.ListMyLinkedIDPsResponse, error) {
|
||||
idps, err := s.repo.SearchMyExternalIDPs(ctx, ListMyLinkedIDPsRequestToModel(req))
|
||||
if err != nil {
|
||||
return nil, err
|
||||
}
|
||||
return &auth_pb.ListMyLinkedIDPsResponse{
|
||||
Result: idp_grpc.IDPsToUserLinkPb(idps.Result),
|
||||
Details: object.ToListDetails(
|
||||
idps.TotalResult,
|
||||
idps.Sequence,
|
||||
idps.Timestamp,
|
||||
),
|
||||
}, nil
|
||||
}
|
||||
|
||||
func (s *Server) RemoveMyLinkedIDP(ctx context.Context, req *auth_pb.RemoveMyLinkedIDPRequest) (*auth_pb.RemoveMyLinkedIDPResponse, error) {
|
||||
objectDetails, err := s.command.RemoveHumanExternalIDP(ctx, RemoveMyLinkedIDPRequestToDomain(ctx, req))
|
||||
if err != nil {
|
||||
return nil, err
|
||||
}
|
||||
return &auth_pb.RemoveMyLinkedIDPResponse{
|
||||
Details: object.DomainToDetailsPb(objectDetails),
|
||||
}, nil
|
||||
}
|
24
internal/api/grpc/auth/idp_converter.go
Normal file
24
internal/api/grpc/auth/idp_converter.go
Normal file
@@ -0,0 +1,24 @@
|
||||
package auth
|
||||
|
||||
import (
|
||||
"context"
|
||||
|
||||
"github.com/caos/zitadel/internal/domain"
|
||||
"github.com/caos/zitadel/internal/user/model"
|
||||
auth_pb "github.com/caos/zitadel/pkg/grpc/auth"
|
||||
)
|
||||
|
||||
func ListMyLinkedIDPsRequestToModel(req *auth_pb.ListMyLinkedIDPsRequest) *model.ExternalIDPSearchRequest {
|
||||
return &model.ExternalIDPSearchRequest{
|
||||
Offset: req.Query.Offset,
|
||||
Limit: uint64(req.Query.Limit),
|
||||
}
|
||||
}
|
||||
|
||||
func RemoveMyLinkedIDPRequestToDomain(ctx context.Context, req *auth_pb.RemoveMyLinkedIDPRequest) *domain.ExternalIDP {
|
||||
return &domain.ExternalIDP{
|
||||
ObjectRoot: ctxToObjectRoot(ctx),
|
||||
IDPConfigID: req.IdpId,
|
||||
ExternalUserID: req.LinkedUserId,
|
||||
}
|
||||
}
|
11
internal/api/grpc/auth/information.go
Normal file
11
internal/api/grpc/auth/information.go
Normal file
@@ -0,0 +1,11 @@
|
||||
package auth
|
||||
|
||||
import (
|
||||
"context"
|
||||
|
||||
"github.com/caos/zitadel/pkg/grpc/auth"
|
||||
)
|
||||
|
||||
func (s *Server) Healthz(context.Context, *auth.HealthzRequest) (*auth.HealthzResponse, error) {
|
||||
return &auth.HealthzResponse{}, nil
|
||||
}
|
101
internal/api/grpc/auth/multi_factor.go
Normal file
101
internal/api/grpc/auth/multi_factor.go
Normal file
@@ -0,0 +1,101 @@
|
||||
package auth
|
||||
|
||||
import (
|
||||
"context"
|
||||
|
||||
"github.com/caos/zitadel/internal/api/authz"
|
||||
"github.com/caos/zitadel/internal/api/grpc/object"
|
||||
user_grpc "github.com/caos/zitadel/internal/api/grpc/user"
|
||||
auth_pb "github.com/caos/zitadel/pkg/grpc/auth"
|
||||
user_pb "github.com/caos/zitadel/pkg/grpc/user"
|
||||
)
|
||||
|
||||
func (s *Server) ListMyAuthFactors(ctx context.Context, _ *auth_pb.ListMyAuthFactorsRequest) (*auth_pb.ListMyAuthFactorsResponse, error) {
|
||||
mfas, err := s.repo.MyUserMFAs(ctx)
|
||||
if err != nil {
|
||||
return nil, err
|
||||
}
|
||||
return &auth_pb.ListMyAuthFactorsResponse{
|
||||
Result: user_grpc.AuthFactorsToPb(mfas),
|
||||
}, nil
|
||||
}
|
||||
|
||||
func (s *Server) AddMyAuthFactorOTP(ctx context.Context, _ *auth_pb.AddMyAuthFactorOTPRequest) (*auth_pb.AddMyAuthFactorOTPResponse, error) {
|
||||
ctxData := authz.GetCtxData(ctx)
|
||||
otp, err := s.command.AddHumanOTP(ctx, ctxData.UserID, ctxData.OrgID)
|
||||
if err != nil {
|
||||
return nil, err
|
||||
}
|
||||
return &auth_pb.AddMyAuthFactorOTPResponse{
|
||||
Url: otp.Url,
|
||||
Secret: otp.SecretString,
|
||||
Details: object.ToDetailsPb(
|
||||
otp.Sequence,
|
||||
otp.ChangeDate,
|
||||
otp.ResourceOwner,
|
||||
),
|
||||
}, nil
|
||||
}
|
||||
|
||||
func (s *Server) VerifyMyAuthFactorOTP(ctx context.Context, req *auth_pb.VerifyMyAuthFactorOTPRequest) (*auth_pb.VerifyMyAuthFactorOTPResponse, error) {
|
||||
ctxData := authz.GetCtxData(ctx)
|
||||
objectDetails, err := s.command.HumanCheckMFAOTPSetup(ctx, ctxData.UserID, req.Code, "", ctxData.ResourceOwner)
|
||||
if err != nil {
|
||||
return nil, err
|
||||
}
|
||||
return &auth_pb.VerifyMyAuthFactorOTPResponse{
|
||||
Details: object.DomainToDetailsPb(objectDetails),
|
||||
}, nil
|
||||
}
|
||||
|
||||
func (s *Server) RemoveMyAuthFactorOTP(ctx context.Context, _ *auth_pb.RemoveMyAuthFactorOTPRequest) (*auth_pb.RemoveMyAuthFactorOTPResponse, error) {
|
||||
ctxData := authz.GetCtxData(ctx)
|
||||
objectDetails, err := s.command.HumanRemoveOTP(ctx, ctxData.UserID, ctxData.OrgID)
|
||||
if err != nil {
|
||||
return nil, err
|
||||
}
|
||||
return &auth_pb.RemoveMyAuthFactorOTPResponse{
|
||||
Details: object.DomainToDetailsPb(objectDetails),
|
||||
}, nil
|
||||
}
|
||||
|
||||
func (s *Server) AddMyAuthFactorU2F(ctx context.Context, _ *auth_pb.AddMyAuthFactorU2FRequest) (*auth_pb.AddMyAuthFactorU2FResponse, error) {
|
||||
ctxData := authz.GetCtxData(ctx)
|
||||
u2f, err := s.command.HumanAddU2FSetup(ctx, ctxData.UserID, ctxData.ResourceOwner, false)
|
||||
if err != nil {
|
||||
return nil, err
|
||||
}
|
||||
return &auth_pb.AddMyAuthFactorU2FResponse{
|
||||
Key: &user_pb.WebAuthNKey{
|
||||
Id: u2f.WebAuthNTokenID,
|
||||
PublicKey: u2f.CredentialCreationData,
|
||||
},
|
||||
Details: object.ToDetailsPb(
|
||||
u2f.Sequence,
|
||||
u2f.ChangeDate,
|
||||
u2f.ResourceOwner,
|
||||
),
|
||||
}, nil
|
||||
}
|
||||
|
||||
func (s *Server) VerifyMyAuthFactorU2F(ctx context.Context, req *auth_pb.VerifyMyAuthFactorU2FRequest) (*auth_pb.VerifyMyAuthFactorU2FResponse, error) {
|
||||
ctxData := authz.GetCtxData(ctx)
|
||||
objectDetails, err := s.command.HumanVerifyU2FSetup(ctx, ctxData.UserID, ctxData.OrgID, req.Verification.TokenName, "", req.Verification.PublicKeyCredential)
|
||||
if err != nil {
|
||||
return nil, err
|
||||
}
|
||||
return &auth_pb.VerifyMyAuthFactorU2FResponse{
|
||||
Details: object.DomainToDetailsPb(objectDetails),
|
||||
}, nil
|
||||
}
|
||||
|
||||
func (s *Server) RemoveMyAuthFactorU2F(ctx context.Context, req *auth_pb.RemoveMyAuthFactorU2FRequest) (*auth_pb.RemoveMyAuthFactorU2FResponse, error) {
|
||||
ctxData := authz.GetCtxData(ctx)
|
||||
objectDetails, err := s.command.HumanRemovePasswordless(ctx, ctxData.UserID, req.TokenId, ctxData.ResourceOwner)
|
||||
if err != nil {
|
||||
return nil, err
|
||||
}
|
||||
return &auth_pb.RemoveMyAuthFactorU2FResponse{
|
||||
Details: object.DomainToDetailsPb(objectDetails),
|
||||
}, nil
|
||||
}
|
20
internal/api/grpc/auth/password.go
Normal file
20
internal/api/grpc/auth/password.go
Normal file
@@ -0,0 +1,20 @@
|
||||
package auth
|
||||
|
||||
import (
|
||||
"context"
|
||||
"github.com/caos/zitadel/internal/api/grpc/object"
|
||||
|
||||
"github.com/caos/zitadel/internal/api/authz"
|
||||
auth_pb "github.com/caos/zitadel/pkg/grpc/auth"
|
||||
)
|
||||
|
||||
func (s *Server) UpdateMyPassword(ctx context.Context, req *auth_pb.UpdateMyPasswordRequest) (*auth_pb.UpdateMyPasswordResponse, error) {
|
||||
ctxData := authz.GetCtxData(ctx)
|
||||
objectDetails, err := s.command.ChangePassword(ctx, ctxData.OrgID, ctxData.UserID, req.OldPassword, req.NewPassword, "")
|
||||
if err != nil {
|
||||
return nil, err
|
||||
}
|
||||
return &auth_pb.UpdateMyPasswordResponse{
|
||||
Details: object.DomainToDetailsPb(objectDetails),
|
||||
}, nil
|
||||
}
|
16
internal/api/grpc/auth/password_complexity.go
Normal file
16
internal/api/grpc/auth/password_complexity.go
Normal file
@@ -0,0 +1,16 @@
|
||||
package auth
|
||||
|
||||
import (
|
||||
"context"
|
||||
|
||||
policy_grpc "github.com/caos/zitadel/internal/api/grpc/policy"
|
||||
auth_pb "github.com/caos/zitadel/pkg/grpc/auth"
|
||||
)
|
||||
|
||||
func (s *Server) GetMyPasswordComplexityPolicy(ctx context.Context, _ *auth_pb.GetMyPasswordComplexityPolicyRequest) (*auth_pb.GetMyPasswordComplexityPolicyResponse, error) {
|
||||
policy, err := s.repo.GetMyPasswordComplexityPolicy(ctx)
|
||||
if err != nil {
|
||||
return nil, err
|
||||
}
|
||||
return &auth_pb.GetMyPasswordComplexityPolicyResponse{Policy: policy_grpc.ModelPasswordComplexityPolicyToPb(policy)}, nil
|
||||
}
|
58
internal/api/grpc/auth/passwordless.go
Normal file
58
internal/api/grpc/auth/passwordless.go
Normal file
@@ -0,0 +1,58 @@
|
||||
package auth
|
||||
|
||||
import (
|
||||
"context"
|
||||
|
||||
"github.com/caos/zitadel/internal/api/authz"
|
||||
"github.com/caos/zitadel/internal/api/grpc/object"
|
||||
user_grpc "github.com/caos/zitadel/internal/api/grpc/user"
|
||||
auth_pb "github.com/caos/zitadel/pkg/grpc/auth"
|
||||
)
|
||||
|
||||
func (s *Server) ListMyPasswordless(ctx context.Context, _ *auth_pb.ListMyPasswordlessRequest) (*auth_pb.ListMyPasswordlessResponse, error) {
|
||||
tokens, err := s.repo.GetMyPasswordless(ctx)
|
||||
if err != nil {
|
||||
return nil, err
|
||||
}
|
||||
return &auth_pb.ListMyPasswordlessResponse{
|
||||
Result: user_grpc.WebAuthNTokensViewToPb(tokens),
|
||||
}, nil
|
||||
}
|
||||
|
||||
func (s *Server) AddMyPasswordless(ctx context.Context, _ *auth_pb.AddMyPasswordlessRequest) (*auth_pb.AddMyPasswordlessResponse, error) {
|
||||
ctxData := authz.GetCtxData(ctx)
|
||||
u2f, err := s.command.HumanAddPasswordlessSetup(ctx, ctxData.UserID, ctxData.ResourceOwner, false)
|
||||
if err != nil {
|
||||
return nil, err
|
||||
}
|
||||
return &auth_pb.AddMyPasswordlessResponse{
|
||||
Key: user_grpc.WebAuthNTokenToWebAuthNKeyPb(u2f),
|
||||
Details: object.ToDetailsPb(
|
||||
u2f.Sequence,
|
||||
u2f.ChangeDate,
|
||||
u2f.ResourceOwner,
|
||||
),
|
||||
}, nil
|
||||
}
|
||||
|
||||
func (s *Server) VerifyMyPasswordless(ctx context.Context, req *auth_pb.VerifyMyPasswordlessRequest) (*auth_pb.VerifyMyPasswordlessResponse, error) {
|
||||
ctxData := authz.GetCtxData(ctx)
|
||||
objectDetails, err := s.command.HumanHumanPasswordlessSetup(ctx, ctxData.UserID, ctxData.OrgID, req.Verification.TokenName, "", req.Verification.PublicKeyCredential)
|
||||
if err != nil {
|
||||
return nil, err
|
||||
}
|
||||
return &auth_pb.VerifyMyPasswordlessResponse{
|
||||
Details: object.DomainToDetailsPb(objectDetails),
|
||||
}, nil
|
||||
}
|
||||
|
||||
func (s *Server) RemoveMyPasswordless(ctx context.Context, req *auth_pb.RemoveMyPasswordlessRequest) (*auth_pb.RemoveMyPasswordlessResponse, error) {
|
||||
ctxData := authz.GetCtxData(ctx)
|
||||
objectDetails, err := s.command.HumanRemovePasswordless(ctx, ctxData.UserID, req.TokenId, ctxData.ResourceOwner)
|
||||
if err != nil {
|
||||
return nil, err
|
||||
}
|
||||
return &auth_pb.RemoveMyPasswordlessResponse{
|
||||
Details: object.DomainToDetailsPb(objectDetails),
|
||||
}, nil
|
||||
}
|
27
internal/api/grpc/auth/permission.go
Normal file
27
internal/api/grpc/auth/permission.go
Normal file
@@ -0,0 +1,27 @@
|
||||
package auth
|
||||
|
||||
import (
|
||||
"context"
|
||||
|
||||
auth_pb "github.com/caos/zitadel/pkg/grpc/auth"
|
||||
)
|
||||
|
||||
func (s *Server) ListMyZitadelPermissions(ctx context.Context, _ *auth_pb.ListMyZitadelPermissionsRequest) (*auth_pb.ListMyZitadelPermissionsResponse, error) {
|
||||
perms, err := s.repo.SearchMyZitadelPermissions(ctx)
|
||||
if err != nil {
|
||||
return nil, err
|
||||
}
|
||||
return &auth_pb.ListMyZitadelPermissionsResponse{
|
||||
Result: perms,
|
||||
}, nil
|
||||
}
|
||||
|
||||
func (s *Server) ListMyProjectPermissions(ctx context.Context, _ *auth_pb.ListMyProjectPermissionsRequest) (*auth_pb.ListMyProjectPermissionsResponse, error) {
|
||||
perms, err := s.repo.SearchMyProjectPermissions(ctx)
|
||||
if err != nil {
|
||||
return nil, err
|
||||
}
|
||||
return &auth_pb.ListMyProjectPermissionsResponse{
|
||||
Result: perms,
|
||||
}, nil
|
||||
}
|
74
internal/api/grpc/auth/phone.go
Normal file
74
internal/api/grpc/auth/phone.go
Normal file
@@ -0,0 +1,74 @@
|
||||
package auth
|
||||
|
||||
import (
|
||||
"context"
|
||||
|
||||
"github.com/caos/zitadel/internal/api/authz"
|
||||
"github.com/caos/zitadel/internal/api/grpc/object"
|
||||
"github.com/caos/zitadel/internal/api/grpc/user"
|
||||
auth_pb "github.com/caos/zitadel/pkg/grpc/auth"
|
||||
)
|
||||
|
||||
func (s *Server) GetMyPhone(ctx context.Context, _ *auth_pb.GetMyPhoneRequest) (*auth_pb.GetMyPhoneResponse, error) {
|
||||
phone, err := s.repo.MyPhone(ctx)
|
||||
if err != nil {
|
||||
return nil, err
|
||||
}
|
||||
return &auth_pb.GetMyPhoneResponse{
|
||||
Phone: user.ModelPhoneToPb(phone),
|
||||
Details: object.ToDetailsPb(
|
||||
phone.Sequence,
|
||||
phone.ChangeDate,
|
||||
phone.ResourceOwner,
|
||||
),
|
||||
}, nil
|
||||
}
|
||||
|
||||
func (s *Server) SetMyPhone(ctx context.Context, req *auth_pb.SetMyPhoneRequest) (*auth_pb.SetMyPhoneResponse, error) {
|
||||
phone, err := s.command.ChangeHumanPhone(ctx, UpdateMyPhoneToDomain(ctx, req))
|
||||
if err != nil {
|
||||
return nil, err
|
||||
}
|
||||
return &auth_pb.SetMyPhoneResponse{
|
||||
Details: object.ToDetailsPb(
|
||||
phone.Sequence,
|
||||
phone.ChangeDate,
|
||||
phone.ResourceOwner,
|
||||
),
|
||||
}, nil
|
||||
}
|
||||
|
||||
func (s *Server) VerifyMyPhone(ctx context.Context, req *auth_pb.VerifyMyPhoneRequest) (*auth_pb.VerifyMyPhoneResponse, error) {
|
||||
ctxData := authz.GetCtxData(ctx)
|
||||
_, err := s.command.VerifyHumanPhone(ctx, ctxData.UserID, req.Code, ctxData.OrgID)
|
||||
if err != nil {
|
||||
return nil, err
|
||||
}
|
||||
|
||||
//TODO: response from business
|
||||
return &auth_pb.VerifyMyPhoneResponse{
|
||||
//Details: object.DomainToDetailsPb(objectDetails),
|
||||
}, nil
|
||||
}
|
||||
|
||||
func (s *Server) ResendMyPhoneVerification(ctx context.Context, _ *auth_pb.ResendMyPhoneVerificationRequest) (*auth_pb.ResendMyPhoneVerificationResponse, error) {
|
||||
ctxData := authz.GetCtxData(ctx)
|
||||
objectDetails, err := s.command.CreateHumanPhoneVerificationCode(ctx, ctxData.UserID, ctxData.ResourceOwner)
|
||||
if err != nil {
|
||||
return nil, err
|
||||
}
|
||||
return &auth_pb.ResendMyPhoneVerificationResponse{
|
||||
Details: object.DomainToDetailsPb(objectDetails),
|
||||
}, nil
|
||||
}
|
||||
|
||||
func (s *Server) RemoveMyPhone(ctx context.Context, _ *auth_pb.RemoveMyPhoneRequest) (*auth_pb.RemoveMyPhoneResponse, error) {
|
||||
ctxData := authz.GetCtxData(ctx)
|
||||
objectDetails, err := s.command.RemoveHumanPhone(ctx, ctxData.UserID, ctxData.ResourceOwner)
|
||||
if err != nil {
|
||||
return nil, err
|
||||
}
|
||||
return &auth_pb.RemoveMyPhoneResponse{
|
||||
Details: object.DomainToDetailsPb(objectDetails),
|
||||
}, nil
|
||||
}
|
15
internal/api/grpc/auth/phone_converter.go
Normal file
15
internal/api/grpc/auth/phone_converter.go
Normal file
@@ -0,0 +1,15 @@
|
||||
package auth
|
||||
|
||||
import (
|
||||
"context"
|
||||
|
||||
"github.com/caos/zitadel/internal/domain"
|
||||
"github.com/caos/zitadel/pkg/grpc/auth"
|
||||
)
|
||||
|
||||
func UpdateMyPhoneToDomain(ctx context.Context, phone *auth.SetMyPhoneRequest) *domain.Phone {
|
||||
return &domain.Phone{
|
||||
ObjectRoot: ctxToObjectRoot(ctx),
|
||||
PhoneNumber: phone.Phone,
|
||||
}
|
||||
}
|
@@ -1,30 +0,0 @@
|
||||
package auth
|
||||
|
||||
import (
|
||||
"github.com/caos/logging"
|
||||
iam_model "github.com/caos/zitadel/internal/iam/model"
|
||||
"github.com/golang/protobuf/ptypes"
|
||||
|
||||
"github.com/caos/zitadel/pkg/grpc/auth"
|
||||
)
|
||||
|
||||
func passwordComplexityPolicyFromModel(policy *iam_model.PasswordComplexityPolicyView) *auth.PasswordComplexityPolicy {
|
||||
creationDate, err := ptypes.TimestampProto(policy.CreationDate)
|
||||
logging.Log("GRPC-Lsi3d").OnError(err).Debug("unable to parse timestamp")
|
||||
|
||||
changeDate, err := ptypes.TimestampProto(policy.ChangeDate)
|
||||
logging.Log("GRPC-P0wr4").OnError(err).Debug("unable to parse timestamp")
|
||||
|
||||
return &auth.PasswordComplexityPolicy{
|
||||
Id: policy.AggregateID,
|
||||
CreationDate: creationDate,
|
||||
ChangeDate: changeDate,
|
||||
Sequence: policy.Sequence,
|
||||
MinLength: policy.MinLength,
|
||||
HasLowercase: policy.HasLowercase,
|
||||
HasUppercase: policy.HasUppercase,
|
||||
HasNumber: policy.HasNumber,
|
||||
HasSymbol: policy.HasSymbol,
|
||||
IsDefault: policy.AggregateID == "",
|
||||
}
|
||||
}
|
@@ -1,11 +0,0 @@
|
||||
package auth
|
||||
|
||||
import (
|
||||
"context"
|
||||
|
||||
"github.com/golang/protobuf/ptypes/empty"
|
||||
)
|
||||
|
||||
func (s *Server) Healthz(_ context.Context, e *empty.Empty) (*empty.Empty, error) {
|
||||
return &empty.Empty{}, nil
|
||||
}
|
38
internal/api/grpc/auth/profile.go
Normal file
38
internal/api/grpc/auth/profile.go
Normal file
@@ -0,0 +1,38 @@
|
||||
package auth
|
||||
|
||||
import (
|
||||
"context"
|
||||
|
||||
object_grpc "github.com/caos/zitadel/internal/api/grpc/object"
|
||||
user_grpc "github.com/caos/zitadel/internal/api/grpc/user"
|
||||
auth_pb "github.com/caos/zitadel/pkg/grpc/auth"
|
||||
)
|
||||
|
||||
func (s *Server) GetMyProfile(ctx context.Context, req *auth_pb.GetMyProfileRequest) (*auth_pb.GetMyProfileResponse, error) {
|
||||
profile, err := s.repo.MyProfile(ctx)
|
||||
if err != nil {
|
||||
return nil, err
|
||||
}
|
||||
return &auth_pb.GetMyProfileResponse{
|
||||
Profile: user_grpc.ProfileToPb(profile),
|
||||
Details: object_grpc.ToDetailsPb(
|
||||
profile.Sequence,
|
||||
profile.ChangeDate,
|
||||
profile.ResourceOwner,
|
||||
),
|
||||
}, nil
|
||||
}
|
||||
|
||||
func (s *Server) UpdateMyProfile(ctx context.Context, req *auth_pb.UpdateMyProfileRequest) (*auth_pb.UpdateMyProfileResponse, error) {
|
||||
profile, err := s.command.ChangeHumanProfile(ctx, UpdateProfileToDomain(ctx, req))
|
||||
if err != nil {
|
||||
return nil, err
|
||||
}
|
||||
return &auth_pb.UpdateMyProfileResponse{
|
||||
Details: object_grpc.ToDetailsPb(
|
||||
profile.Sequence,
|
||||
profile.ChangeDate,
|
||||
profile.ResourceOwner,
|
||||
),
|
||||
}, nil
|
||||
}
|
25
internal/api/grpc/auth/profile_converter.go
Normal file
25
internal/api/grpc/auth/profile_converter.go
Normal file
@@ -0,0 +1,25 @@
|
||||
package auth
|
||||
|
||||
import (
|
||||
"context"
|
||||
|
||||
"github.com/caos/logging"
|
||||
"github.com/caos/zitadel/internal/api/grpc/user"
|
||||
"github.com/caos/zitadel/internal/domain"
|
||||
"github.com/caos/zitadel/pkg/grpc/auth"
|
||||
"golang.org/x/text/language"
|
||||
)
|
||||
|
||||
func UpdateProfileToDomain(ctx context.Context, profile *auth.UpdateMyProfileRequest) *domain.Profile {
|
||||
lang, err := language.Parse(profile.PreferredLanguage)
|
||||
logging.Log("AUTH-x19v6").OnError(err).Debug("unable to parse preferred language")
|
||||
|
||||
return &domain.Profile{
|
||||
ObjectRoot: ctxToObjectRoot(ctx),
|
||||
FirstName: profile.FirstName,
|
||||
LastName: profile.LastName,
|
||||
NickName: profile.NickName,
|
||||
PreferredLanguage: lang,
|
||||
Gender: user.GenderToDomain(profile.Gender),
|
||||
}
|
||||
}
|
@@ -1,25 +0,0 @@
|
||||
package auth
|
||||
|
||||
import (
|
||||
"github.com/caos/zitadel/internal/domain"
|
||||
"github.com/caos/zitadel/pkg/grpc/auth"
|
||||
)
|
||||
|
||||
func searchMethodToModel(method auth.SearchMethod) domain.SearchMethod {
|
||||
switch method {
|
||||
case auth.SearchMethod_SEARCHMETHOD_EQUALS:
|
||||
return domain.SearchMethodEquals
|
||||
case auth.SearchMethod_SEARCHMETHOD_CONTAINS:
|
||||
return domain.SearchMethodContains
|
||||
case auth.SearchMethod_SEARCHMETHOD_STARTS_WITH:
|
||||
return domain.SearchMethodStartsWith
|
||||
case auth.SearchMethod_SEARCHMETHOD_EQUALS_IGNORE_CASE:
|
||||
return domain.SearchMethodEqualsIgnoreCase
|
||||
case auth.SearchMethod_SEARCHMETHOD_CONTAINS_IGNORE_CASE:
|
||||
return domain.SearchMethodContainsIgnoreCase
|
||||
case auth.SearchMethod_SEARCHMETHOD_STARTS_WITH_IGNORE_CASE:
|
||||
return domain.SearchMethodStartsWithIgnoreCase
|
||||
default:
|
||||
return domain.SearchMethodEquals
|
||||
}
|
||||
}
|
@@ -1,15 +1,14 @@
|
||||
package auth
|
||||
|
||||
import (
|
||||
"github.com/caos/zitadel/internal/command"
|
||||
"github.com/caos/zitadel/internal/query"
|
||||
"google.golang.org/grpc"
|
||||
|
||||
"github.com/caos/zitadel/internal/api/authz"
|
||||
"github.com/caos/zitadel/internal/api/grpc/server"
|
||||
"github.com/caos/zitadel/internal/auth/repository"
|
||||
"github.com/caos/zitadel/internal/auth/repository/eventsourcing"
|
||||
"github.com/caos/zitadel/internal/command"
|
||||
"github.com/caos/zitadel/internal/query"
|
||||
"github.com/caos/zitadel/pkg/grpc/auth"
|
||||
"google.golang.org/grpc"
|
||||
)
|
||||
|
||||
var _ auth.AuthServiceServer = (*Server)(nil)
|
||||
@@ -19,6 +18,7 @@ const (
|
||||
)
|
||||
|
||||
type Server struct {
|
||||
auth.UnimplementedAuthServiceServer
|
||||
command *command.Commands
|
||||
query *query.Queries
|
||||
repo repository.Repository
|
||||
|
@@ -2,240 +2,97 @@ package auth
|
||||
|
||||
import (
|
||||
"context"
|
||||
|
||||
"github.com/golang/protobuf/ptypes/empty"
|
||||
"time"
|
||||
|
||||
"github.com/caos/zitadel/internal/api/authz"
|
||||
"github.com/caos/zitadel/pkg/grpc/auth"
|
||||
"github.com/caos/zitadel/internal/api/grpc/change"
|
||||
"github.com/caos/zitadel/internal/api/grpc/object"
|
||||
"github.com/caos/zitadel/internal/api/grpc/org"
|
||||
user_grpc "github.com/caos/zitadel/internal/api/grpc/user"
|
||||
"github.com/caos/zitadel/internal/eventstore/v1/models"
|
||||
grant_model "github.com/caos/zitadel/internal/usergrant/model"
|
||||
auth_pb "github.com/caos/zitadel/pkg/grpc/auth"
|
||||
)
|
||||
|
||||
func (s *Server) GetMyUser(ctx context.Context, _ *empty.Empty) (*auth.UserView, error) {
|
||||
func (s *Server) GetMyUser(ctx context.Context, _ *auth_pb.GetMyUserRequest) (*auth_pb.GetMyUserResponse, error) {
|
||||
user, err := s.repo.MyUser(ctx)
|
||||
if err != nil {
|
||||
return nil, err
|
||||
}
|
||||
return userViewFromModel(user), nil
|
||||
return &auth_pb.GetMyUserResponse{User: user_grpc.UserToPb(user)}, nil
|
||||
}
|
||||
|
||||
func (s *Server) GetMyUserProfile(ctx context.Context, _ *empty.Empty) (*auth.UserProfileView, error) {
|
||||
profile, err := s.repo.MyProfile(ctx)
|
||||
func (s *Server) ListMyUserChanges(ctx context.Context, req *auth_pb.ListMyUserChangesRequest) (*auth_pb.ListMyUserChangesResponse, error) {
|
||||
changes, err := s.repo.MyUserChanges(ctx, req.Query.Offset, uint64(req.Query.Limit), req.Query.Asc)
|
||||
if err != nil {
|
||||
return nil, err
|
||||
}
|
||||
return profileViewFromModel(profile), nil
|
||||
return &auth_pb.ListMyUserChangesResponse{
|
||||
Result: change.UserChangesToPb(changes.Changes),
|
||||
}, nil
|
||||
}
|
||||
|
||||
func (s *Server) GetMyUserEmail(ctx context.Context, _ *empty.Empty) (*auth.UserEmailView, error) {
|
||||
email, err := s.repo.MyEmail(ctx)
|
||||
func (s *Server) ListMyUserSessions(ctx context.Context, req *auth_pb.ListMyUserSessionsRequest) (*auth_pb.ListMyUserSessionsResponse, error) {
|
||||
userSessions, err := s.repo.GetMyUserSessions(ctx)
|
||||
if err != nil {
|
||||
return nil, err
|
||||
}
|
||||
return emailViewFromModel(email), nil
|
||||
return &auth_pb.ListMyUserSessionsResponse{
|
||||
Result: user_grpc.UserSessionsToPb(userSessions),
|
||||
}, nil
|
||||
}
|
||||
|
||||
func (s *Server) GetMyUserPhone(ctx context.Context, _ *empty.Empty) (*auth.UserPhoneView, error) {
|
||||
phone, err := s.repo.MyPhone(ctx)
|
||||
if err != nil {
|
||||
return nil, err
|
||||
}
|
||||
return phoneViewFromModel(phone), nil
|
||||
}
|
||||
|
||||
func (s *Server) RemoveMyUserPhone(ctx context.Context, _ *empty.Empty) (*empty.Empty, error) {
|
||||
func (s *Server) UpdateMyUserName(ctx context.Context, req *auth_pb.UpdateMyUserNameRequest) (*auth_pb.UpdateMyUserNameResponse, error) {
|
||||
ctxData := authz.GetCtxData(ctx)
|
||||
err := s.command.RemoveHumanPhone(ctx, ctxData.UserID, ctxData.ResourceOwner)
|
||||
return &empty.Empty{}, err
|
||||
}
|
||||
|
||||
func (s *Server) GetMyUserAddress(ctx context.Context, _ *empty.Empty) (*auth.UserAddressView, error) {
|
||||
address, err := s.repo.MyAddress(ctx)
|
||||
objectDetails, err := s.command.ChangeUsername(ctx, ctxData.ResourceOwner, ctxData.UserID, req.UserName)
|
||||
if err != nil {
|
||||
return nil, err
|
||||
}
|
||||
return addressViewFromModel(address), nil
|
||||
return &auth_pb.UpdateMyUserNameResponse{
|
||||
Details: object.DomainToDetailsPb(objectDetails),
|
||||
}, nil
|
||||
}
|
||||
|
||||
func (s *Server) GetMyMfas(ctx context.Context, _ *empty.Empty) (*auth.MultiFactors, error) {
|
||||
mfas, err := s.repo.MyUserMFAs(ctx)
|
||||
func ctxToObjectRoot(ctx context.Context) models.ObjectRoot {
|
||||
ctxData := authz.GetCtxData(ctx)
|
||||
return models.ObjectRoot{
|
||||
AggregateID: ctxData.UserID,
|
||||
ResourceOwner: ctxData.ResourceOwner,
|
||||
}
|
||||
}
|
||||
|
||||
func (s *Server) ListMyUserGrants(ctx context.Context, req *auth_pb.ListMyUserGrantsRequest) (*auth_pb.ListMyUserGrantsResponse, error) {
|
||||
res, err := s.repo.SearchMyUserGrants(ctx, ListMyUserGrantsRequestToModel(req))
|
||||
if err != nil {
|
||||
return nil, err
|
||||
}
|
||||
return &auth.MultiFactors{Mfas: mfasFromModel(mfas)}, nil
|
||||
return &auth_pb.ListMyUserGrantsResponse{
|
||||
Result: UserGrantsToPb(res.Result),
|
||||
Details: object.ToListDetails(
|
||||
res.TotalResult,
|
||||
res.Sequence,
|
||||
res.Timestamp,
|
||||
),
|
||||
}, nil
|
||||
}
|
||||
|
||||
func (s *Server) UpdateMyUserProfile(ctx context.Context, request *auth.UpdateUserProfileRequest) (*auth.UserProfile, error) {
|
||||
profile, err := s.command.ChangeHumanProfile(ctx, updateProfileToDomain(ctx, request))
|
||||
func (s *Server) ListMyProjectOrgs(ctx context.Context, req *auth_pb.ListMyProjectOrgsRequest) (*auth_pb.ListMyProjectOrgsResponse, error) {
|
||||
res, err := s.repo.SearchMyProjectOrgs(ctx, ListMyProjectOrgsRequestToModel(req))
|
||||
if err != nil {
|
||||
return nil, err
|
||||
}
|
||||
return profileFromDomain(profile), nil
|
||||
return &auth_pb.ListMyProjectOrgsResponse{
|
||||
//TODO: not all details
|
||||
Details: object.ToListDetails(res.TotalResult, 0, time.Time{}),
|
||||
Result: org.OrgsToPb(res.Result),
|
||||
}, nil
|
||||
}
|
||||
|
||||
func (s *Server) ChangeMyUserName(ctx context.Context, request *auth.ChangeUserNameRequest) (*empty.Empty, error) {
|
||||
ctxData := authz.GetCtxData(ctx)
|
||||
return &empty.Empty{}, s.command.ChangeUsername(ctx, ctxData.ResourceOwner, ctxData.UserID, request.UserName)
|
||||
}
|
||||
|
||||
func (s *Server) ChangeMyUserEmail(ctx context.Context, request *auth.UpdateUserEmailRequest) (*auth.UserEmail, error) {
|
||||
email, err := s.command.ChangeHumanEmail(ctx, updateEmailToDomain(ctx, request))
|
||||
if err != nil {
|
||||
return nil, err
|
||||
func ListMyProjectOrgsRequestToModel(req *auth_pb.ListMyProjectOrgsRequest) *grant_model.UserGrantSearchRequest {
|
||||
return &grant_model.UserGrantSearchRequest{
|
||||
Offset: req.Query.Offset,
|
||||
Limit: uint64(req.Query.Limit),
|
||||
Asc: req.Query.Asc,
|
||||
// Queries: queries,//TODO:user grant queries missing in proto
|
||||
}
|
||||
return emailFromDomain(email), nil
|
||||
}
|
||||
|
||||
func (s *Server) VerifyMyUserEmail(ctx context.Context, request *auth.VerifyMyUserEmailRequest) (*empty.Empty, error) {
|
||||
ctxData := authz.GetCtxData(ctx)
|
||||
err := s.command.VerifyHumanEmail(ctx, ctxData.UserID, request.Code, ctxData.OrgID)
|
||||
return &empty.Empty{}, err
|
||||
}
|
||||
|
||||
func (s *Server) ResendMyEmailVerificationMail(ctx context.Context, _ *empty.Empty) (*empty.Empty, error) {
|
||||
ctxData := authz.GetCtxData(ctx)
|
||||
err := s.command.CreateHumanEmailVerificationCode(ctx, ctxData.UserID, ctxData.ResourceOwner)
|
||||
return &empty.Empty{}, err
|
||||
}
|
||||
|
||||
func (s *Server) ChangeMyUserPhone(ctx context.Context, request *auth.UpdateUserPhoneRequest) (*auth.UserPhone, error) {
|
||||
phone, err := s.command.ChangeHumanPhone(ctx, updatePhoneToDomain(ctx, request))
|
||||
if err != nil {
|
||||
return nil, err
|
||||
}
|
||||
return phoneFromDomain(phone), nil
|
||||
}
|
||||
|
||||
func (s *Server) VerifyMyUserPhone(ctx context.Context, request *auth.VerifyUserPhoneRequest) (*empty.Empty, error) {
|
||||
ctxData := authz.GetCtxData(ctx)
|
||||
err := s.command.VerifyHumanPhone(ctx, ctxData.UserID, request.Code, ctxData.ResourceOwner)
|
||||
return &empty.Empty{}, err
|
||||
}
|
||||
|
||||
func (s *Server) ResendMyPhoneVerificationCode(ctx context.Context, _ *empty.Empty) (*empty.Empty, error) {
|
||||
ctxData := authz.GetCtxData(ctx)
|
||||
err := s.command.CreateHumanPhoneVerificationCode(ctx, ctxData.UserID, ctxData.ResourceOwner)
|
||||
return &empty.Empty{}, err
|
||||
}
|
||||
|
||||
func (s *Server) UpdateMyUserAddress(ctx context.Context, request *auth.UpdateUserAddressRequest) (*auth.UserAddress, error) {
|
||||
address, err := s.command.ChangeHumanAddress(ctx, updateAddressToDomain(ctx, request))
|
||||
if err != nil {
|
||||
return nil, err
|
||||
}
|
||||
return addressFromDomain(address), nil
|
||||
}
|
||||
|
||||
func (s *Server) ChangeMyPassword(ctx context.Context, request *auth.PasswordChange) (*empty.Empty, error) {
|
||||
ctxData := authz.GetCtxData(ctx)
|
||||
err := s.command.ChangePassword(ctx, ctxData.OrgID, ctxData.UserID, request.OldPassword, request.NewPassword, "")
|
||||
return &empty.Empty{}, err
|
||||
}
|
||||
|
||||
func (s *Server) SearchMyExternalIDPs(ctx context.Context, request *auth.ExternalIDPSearchRequest) (*auth.ExternalIDPSearchResponse, error) {
|
||||
externalIDP, err := s.repo.SearchMyExternalIDPs(ctx, externalIDPSearchRequestToModel(request))
|
||||
if err != nil {
|
||||
return nil, err
|
||||
}
|
||||
return externalIDPSearchResponseFromModel(externalIDP), nil
|
||||
}
|
||||
|
||||
func (s *Server) RemoveMyExternalIDP(ctx context.Context, request *auth.ExternalIDPRemoveRequest) (*empty.Empty, error) {
|
||||
err := s.command.RemoveHumanExternalIDP(ctx, externalIDPRemoveToDomain(ctx, request))
|
||||
return &empty.Empty{}, err
|
||||
}
|
||||
|
||||
func (s *Server) GetMyPasswordComplexityPolicy(ctx context.Context, _ *empty.Empty) (*auth.PasswordComplexityPolicy, error) {
|
||||
policy, err := s.repo.GetMyPasswordComplexityPolicy(ctx)
|
||||
if err != nil {
|
||||
return nil, err
|
||||
}
|
||||
return passwordComplexityPolicyFromModel(policy), nil
|
||||
}
|
||||
|
||||
func (s *Server) AddMfaOTP(ctx context.Context, _ *empty.Empty) (_ *auth.MfaOtpResponse, err error) {
|
||||
ctxData := authz.GetCtxData(ctx)
|
||||
otp, err := s.command.AddHumanOTP(ctx, ctxData.UserID, ctxData.OrgID)
|
||||
if err != nil {
|
||||
return nil, err
|
||||
}
|
||||
return otpFromDomain(otp), nil
|
||||
}
|
||||
|
||||
func (s *Server) VerifyMfaOTP(ctx context.Context, request *auth.VerifyMfaOtp) (*empty.Empty, error) {
|
||||
ctxData := authz.GetCtxData(ctx)
|
||||
err := s.command.HumanCheckMFAOTPSetup(ctx, ctxData.UserID, request.Code, "", ctxData.ResourceOwner)
|
||||
return &empty.Empty{}, err
|
||||
}
|
||||
|
||||
func (s *Server) RemoveMfaOTP(ctx context.Context, _ *empty.Empty) (_ *empty.Empty, err error) {
|
||||
ctxData := authz.GetCtxData(ctx)
|
||||
err = s.command.HumanRemoveOTP(ctx, ctxData.UserID, ctxData.OrgID)
|
||||
return &empty.Empty{}, err
|
||||
}
|
||||
|
||||
func (s *Server) AddMyMfaU2F(ctx context.Context, _ *empty.Empty) (_ *auth.WebAuthNResponse, err error) {
|
||||
ctxData := authz.GetCtxData(ctx)
|
||||
u2f, err := s.command.HumanAddU2FSetup(ctx, ctxData.UserID, ctxData.ResourceOwner, false)
|
||||
if err != nil {
|
||||
return nil, err
|
||||
}
|
||||
return verifyWebAuthNFromDomain(u2f), err
|
||||
}
|
||||
|
||||
func (s *Server) VerifyMyMfaU2F(ctx context.Context, request *auth.VerifyWebAuthN) (*empty.Empty, error) {
|
||||
ctxData := authz.GetCtxData(ctx)
|
||||
err := s.command.HumanVerifyU2FSetup(ctx, ctxData.UserID, ctxData.OrgID, request.TokenName, "", request.PublicKeyCredential)
|
||||
return &empty.Empty{}, err
|
||||
}
|
||||
|
||||
func (s *Server) RemoveMyMfaU2F(ctx context.Context, id *auth.WebAuthNTokenID) (*empty.Empty, error) {
|
||||
ctxData := authz.GetCtxData(ctx)
|
||||
err := s.command.HumanRemoveU2F(ctx, ctxData.UserID, id.Id, ctxData.OrgID)
|
||||
return &empty.Empty{}, err
|
||||
}
|
||||
|
||||
func (s *Server) GetMyPasswordless(ctx context.Context, _ *empty.Empty) (_ *auth.WebAuthNTokens, err error) {
|
||||
tokens, err := s.repo.GetMyPasswordless(ctx)
|
||||
if err != nil {
|
||||
return nil, err
|
||||
}
|
||||
return webAuthNTokensFromModel(tokens), err
|
||||
}
|
||||
|
||||
func (s *Server) AddMyPasswordless(ctx context.Context, _ *empty.Empty) (_ *auth.WebAuthNResponse, err error) {
|
||||
ctxData := authz.GetCtxData(ctx)
|
||||
u2f, err := s.command.HumanAddPasswordlessSetup(ctx, ctxData.UserID, ctxData.ResourceOwner, false)
|
||||
if err != nil {
|
||||
return nil, err
|
||||
}
|
||||
return verifyWebAuthNFromDomain(u2f), err
|
||||
}
|
||||
|
||||
func (s *Server) VerifyMyPasswordless(ctx context.Context, request *auth.VerifyWebAuthN) (*empty.Empty, error) {
|
||||
ctxData := authz.GetCtxData(ctx)
|
||||
err := s.command.HumanHumanPasswordlessSetup(ctx, ctxData.UserID, ctxData.OrgID, request.TokenName, "", request.PublicKeyCredential)
|
||||
return &empty.Empty{}, err
|
||||
}
|
||||
|
||||
func (s *Server) RemoveMyPasswordless(ctx context.Context, id *auth.WebAuthNTokenID) (*empty.Empty, error) {
|
||||
ctxData := authz.GetCtxData(ctx)
|
||||
err := s.command.HumanRemovePasswordless(ctx, ctxData.UserID, id.Id, ctxData.ResourceOwner)
|
||||
return &empty.Empty{}, err
|
||||
}
|
||||
|
||||
func (s *Server) GetMyUserChanges(ctx context.Context, request *auth.ChangesRequest) (*auth.Changes, error) {
|
||||
changes, err := s.repo.MyUserChanges(ctx, request.SequenceOffset, request.Limit, request.Asc)
|
||||
if err != nil {
|
||||
return nil, err
|
||||
}
|
||||
return userChangesToResponse(changes, request.GetSequenceOffset(), request.GetLimit()), nil
|
||||
}
|
||||
|
||||
func (s *Server) SearchMyUserMemberships(ctx context.Context, in *auth.UserMembershipSearchRequest) (*auth.UserMembershipSearchResponse, error) {
|
||||
request := userMembershipSearchRequestsToModel(in)
|
||||
request.AppendUserIDQuery(authz.GetCtxData(ctx).UserID)
|
||||
response, err := s.repo.SearchMyUserMemberships(ctx, request)
|
||||
if err != nil {
|
||||
return nil, err
|
||||
}
|
||||
return userMembershipSearchResponseFromModel(response), nil
|
||||
}
|
||||
|
@@ -1,565 +0,0 @@
|
||||
package auth
|
||||
|
||||
import (
|
||||
"context"
|
||||
"encoding/json"
|
||||
"github.com/caos/logging"
|
||||
"github.com/golang/protobuf/ptypes"
|
||||
"golang.org/x/text/language"
|
||||
"google.golang.org/protobuf/encoding/protojson"
|
||||
"google.golang.org/protobuf/types/known/structpb"
|
||||
|
||||
"github.com/caos/zitadel/internal/api/authz"
|
||||
"github.com/caos/zitadel/internal/domain"
|
||||
"github.com/caos/zitadel/internal/eventstore/v1/models"
|
||||
"github.com/caos/zitadel/internal/telemetry/tracing"
|
||||
usr_model "github.com/caos/zitadel/internal/user/model"
|
||||
"github.com/caos/zitadel/pkg/grpc/auth"
|
||||
"github.com/caos/zitadel/pkg/grpc/message"
|
||||
)
|
||||
|
||||
func userViewFromModel(user *usr_model.UserView) *auth.UserView {
|
||||
creationDate, err := ptypes.TimestampProto(user.CreationDate)
|
||||
logging.Log("GRPC-sd32g").OnError(err).Debug("unable to parse timestamp")
|
||||
|
||||
changeDate, err := ptypes.TimestampProto(user.ChangeDate)
|
||||
logging.Log("GRPC-FJKq1").OnError(err).Debug("unable to parse timestamp")
|
||||
|
||||
lastLogin, err := ptypes.TimestampProto(user.LastLogin)
|
||||
logging.Log("GRPC-Gteh2").OnError(err).Debug("unable to parse timestamp")
|
||||
|
||||
userView := &auth.UserView{
|
||||
Id: user.ID,
|
||||
State: userStateFromModel(user.State),
|
||||
CreationDate: creationDate,
|
||||
ChangeDate: changeDate,
|
||||
LastLogin: lastLogin,
|
||||
UserName: user.UserName,
|
||||
Sequence: user.Sequence,
|
||||
ResourceOwner: user.ResourceOwner,
|
||||
LoginNames: user.LoginNames,
|
||||
PreferredLoginName: user.PreferredLoginName,
|
||||
}
|
||||
|
||||
if user.HumanView != nil {
|
||||
userView.User = &auth.UserView_Human{Human: humanViewFromModel(user.HumanView)}
|
||||
}
|
||||
if user.MachineView != nil {
|
||||
userView.User = &auth.UserView_Machine{Machine: machineViewFromModel(user.MachineView)}
|
||||
|
||||
}
|
||||
|
||||
return userView
|
||||
}
|
||||
|
||||
func profileFromDomain(profile *domain.Profile) *auth.UserProfile {
|
||||
creationDate, err := ptypes.TimestampProto(profile.CreationDate)
|
||||
logging.Log("GRPC-56t5s").OnError(err).Debug("unable to parse timestamp")
|
||||
|
||||
changeDate, err := ptypes.TimestampProto(profile.ChangeDate)
|
||||
logging.Log("GRPC-K58ds").OnError(err).Debug("unable to parse timestamp")
|
||||
|
||||
return &auth.UserProfile{
|
||||
Id: profile.AggregateID,
|
||||
CreationDate: creationDate,
|
||||
ChangeDate: changeDate,
|
||||
Sequence: profile.Sequence,
|
||||
FirstName: profile.FirstName,
|
||||
LastName: profile.LastName,
|
||||
DisplayName: profile.DisplayName,
|
||||
NickName: profile.NickName,
|
||||
PreferredLanguage: profile.PreferredLanguage.String(),
|
||||
Gender: genderFromDomain(profile.Gender),
|
||||
}
|
||||
}
|
||||
|
||||
func profileViewFromModel(profile *usr_model.Profile) *auth.UserProfileView {
|
||||
creationDate, err := ptypes.TimestampProto(profile.CreationDate)
|
||||
logging.Log("GRPC-s9iKs").OnError(err).Debug("unable to parse timestamp")
|
||||
|
||||
changeDate, err := ptypes.TimestampProto(profile.ChangeDate)
|
||||
logging.Log("GRPC-9sujE").OnError(err).Debug("unable to parse timestamp")
|
||||
|
||||
return &auth.UserProfileView{
|
||||
Id: profile.AggregateID,
|
||||
CreationDate: creationDate,
|
||||
ChangeDate: changeDate,
|
||||
Sequence: profile.Sequence,
|
||||
FirstName: profile.FirstName,
|
||||
LastName: profile.LastName,
|
||||
DisplayName: profile.DisplayName,
|
||||
NickName: profile.NickName,
|
||||
PreferredLanguage: profile.PreferredLanguage.String(),
|
||||
Gender: genderFromModel(profile.Gender),
|
||||
LoginNames: profile.LoginNames,
|
||||
PreferredLoginName: profile.PreferredLoginName,
|
||||
}
|
||||
}
|
||||
|
||||
func updateProfileToDomain(ctx context.Context, u *auth.UpdateUserProfileRequest) *domain.Profile {
|
||||
preferredLanguage, err := language.Parse(u.PreferredLanguage)
|
||||
logging.Log("GRPC-lk73L").OnError(err).WithField("traceID", tracing.TraceIDFromCtx(ctx)).Debug("language malformed")
|
||||
|
||||
return &domain.Profile{
|
||||
ObjectRoot: ctxToObjectRoot(ctx),
|
||||
FirstName: u.FirstName,
|
||||
LastName: u.LastName,
|
||||
NickName: u.NickName,
|
||||
PreferredLanguage: preferredLanguage,
|
||||
Gender: genderToDomain(u.Gender),
|
||||
}
|
||||
}
|
||||
|
||||
func emailFromDomain(email *domain.Email) *auth.UserEmail {
|
||||
creationDate, err := ptypes.TimestampProto(email.CreationDate)
|
||||
logging.Log("GRPC-sdoi3").OnError(err).Debug("unable to parse timestamp")
|
||||
|
||||
changeDate, err := ptypes.TimestampProto(email.ChangeDate)
|
||||
logging.Log("GRPC-klJK3").OnError(err).Debug("unable to parse timestamp")
|
||||
|
||||
return &auth.UserEmail{
|
||||
Id: email.AggregateID,
|
||||
CreationDate: creationDate,
|
||||
ChangeDate: changeDate,
|
||||
Sequence: email.Sequence,
|
||||
Email: email.EmailAddress,
|
||||
IsEmailVerified: email.IsEmailVerified,
|
||||
}
|
||||
}
|
||||
|
||||
func emailViewFromModel(email *usr_model.Email) *auth.UserEmailView {
|
||||
creationDate, err := ptypes.TimestampProto(email.CreationDate)
|
||||
logging.Log("GRPC-LSp8s").OnError(err).Debug("unable to parse timestamp")
|
||||
|
||||
changeDate, err := ptypes.TimestampProto(email.ChangeDate)
|
||||
logging.Log("GRPC-6szJe").OnError(err).Debug("unable to parse timestamp")
|
||||
|
||||
return &auth.UserEmailView{
|
||||
Id: email.AggregateID,
|
||||
CreationDate: creationDate,
|
||||
ChangeDate: changeDate,
|
||||
Sequence: email.Sequence,
|
||||
Email: email.EmailAddress,
|
||||
IsEmailVerified: email.IsEmailVerified,
|
||||
}
|
||||
}
|
||||
|
||||
func updateEmailToDomain(ctx context.Context, e *auth.UpdateUserEmailRequest) *domain.Email {
|
||||
return &domain.Email{
|
||||
ObjectRoot: ctxToObjectRoot(ctx),
|
||||
EmailAddress: e.Email,
|
||||
}
|
||||
}
|
||||
|
||||
func phoneFromDomain(phone *domain.Phone) *auth.UserPhone {
|
||||
creationDate, err := ptypes.TimestampProto(phone.CreationDate)
|
||||
logging.Log("GRPC-kjn5J").OnError(err).Debug("unable to parse timestamp")
|
||||
|
||||
changeDate, err := ptypes.TimestampProto(phone.ChangeDate)
|
||||
logging.Log("GRPC-LKA9S").OnError(err).Debug("unable to parse timestamp")
|
||||
|
||||
return &auth.UserPhone{
|
||||
Id: phone.AggregateID,
|
||||
CreationDate: creationDate,
|
||||
ChangeDate: changeDate,
|
||||
Sequence: phone.Sequence,
|
||||
Phone: phone.PhoneNumber,
|
||||
IsPhoneVerified: phone.IsPhoneVerified,
|
||||
}
|
||||
}
|
||||
|
||||
func phoneViewFromModel(phone *usr_model.Phone) *auth.UserPhoneView {
|
||||
creationDate, err := ptypes.TimestampProto(phone.CreationDate)
|
||||
logging.Log("GRPC-s5zJS").OnError(err).Debug("unable to parse timestamp")
|
||||
|
||||
changeDate, err := ptypes.TimestampProto(phone.ChangeDate)
|
||||
logging.Log("GRPC-s9kLe").OnError(err).Debug("unable to parse timestamp")
|
||||
|
||||
return &auth.UserPhoneView{
|
||||
Id: phone.AggregateID,
|
||||
CreationDate: creationDate,
|
||||
ChangeDate: changeDate,
|
||||
Sequence: phone.Sequence,
|
||||
Phone: phone.PhoneNumber,
|
||||
IsPhoneVerified: phone.IsPhoneVerified,
|
||||
}
|
||||
}
|
||||
|
||||
func updatePhoneToDomain(ctx context.Context, e *auth.UpdateUserPhoneRequest) *domain.Phone {
|
||||
return &domain.Phone{
|
||||
ObjectRoot: ctxToObjectRoot(ctx),
|
||||
PhoneNumber: e.Phone,
|
||||
}
|
||||
}
|
||||
|
||||
func addressFromDomain(address *domain.Address) *auth.UserAddress {
|
||||
creationDate, err := ptypes.TimestampProto(address.CreationDate)
|
||||
logging.Log("GRPC-65FRs").OnError(err).Debug("unable to parse timestamp")
|
||||
|
||||
changeDate, err := ptypes.TimestampProto(address.ChangeDate)
|
||||
logging.Log("GRPC-aslk4").OnError(err).Debug("unable to parse timestamp")
|
||||
|
||||
return &auth.UserAddress{
|
||||
Id: address.AggregateID,
|
||||
CreationDate: creationDate,
|
||||
ChangeDate: changeDate,
|
||||
Sequence: address.Sequence,
|
||||
Country: address.Country,
|
||||
StreetAddress: address.StreetAddress,
|
||||
Region: address.Region,
|
||||
PostalCode: address.PostalCode,
|
||||
Locality: address.Locality,
|
||||
}
|
||||
}
|
||||
|
||||
func addressViewFromModel(address *usr_model.Address) *auth.UserAddressView {
|
||||
creationDate, err := ptypes.TimestampProto(address.CreationDate)
|
||||
logging.Log("GRPC-sk4fS").OnError(err).Debug("unable to parse timestamp")
|
||||
|
||||
changeDate, err := ptypes.TimestampProto(address.ChangeDate)
|
||||
logging.Log("GRPC-9siEs").OnError(err).Debug("unable to parse timestamp")
|
||||
|
||||
return &auth.UserAddressView{
|
||||
Id: address.AggregateID,
|
||||
CreationDate: creationDate,
|
||||
ChangeDate: changeDate,
|
||||
Sequence: address.Sequence,
|
||||
Country: address.Country,
|
||||
StreetAddress: address.StreetAddress,
|
||||
Region: address.Region,
|
||||
PostalCode: address.PostalCode,
|
||||
Locality: address.Locality,
|
||||
}
|
||||
}
|
||||
|
||||
func updateAddressToDomain(ctx context.Context, address *auth.UpdateUserAddressRequest) *domain.Address {
|
||||
return &domain.Address{
|
||||
ObjectRoot: ctxToObjectRoot(ctx),
|
||||
Country: address.Country,
|
||||
StreetAddress: address.StreetAddress,
|
||||
Region: address.Region,
|
||||
PostalCode: address.PostalCode,
|
||||
Locality: address.Locality,
|
||||
}
|
||||
}
|
||||
|
||||
func externalIDPSearchRequestToModel(request *auth.ExternalIDPSearchRequest) *usr_model.ExternalIDPSearchRequest {
|
||||
return &usr_model.ExternalIDPSearchRequest{
|
||||
Limit: request.Limit,
|
||||
Offset: request.Offset,
|
||||
}
|
||||
}
|
||||
|
||||
func externalIDPRemoveToDomain(ctx context.Context, idp *auth.ExternalIDPRemoveRequest) *domain.ExternalIDP {
|
||||
return &domain.ExternalIDP{
|
||||
ObjectRoot: ctxToObjectRoot(ctx),
|
||||
IDPConfigID: idp.IdpConfigId,
|
||||
ExternalUserID: idp.ExternalUserId,
|
||||
}
|
||||
}
|
||||
|
||||
func externalIDPResponseFromModel(idp *usr_model.ExternalIDP) *auth.ExternalIDPResponse {
|
||||
return &auth.ExternalIDPResponse{
|
||||
IdpConfigId: idp.IDPConfigID,
|
||||
UserId: idp.UserID,
|
||||
DisplayName: idp.DisplayName,
|
||||
}
|
||||
}
|
||||
|
||||
func externalIDPSearchResponseFromModel(response *usr_model.ExternalIDPSearchResponse) *auth.ExternalIDPSearchResponse {
|
||||
viewTimestamp, err := ptypes.TimestampProto(response.Timestamp)
|
||||
logging.Log("GRPC-3h8is").OnError(err).Debug("unable to parse timestamp")
|
||||
|
||||
return &auth.ExternalIDPSearchResponse{
|
||||
Offset: response.Offset,
|
||||
Limit: response.Limit,
|
||||
TotalResult: response.TotalResult,
|
||||
ProcessedSequence: response.Sequence,
|
||||
ViewTimestamp: viewTimestamp,
|
||||
Result: externalIDPViewsFromModel(response.Result),
|
||||
}
|
||||
}
|
||||
|
||||
func externalIDPViewsFromModel(externalIDPs []*usr_model.ExternalIDPView) []*auth.ExternalIDPView {
|
||||
converted := make([]*auth.ExternalIDPView, len(externalIDPs))
|
||||
for i, externalIDP := range externalIDPs {
|
||||
converted[i] = externalIDPViewFromModel(externalIDP)
|
||||
}
|
||||
return converted
|
||||
}
|
||||
|
||||
func externalIDPViewFromModel(externalIDP *usr_model.ExternalIDPView) *auth.ExternalIDPView {
|
||||
creationDate, err := ptypes.TimestampProto(externalIDP.CreationDate)
|
||||
logging.Log("GRPC-Sj8dw").OnError(err).Debug("unable to parse timestamp")
|
||||
|
||||
changeDate, err := ptypes.TimestampProto(externalIDP.ChangeDate)
|
||||
logging.Log("GRPC-Nf8ue").OnError(err).Debug("unable to parse timestamp")
|
||||
|
||||
return &auth.ExternalIDPView{
|
||||
UserId: externalIDP.UserID,
|
||||
IdpConfigId: externalIDP.IDPConfigID,
|
||||
ExternalUserId: externalIDP.ExternalUserID,
|
||||
ExternalUserDisplayName: externalIDP.UserDisplayName,
|
||||
IdpName: externalIDP.IDPName,
|
||||
CreationDate: creationDate,
|
||||
ChangeDate: changeDate,
|
||||
}
|
||||
}
|
||||
|
||||
func otpFromDomain(otp *domain.OTP) *auth.MfaOtpResponse {
|
||||
return &auth.MfaOtpResponse{
|
||||
UserId: otp.AggregateID,
|
||||
Url: otp.Url,
|
||||
Secret: otp.SecretString,
|
||||
State: mfaStateFromDomain(otp.State),
|
||||
}
|
||||
}
|
||||
|
||||
func userStateFromModel(state usr_model.UserState) auth.UserState {
|
||||
switch state {
|
||||
case usr_model.UserStateActive:
|
||||
return auth.UserState_USERSTATE_ACTIVE
|
||||
case usr_model.UserStateInactive:
|
||||
return auth.UserState_USERSTATE_INACTIVE
|
||||
case usr_model.UserStateLocked:
|
||||
return auth.UserState_USERSTATE_LOCKED
|
||||
case usr_model.UserStateInitial:
|
||||
return auth.UserState_USERSTATE_INITIAL
|
||||
case usr_model.UserStateSuspend:
|
||||
return auth.UserState_USERSTATE_SUSPEND
|
||||
default:
|
||||
return auth.UserState_USERSTATE_UNSPECIFIED
|
||||
}
|
||||
}
|
||||
|
||||
func genderFromDomain(gender domain.Gender) auth.Gender {
|
||||
switch gender {
|
||||
case domain.GenderFemale:
|
||||
return auth.Gender_GENDER_FEMALE
|
||||
case domain.GenderMale:
|
||||
return auth.Gender_GENDER_MALE
|
||||
case domain.GenderDiverse:
|
||||
return auth.Gender_GENDER_DIVERSE
|
||||
default:
|
||||
return auth.Gender_GENDER_UNSPECIFIED
|
||||
}
|
||||
}
|
||||
|
||||
func genderFromModel(gender usr_model.Gender) auth.Gender {
|
||||
switch gender {
|
||||
case usr_model.GenderFemale:
|
||||
return auth.Gender_GENDER_FEMALE
|
||||
case usr_model.GenderMale:
|
||||
return auth.Gender_GENDER_MALE
|
||||
case usr_model.GenderDiverse:
|
||||
return auth.Gender_GENDER_DIVERSE
|
||||
default:
|
||||
return auth.Gender_GENDER_UNSPECIFIED
|
||||
}
|
||||
}
|
||||
|
||||
func genderToDomain(gender auth.Gender) domain.Gender {
|
||||
switch gender {
|
||||
case auth.Gender_GENDER_FEMALE:
|
||||
return domain.GenderFemale
|
||||
case auth.Gender_GENDER_MALE:
|
||||
return domain.GenderMale
|
||||
case auth.Gender_GENDER_DIVERSE:
|
||||
return domain.GenderDiverse
|
||||
default:
|
||||
return domain.GenderUnspecified
|
||||
}
|
||||
}
|
||||
|
||||
func mfaStateFromDomain(state domain.MFAState) auth.MFAState {
|
||||
switch state {
|
||||
case domain.MFAStateReady:
|
||||
return auth.MFAState_MFASTATE_READY
|
||||
case domain.MFAStateNotReady:
|
||||
return auth.MFAState_MFASTATE_NOT_READY
|
||||
default:
|
||||
return auth.MFAState_MFASTATE_UNSPECIFIED
|
||||
}
|
||||
}
|
||||
|
||||
func mfasFromModel(mfas []*usr_model.MultiFactor) []*auth.MultiFactor {
|
||||
converted := make([]*auth.MultiFactor, len(mfas))
|
||||
for i, mfa := range mfas {
|
||||
converted[i] = mfaFromModel(mfa)
|
||||
}
|
||||
return converted
|
||||
}
|
||||
|
||||
func mfaFromModel(mfa *usr_model.MultiFactor) *auth.MultiFactor {
|
||||
return &auth.MultiFactor{
|
||||
State: auth.MFAState(mfa.State),
|
||||
Type: mfaTypeFromModel(mfa.Type),
|
||||
Attribute: mfa.Attribute,
|
||||
Id: mfa.ID,
|
||||
}
|
||||
}
|
||||
|
||||
func mfaTypeFromModel(mfaType usr_model.MFAType) auth.MfaType {
|
||||
switch mfaType {
|
||||
case usr_model.MFATypeOTP:
|
||||
return auth.MfaType_MFATYPE_OTP
|
||||
case usr_model.MFATypeU2F:
|
||||
return auth.MfaType_MFATYPE_U2F
|
||||
default:
|
||||
return auth.MfaType_MFATYPE_UNSPECIFIED
|
||||
}
|
||||
}
|
||||
|
||||
func userChangesToResponse(response *usr_model.UserChanges, offset uint64, limit uint64) (_ *auth.Changes) {
|
||||
return &auth.Changes{
|
||||
Limit: limit,
|
||||
Offset: offset,
|
||||
Changes: userChangesToAPI(response),
|
||||
}
|
||||
}
|
||||
|
||||
func userChangesToAPI(changes *usr_model.UserChanges) (_ []*auth.Change) {
|
||||
result := make([]*auth.Change, len(changes.Changes))
|
||||
|
||||
for i, change := range changes.Changes {
|
||||
var data *structpb.Struct
|
||||
changedData, err := json.Marshal(change.Data)
|
||||
if err == nil {
|
||||
data = new(structpb.Struct)
|
||||
err = protojson.Unmarshal(changedData, data)
|
||||
logging.Log("GRPC-0kRsY").OnError(err).Debug("unable to marshal changed data to struct")
|
||||
}
|
||||
result[i] = &auth.Change{
|
||||
ChangeDate: change.ChangeDate,
|
||||
EventType: message.NewLocalizedEventType(change.EventType),
|
||||
Sequence: change.Sequence,
|
||||
Data: data,
|
||||
EditorId: change.ModifierID,
|
||||
Editor: change.ModifierName,
|
||||
}
|
||||
}
|
||||
|
||||
return result
|
||||
}
|
||||
|
||||
func verifyWebAuthNFromDomain(u2f *domain.WebAuthNToken) *auth.WebAuthNResponse {
|
||||
return &auth.WebAuthNResponse{
|
||||
Id: u2f.WebAuthNTokenID,
|
||||
PublicKey: u2f.CredentialCreationData,
|
||||
State: mfaStateFromDomain(u2f.State),
|
||||
}
|
||||
}
|
||||
|
||||
func webAuthNTokensFromModel(tokens []*usr_model.WebAuthNView) *auth.WebAuthNTokens {
|
||||
result := make([]*auth.WebAuthNToken, len(tokens))
|
||||
for i, token := range tokens {
|
||||
result[i] = webAuthNTokenFromModel(token)
|
||||
}
|
||||
return &auth.WebAuthNTokens{Tokens: result}
|
||||
}
|
||||
|
||||
func webAuthNTokenFromModel(token *usr_model.WebAuthNView) *auth.WebAuthNToken {
|
||||
return &auth.WebAuthNToken{
|
||||
Id: token.TokenID,
|
||||
Name: token.Name,
|
||||
State: auth.MFAState(token.State),
|
||||
}
|
||||
}
|
||||
|
||||
func ctxToObjectRoot(ctx context.Context) models.ObjectRoot {
|
||||
ctxData := authz.GetCtxData(ctx)
|
||||
return models.ObjectRoot{
|
||||
AggregateID: ctxData.UserID,
|
||||
ResourceOwner: ctxData.ResourceOwner,
|
||||
}
|
||||
}
|
||||
|
||||
func userMembershipSearchResponseFromModel(response *usr_model.UserMembershipSearchResponse) *auth.UserMembershipSearchResponse {
|
||||
timestamp, err := ptypes.TimestampProto(response.Timestamp)
|
||||
logging.Log("GRPC-Hs8jd").OnError(err).Debug("unable to parse timestamp")
|
||||
return &auth.UserMembershipSearchResponse{
|
||||
Offset: response.Offset,
|
||||
Limit: response.Limit,
|
||||
TotalResult: response.TotalResult,
|
||||
Result: userMembershipViewsFromModel(response.Result),
|
||||
ProcessedSequence: response.Sequence,
|
||||
ViewTimestamp: timestamp,
|
||||
}
|
||||
}
|
||||
|
||||
func userMembershipViewsFromModel(memberships []*usr_model.UserMembershipView) []*auth.UserMembershipView {
|
||||
converted := make([]*auth.UserMembershipView, len(memberships))
|
||||
for i, membership := range memberships {
|
||||
converted[i] = userMembershipViewFromModel(membership)
|
||||
}
|
||||
return converted
|
||||
}
|
||||
|
||||
func userMembershipViewFromModel(membership *usr_model.UserMembershipView) *auth.UserMembershipView {
|
||||
creationDate, err := ptypes.TimestampProto(membership.CreationDate)
|
||||
logging.Log("GRPC-Msnu8").OnError(err).Debug("unable to parse timestamp")
|
||||
|
||||
changeDate, err := ptypes.TimestampProto(membership.ChangeDate)
|
||||
logging.Log("GRPC-Slco9").OnError(err).Debug("unable to parse timestamp")
|
||||
|
||||
return &auth.UserMembershipView{
|
||||
UserId: membership.UserID,
|
||||
AggregateId: membership.AggregateID,
|
||||
ObjectId: membership.ObjectID,
|
||||
MemberType: memberTypeFromModel(membership.MemberType),
|
||||
DisplayName: membership.DisplayName,
|
||||
Roles: membership.Roles,
|
||||
CreationDate: creationDate,
|
||||
ChangeDate: changeDate,
|
||||
Sequence: membership.Sequence,
|
||||
ResourceOwner: membership.ResourceOwner,
|
||||
}
|
||||
}
|
||||
|
||||
func userMembershipSearchRequestsToModel(request *auth.UserMembershipSearchRequest) *usr_model.UserMembershipSearchRequest {
|
||||
return &usr_model.UserMembershipSearchRequest{
|
||||
Offset: request.Offset,
|
||||
Limit: request.Limit,
|
||||
Queries: userMembershipSearchQueriesToModel(request.Queries),
|
||||
}
|
||||
}
|
||||
|
||||
func userMembershipSearchQueriesToModel(queries []*auth.UserMembershipSearchQuery) []*usr_model.UserMembershipSearchQuery {
|
||||
converted := make([]*usr_model.UserMembershipSearchQuery, len(queries))
|
||||
for i, q := range queries {
|
||||
converted[i] = userMembershipSearchQueryToModel(q)
|
||||
}
|
||||
return converted
|
||||
}
|
||||
|
||||
func userMembershipSearchQueryToModel(query *auth.UserMembershipSearchQuery) *usr_model.UserMembershipSearchQuery {
|
||||
return &usr_model.UserMembershipSearchQuery{
|
||||
Key: userMembershipSearchKeyToModel(query.Key),
|
||||
Method: searchMethodToModel(query.Method),
|
||||
Value: query.Value,
|
||||
}
|
||||
}
|
||||
|
||||
func userMembershipSearchKeyToModel(key auth.UserMembershipSearchKey) usr_model.UserMembershipSearchKey {
|
||||
switch key {
|
||||
case auth.UserMembershipSearchKey_USERMEMBERSHIPSEARCHKEY_TYPE:
|
||||
return usr_model.UserMembershipSearchKeyMemberType
|
||||
case auth.UserMembershipSearchKey_USERMEMBERSHIPSEARCHKEY_OBJECT_ID:
|
||||
return usr_model.UserMembershipSearchKeyObjectID
|
||||
default:
|
||||
return usr_model.UserMembershipSearchKeyUnspecified
|
||||
}
|
||||
}
|
||||
|
||||
func memberTypeFromModel(memberType usr_model.MemberType) auth.MemberType {
|
||||
switch memberType {
|
||||
case usr_model.MemberTypeOrganisation:
|
||||
return auth.MemberType_MEMBERTYPE_ORGANISATION
|
||||
case usr_model.MemberTypeProject:
|
||||
return auth.MemberType_MEMBERTYPE_PROJECT
|
||||
case usr_model.MemberTypeProjectGrant:
|
||||
return auth.MemberType_MEMBERTYPE_PROJECT_GRANT
|
||||
default:
|
||||
return auth.MemberType_MEMBERTYPE_UNSPECIFIED
|
||||
}
|
||||
}
|
@@ -1,41 +1,33 @@
|
||||
package auth
|
||||
|
||||
import (
|
||||
"context"
|
||||
|
||||
"github.com/golang/protobuf/ptypes/empty"
|
||||
|
||||
"github.com/caos/zitadel/pkg/grpc/auth"
|
||||
"github.com/caos/zitadel/internal/usergrant/model"
|
||||
auth_pb "github.com/caos/zitadel/pkg/grpc/auth"
|
||||
)
|
||||
|
||||
func (s *Server) SearchMyUserGrant(ctx context.Context, in *auth.UserGrantSearchRequest) (*auth.UserGrantSearchResponse, error) {
|
||||
response, err := s.repo.SearchMyUserGrants(ctx, userGrantSearchRequestsToModel(in))
|
||||
if err != nil {
|
||||
return nil, err
|
||||
func ListMyUserGrantsRequestToModel(req *auth_pb.ListMyUserGrantsRequest) *model.UserGrantSearchRequest {
|
||||
return &model.UserGrantSearchRequest{
|
||||
Offset: req.Query.Offset,
|
||||
Limit: uint64(req.Query.Limit),
|
||||
Asc: req.Query.Asc,
|
||||
}
|
||||
return userGrantSearchResponseFromModel(response), nil
|
||||
}
|
||||
|
||||
func (s *Server) SearchMyProjectOrgs(ctx context.Context, in *auth.MyProjectOrgSearchRequest) (*auth.MyProjectOrgSearchResponse, error) {
|
||||
response, err := s.repo.SearchMyProjectOrgs(ctx, myProjectOrgSearchRequestRequestsToModel(in))
|
||||
if err != nil {
|
||||
return nil, err
|
||||
func UserGrantsToPb(grants []*model.UserGrantView) []*auth_pb.UserGrant {
|
||||
userGrants := make([]*auth_pb.UserGrant, len(grants))
|
||||
for i, grant := range grants {
|
||||
userGrants[i] = UserGrantToPb(grant)
|
||||
}
|
||||
return projectOrgSearchResponseFromModel(response), nil
|
||||
return userGrants
|
||||
}
|
||||
|
||||
func (s *Server) GetMyZitadelPermissions(ctx context.Context, _ *empty.Empty) (*auth.MyPermissions, error) {
|
||||
perms, err := s.repo.SearchMyZitadelPermissions(ctx)
|
||||
if err != nil {
|
||||
return nil, err
|
||||
func UserGrantToPb(grant *model.UserGrantView) *auth_pb.UserGrant {
|
||||
return &auth_pb.UserGrant{
|
||||
GrantId: grant.ID,
|
||||
OrgId: grant.ResourceOwner,
|
||||
OrgName: grant.OrgName,
|
||||
ProjectId: grant.ProjectID,
|
||||
UserId: grant.UserID,
|
||||
Roles: grant.RoleKeys,
|
||||
}
|
||||
return &auth.MyPermissions{Permissions: perms}, nil
|
||||
}
|
||||
|
||||
func (s *Server) GetMyProjectPermissions(ctx context.Context, _ *empty.Empty) (*auth.MyPermissions, error) {
|
||||
perms, err := s.repo.SearchMyProjectPermissions(ctx)
|
||||
if err != nil {
|
||||
return nil, err
|
||||
}
|
||||
return &auth.MyPermissions{Permissions: perms}, nil
|
||||
}
|
||||
|
@@ -1,135 +0,0 @@
|
||||
package auth
|
||||
|
||||
import (
|
||||
"github.com/caos/logging"
|
||||
grant_model "github.com/caos/zitadel/internal/usergrant/model"
|
||||
"github.com/caos/zitadel/pkg/grpc/auth"
|
||||
"github.com/golang/protobuf/ptypes"
|
||||
)
|
||||
|
||||
func userGrantSearchRequestsToModel(request *auth.UserGrantSearchRequest) *grant_model.UserGrantSearchRequest {
|
||||
return &grant_model.UserGrantSearchRequest{
|
||||
Offset: request.Offset,
|
||||
Limit: request.Limit,
|
||||
Queries: userGrantSearchQueriesToModel(request.Queries),
|
||||
}
|
||||
}
|
||||
|
||||
func userGrantSearchQueriesToModel(queries []*auth.UserGrantSearchQuery) []*grant_model.UserGrantSearchQuery {
|
||||
converted := make([]*grant_model.UserGrantSearchQuery, len(queries))
|
||||
for i, q := range queries {
|
||||
converted[i] = userGrantSearchQueryToModel(q)
|
||||
}
|
||||
return converted
|
||||
}
|
||||
|
||||
func userGrantSearchQueryToModel(query *auth.UserGrantSearchQuery) *grant_model.UserGrantSearchQuery {
|
||||
return &grant_model.UserGrantSearchQuery{
|
||||
Key: userGrantSearchKeyToModel(query.Key),
|
||||
Method: searchMethodToModel(query.Method),
|
||||
Value: query.Value,
|
||||
}
|
||||
}
|
||||
|
||||
func userGrantSearchKeyToModel(key auth.UserGrantSearchKey) grant_model.UserGrantSearchKey {
|
||||
switch key {
|
||||
case auth.UserGrantSearchKey_UserGrantSearchKey_ORG_ID:
|
||||
return grant_model.UserGrantSearchKeyResourceOwner
|
||||
case auth.UserGrantSearchKey_UserGrantSearchKey_PROJECT_ID:
|
||||
return grant_model.UserGrantSearchKeyProjectID
|
||||
default:
|
||||
return grant_model.UserGrantSearchKeyUnspecified
|
||||
}
|
||||
}
|
||||
|
||||
func myProjectOrgSearchRequestRequestsToModel(request *auth.MyProjectOrgSearchRequest) *grant_model.UserGrantSearchRequest {
|
||||
return &grant_model.UserGrantSearchRequest{
|
||||
Offset: request.Offset,
|
||||
Limit: request.Limit,
|
||||
Asc: request.Asc,
|
||||
SortingColumn: grant_model.UserGrantSearchKeyResourceOwner,
|
||||
Queries: myProjectOrgSearchQueriesToModel(request.Queries),
|
||||
}
|
||||
}
|
||||
|
||||
func myProjectOrgSearchQueriesToModel(queries []*auth.MyProjectOrgSearchQuery) []*grant_model.UserGrantSearchQuery {
|
||||
converted := make([]*grant_model.UserGrantSearchQuery, len(queries))
|
||||
for i, q := range queries {
|
||||
converted[i] = myProjectOrgSearchQueryToModel(q)
|
||||
}
|
||||
return converted
|
||||
}
|
||||
|
||||
func myProjectOrgSearchQueryToModel(query *auth.MyProjectOrgSearchQuery) *grant_model.UserGrantSearchQuery {
|
||||
return &grant_model.UserGrantSearchQuery{
|
||||
Key: myProjectOrgSearchKeyToModel(query.Key),
|
||||
Method: searchMethodToModel(query.Method),
|
||||
Value: query.Value,
|
||||
}
|
||||
}
|
||||
|
||||
func myProjectOrgSearchKeyToModel(key auth.MyProjectOrgSearchKey) grant_model.UserGrantSearchKey {
|
||||
switch key {
|
||||
case auth.MyProjectOrgSearchKey_MYPROJECTORGSEARCHKEY_ORG_NAME:
|
||||
return grant_model.UserGrantSearchKeyOrgName
|
||||
default:
|
||||
return grant_model.UserGrantSearchKeyUnspecified
|
||||
}
|
||||
}
|
||||
|
||||
func userGrantSearchResponseFromModel(response *grant_model.UserGrantSearchResponse) *auth.UserGrantSearchResponse {
|
||||
timestamp, err := ptypes.TimestampProto(response.Timestamp)
|
||||
logging.Log("GRPC-Lsp0d").OnError(err).Debug("unable to parse timestamp")
|
||||
|
||||
return &auth.UserGrantSearchResponse{
|
||||
Offset: response.Offset,
|
||||
Limit: response.Limit,
|
||||
TotalResult: response.TotalResult,
|
||||
Result: userGrantViewsFromModel(response.Result),
|
||||
ProcessedSequence: response.Sequence,
|
||||
ViewTimestamp: timestamp,
|
||||
}
|
||||
}
|
||||
|
||||
func userGrantViewsFromModel(users []*grant_model.UserGrantView) []*auth.UserGrantView {
|
||||
converted := make([]*auth.UserGrantView, len(users))
|
||||
for i, user := range users {
|
||||
converted[i] = userGrantViewFromModel(user)
|
||||
}
|
||||
return converted
|
||||
}
|
||||
|
||||
func userGrantViewFromModel(grant *grant_model.UserGrantView) *auth.UserGrantView {
|
||||
return &auth.UserGrantView{
|
||||
UserId: grant.UserID,
|
||||
OrgId: grant.ResourceOwner,
|
||||
OrgName: grant.OrgName,
|
||||
ProjectId: grant.ProjectID,
|
||||
Roles: grant.RoleKeys,
|
||||
GrantId: grant.GrantID,
|
||||
}
|
||||
}
|
||||
|
||||
func projectOrgSearchResponseFromModel(response *grant_model.ProjectOrgSearchResponse) *auth.MyProjectOrgSearchResponse {
|
||||
return &auth.MyProjectOrgSearchResponse{
|
||||
Offset: response.Offset,
|
||||
Limit: response.Limit,
|
||||
TotalResult: response.TotalResult,
|
||||
Result: projectOrgsFromModel(response.Result),
|
||||
}
|
||||
}
|
||||
|
||||
func projectOrgsFromModel(projectOrgs []*grant_model.Org) []*auth.Org {
|
||||
converted := make([]*auth.Org, len(projectOrgs))
|
||||
for i, org := range projectOrgs {
|
||||
converted[i] = projectOrgFromModel(org)
|
||||
}
|
||||
return converted
|
||||
}
|
||||
|
||||
func projectOrgFromModel(org *grant_model.Org) *auth.Org {
|
||||
return &auth.Org{
|
||||
Id: org.OrgID,
|
||||
Name: org.OrgName,
|
||||
}
|
||||
}
|
@@ -1,32 +0,0 @@
|
||||
package auth
|
||||
|
||||
import (
|
||||
"github.com/caos/logging"
|
||||
usr_model "github.com/caos/zitadel/internal/user/model"
|
||||
"github.com/caos/zitadel/pkg/grpc/auth"
|
||||
"github.com/golang/protobuf/ptypes"
|
||||
)
|
||||
|
||||
func humanViewFromModel(user *usr_model.HumanView) *auth.HumanView {
|
||||
passwordChanged, err := ptypes.TimestampProto(user.PasswordChanged)
|
||||
logging.Log("MANAG-h4ByY").OnError(err).Debug("unable to parse date")
|
||||
|
||||
return &auth.HumanView{
|
||||
FirstName: user.FirstName,
|
||||
LastName: user.LastName,
|
||||
DisplayName: user.DisplayName,
|
||||
NickName: user.NickName,
|
||||
PreferredLanguage: user.PreferredLanguage,
|
||||
Gender: genderFromModel(user.Gender),
|
||||
Email: user.Email,
|
||||
IsEmailVerified: user.IsEmailVerified,
|
||||
Phone: user.Phone,
|
||||
IsPhoneVerified: user.IsPhoneVerified,
|
||||
Country: user.Country,
|
||||
Locality: user.Locality,
|
||||
PostalCode: user.PostalCode,
|
||||
Region: user.Region,
|
||||
StreetAddress: user.StreetAddress,
|
||||
PasswordChanged: passwordChanged,
|
||||
}
|
||||
}
|
@@ -1,19 +0,0 @@
|
||||
package auth
|
||||
|
||||
import (
|
||||
"github.com/caos/logging"
|
||||
"github.com/golang/protobuf/ptypes"
|
||||
|
||||
usr_model "github.com/caos/zitadel/internal/user/model"
|
||||
"github.com/caos/zitadel/pkg/grpc/auth"
|
||||
)
|
||||
|
||||
func machineViewFromModel(machine *usr_model.MachineView) *auth.MachineView {
|
||||
lastKeyAdded, err := ptypes.TimestampProto(machine.LastKeyAdded)
|
||||
logging.Log("MANAG-wGcAQ").OnError(err).Debug("unable to parse date")
|
||||
return &auth.MachineView{
|
||||
Description: machine.Description,
|
||||
Name: machine.Name,
|
||||
LastKeyAdded: lastKeyAdded,
|
||||
}
|
||||
}
|
@@ -1,17 +0,0 @@
|
||||
package auth
|
||||
|
||||
import (
|
||||
"context"
|
||||
|
||||
"github.com/golang/protobuf/ptypes/empty"
|
||||
|
||||
"github.com/caos/zitadel/pkg/grpc/auth"
|
||||
)
|
||||
|
||||
func (s *Server) GetMyUserSessions(ctx context.Context, _ *empty.Empty) (_ *auth.UserSessionViews, err error) {
|
||||
userSessions, err := s.repo.GetMyUserSessions(ctx)
|
||||
if err != nil {
|
||||
return nil, err
|
||||
}
|
||||
return &auth.UserSessionViews{UserSessions: userSessionViewsFromModel(userSessions)}, nil
|
||||
}
|
@@ -1,38 +0,0 @@
|
||||
package auth
|
||||
|
||||
import (
|
||||
auth_req_model "github.com/caos/zitadel/internal/auth_request/model"
|
||||
usr_model "github.com/caos/zitadel/internal/user/model"
|
||||
"github.com/caos/zitadel/pkg/grpc/auth"
|
||||
)
|
||||
|
||||
func userSessionViewsFromModel(userSessions []*usr_model.UserSessionView) []*auth.UserSessionView {
|
||||
converted := make([]*auth.UserSessionView, len(userSessions))
|
||||
for i, s := range userSessions {
|
||||
converted[i] = userSessionViewFromModel(s)
|
||||
}
|
||||
return converted
|
||||
}
|
||||
|
||||
func userSessionViewFromModel(userSession *usr_model.UserSessionView) *auth.UserSessionView {
|
||||
return &auth.UserSessionView{
|
||||
Sequence: userSession.Sequence,
|
||||
AgentId: userSession.UserAgentID,
|
||||
UserId: userSession.UserID,
|
||||
UserName: userSession.UserName,
|
||||
LoginName: userSession.LoginName,
|
||||
DisplayName: userSession.DisplayName,
|
||||
AuthState: userSessionStateFromModel(userSession.State),
|
||||
}
|
||||
}
|
||||
|
||||
func userSessionStateFromModel(state auth_req_model.UserSessionState) auth.UserSessionState {
|
||||
switch state {
|
||||
case auth_req_model.UserSessionStateActive:
|
||||
return auth.UserSessionState_USERSESSIONSTATE_ACTIVE
|
||||
case auth_req_model.UserSessionStateTerminated:
|
||||
return auth.UserSessionState_USERSESSIONSTATE_TERMINATED
|
||||
default:
|
||||
return auth.UserSessionState_USERSESSIONSTATE_UNSPECIFIED
|
||||
}
|
||||
}
|
Reference in New Issue
Block a user