feat: set up org (#1157)

* add setup steps

* refactoring

* omitempty

* cleanup

* begin org

* create org

* setup org

* setup org

* merge

* fixes

* fixes

* fixes
This commit is contained in:
Livio Amstutz
2021-01-08 11:33:45 +01:00
committed by GitHub
parent 26c8113930
commit ff87264f95
40 changed files with 1160 additions and 162 deletions
+2
View File
@@ -15,6 +15,7 @@ type CommandSide struct {
eventstore *eventstore.Eventstore
idGenerator id.Generator
iamID string
iamDomain string
idpConfigSecretCrypto crypto.Crypto
@@ -37,6 +38,7 @@ func StartCommandSide(config *Config) (repo *CommandSide, err error) {
eventstore: config.Eventstore,
idGenerator: id.SonyFlakeGenerator,
iamID: config.SystemDefaults.IamID,
iamDomain: config.SystemDefaults.Domain,
}
iam_repo.RegisterEventMappers(repo.eventstore)
+1
View File
@@ -6,6 +6,7 @@ import (
"github.com/caos/zitadel/internal/v2/domain"
)
//TODO: private
func (r *CommandSide) GetIAM(ctx context.Context, aggregateID string) (*domain.IAM, error) {
iamWriteModel := NewIAMWriteModel(aggregateID)
err := r.eventstore.FilterToQueryReducer(ctx, iamWriteModel)
+3 -3
View File
@@ -25,9 +25,9 @@ func writeModelToIAM(wm *IAMWriteModel) *domain.IAM {
}
}
func writeModelToMember(writeModel *IAMMemberWriteModel) *domain.IAMMember {
return &domain.IAMMember{
ObjectRoot: writeModelToObjectRoot(writeModel.MemberWriteModel.WriteModel),
func memberWriteModelToMember(writeModel *MemberWriteModel) *domain.Member {
return &domain.Member{
ObjectRoot: writeModelToObjectRoot(writeModel.WriteModel),
Roles: writeModel.Roles,
UserID: writeModel.UserID,
}
+4 -4
View File
@@ -11,7 +11,7 @@ import (
iam_repo "github.com/caos/zitadel/internal/v2/repository/iam"
)
func (r *CommandSide) AddIAMMember(ctx context.Context, member *domain.IAMMember) (*domain.IAMMember, error) {
func (r *CommandSide) AddIAMMember(ctx context.Context, member *domain.Member) (*domain.Member, error) {
//TODO: check if roles valid
if !member.IsValid() {
@@ -35,11 +35,11 @@ func (r *CommandSide) AddIAMMember(ctx context.Context, member *domain.IAMMember
return nil, err
}
return writeModelToMember(addedMember), nil
return memberWriteModelToMember(&addedMember.MemberWriteModel), nil
}
//ChangeIAMMember updates an existing member
func (r *CommandSide) ChangeIAMMember(ctx context.Context, member *domain.IAMMember) (*domain.IAMMember, error) {
func (r *CommandSide) ChangeIAMMember(ctx context.Context, member *domain.Member) (*domain.Member, error) {
//TODO: check if roles valid
if !member.IsValid() {
@@ -67,7 +67,7 @@ func (r *CommandSide) ChangeIAMMember(ctx context.Context, member *domain.IAMMem
return nil, err
}
return writeModelToMember(existingMember), nil
return memberWriteModelToMember(&existingMember.MemberWriteModel), nil
}
func (r *CommandSide) RemoveIAMMember(ctx context.Context, userID string) error {
+10 -11
View File
@@ -8,17 +8,6 @@ import (
iam_repo "github.com/caos/zitadel/internal/v2/repository/iam"
)
func (r *CommandSide) GetDefaultOrgIAMPolicy(ctx context.Context) (*domain.OrgIAMPolicy, error) {
policyWriteModel := NewIAMOrgIAMPolicyWriteModel(r.iamID)
err := r.eventstore.FilterToQueryReducer(ctx, policyWriteModel)
if err != nil {
return nil, err
}
policy := writeModelToOrgIAMPolicy(policyWriteModel)
policy.Default = true
return policy, nil
}
func (r *CommandSide) AddDefaultOrgIAMPolicy(ctx context.Context, policy *domain.OrgIAMPolicy) (*domain.OrgIAMPolicy, error) {
policy.AggregateID = r.iamID
addedPolicy := NewIAMOrgIAMPolicyWriteModel(policy.AggregateID)
@@ -75,6 +64,16 @@ func (r *CommandSide) ChangeDefaultOrgIAMPolicy(ctx context.Context, policy *dom
return writeModelToOrgIAMPolicy(existingPolicy), nil
}
func (r *CommandSide) getDefaultOrgIAMPolicy(ctx context.Context) (*domain.OrgIAMPolicy, error) {
policyWriteModel, err := r.defaultOrgIAMPolicyWriteModelByID(ctx, r.iamID)
if err != nil {
return nil, err
}
policy := writeModelToOrgIAMPolicy(policyWriteModel)
policy.Default = true
return policy, nil
}
func (r *CommandSide) defaultOrgIAMPolicyWriteModelByID(ctx context.Context, iamID string) (policy *IAMOrgIAMPolicyWriteModel, err error) {
ctx, span := tracing.NewSpan(ctx)
defer func() { span.EndWithError(err) }()
+72
View File
@@ -0,0 +1,72 @@
package command
import (
"context"
caos_errs "github.com/caos/zitadel/internal/errors"
"github.com/caos/zitadel/internal/v2/domain"
"github.com/caos/zitadel/internal/v2/repository/org"
"github.com/caos/zitadel/internal/v2/repository/user"
)
func (r *CommandSide) SetUpOrg(ctx context.Context, organisation *domain.Org, admin *domain.User) error {
orgAgg, userAgg, orgMemberAgg, err := r.setUpOrg(ctx, organisation, admin)
if err != nil {
return err
}
_, err = r.eventstore.PushAggregates(ctx, orgAgg, userAgg, orgMemberAgg)
return err
}
func (r *CommandSide) setUpOrg(ctx context.Context, organisation *domain.Org, admin *domain.User) (*org.Aggregate, *user.Aggregate, *org.Aggregate, error) {
orgAgg, _, err := r.addOrg(ctx, organisation)
if err != nil {
return nil, nil, nil, err
}
userAgg, _, err := r.addHuman(ctx, orgAgg.ID(), admin.UserName, admin.Human)
if err != nil {
return nil, nil, nil, err
}
addedMember := NewOrgMemberWriteModel(orgAgg.ID(), userAgg.ID())
orgMemberAgg := OrgAggregateFromWriteModel(&addedMember.WriteModel)
err = r.addOrgMember(ctx, orgMemberAgg, addedMember, domain.NewMember(orgMemberAgg.ID(), userAgg.ID(), domain.OrgOwnerRole)) //TODO: correct?
if err != nil {
return nil, nil, nil, err
}
return orgAgg, userAgg, orgMemberAgg, nil
}
func (r *CommandSide) addOrg(ctx context.Context, organisation *domain.Org) (_ *org.Aggregate, _ *OrgWriteModel, err error) {
if organisation == nil || !organisation.IsValid() {
return nil, nil, caos_errs.ThrowInvalidArgument(nil, "COMM-deLSk", "Errors.Org.Invalid")
}
organisation.AggregateID, err = r.idGenerator.Next()
if err != nil {
return nil, nil, caos_errs.ThrowInternal(err, "COMMA-OwciI", "Errors.Internal")
}
organisation.AddIAMDomain(r.iamDomain)
addedOrg := NewOrgWriteModel(organisation.AggregateID)
orgAgg := OrgAggregateFromWriteModel(&addedOrg.WriteModel)
//TODO: uniqueness org name
orgAgg.PushEvents(org.NewOrgAddedEvent(ctx, organisation.Name))
for _, orgDomain := range organisation.Domains {
if err := r.addOrgDomain(ctx, orgAgg, NewOrgDomainWriteModel(orgAgg.ID(), orgDomain.Domain), orgDomain); err != nil {
return nil, nil, err
}
}
return orgAgg, addedOrg, nil
}
func (r *CommandSide) getOrgWriteModelByID(ctx context.Context, orgID string) (*OrgWriteModel, error) {
orgWriteModel := NewOrgWriteModel(orgID)
err := r.eventstore.FilterToQueryReducer(ctx, orgWriteModel)
if err != nil {
return nil, err
}
return orgWriteModel, nil
}
+19
View File
@@ -4,6 +4,14 @@ import (
"github.com/caos/zitadel/internal/v2/domain"
)
func orgWriteModelToOrg(wm *OrgWriteModel) *domain.Org {
return &domain.Org{
ObjectRoot: writeModelToObjectRoot(wm.WriteModel),
Name: wm.Name,
State: wm.State,
}
}
func orgWriteModelToOrgIAMPolicy(wm *ORGOrgIAMPolicyWriteModel) *domain.OrgIAMPolicy {
return &domain.OrgIAMPolicy{
ObjectRoot: writeModelToObjectRoot(wm.PolicyOrgIAMWriteModel.WriteModel),
@@ -21,3 +29,14 @@ func orgWriteModelToPasswordComplexityPolicy(wm *OrgPasswordComplexityPolicyWrit
HasSymbol: wm.HasSymbol,
}
}
func orgDomainWriteModelToOrgDomain(wm *OrgDomainWriteModel) *domain.OrgDomain {
return &domain.OrgDomain{
ObjectRoot: writeModelToObjectRoot(wm.WriteModel),
Domain: wm.Domain,
Primary: wm.Primary,
Verified: wm.Verified,
ValidationType: wm.ValidationType,
ValidationCode: wm.ValidationCode,
}
}
+43
View File
@@ -0,0 +1,43 @@
package command
import (
"context"
caos_errs "github.com/caos/zitadel/internal/errors"
"github.com/caos/zitadel/internal/v2/domain"
"github.com/caos/zitadel/internal/v2/repository/org"
)
func (r *CommandSide) AddOrgDomain(ctx context.Context, orgDomain *domain.OrgDomain) (*domain.OrgDomain, error) {
domainWriteModel := NewOrgDomainWriteModel(orgDomain.AggregateID, orgDomain.Domain)
orgAgg := OrgAggregateFromWriteModel(&domainWriteModel.WriteModel)
err := r.addOrgDomain(ctx, orgAgg, domainWriteModel, orgDomain)
if err != nil {
return nil, err
}
err = r.eventstore.PushAggregate(ctx, domainWriteModel, orgAgg)
if err != nil {
return nil, err
}
return orgDomainWriteModelToOrgDomain(domainWriteModel), nil
}
func (r *CommandSide) addOrgDomain(ctx context.Context, orgAgg *org.Aggregate, addedDomain *OrgDomainWriteModel, orgDomain *domain.OrgDomain) error {
err := r.eventstore.FilterToQueryReducer(ctx, addedDomain)
if err != nil {
return err
}
if addedDomain.State == domain.OrgDomainStateActive {
return caos_errs.ThrowAlreadyExists(nil, "COMMA-Bd2jj", "Errors.Org.Domain.AlreadyExists")
}
orgAgg.PushEvents(org.NewDomainAddedEvent(ctx, orgDomain.Domain))
if orgDomain.Verified {
//TODO: uniqueness verified domain
//TODO: users with verified domain -> domain claimed
orgAgg.PushEvents(org.NewDomainVerifiedEvent(ctx, orgDomain.Domain))
}
if orgDomain.Primary {
orgAgg.PushEvents(org.NewDomainPrimarySetEvent(ctx, orgDomain.Domain))
}
return nil
}
+90
View File
@@ -0,0 +1,90 @@
package command
import (
"github.com/caos/zitadel/internal/crypto"
"github.com/caos/zitadel/internal/eventstore/v2"
"github.com/caos/zitadel/internal/v2/domain"
"github.com/caos/zitadel/internal/v2/repository/org"
)
type OrgDomainWriteModel struct {
eventstore.WriteModel
Domain string
ValidationType domain.OrgDomainValidationType
ValidationCode *crypto.CryptoValue
Primary bool
Verified bool
State domain.OrgDomainState
}
func NewOrgDomainWriteModel(orgID string, domain string) *OrgDomainWriteModel {
return &OrgDomainWriteModel{
WriteModel: eventstore.WriteModel{
AggregateID: orgID,
},
Domain: domain,
}
}
func (wm *OrgDomainWriteModel) AppendEvents(events ...eventstore.EventReader) {
for _, event := range events {
switch e := event.(type) {
case *org.DomainAddedEvent:
if e.Domain != wm.Domain {
continue
}
wm.WriteModel.AppendEvents(e)
case *org.DomainVerificationAddedEvent:
if e.Domain != wm.Domain {
continue
}
wm.WriteModel.AppendEvents(e)
case *org.DomainVerificationFailedEvent:
if e.Domain != wm.Domain {
continue
}
wm.WriteModel.AppendEvents(e)
case *org.DomainVerifiedEvent:
if e.Domain != wm.Domain {
continue
}
wm.WriteModel.AppendEvents(e)
case *org.DomainPrimarySetEvent:
wm.WriteModel.AppendEvents(e)
case *org.DomainRemovedEvent:
if e.Domain != wm.Domain {
continue
}
wm.WriteModel.AppendEvents(e)
}
}
}
func (wm *OrgDomainWriteModel) Reduce() error {
for _, event := range wm.Events {
switch e := event.(type) {
case *org.DomainAddedEvent:
wm.Domain = e.Domain
wm.State = domain.OrgDomainStateActive
case *org.DomainVerificationAddedEvent:
wm.ValidationType = e.ValidationType
wm.ValidationCode = e.ValidationCode
case *org.DomainVerificationFailedEvent:
//TODO: not handled in v1
case *org.DomainVerifiedEvent:
wm.Verified = true
case *org.DomainPrimarySetEvent:
wm.Primary = e.Domain == wm.Domain
case *org.DomainRemovedEvent:
wm.State = domain.OrgDomainStateRemoved
}
}
return nil
}
func (wm *OrgDomainWriteModel) Query() *eventstore.SearchQueryBuilder {
return eventstore.NewSearchQueryBuilder(eventstore.ColumnsEvent, org.AggregateType).
AggregateIDs(wm.AggregateID)
}
+112
View File
@@ -0,0 +1,112 @@
package command
import (
"context"
"reflect"
"github.com/caos/zitadel/internal/errors"
caos_errs "github.com/caos/zitadel/internal/errors"
"github.com/caos/zitadel/internal/telemetry/tracing"
"github.com/caos/zitadel/internal/v2/domain"
"github.com/caos/zitadel/internal/v2/repository/org"
)
func (r *CommandSide) AddOrgMember(ctx context.Context, member *domain.Member) (*domain.Member, error) {
addedMember := NewOrgMemberWriteModel(member.AggregateID, member.UserID)
orgAgg := OrgAggregateFromWriteModel(&addedMember.WriteModel)
err := r.addOrgMember(ctx, orgAgg, addedMember, member)
if err != nil {
return nil, err
}
err = r.eventstore.PushAggregate(ctx, addedMember, orgAgg)
if err != nil {
return nil, err
}
return memberWriteModelToMember(&addedMember.MemberWriteModel), nil
}
func (r *CommandSide) addOrgMember(ctx context.Context, orgAgg *org.Aggregate, addedMember *OrgMemberWriteModel, member *domain.Member) error {
//TODO: check if roles valid
if !member.IsValid() {
return caos_errs.ThrowPreconditionFailed(nil, "Org-W8m4l", "Errors.Org.MemberInvalid")
}
err := r.eventstore.FilterToQueryReducer(ctx, addedMember)
if err != nil {
return err
}
if addedMember.State == domain.MemberStateActive {
return errors.ThrowAlreadyExists(nil, "Org-PtXi1", "Errors.Org.Member.AlreadyExists")
}
orgAgg.PushEvents(org.NewMemberAddedEvent(ctx, member.UserID, member.Roles...))
return nil
}
//ChangeOrgMember updates an existing member
func (r *CommandSide) ChangeOrgMember(ctx context.Context, member *domain.Member) (*domain.Member, error) {
//TODO: check if roles valid
if !member.IsValid() {
return nil, caos_errs.ThrowPreconditionFailed(nil, "Org-LiaZi", "Errors.Org.MemberInvalid")
}
existingMember, err := r.orgMemberWriteModelByID(ctx, member.AggregateID, member.UserID)
if err != nil {
return nil, err
}
if reflect.DeepEqual(existingMember.Roles, member.Roles) {
return nil, caos_errs.ThrowPreconditionFailed(nil, "Org-LiaZi", "Errors.Org.Member.RolesNotChanged")
}
orgAgg := OrgAggregateFromWriteModel(&existingMember.MemberWriteModel.WriteModel)
orgAgg.PushEvents(org.NewMemberChangedEvent(ctx, member.UserID, member.Roles...))
events, err := r.eventstore.PushAggregates(ctx, orgAgg)
if err != nil {
return nil, err
}
existingMember.AppendEvents(events...)
if err = existingMember.Reduce(); err != nil {
return nil, err
}
return memberWriteModelToMember(&existingMember.MemberWriteModel), nil
}
func (r *CommandSide) RemoveOrgMember(ctx context.Context, orgID, userID string) error {
m, err := r.orgMemberWriteModelByID(ctx, orgID, userID)
if err != nil && !errors.IsNotFound(err) {
return err
}
if errors.IsNotFound(err) {
return nil
}
orgAgg := OrgAggregateFromWriteModel(&m.MemberWriteModel.WriteModel)
orgAgg.PushEvents(org.NewMemberRemovedEvent(ctx, userID))
return r.eventstore.PushAggregate(ctx, m, orgAgg)
}
func (r *CommandSide) orgMemberWriteModelByID(ctx context.Context, orgID, userID string) (member *OrgMemberWriteModel, err error) {
ctx, span := tracing.NewSpan(ctx)
defer func() { span.EndWithError(err) }()
writeModel := NewOrgMemberWriteModel(orgID, userID)
err = r.eventstore.FilterToQueryReducer(ctx, writeModel)
if err != nil {
return nil, err
}
if writeModel.State == domain.MemberStateUnspecified || writeModel.State == domain.MemberStateRemoved {
return nil, errors.ThrowNotFound(nil, "Org-D8JxR", "Errors.NotFound")
}
return writeModel, nil
}
+47
View File
@@ -1,5 +1,52 @@
package command
import (
"github.com/caos/zitadel/internal/eventstore/v2"
"github.com/caos/zitadel/internal/v2/repository/org"
)
type OrgMemberWriteModel struct {
MemberWriteModel
}
func NewOrgMemberWriteModel(orgID, userID string) *OrgMemberWriteModel {
return &OrgMemberWriteModel{
MemberWriteModel{
WriteModel: eventstore.WriteModel{
AggregateID: orgID,
},
UserID: userID,
},
}
}
func (wm *OrgMemberWriteModel) AppendEvents(events ...eventstore.EventReader) {
for _, event := range events {
switch e := event.(type) {
case *org.MemberAddedEvent:
if e.UserID != wm.MemberWriteModel.UserID {
continue
}
wm.MemberWriteModel.AppendEvents(&e.MemberAddedEvent)
case *org.MemberChangedEvent:
if e.UserID != wm.MemberWriteModel.UserID {
continue
}
wm.MemberWriteModel.AppendEvents(&e.MemberChangedEvent)
case *org.MemberRemovedEvent:
if e.UserID != wm.MemberWriteModel.UserID {
continue
}
wm.MemberWriteModel.AppendEvents(&e.MemberRemovedEvent)
}
}
}
func (wm *OrgMemberWriteModel) Reduce() error {
return wm.MemberWriteModel.Reduce()
}
func (wm *OrgMemberWriteModel) Query() *eventstore.SearchQueryBuilder {
return eventstore.NewSearchQueryBuilder(eventstore.ColumnsEvent, org.AggregateType).
AggregateIDs(wm.MemberWriteModel.AggregateID)
}
+47 -1
View File
@@ -2,10 +2,56 @@ package command
import (
"github.com/caos/zitadel/internal/eventstore/v2"
"github.com/caos/zitadel/internal/v2/domain"
"github.com/caos/zitadel/internal/v2/repository/iam"
"github.com/caos/zitadel/internal/v2/repository/org"
)
func ORGAggregateFromWriteModel(wm *eventstore.WriteModel) *org.Aggregate {
type OrgWriteModel struct {
eventstore.WriteModel
Name string
State domain.OrgState
}
func NewOrgWriteModel(orgID string) *OrgWriteModel {
return &OrgWriteModel{
WriteModel: eventstore.WriteModel{
AggregateID: orgID,
},
}
}
func (wm *OrgWriteModel) AppendEvents(events ...eventstore.EventReader) {
wm.WriteModel.AppendEvents(events...)
for _, event := range events {
switch e := event.(type) {
case *org.OrgAddedEvent,
*iam.LabelPolicyChangedEvent:
wm.WriteModel.AppendEvents(e)
}
}
}
func (wm *OrgWriteModel) Reduce() error {
for _, event := range wm.Events {
switch e := event.(type) {
case *org.OrgAddedEvent:
wm.Name = e.Name
wm.State = domain.OrgStateActive
case *org.OrgChangedEvent:
wm.Name = e.Name
}
}
return nil
}
func (wm *OrgWriteModel) Query() *eventstore.SearchQueryBuilder {
return eventstore.NewSearchQueryBuilder(eventstore.ColumnsEvent, org.AggregateType).
AggregateIDs(wm.AggregateID)
}
func OrgAggregateFromWriteModel(wm *eventstore.WriteModel) *org.Aggregate {
return &org.Aggregate{
Aggregate: *eventstore.AggregateFromWriteModel(wm, org.AggregateType, org.AggregateVersion),
}
+28 -17
View File
@@ -5,32 +5,20 @@ import (
caos_errs "github.com/caos/zitadel/internal/errors"
"github.com/caos/zitadel/internal/telemetry/tracing"
"github.com/caos/zitadel/internal/v2/domain"
iam_repo "github.com/caos/zitadel/internal/v2/repository/iam"
"github.com/caos/zitadel/internal/v2/repository/org"
)
func (r *CommandSide) GetOrgIAMPolicy(ctx context.Context, orgID string) (*domain.OrgIAMPolicy, error) {
policy := NewORGOrgIAMPolicyWriteModel(orgID)
err := r.eventstore.FilterToQueryReducer(ctx, policy)
if err != nil {
return nil, err
}
if policy.State == domain.PolicyStateActive {
return orgWriteModelToOrgIAMPolicy(policy), nil
}
return r.GetDefaultOrgIAMPolicy(ctx)
}
func (r *CommandSide) AddOrgIAMPolicy(ctx context.Context, policy *domain.OrgIAMPolicy) (*domain.OrgIAMPolicy, error) {
addedPolicy := NewORGOrgIAMPolicyWriteModel(policy.AggregateID)
err := r.eventstore.FilterToQueryReducer(ctx, addedPolicy)
orgAgg := OrgAggregateFromWriteModel(&addedPolicy.PolicyOrgIAMWriteModel.WriteModel)
err := r.addOrgIAMPolicy(ctx, orgAgg, addedPolicy, policy)
if err != nil {
return nil, err
}
if addedPolicy.State == domain.PolicyStateActive {
return nil, caos_errs.ThrowAlreadyExists(nil, "ORG-5M0ds", "Errors.Org.OrgIAMPolicy.AlreadyExists")
}
orgAgg := ORGAggregateFromWriteModel(&addedPolicy.PolicyOrgIAMWriteModel.WriteModel)
orgAgg.PushEvents(iam_repo.NewOrgIAMPolicyAddedEvent(ctx, policy.UserLoginMustBeDomain))
orgAgg.PushEvents(org.NewOrgIAMPolicyAddedEvent(ctx, policy.UserLoginMustBeDomain))
err = r.eventstore.PushAggregate(ctx, addedPolicy, orgAgg)
if err != nil {
@@ -40,6 +28,18 @@ func (r *CommandSide) AddOrgIAMPolicy(ctx context.Context, policy *domain.OrgIAM
return orgWriteModelToOrgIAMPolicy(addedPolicy), nil
}
func (r *CommandSide) addOrgIAMPolicy(ctx context.Context, orgAgg *org.Aggregate, addedPolicy *ORGOrgIAMPolicyWriteModel, policy *domain.OrgIAMPolicy) error {
err := r.eventstore.FilterToQueryReducer(ctx, addedPolicy)
if err != nil {
return err
}
if addedPolicy.State == domain.PolicyStateActive {
return caos_errs.ThrowAlreadyExists(nil, "ORG-5M0ds", "Errors.Org.OrgIAMPolicy.AlreadyExists")
}
orgAgg.PushEvents(org.NewOrgIAMPolicyAddedEvent(ctx, policy.UserLoginMustBeDomain))
return nil
}
func (r *CommandSide) ChangeOrgIAMPolicy(ctx context.Context, policy *domain.OrgIAMPolicy) (*domain.OrgIAMPolicy, error) {
existingPolicy, err := r.orgIAMPolicyWriteModelByID(ctx, policy.AggregateID)
if err != nil {
@@ -54,7 +54,7 @@ func (r *CommandSide) ChangeOrgIAMPolicy(ctx context.Context, policy *domain.Org
return nil, caos_errs.ThrowPreconditionFailed(nil, "ORG-3M9ds", "Errors.Org.LabelPolicy.NotChanged")
}
orgAgg := ORGAggregateFromWriteModel(&existingPolicy.PolicyOrgIAMWriteModel.WriteModel)
orgAgg := OrgAggregateFromWriteModel(&existingPolicy.PolicyOrgIAMWriteModel.WriteModel)
orgAgg.PushEvents(changedEvent)
err = r.eventstore.PushAggregate(ctx, existingPolicy, orgAgg)
@@ -65,6 +65,17 @@ func (r *CommandSide) ChangeOrgIAMPolicy(ctx context.Context, policy *domain.Org
return orgWriteModelToOrgIAMPolicy(existingPolicy), nil
}
func (r *CommandSide) getOrgIAMPolicy(ctx context.Context, orgID string) (*domain.OrgIAMPolicy, error) {
policy, err := r.orgIAMPolicyWriteModelByID(ctx, orgID)
if err != nil {
return nil, err
}
if policy.State == domain.PolicyStateActive {
return orgWriteModelToOrgIAMPolicy(policy), nil
}
return r.getDefaultOrgIAMPolicy(ctx)
}
func (r *CommandSide) orgIAMPolicyWriteModelByID(ctx context.Context, orgID string) (policy *ORGOrgIAMPolicyWriteModel, err error) {
ctx, span := tracing.NewSpan(ctx)
defer func() { span.EndWithError(err) }()
+47 -12
View File
@@ -4,6 +4,7 @@ import (
"context"
caos_errs "github.com/caos/zitadel/internal/errors"
"github.com/caos/zitadel/internal/eventstore/v2"
"github.com/caos/zitadel/internal/v2/domain"
iam_repo "github.com/caos/zitadel/internal/v2/repository/iam"
)
@@ -48,8 +49,7 @@ type Org struct {
Name string
Domain string
OrgIamPolicy bool
Users []User
Owners []string
Owner User
Projects []Project
}
@@ -84,25 +84,60 @@ func (r *CommandSide) SetupStep1(ctx context.Context, iamID string, step1 *Step1
return err
}
//create orgs
//create projects
//create applications
aggregates := make([]eventstore.Aggregater, 0)
for _, organisation := range step1.Orgs {
orgAgg, userAgg, orgMemberAgg, err := r.setUpOrg(ctx,
&domain.Org{
Name: organisation.Name,
Domains: []*domain.OrgDomain{{Domain: organisation.Domain}},
},
&domain.User{
UserName: organisation.Owner.UserName,
Human: &domain.Human{
Profile: &domain.Profile{
FirstName: organisation.Owner.FirstName,
LastName: organisation.Owner.LastName,
},
Password: &domain.Password{
SecretString: organisation.Owner.Password,
},
Email: &domain.Email{
EmailAddress: organisation.Owner.Email,
IsEmailVerified: true,
},
},
})
if err != nil {
return err
}
if organisation.OrgIamPolicy {
err = r.addOrgIAMPolicy(ctx, orgAgg, NewORGOrgIAMPolicyWriteModel(orgAgg.ID()), &domain.OrgIAMPolicy{UserLoginMustBeDomain: false})
if err != nil {
return err
}
}
aggregates = append(aggregates, orgAgg, userAgg, orgMemberAgg)
//projects
//create applications
}
//set iam owners
//set global org
//set iam project id
/*aggregates:
iam:
default login policy
iam owner
org:
default
caos
zitadel
iam:
default login policy
iam owner
org:
default
caos
zitadel
*/
iamAgg.PushEvents(iam_repo.NewSetupStepDoneEvent(ctx, domain.Step1))
_, err = r.eventstore.PushAggregates(ctx, iamAgg)
_, err = r.eventstore.PushAggregates(ctx, append(aggregates, iamAgg)...)
if err != nil {
return caos_errs.ThrowPreconditionFailed(nil, "EVENT-Gr2hh", "Setup Step1 failed")
}
+1 -1
View File
@@ -59,7 +59,7 @@ func (r *CommandSide) ChangeUsername(ctx context.Context, orgID, userID, userNam
return caos_errs.ThrowPreconditionFailed(nil, "COMMAND-2M9fs", "Errors.User.UsernameNotChanged")
}
orgIAMPolicy, err := r.GetOrgIAMPolicy(ctx, orgID)
orgIAMPolicy, err := r.getOrgIAMPolicy(ctx, orgID)
if err != nil {
return err
}
+25 -16
View File
@@ -2,37 +2,51 @@ package command
import (
"context"
caos_errs "github.com/caos/zitadel/internal/errors"
"github.com/caos/zitadel/internal/v2/domain"
"github.com/caos/zitadel/internal/v2/repository/user"
)
func (r *CommandSide) AddHuman(ctx context.Context, orgID, username string, human *domain.Human) (*domain.Human, error) {
userAgg, addedHuman, err := r.addHuman(ctx, orgID, username, human)
if err != nil {
return nil, err
}
err = r.eventstore.PushAggregate(ctx, addedHuman, userAgg)
if err != nil {
return nil, err
}
return writeModelToHuman(addedHuman), nil
}
func (r *CommandSide) addHuman(ctx context.Context, orgID, username string, human *domain.Human) (*user.Aggregate, *HumanWriteModel, error) {
if !human.IsValid() {
return nil, caos_errs.ThrowInvalidArgument(nil, "COMMAND-4M90d", "Errors.User.Invalid")
return nil, nil, caos_errs.ThrowInvalidArgument(nil, "COMMAND-4M90d", "Errors.User.Invalid")
}
userID, err := r.idGenerator.Next()
if err != nil {
return nil, err
return nil, nil, err
}
human.AggregateID = userID
orgIAMPolicy, err := r.GetOrgIAMPolicy(ctx, orgID)
orgIAMPolicy, err := r.getOrgIAMPolicy(ctx, orgID)
if err != nil {
return nil, err
return nil, nil, err
}
pwPolicy, err := r.GetOrgPasswordComplexityPolicy(ctx, orgID)
if err != nil {
return nil, err
return nil, nil, err
}
addedHuman := NewHumanWriteModel(human.AggregateID)
//TODO: Check Unique Username
if err := human.CheckOrgIAMPolicy(username, orgIAMPolicy); err != nil {
return nil, err
return nil, nil, err
}
human.SetNamesAsDisplayname()
if err := human.HashPasswordIfExisting(pwPolicy, r.userPasswordAlg, true); err != nil {
return nil, err
return nil, nil, err
}
userAgg := UserAggregateFromWriteModel(&addedHuman.WriteModel)
@@ -66,7 +80,7 @@ func (r *CommandSide) AddHuman(ctx context.Context, orgID, username string, huma
if human.IsInitialState() {
initCode, err := domain.NewInitUserCode(r.initializeUserCode)
if err != nil {
return nil, err
return nil, nil, err
}
user.NewHumanInitialCodeAddedEvent(ctx, initCode.Code, initCode.Expiry)
}
@@ -76,19 +90,14 @@ func (r *CommandSide) AddHuman(ctx context.Context, orgID, username string, huma
if human.Phone != nil && human.PhoneNumber != "" && !human.IsPhoneVerified {
phoneCode, err := domain.NewPhoneCode(r.phoneVerificationCode)
if err != nil {
return nil, err
return nil, nil, err
}
user.NewHumanPhoneCodeAddedEvent(ctx, phoneCode.Code, phoneCode.Expiry)
} else if human.Phone != nil && human.PhoneNumber != "" && human.IsPhoneVerified {
userAgg.PushEvents(user.NewHumanPhoneVerifiedEvent(ctx))
}
err = r.eventstore.PushAggregate(ctx, addedHuman, userAgg)
if err != nil {
return nil, err
}
return writeModelToHuman(addedHuman), nil
return userAgg, addedHuman, nil
}
func (r *CommandSide) RegisterHuman(ctx context.Context, orgID, username string, human *domain.Human, externalIDP *domain.ExternalIDP) (*domain.Human, error) {
@@ -100,7 +109,7 @@ func (r *CommandSide) RegisterHuman(ctx context.Context, orgID, username string,
return nil, err
}
human.AggregateID = userID
orgIAMPolicy, err := r.GetOrgIAMPolicy(ctx, orgID)
orgIAMPolicy, err := r.getOrgIAMPolicy(ctx, orgID)
if err != nil {
return nil, err
}
+1 -1
View File
@@ -18,7 +18,7 @@ func (r *CommandSide) AddMachine(ctx context.Context, orgID, username string, ma
}
//TODO: Check Unique username
machine.AggregateID = userID
orgIAMPolicy, err := r.GetOrgIAMPolicy(ctx, orgID)
orgIAMPolicy, err := r.getOrgIAMPolicy(ctx, orgID)
if err != nil {
return nil, err
}