mirror of
https://github.com/zitadel/zitadel.git
synced 2025-08-11 15:49:35 +00:00
fix(org): adding unique constrants to not allow an org to be added twice with same id
This commit is contained in:
@@ -47,14 +47,17 @@ func TestMain(m *testing.M) {
|
||||
func TestServer_CreateOrganization(t *testing.T) {
|
||||
idpResp := Instance.AddGenericOAuthProvider(CTX, Instance.DefaultOrg.Id)
|
||||
|
||||
tests := []struct {
|
||||
name string
|
||||
ctx context.Context
|
||||
req *v2beta_org.CreateOrganizationRequest
|
||||
id string
|
||||
want *v2beta_org.CreateOrganizationResponse
|
||||
wantErr bool
|
||||
}{
|
||||
type test struct {
|
||||
name string
|
||||
ctx context.Context
|
||||
req *v2beta_org.CreateOrganizationRequest
|
||||
id string
|
||||
testfunc func(ctx context.Context, t *testing.T)
|
||||
want *v2beta_org.CreateOrganizationResponse
|
||||
wantErr bool
|
||||
}
|
||||
|
||||
tests := []test{
|
||||
{
|
||||
name: "missing permission",
|
||||
ctx: Instance.WithAuthorization(CTX, integration.UserTypeOrgOwner),
|
||||
@@ -73,6 +76,25 @@ func TestServer_CreateOrganization(t *testing.T) {
|
||||
},
|
||||
wantErr: true,
|
||||
},
|
||||
func() test {
|
||||
orgName := gofakeit.Name()
|
||||
return test{
|
||||
name: "adding org with same name twice",
|
||||
ctx: CTX,
|
||||
req: &v2beta_org.CreateOrganizationRequest{
|
||||
Name: orgName,
|
||||
Admins: nil,
|
||||
},
|
||||
testfunc: func(ctx context.Context, t *testing.T) {
|
||||
// create org initally
|
||||
_, err := Client.CreateOrganization(ctx, &v2beta_org.CreateOrganizationRequest{
|
||||
Name: orgName,
|
||||
})
|
||||
require.NoError(t, err)
|
||||
},
|
||||
wantErr: true,
|
||||
}
|
||||
}(),
|
||||
{
|
||||
name: "invalid admin type",
|
||||
ctx: CTX,
|
||||
@@ -210,9 +232,33 @@ func TestServer_CreateOrganization(t *testing.T) {
|
||||
},
|
||||
want: &v2beta_org.CreateOrganizationResponse{},
|
||||
},
|
||||
func() test {
|
||||
orgID := gofakeit.Name()
|
||||
return test{
|
||||
name: "adding org with same ID twice",
|
||||
ctx: CTX,
|
||||
req: &v2beta_org.CreateOrganizationRequest{
|
||||
Name: orgID,
|
||||
Admins: nil,
|
||||
},
|
||||
testfunc: func(ctx context.Context, t *testing.T) {
|
||||
// create org initally
|
||||
_, err := Client.CreateOrganization(ctx, &v2beta_org.CreateOrganizationRequest{
|
||||
Name: gofakeit.AppName(),
|
||||
Id: &orgID,
|
||||
})
|
||||
require.NoError(t, err)
|
||||
},
|
||||
wantErr: true,
|
||||
}
|
||||
}(),
|
||||
}
|
||||
for _, tt := range tests {
|
||||
t.Run(tt.name, func(t *testing.T) {
|
||||
if tt.testfunc != nil {
|
||||
tt.testfunc(tt.ctx, t)
|
||||
}
|
||||
|
||||
got, err := Client.CreateOrganization(tt.ctx, tt.req)
|
||||
if tt.wantErr {
|
||||
require.Error(t, err)
|
||||
|
@@ -54,16 +54,16 @@ func (mr *MockMessageMockRecorder) GetContent() *gomock.Call {
|
||||
return mr.mock.ctrl.RecordCallWithMethodType(mr.mock, "GetContent", reflect.TypeOf((*MockMessage)(nil).GetContent))
|
||||
}
|
||||
|
||||
// GetTriggeringEvent mocks base method.
|
||||
func (m *MockMessage) GetTriggeringEvent() eventstore.Event {
|
||||
// GetTriggeringEventType mocks base method.
|
||||
func (m *MockMessage) GetTriggeringEventType() eventstore.EventType {
|
||||
m.ctrl.T.Helper()
|
||||
ret := m.ctrl.Call(m, "GetTriggeringEvent")
|
||||
ret0, _ := ret[0].(eventstore.Event)
|
||||
ret := m.ctrl.Call(m, "GetTriggeringEventType")
|
||||
ret0, _ := ret[0].(eventstore.EventType)
|
||||
return ret0
|
||||
}
|
||||
|
||||
// GetTriggeringEvent indicates an expected call of GetTriggeringEvent.
|
||||
func (mr *MockMessageMockRecorder) GetTriggeringEvent() *gomock.Call {
|
||||
// GetTriggeringEventType indicates an expected call of GetTriggeringEventType.
|
||||
func (mr *MockMessageMockRecorder) GetTriggeringEventType() *gomock.Call {
|
||||
mr.mock.ctrl.T.Helper()
|
||||
return mr.mock.ctrl.RecordCallWithMethodType(mr.mock, "GetTriggeringEvent", reflect.TypeOf((*MockMessage)(nil).GetTriggeringEvent))
|
||||
return mr.mock.ctrl.RecordCallWithMethodType(mr.mock, "GetTriggeringEventType", reflect.TypeOf((*MockMessage)(nil).GetTriggeringEventType))
|
||||
}
|
||||
|
@@ -23,6 +23,19 @@ const (
|
||||
OrgStateSearchField = "state"
|
||||
)
|
||||
|
||||
func NewAddOrgIDUniqueConstraint(orgID string) *eventstore.UniqueConstraint {
|
||||
return eventstore.NewAddEventUniqueConstraint(
|
||||
uniqueOrgname,
|
||||
orgID,
|
||||
"Errors.Org.AlreadyExists")
|
||||
}
|
||||
|
||||
func NewRemoveOrgIDUniqueConstraint(orgID string) *eventstore.UniqueConstraint {
|
||||
return eventstore.NewRemoveUniqueConstraint(
|
||||
uniqueOrgname,
|
||||
orgID)
|
||||
}
|
||||
|
||||
func NewAddOrgNameUniqueConstraint(orgName string) *eventstore.UniqueConstraint {
|
||||
return eventstore.NewAddEventUniqueConstraint(
|
||||
uniqueOrgname,
|
||||
@@ -39,6 +52,7 @@ func NewRemoveOrgNameUniqueConstraint(orgName string) *eventstore.UniqueConstrai
|
||||
type OrgAddedEvent struct {
|
||||
eventstore.BaseEvent `json:"-"`
|
||||
|
||||
ID string `json:"id,omitempty"`
|
||||
Name string `json:"name,omitempty"`
|
||||
}
|
||||
|
||||
@@ -47,7 +61,7 @@ func (e *OrgAddedEvent) Payload() interface{} {
|
||||
}
|
||||
|
||||
func (e *OrgAddedEvent) UniqueConstraints() []*eventstore.UniqueConstraint {
|
||||
return []*eventstore.UniqueConstraint{NewAddOrgNameUniqueConstraint(e.Name)}
|
||||
return []*eventstore.UniqueConstraint{NewAddOrgIDUniqueConstraint(e.ID), NewAddOrgNameUniqueConstraint(e.Name)}
|
||||
}
|
||||
|
||||
func (e *OrgAddedEvent) Fields() []*eventstore.FieldOperation {
|
||||
@@ -94,6 +108,7 @@ func NewOrgAddedEvent(ctx context.Context, aggregate *eventstore.Aggregate, name
|
||||
aggregate,
|
||||
OrgAddedEventType,
|
||||
),
|
||||
ID: aggregate.ID,
|
||||
Name: name,
|
||||
}
|
||||
}
|
||||
@@ -276,6 +291,7 @@ func OrgReactivatedEventMapper(event eventstore.Event) (eventstore.Event, error)
|
||||
|
||||
type OrgRemovedEvent struct {
|
||||
eventstore.BaseEvent `json:"-"`
|
||||
id string
|
||||
name string
|
||||
usernames []string
|
||||
loginMustBeDomain bool
|
||||
@@ -290,6 +306,7 @@ func (e *OrgRemovedEvent) Payload() interface{} {
|
||||
|
||||
func (e *OrgRemovedEvent) UniqueConstraints() []*eventstore.UniqueConstraint {
|
||||
constraints := []*eventstore.UniqueConstraint{
|
||||
NewRemoveOrgIDUniqueConstraint(e.id),
|
||||
NewRemoveOrgNameUniqueConstraint(e.name),
|
||||
}
|
||||
for _, name := range e.usernames {
|
||||
@@ -321,6 +338,7 @@ func NewOrgRemovedEvent(ctx context.Context, aggregate *eventstore.Aggregate, na
|
||||
aggregate,
|
||||
OrgRemovedEventType,
|
||||
),
|
||||
id: aggregate.ID,
|
||||
name: name,
|
||||
usernames: usernames,
|
||||
domains: domains,
|
||||
|
@@ -195,7 +195,7 @@ Errors:
|
||||
AlreadyExists: Instance already exists
|
||||
NotChanged: Instance not changed
|
||||
Org:
|
||||
AlreadyExists: Organisation's name already taken
|
||||
AlreadyExists: Organisation's name or id already taken
|
||||
Invalid: Organisation is invalid
|
||||
AlreadyDeactivated: Organisation is already deactivated
|
||||
AlreadyActive: Organisation is already active
|
||||
|
@@ -177,7 +177,7 @@ service OrganizationService {
|
||||
responses: {
|
||||
key: "409"
|
||||
value: {
|
||||
description: "Organisation's name already taken";
|
||||
description: "Organisation's name or id already taken";
|
||||
}
|
||||
};
|
||||
};
|
||||
|
Reference in New Issue
Block a user