fix: some backend bugs (#1438)

* fix: fix setup

* fix oidc app change

* fix: fix migration and proto

* fix: fix granted projects

* setup1 apis instead of apps

* fix: add object detail with creation date

* fix user phone change

* add localizer to AddOIDCAppResponse

* fix test

* fix domain test

* fix: converter

Co-authored-by: Livio Amstutz <livio.a@gmail.com>
This commit is contained in:
Fabi
2021-03-19 18:46:26 +01:00
committed by GitHub
parent 24527bd354
commit 6b1f7ba333
58 changed files with 578 additions and 429 deletions

View File

@@ -9,6 +9,6 @@ func writeModelToObjectDetails(writeModel *eventstore.WriteModel) *domain.Object
return &domain.ObjectDetails{
Sequence: writeModel.ProcessedSequence,
ResourceOwner: writeModel.ResourceOwner,
ChangeDate: writeModel.ChangeDate,
EventDate: writeModel.ChangeDate,
}
}

View File

@@ -13,8 +13,15 @@ import (
)
func (c *Commands) AddIAMMember(ctx context.Context, member *domain.Member) (*domain.Member, error) {
if member.UserID == "" {
return nil, caos_errs.ThrowInvalidArgument(nil, "IAM-Mf83b", "Errors.IAM.MemberInvalid")
}
addedMember := NewIAMMemberWriteModel(member.UserID)
iamAgg := IAMAggregateFromWriteModel(&addedMember.MemberWriteModel.WriteModel)
err := c.checkUserExists(ctx, addedMember.UserID, "")
if err != nil {
return nil, caos_errs.ThrowPreconditionFailed(err, "IAM-5N9vs", "Errors.User.NotFound")
}
event, err := c.addIAMMember(ctx, iamAgg, addedMember, member)
if err != nil {
return nil, err
@@ -38,11 +45,7 @@ func (c *Commands) addIAMMember(ctx context.Context, iamAgg *eventstore.Aggregat
if len(domain.CheckForInvalidRoles(member.Roles, domain.IAMRolePrefix, c.zitadelRoles)) > 0 {
return nil, caos_errs.ThrowInvalidArgument(nil, "IAM-4m0fS", "Errors.IAM.MemberInvalid")
}
err := c.checkUserExists(ctx, addedMember.UserID, "")
if err != nil {
return nil, caos_errs.ThrowPreconditionFailed(err, "IAM-5N9vs", "Errors.User.NotFound")
}
err = c.eventstore.FilterToQueryReducer(ctx, addedMember)
err := c.eventstore.FilterToQueryReducer(ctx, addedMember)
if err != nil {
return nil, err
}

View File

@@ -50,11 +50,46 @@ func TestCommandSide_AddIAMMember(t *testing.T) {
err: caos_errs.IsErrorInvalidArgument,
},
},
{
name: "user not existing, precondition error",
fields: fields{
eventstore: eventstoreExpect(
t,
expectFilter(),
),
},
args: args{
ctx: context.Background(),
member: &domain.Member{
UserID: "user1",
Roles: []string{"IAM_OWNER"},
},
},
res: res{
err: caos_errs.IsPreconditionFailed,
},
},
{
name: "invalid roles, error",
fields: fields{
eventstore: eventstoreExpect(
t,
expectFilter(
eventFromEventPusher(
user.NewHumanAddedEvent(context.Background(),
&user.NewAggregate("user1", "org1").Aggregate,
"username1",
"firstname1",
"lastname1",
"nickname1",
"displayname1",
language.German,
domain.GenderMale,
"email1",
true,
),
),
),
),
},
args: args{
@@ -68,30 +103,6 @@ func TestCommandSide_AddIAMMember(t *testing.T) {
err: caos_errs.IsErrorInvalidArgument,
},
},
{
name: "user not existing, precondition error",
fields: fields{
eventstore: eventstoreExpect(
t,
expectFilter(),
),
zitadelRoles: []authz.RoleMapping{
{
Role: "IAM_OWNER",
},
},
},
args: args{
ctx: context.Background(),
member: &domain.Member{
UserID: "user1",
Roles: []string{"IAM_OWNER"},
},
},
res: res{
err: caos_errs.IsPreconditionFailed,
},
},
{
name: "member already exists, precondition error",
fields: fields{

View File

@@ -31,7 +31,15 @@ func (c *Commands) checkOrgExists(ctx context.Context, orgID string) error {
}
func (c *Commands) SetUpOrg(ctx context.Context, organisation *domain.Org, admin *domain.Human) (*domain.ObjectDetails, error) {
_, orgWriteModel, _, _, events, err := c.setUpOrg(ctx, organisation, admin)
orgIAMPolicy, err := c.getDefaultOrgIAMPolicy(ctx)
if err != nil {
return nil, caos_errs.ThrowPreconditionFailed(err, "COMMAND-33M9f", "Errors.IAM.OrgIAMPolicy.NotFound")
}
pwPolicy, err := c.getDefaultPasswordComplexityPolicy(ctx)
if err != nil {
return nil, caos_errs.ThrowPreconditionFailed(err, "COMMAND-M5Fsd", "Errors.IAM.PasswordComplexity.NotFound")
}
_, orgWriteModel, _, _, events, err := c.setUpOrg(ctx, organisation, admin, orgIAMPolicy, pwPolicy)
if err != nil {
return nil, err
}
@@ -51,7 +59,6 @@ func (c *Commands) AddOrg(ctx context.Context, name, userID, resourceOwner strin
if err != nil {
return nil, err
}
err = c.checkUserExists(ctx, userID, resourceOwner)
if err != nil {
return nil, err
@@ -119,13 +126,13 @@ func (c *Commands) ReactivateOrg(ctx context.Context, orgID string) (*domain.Obj
return writeModelToObjectDetails(&orgWriteModel.WriteModel), nil
}
func (c *Commands) setUpOrg(ctx context.Context, organisation *domain.Org, admin *domain.Human) (orgAgg *eventstore.Aggregate, org *OrgWriteModel, human *HumanWriteModel, orgMember *OrgMemberWriteModel, events []eventstore.EventPusher, err error) {
func (c *Commands) setUpOrg(ctx context.Context, organisation *domain.Org, admin *domain.Human, loginPolicy *domain.OrgIAMPolicy, pwPolicy *domain.PasswordComplexityPolicy) (orgAgg *eventstore.Aggregate, org *OrgWriteModel, human *HumanWriteModel, orgMember *OrgMemberWriteModel, events []eventstore.EventPusher, err error) {
orgAgg, orgWriteModel, addOrgEvents, err := c.addOrg(ctx, organisation)
if err != nil {
return nil, nil, nil, nil, nil, err
}
userEvents, human, err := c.addHuman(ctx, orgAgg.ID, admin)
userEvents, human, err := c.addHuman(ctx, orgAgg.ID, admin, loginPolicy, pwPolicy)
if err != nil {
return nil, nil, nil, nil, nil, err
}

View File

@@ -13,8 +13,15 @@ import (
)
func (c *Commands) AddOrgMember(ctx context.Context, member *domain.Member) (*domain.Member, error) {
if member.UserID == "" {
return nil, caos_errs.ThrowInvalidArgument(nil, "Org-u8fkf", "Errors.Org.MemberInvalid")
}
addedMember := NewOrgMemberWriteModel(member.AggregateID, member.UserID)
orgAgg := OrgAggregateFromWriteModel(&addedMember.WriteModel)
err := c.checkUserExists(ctx, addedMember.UserID, "")
if err != nil {
return nil, caos_errs.ThrowPreconditionFailed(err, "Org-2H8ds", "Errors.User.NotFound")
}
event, err := c.addOrgMember(ctx, orgAgg, addedMember, member)
if err != nil {
return nil, err
@@ -35,13 +42,9 @@ func (c *Commands) addOrgMember(ctx context.Context, orgAgg *eventstore.Aggregat
return nil, caos_errs.ThrowInvalidArgument(nil, "Org-W8m4l", "Errors.Org.MemberInvalid")
}
if len(domain.CheckForInvalidRoles(member.Roles, domain.OrgRolePrefix, c.zitadelRoles)) > 0 {
return nil, caos_errs.ThrowInvalidArgument(nil, "IAM-3m9fs", "Errors.Org.MemberInvalid")
return nil, caos_errs.ThrowInvalidArgument(nil, "Org-4N8es", "Errors.Org.MemberInvalid")
}
err := c.checkUserExists(ctx, addedMember.UserID, "")
if err != nil {
return nil, caos_errs.ThrowPreconditionFailed(err, "ORG-9cmsd", "Errors.User.NotFound")
}
err = c.eventstore.FilterToQueryReducer(ctx, addedMember)
err := c.eventstore.FilterToQueryReducer(ctx, addedMember)
if err != nil {
return nil, err
}

View File

@@ -57,11 +57,49 @@ func TestCommandSide_AddOrgMember(t *testing.T) {
err: caos_errs.IsErrorInvalidArgument,
},
},
{
name: "user not existing, precondition error",
fields: fields{
eventstore: eventstoreExpect(
t,
expectFilter(),
),
},
args: args{
ctx: context.Background(),
member: &domain.Member{
ObjectRoot: models.ObjectRoot{
AggregateID: "org1",
},
UserID: "user1",
Roles: []string{domain.RoleOrgOwner},
},
},
res: res{
err: caos_errs.IsPreconditionFailed,
},
},
{
name: "invalid roles, error",
fields: fields{
eventstore: eventstoreExpect(
t,
expectFilter(
eventFromEventPusher(
user.NewHumanAddedEvent(context.Background(),
&user.NewAggregate("user1", "org1").Aggregate,
"username1",
"firstname1",
"lastname1",
"nickname1",
"displayname1",
language.German,
domain.GenderMale,
"email1",
true,
),
),
),
),
},
args: args{
@@ -78,33 +116,6 @@ func TestCommandSide_AddOrgMember(t *testing.T) {
err: caos_errs.IsErrorInvalidArgument,
},
},
{
name: "user not existing, precondition error",
fields: fields{
eventstore: eventstoreExpect(
t,
expectFilter(),
),
zitadelRoles: []authz.RoleMapping{
{
Role: domain.RoleOrgOwner,
},
},
},
args: args{
ctx: context.Background(),
member: &domain.Member{
ObjectRoot: models.ObjectRoot{
AggregateID: "org1",
},
UserID: "user1",
Roles: []string{domain.RoleOrgOwner},
},
},
res: res{
err: caos_errs.IsPreconditionFailed,
},
},
{
name: "member already exists, precondition error",
fields: fields{

View File

@@ -2,6 +2,11 @@ package command
import (
"context"
"testing"
"github.com/stretchr/testify/assert"
"golang.org/x/text/language"
"github.com/caos/zitadel/internal/api/authz"
"github.com/caos/zitadel/internal/domain"
caos_errs "github.com/caos/zitadel/internal/errors"
@@ -13,9 +18,6 @@ import (
"github.com/caos/zitadel/internal/repository/member"
"github.com/caos/zitadel/internal/repository/org"
"github.com/caos/zitadel/internal/repository/user"
"github.com/stretchr/testify/assert"
"golang.org/x/text/language"
"testing"
)
func TestCommandSide_AddOrg(t *testing.T) {
@@ -122,22 +124,6 @@ func TestCommandSide_AddOrg(t *testing.T) {
),
),
),
expectFilter(
eventFromEventPusher(
user.NewHumanAddedEvent(context.Background(),
&user.NewAggregate("user1", "org1").Aggregate,
"username1",
"firstname1",
"lastname1",
"nickname1",
"displayname1",
language.German,
domain.GenderMale,
"email1",
true,
),
),
),
expectFilterOrgMemberNotFound(),
expectPushFailed(caos_errs.ThrowAlreadyExists(nil, "id", "internal"),
[]*repository.Event{
@@ -207,22 +193,6 @@ func TestCommandSide_AddOrg(t *testing.T) {
),
),
),
expectFilter(
eventFromEventPusher(
user.NewHumanAddedEvent(context.Background(),
&user.NewAggregate("user1", "org1").Aggregate,
"username1",
"firstname1",
"lastname1",
"nickname1",
"displayname1",
language.German,
domain.GenderMale,
"email1",
true,
),
),
),
expectFilterOrgMemberNotFound(),
expectPushFailed(caos_errs.ThrowInternal(nil, "id", "internal"),
[]*repository.Event{
@@ -292,22 +262,6 @@ func TestCommandSide_AddOrg(t *testing.T) {
),
),
),
expectFilter(
eventFromEventPusher(
user.NewHumanAddedEvent(context.Background(),
&user.NewAggregate("user1", "org1").Aggregate,
"username1",
"firstname1",
"lastname1",
"nickname1",
"displayname1",
language.German,
domain.GenderMale,
"email1",
true,
),
),
),
expectFilterOrgMemberNotFound(),
expectPush(
[]*repository.Event{

View File

@@ -43,8 +43,8 @@ func (c *Commands) AddOIDCApplication(ctx context.Context, application *domain.O
}
func (c *Commands) addOIDCApplication(ctx context.Context, projectAgg *eventstore.Aggregate, proj *domain.Project, oidcApp *domain.OIDCApp, resourceOwner string) (events []eventstore.EventPusher, stringPW string, err error) {
if !oidcApp.IsValid() {
return nil, "", caos_errs.ThrowInvalidArgument(nil, "PROJECT-Bff2g", "Errors.Application.Invalid")
if oidcApp.AppName == "" || !oidcApp.IsValid() {
return nil, "", caos_errs.ThrowInvalidArgument(nil, "PROJECT-1n8df", "Errors.Application.Invalid")
}
oidcApp.AppID, err = c.idGenerator.Next()
if err != nil {

View File

@@ -2,6 +2,11 @@ package command
import (
"context"
"testing"
"time"
"github.com/stretchr/testify/assert"
"github.com/caos/zitadel/internal/crypto"
"github.com/caos/zitadel/internal/domain"
caos_errs "github.com/caos/zitadel/internal/errors"
@@ -11,9 +16,6 @@ import (
"github.com/caos/zitadel/internal/id"
id_mock "github.com/caos/zitadel/internal/id/mock"
"github.com/caos/zitadel/internal/repository/project"
"github.com/stretchr/testify/assert"
"testing"
"time"
)
func TestCommandSide_AddOIDCApplication(t *testing.T) {
@@ -285,8 +287,9 @@ func TestCommandSide_ChangeOIDCApplication(t *testing.T) {
AggregateID: "project1",
},
AppID: "",
AppName: "app",
AuthMethodType: domain.OIDCAuthMethodTypePost,
GrantTypes: []domain.OIDCGrantType{domain.OIDCGrantTypeAuthorizationCode},
ResponseTypes: []domain.OIDCResponseType{domain.OIDCResponseTypeCode},
},
resourceOwner: "org1",
},
@@ -308,8 +311,9 @@ func TestCommandSide_ChangeOIDCApplication(t *testing.T) {
AggregateID: "",
},
AppID: "appid",
AppName: "app",
AuthMethodType: domain.OIDCAuthMethodTypePost,
GrantTypes: []domain.OIDCGrantType{domain.OIDCGrantTypeAuthorizationCode},
ResponseTypes: []domain.OIDCResponseType{domain.OIDCResponseTypeCode},
},
resourceOwner: "org1",
},
@@ -331,8 +335,10 @@ func TestCommandSide_ChangeOIDCApplication(t *testing.T) {
ObjectRoot: models.ObjectRoot{
AggregateID: "project1",
},
AppID: "app1",
AppName: "app",
AppID: "app1",
AuthMethodType: domain.OIDCAuthMethodTypePost,
GrantTypes: []domain.OIDCGrantType{domain.OIDCGrantTypeAuthorizationCode},
ResponseTypes: []domain.OIDCResponseType{domain.OIDCResponseTypeCode},
},
resourceOwner: "org1",
},

View File

@@ -13,7 +13,7 @@ import (
func (c *Commands) AddProjectGrant(ctx context.Context, grant *domain.ProjectGrant, resourceOwner string) (_ *domain.ProjectGrant, err error) {
if !grant.IsValid() {
return nil, caos_errs.ThrowInvalidArgument(nil, "PROJECT-Bff2g", "Errors.Project.Grant.Invalid")
return nil, caos_errs.ThrowInvalidArgument(nil, "PROJECT-3b8fs", "Errors.Project.Grant.Invalid")
}
err = c.checkProjectGrantPreCondition(ctx, grant)
if err != nil {

View File

@@ -2,6 +2,7 @@ package command
import (
"context"
"github.com/caos/zitadel/internal/eventstore"
"github.com/caos/zitadel/internal/eventstore/v1/models"
@@ -23,9 +24,10 @@ const (
OIDCApplicationTypeNative = "NATIVE"
OIDCApplicationTypeUserAgent = "USER_AGENT"
OIDCApplicationTypeWeb = "WEB"
OIDCAuthMethodTypeNone = "NONE"
OIDCAuthMethodTypeBasic = "BASIC"
OIDCAuthMethodTypePost = "POST"
AuthMethodTypeNone = "NONE"
AuthMethodTypeBasic = "BASIC"
AuthMethodTypePost = "POST"
AuthMethodTypePrivateKeyJWT = "PRIVATE_KEY_JWT"
)
type Step1 struct {
@@ -70,6 +72,7 @@ type Project struct {
Users []User
Members []string
OIDCApps []OIDCApp
APIs []API
}
type OIDCApp struct {
@@ -83,6 +86,11 @@ type OIDCApp struct {
DevMode bool
}
type API struct {
Name string
AuthMethodType string
}
func (c *Commands) SetupStep1(ctx context.Context, step1 *Step1) error {
var events []eventstore.EventPusher
iamWriteModel := NewIAMWriteModel()
@@ -101,6 +109,13 @@ func (c *Commands) SetupStep1(ctx context.Context, step1 *Step1) error {
logging.Log("SETUP-sd2hj").Info("default login policy set up")
//create orgs
for _, organisation := range step1.Orgs {
orgIAMPolicy := &domain.OrgIAMPolicy{UserLoginMustBeDomain: true}
if organisation.OrgIamPolicy {
orgIAMPolicy.UserLoginMustBeDomain = false
}
pwPolicy := &domain.PasswordComplexityPolicy{
MinLength: 1,
}
orgAgg, _, humanWriteModel, _, setUpOrgEvents, err := c.setUpOrg(ctx,
&domain.Org{
Name: organisation.Name,
@@ -119,7 +134,7 @@ func (c *Commands) SetupStep1(ctx context.Context, step1 *Step1) error {
EmailAddress: organisation.Owner.Email,
IsEmailVerified: true,
},
})
}, orgIAMPolicy, pwPolicy)
if err != nil {
return err
}
@@ -127,7 +142,7 @@ func (c *Commands) SetupStep1(ctx context.Context, step1 *Step1) error {
logging.LogWithFields("SETUP-Gdsfg", "id", orgAgg.ID, "name", organisation.Name).Info("org set up")
if organisation.OrgIamPolicy {
orgIAMPolicyEvent, err := c.addOrgIAMPolicy(ctx, orgAgg, NewORGOrgIAMPolicyWriteModel(orgAgg.ID), &domain.OrgIAMPolicy{UserLoginMustBeDomain: false})
orgIAMPolicyEvent, err := c.addOrgIAMPolicy(ctx, orgAgg, NewORGOrgIAMPolicyWriteModel(orgAgg.ID), orgIAMPolicy)
if err != nil {
return err
}
@@ -165,7 +180,14 @@ func (c *Commands) SetupStep1(ctx context.Context, step1 *Step1) error {
}
//create applications
for _, app := range proj.OIDCApps {
applicationEvents, err := setUpApplication(ctx, c, projectWriteModel, project, app, orgAgg.ID)
applicationEvents, err := setUpOIDCApplication(ctx, c, projectWriteModel, project, app, orgAgg.ID)
if err != nil {
return err
}
events = append(events, applicationEvents...)
}
for _, app := range proj.APIs {
applicationEvents, err := setUpAPI(ctx, c, projectWriteModel, project, app, orgAgg.ID)
if err != nil {
return err
}
@@ -183,7 +205,7 @@ func (c *Commands) SetupStep1(ctx context.Context, step1 *Step1) error {
return nil
}
func setUpApplication(ctx context.Context, r *Commands, projectWriteModel *ProjectWriteModel, project *domain.Project, oidcApp OIDCApp, resourceOwner string) ([]eventstore.EventPusher, error) {
func setUpOIDCApplication(ctx context.Context, r *Commands, projectWriteModel *ProjectWriteModel, project *domain.Project, oidcApp OIDCApp, resourceOwner string) ([]eventstore.EventPusher, error) {
app := &domain.OIDCApp{
ObjectRoot: models.ObjectRoot{
AggregateID: projectWriteModel.AggregateID,
@@ -206,6 +228,24 @@ func setUpApplication(ctx context.Context, r *Commands, projectWriteModel *Proje
return events, nil
}
func setUpAPI(ctx context.Context, r *Commands, projectWriteModel *ProjectWriteModel, project *domain.Project, apiApp API, resourceOwner string) ([]eventstore.EventPusher, error) {
app := &domain.APIApp{
ObjectRoot: models.ObjectRoot{
AggregateID: projectWriteModel.AggregateID,
},
AppName: apiApp.Name,
AuthMethodType: getAPIAuthMethod(apiApp.AuthMethodType),
}
projectAgg := ProjectAggregateFromWriteModel(&projectWriteModel.WriteModel)
events, _, err := r.addAPIApplication(ctx, projectAgg, project, app, resourceOwner)
if err != nil {
return nil, err
}
logging.LogWithFields("SETUP-Dbgsf", "name", app.AppName, "clientID", app.ClientID).Info("application set up")
return events, nil
}
func getOIDCResponseTypes(responseTypes []string) []domain.OIDCResponseType {
types := make([]domain.OIDCResponseType, len(responseTypes))
for i, t := range responseTypes {
@@ -260,12 +300,24 @@ func getOIDCApplicationType(appType string) domain.OIDCApplicationType {
func getOIDCAuthMethod(authMethod string) domain.OIDCAuthMethodType {
switch authMethod {
case OIDCAuthMethodTypeNone:
case AuthMethodTypeNone:
return domain.OIDCAuthMethodTypeNone
case OIDCAuthMethodTypeBasic:
case AuthMethodTypeBasic:
return domain.OIDCAuthMethodTypeBasic
case OIDCAuthMethodTypePost:
case AuthMethodTypePost:
return domain.OIDCAuthMethodTypePost
case AuthMethodTypePrivateKeyJWT:
return domain.OIDCAuthMethodTypePrivateKeyJWT
}
return domain.OIDCAuthMethodTypeBasic
}
func getAPIAuthMethod(authMethod string) domain.APIAuthMethodType {
switch authMethod {
case AuthMethodTypeBasic:
return domain.APIAuthMethodTypeBasic
case AuthMethodTypePrivateKeyJWT:
return domain.APIAuthMethodTypePrivateKeyJWT
}
return domain.APIAuthMethodTypePrivateKeyJWT
}

View File

@@ -22,7 +22,18 @@ func (c *Commands) getHuman(ctx context.Context, userID, resourceowner string) (
}
func (c *Commands) AddHuman(ctx context.Context, orgID string, human *domain.Human) (*domain.Human, error) {
events, addedHuman, err := c.addHuman(ctx, orgID, human)
if orgID == "" {
return nil, caos_errs.ThrowInvalidArgument(nil, "COMMAND-4M90d", "Errors.ResourceOwnerMissing")
}
orgIAMPolicy, err := c.getOrgIAMPolicy(ctx, orgID)
if err != nil {
return nil, caos_errs.ThrowPreconditionFailed(err, "COMMAND-33M9f", "Errors.Org.OrgIAMPolicy.NotFound")
}
pwPolicy, err := c.getOrgPasswordComplexityPolicy(ctx, orgID)
if err != nil {
return nil, caos_errs.ThrowPreconditionFailed(err, "COMMAND-M5Fsd", "Errors.Org.PasswordComplexity.NotFound")
}
events, addedHuman, err := c.addHuman(ctx, orgID, human, orgIAMPolicy, pwPolicy)
if err != nil {
return nil, err
}
@@ -39,11 +50,11 @@ func (c *Commands) AddHuman(ctx context.Context, orgID string, human *domain.Hum
return writeModelToHuman(addedHuman), nil
}
func (c *Commands) addHuman(ctx context.Context, orgID string, human *domain.Human) ([]eventstore.EventPusher, *HumanWriteModel, error) {
func (c *Commands) addHuman(ctx context.Context, orgID string, human *domain.Human, orgIAMPolicy *domain.OrgIAMPolicy, pwPolicy *domain.PasswordComplexityPolicy) ([]eventstore.EventPusher, *HumanWriteModel, error) {
if orgID == "" || !human.IsValid() {
return nil, nil, caos_errs.ThrowInvalidArgument(nil, "COMMAND-4M90d", "Errors.User.Invalid")
}
return c.createHuman(ctx, orgID, human, nil, false)
return c.createHuman(ctx, orgID, human, nil, false, orgIAMPolicy, pwPolicy)
}
func (c *Commands) RegisterHuman(ctx context.Context, orgID string, human *domain.Human, externalIDP *domain.ExternalIDP, orgMemberRoles []string) (*domain.Human, error) {
@@ -85,26 +96,26 @@ func (c *Commands) registerHuman(ctx context.Context, orgID string, human *domai
if orgID == "" || !human.IsValid() || externalIDP == nil && (human.Password == nil || human.SecretString == "") {
return nil, nil, caos_errs.ThrowInvalidArgument(nil, "COMMAND-9dk45", "Errors.User.Invalid")
}
return c.createHuman(ctx, orgID, human, externalIDP, true)
}
func (c *Commands) createHuman(ctx context.Context, orgID string, human *domain.Human, externalIDP *domain.ExternalIDP, selfregister bool) ([]eventstore.EventPusher, *HumanWriteModel, error) {
userID, err := c.idGenerator.Next()
if err != nil {
return nil, nil, err
}
human.AggregateID = userID
orgIAMPolicy, err := c.getOrgIAMPolicy(ctx, orgID)
if err != nil {
return nil, nil, caos_errs.ThrowPreconditionFailed(err, "COMMAND-33M9f", "Errors.Org.OrgIAMPolicy.NotFound")
}
if err := human.CheckOrgIAMPolicy(orgIAMPolicy); err != nil {
return nil, nil, err
}
pwPolicy, err := c.getOrgPasswordComplexityPolicy(ctx, orgID)
if err != nil {
return nil, nil, caos_errs.ThrowPreconditionFailed(err, "COMMAND-M5Fsd", "Errors.Org.PasswordComplexity.NotFound")
}
return c.createHuman(ctx, orgID, human, externalIDP, true, orgIAMPolicy, pwPolicy)
}
func (c *Commands) createHuman(ctx context.Context, orgID string, human *domain.Human, externalIDP *domain.ExternalIDP, selfregister bool, orgIAMPolicy *domain.OrgIAMPolicy, pwPolicy *domain.PasswordComplexityPolicy) ([]eventstore.EventPusher, *HumanWriteModel, error) {
if err := human.CheckOrgIAMPolicy(orgIAMPolicy); err != nil {
return nil, nil, err
}
userID, err := c.idGenerator.Next()
if err != nil {
return nil, nil, err
}
human.AggregateID = userID
human.SetNamesAsDisplayname()
if err := human.HashPasswordIfExisting(pwPolicy, c.userPasswordAlg, !selfregister); err != nil {
return nil, nil, err

View File

@@ -12,12 +12,12 @@ import (
"github.com/caos/zitadel/internal/telemetry/tracing"
)
func (c *Commands) ChangeHumanPhone(ctx context.Context, phone *domain.Phone) (*domain.Phone, error) {
func (c *Commands) ChangeHumanPhone(ctx context.Context, phone *domain.Phone, resourceOwner string) (*domain.Phone, error) {
if !phone.IsValid() {
return nil, caos_errs.ThrowInvalidArgument(nil, "COMMAND-6M0ds", "Errors.Phone.Invalid")
}
existingPhone, err := c.phoneWriteModelByID(ctx, phone.AggregateID, phone.ResourceOwner)
existingPhone, err := c.phoneWriteModelByID(ctx, phone.AggregateID, resourceOwner)
if err != nil {
return nil, err
}

View File

@@ -261,7 +261,7 @@ func TestCommandSide_ChangeHumanPhone(t *testing.T) {
eventstore: tt.fields.eventstore,
phoneVerificationCode: tt.fields.secretGenerator,
}
got, err := r.ChangeHumanPhone(tt.args.ctx, tt.args.email)
got, err := r.ChangeHumanPhone(tt.args.ctx, tt.args.email, tt.args.resourceOwner)
if tt.res.err == nil {
assert.NoError(t, err)
}

View File

@@ -68,27 +68,6 @@ func TestCommandSide_AddHuman(t *testing.T) {
err: caos_errs.IsErrorInvalidArgument,
},
},
{
name: "user invalid, invalid argument error",
fields: fields{
eventstore: eventstoreExpect(
t,
),
},
args: args{
ctx: context.Background(),
orgID: "org1",
human: &domain.Human{
Username: "username",
Profile: &domain.Profile{
FirstName: "firstname",
},
},
},
res: res{
err: caos_errs.IsErrorInvalidArgument,
},
},
{
name: "org policy not found, precondition error",
fields: fields{
@@ -97,7 +76,6 @@ func TestCommandSide_AddHuman(t *testing.T) {
expectFilter(),
expectFilter(),
),
idGenerator: id_mock.NewIDGeneratorExpectIDs(t, "user1"),
},
args: args{
ctx: context.Background(),
@@ -117,40 +95,6 @@ func TestCommandSide_AddHuman(t *testing.T) {
err: caos_errs.IsPreconditionFailed,
},
},
{
name: "org policy check failed, precondition error",
fields: fields{
eventstore: eventstoreExpect(
t,
expectFilter(
eventFromEventPusher(
org.NewOrgIAMPolicyAddedEvent(context.Background(),
&user.NewAggregate("user1", "org1").Aggregate,
true,
),
),
),
),
idGenerator: id_mock.NewIDGeneratorExpectIDs(t, "user1"),
},
args: args{
ctx: context.Background(),
orgID: "org1",
human: &domain.Human{
Username: "email@test.ch",
Profile: &domain.Profile{
FirstName: "firstname",
LastName: "lastname",
},
Email: &domain.Email{
EmailAddress: "email@test.ch",
},
},
},
res: res{
err: caos_errs.IsPreconditionFailed,
},
},
{
name: "password policy not found, precondition error",
fields: fields{
@@ -167,7 +111,6 @@ func TestCommandSide_AddHuman(t *testing.T) {
expectFilter(),
expectFilter(),
),
idGenerator: id_mock.NewIDGeneratorExpectIDs(t, "user1"),
},
args: args{
ctx: context.Background(),
@@ -187,6 +130,92 @@ func TestCommandSide_AddHuman(t *testing.T) {
err: caos_errs.IsPreconditionFailed,
},
},
{
name: "user invalid, invalid argument error",
fields: fields{
eventstore: eventstoreExpect(
t,
expectFilter(
eventFromEventPusher(
org.NewOrgIAMPolicyAddedEvent(context.Background(),
&user.NewAggregate("user1", "org1").Aggregate,
true,
),
),
),
expectFilter(
eventFromEventPusher(
org.NewPasswordComplexityPolicyAddedEvent(context.Background(),
&user.NewAggregate("user1", "org1").Aggregate,
1,
false,
false,
false,
false,
),
),
),
),
},
args: args{
ctx: context.Background(),
orgID: "org1",
human: &domain.Human{
Username: "username",
Profile: &domain.Profile{
FirstName: "firstname",
},
},
},
res: res{
err: caos_errs.IsErrorInvalidArgument,
},
},
{
name: "org policy check failed, precondition error",
fields: fields{
eventstore: eventstoreExpect(
t,
expectFilter(
eventFromEventPusher(
org.NewOrgIAMPolicyAddedEvent(context.Background(),
&user.NewAggregate("user1", "org1").Aggregate,
true,
),
),
),
expectFilter(
eventFromEventPusher(
org.NewPasswordComplexityPolicyAddedEvent(context.Background(),
&user.NewAggregate("user1", "org1").Aggregate,
1,
false,
false,
false,
false,
),
),
),
),
},
args: args{
ctx: context.Background(),
orgID: "org1",
human: &domain.Human{
Username: "email@test.ch",
Profile: &domain.Profile{
FirstName: "firstname",
LastName: "lastname",
},
Email: &domain.Email{
EmailAddress: "email@test.ch",
},
},
},
res: res{
err: caos_errs.IsPreconditionFailed,
},
},
{
name: "add human (with initial code), ok",
fields: fields{
@@ -747,7 +776,44 @@ func TestCommandSide_RegisterHuman(t *testing.T) {
expectFilter(),
expectFilter(),
),
idGenerator: id_mock.NewIDGeneratorExpectIDs(t, "user1"),
},
args: args{
ctx: context.Background(),
orgID: "org1",
human: &domain.Human{
Username: "username",
Profile: &domain.Profile{
FirstName: "firstname",
LastName: "lastname",
},
Email: &domain.Email{
EmailAddress: "email@test.ch",
},
Password: &domain.Password{
SecretString: "password",
},
},
},
res: res{
err: caos_errs.IsPreconditionFailed,
},
},
{
name: "password policy not found, precondition error",
fields: fields{
eventstore: eventstoreExpect(
t,
expectFilter(
eventFromEventPusher(
org.NewOrgIAMPolicyAddedEvent(context.Background(),
&org.NewAggregate("org1", "org1").Aggregate,
true,
),
),
),
expectFilter(),
expectFilter(),
),
},
args: args{
ctx: context.Background(),
@@ -778,13 +844,24 @@ func TestCommandSide_RegisterHuman(t *testing.T) {
expectFilter(
eventFromEventPusher(
org.NewOrgIAMPolicyAddedEvent(context.Background(),
&user.NewAggregate("user1", "org1").Aggregate,
&org.NewAggregate("org1", "org1").Aggregate,
true,
),
),
),
expectFilter(
eventFromEventPusher(
org.NewPasswordComplexityPolicyAddedEvent(context.Background(),
&org.NewAggregate("org1", "org1").Aggregate,
1,
false,
false,
false,
false,
),
),
),
),
idGenerator: id_mock.NewIDGeneratorExpectIDs(t, "user1"),
},
args: args{
ctx: context.Background(),
@@ -807,45 +884,6 @@ func TestCommandSide_RegisterHuman(t *testing.T) {
err: caos_errs.IsPreconditionFailed,
},
},
{
name: "password policy not found, precondition error",
fields: fields{
eventstore: eventstoreExpect(
t,
expectFilter(
eventFromEventPusher(
org.NewOrgIAMPolicyAddedEvent(context.Background(),
&user.NewAggregate("user1", "org1").Aggregate,
true,
),
),
),
expectFilter(),
expectFilter(),
),
idGenerator: id_mock.NewIDGeneratorExpectIDs(t, "user1"),
},
args: args{
ctx: context.Background(),
orgID: "org1",
human: &domain.Human{
Username: "username",
Profile: &domain.Profile{
FirstName: "firstname",
LastName: "lastname",
},
Email: &domain.Email{
EmailAddress: "email@test.ch",
},
Password: &domain.Password{
SecretString: "password",
},
},
},
res: res{
err: caos_errs.IsPreconditionFailed,
},
},
{
name: "add human (with password and initial code), ok",
fields: fields{
@@ -854,7 +892,7 @@ func TestCommandSide_RegisterHuman(t *testing.T) {
expectFilter(
eventFromEventPusher(
org.NewOrgIAMPolicyAddedEvent(context.Background(),
&user.NewAggregate("user1", "org1").Aggregate,
&org.NewAggregate("org1", "org1").Aggregate,
true,
),
),
@@ -862,7 +900,7 @@ func TestCommandSide_RegisterHuman(t *testing.T) {
expectFilter(
eventFromEventPusher(
org.NewPasswordComplexityPolicyAddedEvent(context.Background(),
&user.NewAggregate("user1", "org1").Aggregate,
&org.NewAggregate("org1", "org1").Aggregate,
1,
false,
false,
@@ -941,7 +979,7 @@ func TestCommandSide_RegisterHuman(t *testing.T) {
expectFilter(
eventFromEventPusher(
org.NewOrgIAMPolicyAddedEvent(context.Background(),
&user.NewAggregate("user1", "org1").Aggregate,
&user.NewAggregate("org1", "org1").Aggregate,
true,
),
),
@@ -949,7 +987,7 @@ func TestCommandSide_RegisterHuman(t *testing.T) {
expectFilter(
eventFromEventPusher(
org.NewPasswordComplexityPolicyAddedEvent(context.Background(),
&user.NewAggregate("user1", "org1").Aggregate,
&org.NewAggregate("org1", "org1").Aggregate,
1,
false,
false,
@@ -1022,7 +1060,7 @@ func TestCommandSide_RegisterHuman(t *testing.T) {
expectFilter(
eventFromEventPusher(
org.NewOrgIAMPolicyAddedEvent(context.Background(),
&user.NewAggregate("user1", "org1").Aggregate,
&org.NewAggregate("org1", "org1").Aggregate,
true,
),
),
@@ -1030,7 +1068,7 @@ func TestCommandSide_RegisterHuman(t *testing.T) {
expectFilter(
eventFromEventPusher(
org.NewPasswordComplexityPolicyAddedEvent(context.Background(),
&user.NewAggregate("user1", "org1").Aggregate,
&org.NewAggregate("org1", "org1").Aggregate,
1,
false,
false,
@@ -1125,7 +1163,7 @@ func TestCommandSide_RegisterHuman(t *testing.T) {
expectFilter(
eventFromEventPusher(
org.NewOrgIAMPolicyAddedEvent(context.Background(),
&user.NewAggregate("user1", "org1").Aggregate,
&org.NewAggregate("org1", "org1").Aggregate,
true,
),
),
@@ -1133,7 +1171,7 @@ func TestCommandSide_RegisterHuman(t *testing.T) {
expectFilter(
eventFromEventPusher(
org.NewPasswordComplexityPolicyAddedEvent(context.Background(),
&user.NewAggregate("user1", "org1").Aggregate,
&org.NewAggregate("org1", "org1").Aggregate,
1,
false,
false,