mirror of
https://github.com/zitadel/zitadel.git
synced 2025-08-11 21:37:32 +00:00
feat: user v3 api update (#8582)
# Which Problems Are Solved Users are not yet able to update their information an status in user API v3. # How the Problems Are Solved Add endpoints and functionality to update users and their status in user API v3. # Additional Changes Aggregate_type and event_types are updated with "userschema" to avoid conflicts with old events. # Additional Context closes #7898
This commit is contained in:
@@ -250,16 +250,26 @@ func TestServer_ExecutionTarget(t *testing.T) {
|
||||
require.NoError(t, err)
|
||||
defer close()
|
||||
}
|
||||
|
||||
got, err := instance.Client.ActionV3Alpha.GetTarget(tt.ctx, tt.req)
|
||||
if tt.wantErr {
|
||||
require.Error(t, err)
|
||||
return
|
||||
retryDuration := 5 * time.Second
|
||||
if ctxDeadline, ok := isolatedIAMOwnerCTX.Deadline(); ok {
|
||||
retryDuration = time.Until(ctxDeadline)
|
||||
}
|
||||
require.NoError(t, err)
|
||||
|
||||
integration.AssertResourceDetails(t, tt.want.GetTarget().GetDetails(), got.GetTarget().GetDetails())
|
||||
assert.Equal(t, tt.want.GetTarget().GetConfig(), got.GetTarget().GetConfig())
|
||||
require.EventuallyWithT(t, func(ttt *assert.CollectT) {
|
||||
got, err := instance.Client.ActionV3Alpha.GetTarget(tt.ctx, tt.req)
|
||||
if tt.wantErr {
|
||||
assert.Error(ttt, err, "Error: "+err.Error())
|
||||
} else {
|
||||
assert.NoError(ttt, err)
|
||||
}
|
||||
if err != nil {
|
||||
return
|
||||
}
|
||||
|
||||
integration.AssertResourceDetails(t, tt.want.GetTarget().GetDetails(), got.GetTarget().GetDetails())
|
||||
assert.Equal(t, tt.want.GetTarget().GetConfig(), got.GetTarget().GetConfig())
|
||||
}, retryDuration, time.Millisecond*100, "timeout waiting for expected execution result")
|
||||
|
||||
if tt.clean != nil {
|
||||
tt.clean(tt.ctx)
|
||||
}
|
||||
|
@@ -75,3 +75,18 @@ func SearchQueryPbToQuery(defaults systemdefaults.SystemDefaults, query *resourc
|
||||
}
|
||||
return offset, limit, asc, nil
|
||||
}
|
||||
|
||||
func ResourceOwnerFromOrganization(organization *object.Organization) string {
|
||||
if organization == nil {
|
||||
return ""
|
||||
}
|
||||
|
||||
if organization.GetOrgId() != "" {
|
||||
return organization.GetOrgId()
|
||||
}
|
||||
if organization.GetOrgDomain() != "" {
|
||||
// TODO get org from domain
|
||||
return ""
|
||||
}
|
||||
return ""
|
||||
}
|
||||
|
@@ -14,50 +14,41 @@ import (
|
||||
|
||||
"github.com/zitadel/zitadel/internal/integration"
|
||||
"github.com/zitadel/zitadel/pkg/grpc/feature/v2"
|
||||
user "github.com/zitadel/zitadel/pkg/grpc/resources/user/v3alpha"
|
||||
)
|
||||
|
||||
var (
|
||||
IAMOwnerCTX, SystemCTX context.Context
|
||||
UserCTX context.Context
|
||||
Instance *integration.Instance
|
||||
Client user.ZITADELUsersClient
|
||||
CTX context.Context
|
||||
)
|
||||
|
||||
func TestMain(m *testing.M) {
|
||||
os.Exit(func() int {
|
||||
ctx, cancel := context.WithTimeout(context.Background(), 15*time.Minute)
|
||||
defer cancel()
|
||||
|
||||
Instance = integration.NewInstance(ctx)
|
||||
|
||||
IAMOwnerCTX = Instance.WithAuthorization(ctx, integration.UserTypeIAMOwner)
|
||||
SystemCTX = integration.WithSystemAuthorization(ctx)
|
||||
UserCTX = Instance.WithAuthorization(ctx, integration.UserTypeLogin)
|
||||
Client = Instance.Client.UserV3Alpha
|
||||
CTX = ctx
|
||||
return m.Run()
|
||||
}())
|
||||
}
|
||||
|
||||
func ensureFeatureEnabled(t *testing.T, iamOwnerCTX context.Context) {
|
||||
f, err := Instance.Client.FeatureV2.GetInstanceFeatures(iamOwnerCTX, &feature.GetInstanceFeaturesRequest{
|
||||
func ensureFeatureEnabled(t *testing.T, instance *integration.Instance) {
|
||||
ctx := instance.WithAuthorization(CTX, integration.UserTypeIAMOwner)
|
||||
f, err := instance.Client.FeatureV2.GetInstanceFeatures(ctx, &feature.GetInstanceFeaturesRequest{
|
||||
Inheritance: true,
|
||||
})
|
||||
require.NoError(t, err)
|
||||
if f.UserSchema.GetEnabled() {
|
||||
return
|
||||
}
|
||||
_, err = Instance.Client.FeatureV2.SetInstanceFeatures(iamOwnerCTX, &feature.SetInstanceFeaturesRequest{
|
||||
_, err = instance.Client.FeatureV2.SetInstanceFeatures(ctx, &feature.SetInstanceFeaturesRequest{
|
||||
UserSchema: gu.Ptr(true),
|
||||
})
|
||||
require.NoError(t, err)
|
||||
retryDuration := time.Minute
|
||||
if ctxDeadline, ok := iamOwnerCTX.Deadline(); ok {
|
||||
if ctxDeadline, ok := ctx.Deadline(); ok {
|
||||
retryDuration = time.Until(ctxDeadline)
|
||||
}
|
||||
require.EventuallyWithT(t,
|
||||
func(ttt *assert.CollectT) {
|
||||
f, err := Instance.Client.FeatureV2.GetInstanceFeatures(iamOwnerCTX, &feature.GetInstanceFeaturesRequest{
|
||||
f, err := instance.Client.FeatureV2.GetInstanceFeatures(ctx, &feature.GetInstanceFeaturesRequest{
|
||||
Inheritance: true,
|
||||
})
|
||||
require.NoError(ttt, err)
|
||||
|
File diff suppressed because it is too large
Load Diff
@@ -8,6 +8,7 @@ import (
|
||||
"github.com/zitadel/zitadel/internal/api/authz"
|
||||
resource_object "github.com/zitadel/zitadel/internal/api/grpc/resources/object/v3alpha"
|
||||
"github.com/zitadel/zitadel/internal/command"
|
||||
"github.com/zitadel/zitadel/internal/domain"
|
||||
"github.com/zitadel/zitadel/internal/zerrors"
|
||||
object "github.com/zitadel/zitadel/pkg/grpc/object/v3alpha"
|
||||
"github.com/zitadel/zitadel/pkg/grpc/resources/user/v3alpha"
|
||||
@@ -26,7 +27,7 @@ func (s *Server) CreateUser(ctx context.Context, req *user.CreateUserRequest) (_
|
||||
return nil, err
|
||||
}
|
||||
return &user.CreateUserResponse{
|
||||
Details: resource_object.DomainToDetailsPb(schemauser.Details, object.OwnerType_OWNER_TYPE_ORG, schemauser.ResourceOwner),
|
||||
Details: resource_object.DomainToDetailsPb(schemauser.Details, object.OwnerType_OWNER_TYPE_ORG, schemauser.Details.ResourceOwner),
|
||||
EmailCode: gu.Ptr(schemauser.ReturnCodeEmail),
|
||||
PhoneCode: gu.Ptr(schemauser.ReturnCodePhone),
|
||||
}, nil
|
||||
@@ -37,19 +38,35 @@ func createUserRequestToCreateSchemaUser(ctx context.Context, req *user.CreateUs
|
||||
if err != nil {
|
||||
return nil, err
|
||||
}
|
||||
|
||||
return &command.CreateSchemaUser{
|
||||
ResourceOwner: authz.GetCtxData(ctx).OrgID,
|
||||
ResourceOwner: organizationToCreateResourceOwner(ctx, req.Organization),
|
||||
SchemaID: req.GetUser().GetSchemaId(),
|
||||
ID: req.GetUser().GetUserId(),
|
||||
Data: data,
|
||||
}, nil
|
||||
}
|
||||
|
||||
func organizationToCreateResourceOwner(ctx context.Context, org *object.Organization) string {
|
||||
resourceOwner := authz.GetCtxData(ctx).OrgID
|
||||
if resourceOwnerReq := resource_object.ResourceOwnerFromOrganization(org); resourceOwnerReq != "" {
|
||||
return resourceOwnerReq
|
||||
}
|
||||
return resourceOwner
|
||||
}
|
||||
|
||||
func organizationToUpdateResourceOwner(org *object.Organization) string {
|
||||
if resourceOwnerReq := resource_object.ResourceOwnerFromOrganization(org); resourceOwnerReq != "" {
|
||||
return resourceOwnerReq
|
||||
}
|
||||
return ""
|
||||
}
|
||||
|
||||
func (s *Server) DeleteUser(ctx context.Context, req *user.DeleteUserRequest) (_ *user.DeleteUserResponse, err error) {
|
||||
if err := checkUserSchemaEnabled(ctx); err != nil {
|
||||
return nil, err
|
||||
}
|
||||
details, err := s.command.DeleteSchemaUser(ctx, req.GetUserId())
|
||||
details, err := s.command.DeleteSchemaUser(ctx, organizationToUpdateResourceOwner(req.Organization), req.GetId())
|
||||
if err != nil {
|
||||
return nil, err
|
||||
}
|
||||
@@ -64,3 +81,126 @@ func checkUserSchemaEnabled(ctx context.Context) error {
|
||||
}
|
||||
return zerrors.ThrowPreconditionFailed(nil, "TODO", "Errors.UserSchema.NotEnabled")
|
||||
}
|
||||
|
||||
func (s *Server) PatchUser(ctx context.Context, req *user.PatchUserRequest) (_ *user.PatchUserResponse, err error) {
|
||||
if err := checkUserSchemaEnabled(ctx); err != nil {
|
||||
return nil, err
|
||||
}
|
||||
schemauser, err := patchUserRequestToChangeSchemaUser(req)
|
||||
if err != nil {
|
||||
return nil, err
|
||||
}
|
||||
|
||||
if err := s.command.ChangeSchemaUser(ctx, schemauser, s.userCodeAlg); err != nil {
|
||||
return nil, err
|
||||
}
|
||||
return &user.PatchUserResponse{
|
||||
Details: resource_object.DomainToDetailsPb(schemauser.Details, object.OwnerType_OWNER_TYPE_ORG, schemauser.Details.ResourceOwner),
|
||||
EmailCode: gu.Ptr(schemauser.ReturnCodeEmail),
|
||||
PhoneCode: gu.Ptr(schemauser.ReturnCodePhone),
|
||||
}, nil
|
||||
}
|
||||
|
||||
func patchUserRequestToChangeSchemaUser(req *user.PatchUserRequest) (_ *command.ChangeSchemaUser, err error) {
|
||||
var data []byte
|
||||
if req.GetUser().Data != nil {
|
||||
data, err = req.GetUser().GetData().MarshalJSON()
|
||||
if err != nil {
|
||||
return nil, err
|
||||
}
|
||||
}
|
||||
|
||||
var email *command.Email
|
||||
var phone *command.Phone
|
||||
if req.GetUser().GetContact() != nil {
|
||||
if req.GetUser().GetContact().GetEmail() != nil {
|
||||
email = &command.Email{
|
||||
Address: domain.EmailAddress(req.GetUser().GetContact().Email.Address),
|
||||
}
|
||||
if req.GetUser().GetContact().Email.GetIsVerified() {
|
||||
email.Verified = true
|
||||
}
|
||||
if req.GetUser().GetContact().Email.GetReturnCode() != nil {
|
||||
email.ReturnCode = true
|
||||
}
|
||||
if req.GetUser().GetContact().Email.GetSendCode() != nil {
|
||||
email.URLTemplate = req.GetUser().GetContact().Email.GetSendCode().GetUrlTemplate()
|
||||
}
|
||||
}
|
||||
if req.GetUser().GetContact().Phone != nil {
|
||||
phone = &command.Phone{
|
||||
Number: domain.PhoneNumber(req.GetUser().GetContact().Phone.Number),
|
||||
}
|
||||
if req.GetUser().GetContact().Phone.GetIsVerified() {
|
||||
phone.Verified = true
|
||||
}
|
||||
if req.GetUser().GetContact().Phone.GetReturnCode() != nil {
|
||||
phone.ReturnCode = true
|
||||
}
|
||||
}
|
||||
}
|
||||
return &command.ChangeSchemaUser{
|
||||
ResourceOwner: organizationToUpdateResourceOwner(req.Organization),
|
||||
ID: req.GetId(),
|
||||
SchemaID: req.GetUser().SchemaId,
|
||||
Data: data,
|
||||
Email: email,
|
||||
Phone: phone,
|
||||
}, nil
|
||||
}
|
||||
|
||||
func (s *Server) DeactivateUser(ctx context.Context, req *user.DeactivateUserRequest) (_ *user.DeactivateUserResponse, err error) {
|
||||
if err := checkUserSchemaEnabled(ctx); err != nil {
|
||||
return nil, err
|
||||
}
|
||||
|
||||
details, err := s.command.DeactivateSchemaUser(ctx, organizationToUpdateResourceOwner(req.Organization), req.GetId())
|
||||
if err != nil {
|
||||
return nil, err
|
||||
}
|
||||
return &user.DeactivateUserResponse{
|
||||
Details: resource_object.DomainToDetailsPb(details, object.OwnerType_OWNER_TYPE_ORG, details.ResourceOwner),
|
||||
}, nil
|
||||
}
|
||||
|
||||
func (s *Server) ActivateUser(ctx context.Context, req *user.ActivateUserRequest) (_ *user.ActivateUserResponse, err error) {
|
||||
if err := checkUserSchemaEnabled(ctx); err != nil {
|
||||
return nil, err
|
||||
}
|
||||
|
||||
details, err := s.command.ActivateSchemaUser(ctx, organizationToUpdateResourceOwner(req.Organization), req.GetId())
|
||||
if err != nil {
|
||||
return nil, err
|
||||
}
|
||||
return &user.ActivateUserResponse{
|
||||
Details: resource_object.DomainToDetailsPb(details, object.OwnerType_OWNER_TYPE_ORG, details.ResourceOwner),
|
||||
}, nil
|
||||
}
|
||||
|
||||
func (s *Server) LockUser(ctx context.Context, req *user.LockUserRequest) (_ *user.LockUserResponse, err error) {
|
||||
if err := checkUserSchemaEnabled(ctx); err != nil {
|
||||
return nil, err
|
||||
}
|
||||
|
||||
details, err := s.command.LockSchemaUser(ctx, organizationToUpdateResourceOwner(req.Organization), req.GetId())
|
||||
if err != nil {
|
||||
return nil, err
|
||||
}
|
||||
return &user.LockUserResponse{
|
||||
Details: resource_object.DomainToDetailsPb(details, object.OwnerType_OWNER_TYPE_ORG, details.ResourceOwner),
|
||||
}, nil
|
||||
}
|
||||
|
||||
func (s *Server) UnlockUser(ctx context.Context, req *user.UnlockUserRequest) (_ *user.UnlockUserResponse, err error) {
|
||||
if err := checkUserSchemaEnabled(ctx); err != nil {
|
||||
return nil, err
|
||||
}
|
||||
|
||||
details, err := s.command.UnlockSchemaUser(ctx, organizationToUpdateResourceOwner(req.Organization), req.GetId())
|
||||
if err != nil {
|
||||
return nil, err
|
||||
}
|
||||
return &user.UnlockUserResponse{
|
||||
Details: resource_object.DomainToDetailsPb(details, object.OwnerType_OWNER_TYPE_ORG, details.ResourceOwner),
|
||||
}, nil
|
||||
}
|
||||
|
@@ -20,7 +20,10 @@ import (
|
||||
)
|
||||
|
||||
func TestServer_ListUserSchemas(t *testing.T) {
|
||||
ensureFeatureEnabled(t, IAMOwnerCTX)
|
||||
t.Parallel()
|
||||
instance := integration.NewInstance(CTX)
|
||||
ensureFeatureEnabled(t, instance)
|
||||
isolatedIAMOwnerCTX := instance.WithAuthorization(CTX, integration.UserTypeIAMOwner)
|
||||
|
||||
userSchema := new(structpb.Struct)
|
||||
err := userSchema.UnmarshalJSON([]byte(`{
|
||||
@@ -43,7 +46,7 @@ func TestServer_ListUserSchemas(t *testing.T) {
|
||||
{
|
||||
name: "missing permission",
|
||||
args: args{
|
||||
ctx: Instance.WithAuthorization(context.Background(), integration.UserTypeOrgOwner),
|
||||
ctx: instance.WithAuthorization(context.Background(), integration.UserTypeOrgOwner),
|
||||
req: &schema.SearchUserSchemasRequest{},
|
||||
},
|
||||
wantErr: true,
|
||||
@@ -51,7 +54,7 @@ func TestServer_ListUserSchemas(t *testing.T) {
|
||||
{
|
||||
name: "not found, error",
|
||||
args: args{
|
||||
ctx: IAMOwnerCTX,
|
||||
ctx: isolatedIAMOwnerCTX,
|
||||
req: &schema.SearchUserSchemasRequest{
|
||||
Filters: []*schema.SearchFilter{
|
||||
{
|
||||
@@ -75,11 +78,11 @@ func TestServer_ListUserSchemas(t *testing.T) {
|
||||
{
|
||||
name: "single (id), ok",
|
||||
args: args{
|
||||
ctx: IAMOwnerCTX,
|
||||
ctx: isolatedIAMOwnerCTX,
|
||||
req: &schema.SearchUserSchemasRequest{},
|
||||
prepare: func(request *schema.SearchUserSchemasRequest, resp *schema.SearchUserSchemasResponse) error {
|
||||
schemaType := gofakeit.Name()
|
||||
createResp := Instance.CreateUserSchemaEmptyWithType(IAMOwnerCTX, schemaType)
|
||||
createResp := instance.CreateUserSchemaEmptyWithType(isolatedIAMOwnerCTX, schemaType)
|
||||
request.Filters = []*schema.SearchFilter{
|
||||
{
|
||||
Filter: &schema.SearchFilter_IdFilter{
|
||||
@@ -121,14 +124,14 @@ func TestServer_ListUserSchemas(t *testing.T) {
|
||||
{
|
||||
name: "multiple (type), ok",
|
||||
args: args{
|
||||
ctx: IAMOwnerCTX,
|
||||
ctx: isolatedIAMOwnerCTX,
|
||||
req: &schema.SearchUserSchemasRequest{},
|
||||
prepare: func(request *schema.SearchUserSchemasRequest, resp *schema.SearchUserSchemasResponse) error {
|
||||
schemaType := gofakeit.Name()
|
||||
schemaType1 := schemaType + "_1"
|
||||
schemaType2 := schemaType + "_2"
|
||||
createResp := Instance.CreateUserSchemaEmptyWithType(IAMOwnerCTX, schemaType1)
|
||||
createResp2 := Instance.CreateUserSchemaEmptyWithType(IAMOwnerCTX, schemaType2)
|
||||
createResp := instance.CreateUserSchemaEmptyWithType(isolatedIAMOwnerCTX, schemaType1)
|
||||
createResp2 := instance.CreateUserSchemaEmptyWithType(isolatedIAMOwnerCTX, schemaType2)
|
||||
|
||||
request.SortingColumn = gu.Ptr(schema.FieldName_FIELD_NAME_TYPE)
|
||||
request.Query = &object.SearchQuery{Desc: false}
|
||||
@@ -186,12 +189,12 @@ func TestServer_ListUserSchemas(t *testing.T) {
|
||||
}
|
||||
|
||||
retryDuration := 20 * time.Second
|
||||
if ctxDeadline, ok := IAMOwnerCTX.Deadline(); ok {
|
||||
if ctxDeadline, ok := isolatedIAMOwnerCTX.Deadline(); ok {
|
||||
retryDuration = time.Until(ctxDeadline)
|
||||
}
|
||||
|
||||
require.EventuallyWithT(t, func(ttt *assert.CollectT) {
|
||||
got, err := Client.SearchUserSchemas(tt.args.ctx, tt.args.req)
|
||||
got, err := instance.Client.UserSchemaV3.SearchUserSchemas(tt.args.ctx, tt.args.req)
|
||||
if tt.wantErr {
|
||||
require.Error(ttt, err)
|
||||
return
|
||||
@@ -215,7 +218,10 @@ func TestServer_ListUserSchemas(t *testing.T) {
|
||||
}
|
||||
|
||||
func TestServer_GetUserSchema(t *testing.T) {
|
||||
ensureFeatureEnabled(t, IAMOwnerCTX)
|
||||
t.Parallel()
|
||||
instance := integration.NewInstance(CTX)
|
||||
ensureFeatureEnabled(t, instance)
|
||||
isolatedIAMOwnerCTX := instance.WithAuthorization(CTX, integration.UserTypeIAMOwner)
|
||||
|
||||
userSchema := new(structpb.Struct)
|
||||
err := userSchema.UnmarshalJSON([]byte(`{
|
||||
@@ -238,11 +244,11 @@ func TestServer_GetUserSchema(t *testing.T) {
|
||||
{
|
||||
name: "missing permission",
|
||||
args: args{
|
||||
ctx: Instance.WithAuthorization(context.Background(), integration.UserTypeOrgOwner),
|
||||
ctx: instance.WithAuthorization(context.Background(), integration.UserTypeOrgOwner),
|
||||
req: &schema.GetUserSchemaRequest{},
|
||||
prepare: func(request *schema.GetUserSchemaRequest, resp *schema.GetUserSchemaResponse) error {
|
||||
schemaType := gofakeit.Name()
|
||||
createResp := Instance.CreateUserSchemaEmptyWithType(IAMOwnerCTX, schemaType)
|
||||
createResp := instance.CreateUserSchemaEmptyWithType(isolatedIAMOwnerCTX, schemaType)
|
||||
request.Id = createResp.GetDetails().GetId()
|
||||
return nil
|
||||
},
|
||||
@@ -252,7 +258,7 @@ func TestServer_GetUserSchema(t *testing.T) {
|
||||
{
|
||||
name: "not existing, error",
|
||||
args: args{
|
||||
ctx: IAMOwnerCTX,
|
||||
ctx: isolatedIAMOwnerCTX,
|
||||
req: &schema.GetUserSchemaRequest{
|
||||
Id: "notexisting",
|
||||
},
|
||||
@@ -262,11 +268,11 @@ func TestServer_GetUserSchema(t *testing.T) {
|
||||
{
|
||||
name: "get, ok",
|
||||
args: args{
|
||||
ctx: IAMOwnerCTX,
|
||||
ctx: isolatedIAMOwnerCTX,
|
||||
req: &schema.GetUserSchemaRequest{},
|
||||
prepare: func(request *schema.GetUserSchemaRequest, resp *schema.GetUserSchemaResponse) error {
|
||||
schemaType := gofakeit.Name()
|
||||
createResp := Instance.CreateUserSchemaEmptyWithType(IAMOwnerCTX, schemaType)
|
||||
createResp := instance.CreateUserSchemaEmptyWithType(isolatedIAMOwnerCTX, schemaType)
|
||||
request.Id = createResp.GetDetails().GetId()
|
||||
|
||||
resp.UserSchema.Config.Type = schemaType
|
||||
@@ -295,12 +301,12 @@ func TestServer_GetUserSchema(t *testing.T) {
|
||||
}
|
||||
|
||||
retryDuration := 5 * time.Second
|
||||
if ctxDeadline, ok := IAMOwnerCTX.Deadline(); ok {
|
||||
if ctxDeadline, ok := isolatedIAMOwnerCTX.Deadline(); ok {
|
||||
retryDuration = time.Until(ctxDeadline)
|
||||
}
|
||||
|
||||
require.EventuallyWithT(t, func(ttt *assert.CollectT) {
|
||||
got, err := Client.GetUserSchema(tt.args.ctx, tt.args.req)
|
||||
got, err := instance.Client.UserSchemaV3.GetUserSchema(tt.args.ctx, tt.args.req)
|
||||
if tt.wantErr {
|
||||
assert.Error(t, err, "Error: "+err.Error())
|
||||
} else {
|
||||
|
@@ -14,49 +14,41 @@ import (
|
||||
|
||||
"github.com/zitadel/zitadel/internal/integration"
|
||||
"github.com/zitadel/zitadel/pkg/grpc/feature/v2"
|
||||
schema "github.com/zitadel/zitadel/pkg/grpc/resources/userschema/v3alpha"
|
||||
)
|
||||
|
||||
var (
|
||||
IAMOwnerCTX, SystemCTX context.Context
|
||||
Instance *integration.Instance
|
||||
Client schema.ZITADELUserSchemasClient
|
||||
CTX context.Context
|
||||
)
|
||||
|
||||
func TestMain(m *testing.M) {
|
||||
os.Exit(func() int {
|
||||
ctx, cancel := context.WithTimeout(context.Background(), 15*time.Minute)
|
||||
defer cancel()
|
||||
|
||||
Instance = integration.NewInstance(ctx)
|
||||
|
||||
IAMOwnerCTX = Instance.WithAuthorization(ctx, integration.UserTypeIAMOwner)
|
||||
SystemCTX = integration.WithSystemAuthorization(ctx)
|
||||
Client = Instance.Client.UserSchemaV3
|
||||
|
||||
CTX = ctx
|
||||
return m.Run()
|
||||
}())
|
||||
}
|
||||
|
||||
func ensureFeatureEnabled(t *testing.T, iamOwnerCTX context.Context) {
|
||||
f, err := Instance.Client.FeatureV2.GetInstanceFeatures(iamOwnerCTX, &feature.GetInstanceFeaturesRequest{
|
||||
func ensureFeatureEnabled(t *testing.T, instance *integration.Instance) {
|
||||
ctx := instance.WithAuthorization(CTX, integration.UserTypeIAMOwner)
|
||||
f, err := instance.Client.FeatureV2.GetInstanceFeatures(ctx, &feature.GetInstanceFeaturesRequest{
|
||||
Inheritance: true,
|
||||
})
|
||||
require.NoError(t, err)
|
||||
if f.UserSchema.GetEnabled() {
|
||||
return
|
||||
}
|
||||
_, err = Instance.Client.FeatureV2.SetInstanceFeatures(iamOwnerCTX, &feature.SetInstanceFeaturesRequest{
|
||||
_, err = instance.Client.FeatureV2.SetInstanceFeatures(ctx, &feature.SetInstanceFeaturesRequest{
|
||||
UserSchema: gu.Ptr(true),
|
||||
})
|
||||
require.NoError(t, err)
|
||||
retryDuration := time.Minute
|
||||
if ctxDeadline, ok := iamOwnerCTX.Deadline(); ok {
|
||||
if ctxDeadline, ok := ctx.Deadline(); ok {
|
||||
retryDuration = time.Until(ctxDeadline)
|
||||
}
|
||||
require.EventuallyWithT(t,
|
||||
func(ttt *assert.CollectT) {
|
||||
f, err := Instance.Client.FeatureV2.GetInstanceFeatures(iamOwnerCTX, &feature.GetInstanceFeaturesRequest{
|
||||
f, err := instance.Client.FeatureV2.GetInstanceFeatures(ctx, &feature.GetInstanceFeaturesRequest{
|
||||
Inheritance: true,
|
||||
})
|
||||
require.NoError(ttt, err)
|
||||
|
@@ -19,7 +19,10 @@ import (
|
||||
)
|
||||
|
||||
func TestServer_CreateUserSchema(t *testing.T) {
|
||||
ensureFeatureEnabled(t, IAMOwnerCTX)
|
||||
t.Parallel()
|
||||
instance := integration.NewInstance(CTX)
|
||||
ensureFeatureEnabled(t, instance)
|
||||
isolatedIAMOwnerCTX := instance.WithAuthorization(CTX, integration.UserTypeIAMOwner)
|
||||
|
||||
tests := []struct {
|
||||
name string
|
||||
@@ -30,7 +33,7 @@ func TestServer_CreateUserSchema(t *testing.T) {
|
||||
}{
|
||||
{
|
||||
name: "missing permission, error",
|
||||
ctx: Instance.WithAuthorization(context.Background(), integration.UserTypeOrgOwner),
|
||||
ctx: instance.WithAuthorization(context.Background(), integration.UserTypeOrgOwner),
|
||||
req: &schema.CreateUserSchemaRequest{
|
||||
UserSchema: &schema.UserSchema{
|
||||
Type: gofakeit.Name(),
|
||||
@@ -40,7 +43,7 @@ func TestServer_CreateUserSchema(t *testing.T) {
|
||||
},
|
||||
{
|
||||
name: "empty type",
|
||||
ctx: IAMOwnerCTX,
|
||||
ctx: isolatedIAMOwnerCTX,
|
||||
req: &schema.CreateUserSchemaRequest{
|
||||
UserSchema: &schema.UserSchema{
|
||||
Type: "",
|
||||
@@ -50,7 +53,7 @@ func TestServer_CreateUserSchema(t *testing.T) {
|
||||
},
|
||||
{
|
||||
name: "empty schema, error",
|
||||
ctx: IAMOwnerCTX,
|
||||
ctx: isolatedIAMOwnerCTX,
|
||||
req: &schema.CreateUserSchemaRequest{
|
||||
UserSchema: &schema.UserSchema{
|
||||
Type: gofakeit.Name(),
|
||||
@@ -60,7 +63,7 @@ func TestServer_CreateUserSchema(t *testing.T) {
|
||||
},
|
||||
{
|
||||
name: "invalid schema, error",
|
||||
ctx: IAMOwnerCTX,
|
||||
ctx: isolatedIAMOwnerCTX,
|
||||
req: &schema.CreateUserSchemaRequest{
|
||||
UserSchema: &schema.UserSchema{
|
||||
Type: gofakeit.Name(),
|
||||
@@ -91,7 +94,7 @@ func TestServer_CreateUserSchema(t *testing.T) {
|
||||
},
|
||||
{
|
||||
name: "no authenticators, ok",
|
||||
ctx: IAMOwnerCTX,
|
||||
ctx: isolatedIAMOwnerCTX,
|
||||
req: &schema.CreateUserSchemaRequest{
|
||||
UserSchema: &schema.UserSchema{
|
||||
Type: gofakeit.Name(),
|
||||
@@ -123,14 +126,14 @@ func TestServer_CreateUserSchema(t *testing.T) {
|
||||
Changed: timestamppb.Now(),
|
||||
Owner: &object.Owner{
|
||||
Type: object.OwnerType_OWNER_TYPE_INSTANCE,
|
||||
Id: Instance.ID(),
|
||||
Id: instance.ID(),
|
||||
},
|
||||
},
|
||||
},
|
||||
},
|
||||
{
|
||||
name: "invalid authenticator, error",
|
||||
ctx: IAMOwnerCTX,
|
||||
ctx: isolatedIAMOwnerCTX,
|
||||
req: &schema.CreateUserSchemaRequest{
|
||||
UserSchema: &schema.UserSchema{
|
||||
Type: gofakeit.Name(),
|
||||
@@ -164,7 +167,7 @@ func TestServer_CreateUserSchema(t *testing.T) {
|
||||
},
|
||||
{
|
||||
name: "with authenticator, ok",
|
||||
ctx: IAMOwnerCTX,
|
||||
ctx: isolatedIAMOwnerCTX,
|
||||
req: &schema.CreateUserSchemaRequest{
|
||||
UserSchema: &schema.UserSchema{
|
||||
Type: gofakeit.Name(),
|
||||
@@ -199,14 +202,14 @@ func TestServer_CreateUserSchema(t *testing.T) {
|
||||
Changed: timestamppb.Now(),
|
||||
Owner: &object.Owner{
|
||||
Type: object.OwnerType_OWNER_TYPE_INSTANCE,
|
||||
Id: Instance.ID(),
|
||||
Id: instance.ID(),
|
||||
},
|
||||
},
|
||||
},
|
||||
},
|
||||
{
|
||||
name: "with invalid permission, error",
|
||||
ctx: IAMOwnerCTX,
|
||||
ctx: isolatedIAMOwnerCTX,
|
||||
req: &schema.CreateUserSchemaRequest{
|
||||
UserSchema: &schema.UserSchema{
|
||||
Type: gofakeit.Name(),
|
||||
@@ -241,7 +244,7 @@ func TestServer_CreateUserSchema(t *testing.T) {
|
||||
},
|
||||
{
|
||||
name: "with valid permission, ok",
|
||||
ctx: IAMOwnerCTX,
|
||||
ctx: isolatedIAMOwnerCTX,
|
||||
req: &schema.CreateUserSchemaRequest{
|
||||
UserSchema: &schema.UserSchema{
|
||||
Type: gofakeit.Name(),
|
||||
@@ -280,7 +283,7 @@ func TestServer_CreateUserSchema(t *testing.T) {
|
||||
Changed: timestamppb.Now(),
|
||||
Owner: &object.Owner{
|
||||
Type: object.OwnerType_OWNER_TYPE_INSTANCE,
|
||||
Id: Instance.ID(),
|
||||
Id: instance.ID(),
|
||||
},
|
||||
},
|
||||
},
|
||||
@@ -288,7 +291,7 @@ func TestServer_CreateUserSchema(t *testing.T) {
|
||||
}
|
||||
for _, tt := range tests {
|
||||
t.Run(tt.name, func(t *testing.T) {
|
||||
got, err := Client.CreateUserSchema(tt.ctx, tt.req)
|
||||
got, err := instance.Client.UserSchemaV3.CreateUserSchema(tt.ctx, tt.req)
|
||||
if tt.wantErr {
|
||||
require.Error(t, err)
|
||||
return
|
||||
@@ -301,7 +304,10 @@ func TestServer_CreateUserSchema(t *testing.T) {
|
||||
}
|
||||
|
||||
func TestServer_UpdateUserSchema(t *testing.T) {
|
||||
ensureFeatureEnabled(t, IAMOwnerCTX)
|
||||
t.Parallel()
|
||||
instance := integration.NewInstance(CTX)
|
||||
ensureFeatureEnabled(t, instance)
|
||||
isolatedIAMOwnerCTX := instance.WithAuthorization(CTX, integration.UserTypeIAMOwner)
|
||||
|
||||
type args struct {
|
||||
ctx context.Context
|
||||
@@ -317,12 +323,12 @@ func TestServer_UpdateUserSchema(t *testing.T) {
|
||||
{
|
||||
name: "missing permission, error",
|
||||
prepare: func(request *schema.PatchUserSchemaRequest) error {
|
||||
schemaID := Instance.CreateUserSchemaEmpty(IAMOwnerCTX).GetDetails().GetId()
|
||||
schemaID := instance.CreateUserSchemaEmpty(isolatedIAMOwnerCTX).GetDetails().GetId()
|
||||
request.Id = schemaID
|
||||
return nil
|
||||
},
|
||||
args: args{
|
||||
ctx: Instance.WithAuthorization(context.Background(), integration.UserTypeOrgOwner),
|
||||
ctx: instance.WithAuthorization(context.Background(), integration.UserTypeOrgOwner),
|
||||
req: &schema.PatchUserSchemaRequest{
|
||||
UserSchema: &schema.PatchUserSchema{
|
||||
Type: gu.Ptr(gofakeit.Name()),
|
||||
@@ -337,7 +343,7 @@ func TestServer_UpdateUserSchema(t *testing.T) {
|
||||
return nil
|
||||
},
|
||||
args: args{
|
||||
ctx: IAMOwnerCTX,
|
||||
ctx: isolatedIAMOwnerCTX,
|
||||
req: &schema.PatchUserSchemaRequest{},
|
||||
},
|
||||
wantErr: true,
|
||||
@@ -349,7 +355,7 @@ func TestServer_UpdateUserSchema(t *testing.T) {
|
||||
return nil
|
||||
},
|
||||
args: args{
|
||||
ctx: IAMOwnerCTX,
|
||||
ctx: isolatedIAMOwnerCTX,
|
||||
req: &schema.PatchUserSchemaRequest{},
|
||||
},
|
||||
wantErr: true,
|
||||
@@ -357,12 +363,12 @@ func TestServer_UpdateUserSchema(t *testing.T) {
|
||||
{
|
||||
name: "empty type, error",
|
||||
prepare: func(request *schema.PatchUserSchemaRequest) error {
|
||||
schemaID := Instance.CreateUserSchemaEmpty(IAMOwnerCTX).GetDetails().GetId()
|
||||
schemaID := instance.CreateUserSchemaEmpty(isolatedIAMOwnerCTX).GetDetails().GetId()
|
||||
request.Id = schemaID
|
||||
return nil
|
||||
},
|
||||
args: args{
|
||||
ctx: IAMOwnerCTX,
|
||||
ctx: isolatedIAMOwnerCTX,
|
||||
req: &schema.PatchUserSchemaRequest{
|
||||
UserSchema: &schema.PatchUserSchema{
|
||||
Type: gu.Ptr(""),
|
||||
@@ -374,12 +380,12 @@ func TestServer_UpdateUserSchema(t *testing.T) {
|
||||
{
|
||||
name: "update type, ok",
|
||||
prepare: func(request *schema.PatchUserSchemaRequest) error {
|
||||
schemaID := Instance.CreateUserSchemaEmpty(IAMOwnerCTX).GetDetails().GetId()
|
||||
schemaID := instance.CreateUserSchemaEmpty(isolatedIAMOwnerCTX).GetDetails().GetId()
|
||||
request.Id = schemaID
|
||||
return nil
|
||||
},
|
||||
args: args{
|
||||
ctx: IAMOwnerCTX,
|
||||
ctx: isolatedIAMOwnerCTX,
|
||||
req: &schema.PatchUserSchemaRequest{
|
||||
UserSchema: &schema.PatchUserSchema{
|
||||
Type: gu.Ptr(gofakeit.Name()),
|
||||
@@ -391,7 +397,7 @@ func TestServer_UpdateUserSchema(t *testing.T) {
|
||||
Changed: timestamppb.Now(),
|
||||
Owner: &object.Owner{
|
||||
Type: object.OwnerType_OWNER_TYPE_INSTANCE,
|
||||
Id: Instance.ID(),
|
||||
Id: instance.ID(),
|
||||
},
|
||||
},
|
||||
},
|
||||
@@ -399,12 +405,12 @@ func TestServer_UpdateUserSchema(t *testing.T) {
|
||||
{
|
||||
name: "empty schema, ok",
|
||||
prepare: func(request *schema.PatchUserSchemaRequest) error {
|
||||
schemaID := Instance.CreateUserSchemaEmpty(IAMOwnerCTX).GetDetails().GetId()
|
||||
schemaID := instance.CreateUserSchemaEmpty(isolatedIAMOwnerCTX).GetDetails().GetId()
|
||||
request.Id = schemaID
|
||||
return nil
|
||||
},
|
||||
args: args{
|
||||
ctx: IAMOwnerCTX,
|
||||
ctx: isolatedIAMOwnerCTX,
|
||||
req: &schema.PatchUserSchemaRequest{
|
||||
UserSchema: &schema.PatchUserSchema{
|
||||
DataType: &schema.PatchUserSchema_Schema{},
|
||||
@@ -416,7 +422,7 @@ func TestServer_UpdateUserSchema(t *testing.T) {
|
||||
Changed: timestamppb.Now(),
|
||||
Owner: &object.Owner{
|
||||
Type: object.OwnerType_OWNER_TYPE_INSTANCE,
|
||||
Id: Instance.ID(),
|
||||
Id: instance.ID(),
|
||||
},
|
||||
},
|
||||
},
|
||||
@@ -424,12 +430,12 @@ func TestServer_UpdateUserSchema(t *testing.T) {
|
||||
{
|
||||
name: "invalid schema, error",
|
||||
prepare: func(request *schema.PatchUserSchemaRequest) error {
|
||||
schemaID := Instance.CreateUserSchemaEmpty(IAMOwnerCTX).GetDetails().GetId()
|
||||
schemaID := instance.CreateUserSchemaEmpty(isolatedIAMOwnerCTX).GetDetails().GetId()
|
||||
request.Id = schemaID
|
||||
return nil
|
||||
},
|
||||
args: args{
|
||||
ctx: IAMOwnerCTX,
|
||||
ctx: isolatedIAMOwnerCTX,
|
||||
req: &schema.PatchUserSchemaRequest{
|
||||
UserSchema: &schema.PatchUserSchema{
|
||||
DataType: &schema.PatchUserSchema_Schema{
|
||||
@@ -462,12 +468,12 @@ func TestServer_UpdateUserSchema(t *testing.T) {
|
||||
{
|
||||
name: "update schema, ok",
|
||||
prepare: func(request *schema.PatchUserSchemaRequest) error {
|
||||
schemaID := Instance.CreateUserSchemaEmpty(IAMOwnerCTX).GetDetails().GetId()
|
||||
schemaID := instance.CreateUserSchemaEmpty(isolatedIAMOwnerCTX).GetDetails().GetId()
|
||||
request.Id = schemaID
|
||||
return nil
|
||||
},
|
||||
args: args{
|
||||
ctx: IAMOwnerCTX,
|
||||
ctx: isolatedIAMOwnerCTX,
|
||||
req: &schema.PatchUserSchemaRequest{
|
||||
UserSchema: &schema.PatchUserSchema{
|
||||
DataType: &schema.PatchUserSchema_Schema{
|
||||
@@ -500,7 +506,7 @@ func TestServer_UpdateUserSchema(t *testing.T) {
|
||||
Changed: timestamppb.Now(),
|
||||
Owner: &object.Owner{
|
||||
Type: object.OwnerType_OWNER_TYPE_INSTANCE,
|
||||
Id: Instance.ID(),
|
||||
Id: instance.ID(),
|
||||
},
|
||||
},
|
||||
},
|
||||
@@ -508,12 +514,12 @@ func TestServer_UpdateUserSchema(t *testing.T) {
|
||||
{
|
||||
name: "invalid authenticator, error",
|
||||
prepare: func(request *schema.PatchUserSchemaRequest) error {
|
||||
schemaID := Instance.CreateUserSchemaEmpty(IAMOwnerCTX).GetDetails().GetId()
|
||||
schemaID := instance.CreateUserSchemaEmpty(isolatedIAMOwnerCTX).GetDetails().GetId()
|
||||
request.Id = schemaID
|
||||
return nil
|
||||
},
|
||||
args: args{
|
||||
ctx: IAMOwnerCTX,
|
||||
ctx: isolatedIAMOwnerCTX,
|
||||
req: &schema.PatchUserSchemaRequest{
|
||||
UserSchema: &schema.PatchUserSchema{
|
||||
PossibleAuthenticators: []schema.AuthenticatorType{
|
||||
@@ -527,12 +533,12 @@ func TestServer_UpdateUserSchema(t *testing.T) {
|
||||
{
|
||||
name: "update authenticator, ok",
|
||||
prepare: func(request *schema.PatchUserSchemaRequest) error {
|
||||
schemaID := Instance.CreateUserSchemaEmpty(IAMOwnerCTX).GetDetails().GetId()
|
||||
schemaID := instance.CreateUserSchemaEmpty(isolatedIAMOwnerCTX).GetDetails().GetId()
|
||||
request.Id = schemaID
|
||||
return nil
|
||||
},
|
||||
args: args{
|
||||
ctx: IAMOwnerCTX,
|
||||
ctx: isolatedIAMOwnerCTX,
|
||||
req: &schema.PatchUserSchemaRequest{
|
||||
UserSchema: &schema.PatchUserSchema{
|
||||
PossibleAuthenticators: []schema.AuthenticatorType{
|
||||
@@ -546,7 +552,7 @@ func TestServer_UpdateUserSchema(t *testing.T) {
|
||||
Changed: timestamppb.Now(),
|
||||
Owner: &object.Owner{
|
||||
Type: object.OwnerType_OWNER_TYPE_INSTANCE,
|
||||
Id: Instance.ID(),
|
||||
Id: instance.ID(),
|
||||
},
|
||||
},
|
||||
},
|
||||
@@ -554,8 +560,8 @@ func TestServer_UpdateUserSchema(t *testing.T) {
|
||||
{
|
||||
name: "inactive, error",
|
||||
prepare: func(request *schema.PatchUserSchemaRequest) error {
|
||||
schemaID := Instance.CreateUserSchemaEmpty(IAMOwnerCTX).GetDetails().GetId()
|
||||
_, err := Client.DeactivateUserSchema(IAMOwnerCTX, &schema.DeactivateUserSchemaRequest{
|
||||
schemaID := instance.CreateUserSchemaEmpty(isolatedIAMOwnerCTX).GetDetails().GetId()
|
||||
_, err := instance.Client.UserSchemaV3.DeactivateUserSchema(isolatedIAMOwnerCTX, &schema.DeactivateUserSchemaRequest{
|
||||
Id: schemaID,
|
||||
})
|
||||
require.NoError(t, err)
|
||||
@@ -563,7 +569,7 @@ func TestServer_UpdateUserSchema(t *testing.T) {
|
||||
return nil
|
||||
},
|
||||
args: args{
|
||||
ctx: IAMOwnerCTX,
|
||||
ctx: isolatedIAMOwnerCTX,
|
||||
req: &schema.PatchUserSchemaRequest{
|
||||
UserSchema: &schema.PatchUserSchema{
|
||||
Type: gu.Ptr(gofakeit.Name()),
|
||||
@@ -578,7 +584,7 @@ func TestServer_UpdateUserSchema(t *testing.T) {
|
||||
err := tt.prepare(tt.args.req)
|
||||
require.NoError(t, err)
|
||||
|
||||
got, err := Client.PatchUserSchema(tt.args.ctx, tt.args.req)
|
||||
got, err := instance.Client.UserSchemaV3.PatchUserSchema(tt.args.ctx, tt.args.req)
|
||||
if tt.wantErr {
|
||||
require.Error(t, err)
|
||||
return
|
||||
@@ -590,7 +596,10 @@ func TestServer_UpdateUserSchema(t *testing.T) {
|
||||
}
|
||||
|
||||
func TestServer_DeactivateUserSchema(t *testing.T) {
|
||||
ensureFeatureEnabled(t, IAMOwnerCTX)
|
||||
t.Parallel()
|
||||
instance := integration.NewInstance(CTX)
|
||||
ensureFeatureEnabled(t, instance)
|
||||
isolatedIAMOwnerCTX := instance.WithAuthorization(CTX, integration.UserTypeIAMOwner)
|
||||
|
||||
type args struct {
|
||||
ctx context.Context
|
||||
@@ -606,7 +615,7 @@ func TestServer_DeactivateUserSchema(t *testing.T) {
|
||||
{
|
||||
name: "not existing, error",
|
||||
args: args{
|
||||
IAMOwnerCTX,
|
||||
isolatedIAMOwnerCTX,
|
||||
&schema.DeactivateUserSchemaRequest{
|
||||
Id: "notexisting",
|
||||
},
|
||||
@@ -617,10 +626,10 @@ func TestServer_DeactivateUserSchema(t *testing.T) {
|
||||
{
|
||||
name: "active, ok",
|
||||
args: args{
|
||||
IAMOwnerCTX,
|
||||
isolatedIAMOwnerCTX,
|
||||
&schema.DeactivateUserSchemaRequest{},
|
||||
func(request *schema.DeactivateUserSchemaRequest) error {
|
||||
schemaID := Instance.CreateUserSchemaEmpty(IAMOwnerCTX).GetDetails().GetId()
|
||||
schemaID := instance.CreateUserSchemaEmpty(isolatedIAMOwnerCTX).GetDetails().GetId()
|
||||
request.Id = schemaID
|
||||
return nil
|
||||
},
|
||||
@@ -630,7 +639,7 @@ func TestServer_DeactivateUserSchema(t *testing.T) {
|
||||
Changed: timestamppb.Now(),
|
||||
Owner: &object.Owner{
|
||||
Type: object.OwnerType_OWNER_TYPE_INSTANCE,
|
||||
Id: Instance.ID(),
|
||||
Id: instance.ID(),
|
||||
},
|
||||
},
|
||||
},
|
||||
@@ -638,12 +647,12 @@ func TestServer_DeactivateUserSchema(t *testing.T) {
|
||||
{
|
||||
name: "inactive, error",
|
||||
args: args{
|
||||
IAMOwnerCTX,
|
||||
isolatedIAMOwnerCTX,
|
||||
&schema.DeactivateUserSchemaRequest{},
|
||||
func(request *schema.DeactivateUserSchemaRequest) error {
|
||||
schemaID := Instance.CreateUserSchemaEmpty(IAMOwnerCTX).GetDetails().GetId()
|
||||
schemaID := instance.CreateUserSchemaEmpty(isolatedIAMOwnerCTX).GetDetails().GetId()
|
||||
request.Id = schemaID
|
||||
_, err := Client.DeactivateUserSchema(IAMOwnerCTX, &schema.DeactivateUserSchemaRequest{
|
||||
_, err := instance.Client.UserSchemaV3.DeactivateUserSchema(isolatedIAMOwnerCTX, &schema.DeactivateUserSchemaRequest{
|
||||
Id: schemaID,
|
||||
})
|
||||
return err
|
||||
@@ -657,7 +666,7 @@ func TestServer_DeactivateUserSchema(t *testing.T) {
|
||||
err := tt.args.prepare(tt.args.req)
|
||||
require.NoError(t, err)
|
||||
|
||||
got, err := Client.DeactivateUserSchema(tt.args.ctx, tt.args.req)
|
||||
got, err := instance.Client.UserSchemaV3.DeactivateUserSchema(tt.args.ctx, tt.args.req)
|
||||
if tt.wantErr {
|
||||
require.Error(t, err)
|
||||
return
|
||||
@@ -669,7 +678,10 @@ func TestServer_DeactivateUserSchema(t *testing.T) {
|
||||
}
|
||||
|
||||
func TestServer_ReactivateUserSchema(t *testing.T) {
|
||||
ensureFeatureEnabled(t, IAMOwnerCTX)
|
||||
t.Parallel()
|
||||
instance := integration.NewInstance(CTX)
|
||||
ensureFeatureEnabled(t, instance)
|
||||
isolatedIAMOwnerCTX := instance.WithAuthorization(CTX, integration.UserTypeIAMOwner)
|
||||
|
||||
type args struct {
|
||||
ctx context.Context
|
||||
@@ -685,7 +697,7 @@ func TestServer_ReactivateUserSchema(t *testing.T) {
|
||||
{
|
||||
name: "not existing, error",
|
||||
args: args{
|
||||
IAMOwnerCTX,
|
||||
isolatedIAMOwnerCTX,
|
||||
&schema.ReactivateUserSchemaRequest{
|
||||
Id: "notexisting",
|
||||
},
|
||||
@@ -696,10 +708,10 @@ func TestServer_ReactivateUserSchema(t *testing.T) {
|
||||
{
|
||||
name: "active, error",
|
||||
args: args{
|
||||
ctx: IAMOwnerCTX,
|
||||
ctx: isolatedIAMOwnerCTX,
|
||||
req: &schema.ReactivateUserSchemaRequest{},
|
||||
prepare: func(request *schema.ReactivateUserSchemaRequest) error {
|
||||
schemaID := Instance.CreateUserSchemaEmpty(IAMOwnerCTX).GetDetails().GetId()
|
||||
schemaID := instance.CreateUserSchemaEmpty(isolatedIAMOwnerCTX).GetDetails().GetId()
|
||||
request.Id = schemaID
|
||||
return nil
|
||||
},
|
||||
@@ -709,12 +721,12 @@ func TestServer_ReactivateUserSchema(t *testing.T) {
|
||||
{
|
||||
name: "inactive, ok",
|
||||
args: args{
|
||||
ctx: IAMOwnerCTX,
|
||||
ctx: isolatedIAMOwnerCTX,
|
||||
req: &schema.ReactivateUserSchemaRequest{},
|
||||
prepare: func(request *schema.ReactivateUserSchemaRequest) error {
|
||||
schemaID := Instance.CreateUserSchemaEmpty(IAMOwnerCTX).GetDetails().GetId()
|
||||
schemaID := instance.CreateUserSchemaEmpty(isolatedIAMOwnerCTX).GetDetails().GetId()
|
||||
request.Id = schemaID
|
||||
_, err := Client.DeactivateUserSchema(IAMOwnerCTX, &schema.DeactivateUserSchemaRequest{
|
||||
_, err := instance.Client.UserSchemaV3.DeactivateUserSchema(isolatedIAMOwnerCTX, &schema.DeactivateUserSchemaRequest{
|
||||
Id: schemaID,
|
||||
})
|
||||
return err
|
||||
@@ -725,7 +737,7 @@ func TestServer_ReactivateUserSchema(t *testing.T) {
|
||||
Changed: timestamppb.Now(),
|
||||
Owner: &object.Owner{
|
||||
Type: object.OwnerType_OWNER_TYPE_INSTANCE,
|
||||
Id: Instance.ID(),
|
||||
Id: instance.ID(),
|
||||
},
|
||||
},
|
||||
},
|
||||
@@ -736,7 +748,7 @@ func TestServer_ReactivateUserSchema(t *testing.T) {
|
||||
err := tt.args.prepare(tt.args.req)
|
||||
require.NoError(t, err)
|
||||
|
||||
got, err := Client.ReactivateUserSchema(tt.args.ctx, tt.args.req)
|
||||
got, err := instance.Client.UserSchemaV3.ReactivateUserSchema(tt.args.ctx, tt.args.req)
|
||||
if tt.wantErr {
|
||||
require.Error(t, err)
|
||||
return
|
||||
@@ -748,7 +760,10 @@ func TestServer_ReactivateUserSchema(t *testing.T) {
|
||||
}
|
||||
|
||||
func TestServer_DeleteUserSchema(t *testing.T) {
|
||||
ensureFeatureEnabled(t, IAMOwnerCTX)
|
||||
t.Parallel()
|
||||
instance := integration.NewInstance(CTX)
|
||||
ensureFeatureEnabled(t, instance)
|
||||
isolatedIAMOwnerCTX := instance.WithAuthorization(CTX, integration.UserTypeIAMOwner)
|
||||
|
||||
type args struct {
|
||||
ctx context.Context
|
||||
@@ -764,7 +779,7 @@ func TestServer_DeleteUserSchema(t *testing.T) {
|
||||
{
|
||||
name: "not existing, error",
|
||||
args: args{
|
||||
IAMOwnerCTX,
|
||||
isolatedIAMOwnerCTX,
|
||||
&schema.DeleteUserSchemaRequest{
|
||||
Id: "notexisting",
|
||||
},
|
||||
@@ -775,10 +790,10 @@ func TestServer_DeleteUserSchema(t *testing.T) {
|
||||
{
|
||||
name: "delete, ok",
|
||||
args: args{
|
||||
ctx: IAMOwnerCTX,
|
||||
ctx: isolatedIAMOwnerCTX,
|
||||
req: &schema.DeleteUserSchemaRequest{},
|
||||
prepare: func(request *schema.DeleteUserSchemaRequest) error {
|
||||
schemaID := Instance.CreateUserSchemaEmpty(IAMOwnerCTX).GetDetails().GetId()
|
||||
schemaID := instance.CreateUserSchemaEmpty(isolatedIAMOwnerCTX).GetDetails().GetId()
|
||||
request.Id = schemaID
|
||||
return nil
|
||||
},
|
||||
@@ -788,7 +803,7 @@ func TestServer_DeleteUserSchema(t *testing.T) {
|
||||
Changed: timestamppb.Now(),
|
||||
Owner: &object.Owner{
|
||||
Type: object.OwnerType_OWNER_TYPE_INSTANCE,
|
||||
Id: Instance.ID(),
|
||||
Id: instance.ID(),
|
||||
},
|
||||
},
|
||||
},
|
||||
@@ -796,12 +811,12 @@ func TestServer_DeleteUserSchema(t *testing.T) {
|
||||
{
|
||||
name: "deleted, error",
|
||||
args: args{
|
||||
ctx: IAMOwnerCTX,
|
||||
ctx: isolatedIAMOwnerCTX,
|
||||
req: &schema.DeleteUserSchemaRequest{},
|
||||
prepare: func(request *schema.DeleteUserSchemaRequest) error {
|
||||
schemaID := Instance.CreateUserSchemaEmpty(IAMOwnerCTX).GetDetails().GetId()
|
||||
schemaID := instance.CreateUserSchemaEmpty(isolatedIAMOwnerCTX).GetDetails().GetId()
|
||||
request.Id = schemaID
|
||||
_, err := Client.DeleteUserSchema(IAMOwnerCTX, &schema.DeleteUserSchemaRequest{
|
||||
_, err := instance.Client.UserSchemaV3.DeleteUserSchema(isolatedIAMOwnerCTX, &schema.DeleteUserSchemaRequest{
|
||||
Id: schemaID,
|
||||
})
|
||||
return err
|
||||
@@ -815,7 +830,7 @@ func TestServer_DeleteUserSchema(t *testing.T) {
|
||||
err := tt.args.prepare(tt.args.req)
|
||||
require.NoError(t, err)
|
||||
|
||||
got, err := Client.DeleteUserSchema(tt.args.ctx, tt.args.req)
|
||||
got, err := instance.Client.UserSchemaV3.DeleteUserSchema(tt.args.ctx, tt.args.req)
|
||||
if tt.wantErr {
|
||||
require.Error(t, err)
|
||||
return
|
||||
|
@@ -186,7 +186,7 @@ func validateUserSchema(userSchema json.RawMessage) error {
|
||||
}
|
||||
|
||||
func (c *Commands) getSchemaWriteModelByID(ctx context.Context, resourceOwner, id string) (*UserSchemaWriteModel, error) {
|
||||
writeModel := NewUserSchemaWriteModel(resourceOwner, id, "")
|
||||
writeModel := NewUserSchemaWriteModel(resourceOwner, id)
|
||||
if err := c.eventstore.FilterToQueryReducer(ctx, writeModel); err != nil {
|
||||
return nil, err
|
||||
}
|
||||
|
@@ -19,16 +19,15 @@ type UserSchemaWriteModel struct {
|
||||
Schema json.RawMessage
|
||||
PossibleAuthenticators []domain.AuthenticatorType
|
||||
State domain.UserSchemaState
|
||||
Revision uint64
|
||||
SchemaRevision uint64
|
||||
}
|
||||
|
||||
func NewUserSchemaWriteModel(resourceOwner, schemaID, ty string) *UserSchemaWriteModel {
|
||||
func NewUserSchemaWriteModel(resourceOwner, schemaID string) *UserSchemaWriteModel {
|
||||
return &UserSchemaWriteModel{
|
||||
WriteModel: eventstore.WriteModel{
|
||||
AggregateID: schemaID,
|
||||
ResourceOwner: resourceOwner,
|
||||
},
|
||||
SchemaType: ty,
|
||||
}
|
||||
}
|
||||
|
||||
@@ -40,13 +39,13 @@ func (wm *UserSchemaWriteModel) Reduce() error {
|
||||
wm.Schema = e.Schema
|
||||
wm.PossibleAuthenticators = e.PossibleAuthenticators
|
||||
wm.State = domain.UserSchemaStateActive
|
||||
wm.Revision = 1
|
||||
wm.SchemaRevision = 1
|
||||
case *schema.UpdatedEvent:
|
||||
if e.SchemaType != nil {
|
||||
wm.SchemaType = *e.SchemaType
|
||||
}
|
||||
if e.SchemaRevision != nil {
|
||||
wm.Revision = *e.SchemaRevision
|
||||
wm.SchemaRevision = *e.SchemaRevision
|
||||
}
|
||||
if len(e.Schema) > 0 {
|
||||
wm.Schema = e.Schema
|
||||
@@ -79,10 +78,6 @@ func (wm *UserSchemaWriteModel) Query() *eventstore.SearchQueryBuilder {
|
||||
schema.DeletedType,
|
||||
)
|
||||
|
||||
if wm.SchemaType != "" {
|
||||
query = query.EventData(map[string]interface{}{"schemaType": wm.SchemaType})
|
||||
}
|
||||
|
||||
return query.Builder()
|
||||
}
|
||||
func (wm *UserSchemaWriteModel) NewUpdatedEvent(
|
||||
@@ -99,7 +94,7 @@ func (wm *UserSchemaWriteModel) NewUpdatedEvent(
|
||||
if !bytes.Equal(wm.Schema, userSchema) {
|
||||
changes = append(changes, schema.ChangeSchema(userSchema))
|
||||
// change revision if the content of the schema changed
|
||||
changes = append(changes, schema.IncreaseRevision(wm.Revision))
|
||||
changes = append(changes, schema.IncreaseRevision(wm.SchemaRevision))
|
||||
}
|
||||
if len(possibleAuthenticators) > 0 && slices.Compare(wm.PossibleAuthenticators, possibleAuthenticators) != 0 {
|
||||
changes = append(changes, schema.ChangePossibleAuthenticators(possibleAuthenticators))
|
||||
|
@@ -15,14 +15,14 @@ import (
|
||||
)
|
||||
|
||||
type CreateSchemaUser struct {
|
||||
Details *domain.ObjectDetails
|
||||
ResourceOwner string
|
||||
Details *domain.ObjectDetails
|
||||
|
||||
SchemaID string
|
||||
schemaRevision uint64
|
||||
|
||||
ID string
|
||||
Data json.RawMessage
|
||||
ResourceOwner string
|
||||
ID string
|
||||
Data json.RawMessage
|
||||
|
||||
Email *Email
|
||||
ReturnCodeEmail string
|
||||
@@ -45,7 +45,7 @@ func (s *CreateSchemaUser) Valid(ctx context.Context, c *Commands) (err error) {
|
||||
if !schemaWriteModel.Exists() {
|
||||
return zerrors.ThrowPreconditionFailed(nil, "COMMAND-N9QOuN4F7o", "Errors.UserSchema.NotExists")
|
||||
}
|
||||
s.schemaRevision = schemaWriteModel.Revision
|
||||
s.schemaRevision = schemaWriteModel.SchemaRevision
|
||||
|
||||
if s.ID == "" {
|
||||
s.ID, err = c.idGenerator.Next()
|
||||
@@ -120,13 +120,13 @@ func (c *Commands) CreateSchemaUser(ctx context.Context, user *CreateSchemaUser,
|
||||
),
|
||||
}
|
||||
if user.Email != nil {
|
||||
events, user.ReturnCodeEmail, err = c.updateSchemaUserEmail(ctx, events, userAgg, user.Email, alg)
|
||||
events, user.ReturnCodeEmail, err = c.updateSchemaUserEmail(ctx, writeModel, events, userAgg, user.Email, alg)
|
||||
if err != nil {
|
||||
return err
|
||||
}
|
||||
}
|
||||
if user.Phone != nil {
|
||||
events, user.ReturnCodePhone, err = c.updateSchemaUserPhone(ctx, events, userAgg, user.Phone, alg)
|
||||
events, user.ReturnCodePhone, err = c.updateSchemaUserPhone(ctx, writeModel, events, userAgg, user.Phone, alg)
|
||||
if err != nil {
|
||||
return err
|
||||
}
|
||||
@@ -139,11 +139,11 @@ func (c *Commands) CreateSchemaUser(ctx context.Context, user *CreateSchemaUser,
|
||||
return nil
|
||||
}
|
||||
|
||||
func (c *Commands) DeleteSchemaUser(ctx context.Context, id string) (*domain.ObjectDetails, error) {
|
||||
func (c *Commands) DeleteSchemaUser(ctx context.Context, resourceOwner, id string) (*domain.ObjectDetails, error) {
|
||||
if id == "" {
|
||||
return nil, zerrors.ThrowInvalidArgument(nil, "COMMAND-Vs4wJCME7T", "Errors.IDMissing")
|
||||
}
|
||||
writeModel, err := c.getSchemaUserExists(ctx, "", id)
|
||||
writeModel, err := c.getSchemaUserExists(ctx, resourceOwner, id)
|
||||
if err != nil {
|
||||
return nil, err
|
||||
}
|
||||
@@ -161,7 +161,235 @@ func (c *Commands) DeleteSchemaUser(ctx context.Context, id string) (*domain.Obj
|
||||
return writeModelToObjectDetails(&writeModel.WriteModel), nil
|
||||
}
|
||||
|
||||
func (c *Commands) updateSchemaUserEmail(ctx context.Context, events []eventstore.Command, agg *eventstore.Aggregate, email *Email, alg crypto.EncryptionAlgorithm) (_ []eventstore.Command, plainCode string, err error) {
|
||||
type ChangeSchemaUser struct {
|
||||
Details *domain.ObjectDetails
|
||||
|
||||
SchemaID *string
|
||||
schemaWriteModel *UserSchemaWriteModel
|
||||
|
||||
ResourceOwner string
|
||||
ID string
|
||||
Data json.RawMessage
|
||||
|
||||
Email *Email
|
||||
ReturnCodeEmail string
|
||||
Phone *Phone
|
||||
ReturnCodePhone string
|
||||
}
|
||||
|
||||
func (s *ChangeSchemaUser) Valid(ctx context.Context, c *Commands) (err error) {
|
||||
if s.ID == "" {
|
||||
return zerrors.ThrowInvalidArgument(nil, "COMMAND-gEJR1QOGHb", "Errors.IDMissing")
|
||||
}
|
||||
if s.SchemaID != nil {
|
||||
s.schemaWriteModel, err = c.getSchemaWriteModelByID(ctx, "", *s.SchemaID)
|
||||
if err != nil {
|
||||
return err
|
||||
}
|
||||
if !s.schemaWriteModel.Exists() {
|
||||
return zerrors.ThrowPreconditionFailed(nil, "COMMAND-VLDTtxT3If", "Errors.UserSchema.NotExists")
|
||||
}
|
||||
}
|
||||
|
||||
if s.Email != nil && s.Email.Address != "" {
|
||||
if err := s.Email.Validate(); err != nil {
|
||||
return err
|
||||
}
|
||||
}
|
||||
|
||||
if s.Phone != nil && s.Phone.Number != "" {
|
||||
if s.Phone.Number, err = s.Phone.Number.Normalize(); err != nil {
|
||||
return err
|
||||
}
|
||||
}
|
||||
|
||||
return nil
|
||||
}
|
||||
|
||||
func (s *ChangeSchemaUser) ValidData(ctx context.Context, c *Commands, existingUser *UserV3WriteModel) (err error) {
|
||||
// get role for permission check in schema through extension
|
||||
role, err := c.getSchemaRoleForWrite(ctx, existingUser.ResourceOwner, existingUser.AggregateID)
|
||||
if err != nil {
|
||||
return err
|
||||
}
|
||||
|
||||
if s.schemaWriteModel == nil {
|
||||
s.schemaWriteModel, err = c.getSchemaWriteModelByID(ctx, "", existingUser.SchemaID)
|
||||
if err != nil {
|
||||
return err
|
||||
}
|
||||
}
|
||||
|
||||
schema, err := domain_schema.NewSchema(role, bytes.NewReader(s.schemaWriteModel.Schema))
|
||||
if err != nil {
|
||||
return err
|
||||
}
|
||||
|
||||
// if data not changed but a new schema or revision should be used
|
||||
data := s.Data
|
||||
if s.Data == nil {
|
||||
data = existingUser.Data
|
||||
}
|
||||
|
||||
var v interface{}
|
||||
if err := json.Unmarshal(data, &v); err != nil {
|
||||
return zerrors.ThrowInvalidArgument(nil, "COMMAND-7o3ZGxtXUz", "Errors.User.Invalid")
|
||||
}
|
||||
|
||||
if err := schema.Validate(v); err != nil {
|
||||
return zerrors.ThrowPreconditionFailed(nil, "COMMAND-SlKXqLSeL6", "Errors.UserSchema.Data.Invalid")
|
||||
}
|
||||
return nil
|
||||
}
|
||||
|
||||
func (c *Commands) ChangeSchemaUser(ctx context.Context, user *ChangeSchemaUser, alg crypto.EncryptionAlgorithm) (err error) {
|
||||
if err := user.Valid(ctx, c); err != nil {
|
||||
return err
|
||||
}
|
||||
|
||||
writeModel, err := c.getSchemaUserWriteModelByID(ctx, user.ResourceOwner, user.ID)
|
||||
if err != nil {
|
||||
return err
|
||||
}
|
||||
if !writeModel.Exists() {
|
||||
return zerrors.ThrowPreconditionFailed(nil, "COMMAND-Nn8CRVlkeZ", "Errors.User.NotFound")
|
||||
}
|
||||
|
||||
userAgg := UserV3AggregateFromWriteModel(&writeModel.WriteModel)
|
||||
events := make([]eventstore.Command, 0)
|
||||
if user.Data != nil || user.SchemaID != nil {
|
||||
if err := user.ValidData(ctx, c, writeModel); err != nil {
|
||||
return err
|
||||
}
|
||||
updateEvent := writeModel.NewUpdatedEvent(ctx,
|
||||
userAgg,
|
||||
user.schemaWriteModel.AggregateID,
|
||||
user.schemaWriteModel.SchemaRevision,
|
||||
user.Data,
|
||||
)
|
||||
if updateEvent != nil {
|
||||
events = append(events, updateEvent)
|
||||
}
|
||||
}
|
||||
if user.Email != nil {
|
||||
events, user.ReturnCodeEmail, err = c.updateSchemaUserEmail(ctx, writeModel, events, userAgg, user.Email, alg)
|
||||
if err != nil {
|
||||
return err
|
||||
}
|
||||
}
|
||||
if user.Phone != nil {
|
||||
events, user.ReturnCodePhone, err = c.updateSchemaUserPhone(ctx, writeModel, events, userAgg, user.Phone, alg)
|
||||
if err != nil {
|
||||
return err
|
||||
}
|
||||
}
|
||||
if len(events) == 0 {
|
||||
user.Details = writeModelToObjectDetails(&writeModel.WriteModel)
|
||||
return nil
|
||||
}
|
||||
if err := c.pushAppendAndReduce(ctx, writeModel, events...); err != nil {
|
||||
return err
|
||||
}
|
||||
user.Details = writeModelToObjectDetails(&writeModel.WriteModel)
|
||||
return nil
|
||||
}
|
||||
|
||||
func (c *Commands) checkPermissionUpdateUserState(ctx context.Context, resourceOwner, userID string) error {
|
||||
return c.checkPermission(ctx, domain.PermissionUserWrite, resourceOwner, userID)
|
||||
}
|
||||
|
||||
func (c *Commands) LockSchemaUser(ctx context.Context, resourceOwner, id string) (*domain.ObjectDetails, error) {
|
||||
if id == "" {
|
||||
return nil, zerrors.ThrowInvalidArgument(nil, "COMMAND-Eu8I2VAfjF", "Errors.IDMissing")
|
||||
}
|
||||
writeModel, err := c.getSchemaUserExists(ctx, resourceOwner, id)
|
||||
if err != nil {
|
||||
return nil, err
|
||||
}
|
||||
if !writeModel.Exists() || writeModel.Locked {
|
||||
return nil, zerrors.ThrowNotFound(nil, "COMMAND-G4LOrnjY7q", "Errors.User.NotFound")
|
||||
}
|
||||
if err := c.checkPermissionUpdateUserState(ctx, writeModel.ResourceOwner, writeModel.AggregateID); err != nil {
|
||||
return nil, err
|
||||
}
|
||||
if err := c.pushAppendAndReduce(ctx, writeModel,
|
||||
schemauser.NewLockedEvent(ctx, UserV3AggregateFromWriteModel(&writeModel.WriteModel)),
|
||||
); err != nil {
|
||||
return nil, err
|
||||
}
|
||||
return writeModelToObjectDetails(&writeModel.WriteModel), nil
|
||||
}
|
||||
|
||||
func (c *Commands) UnlockSchemaUser(ctx context.Context, resourceOwner, id string) (*domain.ObjectDetails, error) {
|
||||
if id == "" {
|
||||
return nil, zerrors.ThrowInvalidArgument(nil, "COMMAND-krXtYscQZh", "Errors.IDMissing")
|
||||
}
|
||||
writeModel, err := c.getSchemaUserExists(ctx, resourceOwner, id)
|
||||
if err != nil {
|
||||
return nil, err
|
||||
}
|
||||
if !writeModel.Exists() || !writeModel.Locked {
|
||||
return nil, zerrors.ThrowNotFound(nil, "COMMAND-gpBv46Lh9m", "Errors.User.NotFound")
|
||||
}
|
||||
if err := c.checkPermissionUpdateUserState(ctx, writeModel.ResourceOwner, writeModel.AggregateID); err != nil {
|
||||
return nil, err
|
||||
}
|
||||
if err := c.pushAppendAndReduce(ctx, writeModel,
|
||||
schemauser.NewUnlockedEvent(ctx, UserV3AggregateFromWriteModel(&writeModel.WriteModel)),
|
||||
); err != nil {
|
||||
return nil, err
|
||||
}
|
||||
return writeModelToObjectDetails(&writeModel.WriteModel), nil
|
||||
}
|
||||
|
||||
func (c *Commands) DeactivateSchemaUser(ctx context.Context, resourceOwner, id string) (*domain.ObjectDetails, error) {
|
||||
if id == "" {
|
||||
return nil, zerrors.ThrowInvalidArgument(nil, "COMMAND-pjJhge86ZV", "Errors.IDMissing")
|
||||
}
|
||||
writeModel, err := c.getSchemaUserExists(ctx, resourceOwner, id)
|
||||
if err != nil {
|
||||
return nil, err
|
||||
}
|
||||
if writeModel.State != domain.UserStateActive {
|
||||
return nil, zerrors.ThrowNotFound(nil, "COMMAND-Ob6lR5iFTe", "Errors.User.NotFound")
|
||||
}
|
||||
if err := c.checkPermissionUpdateUserState(ctx, writeModel.ResourceOwner, writeModel.AggregateID); err != nil {
|
||||
return nil, err
|
||||
}
|
||||
if err := c.pushAppendAndReduce(ctx, writeModel,
|
||||
schemauser.NewDeactivatedEvent(ctx, UserV3AggregateFromWriteModel(&writeModel.WriteModel)),
|
||||
); err != nil {
|
||||
return nil, err
|
||||
}
|
||||
return writeModelToObjectDetails(&writeModel.WriteModel), nil
|
||||
}
|
||||
|
||||
func (c *Commands) ActivateSchemaUser(ctx context.Context, resourceOwner, id string) (*domain.ObjectDetails, error) {
|
||||
if id == "" {
|
||||
return nil, zerrors.ThrowInvalidArgument(nil, "COMMAND-17XupGvxBJ", "Errors.IDMissing")
|
||||
}
|
||||
writeModel, err := c.getSchemaUserExists(ctx, "", id)
|
||||
if err != nil {
|
||||
return nil, err
|
||||
}
|
||||
if writeModel.State != domain.UserStateInactive {
|
||||
return nil, zerrors.ThrowNotFound(nil, "COMMAND-rQjbBr4J3j", "Errors.User.NotFound")
|
||||
}
|
||||
if err := c.checkPermissionUpdateUserState(ctx, writeModel.ResourceOwner, writeModel.AggregateID); err != nil {
|
||||
return nil, err
|
||||
}
|
||||
if err := c.pushAppendAndReduce(ctx, writeModel,
|
||||
schemauser.NewActivatedEvent(ctx, UserV3AggregateFromWriteModel(&writeModel.WriteModel)),
|
||||
); err != nil {
|
||||
return nil, err
|
||||
}
|
||||
return writeModelToObjectDetails(&writeModel.WriteModel), nil
|
||||
}
|
||||
|
||||
func (c *Commands) updateSchemaUserEmail(ctx context.Context, existing *UserV3WriteModel, events []eventstore.Command, agg *eventstore.Aggregate, email *Email, alg crypto.EncryptionAlgorithm) (_ []eventstore.Command, plainCode string, err error) {
|
||||
if existing.Email == string(email.Address) {
|
||||
return events, plainCode, nil
|
||||
}
|
||||
|
||||
events = append(events, schemauser.NewEmailUpdatedEvent(ctx,
|
||||
agg,
|
||||
@@ -187,8 +415,12 @@ func (c *Commands) updateSchemaUserEmail(ctx context.Context, events []eventstor
|
||||
return events, plainCode, nil
|
||||
}
|
||||
|
||||
func (c *Commands) updateSchemaUserPhone(ctx context.Context, events []eventstore.Command, agg *eventstore.Aggregate, phone *Phone, alg crypto.EncryptionAlgorithm) (_ []eventstore.Command, plainCode string, err error) {
|
||||
events = append(events, schemauser.NewPhoneChangedEvent(ctx,
|
||||
func (c *Commands) updateSchemaUserPhone(ctx context.Context, existing *UserV3WriteModel, events []eventstore.Command, agg *eventstore.Aggregate, phone *Phone, alg crypto.EncryptionAlgorithm) (_ []eventstore.Command, plainCode string, err error) {
|
||||
if existing.Phone == string(phone.Number) {
|
||||
return events, plainCode, nil
|
||||
}
|
||||
|
||||
events = append(events, schemauser.NewPhoneUpdatedEvent(ctx,
|
||||
agg,
|
||||
phone.Number,
|
||||
))
|
||||
@@ -218,3 +450,11 @@ func (c *Commands) getSchemaUserExists(ctx context.Context, resourceOwner, id st
|
||||
}
|
||||
return writeModel, nil
|
||||
}
|
||||
|
||||
func (c *Commands) getSchemaUserWriteModelByID(ctx context.Context, resourceOwner, id string) (*UserV3WriteModel, error) {
|
||||
writeModel := NewUserV3WriteModel(resourceOwner, id)
|
||||
if err := c.eventstore.FilterToQueryReducer(ctx, writeModel); err != nil {
|
||||
return nil, err
|
||||
}
|
||||
return writeModel, nil
|
||||
}
|
||||
|
@@ -29,7 +29,8 @@ type UserV3WriteModel struct {
|
||||
|
||||
Data json.RawMessage
|
||||
|
||||
State domain.UserState
|
||||
Locked bool
|
||||
State domain.UserState
|
||||
}
|
||||
|
||||
func NewExistsUserV3WriteModel(resourceOwner, userID string) *UserV3WriteModel {
|
||||
@@ -61,8 +62,9 @@ func (wm *UserV3WriteModel) Reduce() error {
|
||||
switch e := event.(type) {
|
||||
case *schemauser.CreatedEvent:
|
||||
wm.SchemaID = e.SchemaID
|
||||
wm.SchemaRevision = 1
|
||||
wm.SchemaRevision = e.SchemaRevision
|
||||
wm.Data = e.Data
|
||||
wm.Locked = false
|
||||
|
||||
wm.State = domain.UserStateActive
|
||||
case *schemauser.UpdatedEvent:
|
||||
@@ -79,6 +81,8 @@ func (wm *UserV3WriteModel) Reduce() error {
|
||||
wm.State = domain.UserStateDeleted
|
||||
case *schemauser.EmailUpdatedEvent:
|
||||
wm.Email = string(e.EmailAddress)
|
||||
wm.IsEmailVerified = false
|
||||
wm.EmailVerifiedFailedCount = 0
|
||||
case *schemauser.EmailCodeAddedEvent:
|
||||
wm.IsEmailVerified = false
|
||||
wm.EmailVerifiedFailedCount = 0
|
||||
@@ -87,8 +91,10 @@ func (wm *UserV3WriteModel) Reduce() error {
|
||||
wm.EmailVerifiedFailedCount = 0
|
||||
case *schemauser.EmailVerificationFailedEvent:
|
||||
wm.EmailVerifiedFailedCount += 1
|
||||
case *schemauser.PhoneChangedEvent:
|
||||
case *schemauser.PhoneUpdatedEvent:
|
||||
wm.Phone = string(e.PhoneNumber)
|
||||
wm.IsPhoneVerified = false
|
||||
wm.PhoneVerifiedFailedCount = 0
|
||||
case *schemauser.PhoneCodeAddedEvent:
|
||||
wm.IsPhoneVerified = false
|
||||
wm.PhoneVerifiedFailedCount = 0
|
||||
@@ -97,28 +103,39 @@ func (wm *UserV3WriteModel) Reduce() error {
|
||||
wm.IsPhoneVerified = true
|
||||
case *schemauser.PhoneVerificationFailedEvent:
|
||||
wm.PhoneVerifiedFailedCount += 1
|
||||
case *schemauser.LockedEvent:
|
||||
wm.Locked = true
|
||||
case *schemauser.UnlockedEvent:
|
||||
wm.Locked = false
|
||||
case *schemauser.DeactivatedEvent:
|
||||
wm.State = domain.UserStateInactive
|
||||
case *schemauser.ActivatedEvent:
|
||||
wm.State = domain.UserStateActive
|
||||
}
|
||||
}
|
||||
return wm.WriteModel.Reduce()
|
||||
}
|
||||
|
||||
func (wm *UserV3WriteModel) Query() *eventstore.SearchQueryBuilder {
|
||||
query := eventstore.NewSearchQueryBuilder(eventstore.ColumnsEvent).
|
||||
ResourceOwner(wm.ResourceOwner).
|
||||
AddQuery().
|
||||
AggregateTypes(schemauser.AggregateType).
|
||||
AggregateIDs(wm.AggregateID).
|
||||
EventTypes(
|
||||
schemauser.CreatedType,
|
||||
schemauser.DeletedType,
|
||||
)
|
||||
builder := eventstore.NewSearchQueryBuilder(eventstore.ColumnsEvent)
|
||||
if wm.ResourceOwner != "" {
|
||||
builder = builder.ResourceOwner(wm.ResourceOwner)
|
||||
}
|
||||
eventtypes := []eventstore.EventType{
|
||||
schemauser.CreatedType,
|
||||
schemauser.DeletedType,
|
||||
schemauser.ActivatedType,
|
||||
schemauser.DeactivatedType,
|
||||
schemauser.LockedType,
|
||||
schemauser.UnlockedType,
|
||||
}
|
||||
if wm.DataWM {
|
||||
query = query.EventTypes(
|
||||
eventtypes = append(eventtypes,
|
||||
schemauser.UpdatedType,
|
||||
)
|
||||
}
|
||||
if wm.EmailWM {
|
||||
query = query.EventTypes(
|
||||
eventtypes = append(eventtypes,
|
||||
schemauser.EmailUpdatedType,
|
||||
schemauser.EmailVerifiedType,
|
||||
schemauser.EmailCodeAddedType,
|
||||
@@ -126,31 +143,34 @@ func (wm *UserV3WriteModel) Query() *eventstore.SearchQueryBuilder {
|
||||
)
|
||||
}
|
||||
if wm.PhoneWM {
|
||||
query = query.EventTypes(
|
||||
eventtypes = append(eventtypes,
|
||||
schemauser.PhoneUpdatedType,
|
||||
schemauser.PhoneVerifiedType,
|
||||
schemauser.PhoneCodeAddedType,
|
||||
schemauser.PhoneVerificationFailedType,
|
||||
)
|
||||
}
|
||||
return query.Builder()
|
||||
return builder.AddQuery().
|
||||
AggregateTypes(schemauser.AggregateType).
|
||||
AggregateIDs(wm.AggregateID).
|
||||
EventTypes(eventtypes...).Builder()
|
||||
}
|
||||
|
||||
func (wm *UserV3WriteModel) NewUpdatedEvent(
|
||||
ctx context.Context,
|
||||
agg *eventstore.Aggregate,
|
||||
schemaID *string,
|
||||
schemaRevision *uint64,
|
||||
schemaID string,
|
||||
schemaRevision uint64,
|
||||
data json.RawMessage,
|
||||
) *schemauser.UpdatedEvent {
|
||||
changes := make([]schemauser.Changes, 0)
|
||||
if schemaID != nil && wm.SchemaID != *schemaID {
|
||||
changes = append(changes, schemauser.ChangeSchemaID(wm.SchemaID, *schemaID))
|
||||
if wm.SchemaID != schemaID {
|
||||
changes = append(changes, schemauser.ChangeSchemaID(schemaID))
|
||||
}
|
||||
if schemaRevision != nil && wm.SchemaRevision != *schemaRevision {
|
||||
changes = append(changes, schemauser.ChangeSchemaRevision(wm.SchemaRevision, *schemaRevision))
|
||||
if wm.SchemaRevision != schemaRevision {
|
||||
changes = append(changes, schemauser.ChangeSchemaRevision(schemaRevision))
|
||||
}
|
||||
if !bytes.Equal(wm.Data, data) {
|
||||
if data != nil && !bytes.Equal(wm.Data, data) {
|
||||
changes = append(changes, schemauser.ChangeData(data))
|
||||
}
|
||||
if len(changes) == 0 {
|
||||
|
File diff suppressed because it is too large
Load Diff
@@ -28,7 +28,7 @@ import (
|
||||
object_v3alpha "github.com/zitadel/zitadel/pkg/grpc/object/v3alpha"
|
||||
oidc_pb "github.com/zitadel/zitadel/pkg/grpc/oidc/v2"
|
||||
oidc_pb_v2beta "github.com/zitadel/zitadel/pkg/grpc/oidc/v2beta"
|
||||
org "github.com/zitadel/zitadel/pkg/grpc/org/v2"
|
||||
"github.com/zitadel/zitadel/pkg/grpc/org/v2"
|
||||
org_v2beta "github.com/zitadel/zitadel/pkg/grpc/org/v2beta"
|
||||
action "github.com/zitadel/zitadel/pkg/grpc/resources/action/v3alpha"
|
||||
user_v3alpha "github.com/zitadel/zitadel/pkg/grpc/resources/user/v3alpha"
|
||||
@@ -784,3 +784,55 @@ func (i *Instance) CreateInviteCode(ctx context.Context, userID string) *user_v2
|
||||
logging.OnError(err).Fatal("create invite code")
|
||||
return user
|
||||
}
|
||||
|
||||
func (i *Instance) LockSchemaUser(ctx context.Context, orgID string, userID string) *user_v3alpha.LockUserResponse {
|
||||
var org *object_v3alpha.Organization
|
||||
if orgID != "" {
|
||||
org = &object_v3alpha.Organization{Property: &object_v3alpha.Organization_OrgId{OrgId: orgID}}
|
||||
}
|
||||
user, err := i.Client.UserV3Alpha.LockUser(ctx, &user_v3alpha.LockUserRequest{
|
||||
Organization: org,
|
||||
Id: userID,
|
||||
})
|
||||
logging.OnError(err).Fatal("lock user")
|
||||
return user
|
||||
}
|
||||
|
||||
func (i *Instance) UnlockSchemaUser(ctx context.Context, orgID string, userID string) *user_v3alpha.UnlockUserResponse {
|
||||
var org *object_v3alpha.Organization
|
||||
if orgID != "" {
|
||||
org = &object_v3alpha.Organization{Property: &object_v3alpha.Organization_OrgId{OrgId: orgID}}
|
||||
}
|
||||
user, err := i.Client.UserV3Alpha.UnlockUser(ctx, &user_v3alpha.UnlockUserRequest{
|
||||
Organization: org,
|
||||
Id: userID,
|
||||
})
|
||||
logging.OnError(err).Fatal("unlock user")
|
||||
return user
|
||||
}
|
||||
|
||||
func (i *Instance) DeactivateSchemaUser(ctx context.Context, orgID string, userID string) *user_v3alpha.DeactivateUserResponse {
|
||||
var org *object_v3alpha.Organization
|
||||
if orgID != "" {
|
||||
org = &object_v3alpha.Organization{Property: &object_v3alpha.Organization_OrgId{OrgId: orgID}}
|
||||
}
|
||||
user, err := i.Client.UserV3Alpha.DeactivateUser(ctx, &user_v3alpha.DeactivateUserRequest{
|
||||
Organization: org,
|
||||
Id: userID,
|
||||
})
|
||||
logging.OnError(err).Fatal("deactivate user")
|
||||
return user
|
||||
}
|
||||
|
||||
func (i *Instance) ActivateSchemaUser(ctx context.Context, orgID string, userID string) *user_v3alpha.ActivateUserResponse {
|
||||
var org *object_v3alpha.Organization
|
||||
if orgID != "" {
|
||||
org = &object_v3alpha.Organization{Property: &object_v3alpha.Organization_OrgId{OrgId: orgID}}
|
||||
}
|
||||
user, err := i.Client.UserV3Alpha.ActivateUser(ctx, &user_v3alpha.ActivateUserRequest{
|
||||
Organization: org,
|
||||
Id: userID,
|
||||
})
|
||||
logging.OnError(err).Fatal("reactivate user")
|
||||
return user
|
||||
}
|
||||
|
@@ -5,8 +5,8 @@ import (
|
||||
)
|
||||
|
||||
const (
|
||||
AggregateType = "user"
|
||||
AggregateVersion = "v3"
|
||||
AggregateType = "schemauser"
|
||||
AggregateVersion = "v1"
|
||||
)
|
||||
|
||||
type Aggregate struct {
|
||||
|
@@ -8,7 +8,6 @@ import (
|
||||
"github.com/zitadel/zitadel/internal/crypto"
|
||||
"github.com/zitadel/zitadel/internal/domain"
|
||||
"github.com/zitadel/zitadel/internal/eventstore"
|
||||
"github.com/zitadel/zitadel/internal/zerrors"
|
||||
)
|
||||
|
||||
const (
|
||||
@@ -21,11 +20,15 @@ const (
|
||||
)
|
||||
|
||||
type EmailUpdatedEvent struct {
|
||||
eventstore.BaseEvent `json:"-"`
|
||||
*eventstore.BaseEvent `json:"-"`
|
||||
|
||||
EmailAddress domain.EmailAddress `json:"email,omitempty"`
|
||||
}
|
||||
|
||||
func (e *EmailUpdatedEvent) SetBaseEvent(event *eventstore.BaseEvent) {
|
||||
e.BaseEvent = event
|
||||
}
|
||||
|
||||
func (e *EmailUpdatedEvent) Payload() interface{} {
|
||||
return e
|
||||
}
|
||||
@@ -36,7 +39,7 @@ func (e *EmailUpdatedEvent) UniqueConstraints() []*eventstore.UniqueConstraint {
|
||||
|
||||
func NewEmailUpdatedEvent(ctx context.Context, aggregate *eventstore.Aggregate, emailAddress domain.EmailAddress) *EmailUpdatedEvent {
|
||||
return &EmailUpdatedEvent{
|
||||
BaseEvent: *eventstore.NewBaseEventForPush(
|
||||
BaseEvent: eventstore.NewBaseEventForPush(
|
||||
ctx,
|
||||
aggregate,
|
||||
EmailUpdatedType,
|
||||
@@ -45,24 +48,16 @@ func NewEmailUpdatedEvent(ctx context.Context, aggregate *eventstore.Aggregate,
|
||||
}
|
||||
}
|
||||
|
||||
func EmailUpdatedEventMapper(event eventstore.Event) (eventstore.Event, error) {
|
||||
emailChangedEvent := &EmailUpdatedEvent{
|
||||
BaseEvent: *eventstore.BaseEventFromRepo(event),
|
||||
}
|
||||
err := event.Unmarshal(emailChangedEvent)
|
||||
if err != nil {
|
||||
return nil, zerrors.ThrowInternal(err, "USER-4M0sd", "unable to unmarshal human password changed")
|
||||
}
|
||||
|
||||
return emailChangedEvent, nil
|
||||
}
|
||||
|
||||
type EmailVerifiedEvent struct {
|
||||
eventstore.BaseEvent `json:"-"`
|
||||
*eventstore.BaseEvent `json:"-"`
|
||||
|
||||
IsEmailVerified bool `json:"-"`
|
||||
}
|
||||
|
||||
func (e *EmailVerifiedEvent) SetBaseEvent(event *eventstore.BaseEvent) {
|
||||
e.BaseEvent = event
|
||||
}
|
||||
|
||||
func (e *EmailVerifiedEvent) Payload() interface{} {
|
||||
return nil
|
||||
}
|
||||
@@ -73,7 +68,7 @@ func (e *EmailVerifiedEvent) UniqueConstraints() []*eventstore.UniqueConstraint
|
||||
|
||||
func NewEmailVerifiedEvent(ctx context.Context, aggregate *eventstore.Aggregate) *EmailVerifiedEvent {
|
||||
return &EmailVerifiedEvent{
|
||||
BaseEvent: *eventstore.NewBaseEventForPush(
|
||||
BaseEvent: eventstore.NewBaseEventForPush(
|
||||
ctx,
|
||||
aggregate,
|
||||
EmailVerifiedType,
|
||||
@@ -81,18 +76,13 @@ func NewEmailVerifiedEvent(ctx context.Context, aggregate *eventstore.Aggregate)
|
||||
}
|
||||
}
|
||||
|
||||
func HumanVerifiedEventMapper(event eventstore.Event) (eventstore.Event, error) {
|
||||
emailVerified := &EmailVerifiedEvent{
|
||||
BaseEvent: *eventstore.BaseEventFromRepo(event),
|
||||
IsEmailVerified: true,
|
||||
}
|
||||
return emailVerified, nil
|
||||
}
|
||||
|
||||
type EmailVerificationFailedEvent struct {
|
||||
eventstore.BaseEvent `json:"-"`
|
||||
*eventstore.BaseEvent `json:"-"`
|
||||
}
|
||||
|
||||
func (e *EmailVerificationFailedEvent) SetBaseEvent(event *eventstore.BaseEvent) {
|
||||
e.BaseEvent = event
|
||||
}
|
||||
func (e *EmailVerificationFailedEvent) Payload() interface{} {
|
||||
return nil
|
||||
}
|
||||
@@ -101,9 +91,9 @@ func (e *EmailVerificationFailedEvent) UniqueConstraints() []*eventstore.UniqueC
|
||||
return nil
|
||||
}
|
||||
|
||||
func NewHumanEmailVerificationFailedEvent(ctx context.Context, aggregate *eventstore.Aggregate) *EmailVerificationFailedEvent {
|
||||
func NewEmailVerificationFailedEvent(ctx context.Context, aggregate *eventstore.Aggregate) *EmailVerificationFailedEvent {
|
||||
return &EmailVerificationFailedEvent{
|
||||
BaseEvent: *eventstore.NewBaseEventForPush(
|
||||
BaseEvent: eventstore.NewBaseEventForPush(
|
||||
ctx,
|
||||
aggregate,
|
||||
EmailVerificationFailedType,
|
||||
@@ -111,14 +101,8 @@ func NewHumanEmailVerificationFailedEvent(ctx context.Context, aggregate *events
|
||||
}
|
||||
}
|
||||
|
||||
func EmailVerificationFailedEventMapper(event eventstore.Event) (eventstore.Event, error) {
|
||||
return &EmailVerificationFailedEvent{
|
||||
BaseEvent: *eventstore.BaseEventFromRepo(event),
|
||||
}, nil
|
||||
}
|
||||
|
||||
type EmailCodeAddedEvent struct {
|
||||
eventstore.BaseEvent `json:"-"`
|
||||
*eventstore.BaseEvent `json:"-"`
|
||||
|
||||
Code *crypto.CryptoValue `json:"code,omitempty"`
|
||||
Expiry time.Duration `json:"expiry,omitempty"`
|
||||
@@ -127,6 +111,10 @@ type EmailCodeAddedEvent struct {
|
||||
TriggeredAtOrigin string `json:"triggerOrigin,omitempty"`
|
||||
}
|
||||
|
||||
func (e *EmailCodeAddedEvent) SetBaseEvent(event *eventstore.BaseEvent) {
|
||||
e.BaseEvent = event
|
||||
}
|
||||
|
||||
func (e *EmailCodeAddedEvent) Payload() interface{} {
|
||||
return e
|
||||
}
|
||||
@@ -148,7 +136,7 @@ func NewEmailCodeAddedEvent(
|
||||
codeReturned bool,
|
||||
) *EmailCodeAddedEvent {
|
||||
return &EmailCodeAddedEvent{
|
||||
BaseEvent: *eventstore.NewBaseEventForPush(
|
||||
BaseEvent: eventstore.NewBaseEventForPush(
|
||||
ctx,
|
||||
aggregate,
|
||||
EmailCodeAddedType,
|
||||
@@ -161,22 +149,13 @@ func NewEmailCodeAddedEvent(
|
||||
}
|
||||
}
|
||||
|
||||
func EmailCodeAddedEventMapper(event eventstore.Event) (eventstore.Event, error) {
|
||||
codeAdded := &EmailCodeAddedEvent{
|
||||
BaseEvent: *eventstore.BaseEventFromRepo(event),
|
||||
}
|
||||
err := event.Unmarshal(codeAdded)
|
||||
if err != nil {
|
||||
return nil, zerrors.ThrowInternal(err, "USER-3M0sd", "unable to unmarshal human email code added")
|
||||
}
|
||||
|
||||
return codeAdded, nil
|
||||
}
|
||||
|
||||
type EmailCodeSentEvent struct {
|
||||
eventstore.BaseEvent `json:"-"`
|
||||
*eventstore.BaseEvent `json:"-"`
|
||||
}
|
||||
|
||||
func (e *EmailCodeSentEvent) SetBaseEvent(event *eventstore.BaseEvent) {
|
||||
e.BaseEvent = event
|
||||
}
|
||||
func (e *EmailCodeSentEvent) Payload() interface{} {
|
||||
return nil
|
||||
}
|
||||
@@ -185,18 +164,12 @@ func (e *EmailCodeSentEvent) UniqueConstraints() []*eventstore.UniqueConstraint
|
||||
return nil
|
||||
}
|
||||
|
||||
func NewHumanEmailCodeSentEvent(ctx context.Context, aggregate *eventstore.Aggregate) *EmailCodeSentEvent {
|
||||
func NewEmailCodeSentEvent(ctx context.Context, aggregate *eventstore.Aggregate) *EmailCodeSentEvent {
|
||||
return &EmailCodeSentEvent{
|
||||
BaseEvent: *eventstore.NewBaseEventForPush(
|
||||
BaseEvent: eventstore.NewBaseEventForPush(
|
||||
ctx,
|
||||
aggregate,
|
||||
EmailCodeSentType,
|
||||
),
|
||||
}
|
||||
}
|
||||
|
||||
func EmailCodeSentEventMapper(event eventstore.Event) (eventstore.Event, error) {
|
||||
return &EmailCodeSentEvent{
|
||||
BaseEvent: *eventstore.BaseEventFromRepo(event),
|
||||
}, nil
|
||||
}
|
||||
|
@@ -6,4 +6,18 @@ func init() {
|
||||
eventstore.RegisterFilterEventMapper(AggregateType, CreatedType, eventstore.GenericEventMapper[CreatedEvent])
|
||||
eventstore.RegisterFilterEventMapper(AggregateType, UpdatedType, eventstore.GenericEventMapper[UpdatedEvent])
|
||||
eventstore.RegisterFilterEventMapper(AggregateType, DeletedType, eventstore.GenericEventMapper[DeletedEvent])
|
||||
eventstore.RegisterFilterEventMapper(AggregateType, LockedType, eventstore.GenericEventMapper[LockedEvent])
|
||||
eventstore.RegisterFilterEventMapper(AggregateType, UnlockedType, eventstore.GenericEventMapper[UnlockedEvent])
|
||||
eventstore.RegisterFilterEventMapper(AggregateType, ActivatedType, eventstore.GenericEventMapper[ActivatedEvent])
|
||||
eventstore.RegisterFilterEventMapper(AggregateType, DeactivatedType, eventstore.GenericEventMapper[DeactivatedEvent])
|
||||
eventstore.RegisterFilterEventMapper(AggregateType, EmailUpdatedType, eventstore.GenericEventMapper[EmailUpdatedEvent])
|
||||
eventstore.RegisterFilterEventMapper(AggregateType, EmailCodeAddedType, eventstore.GenericEventMapper[EmailCodeAddedEvent])
|
||||
eventstore.RegisterFilterEventMapper(AggregateType, EmailCodeSentType, eventstore.GenericEventMapper[EmailCodeSentEvent])
|
||||
eventstore.RegisterFilterEventMapper(AggregateType, EmailVerifiedType, eventstore.GenericEventMapper[EmailVerifiedEvent])
|
||||
eventstore.RegisterFilterEventMapper(AggregateType, EmailVerificationFailedType, eventstore.GenericEventMapper[EmailVerificationFailedEvent])
|
||||
eventstore.RegisterFilterEventMapper(AggregateType, PhoneUpdatedType, eventstore.GenericEventMapper[PhoneUpdatedEvent])
|
||||
eventstore.RegisterFilterEventMapper(AggregateType, PhoneCodeAddedType, eventstore.GenericEventMapper[PhoneCodeAddedEvent])
|
||||
eventstore.RegisterFilterEventMapper(AggregateType, PhoneCodeSentType, eventstore.GenericEventMapper[PhoneCodeSentEvent])
|
||||
eventstore.RegisterFilterEventMapper(AggregateType, PhoneVerifiedType, eventstore.GenericEventMapper[PhoneVerifiedEvent])
|
||||
eventstore.RegisterFilterEventMapper(AggregateType, PhoneVerificationFailedType, eventstore.GenericEventMapper[PhoneVerificationFailedEvent])
|
||||
}
|
||||
|
@@ -8,7 +8,6 @@ import (
|
||||
"github.com/zitadel/zitadel/internal/crypto"
|
||||
"github.com/zitadel/zitadel/internal/domain"
|
||||
"github.com/zitadel/zitadel/internal/eventstore"
|
||||
"github.com/zitadel/zitadel/internal/zerrors"
|
||||
)
|
||||
|
||||
const (
|
||||
@@ -20,23 +19,27 @@ const (
|
||||
PhoneCodeSentType = phoneEventPrefix + "code.sent"
|
||||
)
|
||||
|
||||
type PhoneChangedEvent struct {
|
||||
eventstore.BaseEvent `json:"-"`
|
||||
type PhoneUpdatedEvent struct {
|
||||
*eventstore.BaseEvent `json:"-"`
|
||||
|
||||
PhoneNumber domain.PhoneNumber `json:"phone,omitempty"`
|
||||
}
|
||||
|
||||
func (e *PhoneChangedEvent) Payload() interface{} {
|
||||
func (e *PhoneUpdatedEvent) SetBaseEvent(event *eventstore.BaseEvent) {
|
||||
e.BaseEvent = event
|
||||
}
|
||||
|
||||
func (e *PhoneUpdatedEvent) Payload() interface{} {
|
||||
return e
|
||||
}
|
||||
|
||||
func (e *PhoneChangedEvent) UniqueConstraints() []*eventstore.UniqueConstraint {
|
||||
func (e *PhoneUpdatedEvent) UniqueConstraints() []*eventstore.UniqueConstraint {
|
||||
return nil
|
||||
}
|
||||
|
||||
func NewPhoneChangedEvent(ctx context.Context, aggregate *eventstore.Aggregate, phone domain.PhoneNumber) *PhoneChangedEvent {
|
||||
return &PhoneChangedEvent{
|
||||
BaseEvent: *eventstore.NewBaseEventForPush(
|
||||
func NewPhoneUpdatedEvent(ctx context.Context, aggregate *eventstore.Aggregate, phone domain.PhoneNumber) *PhoneUpdatedEvent {
|
||||
return &PhoneUpdatedEvent{
|
||||
BaseEvent: eventstore.NewBaseEventForPush(
|
||||
ctx,
|
||||
aggregate,
|
||||
PhoneUpdatedType,
|
||||
@@ -45,24 +48,15 @@ func NewPhoneChangedEvent(ctx context.Context, aggregate *eventstore.Aggregate,
|
||||
}
|
||||
}
|
||||
|
||||
func PhoneChangedEventMapper(event eventstore.Event) (eventstore.Event, error) {
|
||||
phoneChangedEvent := &PhoneChangedEvent{
|
||||
BaseEvent: *eventstore.BaseEventFromRepo(event),
|
||||
}
|
||||
err := event.Unmarshal(phoneChangedEvent)
|
||||
if err != nil {
|
||||
return nil, zerrors.ThrowInternal(err, "USER-5M0pd", "unable to unmarshal phone changed")
|
||||
}
|
||||
|
||||
return phoneChangedEvent, nil
|
||||
}
|
||||
|
||||
type PhoneVerifiedEvent struct {
|
||||
eventstore.BaseEvent `json:"-"`
|
||||
*eventstore.BaseEvent `json:"-"`
|
||||
|
||||
IsPhoneVerified bool `json:"-"`
|
||||
}
|
||||
|
||||
func (e *PhoneVerifiedEvent) SetBaseEvent(event *eventstore.BaseEvent) {
|
||||
e.BaseEvent = event
|
||||
}
|
||||
func (e *PhoneVerifiedEvent) Payload() interface{} {
|
||||
return nil
|
||||
}
|
||||
@@ -73,7 +67,7 @@ func (e *PhoneVerifiedEvent) UniqueConstraints() []*eventstore.UniqueConstraint
|
||||
|
||||
func NewPhoneVerifiedEvent(ctx context.Context, aggregate *eventstore.Aggregate) *PhoneVerifiedEvent {
|
||||
return &PhoneVerifiedEvent{
|
||||
BaseEvent: *eventstore.NewBaseEventForPush(
|
||||
BaseEvent: eventstore.NewBaseEventForPush(
|
||||
ctx,
|
||||
aggregate,
|
||||
PhoneVerifiedType,
|
||||
@@ -81,15 +75,12 @@ func NewPhoneVerifiedEvent(ctx context.Context, aggregate *eventstore.Aggregate)
|
||||
}
|
||||
}
|
||||
|
||||
func PhoneVerifiedEventMapper(event eventstore.Event) (eventstore.Event, error) {
|
||||
return &PhoneVerifiedEvent{
|
||||
BaseEvent: *eventstore.BaseEventFromRepo(event),
|
||||
IsPhoneVerified: true,
|
||||
}, nil
|
||||
type PhoneVerificationFailedEvent struct {
|
||||
*eventstore.BaseEvent `json:"-"`
|
||||
}
|
||||
|
||||
type PhoneVerificationFailedEvent struct {
|
||||
eventstore.BaseEvent `json:"-"`
|
||||
func (e *PhoneVerificationFailedEvent) SetBaseEvent(event *eventstore.BaseEvent) {
|
||||
e.BaseEvent = event
|
||||
}
|
||||
|
||||
func (e *PhoneVerificationFailedEvent) Payload() interface{} {
|
||||
@@ -102,7 +93,7 @@ func (e *PhoneVerificationFailedEvent) UniqueConstraints() []*eventstore.UniqueC
|
||||
|
||||
func NewPhoneVerificationFailedEvent(ctx context.Context, aggregate *eventstore.Aggregate) *PhoneVerificationFailedEvent {
|
||||
return &PhoneVerificationFailedEvent{
|
||||
BaseEvent: *eventstore.NewBaseEventForPush(
|
||||
BaseEvent: eventstore.NewBaseEventForPush(
|
||||
ctx,
|
||||
aggregate,
|
||||
PhoneVerificationFailedType,
|
||||
@@ -110,14 +101,8 @@ func NewPhoneVerificationFailedEvent(ctx context.Context, aggregate *eventstore.
|
||||
}
|
||||
}
|
||||
|
||||
func PhoneVerificationFailedEventMapper(event eventstore.Event) (eventstore.Event, error) {
|
||||
return &PhoneVerificationFailedEvent{
|
||||
BaseEvent: *eventstore.BaseEventFromRepo(event),
|
||||
}, nil
|
||||
}
|
||||
|
||||
type PhoneCodeAddedEvent struct {
|
||||
eventstore.BaseEvent `json:"-"`
|
||||
*eventstore.BaseEvent `json:"-"`
|
||||
|
||||
Code *crypto.CryptoValue `json:"code,omitempty"`
|
||||
Expiry time.Duration `json:"expiry,omitempty"`
|
||||
@@ -137,6 +122,10 @@ func (e *PhoneCodeAddedEvent) TriggerOrigin() string {
|
||||
return e.TriggeredAtOrigin
|
||||
}
|
||||
|
||||
func (e *PhoneCodeAddedEvent) SetBaseEvent(event *eventstore.BaseEvent) {
|
||||
e.BaseEvent = event
|
||||
}
|
||||
|
||||
func NewPhoneCodeAddedEvent(
|
||||
ctx context.Context,
|
||||
aggregate *eventstore.Aggregate,
|
||||
@@ -145,7 +134,7 @@ func NewPhoneCodeAddedEvent(
|
||||
codeReturned bool,
|
||||
) *PhoneCodeAddedEvent {
|
||||
return &PhoneCodeAddedEvent{
|
||||
BaseEvent: *eventstore.NewBaseEventForPush(
|
||||
BaseEvent: eventstore.NewBaseEventForPush(
|
||||
ctx,
|
||||
aggregate,
|
||||
PhoneCodeAddedType,
|
||||
@@ -157,20 +146,8 @@ func NewPhoneCodeAddedEvent(
|
||||
}
|
||||
}
|
||||
|
||||
func PhoneCodeAddedEventMapper(event eventstore.Event) (eventstore.Event, error) {
|
||||
codeAdded := &PhoneCodeAddedEvent{
|
||||
BaseEvent: *eventstore.BaseEventFromRepo(event),
|
||||
}
|
||||
err := event.Unmarshal(codeAdded)
|
||||
if err != nil {
|
||||
return nil, zerrors.ThrowInternal(err, "USER-6Ms9d", "unable to unmarshal phone code added")
|
||||
}
|
||||
|
||||
return codeAdded, nil
|
||||
}
|
||||
|
||||
type PhoneCodeSentEvent struct {
|
||||
eventstore.BaseEvent `json:"-"`
|
||||
*eventstore.BaseEvent `json:"-"`
|
||||
}
|
||||
|
||||
func (e *PhoneCodeSentEvent) Payload() interface{} {
|
||||
@@ -181,18 +158,16 @@ func (e *PhoneCodeSentEvent) UniqueConstraints() []*eventstore.UniqueConstraint
|
||||
return nil
|
||||
}
|
||||
|
||||
func (e *PhoneCodeSentEvent) SetBaseEvent(event *eventstore.BaseEvent) {
|
||||
e.BaseEvent = event
|
||||
}
|
||||
|
||||
func NewPhoneCodeSentEvent(ctx context.Context, aggregate *eventstore.Aggregate) *PhoneCodeSentEvent {
|
||||
return &PhoneCodeSentEvent{
|
||||
BaseEvent: *eventstore.NewBaseEventForPush(
|
||||
BaseEvent: eventstore.NewBaseEventForPush(
|
||||
ctx,
|
||||
aggregate,
|
||||
PhoneCodeSentType,
|
||||
),
|
||||
}
|
||||
}
|
||||
|
||||
func PhoneCodeSentEventMapper(event eventstore.Event) (eventstore.Event, error) {
|
||||
return &PhoneCodeSentEvent{
|
||||
BaseEvent: *eventstore.BaseEventFromRepo(event),
|
||||
}, nil
|
||||
}
|
||||
|
@@ -8,10 +8,14 @@ import (
|
||||
)
|
||||
|
||||
const (
|
||||
eventPrefix = "user."
|
||||
CreatedType = eventPrefix + "created"
|
||||
UpdatedType = eventPrefix + "updated"
|
||||
DeletedType = eventPrefix + "deleted"
|
||||
eventPrefix = "schemauser."
|
||||
CreatedType = eventPrefix + "created"
|
||||
UpdatedType = eventPrefix + "updated"
|
||||
DeletedType = eventPrefix + "deleted"
|
||||
LockedType = eventPrefix + "locked"
|
||||
UnlockedType = eventPrefix + "unlocked"
|
||||
DeactivatedType = eventPrefix + "deactivated"
|
||||
ActivatedType = eventPrefix + "activated"
|
||||
)
|
||||
|
||||
type CreatedEvent struct {
|
||||
@@ -60,8 +64,6 @@ type UpdatedEvent struct {
|
||||
SchemaID *string `json:"schemaID,omitempty"`
|
||||
SchemaRevision *uint64 `json:"schemaRevision,omitempty"`
|
||||
Data json.RawMessage `json:"schema,omitempty"`
|
||||
oldSchemaID string
|
||||
oldRevision uint64
|
||||
}
|
||||
|
||||
func (e *UpdatedEvent) SetBaseEvent(event *eventstore.BaseEvent) {
|
||||
@@ -95,16 +97,14 @@ func NewUpdatedEvent(
|
||||
|
||||
type Changes func(event *UpdatedEvent)
|
||||
|
||||
func ChangeSchemaID(oldSchemaID, schemaID string) func(event *UpdatedEvent) {
|
||||
func ChangeSchemaID(schemaID string) func(event *UpdatedEvent) {
|
||||
return func(e *UpdatedEvent) {
|
||||
e.SchemaID = &schemaID
|
||||
e.oldSchemaID = oldSchemaID
|
||||
}
|
||||
}
|
||||
func ChangeSchemaRevision(oldSchemaRevision, schemaRevision uint64) func(event *UpdatedEvent) {
|
||||
func ChangeSchemaRevision(schemaRevision uint64) func(event *UpdatedEvent) {
|
||||
return func(e *UpdatedEvent) {
|
||||
e.SchemaRevision = &schemaRevision
|
||||
e.oldRevision = oldSchemaRevision
|
||||
}
|
||||
}
|
||||
|
||||
@@ -142,3 +142,119 @@ func NewDeletedEvent(
|
||||
),
|
||||
}
|
||||
}
|
||||
|
||||
type LockedEvent struct {
|
||||
*eventstore.BaseEvent `json:"-"`
|
||||
}
|
||||
|
||||
func (e *LockedEvent) SetBaseEvent(event *eventstore.BaseEvent) {
|
||||
e.BaseEvent = event
|
||||
}
|
||||
|
||||
func (e *LockedEvent) Payload() interface{} {
|
||||
return e
|
||||
}
|
||||
|
||||
func (e *LockedEvent) UniqueConstraints() []*eventstore.UniqueConstraint {
|
||||
return nil
|
||||
}
|
||||
|
||||
func NewLockedEvent(
|
||||
ctx context.Context,
|
||||
aggregate *eventstore.Aggregate,
|
||||
) *LockedEvent {
|
||||
return &LockedEvent{
|
||||
BaseEvent: eventstore.NewBaseEventForPush(
|
||||
ctx,
|
||||
aggregate,
|
||||
LockedType,
|
||||
),
|
||||
}
|
||||
}
|
||||
|
||||
type UnlockedEvent struct {
|
||||
*eventstore.BaseEvent `json:"-"`
|
||||
}
|
||||
|
||||
func (e *UnlockedEvent) SetBaseEvent(event *eventstore.BaseEvent) {
|
||||
e.BaseEvent = event
|
||||
}
|
||||
|
||||
func (e *UnlockedEvent) Payload() interface{} {
|
||||
return e
|
||||
}
|
||||
|
||||
func (e *UnlockedEvent) UniqueConstraints() []*eventstore.UniqueConstraint {
|
||||
return nil
|
||||
}
|
||||
|
||||
func NewUnlockedEvent(
|
||||
ctx context.Context,
|
||||
aggregate *eventstore.Aggregate,
|
||||
) *UnlockedEvent {
|
||||
return &UnlockedEvent{
|
||||
BaseEvent: eventstore.NewBaseEventForPush(
|
||||
ctx,
|
||||
aggregate,
|
||||
UnlockedType,
|
||||
),
|
||||
}
|
||||
}
|
||||
|
||||
type DeactivatedEvent struct {
|
||||
*eventstore.BaseEvent `json:"-"`
|
||||
}
|
||||
|
||||
func (e *DeactivatedEvent) SetBaseEvent(event *eventstore.BaseEvent) {
|
||||
e.BaseEvent = event
|
||||
}
|
||||
|
||||
func (e *DeactivatedEvent) Payload() interface{} {
|
||||
return e
|
||||
}
|
||||
|
||||
func (e *DeactivatedEvent) UniqueConstraints() []*eventstore.UniqueConstraint {
|
||||
return nil
|
||||
}
|
||||
|
||||
func NewDeactivatedEvent(
|
||||
ctx context.Context,
|
||||
aggregate *eventstore.Aggregate,
|
||||
) *DeactivatedEvent {
|
||||
return &DeactivatedEvent{
|
||||
BaseEvent: eventstore.NewBaseEventForPush(
|
||||
ctx,
|
||||
aggregate,
|
||||
DeactivatedType,
|
||||
),
|
||||
}
|
||||
}
|
||||
|
||||
type ActivatedEvent struct {
|
||||
*eventstore.BaseEvent `json:"-"`
|
||||
}
|
||||
|
||||
func (e *ActivatedEvent) SetBaseEvent(event *eventstore.BaseEvent) {
|
||||
e.BaseEvent = event
|
||||
}
|
||||
|
||||
func (e *ActivatedEvent) Payload() interface{} {
|
||||
return e
|
||||
}
|
||||
|
||||
func (e *ActivatedEvent) UniqueConstraints() []*eventstore.UniqueConstraint {
|
||||
return nil
|
||||
}
|
||||
|
||||
func NewActivatedEvent(
|
||||
ctx context.Context,
|
||||
aggregate *eventstore.Aggregate,
|
||||
) *ActivatedEvent {
|
||||
return &ActivatedEvent{
|
||||
BaseEvent: eventstore.NewBaseEventForPush(
|
||||
ctx,
|
||||
aggregate,
|
||||
ActivatedType,
|
||||
),
|
||||
}
|
||||
}
|
||||
|
Reference in New Issue
Block a user