feat: setup (#1166)

* add setup steps

* refactoring

* omitempty

* cleanup

* begin org

* create org

* setup org

* setup org

* merge

* fixes

* fixes

* fixes

* add project

* add oidc application

* fix app creation

* add resourceOwner to writemodels

* resource owner

* cleanup

* global org, iam project and iam member in setup

* logs

* logs

* logs

* cleanup

* Update internal/v2/command/project.go

Co-authored-by: Fabi <38692350+fgerschwiler@users.noreply.github.com>

* check project state

Co-authored-by: Fabi <38692350+fgerschwiler@users.noreply.github.com>
This commit is contained in:
Livio Amstutz 2021-01-12 12:59:51 +01:00 committed by GitHub
parent ff87264f95
commit e5731b0d3b
No known key found for this signature in database
GPG Key ID: 4AEE18F83AFDEB23
97 changed files with 1664 additions and 698 deletions

View File

@ -67,8 +67,6 @@ SetUp:
ApplicationType: 'USER_AGENT'
AuthMethodType: 'NONE'
DevMode: $ZITADEL_CONSOLE_DEV_MODE
Owners:
- 'zitadel-admin@caos.ch'
Step2:
DefaultPasswordComplexityPolicy:
MinLength: 8

View File

@ -23,6 +23,7 @@ type CtxData struct {
ProjectID string
AgentID string
PreferredLanguage string
ResourceOwner string
}
func (ctxData CtxData) IsZero() bool {
@ -47,7 +48,7 @@ func VerifyTokenAndCreateCtxData(ctx context.Context, token, orgID string, t *To
}
}
userID, clientID, agentID, prefLang, err := verifyAccessToken(ctx, token, t, method)
userID, clientID, agentID, prefLang, resourceOwner, err := verifyAccessToken(ctx, token, t, method)
if err != nil {
return CtxData{}, err
}
@ -64,6 +65,7 @@ func VerifyTokenAndCreateCtxData(ctx context.Context, token, orgID string, t *To
ProjectID: projectID,
AgentID: agentID,
PreferredLanguage: prefLang,
ResourceOwner: resourceOwner,
}, nil
}

View File

@ -15,8 +15,8 @@ type testVerifier struct {
grant *Grant
}
func (v *testVerifier) VerifyAccessToken(ctx context.Context, token, clientID string) (string, string, string, error) {
return "userID", "agentID", "de", nil
func (v *testVerifier) VerifyAccessToken(ctx context.Context, token, clientID string) (string, string, string, string, error) {
return "userID", "agentID", "de", "orgID", nil
}
func (v *testVerifier) ResolveGrants(ctx context.Context) (*Grant, error) {

View File

@ -20,7 +20,7 @@ type TokenVerifier struct {
}
type authZRepo interface {
VerifyAccessToken(ctx context.Context, token, clientID string) (userID, agentID, prefLang string, err error)
VerifyAccessToken(ctx context.Context, token, clientID string) (userID, agentID, prefLang, resourceOwner string, err error)
VerifierClientID(ctx context.Context, name string) (clientID string, err error)
ResolveGrants(ctx context.Context) (grant *Grant, err error)
ProjectIDAndOriginsByClientID(ctx context.Context, clientID string) (projectID string, origins []string, err error)
@ -31,13 +31,13 @@ func Start(authZRepo authZRepo) (v *TokenVerifier) {
return &TokenVerifier{authZRepo: authZRepo}
}
func (v *TokenVerifier) VerifyAccessToken(ctx context.Context, token string, method string) (userID, clientID, agentID, prefLang string, err error) {
func (v *TokenVerifier) VerifyAccessToken(ctx context.Context, token string, method string) (userID, clientID, agentID, prefLang, resourceOwner string, err error) {
clientID, err = v.clientIDFromMethod(ctx, method)
if err != nil {
return "", "", "", "", err
return "", "", "", "", "", err
}
userID, agentID, prefLang, err = v.authZRepo.VerifyAccessToken(ctx, token, clientID)
return userID, clientID, agentID, prefLang, err
userID, agentID, prefLang, resourceOwner, err = v.authZRepo.VerifyAccessToken(ctx, token, clientID)
return userID, clientID, agentID, prefLang, resourceOwner, err
}
type client struct {
@ -111,13 +111,13 @@ func (v *TokenVerifier) CheckAuthMethod(method string) (Option, bool) {
return authOpt, ok
}
func verifyAccessToken(ctx context.Context, token string, t *TokenVerifier, method string) (userID, clientID, agentID, prefLang string, err error) {
func verifyAccessToken(ctx context.Context, token string, t *TokenVerifier, method string) (userID, clientID, agentID, prefLan, resourceOwner string, err error) {
ctx, span := tracing.NewSpan(ctx)
defer func() { span.EndWithError(err) }()
parts := strings.Split(token, BearerPrefix)
if len(parts) != 2 {
return "", "", "", "", caos_errs.ThrowUnauthenticated(nil, "AUTH-7fs1e", "invalid auth header")
return "", "", "", "", "", caos_errs.ThrowUnauthenticated(nil, "AUTH-7fs1e", "invalid auth header")
}
return t.VerifyAccessToken(ctx, parts[1], method)
}

View File

@ -58,7 +58,7 @@ func Test_VerifyAccessToken(t *testing.T) {
}
for _, tt := range tests {
t.Run(tt.name, func(t *testing.T) {
_, _, _, _, err := verifyAccessToken(tt.args.ctx, tt.args.token, tt.args.verifier, tt.args.method)
_, _, _, _, _, err := verifyAccessToken(tt.args.ctx, tt.args.token, tt.args.verifier, tt.args.method)
if tt.wantErr && err == nil {
t.Errorf("got wrong result, should get err: actual: %v ", err)
}

View File

@ -2,9 +2,10 @@ package auth
import (
"context"
"github.com/caos/zitadel/internal/api/authz"
"github.com/golang/protobuf/ptypes/empty"
"github.com/caos/zitadel/internal/api/authz"
"github.com/caos/zitadel/pkg/grpc/auth"
)
@ -71,7 +72,7 @@ func (s *Server) UpdateMyUserProfile(ctx context.Context, request *auth.UpdateUs
func (s *Server) ChangeMyUserName(ctx context.Context, request *auth.ChangeUserNameRequest) (*empty.Empty, error) {
ctxData := authz.GetCtxData(ctx)
return &empty.Empty{}, s.command.ChangeUsername(ctx, ctxData.OrgID, ctxData.UserID, request.UserName)
return &empty.Empty{}, s.command.ChangeUsername(ctx, ctxData.ResourceOwner, ctxData.UserID, request.UserName)
}
func (s *Server) ChangeMyUserEmail(ctx context.Context, request *auth.UpdateUserEmailRequest) (*auth.UserEmail, error) {

View File

@ -3,7 +3,6 @@ package auth
import (
"context"
"encoding/json"
"github.com/caos/zitadel/internal/v2/domain"
"github.com/caos/logging"
"github.com/golang/protobuf/ptypes"
@ -15,6 +14,7 @@ import (
"github.com/caos/zitadel/internal/eventstore/models"
"github.com/caos/zitadel/internal/telemetry/tracing"
usr_model "github.com/caos/zitadel/internal/user/model"
"github.com/caos/zitadel/internal/v2/domain"
"github.com/caos/zitadel/pkg/grpc/auth"
"github.com/caos/zitadel/pkg/grpc/message"
)
@ -103,7 +103,7 @@ func updateProfileToDomain(ctx context.Context, u *auth.UpdateUserProfileRequest
logging.Log("GRPC-lk73L").OnError(err).WithField("traceID", tracing.TraceIDFromCtx(ctx)).Debug("language malformed")
return &domain.Profile{
ObjectRoot: models.ObjectRoot{AggregateID: authz.GetCtxData(ctx).UserID},
ObjectRoot: ctxToObjectRoot(ctx),
FirstName: u.FirstName,
LastName: u.LastName,
NickName: u.NickName,
@ -148,7 +148,7 @@ func emailViewFromModel(email *usr_model.Email) *auth.UserEmailView {
func updateEmailToDomain(ctx context.Context, e *auth.UpdateUserEmailRequest) *domain.Email {
return &domain.Email{
ObjectRoot: models.ObjectRoot{AggregateID: authz.GetCtxData(ctx).UserID},
ObjectRoot: ctxToObjectRoot(ctx),
EmailAddress: e.Email,
}
}
@ -189,7 +189,7 @@ func phoneViewFromModel(phone *usr_model.Phone) *auth.UserPhoneView {
func updatePhoneToDomain(ctx context.Context, e *auth.UpdateUserPhoneRequest) *domain.Phone {
return &domain.Phone{
ObjectRoot: models.ObjectRoot{AggregateID: authz.GetCtxData(ctx).UserID},
ObjectRoot: ctxToObjectRoot(ctx),
PhoneNumber: e.Phone,
}
}
@ -236,7 +236,7 @@ func addressViewFromModel(address *usr_model.Address) *auth.UserAddressView {
func updateAddressToModel(ctx context.Context, address *auth.UpdateUserAddressRequest) *usr_model.Address {
return &usr_model.Address{
ObjectRoot: models.ObjectRoot{AggregateID: authz.GetCtxData(ctx).UserID},
ObjectRoot: ctxToObjectRoot(ctx),
Country: address.Country,
StreetAddress: address.StreetAddress,
Region: address.Region,
@ -254,7 +254,7 @@ func externalIDPSearchRequestToModel(request *auth.ExternalIDPSearchRequest) *us
func externalIDPRemoveToModel(ctx context.Context, idp *auth.ExternalIDPRemoveRequest) *usr_model.ExternalIDP {
return &usr_model.ExternalIDP{
ObjectRoot: models.ObjectRoot{AggregateID: authz.GetCtxData(ctx).UserID},
ObjectRoot: ctxToObjectRoot(ctx),
IDPConfigID: idp.IdpConfigId,
UserID: idp.ExternalUserId,
}
@ -454,3 +454,11 @@ func webAuthNTokenFromModel(token *usr_model.WebAuthNToken) *auth.WebAuthNToken
State: mfaStateFromModel(token.State),
}
}
func ctxToObjectRoot(ctx context.Context) models.ObjectRoot {
ctxData := authz.GetCtxData(ctx)
return models.ObjectRoot{
AggregateID: ctxData.UserID,
ResourceOwner: ctxData.ResourceOwner,
}
}

View File

@ -60,7 +60,7 @@ func (s *Server) CreateUser(ctx context.Context, in *management.CreateUserReques
}
func (s *Server) DeactivateUser(ctx context.Context, in *management.UserID) (*management.UserResponse, error) {
user, err := s.command.DeactivateUser(ctx, in.Id)
user, err := s.command.DeactivateUser(ctx, in.Id, authz.GetCtxData(ctx).OrgID)
if err != nil {
return nil, err
}
@ -68,7 +68,7 @@ func (s *Server) DeactivateUser(ctx context.Context, in *management.UserID) (*ma
}
func (s *Server) ReactivateUser(ctx context.Context, in *management.UserID) (*management.UserResponse, error) {
user, err := s.command.ReactivateUser(ctx, in.Id)
user, err := s.command.ReactivateUser(ctx, in.Id, authz.GetCtxData(ctx).OrgID)
if err != nil {
return nil, err
}
@ -76,7 +76,7 @@ func (s *Server) ReactivateUser(ctx context.Context, in *management.UserID) (*ma
}
func (s *Server) LockUser(ctx context.Context, in *management.UserID) (*management.UserResponse, error) {
user, err := s.command.LockUser(ctx, in.Id)
user, err := s.command.LockUser(ctx, in.Id, authz.GetCtxData(ctx).OrgID)
if err != nil {
return nil, err
}
@ -84,7 +84,7 @@ func (s *Server) LockUser(ctx context.Context, in *management.UserID) (*manageme
}
func (s *Server) UnlockUser(ctx context.Context, in *management.UserID) (*management.UserResponse, error) {
user, err := s.command.UnlockUser(ctx, in.Id)
user, err := s.command.UnlockUser(ctx, in.Id, authz.GetCtxData(ctx).OrgID)
if err != nil {
return nil, err
}
@ -92,12 +92,12 @@ func (s *Server) UnlockUser(ctx context.Context, in *management.UserID) (*manage
}
func (s *Server) DeleteUser(ctx context.Context, in *management.UserID) (*empty.Empty, error) {
err := s.command.RemoveUser(ctx, in.Id)
err := s.command.RemoveUser(ctx, in.Id, authz.GetCtxData(ctx).OrgID)
return &empty.Empty{}, err
}
func (s *Server) UpdateUserMachine(ctx context.Context, in *management.UpdateMachineRequest) (*management.MachineResponse, error) {
machine, err := s.command.ChangeMachine(ctx, updateMachineToDomain(in))
machine, err := s.command.ChangeMachine(ctx, updateMachineToDomain(authz.GetCtxData(ctx), in))
if err != nil {
return nil, err
}
@ -141,7 +141,7 @@ func (s *Server) ChangeUserEmail(ctx context.Context, request *management.Update
}
func (s *Server) ResendEmailVerificationMail(ctx context.Context, in *management.UserID) (*empty.Empty, error) {
err := s.command.CreateHumanEmailVerificationCode(ctx, in.Id)
err := s.command.CreateHumanEmailVerificationCode(ctx, in.Id, authz.GetCtxData(ctx).OrgID)
return &empty.Empty{}, err
}
@ -162,12 +162,12 @@ func (s *Server) ChangeUserPhone(ctx context.Context, request *management.Update
}
func (s *Server) RemoveUserPhone(ctx context.Context, userID *management.UserID) (*empty.Empty, error) {
err := s.command.RemoveHumanPhone(ctx, userID.Id)
err := s.command.RemoveHumanPhone(ctx, userID.Id, authz.GetCtxData(ctx).OrgID)
return &empty.Empty{}, err
}
func (s *Server) ResendPhoneVerificationCode(ctx context.Context, in *management.UserID) (*empty.Empty, error) {
err := s.command.CreateHumanPhoneVerificationCode(ctx, in.Id)
err := s.command.CreateHumanPhoneVerificationCode(ctx, in.Id, authz.GetCtxData(ctx).OrgID)
return &empty.Empty{}, err
}
@ -180,7 +180,7 @@ func (s *Server) GetUserAddress(ctx context.Context, in *management.UserID) (*ma
}
func (s *Server) UpdateUserAddress(ctx context.Context, request *management.UpdateUserAddressRequest) (*management.UserAddress, error) {
address, err := s.command.ChangeHumanAddress(ctx, updateAddressToDomain(request))
address, err := s.command.ChangeHumanAddress(ctx, updateAddressToDomain(authz.GetCtxData(ctx), request))
if err != nil {
return nil, err
}
@ -188,7 +188,7 @@ func (s *Server) UpdateUserAddress(ctx context.Context, request *management.Upda
}
func (s *Server) SendSetPasswordNotification(ctx context.Context, request *management.SetPasswordNotificationRequest) (*empty.Empty, error) {
err := s.command.RequestSetPassword(ctx, request.Id, notifyTypeToDomain(request.Type))
err := s.command.RequestSetPassword(ctx, request.Id, authz.GetCtxData(ctx).OrgID, notifyTypeToDomain(request.Type))
return &empty.Empty{}, err
}
@ -197,7 +197,7 @@ func (s *Server) SetInitialPassword(ctx context.Context, request *management.Pas
}
func (s *Server) ResendInitialMail(ctx context.Context, request *management.InitialMailRequest) (*empty.Empty, error) {
return &empty.Empty{}, s.command.ResendInitialMail(ctx, request.Id, request.Email)
return &empty.Empty{}, s.command.ResendInitialMail(ctx, request.Id, request.Email, authz.GetCtxData(ctx).OrgID)
}
func (s *Server) SearchUserExternalIDPs(ctx context.Context, request *management.ExternalIDPSearchRequest) (*management.ExternalIDPSearchResponse, error) {
@ -209,7 +209,7 @@ func (s *Server) SearchUserExternalIDPs(ctx context.Context, request *management
}
func (s *Server) RemoveExternalIDP(ctx context.Context, request *management.ExternalIDPRemoveRequest) (*empty.Empty, error) {
return &empty.Empty{}, s.command.RemoveHumanExternalIDP(ctx, externalIDPRemoveToDomain(request))
return &empty.Empty{}, s.command.RemoveHumanExternalIDP(ctx, externalIDPRemoveToDomain(authz.GetCtxData(ctx), request))
}
func (s *Server) GetUserMfas(ctx context.Context, userID *management.UserID) (*management.UserMultiFactors, error) {
@ -221,11 +221,11 @@ func (s *Server) GetUserMfas(ctx context.Context, userID *management.UserID) (*m
}
func (s *Server) RemoveMfaOTP(ctx context.Context, userID *management.UserID) (*empty.Empty, error) {
return &empty.Empty{}, s.command.RemoveHumanOTP(ctx, userID.Id)
return &empty.Empty{}, s.command.RemoveHumanOTP(ctx, userID.Id, authz.GetCtxData(ctx).OrgID)
}
func (s *Server) RemoveMfaU2F(ctx context.Context, webAuthNTokenID *management.WebAuthNTokenID) (*empty.Empty, error) {
return &empty.Empty{}, s.command.RemoveHumanU2F(ctx, webAuthNTokenID.UserId, webAuthNTokenID.Id)
return &empty.Empty{}, s.command.RemoveHumanU2F(ctx, webAuthNTokenID.UserId, webAuthNTokenID.Id, authz.GetCtxData(ctx).OrgID)
}
func (s *Server) GetPasswordless(ctx context.Context, userID *management.UserID) (_ *management.WebAuthNTokens, err error) {
@ -237,7 +237,7 @@ func (s *Server) GetPasswordless(ctx context.Context, userID *management.UserID)
}
func (s *Server) RemovePasswordless(ctx context.Context, id *management.WebAuthNTokenID) (*empty.Empty, error) {
return &empty.Empty{}, s.command.RemoveHumanPasswordless(ctx, id.UserId, id.Id)
return &empty.Empty{}, s.command.RemoveHumanPasswordless(ctx, id.UserId, id.Id, authz.GetCtxData(ctx).OrgID)
}
func (s *Server) SearchUserMemberships(ctx context.Context, in *management.UserMembershipSearchRequest) (*management.UserMembershipSearchResponse, error) {

View File

@ -4,12 +4,14 @@ import (
"encoding/json"
"github.com/caos/logging"
"github.com/caos/zitadel/internal/v2/domain"
"github.com/golang/protobuf/ptypes"
"golang.org/x/text/language"
"google.golang.org/protobuf/encoding/protojson"
"google.golang.org/protobuf/types/known/structpb"
"github.com/caos/zitadel/internal/api/authz"
"github.com/caos/zitadel/internal/v2/domain"
"github.com/caos/zitadel/internal/eventstore/models"
"github.com/caos/zitadel/internal/model"
usr_model "github.com/caos/zitadel/internal/user/model"
@ -76,9 +78,12 @@ func externalIDPSearchRequestToModel(request *management.ExternalIDPSearchReques
}
}
func externalIDPRemoveToDomain(idp *management.ExternalIDPRemoveRequest) *domain.ExternalIDP {
func externalIDPRemoveToDomain(ctxData authz.CtxData, idp *management.ExternalIDPRemoveRequest) *domain.ExternalIDP {
return &domain.ExternalIDP{
ObjectRoot: models.ObjectRoot{AggregateID: idp.UserId},
ObjectRoot: models.ObjectRoot{
AggregateID: idp.UserId,
ResourceOwner: ctxData.ResourceOwner,
},
IDPConfigID: idp.IdpConfigId,
ExternalUserID: idp.ExternalUserId,
}
@ -387,9 +392,12 @@ func addressViewFromModel(address *usr_model.Address) *management.UserAddressVie
}
}
func updateAddressToDomain(address *management.UpdateUserAddressRequest) *domain.Address {
func updateAddressToDomain(ctxData authz.CtxData, address *management.UpdateUserAddressRequest) *domain.Address {
return &domain.Address{
ObjectRoot: models.ObjectRoot{AggregateID: address.Id},
ObjectRoot: models.ObjectRoot{
AggregateID: address.Id,
ResourceOwner: ctxData.OrgID,
},
Country: address.Country,
StreetAddress: address.StreetAddress,
Region: address.Region,

View File

@ -2,15 +2,18 @@ package management
import (
"encoding/json"
"github.com/caos/zitadel/internal/v2/domain"
"time"
"github.com/caos/zitadel/internal/api/authz"
"github.com/caos/zitadel/internal/v2/domain"
"github.com/caos/logging"
"github.com/golang/protobuf/ptypes"
"github.com/caos/zitadel/internal/eventstore/models"
"github.com/caos/zitadel/internal/model"
usr_model "github.com/caos/zitadel/internal/user/model"
"github.com/caos/zitadel/pkg/grpc/management"
"github.com/golang/protobuf/ptypes"
)
func machineCreateToDomain(machine *management.CreateMachineRequest) *domain.Machine {
@ -20,9 +23,12 @@ func machineCreateToDomain(machine *management.CreateMachineRequest) *domain.Mac
}
}
func updateMachineToDomain(machine *management.UpdateMachineRequest) *domain.Machine {
func updateMachineToDomain(ctxData authz.CtxData, machine *management.UpdateMachineRequest) *domain.Machine {
return &domain.Machine{
ObjectRoot: models.ObjectRoot{AggregateID: machine.Id},
ObjectRoot: models.ObjectRoot{
AggregateID: machine.Id,
ResourceOwner: ctxData.ResourceOwner,
},
Name: machine.Name,
Description: machine.Description,
}

View File

@ -21,8 +21,8 @@ var (
type verifierMock struct{}
func (v *verifierMock) VerifyAccessToken(ctx context.Context, token, clientID string) (string, string, string, error) {
return "", "", "", nil
func (v *verifierMock) VerifyAccessToken(ctx context.Context, token, clientID string) (string, string, string, string, error) {
return "", "", "", "", nil
}
func (v *verifierMock) ResolveGrants(ctx context.Context) (*authz.Grant, error) {
return nil, nil

View File

@ -6,9 +6,6 @@ import (
"time"
"github.com/caos/logging"
usr_model "github.com/caos/zitadel/internal/user/model"
usr_event "github.com/caos/zitadel/internal/user/repository/eventsourcing"
"github.com/caos/zitadel/internal/user/repository/view/model"
"github.com/caos/zitadel/internal/authz/repository/eventsourcing/view"
"github.com/caos/zitadel/internal/crypto"
@ -16,6 +13,9 @@ import (
iam_event "github.com/caos/zitadel/internal/iam/repository/eventsourcing"
proj_event "github.com/caos/zitadel/internal/project/repository/eventsourcing"
"github.com/caos/zitadel/internal/telemetry/tracing"
usr_model "github.com/caos/zitadel/internal/user/model"
usr_event "github.com/caos/zitadel/internal/user/repository/eventsourcing"
"github.com/caos/zitadel/internal/user/repository/view/model"
)
type TokenVerifierRepo struct {
@ -60,37 +60,37 @@ func (repo *TokenVerifierRepo) TokenByID(ctx context.Context, tokenID, userID st
return model.TokenViewToModel(token), nil
}
func (repo *TokenVerifierRepo) VerifyAccessToken(ctx context.Context, tokenString, clientID string) (userID string, agentID string, prefLang string, err error) {
func (repo *TokenVerifierRepo) VerifyAccessToken(ctx context.Context, tokenString, clientID string) (userID string, agentID string, prefLang, resourceOwner string, err error) {
ctx, span := tracing.NewSpan(ctx)
defer func() { span.EndWithError(err) }()
//TODO: use real key
tokenIDSubject, err := crypto.DecryptAESString(tokenString, string(repo.TokenVerificationKey[:32]))
if err != nil {
return "", "", "", caos_errs.ThrowUnauthenticated(nil, "APP-8EF0zZ", "invalid token")
return "", "", "", "", caos_errs.ThrowUnauthenticated(nil, "APP-8EF0zZ", "invalid token")
}
splittedToken := strings.Split(tokenIDSubject, ":")
if len(splittedToken) != 2 {
return "", "", "", caos_errs.ThrowUnauthenticated(nil, "APP-GDg3a", "invalid token")
return "", "", "", "", caos_errs.ThrowUnauthenticated(nil, "APP-GDg3a", "invalid token")
}
token, err := repo.TokenByID(ctx, splittedToken[0], splittedToken[1])
if err != nil {
return "", "", "", caos_errs.ThrowUnauthenticated(err, "APP-BxUSiL", "invalid token")
return "", "", "", "", caos_errs.ThrowUnauthenticated(err, "APP-BxUSiL", "invalid token")
}
if !token.Expiration.After(time.Now().UTC()) {
return "", "", "", caos_errs.ThrowUnauthenticated(err, "APP-k9KS0", "invalid token")
return "", "", "", "", caos_errs.ThrowUnauthenticated(err, "APP-k9KS0", "invalid token")
}
projectID, _, err := repo.ProjectIDAndOriginsByClientID(ctx, clientID)
if err != nil {
return "", "", "", caos_errs.ThrowUnauthenticated(err, "APP-5M9so", "invalid token")
return "", "", "", "", caos_errs.ThrowUnauthenticated(err, "APP-5M9so", "invalid token")
}
for _, aud := range token.Audience {
if clientID == aud || projectID == aud {
return token.UserID, token.UserAgentID, token.PreferredLanguage, nil
return token.UserID, token.UserAgentID, token.PreferredLanguage, token.ResourceOwner, nil
}
}
return "", "", "", caos_errs.ThrowUnauthenticated(nil, "APP-Zxfako", "invalid audience")
return "", "", "", "", caos_errs.ThrowUnauthenticated(nil, "APP-Zxfako", "invalid audience")
}
func (repo *TokenVerifierRepo) ProjectIDAndOriginsByClientID(ctx context.Context, clientID string) (projectID string, origins []string, err error) {

View File

@ -78,7 +78,7 @@ func IAMSetGlobalOrgAggregate(aggCreator *es_models.AggregateCreator, iam *model
func IAMSetIamProjectAggregate(aggCreator *es_models.AggregateCreator, iam *model.IAM, projectID string) func(ctx context.Context) (*es_models.Aggregate, error) {
return func(ctx context.Context) (*es_models.Aggregate, error) {
if projectID == "" {
return nil, errors.ThrowPreconditionFailed(nil, "EVENT-sjuw3", "Errors.IAM.IamProjectIDMisisng")
return nil, errors.ThrowPreconditionFailed(nil, "EVENT-sjuw3", "Errors.IAM.IAMProjectIDMissing")
}
agg, err := IAMAggregate(ctx, aggCreator, iam)
if err != nil {

View File

@ -12,26 +12,14 @@ import (
)
const (
OrgOwnerRole = "ORG_OWNER"
SetupUser = "SETUP"
OIDCResponseTypeCode = "CODE"
OIDCResponseTypeIDToken = "ID_TOKEN"
OIDCResponseTypeToken = "ID_TOKEN TOKEN"
OIDCGrantTypeAuthorizationCode = "AUTHORIZATION_CODE"
OIDCGrantTypeImplicit = "IMPLICIT"
OIDCGrantTypeRefreshToken = "REFRESH_TOKEN"
OIDCApplicationTypeNative = "NATIVE"
OIDCApplicationTypeUserAgent = "USER_AGENT"
OIDCApplicationTypeWeb = "WEB"
OIDCAuthMethodTypeNone = "NONE"
OIDCAuthMethodTypeBasic = "BASIC"
OIDCAuthMethodTypePost = "POST"
OrgOwnerRole = "ORG_OWNER"
SetupUser = "SETUP"
)
func Execute(ctx context.Context, setUpConfig IAMSetUp, iamID string, commands *command.CommandSide) error {
logging.Log("SETUP-JAK2q").Info("starting setup")
iam, err := commands.GetIAM(ctx, iamID)
iam, err := commands.GetIAM(ctx)
if err != nil && !caos_errs.IsNotFound(err) {
return err
}

View File

@ -1,291 +0,0 @@
package setup
// TODO: implement
//import (
// "context"
//
// "github.com/caos/logging"
//
// iam_model "github.com/caos/zitadel/internal/iam/model"
// "github.com/caos/zitadel/internal/v2/command"
//)
//
//type Step1 struct {
// //GlobalOrg string
// //IAMProject string
// //DefaultLoginPolicy LoginPolicy
// //Orgs []Org
// //Owners []string
// command.Step1
//
// //setup *Setup
// //createdUsers map[string]*usr_model.User
// //createdOrgs map[string]*org_model.Org
// //createdProjects map[string]*proj_model.Project
// //pwComplexityPolicy *iam_model.PasswordComplexityPolicyView
//}
//
//func (s *Step1) isNil() bool {
// return s == nil
//}
//
//func (s *Step1) step() iam_model.Step {
// return iam_model.Step1
//}
//
////func (s *Step1) init(setup *Setup) {
//// s.setup = setup
//// s.createdUsers = make(map[string]*usr_model.User)
//// s.createdOrgs = make(map[string]*org_model.Org)
//// s.createdProjects = make(map[string]*proj_model.Project)
////}
//
//func (s *Step1) execute(ctx context.Context, iamID string, commands command.CommandSide) error {
// err := commands.SetupStep1(ctx, iamID, s.Step1)
// if err != nil {
// logging.Log("SETUP-de342").WithField("step", s.step()).WithError(err).Error("unable to finish setup")
// return err
// }
// return nil
//}
//
//func (step *Step1) loginPolicy(ctx context.Context, policy LoginPolicy) error {
// logging.Log("SETUP-4djul").Info("setting up login policy")
// loginPolicy := &iam_model.LoginPolicy{
// ObjectRoot: models.ObjectRoot{
// AggregateID: step.setup.iamID,
// },
// AllowRegister: policy.AllowRegister,
// AllowUsernamePassword: policy.AllowUsernamePassword,
// AllowExternalIdp: policy.AllowExternalIdp,
// }
// _, err := step.setup.Commands.AddDefaultLoginPolicy(ctx, loginPolicy)
// return err
//}
//
//func (step *Step1) orgs(ctx context.Context, orgs []Org) error {
// logging.Log("SETUP-dsTh3").Info("setting up orgs")
// for _, iamOrg := range orgs {
// org, err := step.org(ctx, iamOrg)
// if err != nil {
// logging.LogWithFields("SETUP-IlLif", "Org", iamOrg.Name).WithError(err).Error("unable to create org")
// return err
// }
// step.createdOrgs[iamOrg.Name] = org
// logging.LogWithFields("SETUP-HR2gh", "name", org.Name, "ID", org.AggregateID).Info("created organisation")
//
// var policy *iam_model.OrgIAMPolicyView
// if iamOrg.OrgIamPolicy {
// policy, err = step.iamorgpolicy(ctx, org)
// if err != nil {
// logging.LogWithFields("SETUP-IlLif", "Org IAM Policy", iamOrg.Name).WithError(err).Error("unable to create iam org policy")
// return err
// }
// } else {
// policy = &iam_model.OrgIAMPolicyView{
// UserLoginMustBeDomain: true,
// }
// }
//
// ctx = setSetUpContextData(ctx, org.AggregateID)
// err = step.users(ctx, iamOrg.Users, policy)
// if err != nil {
// logging.LogWithFields("SETUP-8zfwz", "Org", iamOrg.Name).WithError(err).Error("unable to set up org users")
// return err
// }
//
// err = step.orgOwners(ctx, org, iamOrg.Owners)
// if err != nil {
// logging.LogWithFields("SETUP-0874m", "Org", iamOrg.Name).WithError(err).Error("unable to set up org owners")
// return err
// }
//
// err = step.projects(ctx, iamOrg.Projects, step.createdUsers[iamOrg.Owners[0]].AggregateID)
// if err != nil {
// logging.LogWithFields("SETUP-wUzqY", "Org", iamOrg.Name).WithError(err).Error("unable to set up org projects")
// return err
// }
// }
// logging.Log("SETUP-dgjT4").Info("orgs set up")
// return nil
//}
//
//func (step *Step1) org(ctx context.Context, org Org) (*org_model.Org, error) {
// ctx = setSetUpContextData(ctx, "")
// createOrg := &org_model.Org{
// Name: org.Name,
// Domains: []*org_model.OrgDomain{{Domain: org.Domain}},
// }
// return step.setup.OrgEvents.CreateOrg(ctx, createOrg, nil)
//}
//
//func (step *Step1) iamorgpolicy(ctx context.Context, org *org_model.Org) (*iam_model.OrgIAMPolicyView, error) {
// ctx = setSetUpContextData(ctx, org.AggregateID)
// policy := &iam_model.OrgIAMPolicy{
// ObjectRoot: models.ObjectRoot{AggregateID: org.AggregateID},
// UserLoginMustBeDomain: false,
// }
// createdpolicy, err := step.setup.OrgEvents.AddOrgIAMPolicy(ctx, policy)
// if err != nil {
// return nil, err
// }
// return &iam_model.OrgIAMPolicyView{
// AggregateID: org.AggregateID,
// UserLoginMustBeDomain: createdpolicy.UserLoginMustBeDomain,
// }, nil
//}
//
//func (step *Step1) iamOwners(ctx context.Context, owners []string) error {
// logging.Log("SETUP-dtxfj").Info("setting iam owners")
// for _, iamOwner := range owners {
// user, ok := step.createdUsers[iamOwner]
// if !ok {
// logging.LogWithFields("SETUP-8siew", "Owner", iamOwner).Error("unable to add user to iam members")
// return caos_errs.ThrowPreconditionFailedf(nil, "SETUP-su6L3", "unable to add user to iam members")
// }
// _, err := step.setup.Commands.AddIAMMember(ctx, &iam_model.IAMMember{ObjectRoot: models.ObjectRoot{AggregateID: step.setup.iamID}, UserID: user.AggregateID, Roles: []string{"IAM_OWNER"}})
// if err != nil {
// logging.Log("SETUP-LM7rI").WithError(err).Error("unable to add iam administrator to iam members as owner")
// return err
// }
// }
// logging.Log("SETUP-fg5aq").Info("iam owners set")
// return nil
//}
//
//func (step *Step1) setGlobalOrg(ctx context.Context, globalOrgName string) error {
// logging.Log("SETUP-dsj75").Info("setting global org")
// globalOrg, ok := step.createdOrgs[globalOrgName]
// if !ok {
// logging.LogWithFields("SETUP-FBhs9", "GlobalOrg", globalOrgName).Error("global org not created")
// return caos_errs.ThrowPreconditionFailedf(nil, "SETUP-4GwU7", "global org not created: %v", globalOrgName)
// }
//
// if _, err := step.setup.IamEvents.SetGlobalOrg(ctx, step.setup.iamID, globalOrg.AggregateID); err != nil {
// logging.Log("SETUP-uGMA3").WithError(err).Error("unable to set global org on iam")
// return err
// }
// logging.Log("SETUP-d32h1").Info("global org set")
// return nil
//}
//
//func (step *Step1) setIamProject(ctx context.Context, iamProjectName string) error {
// logging.Log("SETUP-HE3qa").Info("setting iam project")
// iamProject, ok := step.createdProjects[iamProjectName]
// if !ok {
// logging.LogWithFields("SETUP-SJFWP", "IAM Project", iamProjectName).Error("iam project created")
// return caos_errs.ThrowPreconditionFailedf(nil, "SETUP-sGmQt", "iam project not created: %v", iamProjectName)
// }
//
// if _, err := step.setup.IamEvents.SetIAMProject(ctx, step.setup.iamID, iamProject.AggregateID); err != nil {
// logging.Log("SETUP-i1pNh").WithError(err).Error("unable to set iam project on iam")
// return err
// }
// logging.Log("SETUP-d7WEU").Info("iam project set")
// return nil
//}
//
//func (step *Step1) users(ctx context.Context, users []User, orgPolicy *iam_model.OrgIAMPolicyView) error {
// for _, user := range users {
// created, err := step.user(ctx, user, orgPolicy)
// if err != nil {
// logging.LogWithFields("SETUP-9soer", "Email", user.Email).WithError(err).Error("unable to create iam user")
// return err
// }
// step.createdUsers[user.Email] = created
// }
// return nil
//}
//
//func (step *Step1) user(ctx context.Context, user User, orgPolicy *iam_model.OrgIAMPolicyView) (*usr_model.User, error) {
// createUser := &usr_model.User{
// UserName: user.UserName,
// Human: &usr_model.Human{
// Profile: &usr_model.Profile{
// FirstName: user.FirstName,
// LastName: user.LastName,
// },
// Email: &usr_model.Email{
// EmailAddress: user.Email,
// IsEmailVerified: true,
// },
// Password: &usr_model.Password{
// SecretString: user.Password,
// },
// },
// }
// return step.setup.UserEvents.CreateUser(ctx, createUser, step.pwComplexityPolicy, orgPolicy)
//}
//
//func (step *Step1) orgOwners(ctx context.Context, org *org_model.Org, owners []string) error {
// for _, orgOwner := range owners {
// user, ok := step.createdUsers[orgOwner]
// if !ok {
// logging.LogWithFields("SETUP-s9ilr", "Owner", orgOwner).Error("unable to add user to org members")
// return caos_errs.ThrowPreconditionFailedf(nil, "SETUP-s0prs", "unable to add user to org members: %v", orgOwner)
// }
// err := step.orgOwner(ctx, org, user)
// if err != nil {
// logging.Log("SETUP-s90oe").WithError(err).Error("unable to add global org admin to members of global org")
// return err
// }
// }
// return nil
//}
//
//func (step *Step1) orgOwner(ctx context.Context, org *org_model.Org, user *usr_model.User) error {
// addMember := &org_model.OrgMember{
// ObjectRoot: models.ObjectRoot{AggregateID: org.AggregateID},
// UserID: user.AggregateID,
// Roles: []string{OrgOwnerRole},
// }
// _, err := step.setup.OrgEvents.AddOrgMember(ctx, addMember)
// return err
//}
//
//func (step *Step1) projects(ctx context.Context, projects []Project, ownerID string) error {
// ctxData := authz.GetCtxData(ctx)
// ctxData.UserID = ownerID
// projectCtx := authz.SetCtxData(ctx, ctxData)
//
// for _, project := range projects {
// createdProject, err := step.project(projectCtx, project)
// if err != nil {
// return err
// }
// step.createdProjects[createdProject.Name] = createdProject
// for _, oidc := range project.OIDCApps {
// app, err := step.oidcApp(ctx, createdProject, oidc)
// if err != nil {
// return err
// }
// logging.LogWithFields("SETUP-asd32f", "name", app.Name, "clientID", app.OIDCConfig.ClientID).Info("created OIDC application")
// }
// }
// return nil
//}
//
//func (step *Step1) project(ctx context.Context, project Project) (*proj_model.Project, error) {
// addProject := &proj_model.Project{
// Name: project.Name,
// }
// return step.setup.ProjectEvents.CreateProject(ctx, addProject, false)
//}
//
//func (step *Step1) oidcApp(ctx context.Context, project *proj_model.Project, oidc OIDCApp) (*proj_model.Application, error) {
// addOIDCApp := &proj_model.Application{
// ObjectRoot: models.ObjectRoot{AggregateID: project.AggregateID},
// Name: oidc.Name,
// OIDCConfig: &proj_model.OIDCConfig{
// RedirectUris: oidc.RedirectUris,
// ResponseTypes: getOIDCResponseTypes(oidc.ResponseTypes),
// GrantTypes: getOIDCGrantTypes(oidc.GrantTypes),
// ApplicationType: getOIDCApplicationType(oidc.ApplicationType),
// AuthMethodType: getOIDCAuthMethod(oidc.AuthMethodType),
// PostLogoutRedirectUris: oidc.PostLogoutRedirectUris,
// DevMode: oidc.DevMode,
// },
// }
// return step.setup.ProjectEvents.AddApplication(ctx, addOIDCApp)
//}

View File

@ -185,7 +185,9 @@ Errors:
MemberNotExisting: Member existiert nicht
IDMissing: Id fehlt
GlobalOrgMissing: Globale Organisation fehlt
IamProjectIDMisisng: Iam Project ID fehlt
GlobalOrgAlreadySet: Globale Organisation wurde bereits gesetzt
IAMProjectIDMissing: IAM Project ID fehlt
IamProjectAlreadySet: IAM Project ID wurde bereits gesetzt
IdpInvalid: IDP Konfiguration ist ungültig
IdpNotExisting: IDP Konfiguration existiert nicht
OIDCConfigInvalid: OIDC IDP Konfiguration ist ungültig

View File

@ -185,7 +185,9 @@ Errors:
MemberNotExisting: Member does not exist
IDMissing: Id missing
GlobalOrgMissing: Global organisation missing
IamProjectIDMisisng: Iam project id missing
GlobalOrgAlreadySet: Global organisation has already been set
IAMProjectIDMissing: IAM project id missing
IamProjectAlreadySet: IAM project id has already been set
IdpInvalid: IDP configuration is invalid
IdpNotExisting: IDP configuration does not exist
OIDCConfigInvalid: OIDC IDP configuration is invalid

View File

@ -14,18 +14,18 @@ import (
type CommandSide struct {
eventstore *eventstore.Eventstore
idGenerator id.Generator
iamID string
iamDomain string
idpConfigSecretCrypto crypto.Crypto
userPasswordAlg crypto.HashAlgorithm
initializeUserCode crypto.Generator
emailVerificationCode crypto.Generator
phoneVerificationCode crypto.Generator
passwordVerificationCode crypto.Generator
machineKeyAlg crypto.EncryptionAlgorithm
machineKeySize int
userPasswordAlg crypto.HashAlgorithm
initializeUserCode crypto.Generator
emailVerificationCode crypto.Generator
phoneVerificationCode crypto.Generator
passwordVerificationCode crypto.Generator
machineKeyAlg crypto.EncryptionAlgorithm
machineKeySize int
applicationSecretGenerator crypto.Generator
}
type Config struct {
@ -37,34 +37,37 @@ func StartCommandSide(config *Config) (repo *CommandSide, err error) {
repo = &CommandSide{
eventstore: config.Eventstore,
idGenerator: id.SonyFlakeGenerator,
iamID: config.SystemDefaults.IamID,
iamDomain: config.SystemDefaults.Domain,
}
iam_repo.RegisterEventMappers(repo.eventstore)
//TODO: simplify!!!!
repo.idpConfigSecretCrypto, err = crypto.NewAESCrypto(config.SystemDefaults.IDPConfigVerificationKey)
if err != nil {
return nil, err
}
aesCrypto, err := crypto.NewAESCrypto(config.SystemDefaults.UserVerificationKey)
userEncryptionAlgorithm, err := crypto.NewAESCrypto(config.SystemDefaults.UserVerificationKey)
if err != nil {
return nil, err
}
repo.initializeUserCode = crypto.NewEncryptionGenerator(config.SystemDefaults.SecretGenerators.InitializeUserCode, aesCrypto)
repo.emailVerificationCode = crypto.NewEncryptionGenerator(config.SystemDefaults.SecretGenerators.EmailVerificationCode, aesCrypto)
repo.phoneVerificationCode = crypto.NewEncryptionGenerator(config.SystemDefaults.SecretGenerators.PhoneVerificationCode, aesCrypto)
repo.passwordVerificationCode = crypto.NewEncryptionGenerator(config.SystemDefaults.SecretGenerators.PasswordVerificationCode, aesCrypto)
repo.initializeUserCode = crypto.NewEncryptionGenerator(config.SystemDefaults.SecretGenerators.InitializeUserCode, userEncryptionAlgorithm)
repo.emailVerificationCode = crypto.NewEncryptionGenerator(config.SystemDefaults.SecretGenerators.EmailVerificationCode, userEncryptionAlgorithm)
repo.phoneVerificationCode = crypto.NewEncryptionGenerator(config.SystemDefaults.SecretGenerators.PhoneVerificationCode, userEncryptionAlgorithm)
repo.passwordVerificationCode = crypto.NewEncryptionGenerator(config.SystemDefaults.SecretGenerators.PasswordVerificationCode, userEncryptionAlgorithm)
repo.userPasswordAlg = crypto.NewBCrypt(config.SystemDefaults.SecretGenerators.PasswordSaltCost)
repo.machineKeyAlg = aesCrypto
repo.machineKeyAlg = userEncryptionAlgorithm
repo.machineKeySize = int(config.SystemDefaults.SecretGenerators.MachineKeySize)
passwordAlg := crypto.NewBCrypt(config.SystemDefaults.SecretGenerators.PasswordSaltCost)
repo.applicationSecretGenerator = crypto.NewHashGenerator(config.SystemDefaults.SecretGenerators.ClientSecretGenerator, passwordAlg)
return repo, nil
}
func (r *CommandSide) iamByID(ctx context.Context, id string) (_ *IAMWriteModel, err error) {
func (r *CommandSide) getIAMWriteModel(ctx context.Context) (_ *IAMWriteModel, err error) {
ctx, span := tracing.NewSpan(ctx)
defer func() { span.EndWithError(err) }()
writeModel := NewIAMWriteModel(id)
writeModel := NewIAMWriteModel()
err = r.eventstore.FilterToQueryReducer(ctx, writeModel)
if err != nil {
return nil, err

View File

@ -3,15 +3,41 @@ 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/iam"
)
//TODO: private
func (r *CommandSide) GetIAM(ctx context.Context, aggregateID string) (*domain.IAM, error) {
iamWriteModel := NewIAMWriteModel(aggregateID)
func (r *CommandSide) GetIAM(ctx context.Context) (*domain.IAM, error) {
iamWriteModel := NewIAMWriteModel()
err := r.eventstore.FilterToQueryReducer(ctx, iamWriteModel)
if err != nil {
return nil, err
}
return writeModelToIAM(iamWriteModel), nil
}
func (r *CommandSide) setGlobalOrg(ctx context.Context, iamAgg *iam.Aggregate, iamWriteModel *IAMWriteModel, orgID string) error {
err := r.eventstore.FilterToQueryReducer(ctx, iamWriteModel)
if err != nil {
return err
}
if iamWriteModel.GlobalOrgID != "" {
return caos_errs.ThrowPreconditionFailed(nil, "IAM-HGG24", "Errors.IAM.GlobalOrgAlreadySet")
}
iamAgg.PushEvents(iam.NewGlobalOrgSetEventEvent(ctx, orgID))
return nil
}
func (r *CommandSide) setIAMProject(ctx context.Context, iamAgg *iam.Aggregate, iamWriteModel *IAMWriteModel, projectID string) error {
err := r.eventstore.FilterToQueryReducer(ctx, iamWriteModel)
if err != nil {
return err
}
if iamWriteModel.ProjectID != "" {
return caos_errs.ThrowPreconditionFailed(nil, "IAM-EGbw2", "Errors.IAM.IAMProjectAlreadySet")
}
iamAgg.PushEvents(iam.NewIAMProjectSetEvent(ctx, projectID))
return nil
}

View File

@ -22,7 +22,7 @@ func (r *CommandSide) AddDefaultIDPConfig(ctx context.Context, config *domain.ID
return nil, err
}
//TODO: check name unique on aggregate
addedConfig := NewIAMIDPConfigWriteModel(config.AggregateID, idpConfigID)
addedConfig := NewIAMIDPConfigWriteModel(idpConfigID)
clientSecret, err := crypto.Crypt([]byte(config.OIDCConfig.ClientSecretString), r.idpConfigSecretCrypto)
if err != nil {
@ -58,7 +58,7 @@ func (r *CommandSide) AddDefaultIDPConfig(ctx context.Context, config *domain.ID
}
func (r *CommandSide) ChangeDefaultIDPConfig(ctx context.Context, config *domain.IDPConfig) (*domain.IDPConfig, error) {
existingIDP, err := r.iamIDPConfigWriteModelByID(ctx, config.AggregateID, config.IDPConfigID)
existingIDP, err := r.iamIDPConfigWriteModelByID(ctx, config.IDPConfigID)
if err != nil {
return nil, err
}
@ -81,7 +81,7 @@ func (r *CommandSide) ChangeDefaultIDPConfig(ctx context.Context, config *domain
}
func (r *CommandSide) DeactivateDefaultIDPConfig(ctx context.Context, idpID string) (*domain.IDPConfig, error) {
existingIDP, err := r.iamIDPConfigWriteModelByID(ctx, r.iamID, idpID)
existingIDP, err := r.iamIDPConfigWriteModelByID(ctx, idpID)
if err != nil {
return nil, err
}
@ -99,7 +99,7 @@ func (r *CommandSide) DeactivateDefaultIDPConfig(ctx context.Context, idpID stri
}
func (r *CommandSide) ReactivateDefaultIDPConfig(ctx context.Context, idpID string) (*domain.IDPConfig, error) {
existingIDP, err := r.iamIDPConfigWriteModelByID(ctx, r.iamID, idpID)
existingIDP, err := r.iamIDPConfigWriteModelByID(ctx, idpID)
if err != nil {
return nil, err
}
@ -117,8 +117,8 @@ func (r *CommandSide) ReactivateDefaultIDPConfig(ctx context.Context, idpID stri
return writeModelToIDPConfig(existingIDP), nil
}
func (r *CommandSide) RemoveDefaultIDPConfig(ctx context.Context, iamID, idpID string) (*domain.IDPConfig, error) {
writeModel, err := r.pushDefaultIDPWriteModel(ctx, iamID, idpID, func(a *iam.Aggregate, _ *IAMIDPConfigWriteModel) *iam.Aggregate {
func (r *CommandSide) RemoveDefaultIDPConfig(ctx context.Context, idpID string) (*domain.IDPConfig, error) {
writeModel, err := r.pushDefaultIDPWriteModel(ctx, idpID, func(a *iam.Aggregate, _ *IAMIDPConfigWriteModel) *iam.Aggregate {
a.Aggregate = *a.PushEvents(iam_repo.NewIDPConfigRemovedEvent(ctx, idpID))
return a
})
@ -129,8 +129,8 @@ func (r *CommandSide) RemoveDefaultIDPConfig(ctx context.Context, iamID, idpID s
return writeModelToIDPConfig(writeModel), nil
}
func (r *CommandSide) pushDefaultIDPWriteModel(ctx context.Context, iamID, idpID string, eventSetter func(*iam.Aggregate, *IAMIDPConfigWriteModel) *iam.Aggregate) (*IAMIDPConfigWriteModel, error) {
writeModel := NewIAMIDPConfigWriteModel(iamID, idpID)
func (r *CommandSide) pushDefaultIDPWriteModel(ctx context.Context, idpID string, eventSetter func(*iam.Aggregate, *IAMIDPConfigWriteModel) *iam.Aggregate) (*IAMIDPConfigWriteModel, error) {
writeModel := NewIAMIDPConfigWriteModel(idpID)
err := r.eventstore.FilterToQueryReducer(ctx, writeModel)
if err != nil {
return nil, err
@ -145,11 +145,11 @@ func (r *CommandSide) pushDefaultIDPWriteModel(ctx context.Context, iamID, idpID
return writeModel, nil
}
func (r *CommandSide) iamIDPConfigWriteModelByID(ctx context.Context, iamID, idpID string) (policy *IAMIDPConfigWriteModel, err error) {
func (r *CommandSide) iamIDPConfigWriteModelByID(ctx context.Context, idpID string) (policy *IAMIDPConfigWriteModel, err error) {
ctx, span := tracing.NewSpan(ctx)
defer func() { span.EndWithError(err) }()
writeModel := NewIAMIDPConfigWriteModel(iamID, idpID)
writeModel := NewIAMIDPConfigWriteModel(idpID)
err = r.eventstore.FilterToQueryReducer(ctx, writeModel)
if err != nil {
return nil, err

View File

@ -2,6 +2,7 @@ package command
import (
"context"
"github.com/caos/zitadel/internal/eventstore/v2"
"github.com/caos/zitadel/internal/v2/domain"
"github.com/caos/zitadel/internal/v2/repository/iam"
@ -11,11 +12,12 @@ type IAMIDPConfigWriteModel struct {
IDPConfigWriteModel
}
func NewIAMIDPConfigWriteModel(iamID, configID string) *IAMIDPConfigWriteModel {
func NewIAMIDPConfigWriteModel(configID string) *IAMIDPConfigWriteModel {
return &IAMIDPConfigWriteModel{
IDPConfigWriteModel{
WriteModel: eventstore.WriteModel{
AggregateID: iamID,
AggregateID: domain.IAMID,
ResourceOwner: domain.IAMID,
},
ConfigID: configID,
},
@ -24,7 +26,8 @@ func NewIAMIDPConfigWriteModel(iamID, configID string) *IAMIDPConfigWriteModel {
func (wm *IAMIDPConfigWriteModel) Query() *eventstore.SearchQueryBuilder {
return eventstore.NewSearchQueryBuilder(eventstore.ColumnsEvent, iam.AggregateType).
AggregateIDs(wm.AggregateID)
AggregateIDs(wm.AggregateID).
ResourceOwner(wm.ResourceOwner)
}
func (wm *IAMIDPConfigWriteModel) AppendEvents(events ...eventstore.EventReader) {

View File

@ -7,7 +7,7 @@ import (
)
func (r *CommandSide) ChangeDefaultIDPOIDCConfig(ctx context.Context, config *domain.OIDCIDPConfig) (*domain.OIDCIDPConfig, error) {
existingConfig := NewIDPOIDCConfigWriteModel(config.AggregateID, config.IDPConfigID)
existingConfig := NewIAMIDPOIDCConfigWriteModel(config.IDPConfigID)
err := r.eventstore.FilterToQueryReducer(ctx, existingConfig)
if err != nil {
return nil, err

View File

@ -2,22 +2,24 @@ package command
import (
"context"
"reflect"
"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/iam"
"reflect"
)
type IDPOIDCConfigWriteModel struct {
OIDCConfigWriteModel
}
func NewIDPOIDCConfigWriteModel(iamID, idpConfigID string) *IDPOIDCConfigWriteModel {
func NewIAMIDPOIDCConfigWriteModel(idpConfigID string) *IDPOIDCConfigWriteModel {
return &IDPOIDCConfigWriteModel{
OIDCConfigWriteModel{
WriteModel: eventstore.WriteModel{
AggregateID: iamID,
AggregateID: domain.IAMID,
ResourceOwner: domain.IAMID,
},
IDPConfigID: idpConfigID,
},
@ -67,7 +69,8 @@ func (wm *IDPOIDCConfigWriteModel) Reduce() error {
func (wm *IDPOIDCConfigWriteModel) Query() *eventstore.SearchQueryBuilder {
return eventstore.NewSearchQueryBuilder(eventstore.ColumnsEvent, iam.AggregateType).
AggregateIDs(wm.AggregateID)
AggregateIDs(wm.AggregateID).
ResourceOwner(wm.ResourceOwner)
}
func (wm *IDPOIDCConfigWriteModel) NewChangedEvent(

View File

@ -2,33 +2,22 @@ package command
import (
"context"
"github.com/caos/zitadel/internal/v2/domain"
"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"
iam_repo "github.com/caos/zitadel/internal/v2/repository/iam"
)
func (r *CommandSide) AddIAMMember(ctx context.Context, member *domain.Member) (*domain.Member, error) {
//TODO: check if roles valid
if !member.IsValid() {
return nil, caos_errs.ThrowPreconditionFailed(nil, "IAM-W8m4l", "Errors.IAM.MemberInvalid")
}
addedMember := NewIAMMemberWriteModel(member.AggregateID, member.UserID)
err := r.eventstore.FilterToQueryReducer(ctx, addedMember)
addedMember := NewIAMMemberWriteModel(member.UserID)
iamAgg := IAMAggregateFromWriteModel(&addedMember.MemberWriteModel.WriteModel)
err := r.addIAMMember(ctx, iamAgg, addedMember, member)
if err != nil {
return nil, err
}
if addedMember.State == domain.MemberStateActive {
return nil, errors.ThrowAlreadyExists(nil, "IAM-PtXi1", "Errors.IAM.Member.AlreadyExists")
}
iamAgg := IAMAggregateFromWriteModel(&addedMember.MemberWriteModel.WriteModel)
iamAgg.PushEvents(iam_repo.NewMemberAddedEvent(ctx, member.UserID, member.Roles...))
err = r.eventstore.PushAggregate(ctx, addedMember, iamAgg)
if err != nil {
@ -38,6 +27,26 @@ func (r *CommandSide) AddIAMMember(ctx context.Context, member *domain.Member) (
return memberWriteModelToMember(&addedMember.MemberWriteModel), nil
}
func (r *CommandSide) addIAMMember(ctx context.Context, iamAgg *iam_repo.Aggregate, addedMember *IAMMemberWriteModel, member *domain.Member) error {
//TODO: check if roles valid
if !member.IsValid() {
return caos_errs.ThrowPreconditionFailed(nil, "IAM-GR34U", "Errors.IAM.MemberInvalid")
}
err := r.eventstore.FilterToQueryReducer(ctx, addedMember)
if err != nil {
return err
}
if addedMember.State == domain.MemberStateActive {
return errors.ThrowAlreadyExists(nil, "IAM-sdgQ4", "Errors.IAM.Member.AlreadyExists")
}
iamAgg.PushEvents(iam_repo.NewMemberAddedEvent(ctx, member.UserID, member.Roles...))
return nil
}
//ChangeIAMMember updates an existing member
func (r *CommandSide) ChangeIAMMember(ctx context.Context, member *domain.Member) (*domain.Member, error) {
//TODO: check if roles valid
@ -46,7 +55,7 @@ func (r *CommandSide) ChangeIAMMember(ctx context.Context, member *domain.Member
return nil, caos_errs.ThrowPreconditionFailed(nil, "IAM-LiaZi", "Errors.IAM.MemberInvalid")
}
existingMember, err := r.iamMemberWriteModelByID(ctx, member.AggregateID, member.UserID)
existingMember, err := r.iamMemberWriteModelByID(ctx, member.UserID)
if err != nil {
return nil, err
}
@ -71,7 +80,7 @@ func (r *CommandSide) ChangeIAMMember(ctx context.Context, member *domain.Member
}
func (r *CommandSide) RemoveIAMMember(ctx context.Context, userID string) error {
m, err := r.iamMemberWriteModelByID(ctx, r.iamID, userID)
m, err := r.iamMemberWriteModelByID(ctx, userID)
if err != nil && !errors.IsNotFound(err) {
return err
}
@ -85,11 +94,11 @@ func (r *CommandSide) RemoveIAMMember(ctx context.Context, userID string) error
return r.eventstore.PushAggregate(ctx, m, iamAgg)
}
func (r *CommandSide) iamMemberWriteModelByID(ctx context.Context, iamID, userID string) (member *IAMMemberWriteModel, err error) {
func (r *CommandSide) iamMemberWriteModelByID(ctx context.Context, userID string) (member *IAMMemberWriteModel, err error) {
ctx, span := tracing.NewSpan(ctx)
defer func() { span.EndWithError(err) }()
writeModel := NewIAMMemberWriteModel(iamID, userID)
writeModel := NewIAMMemberWriteModel(userID)
err = r.eventstore.FilterToQueryReducer(ctx, writeModel)
if err != nil {
return nil, err

View File

@ -2,6 +2,7 @@ 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"
)
@ -9,11 +10,12 @@ type IAMMemberWriteModel struct {
MemberWriteModel
}
func NewIAMMemberWriteModel(iamID, userID string) *IAMMemberWriteModel {
func NewIAMMemberWriteModel(userID string) *IAMMemberWriteModel {
return &IAMMemberWriteModel{
MemberWriteModel{
WriteModel: eventstore.WriteModel{
AggregateID: iamID,
AggregateID: domain.IAMID,
ResourceOwner: domain.IAMID,
},
UserID: userID,
},
@ -48,5 +50,5 @@ func (wm *IAMMemberWriteModel) Reduce() error {
func (wm *IAMMemberWriteModel) Query() *eventstore.SearchQueryBuilder {
return eventstore.NewSearchQueryBuilder(eventstore.ColumnsEvent, iam.AggregateType).
AggregateIDs(wm.MemberWriteModel.AggregateID)
AggregateIDs(wm.MemberWriteModel.AggregateID).ResourceOwner(wm.ResourceOwner)
}

View File

@ -16,10 +16,11 @@ type IAMWriteModel struct {
ProjectID string
}
func NewIAMWriteModel(iamID string) *IAMWriteModel {
func NewIAMWriteModel() *IAMWriteModel {
return &IAMWriteModel{
WriteModel: eventstore.WriteModel{
AggregateID: iamID,
AggregateID: domain.IAMID,
ResourceOwner: domain.IAMID,
},
}
}
@ -56,7 +57,8 @@ func (wm *IAMWriteModel) Reduce() error {
func (wm *IAMWriteModel) Query() *eventstore.SearchQueryBuilder {
return eventstore.NewSearchQueryBuilder(eventstore.ColumnsEvent, iam.AggregateType).
AggregateIDs(wm.AggregateID)
AggregateIDs(wm.AggregateID).
ResourceOwner(wm.ResourceOwner)
}
//

View File

@ -9,8 +9,7 @@ import (
)
func (r *CommandSide) AddDefaultLabelPolicy(ctx context.Context, policy *domain.LabelPolicy) (*domain.LabelPolicy, error) {
policy.AggregateID = r.iamID
addedPolicy := NewIAMLabelPolicyWriteModel(policy.AggregateID)
addedPolicy := NewIAMLabelPolicyWriteModel()
iamAgg := IAMAggregateFromWriteModel(&addedPolicy.LabelPolicyWriteModel.WriteModel)
err := r.addDefaultLabelPolicy(ctx, nil, addedPolicy, policy)
if err != nil {
@ -40,8 +39,7 @@ func (r *CommandSide) addDefaultLabelPolicy(ctx context.Context, iamAgg *iam_rep
}
func (r *CommandSide) ChangeDefaultLabelPolicy(ctx context.Context, policy *domain.LabelPolicy) (*domain.LabelPolicy, error) {
policy.AggregateID = r.iamID
existingPolicy, err := r.defaultLabelPolicyWriteModelByID(ctx, policy.AggregateID)
existingPolicy, err := r.defaultLabelPolicyWriteModelByID(ctx)
if err != nil {
return nil, err
}
@ -66,11 +64,11 @@ func (r *CommandSide) ChangeDefaultLabelPolicy(ctx context.Context, policy *doma
return writeModelToLabelPolicy(existingPolicy), nil
}
func (r *CommandSide) defaultLabelPolicyWriteModelByID(ctx context.Context, iamID string) (policy *IAMLabelPolicyWriteModel, err error) {
func (r *CommandSide) defaultLabelPolicyWriteModelByID(ctx context.Context) (policy *IAMLabelPolicyWriteModel, err error) {
ctx, span := tracing.NewSpan(ctx)
defer func() { span.EndWithError(err) }()
writeModel := NewIAMLabelPolicyWriteModel(iamID)
writeModel := NewIAMLabelPolicyWriteModel()
err = r.eventstore.FilterToQueryReducer(ctx, writeModel)
if err != nil {
return nil, err

View File

@ -2,7 +2,9 @@ package command
import (
"context"
"github.com/caos/zitadel/internal/eventstore/v2"
"github.com/caos/zitadel/internal/v2/domain"
"github.com/caos/zitadel/internal/v2/repository/iam"
)
@ -10,11 +12,12 @@ type IAMLabelPolicyWriteModel struct {
LabelPolicyWriteModel
}
func NewIAMLabelPolicyWriteModel(iamID string) *IAMLabelPolicyWriteModel {
func NewIAMLabelPolicyWriteModel() *IAMLabelPolicyWriteModel {
return &IAMLabelPolicyWriteModel{
LabelPolicyWriteModel{
WriteModel: eventstore.WriteModel{
AggregateID: iamID,
AggregateID: domain.IAMID,
ResourceOwner: domain.IAMID,
},
},
}
@ -37,7 +40,8 @@ func (wm *IAMLabelPolicyWriteModel) Reduce() error {
func (wm *IAMLabelPolicyWriteModel) Query() *eventstore.SearchQueryBuilder {
return eventstore.NewSearchQueryBuilder(eventstore.ColumnsEvent, iam.AggregateType).
AggregateIDs(wm.LabelPolicyWriteModel.AggregateID)
AggregateIDs(wm.LabelPolicyWriteModel.AggregateID).
ResourceOwner(wm.ResourceOwner)
}
func (wm *IAMLabelPolicyWriteModel) NewChangedEvent(

View File

@ -11,7 +11,7 @@ import (
)
func (r *CommandSide) GetDefaultLoginPolicy(ctx context.Context) (*domain.LoginPolicy, error) {
policyWriteModel := NewIAMLoginPolicyWriteModel(r.iamID)
policyWriteModel := NewIAMLoginPolicyWriteModel()
err := r.eventstore.FilterToQueryReducer(ctx, policyWriteModel)
if err != nil {
return nil, err
@ -22,8 +22,7 @@ func (r *CommandSide) GetDefaultLoginPolicy(ctx context.Context) (*domain.LoginP
}
func (r *CommandSide) AddDefaultLoginPolicy(ctx context.Context, policy *domain.LoginPolicy) (*domain.LoginPolicy, error) {
policy.AggregateID = r.iamID
addedPolicy := NewIAMLoginPolicyWriteModel(policy.AggregateID)
addedPolicy := NewIAMLoginPolicyWriteModel()
iamAgg := IAMAggregateFromWriteModel(&addedPolicy.WriteModel)
err := r.addDefaultLoginPolicy(ctx, nil, addedPolicy, policy)
if err != nil {
@ -52,8 +51,7 @@ func (r *CommandSide) addDefaultLoginPolicy(ctx context.Context, iamAgg *iam_rep
}
func (r *CommandSide) ChangeDefaultLoginPolicy(ctx context.Context, policy *domain.LoginPolicy) (*domain.LoginPolicy, error) {
policy.AggregateID = r.iamID
existingPolicy := NewIAMLoginPolicyWriteModel(r.iamID)
existingPolicy := NewIAMLoginPolicyWriteModel()
iamAgg := IAMAggregateFromWriteModel(&existingPolicy.LoginPolicyWriteModel.WriteModel)
err := r.changeDefaultLoginPolicy(ctx, iamAgg, existingPolicy, policy)
if err != nil {
@ -68,7 +66,6 @@ func (r *CommandSide) ChangeDefaultLoginPolicy(ctx context.Context, policy *doma
}
func (r *CommandSide) changeDefaultLoginPolicy(ctx context.Context, iamAgg *iam_repo.Aggregate, existingPolicy *IAMLoginPolicyWriteModel, policy *domain.LoginPolicy) error {
policy.AggregateID = r.iamID
err := r.defaultLoginPolicyWriteModelByID(ctx, existingPolicy)
if err != nil {
return err
@ -86,8 +83,7 @@ func (r *CommandSide) changeDefaultLoginPolicy(ctx context.Context, iamAgg *iam_
}
func (r *CommandSide) AddIDPProviderToDefaultLoginPolicy(ctx context.Context, idpProvider *domain.IDPProvider) (*domain.IDPProvider, error) {
idpProvider.AggregateID = r.iamID
idpModel := NewIAMIdentityProviderWriteModel(idpProvider.AggregateID, idpProvider.IDPConfigID)
idpModel := NewIAMIdentityProviderWriteModel(idpProvider.IDPConfigID)
err := r.eventstore.FilterToQueryReducer(ctx, idpModel)
if err != nil {
return nil, err
@ -107,8 +103,7 @@ func (r *CommandSide) AddIDPProviderToDefaultLoginPolicy(ctx context.Context, id
}
func (r *CommandSide) RemoveIDPProviderFromDefaultLoginPolicy(ctx context.Context, idpProvider *iam_model.IDPProvider) error {
idpProvider.AggregateID = r.iamID
idpModel := NewIAMIdentityProviderWriteModel(idpProvider.AggregateID, idpProvider.IDPConfigID)
idpModel := NewIAMIdentityProviderWriteModel(idpProvider.IDPConfigID)
err := r.eventstore.FilterToQueryReducer(ctx, idpModel)
if err != nil {
return err
@ -123,7 +118,7 @@ func (r *CommandSide) RemoveIDPProviderFromDefaultLoginPolicy(ctx context.Contex
}
func (r *CommandSide) AddSecondFactorToDefaultLoginPolicy(ctx context.Context, secondFactor iam_model.SecondFactorType) (iam_model.SecondFactorType, error) {
secondFactorModel := NewIAMSecondFactorWriteModel(r.iamID)
secondFactorModel := NewIAMSecondFactorWriteModel()
iamAgg := IAMAggregateFromWriteModel(&secondFactorModel.SecondFactorWriteModel.WriteModel)
err := r.addSecondFactorToDefaultLoginPolicy(ctx, nil, secondFactorModel, secondFactor)
if err != nil {
@ -153,7 +148,7 @@ func (r *CommandSide) addSecondFactorToDefaultLoginPolicy(ctx context.Context, i
}
func (r *CommandSide) RemoveSecondFactorFromDefaultLoginPolicy(ctx context.Context, secondFactor iam_model.SecondFactorType) error {
secondFactorModel := NewIAMSecondFactorWriteModel(r.iamID)
secondFactorModel := NewIAMSecondFactorWriteModel()
err := r.eventstore.FilterToQueryReducer(ctx, secondFactorModel)
if err != nil {
return err
@ -168,7 +163,7 @@ func (r *CommandSide) RemoveSecondFactorFromDefaultLoginPolicy(ctx context.Conte
}
func (r *CommandSide) AddMultiFactorToDefaultLoginPolicy(ctx context.Context, multiFactor iam_model.MultiFactorType) (iam_model.MultiFactorType, error) {
multiFactorModel := NewIAMMultiFactorWriteModel(r.iamID)
multiFactorModel := NewIAMMultiFactorWriteModel()
iamAgg := IAMAggregateFromWriteModel(&multiFactorModel.MultiFactoryWriteModel.WriteModel)
err := r.addMultiFactorToDefaultLoginPolicy(ctx, iamAgg, multiFactorModel, multiFactor)
if err != nil {
@ -197,7 +192,7 @@ func (r *CommandSide) addMultiFactorToDefaultLoginPolicy(ctx context.Context, ia
}
func (r *CommandSide) RemoveMultiFactorFromDefaultLoginPolicy(ctx context.Context, multiFactor iam_model.MultiFactorType) error {
multiFactorModel := NewIAMMultiFactorWriteModel(r.iamID)
multiFactorModel := NewIAMMultiFactorWriteModel()
err := r.eventstore.FilterToQueryReducer(ctx, multiFactorModel)
if err != nil {
return err

View File

@ -2,6 +2,7 @@ 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"
)
@ -9,11 +10,12 @@ type IAMSecondFactorWriteModel struct {
SecondFactorWriteModel
}
func NewIAMSecondFactorWriteModel(iamID string) *IAMSecondFactorWriteModel {
func NewIAMSecondFactorWriteModel() *IAMSecondFactorWriteModel {
return &IAMSecondFactorWriteModel{
SecondFactorWriteModel{
WriteModel: eventstore.WriteModel{
AggregateID: iamID,
AggregateID: domain.IAMID,
ResourceOwner: domain.IAMID,
},
},
}
@ -34,18 +36,20 @@ func (wm *IAMSecondFactorWriteModel) Reduce() error {
func (wm *IAMSecondFactorWriteModel) Query() *eventstore.SearchQueryBuilder {
return eventstore.NewSearchQueryBuilder(eventstore.ColumnsEvent, iam.AggregateType).
AggregateIDs(wm.WriteModel.AggregateID)
AggregateIDs(wm.WriteModel.AggregateID).
ResourceOwner(wm.ResourceOwner)
}
type IAMMultiFactorWriteModel struct {
MultiFactoryWriteModel
}
func NewIAMMultiFactorWriteModel(iamID string) *IAMMultiFactorWriteModel {
func NewIAMMultiFactorWriteModel() *IAMMultiFactorWriteModel {
return &IAMMultiFactorWriteModel{
MultiFactoryWriteModel{
WriteModel: eventstore.WriteModel{
AggregateID: iamID,
AggregateID: domain.IAMID,
ResourceOwner: domain.IAMID,
},
},
}
@ -66,5 +70,6 @@ func (wm *IAMMultiFactorWriteModel) Reduce() error {
func (wm *IAMMultiFactorWriteModel) Query() *eventstore.SearchQueryBuilder {
return eventstore.NewSearchQueryBuilder(eventstore.ColumnsEvent, iam.AggregateType).
AggregateIDs(wm.WriteModel.AggregateID)
AggregateIDs(wm.WriteModel.AggregateID).
ResourceOwner(wm.ResourceOwner)
}

View File

@ -2,6 +2,7 @@ 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"
)
@ -9,11 +10,12 @@ type IAMIdentityProviderWriteModel struct {
IdentityProviderWriteModel
}
func NewIAMIdentityProviderWriteModel(iamID, idpConfigID string) *IAMIdentityProviderWriteModel {
func NewIAMIdentityProviderWriteModel(idpConfigID string) *IAMIdentityProviderWriteModel {
return &IAMIdentityProviderWriteModel{
IdentityProviderWriteModel: IdentityProviderWriteModel{
WriteModel: eventstore.WriteModel{
AggregateID: iamID,
AggregateID: domain.IAMID,
ResourceOwner: domain.IAMID,
},
IDPConfigID: idpConfigID,
},
@ -38,5 +40,6 @@ func (wm *IAMIdentityProviderWriteModel) Reduce() error {
func (wm *IAMIdentityProviderWriteModel) Query() *eventstore.SearchQueryBuilder {
return eventstore.NewSearchQueryBuilder(eventstore.ColumnsEvent, iam.AggregateType).
AggregateIDs(wm.AggregateID)
AggregateIDs(wm.AggregateID).
ResourceOwner(wm.ResourceOwner)
}

View File

@ -2,6 +2,7 @@ package command
import (
"context"
"github.com/caos/zitadel/internal/eventstore/v2"
"github.com/caos/zitadel/internal/v2/domain"
"github.com/caos/zitadel/internal/v2/repository/iam"
@ -11,11 +12,12 @@ type IAMLoginPolicyWriteModel struct {
LoginPolicyWriteModel
}
func NewIAMLoginPolicyWriteModel(iamID string) *IAMLoginPolicyWriteModel {
func NewIAMLoginPolicyWriteModel() *IAMLoginPolicyWriteModel {
return &IAMLoginPolicyWriteModel{
LoginPolicyWriteModel{
WriteModel: eventstore.WriteModel{
AggregateID: iamID,
AggregateID: domain.IAMID,
ResourceOwner: domain.IAMID,
},
},
}
@ -42,7 +44,8 @@ func (wm *IAMLoginPolicyWriteModel) Reduce() error {
func (wm *IAMLoginPolicyWriteModel) Query() *eventstore.SearchQueryBuilder {
return eventstore.NewSearchQueryBuilder(eventstore.ColumnsEvent, iam.AggregateType).
AggregateIDs(wm.LoginPolicyWriteModel.AggregateID)
AggregateIDs(wm.LoginPolicyWriteModel.AggregateID).
ResourceOwner(wm.ResourceOwner)
}
func (wm *IAMLoginPolicyWriteModel) NewChangedEvent(

View File

@ -9,8 +9,7 @@ import (
)
func (r *CommandSide) AddDefaultOrgIAMPolicy(ctx context.Context, policy *domain.OrgIAMPolicy) (*domain.OrgIAMPolicy, error) {
policy.AggregateID = r.iamID
addedPolicy := NewIAMOrgIAMPolicyWriteModel(policy.AggregateID)
addedPolicy := NewIAMOrgIAMPolicyWriteModel()
iamAgg := IAMAggregateFromWriteModel(&addedPolicy.WriteModel)
err := r.addDefaultOrgIAMPolicy(ctx, nil, addedPolicy, policy)
if err != nil {
@ -39,8 +38,7 @@ func (r *CommandSide) addDefaultOrgIAMPolicy(ctx context.Context, iamAgg *iam_re
}
func (r *CommandSide) ChangeDefaultOrgIAMPolicy(ctx context.Context, policy *domain.OrgIAMPolicy) (*domain.OrgIAMPolicy, error) {
policy.AggregateID = r.iamID
existingPolicy, err := r.defaultOrgIAMPolicyWriteModelByID(ctx, policy.AggregateID)
existingPolicy, err := r.defaultOrgIAMPolicyWriteModelByID(ctx)
if err != nil {
return nil, err
}
@ -65,7 +63,7 @@ func (r *CommandSide) ChangeDefaultOrgIAMPolicy(ctx context.Context, policy *dom
}
func (r *CommandSide) getDefaultOrgIAMPolicy(ctx context.Context) (*domain.OrgIAMPolicy, error) {
policyWriteModel, err := r.defaultOrgIAMPolicyWriteModelByID(ctx, r.iamID)
policyWriteModel, err := r.defaultOrgIAMPolicyWriteModelByID(ctx)
if err != nil {
return nil, err
}
@ -74,11 +72,11 @@ func (r *CommandSide) getDefaultOrgIAMPolicy(ctx context.Context) (*domain.OrgIA
return policy, nil
}
func (r *CommandSide) defaultOrgIAMPolicyWriteModelByID(ctx context.Context, iamID string) (policy *IAMOrgIAMPolicyWriteModel, err error) {
func (r *CommandSide) defaultOrgIAMPolicyWriteModelByID(ctx context.Context) (policy *IAMOrgIAMPolicyWriteModel, err error) {
ctx, span := tracing.NewSpan(ctx)
defer func() { span.EndWithError(err) }()
writeModel := NewIAMOrgIAMPolicyWriteModel(iamID)
writeModel := NewIAMOrgIAMPolicyWriteModel()
err = r.eventstore.FilterToQueryReducer(ctx, writeModel)
if err != nil {
return nil, err

View File

@ -2,7 +2,9 @@ package command
import (
"context"
"github.com/caos/zitadel/internal/eventstore/v2"
"github.com/caos/zitadel/internal/v2/domain"
"github.com/caos/zitadel/internal/v2/repository/iam"
)
@ -10,11 +12,12 @@ type IAMOrgIAMPolicyWriteModel struct {
PolicyOrgIAMWriteModel
}
func NewIAMOrgIAMPolicyWriteModel(iamID string) *IAMOrgIAMPolicyWriteModel {
func NewIAMOrgIAMPolicyWriteModel() *IAMOrgIAMPolicyWriteModel {
return &IAMOrgIAMPolicyWriteModel{
PolicyOrgIAMWriteModel{
WriteModel: eventstore.WriteModel{
AggregateID: iamID,
AggregateID: domain.IAMID,
ResourceOwner: domain.IAMID,
},
},
}
@ -37,7 +40,8 @@ func (wm *IAMOrgIAMPolicyWriteModel) Reduce() error {
func (wm *IAMOrgIAMPolicyWriteModel) Query() *eventstore.SearchQueryBuilder {
return eventstore.NewSearchQueryBuilder(eventstore.ColumnsEvent, iam.AggregateType).
AggregateIDs(wm.PolicyOrgIAMWriteModel.AggregateID)
AggregateIDs(wm.PolicyOrgIAMWriteModel.AggregateID).
ResourceOwner(wm.ResourceOwner)
}
func (wm *IAMOrgIAMPolicyWriteModel) NewChangedEvent(ctx context.Context, userLoginMustBeDomain bool) (*iam.OrgIAMPolicyChangedEvent, bool) {

View File

@ -9,8 +9,7 @@ import (
)
func (r *CommandSide) AddDefaultPasswordAgePolicy(ctx context.Context, policy *domain.PasswordAgePolicy) (*domain.PasswordAgePolicy, error) {
policy.AggregateID = r.iamID
addedPolicy := NewIAMPasswordAgePolicyWriteModel(policy.AggregateID)
addedPolicy := NewIAMPasswordAgePolicyWriteModel()
iamAgg := IAMAggregateFromWriteModel(&addedPolicy.WriteModel)
err := r.addDefaultPasswordAgePolicy(ctx, nil, addedPolicy, policy)
if err != nil {
@ -40,8 +39,7 @@ func (r *CommandSide) addDefaultPasswordAgePolicy(ctx context.Context, iamAgg *i
}
func (r *CommandSide) ChangeDefaultPasswordAgePolicy(ctx context.Context, policy *domain.PasswordAgePolicy) (*domain.PasswordAgePolicy, error) {
policy.AggregateID = r.iamID
existingPolicy, err := r.defaultPasswordAgePolicyWriteModelByID(ctx, policy.AggregateID)
existingPolicy, err := r.defaultPasswordAgePolicyWriteModelByID(ctx)
if err != nil {
return nil, err
}
@ -65,11 +63,11 @@ func (r *CommandSide) ChangeDefaultPasswordAgePolicy(ctx context.Context, policy
return writeModelToPasswordAgePolicy(existingPolicy), nil
}
func (r *CommandSide) defaultPasswordAgePolicyWriteModelByID(ctx context.Context, iamID string) (policy *IAMPasswordAgePolicyWriteModel, err error) {
func (r *CommandSide) defaultPasswordAgePolicyWriteModelByID(ctx context.Context) (policy *IAMPasswordAgePolicyWriteModel, err error) {
ctx, span := tracing.NewSpan(ctx)
defer func() { span.EndWithError(err) }()
writeModel := NewIAMPasswordAgePolicyWriteModel(iamID)
writeModel := NewIAMPasswordAgePolicyWriteModel()
err = r.eventstore.FilterToQueryReducer(ctx, writeModel)
if err != nil {
return nil, err

View File

@ -2,7 +2,9 @@ package command
import (
"context"
"github.com/caos/zitadel/internal/eventstore/v2"
"github.com/caos/zitadel/internal/v2/domain"
"github.com/caos/zitadel/internal/v2/repository/iam"
)
@ -10,11 +12,12 @@ type IAMPasswordAgePolicyWriteModel struct {
PasswordAgePolicyWriteModel
}
func NewIAMPasswordAgePolicyWriteModel(iamID string) *IAMPasswordAgePolicyWriteModel {
func NewIAMPasswordAgePolicyWriteModel() *IAMPasswordAgePolicyWriteModel {
return &IAMPasswordAgePolicyWriteModel{
PasswordAgePolicyWriteModel{
WriteModel: eventstore.WriteModel{
AggregateID: iamID,
AggregateID: domain.IAMID,
ResourceOwner: domain.IAMID,
},
},
}
@ -37,7 +40,8 @@ func (wm *IAMPasswordAgePolicyWriteModel) Reduce() error {
func (wm *IAMPasswordAgePolicyWriteModel) Query() *eventstore.SearchQueryBuilder {
return eventstore.NewSearchQueryBuilder(eventstore.ColumnsEvent, iam.AggregateType).
AggregateIDs(wm.PasswordAgePolicyWriteModel.AggregateID)
AggregateIDs(wm.PasswordAgePolicyWriteModel.AggregateID).
ResourceOwner(wm.ResourceOwner)
}
func (wm *IAMPasswordAgePolicyWriteModel) NewChangedEvent(ctx context.Context, expireWarnDays, maxAgeDays uint64) (*iam.PasswordAgePolicyChangedEvent, bool) {

View File

@ -9,7 +9,7 @@ import (
)
func (r *CommandSide) GetDefaultPasswordComplexityPolicy(ctx context.Context) (*domain.PasswordComplexityPolicy, error) {
policyWriteModel := NewIAMPasswordComplexityPolicyWriteModel(r.iamID)
policyWriteModel := NewIAMPasswordComplexityPolicyWriteModel()
err := r.eventstore.FilterToQueryReducer(ctx, policyWriteModel)
if err != nil {
return nil, err
@ -20,8 +20,7 @@ func (r *CommandSide) GetDefaultPasswordComplexityPolicy(ctx context.Context) (*
}
func (r *CommandSide) AddDefaultPasswordComplexityPolicy(ctx context.Context, policy *domain.PasswordComplexityPolicy) (*domain.PasswordComplexityPolicy, error) {
policy.AggregateID = r.iamID
addedPolicy := NewIAMPasswordComplexityPolicyWriteModel(policy.AggregateID)
addedPolicy := NewIAMPasswordComplexityPolicyWriteModel()
iamAgg := IAMAggregateFromWriteModel(&addedPolicy.WriteModel)
err := r.addDefaultPasswordComplexityPolicy(ctx, iamAgg, addedPolicy, policy)
if err != nil {
@ -55,12 +54,11 @@ func (r *CommandSide) addDefaultPasswordComplexityPolicy(ctx context.Context, ia
}
func (r *CommandSide) ChangeDefaultPasswordComplexityPolicy(ctx context.Context, policy *domain.PasswordComplexityPolicy) (*domain.PasswordComplexityPolicy, error) {
policy.AggregateID = r.iamID
if err := policy.IsValid(); err != nil {
return nil, err
}
existingPolicy, err := r.defaultPasswordComplexityPolicyWriteModelByID(ctx, policy.AggregateID)
existingPolicy, err := r.defaultPasswordComplexityPolicyWriteModelByID(ctx)
if err != nil {
return nil, err
}
@ -83,11 +81,11 @@ func (r *CommandSide) ChangeDefaultPasswordComplexityPolicy(ctx context.Context,
return writeModelToPasswordComplexityPolicy(existingPolicy), nil
}
func (r *CommandSide) defaultPasswordComplexityPolicyWriteModelByID(ctx context.Context, iamID string) (policy *IAMPasswordComplexityPolicyWriteModel, err error) {
func (r *CommandSide) defaultPasswordComplexityPolicyWriteModelByID(ctx context.Context) (policy *IAMPasswordComplexityPolicyWriteModel, err error) {
ctx, span := tracing.NewSpan(ctx)
defer func() { span.EndWithError(err) }()
writeModel := NewIAMPasswordComplexityPolicyWriteModel(iamID)
writeModel := NewIAMPasswordComplexityPolicyWriteModel()
err = r.eventstore.FilterToQueryReducer(ctx, writeModel)
if err != nil {
return nil, err

View File

@ -2,7 +2,9 @@ package command
import (
"context"
"github.com/caos/zitadel/internal/eventstore/v2"
"github.com/caos/zitadel/internal/v2/domain"
"github.com/caos/zitadel/internal/v2/repository/iam"
)
@ -10,11 +12,12 @@ type IAMPasswordComplexityPolicyWriteModel struct {
PasswordComplexityPolicyWriteModel
}
func NewIAMPasswordComplexityPolicyWriteModel(iamID string) *IAMPasswordComplexityPolicyWriteModel {
func NewIAMPasswordComplexityPolicyWriteModel() *IAMPasswordComplexityPolicyWriteModel {
return &IAMPasswordComplexityPolicyWriteModel{
PasswordComplexityPolicyWriteModel{
WriteModel: eventstore.WriteModel{
AggregateID: iamID,
AggregateID: domain.IAMID,
ResourceOwner: domain.IAMID,
},
},
}
@ -37,7 +40,8 @@ func (wm *IAMPasswordComplexityPolicyWriteModel) Reduce() error {
func (wm *IAMPasswordComplexityPolicyWriteModel) Query() *eventstore.SearchQueryBuilder {
return eventstore.NewSearchQueryBuilder(eventstore.ColumnsEvent, iam.AggregateType).
AggregateIDs(wm.PasswordComplexityPolicyWriteModel.AggregateID)
AggregateIDs(wm.PasswordComplexityPolicyWriteModel.AggregateID).
ResourceOwner(wm.ResourceOwner)
}
func (wm *IAMPasswordComplexityPolicyWriteModel) NewChangedEvent(

View File

@ -9,8 +9,7 @@ import (
)
func (r *CommandSide) AddDefaultPasswordLockoutPolicy(ctx context.Context, policy *domain.PasswordLockoutPolicy) (*domain.PasswordLockoutPolicy, error) {
policy.AggregateID = r.iamID
addedPolicy := NewIAMPasswordLockoutPolicyWriteModel(policy.AggregateID)
addedPolicy := NewIAMPasswordLockoutPolicyWriteModel()
iamAgg := IAMAggregateFromWriteModel(&addedPolicy.WriteModel)
err := r.addDefaultPasswordLockoutPolicy(ctx, nil, addedPolicy, policy)
if err != nil {
@ -40,8 +39,7 @@ func (r *CommandSide) addDefaultPasswordLockoutPolicy(ctx context.Context, iamAg
}
func (r *CommandSide) ChangeDefaultPasswordLockoutPolicy(ctx context.Context, policy *domain.PasswordLockoutPolicy) (*domain.PasswordLockoutPolicy, error) {
policy.AggregateID = r.iamID
existingPolicy, err := r.defaultPasswordLockoutPolicyWriteModelByID(ctx, policy.AggregateID)
existingPolicy, err := r.defaultPasswordLockoutPolicyWriteModelByID(ctx)
if err != nil {
return nil, err
}
@ -65,11 +63,11 @@ func (r *CommandSide) ChangeDefaultPasswordLockoutPolicy(ctx context.Context, po
return writeModelToPasswordLockoutPolicy(existingPolicy), nil
}
func (r *CommandSide) defaultPasswordLockoutPolicyWriteModelByID(ctx context.Context, iamID string) (policy *IAMPasswordLockoutPolicyWriteModel, err error) {
func (r *CommandSide) defaultPasswordLockoutPolicyWriteModelByID(ctx context.Context) (policy *IAMPasswordLockoutPolicyWriteModel, err error) {
ctx, span := tracing.NewSpan(ctx)
defer func() { span.EndWithError(err) }()
writeModel := NewIAMPasswordLockoutPolicyWriteModel(iamID)
writeModel := NewIAMPasswordLockoutPolicyWriteModel()
err = r.eventstore.FilterToQueryReducer(ctx, writeModel)
if err != nil {
return nil, err

View File

@ -2,7 +2,9 @@ package command
import (
"context"
"github.com/caos/zitadel/internal/eventstore/v2"
"github.com/caos/zitadel/internal/v2/domain"
"github.com/caos/zitadel/internal/v2/repository/iam"
)
@ -10,11 +12,12 @@ type IAMPasswordLockoutPolicyWriteModel struct {
PasswordLockoutPolicyWriteModel
}
func NewIAMPasswordLockoutPolicyWriteModel(iamID string) *IAMPasswordLockoutPolicyWriteModel {
func NewIAMPasswordLockoutPolicyWriteModel() *IAMPasswordLockoutPolicyWriteModel {
return &IAMPasswordLockoutPolicyWriteModel{
PasswordLockoutPolicyWriteModel{
WriteModel: eventstore.WriteModel{
AggregateID: iamID,
AggregateID: domain.IAMID,
ResourceOwner: domain.IAMID,
},
},
}
@ -37,7 +40,8 @@ func (wm *IAMPasswordLockoutPolicyWriteModel) Reduce() error {
func (wm *IAMPasswordLockoutPolicyWriteModel) Query() *eventstore.SearchQueryBuilder {
return eventstore.NewSearchQueryBuilder(eventstore.ColumnsEvent, iam.AggregateType).
AggregateIDs(wm.PasswordLockoutPolicyWriteModel.AggregateID)
AggregateIDs(wm.PasswordLockoutPolicyWriteModel.AggregateID).
ResourceOwner(wm.ResourceOwner)
}
func (wm *IAMPasswordLockoutPolicyWriteModel) NewChangedEvent(ctx context.Context, maxAttempts uint64, showLockoutFailure bool) (*iam.PasswordLockoutPolicyChangedEvent, bool) {

View File

@ -32,7 +32,7 @@ func (r *CommandSide) setUpOrg(ctx context.Context, organisation *domain.Org, ad
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?
err = r.addOrgMember(ctx, orgMemberAgg, addedMember, domain.NewMember(orgMemberAgg.ID(), userAgg.ID(), domain.RoleOrgOwner))
if err != nil {
return nil, nil, nil, err
}

View File

@ -22,7 +22,8 @@ type OrgDomainWriteModel struct {
func NewOrgDomainWriteModel(orgID string, domain string) *OrgDomainWriteModel {
return &OrgDomainWriteModel{
WriteModel: eventstore.WriteModel{
AggregateID: orgID,
AggregateID: orgID,
ResourceOwner: orgID,
},
Domain: domain,
}
@ -86,5 +87,6 @@ func (wm *OrgDomainWriteModel) Reduce() error {
func (wm *OrgDomainWriteModel) Query() *eventstore.SearchQueryBuilder {
return eventstore.NewSearchQueryBuilder(eventstore.ColumnsEvent, org.AggregateType).
AggregateIDs(wm.AggregateID)
AggregateIDs(wm.AggregateID).
ResourceOwner(wm.ResourceOwner)
}

View File

@ -13,7 +13,8 @@ func NewOrgMemberWriteModel(orgID, userID string) *OrgMemberWriteModel {
return &OrgMemberWriteModel{
MemberWriteModel{
WriteModel: eventstore.WriteModel{
AggregateID: orgID,
AggregateID: orgID,
ResourceOwner: orgID,
},
UserID: userID,
},
@ -48,5 +49,6 @@ func (wm *OrgMemberWriteModel) Reduce() error {
func (wm *OrgMemberWriteModel) Query() *eventstore.SearchQueryBuilder {
return eventstore.NewSearchQueryBuilder(eventstore.ColumnsEvent, org.AggregateType).
AggregateIDs(wm.MemberWriteModel.AggregateID)
AggregateIDs(wm.MemberWriteModel.AggregateID).
ResourceOwner(wm.ResourceOwner)
}

View File

@ -17,7 +17,8 @@ type OrgWriteModel struct {
func NewOrgWriteModel(orgID string) *OrgWriteModel {
return &OrgWriteModel{
WriteModel: eventstore.WriteModel{
AggregateID: orgID,
AggregateID: orgID,
ResourceOwner: orgID,
},
}
}
@ -48,7 +49,8 @@ func (wm *OrgWriteModel) Reduce() error {
func (wm *OrgWriteModel) Query() *eventstore.SearchQueryBuilder {
return eventstore.NewSearchQueryBuilder(eventstore.ColumnsEvent, org.AggregateType).
AggregateIDs(wm.AggregateID)
AggregateIDs(wm.AggregateID).
ResourceOwner(wm.ResourceOwner)
}
func OrgAggregateFromWriteModel(wm *eventstore.WriteModel) *org.Aggregate {

View File

@ -2,6 +2,7 @@ package command
import (
"context"
"github.com/caos/zitadel/internal/eventstore/v2"
"github.com/caos/zitadel/internal/v2/repository/org"
)
@ -14,7 +15,8 @@ func NewORGOrgIAMPolicyWriteModel(orgID string) *ORGOrgIAMPolicyWriteModel {
return &ORGOrgIAMPolicyWriteModel{
PolicyOrgIAMWriteModel{
WriteModel: eventstore.WriteModel{
AggregateID: orgID,
AggregateID: orgID,
ResourceOwner: orgID,
},
},
}
@ -37,7 +39,8 @@ func (wm *ORGOrgIAMPolicyWriteModel) Reduce() error {
func (wm *ORGOrgIAMPolicyWriteModel) Query() *eventstore.SearchQueryBuilder {
return eventstore.NewSearchQueryBuilder(eventstore.ColumnsEvent, org.AggregateType).
AggregateIDs(wm.PolicyOrgIAMWriteModel.AggregateID)
AggregateIDs(wm.PolicyOrgIAMWriteModel.AggregateID).
ResourceOwner(wm.ResourceOwner)
}
func (wm *ORGOrgIAMPolicyWriteModel) NewChangedEvent(ctx context.Context, userLoginMustBeDomain bool) (*org.OrgIAMPolicyChangedEvent, bool) {

View File

@ -2,6 +2,7 @@ package command
import (
"context"
"github.com/caos/zitadel/internal/eventstore/v2"
"github.com/caos/zitadel/internal/v2/repository/org"
)
@ -10,11 +11,12 @@ type OrgPasswordComplexityPolicyWriteModel struct {
PasswordComplexityPolicyWriteModel
}
func NewOrgPasswordComplexityPolicyWriteModel(iamID string) *OrgPasswordComplexityPolicyWriteModel {
func NewOrgPasswordComplexityPolicyWriteModel(orgID string) *OrgPasswordComplexityPolicyWriteModel {
return &OrgPasswordComplexityPolicyWriteModel{
PasswordComplexityPolicyWriteModel{
WriteModel: eventstore.WriteModel{
AggregateID: iamID,
AggregateID: orgID,
ResourceOwner: orgID,
},
},
}
@ -37,7 +39,8 @@ func (wm *OrgPasswordComplexityPolicyWriteModel) Reduce() error {
func (wm *OrgPasswordComplexityPolicyWriteModel) Query() *eventstore.SearchQueryBuilder {
return eventstore.NewSearchQueryBuilder(eventstore.ColumnsEvent, org.AggregateType).
AggregateIDs(wm.PasswordComplexityPolicyWriteModel.AggregateID)
AggregateIDs(wm.PasswordComplexityPolicyWriteModel.AggregateID).
ResourceOwner(wm.ResourceOwner)
}
func (wm *OrgPasswordComplexityPolicyWriteModel) NewChangedEvent(

View File

@ -0,0 +1,65 @@
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/project"
)
func (r *CommandSide) AddProject(ctx context.Context, project *domain.Project, resourceOwner, ownerUserID string) (_ *domain.Project, err error) {
projectAgg, addedProject, err := r.addProject(ctx, project, resourceOwner, ownerUserID)
if err != nil {
return nil, err
}
err = r.eventstore.PushAggregate(ctx, addedProject, projectAgg)
if err != nil {
return nil, err
}
return projectWriteModelToProject(addedProject), nil
}
func (r *CommandSide) addProject(ctx context.Context, projectAdd *domain.Project, resourceOwner, ownerUserID string) (_ *project.Aggregate, _ *ProjectWriteModel, err error) {
if !projectAdd.IsValid() {
return nil, nil, caos_errs.ThrowPreconditionFailed(nil, "PROJECT-IOVCC", "Errors.Project.Invalid")
}
projectAdd.AggregateID, err = r.idGenerator.Next()
if err != nil {
return nil, nil, err
}
// TODO: Add uniqueness check
addedProject := NewProjectWriteModel(projectAdd.AggregateID, resourceOwner)
projectAgg := ProjectAggregateFromWriteModel(&addedProject.WriteModel)
projectRole := domain.RoleOrgOwner
//if global { //TODO: !
// projectRole = domain.RoleProjectOwnerGlobal
//}
projectAgg.PushEvents(
project.NewProjectAddedEvent(ctx, projectAdd.Name),
project.NewMemberAddedEvent(ctx, ownerUserID, projectRole),
)
return projectAgg, addedProject, nil
}
func (r *CommandSide) getProjectByID(ctx context.Context, projectID, resourceOwner string) (*domain.Project, error) {
projectWriteModel, err := r.getProjectWriteModelByID(ctx, projectID, resourceOwner)
if err != nil {
return nil, err
}
if projectWriteModel.State == domain.ProjectStateUnspecified || projectWriteModel.State == domain.ProjectStateRemoved {
return nil, caos_errs.ThrowNotFound(nil, "PROJECT-Gd2hh", "Errors.Project.NotFound")
}
return projectWriteModelToProject(projectWriteModel), nil
}
func (r *CommandSide) getProjectWriteModelByID(ctx context.Context, projectID, resourceOwner string) (*ProjectWriteModel, error) {
projectWriteModel := NewProjectWriteModel(projectID, resourceOwner)
err := r.eventstore.FilterToQueryReducer(ctx, projectWriteModel)
if err != nil {
return nil, err
}
return projectWriteModel, nil
}

View File

@ -0,0 +1,73 @@
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/project"
)
func (r *CommandSide) AddApplication(ctx context.Context, application *domain.Application, resourceOwner string) (_ *domain.Application, err error) {
project, err := r.getProjectByID(ctx, application.AggregateID, resourceOwner)
if err != nil {
return nil, err
}
addedApplication := NewApplicationWriteModel(application.AggregateID, resourceOwner)
projectAgg := ProjectAggregateFromWriteModel(&addedApplication.WriteModel)
err = r.addApplication(ctx, projectAgg, project, application)
if err != nil {
return nil, err
}
err = r.eventstore.PushAggregate(ctx, addedApplication, projectAgg)
if err != nil {
return nil, err
}
return applicationWriteModelToApplication(addedApplication), nil
}
func (r *CommandSide) addApplication(ctx context.Context, projectAgg *project.Aggregate, proj *domain.Project, application *domain.Application) (err error) {
if !application.IsValid(true) {
return caos_errs.ThrowPreconditionFailed(nil, "PROJECT-Bff2g", "Errors.Application.Invalid")
}
application.AppID, err = r.idGenerator.Next()
if err != nil {
return err
}
projectAgg.PushEvents(project.NewApplicationAddedEvent(ctx, application.AppID, application.Name, application.Type))
var stringPw string
if application.OIDCConfig != nil {
application.OIDCConfig.AppID = application.AppID
err = application.OIDCConfig.GenerateNewClientID(r.idGenerator, proj)
if err != nil {
return err
}
stringPw, err = application.OIDCConfig.GenerateClientSecretIfNeeded(r.applicationSecretGenerator)
if err != nil {
return err
}
projectAgg.PushEvents(project.NewOIDCConfigAddedEvent(ctx,
application.OIDCConfig.OIDCVersion,
application.OIDCConfig.AppID,
application.OIDCConfig.ClientID,
application.OIDCConfig.ClientSecret,
application.OIDCConfig.RedirectUris,
application.OIDCConfig.ResponseTypes,
application.OIDCConfig.GrantTypes,
application.OIDCConfig.ApplicationType,
application.OIDCConfig.AuthMethodType,
application.OIDCConfig.PostLogoutRedirectUris,
application.OIDCConfig.DevMode,
application.OIDCConfig.AccessTokenType,
application.OIDCConfig.AccessTokenRoleAssertion,
application.OIDCConfig.IDTokenRoleAssertion,
application.OIDCConfig.IDTokenUserinfoAssertion,
application.OIDCConfig.ClockSkew))
}
_ = stringPw
return nil
}

View File

@ -0,0 +1,55 @@
package command
import (
"github.com/caos/zitadel/internal/eventstore/v2"
"github.com/caos/zitadel/internal/v2/domain"
"github.com/caos/zitadel/internal/v2/repository/project"
)
type ApplicationWriteModel struct {
eventstore.WriteModel
AppID string
State domain.AppState
Name string
Type domain.AppType
OIDCConfig *domain.OIDCConfig
}
func NewApplicationWriteModel(projectID, resourceOwner string) *ApplicationWriteModel {
return &ApplicationWriteModel{
WriteModel: eventstore.WriteModel{
AggregateID: projectID,
ResourceOwner: resourceOwner,
},
}
}
func (wm *ApplicationWriteModel) AppendEvents(events ...eventstore.EventReader) {
wm.WriteModel.AppendEvents(events...)
for _, event := range events {
switch e := event.(type) {
case *project.ApplicationAddedEvent:
wm.WriteModel.AppendEvents(e)
}
}
}
func (wm *ApplicationWriteModel) Reduce() error {
for _, event := range wm.Events {
switch e := event.(type) {
case *project.ApplicationAddedEvent:
wm.Name = e.Name
wm.State = domain.AppStateActive
//case *project.ApplicationChangedEvent:
// wm.Name = e.Name
}
}
return nil
}
func (wm *ApplicationWriteModel) Query() *eventstore.SearchQueryBuilder {
return eventstore.NewSearchQueryBuilder(eventstore.ColumnsEvent, project.AggregateType).
AggregateIDs(wm.AggregateID).
ResourceOwner(wm.ResourceOwner)
}

View File

@ -0,0 +1,25 @@
package command
import (
"github.com/caos/zitadel/internal/v2/domain"
)
func projectWriteModelToProject(writeModel *ProjectWriteModel) *domain.Project {
return &domain.Project{
ObjectRoot: writeModelToObjectRoot(writeModel.WriteModel),
Name: writeModel.Name,
ProjectRoleAssertion: writeModel.ProjectRoleAssertion,
ProjectRoleCheck: writeModel.ProjectRoleCheck,
}
}
func applicationWriteModelToApplication(writeModel *ApplicationWriteModel) *domain.Application {
return &domain.Application{
ObjectRoot: writeModelToObjectRoot(writeModel.WriteModel),
AppID: writeModel.AggregateID,
State: writeModel.State,
Name: writeModel.Name,
Type: writeModel.Type,
//TODO: OIDC Config
}
}

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/project"
)
func (r *CommandSide) AddProjectMember(ctx context.Context, member *domain.Member, resourceOwner string) (*domain.Member, error) {
addedMember := NewProjectMemberWriteModel(member.AggregateID, member.UserID, resourceOwner)
projectAgg := ProjectAggregateFromWriteModel(&addedMember.WriteModel)
err := r.addProjectMember(ctx, projectAgg, addedMember, member)
if err != nil {
return nil, err
}
err = r.eventstore.PushAggregate(ctx, addedMember, projectAgg)
if err != nil {
return nil, err
}
return memberWriteModelToMember(&addedMember.MemberWriteModel), nil
}
func (r *CommandSide) addProjectMember(ctx context.Context, projectAgg *project.Aggregate, addedMember *ProjectMemberWriteModel, member *domain.Member) error {
//TODO: check if roles valid
if !member.IsValid() {
return caos_errs.ThrowPreconditionFailed(nil, "PROJECT-W8m4l", "Errors.Project.MemberInvalid")
}
err := r.eventstore.FilterToQueryReducer(ctx, addedMember)
if err != nil {
return err
}
if addedMember.State == domain.MemberStateActive {
return errors.ThrowAlreadyExists(nil, "PROJECT-PtXi1", "Errors.Project.Member.AlreadyExists")
}
projectAgg.PushEvents(project.NewMemberAddedEvent(ctx, member.UserID, member.Roles...))
return nil
}
//ChangeProjectMember updates an existing member
func (r *CommandSide) ChangeProjectMember(ctx context.Context, member *domain.Member, resourceOwner string) (*domain.Member, error) {
//TODO: check if roles valid
if !member.IsValid() {
return nil, caos_errs.ThrowPreconditionFailed(nil, "PROJECT-LiaZi", "Errors.Project.MemberInvalid")
}
existingMember, err := r.projectMemberWriteModelByID(ctx, member.AggregateID, member.UserID, resourceOwner)
if err != nil {
return nil, err
}
if reflect.DeepEqual(existingMember.Roles, member.Roles) {
return nil, caos_errs.ThrowPreconditionFailed(nil, "PROJECT-LiaZi", "Errors.Project.Member.RolesNotChanged")
}
projectAgg := ProjectAggregateFromWriteModel(&existingMember.MemberWriteModel.WriteModel)
projectAgg.PushEvents(project.NewMemberChangedEvent(ctx, member.UserID, member.Roles...))
events, err := r.eventstore.PushAggregates(ctx, projectAgg)
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) RemoveProjectMember(ctx context.Context, projectID, userID, resourceOwner string) error {
m, err := r.projectMemberWriteModelByID(ctx, projectID, userID, resourceOwner)
if err != nil && !errors.IsNotFound(err) {
return err
}
if errors.IsNotFound(err) {
return nil
}
projectAgg := ProjectAggregateFromWriteModel(&m.MemberWriteModel.WriteModel)
projectAgg.PushEvents(project.NewMemberRemovedEvent(ctx, userID))
return r.eventstore.PushAggregate(ctx, m, projectAgg)
}
func (r *CommandSide) projectMemberWriteModelByID(ctx context.Context, projectID, userID, resourceOwner string) (member *ProjectMemberWriteModel, err error) {
ctx, span := tracing.NewSpan(ctx)
defer func() { span.EndWithError(err) }()
writeModel := NewProjectMemberWriteModel(projectID, userID, resourceOwner)
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, "PROJECT-D8JxR", "Errors.NotFound")
}
return writeModel, nil
}

View File

@ -0,0 +1,54 @@
package command
import (
"github.com/caos/zitadel/internal/eventstore/v2"
"github.com/caos/zitadel/internal/v2/repository/project"
)
type ProjectMemberWriteModel struct {
MemberWriteModel
}
func NewProjectMemberWriteModel(projectID, userID, resourceOwner string) *ProjectMemberWriteModel {
return &ProjectMemberWriteModel{
MemberWriteModel{
WriteModel: eventstore.WriteModel{
AggregateID: projectID,
ResourceOwner: resourceOwner,
},
UserID: userID,
},
}
}
func (wm *ProjectMemberWriteModel) AppendEvents(events ...eventstore.EventReader) {
for _, event := range events {
switch e := event.(type) {
case *project.MemberAddedEvent:
if e.UserID != wm.MemberWriteModel.UserID {
continue
}
wm.MemberWriteModel.AppendEvents(&e.MemberAddedEvent)
case *project.MemberChangedEvent:
if e.UserID != wm.MemberWriteModel.UserID {
continue
}
wm.MemberWriteModel.AppendEvents(&e.MemberChangedEvent)
case *project.MemberRemovedEvent:
if e.UserID != wm.MemberWriteModel.UserID {
continue
}
wm.MemberWriteModel.AppendEvents(&e.MemberRemovedEvent)
}
}
}
func (wm *ProjectMemberWriteModel) Reduce() error {
return wm.MemberWriteModel.Reduce()
}
func (wm *ProjectMemberWriteModel) Query() *eventstore.SearchQueryBuilder {
return eventstore.NewSearchQueryBuilder(eventstore.ColumnsEvent, project.AggregateType).
AggregateIDs(wm.MemberWriteModel.AggregateID).
ResourceOwner(wm.ResourceOwner)
}

View File

@ -0,0 +1,60 @@
package command
import (
"github.com/caos/zitadel/internal/eventstore/v2"
"github.com/caos/zitadel/internal/v2/domain"
"github.com/caos/zitadel/internal/v2/repository/project"
)
type ProjectWriteModel struct {
eventstore.WriteModel
Name string
ProjectRoleAssertion bool
ProjectRoleCheck bool
State domain.ProjectState
}
func NewProjectWriteModel(projectID string, resourceOwner string) *ProjectWriteModel {
return &ProjectWriteModel{
WriteModel: eventstore.WriteModel{
AggregateID: projectID,
ResourceOwner: resourceOwner,
},
}
}
func (wm *ProjectWriteModel) AppendEvents(events ...eventstore.EventReader) {
wm.WriteModel.AppendEvents(events...)
for _, event := range events {
switch e := event.(type) {
case *project.ProjectAddedEvent:
wm.WriteModel.AppendEvents(e)
}
}
}
func (wm *ProjectWriteModel) Reduce() error {
for _, event := range wm.Events {
switch e := event.(type) {
case *project.ProjectAddedEvent:
wm.Name = e.Name
wm.State = domain.ProjectStateActive
//case *project.ProjectChangedEvent:
// wm.Name = e.Name
}
}
return nil
}
func (wm *ProjectWriteModel) Query() *eventstore.SearchQueryBuilder {
return eventstore.NewSearchQueryBuilder(eventstore.ColumnsEvent, project.AggregateType).
AggregateIDs(wm.AggregateID).
ResourceOwner(wm.ResourceOwner)
}
func ProjectAggregateFromWriteModel(wm *eventstore.WriteModel) *project.Aggregate {
return &project.Aggregate{
Aggregate: *eventstore.AggregateFromWriteModel(wm, project.AggregateType, project.AggregateVersion),
}
}

View File

@ -22,7 +22,7 @@ const (
)
func (r *CommandSide) ExecuteSetupSteps(ctx context.Context, steps []Step) error {
iam, err := r.GetIAM(ctx, r.iamID)
iam, err := r.GetIAM(ctx)
if err != nil && !caos_errs.IsNotFound(err) {
return err
}
@ -32,13 +32,13 @@ func (r *CommandSide) ExecuteSetupSteps(ctx context.Context, steps []Step) error
}
if iam == nil {
iam = &domain.IAM{ObjectRoot: models.ObjectRoot{AggregateID: r.iamID}}
iam = &domain.IAM{ObjectRoot: models.ObjectRoot{}}
}
ctx = setSetUpContextData(ctx, r.iamID)
ctx = setSetUpContextData(ctx)
for _, step := range steps {
iam, err = r.StartSetup(ctx, r.iamID, step.Step())
iam, err = r.StartSetup(ctx, step.Step())
if err != nil {
return err
}
@ -51,12 +51,12 @@ func (r *CommandSide) ExecuteSetupSteps(ctx context.Context, steps []Step) error
return nil
}
func setSetUpContextData(ctx context.Context, orgID string) context.Context {
return authz.SetCtxData(ctx, authz.CtxData{UserID: SetupUser, OrgID: orgID})
func setSetUpContextData(ctx context.Context) context.Context {
return authz.SetCtxData(ctx, authz.CtxData{UserID: SetupUser})
}
func (r *CommandSide) StartSetup(ctx context.Context, iamID string, step domain.Step) (*domain.IAM, error) {
iamWriteModel, err := r.iamByID(ctx, iamID)
func (r *CommandSide) StartSetup(ctx context.Context, step domain.Step) (*domain.IAM, error) {
iamWriteModel, err := r.getIAMWriteModel(ctx)
if err != nil && !caos_errs.IsNotFound(err) {
return nil, err
}
@ -68,11 +68,12 @@ func (r *CommandSide) StartSetup(ctx context.Context, iamID string, step domain.
if err != nil {
return nil, caos_errs.ThrowPreconditionFailed(nil, "EVENT-Grgh1", "Setup start failed")
}
logging.LogWithFields("SETUP-fhh21", "step", step).Info("setup step started")
return writeModelToIAM(iamWriteModel), nil
}
func (r *CommandSide) setup(ctx context.Context, step Step, iamAggregateProvider func(*IAMWriteModel) (*iam_repo.Aggregate, error)) error {
iam, err := r.iamByID(ctx, r.iamID)
iam, err := r.getIAMWriteModel(ctx)
if err != nil && !caos_errs.IsNotFound(err) {
return err
}
@ -89,44 +90,6 @@ func (r *CommandSide) setup(ctx context.Context, step Step, iamAggregateProvider
if err != nil {
return caos_errs.ThrowPreconditionFailedf(nil, "EVENT-dbG31", "Setup %s failed", step.Step())
}
logging.LogWithFields("SETUP-Sg1t1", "step", step.Step()).Info("setup step done")
return nil
}
//func (r *CommandSide) setupDone(ctx context.Context, iamAgg *iam_repo.Aggregate, event eventstore.EventPusher, aggregates ...eventstore.Aggregater) error {
// aggregate := iamAgg.PushEvents(event)
//
// aggregates = append(aggregates, aggregate)
// _, err := r.eventstore.PushAggregates(ctx, aggregates...)
// if err != nil {
// return caos_errs.ThrowPreconditionFailed(nil, "EVENT-Dgd2", "Setup done failed")
// }
// return nil
//}
//
////TODO: should not use readmodel
//func (r *CommandSide) setup(ctx context.Context, iamID string, step iam_repo.Step, event eventstore.EventPusher) (*iam_model.IAM, error) {
// iam, err := r.iamByID(ctx, iamID)
// if err != nil && !caos_errs.IsNotFound(err) {
// return nil, err
// }
//
// if iam != nil && (iam.SetUpStarted >= iam_repo.Step(step) || iam.SetUpStarted != iam.SetUpDone) {
// return nil, caos_errs.ThrowPreconditionFailed(nil, "EVENT-9so34", "setup error")
// }
//
// aggregate := query.AggregateFromReadModel(iam).
// PushEvents(event)
//
// events, err := r.eventstore.PushAggregates(ctx, aggregate)
// if err != nil {
// return nil, err
// }
//
// if err = iam.AppendAndReduce(events...); err != nil {
// return nil, err
// }
// return nil, nil
// //TODO: return write model
// //return readModelToIAM(iam), nil
//}

View File

@ -3,24 +3,36 @@ package command
import (
"context"
"github.com/caos/logging"
caos_errs "github.com/caos/zitadel/internal/errors"
"github.com/caos/zitadel/internal/eventstore/models"
"github.com/caos/zitadel/internal/eventstore/v2"
"github.com/caos/zitadel/internal/v2/domain"
iam_repo "github.com/caos/zitadel/internal/v2/repository/iam"
"github.com/caos/zitadel/internal/v2/repository/project"
)
const (
OIDCResponseTypeCode = "CODE"
OIDCResponseTypeIDToken = "ID_TOKEN"
OIDCResponseTypeToken = "ID_TOKEN TOKEN"
OIDCGrantTypeAuthorizationCode = "AUTHORIZATION_CODE"
OIDCGrantTypeImplicit = "IMPLICIT"
OIDCGrantTypeRefreshToken = "REFRESH_TOKEN"
OIDCApplicationTypeNative = "NATIVE"
OIDCApplicationTypeUserAgent = "USER_AGENT"
OIDCApplicationTypeWeb = "WEB"
OIDCAuthMethodTypeNone = "NONE"
OIDCAuthMethodTypeBasic = "BASIC"
OIDCAuthMethodTypePost = "POST"
)
type Step1 struct {
GlobalOrg string
IAMProject string
DefaultLoginPolicy LoginPolicy //*iam_model.LoginPolicy
DefaultLoginPolicy LoginPolicy
Orgs []Org
Owners []string
//setup *Setup
//createdUsers map[string]*usr_model.User
//createdOrgs map[string]*org_model.Org
//createdProjects map[string]*proj_model.Project
//pwComplexityPolicy *iam_model.PasswordComplexityPolicyView
}
func (s *Step1) Step() domain.Step {
@ -28,7 +40,7 @@ func (s *Step1) Step() domain.Step {
}
func (s *Step1) execute(ctx context.Context, commandSide *CommandSide) error {
return commandSide.SetupStep1(ctx, commandSide.iamID, s)
return commandSide.SetupStep1(ctx, s)
}
type LoginPolicy struct {
@ -71,10 +83,11 @@ type OIDCApp struct {
DevMode bool
}
func (r *CommandSide) SetupStep1(ctx context.Context, iamID string, step1 *Step1) error {
iamAgg := iam_repo.NewAggregate(r.iamID, "", 0)
func (r *CommandSide) SetupStep1(ctx context.Context, step1 *Step1) error {
iamWriteModel := NewIAMWriteModel()
iamAgg := IAMAggregateFromWriteModel(&iamWriteModel.WriteModel)
//create default login policy
err := r.addDefaultLoginPolicy(ctx, iamAgg, NewIAMLoginPolicyWriteModel(iamAgg.ID()),
err := r.addDefaultLoginPolicy(ctx, iamAgg, NewIAMLoginPolicyWriteModel(),
&domain.LoginPolicy{
AllowUsernamePassword: step1.DefaultLoginPolicy.AllowUsernamePassword,
AllowRegister: step1.DefaultLoginPolicy.AllowRegister,
@ -83,6 +96,7 @@ func (r *CommandSide) SetupStep1(ctx context.Context, iamID string, step1 *Step1
if err != nil {
return err
}
logging.Log("SETUP-sd2hj").Info("default login policy set up")
//create orgs
aggregates := make([]eventstore.Aggregater, 0)
for _, organisation := range step1.Orgs {
@ -110,6 +124,8 @@ func (r *CommandSide) SetupStep1(ctx context.Context, iamID string, step1 *Step1
if err != nil {
return err
}
logging.LogWithFields("SETUP-Gdsfg", "id", orgAgg.ID(), "name", organisation.Name).Info("org set up")
if organisation.OrgIamPolicy {
err = r.addOrgIAMPolicy(ctx, orgAgg, NewORGOrgIAMPolicyWriteModel(orgAgg.ID()), &domain.OrgIAMPolicy{UserLoginMustBeDomain: false})
if err != nil {
@ -117,24 +133,43 @@ func (r *CommandSide) SetupStep1(ctx context.Context, iamID string, step1 *Step1
}
}
aggregates = append(aggregates, orgAgg, userAgg, orgMemberAgg)
if organisation.Name == step1.GlobalOrg {
err = r.setGlobalOrg(ctx, iamAgg, iamWriteModel, orgAgg.ID())
if err != nil {
return err
}
logging.Log("SETUP-BDn52").Info("global org set")
}
//projects
//create applications
for _, proj := range organisation.Projects {
project := &domain.Project{Name: proj.Name}
projectAgg, _, err := r.addProject(ctx, project, orgAgg.ID(), userAgg.ID())
if err != nil {
return err
}
if project.Name == step1.IAMProject {
err = r.setIAMProject(ctx, iamAgg, iamWriteModel, projectAgg.ID())
if err != nil {
return err
}
logging.Log("SETUP-Bdfs1").Info("IAM project set")
err = r.addIAMMember(ctx, iamAgg, NewIAMMemberWriteModel(userAgg.ID()), domain.NewMember(iamAgg.ID(), userAgg.ID(), domain.RoleIAMOwner))
if err != nil {
return err
}
logging.Log("SETUP-BSf2h").Info("IAM owner set")
}
//create applications
for _, app := range proj.OIDCApps {
err = setUpApplication(ctx, r, projectAgg, project, app)
if err != nil {
return err
}
}
aggregates = append(aggregates, projectAgg)
}
}
//set iam owners
//set global org
//set iam project id
/*aggregates:
iam:
default login policy
iam owner
org:
default
caos
zitadel
*/
iamAgg.PushEvents(iam_repo.NewSetupStepDoneEvent(ctx, domain.Step1))
_, err = r.eventstore.PushAggregates(ctx, append(aggregates, iamAgg)...)
@ -143,3 +178,91 @@ func (r *CommandSide) SetupStep1(ctx context.Context, iamID string, step1 *Step1
}
return nil
}
func setUpApplication(ctx context.Context, r *CommandSide, projectAgg *project.Aggregate, project *domain.Project, oidcApp OIDCApp) error {
app := &domain.Application{
ObjectRoot: models.ObjectRoot{
AggregateID: projectAgg.ID(),
},
Name: oidcApp.Name,
Type: domain.AppTypeOIDC,
OIDCConfig: &domain.OIDCConfig{
RedirectUris: oidcApp.RedirectUris,
ResponseTypes: getOIDCResponseTypes(oidcApp.ResponseTypes),
GrantTypes: getOIDCGrantTypes(oidcApp.GrantTypes),
ApplicationType: getOIDCApplicationType(oidcApp.ApplicationType),
AuthMethodType: getOIDCAuthMethod(oidcApp.AuthMethodType),
DevMode: oidcApp.DevMode,
},
}
err := r.addApplication(ctx, projectAgg, project, app)
if err != nil {
return err
}
logging.LogWithFields("SETUP-Edgw4", "name", app.Name, "clientID", app.OIDCConfig.ClientID).Info("application set up")
return nil
}
func getOIDCResponseTypes(responseTypes []string) []domain.OIDCResponseType {
types := make([]domain.OIDCResponseType, len(responseTypes))
for i, t := range responseTypes {
types[i] = getOIDCResponseType(t)
}
return types
}
func getOIDCResponseType(responseType string) domain.OIDCResponseType {
switch responseType {
case OIDCResponseTypeCode:
return domain.OIDCResponseTypeCode
case OIDCResponseTypeIDToken:
return domain.OIDCResponseTypeIDToken
case OIDCResponseTypeToken:
return domain.OIDCResponseTypeIDTokenToken
}
return domain.OIDCResponseTypeCode
}
func getOIDCGrantTypes(grantTypes []string) []domain.OIDCGrantType {
types := make([]domain.OIDCGrantType, len(grantTypes))
for i, t := range grantTypes {
types[i] = getOIDCGrantType(t)
}
return types
}
func getOIDCGrantType(grantTypes string) domain.OIDCGrantType {
switch grantTypes {
case OIDCGrantTypeAuthorizationCode:
return domain.OIDCGrantTypeAuthorizationCode
case OIDCGrantTypeImplicit:
return domain.OIDCGrantTypeImplicit
case OIDCGrantTypeRefreshToken:
return domain.OIDCGrantTypeRefreshToken
}
return domain.OIDCGrantTypeAuthorizationCode
}
func getOIDCApplicationType(appType string) domain.OIDCApplicationType {
switch appType {
case OIDCApplicationTypeNative:
return domain.OIDCApplicationTypeNative
case OIDCApplicationTypeUserAgent:
return domain.OIDCApplicationTypeUserAgent
case OIDCApplicationTypeWeb:
return domain.OIDCApplicationTypeWeb
}
return domain.OIDCApplicationTypeWeb
}
func getOIDCAuthMethod(authMethod string) domain.OIDCAuthMethodType {
switch authMethod {
case OIDCAuthMethodTypeNone:
return domain.OIDCAuthMethodTypeNone
case OIDCAuthMethodTypeBasic:
return domain.OIDCAuthMethodTypeBasic
case OIDCAuthMethodTypePost:
return domain.OIDCAuthMethodTypePost
}
return domain.OIDCAuthMethodTypeBasic
}

View File

@ -3,6 +3,8 @@ package command
import (
"context"
"github.com/caos/logging"
iam_model "github.com/caos/zitadel/internal/iam/model"
"github.com/caos/zitadel/internal/v2/domain"
iam_repo "github.com/caos/zitadel/internal/v2/repository/iam"
@ -23,7 +25,7 @@ func (s *Step2) execute(ctx context.Context, commandSide *CommandSide) error {
func (r *CommandSide) SetupStep2(ctx context.Context, step *Step2) error {
fn := func(iam *IAMWriteModel) (*iam_repo.Aggregate, error) {
iamAgg := IAMAggregateFromWriteModel(&iam.WriteModel)
err := r.addDefaultPasswordComplexityPolicy(ctx, iamAgg, NewIAMPasswordComplexityPolicyWriteModel(iam.AggregateID), &domain.PasswordComplexityPolicy{
err := r.addDefaultPasswordComplexityPolicy(ctx, iamAgg, NewIAMPasswordComplexityPolicyWriteModel(), &domain.PasswordComplexityPolicy{
MinLength: step.DefaultPasswordComplexityPolicy.MinLength,
HasLowercase: step.DefaultPasswordComplexityPolicy.HasLowercase,
HasUppercase: step.DefaultPasswordComplexityPolicy.HasUppercase,
@ -33,7 +35,8 @@ func (r *CommandSide) SetupStep2(ctx context.Context, step *Step2) error {
if err != nil {
return nil, err
}
return iamAgg, err
logging.Log("SETUP-ADgd2").Info("default password complexity policy set up")
return iamAgg, nil
}
return r.setup(ctx, step, fn)
}

View File

@ -3,6 +3,8 @@ package command
import (
"context"
"github.com/caos/logging"
iam_model "github.com/caos/zitadel/internal/iam/model"
"github.com/caos/zitadel/internal/v2/domain"
iam_repo "github.com/caos/zitadel/internal/v2/repository/iam"
@ -23,13 +25,14 @@ func (s *Step3) execute(ctx context.Context, commandSide *CommandSide) error {
func (r *CommandSide) SetupStep3(ctx context.Context, step *Step3) error {
fn := func(iam *IAMWriteModel) (*iam_repo.Aggregate, error) {
iamAgg := IAMAggregateFromWriteModel(&iam.WriteModel)
err := r.addDefaultPasswordAgePolicy(ctx, iamAgg, NewIAMPasswordAgePolicyWriteModel(iam.AggregateID), &domain.PasswordAgePolicy{
err := r.addDefaultPasswordAgePolicy(ctx, iamAgg, NewIAMPasswordAgePolicyWriteModel(), &domain.PasswordAgePolicy{
MaxAgeDays: step.DefaultPasswordAgePolicy.MaxAgeDays,
ExpireWarnDays: step.DefaultPasswordAgePolicy.ExpireWarnDays,
})
if err != nil {
return nil, err
}
logging.Log("SETUP-DBqgq").Info("default password age policy set up")
return iamAgg, nil
}
return r.setup(ctx, step, fn)

View File

@ -3,6 +3,8 @@ package command
import (
"context"
"github.com/caos/logging"
iam_model "github.com/caos/zitadel/internal/iam/model"
"github.com/caos/zitadel/internal/v2/domain"
iam_repo "github.com/caos/zitadel/internal/v2/repository/iam"
@ -23,13 +25,14 @@ func (s *Step4) execute(ctx context.Context, commandSide *CommandSide) error {
func (r *CommandSide) SetupStep4(ctx context.Context, step *Step4) error {
fn := func(iam *IAMWriteModel) (*iam_repo.Aggregate, error) {
iamAgg := IAMAggregateFromWriteModel(&iam.WriteModel)
err := r.addDefaultPasswordLockoutPolicy(ctx, iamAgg, NewIAMPasswordLockoutPolicyWriteModel(iam.AggregateID), &domain.PasswordLockoutPolicy{
err := r.addDefaultPasswordLockoutPolicy(ctx, iamAgg, NewIAMPasswordLockoutPolicyWriteModel(), &domain.PasswordLockoutPolicy{
MaxAttempts: step.DefaultPasswordLockoutPolicy.MaxAttempts,
ShowLockOutFailures: step.DefaultPasswordLockoutPolicy.ShowLockOutFailures,
})
if err != nil {
return nil, err
}
logging.Log("SETUP-Bfnge").Info("default password lockout policy set up")
return iamAgg, nil
}
return r.setup(ctx, step, fn)

View File

@ -3,6 +3,8 @@ package command
import (
"context"
"github.com/caos/logging"
iam_model "github.com/caos/zitadel/internal/iam/model"
"github.com/caos/zitadel/internal/v2/domain"
iam_repo "github.com/caos/zitadel/internal/v2/repository/iam"
@ -23,12 +25,13 @@ func (s *Step5) execute(ctx context.Context, commandSide *CommandSide) error {
func (r *CommandSide) SetupStep5(ctx context.Context, step *Step5) error {
fn := func(iam *IAMWriteModel) (*iam_repo.Aggregate, error) {
iamAgg := IAMAggregateFromWriteModel(&iam.WriteModel)
err := r.addDefaultOrgIAMPolicy(ctx, iamAgg, NewIAMOrgIAMPolicyWriteModel(iam.AggregateID), &domain.OrgIAMPolicy{
err := r.addDefaultOrgIAMPolicy(ctx, iamAgg, NewIAMOrgIAMPolicyWriteModel(), &domain.OrgIAMPolicy{
UserLoginMustBeDomain: step.DefaultOrgIAMPolicy.UserLoginMustBeDomain,
})
if err != nil {
return nil, err
}
logging.Log("SETUP-ADgd2").Info("default org iam policy set up")
return iamAgg, nil
}
return r.setup(ctx, step, fn)

View File

@ -3,6 +3,8 @@ package command
import (
"context"
"github.com/caos/logging"
iam_model "github.com/caos/zitadel/internal/iam/model"
"github.com/caos/zitadel/internal/v2/domain"
iam_repo "github.com/caos/zitadel/internal/v2/repository/iam"
@ -23,13 +25,14 @@ func (s *Step6) execute(ctx context.Context, commandSide *CommandSide) error {
func (r *CommandSide) SetupStep6(ctx context.Context, step *Step6) error {
fn := func(iam *IAMWriteModel) (*iam_repo.Aggregate, error) {
iamAgg := IAMAggregateFromWriteModel(&iam.WriteModel)
err := r.addDefaultLabelPolicy(ctx, iamAgg, NewIAMLabelPolicyWriteModel(iam.AggregateID), &domain.LabelPolicy{
err := r.addDefaultLabelPolicy(ctx, iamAgg, NewIAMLabelPolicyWriteModel(), &domain.LabelPolicy{
PrimaryColor: step.DefaultLabelPolicy.PrimaryColor,
SecondaryColor: step.DefaultLabelPolicy.SecondaryColor,
})
if err != nil {
return nil, err
}
logging.Log("SETUP-ADgd2").Info("default label policy set up")
return iamAgg, nil
}
return r.setup(ctx, step, fn)

View File

@ -3,6 +3,8 @@ package command
import (
"context"
"github.com/caos/logging"
iam_model "github.com/caos/zitadel/internal/iam/model"
"github.com/caos/zitadel/internal/v2/domain"
iam_repo "github.com/caos/zitadel/internal/v2/repository/iam"
@ -22,7 +24,7 @@ func (s *Step7) execute(ctx context.Context, commandSide *CommandSide) error {
func (r *CommandSide) SetupStep7(ctx context.Context, step *Step7) error {
fn := func(iam *IAMWriteModel) (*iam_repo.Aggregate, error) {
secondFactorModel := NewIAMSecondFactorWriteModel(iam.AggregateID)
secondFactorModel := NewIAMSecondFactorWriteModel()
iamAgg := IAMAggregateFromWriteModel(&secondFactorModel.SecondFactorWriteModel.WriteModel)
if !step.OTP {
return iamAgg, nil
@ -31,6 +33,7 @@ func (r *CommandSide) SetupStep7(ctx context.Context, step *Step7) error {
if err != nil {
return nil, err
}
logging.Log("SETUP-Dggsg").Info("added OTP to 2FA login policy")
return iamAgg, nil
}
return r.setup(ctx, step, fn)

View File

@ -3,6 +3,8 @@ package command
import (
"context"
"github.com/caos/logging"
iam_model "github.com/caos/zitadel/internal/iam/model"
"github.com/caos/zitadel/internal/v2/domain"
iam_repo "github.com/caos/zitadel/internal/v2/repository/iam"
@ -22,7 +24,7 @@ func (s *Step8) execute(ctx context.Context, commandSide *CommandSide) error {
func (r *CommandSide) SetupStep8(ctx context.Context, step *Step8) error {
fn := func(iam *IAMWriteModel) (*iam_repo.Aggregate, error) {
secondFactorModel := NewIAMSecondFactorWriteModel(iam.AggregateID)
secondFactorModel := NewIAMSecondFactorWriteModel()
iamAgg := IAMAggregateFromWriteModel(&secondFactorModel.SecondFactorWriteModel.WriteModel)
if !step.U2F {
return iamAgg, nil
@ -31,6 +33,7 @@ func (r *CommandSide) SetupStep8(ctx context.Context, step *Step8) error {
if err != nil {
return nil, err
}
logging.Log("SETUP-BDhne").Info("added U2F to 2FA login policy")
return iamAgg, nil
}
return r.setup(ctx, step, fn)

View File

@ -3,6 +3,8 @@ package command
import (
"context"
"github.com/caos/logging"
iam_model "github.com/caos/zitadel/internal/iam/model"
"github.com/caos/zitadel/internal/v2/domain"
iam_repo "github.com/caos/zitadel/internal/v2/repository/iam"
@ -22,7 +24,7 @@ func (s *Step9) execute(ctx context.Context, commandSide *CommandSide) error {
func (r *CommandSide) SetupStep9(ctx context.Context, step *Step9) error {
fn := func(iam *IAMWriteModel) (*iam_repo.Aggregate, error) {
multiFactorModel := NewIAMMultiFactorWriteModel(iam.AggregateID)
multiFactorModel := NewIAMMultiFactorWriteModel()
iamAgg := IAMAggregateFromWriteModel(&multiFactorModel.MultiFactoryWriteModel.WriteModel)
if !step.Passwordless {
return iamAgg, nil
@ -31,10 +33,12 @@ func (r *CommandSide) SetupStep9(ctx context.Context, step *Step9) error {
if err != nil {
return nil, err
}
logging.Log("SETUP-AEG2t").Info("allowed passwordless in login policy")
err = r.addMultiFactorToDefaultLoginPolicy(ctx, iamAgg, multiFactorModel, iam_model.MultiFactorTypeU2FWithPIN)
if err != nil {
return nil, err
}
logging.Log("SETUP-ADfng").Info("added passwordless to MFA login policy")
return iamAgg, err
}
return r.setup(ctx, step, fn)
@ -46,5 +50,5 @@ func setPasswordlessAllowedInPolicy(ctx context.Context, c *CommandSide, iamAgg
return err
}
policy.PasswordlessType = domain.PasswordlessTypeAllowed
return c.changeDefaultLoginPolicy(ctx, iamAgg, NewIAMLoginPolicyWriteModel(iamAgg.ID()), policy)
return c.changeDefaultLoginPolicy(ctx, iamAgg, NewIAMLoginPolicyWriteModel(), policy)
}

View File

@ -2,6 +2,7 @@ package command
import (
"context"
caos_errs "github.com/caos/zitadel/internal/errors"
"github.com/caos/zitadel/internal/telemetry/tracing"
"github.com/caos/zitadel/internal/v2/domain"
@ -48,7 +49,7 @@ func (r *CommandSide) ChangeUsername(ctx context.Context, orgID, userID, userNam
if orgID == "" || userID == "" || userName == "" {
return caos_errs.ThrowPreconditionFailed(nil, "COMMAND-2N9fs", "Errors.IDMissing")
}
existingUser, err := r.userWriteModelByID(ctx, userID)
existingUser, err := r.userWriteModelByID(ctx, userID, orgID)
if err != nil {
return err
}
@ -74,11 +75,11 @@ func (r *CommandSide) ChangeUsername(ctx context.Context, orgID, userID, userNam
return r.eventstore.PushAggregate(ctx, existingUser, userAgg)
}
func (r *CommandSide) DeactivateUser(ctx context.Context, userID string) (*domain.User, error) {
func (r *CommandSide) DeactivateUser(ctx context.Context, userID, resourceOwner string) (*domain.User, error) {
if userID == "" {
return nil, caos_errs.ThrowPreconditionFailed(nil, "COMMAND-m0gDf", "Errors.User.UserIDMissing")
}
existingUser, err := r.userWriteModelByID(ctx, userID)
existingUser, err := r.userWriteModelByID(ctx, userID, resourceOwner)
if err != nil {
return nil, err
}
@ -98,11 +99,11 @@ func (r *CommandSide) DeactivateUser(ctx context.Context, userID string) (*domai
return writeModelToUser(existingUser), nil
}
func (r *CommandSide) ReactivateUser(ctx context.Context, userID string) (*domain.User, error) {
func (r *CommandSide) ReactivateUser(ctx context.Context, userID, resourceOwner string) (*domain.User, error) {
if userID == "" {
return nil, caos_errs.ThrowPreconditionFailed(nil, "COMMAND-4M9ds", "Errors.User.UserIDMissing")
}
existingUser, err := r.userWriteModelByID(ctx, userID)
existingUser, err := r.userWriteModelByID(ctx, userID, resourceOwner)
if err != nil {
return nil, err
}
@ -122,11 +123,11 @@ func (r *CommandSide) ReactivateUser(ctx context.Context, userID string) (*domai
return writeModelToUser(existingUser), nil
}
func (r *CommandSide) LockUser(ctx context.Context, userID string) (*domain.User, error) {
func (r *CommandSide) LockUser(ctx context.Context, userID, resourceOwner string) (*domain.User, error) {
if userID == "" {
return nil, caos_errs.ThrowPreconditionFailed(nil, "COMMAND-2M0sd", "Errors.User.UserIDMissing")
}
existingUser, err := r.userWriteModelByID(ctx, userID)
existingUser, err := r.userWriteModelByID(ctx, userID, resourceOwner)
if err != nil {
return nil, err
}
@ -146,11 +147,11 @@ func (r *CommandSide) LockUser(ctx context.Context, userID string) (*domain.User
return writeModelToUser(existingUser), nil
}
func (r *CommandSide) UnlockUser(ctx context.Context, userID string) (*domain.User, error) {
func (r *CommandSide) UnlockUser(ctx context.Context, userID, resourceOwner string) (*domain.User, error) {
if userID == "" {
return nil, caos_errs.ThrowPreconditionFailed(nil, "COMMAND-M0dse", "Errors.User.UserIDMissing")
}
existingUser, err := r.userWriteModelByID(ctx, userID)
existingUser, err := r.userWriteModelByID(ctx, userID, resourceOwner)
if err != nil {
return nil, err
}
@ -170,11 +171,11 @@ func (r *CommandSide) UnlockUser(ctx context.Context, userID string) (*domain.Us
return writeModelToUser(existingUser), nil
}
func (r *CommandSide) RemoveUser(ctx context.Context, userID string) error {
func (r *CommandSide) RemoveUser(ctx context.Context, userID, resourceOwner string) error {
if userID == "" {
return caos_errs.ThrowPreconditionFailed(nil, "COMMAND-2M0ds", "Errors.User.UserIDMissing")
}
existingUser, err := r.userWriteModelByID(ctx, userID)
existingUser, err := r.userWriteModelByID(ctx, userID, resourceOwner)
if err != nil {
return err
}
@ -189,11 +190,11 @@ func (r *CommandSide) RemoveUser(ctx context.Context, userID string) error {
return r.eventstore.PushAggregate(ctx, existingUser, userAgg)
}
func (r *CommandSide) userWriteModelByID(ctx context.Context, userID string) (writeModel *UserWriteModel, err error) {
func (r *CommandSide) userWriteModelByID(ctx context.Context, userID, resourceOwner string) (writeModel *UserWriteModel, err error) {
ctx, span := tracing.NewSpan(ctx)
defer func() { span.EndWithError(err) }()
writeModel = NewUserWriteModel(userID)
writeModel = NewUserWriteModel(userID, resourceOwner)
err = r.eventstore.FilterToQueryReducer(ctx, writeModel)
if err != nil {
return nil, err

View File

@ -39,7 +39,7 @@ func (r *CommandSide) addHuman(ctx context.Context, orgID, username string, huma
return nil, nil, err
}
addedHuman := NewHumanWriteModel(human.AggregateID)
addedHuman := NewHumanWriteModel(human.AggregateID, orgID)
//TODO: Check Unique Username
if err := human.CheckOrgIAMPolicy(username, orgIAMPolicy); err != nil {
return nil, nil, err
@ -118,7 +118,7 @@ func (r *CommandSide) RegisterHuman(ctx context.Context, orgID, username string,
return nil, err
}
addedHuman := NewHumanWriteModel(human.AggregateID)
addedHuman := NewHumanWriteModel(human.AggregateID, orgID)
//TODO: Check Unique Username or unique external idp
if err := human.CheckOrgIAMPolicy(username, orgIAMPolicy); err != nil {
return nil, err
@ -185,12 +185,12 @@ func (r *CommandSide) RegisterHuman(ctx context.Context, orgID, username string,
return writeModelToHuman(addedHuman), nil
}
func (r *CommandSide) ResendInitialMail(ctx context.Context, userID, email string) (err error) {
func (r *CommandSide) ResendInitialMail(ctx context.Context, userID, email, resourceOwner string) (err error) {
if userID == "" {
return caos_errs.ThrowPreconditionFailed(nil, "COMMAND-2M9fs", "Errors.User.UserIDMissing")
}
existingEmail, err := r.emailWriteModel(ctx, userID)
existingEmail, err := r.emailWriteModel(ctx, userID, resourceOwner)
if err != nil {
return err
}

View File

@ -8,7 +8,7 @@ import (
)
func (r *CommandSide) ChangeHumanAddress(ctx context.Context, address *domain.Address) (*domain.Address, error) {
existingAddress, err := r.addressWriteModel(ctx, address.AggregateID)
existingAddress, err := r.addressWriteModel(ctx, address.AggregateID, address.ResourceOwner)
if err != nil {
return nil, err
}
@ -30,11 +30,11 @@ func (r *CommandSide) ChangeHumanAddress(ctx context.Context, address *domain.Ad
return writeModelToAddress(existingAddress), nil
}
func (r *CommandSide) addressWriteModel(ctx context.Context, userID string) (writeModel *HumanAddressWriteModel, err error) {
func (r *CommandSide) addressWriteModel(ctx context.Context, userID, resourceOwner string) (writeModel *HumanAddressWriteModel, err error) {
ctx, span := tracing.NewSpan(ctx)
defer func() { span.EndWithError(err) }()
writeModel = NewHumanAddressWriteModel(userID)
writeModel = NewHumanAddressWriteModel(userID, resourceOwner)
err = r.eventstore.FilterToQueryReducer(ctx, writeModel)
if err != nil {
return nil, err

View File

@ -2,6 +2,7 @@ package command
import (
"context"
"github.com/caos/zitadel/internal/eventstore/v2"
"github.com/caos/zitadel/internal/v2/domain"
"github.com/caos/zitadel/internal/v2/repository/user"
@ -19,10 +20,11 @@ type HumanAddressWriteModel struct {
State domain.AddressState
}
func NewHumanAddressWriteModel(userID string) *HumanAddressWriteModel {
func NewHumanAddressWriteModel(userID, resourceOwner string) *HumanAddressWriteModel {
return &HumanAddressWriteModel{
WriteModel: eventstore.WriteModel{
AggregateID: userID,
AggregateID: userID,
ResourceOwner: resourceOwner,
},
}
}
@ -82,7 +84,8 @@ func (wm *HumanAddressWriteModel) Reduce() error {
func (wm *HumanAddressWriteModel) Query() *eventstore.SearchQueryBuilder {
return eventstore.NewSearchQueryBuilder(eventstore.ColumnsEvent, user.AggregateType).
AggregateIDs(wm.AggregateID)
AggregateIDs(wm.AggregateID).
ResourceOwner(wm.ResourceOwner)
}
func (wm *HumanAddressWriteModel) NewChangedEvent(

View File

@ -13,7 +13,7 @@ func (r *CommandSide) ChangeHumanEmail(ctx context.Context, email *domain.Email)
return nil, caos_errs.ThrowPreconditionFailed(nil, "COMMAND-4M9sf", "Errors.Email.Invalid")
}
existingEmail, err := r.emailWriteModel(ctx, email.AggregateID)
existingEmail, err := r.emailWriteModel(ctx, email.AggregateID, email.ResourceOwner)
if err != nil {
return nil, err
}
@ -45,12 +45,12 @@ func (r *CommandSide) ChangeHumanEmail(ctx context.Context, email *domain.Email)
return writeModelToEmail(existingEmail), nil
}
func (r *CommandSide) CreateHumanEmailVerificationCode(ctx context.Context, userID string) error {
func (r *CommandSide) CreateHumanEmailVerificationCode(ctx context.Context, userID, resourceOwner string) error {
if userID == "" {
return caos_errs.ThrowPreconditionFailed(nil, "COMMAND-4M0ds", "Errors.User.UserIDMissing")
}
existingEmail, err := r.emailWriteModel(ctx, userID)
existingEmail, err := r.emailWriteModel(ctx, userID, resourceOwner)
if err != nil {
return err
}
@ -73,11 +73,11 @@ func (r *CommandSide) CreateHumanEmailVerificationCode(ctx context.Context, user
return r.eventstore.PushAggregate(ctx, existingEmail, userAgg)
}
func (r *CommandSide) emailWriteModel(ctx context.Context, userID string) (writeModel *HumanEmailWriteModel, err error) {
func (r *CommandSide) emailWriteModel(ctx context.Context, userID, resourceOwner string) (writeModel *HumanEmailWriteModel, err error) {
ctx, span := tracing.NewSpan(ctx)
defer func() { span.EndWithError(err) }()
writeModel = NewHumanEmailWriteModel(userID)
writeModel = NewHumanEmailWriteModel(userID, resourceOwner)
err = r.eventstore.FilterToQueryReducer(ctx, writeModel)
if err != nil {
return nil, err

View File

@ -2,6 +2,7 @@ package command
import (
"context"
"github.com/caos/zitadel/internal/eventstore/v2"
"github.com/caos/zitadel/internal/v2/domain"
"github.com/caos/zitadel/internal/v2/repository/user"
@ -16,10 +17,11 @@ type HumanEmailWriteModel struct {
UserState domain.UserState
}
func NewHumanEmailWriteModel(userID string) *HumanEmailWriteModel {
func NewHumanEmailWriteModel(userID, resourceOwner string) *HumanEmailWriteModel {
return &HumanEmailWriteModel{
WriteModel: eventstore.WriteModel{
AggregateID: userID,
AggregateID: userID,
ResourceOwner: resourceOwner,
},
}
}
@ -65,7 +67,8 @@ func (wm *HumanEmailWriteModel) Reduce() error {
func (wm *HumanEmailWriteModel) Query() *eventstore.SearchQueryBuilder {
return eventstore.NewSearchQueryBuilder(eventstore.ColumnsEvent, user.AggregateType).
AggregateIDs(wm.AggregateID)
AggregateIDs(wm.AggregateID).
ResourceOwner(wm.ResourceOwner)
}
func (wm *HumanEmailWriteModel) NewChangedEvent(

View File

@ -17,7 +17,7 @@ func (r *CommandSide) removeHumanExternalIDP(ctx context.Context, externalIDP *d
return caos_errs.ThrowPreconditionFailed(nil, "COMMAND-3M9ds", "Errors.IDMissing")
}
existingExternalIDP, err := r.externalIDPWriteModelByID(ctx, externalIDP.AggregateID, externalIDP.IDPConfigID, externalIDP.ExternalUserID)
existingExternalIDP, err := r.externalIDPWriteModelByID(ctx, externalIDP.AggregateID, externalIDP.IDPConfigID, externalIDP.ExternalUserID, externalIDP.ResourceOwner)
if err != nil {
return err
}
@ -39,11 +39,11 @@ func (r *CommandSide) removeHumanExternalIDP(ctx context.Context, externalIDP *d
return r.eventstore.PushAggregate(ctx, existingExternalIDP, userAgg)
}
func (r *CommandSide) externalIDPWriteModelByID(ctx context.Context, userID, idpConfigID, externalUserID string) (writeModel *HumanExternalIDPWriteModel, err error) {
func (r *CommandSide) externalIDPWriteModelByID(ctx context.Context, userID, idpConfigID, externalUserID, resourceOwner string) (writeModel *HumanExternalIDPWriteModel, err error) {
ctx, span := tracing.NewSpan(ctx)
defer func() { span.EndWithError(err) }()
writeModel = NewHumanExternalIDPWriteModel(userID, idpConfigID, externalUserID)
writeModel = NewHumanExternalIDPWriteModel(userID, idpConfigID, externalUserID, resourceOwner)
err = r.eventstore.FilterToQueryReducer(ctx, writeModel)
if err != nil {
return nil, err

View File

@ -16,10 +16,11 @@ type HumanExternalIDPWriteModel struct {
State domain.ExternalIDPState
}
func NewHumanExternalIDPWriteModel(userID, idpConfigID, externalUserID string) *HumanExternalIDPWriteModel {
func NewHumanExternalIDPWriteModel(userID, idpConfigID, externalUserID, resourceOwner string) *HumanExternalIDPWriteModel {
return &HumanExternalIDPWriteModel{
WriteModel: eventstore.WriteModel{
AggregateID: userID,
AggregateID: userID,
ResourceOwner: resourceOwner,
},
IDPConfigID: idpConfigID,
ExternalUserID: externalUserID,
@ -68,5 +69,6 @@ func (wm *HumanExternalIDPWriteModel) Reduce() error {
func (wm *HumanExternalIDPWriteModel) Query() *eventstore.SearchQueryBuilder {
return eventstore.NewSearchQueryBuilder(eventstore.ColumnsEvent, user.AggregateType).
AggregateIDs(wm.AggregateID)
AggregateIDs(wm.AggregateID).
ResourceOwner(wm.ResourceOwner)
}

View File

@ -38,10 +38,11 @@ type HumanWriteModel struct {
UserState domain.UserState
}
func NewHumanWriteModel(userID string) *HumanWriteModel {
func NewHumanWriteModel(userID, resourceOwner string) *HumanWriteModel {
return &HumanWriteModel{
WriteModel: eventstore.WriteModel{
AggregateID: userID,
AggregateID: userID,
ResourceOwner: resourceOwner,
},
}
}
@ -115,7 +116,8 @@ func (wm *HumanWriteModel) Reduce() error {
func (wm *HumanWriteModel) Query() *eventstore.SearchQueryBuilder {
return eventstore.NewSearchQueryBuilder(eventstore.ColumnsEvent, user.AggregateType).
AggregateIDs(wm.AggregateID)
AggregateIDs(wm.AggregateID).
ResourceOwner(wm.ResourceOwner)
}
func (wm *HumanWriteModel) reduceHumanAddedEvent(e *user.HumanAddedEvent) {

View File

@ -8,12 +8,12 @@ import (
"github.com/caos/zitadel/internal/v2/repository/user"
)
func (r *CommandSide) RemoveHumanOTP(ctx context.Context, userID string) error {
func (r *CommandSide) RemoveHumanOTP(ctx context.Context, userID, resourceOwner string) error {
if userID == "" {
return caos_errs.ThrowPreconditionFailed(nil, "COMMAND-5M0sd", "Errors.User.UserIDMissing")
}
existingOTP, err := r.otpWriteModelByID(ctx, userID)
existingOTP, err := r.otpWriteModelByID(ctx, userID, resourceOwner)
if err != nil {
return err
}
@ -28,11 +28,11 @@ func (r *CommandSide) RemoveHumanOTP(ctx context.Context, userID string) error {
return r.eventstore.PushAggregate(ctx, existingOTP, userAgg)
}
func (r *CommandSide) otpWriteModelByID(ctx context.Context, userID string) (writeModel *HumanOTPWriteModel, err error) {
func (r *CommandSide) otpWriteModelByID(ctx context.Context, userID, resourceOwner string) (writeModel *HumanOTPWriteModel, err error) {
ctx, span := tracing.NewSpan(ctx)
defer func() { span.EndWithError(err) }()
writeModel = NewHumanOTPWriteModel(userID)
writeModel = NewHumanOTPWriteModel(userID, resourceOwner)
err = r.eventstore.FilterToQueryReducer(ctx, writeModel)
if err != nil {
return nil, err

View File

@ -15,10 +15,11 @@ type HumanOTPWriteModel struct {
State domain.OTPState
}
func NewHumanOTPWriteModel(userID string) *HumanOTPWriteModel {
func NewHumanOTPWriteModel(userID, resourceOwner string) *HumanOTPWriteModel {
return &HumanOTPWriteModel{
WriteModel: eventstore.WriteModel{
AggregateID: userID,
AggregateID: userID,
ResourceOwner: resourceOwner,
},
}
}
@ -53,5 +54,6 @@ func (wm *HumanOTPWriteModel) Reduce() error {
func (wm *HumanOTPWriteModel) Query() *eventstore.SearchQueryBuilder {
return eventstore.NewSearchQueryBuilder(eventstore.ColumnsEvent, user.AggregateType).
AggregateIDs(wm.AggregateID)
AggregateIDs(wm.AggregateID).
ResourceOwner(wm.ResourceOwner)
}

View File

@ -13,7 +13,7 @@ func (r *CommandSide) SetOneTimePassword(ctx context.Context, orgID, userID, pas
ctx, span := tracing.NewSpan(ctx)
defer func() { span.EndWithError(err) }()
existingPassword, err := r.passwordWriteModel(ctx, userID)
existingPassword, err := r.passwordWriteModel(ctx, userID, orgID)
if err != nil {
return err
}
@ -24,11 +24,11 @@ func (r *CommandSide) SetOneTimePassword(ctx context.Context, orgID, userID, pas
return r.changePassword(ctx, orgID, userID, "", password, existingPassword)
}
func (r *CommandSide) ChangePassword(ctx context.Context, orgID, userID, oldPassword, newPassword, userAgentID string) (err error) {
func (r *CommandSide) ChangePassword(ctx context.Context, orgID, userID, oldPassword, newPassword, userAgentID, resourceOwner string) (err error) {
ctx, span := tracing.NewSpan(ctx)
defer func() { span.EndWithError(err) }()
existingPassword, err := r.passwordWriteModel(ctx, userID)
existingPassword, err := r.passwordWriteModel(ctx, userID, resourceOwner)
if err != nil {
return err
}
@ -74,8 +74,8 @@ func (r *CommandSide) changePassword(ctx context.Context, orgID, userID, userAge
return r.eventstore.PushAggregate(ctx, existingPassword, userAgg)
}
func (r *CommandSide) RequestSetPassword(ctx context.Context, userID string, notifyType domain.NotificationType) (err error) {
existingHuman, err := r.userWriteModelByID(ctx, userID)
func (r *CommandSide) RequestSetPassword(ctx context.Context, userID, resourceOwner string, notifyType domain.NotificationType) (err error) {
existingHuman, err := r.userWriteModelByID(ctx, userID, resourceOwner)
if err != nil {
return err
}
@ -94,11 +94,11 @@ func (r *CommandSide) RequestSetPassword(ctx context.Context, userID string, not
return r.eventstore.PushAggregate(ctx, existingHuman, userAgg)
}
func (r *CommandSide) passwordWriteModel(ctx context.Context, userID string) (writeModel *HumanPasswordWriteModel, err error) {
func (r *CommandSide) passwordWriteModel(ctx context.Context, userID, resourceOwner string) (writeModel *HumanPasswordWriteModel, err error) {
ctx, span := tracing.NewSpan(ctx)
defer func() { span.EndWithError(err) }()
writeModel = NewHumanPasswordWriteModel(userID)
writeModel = NewHumanPasswordWriteModel(userID, resourceOwner)
err = r.eventstore.FilterToQueryReducer(ctx, writeModel)
if err != nil {
return nil, err

View File

@ -16,10 +16,11 @@ type HumanPasswordWriteModel struct {
UserState domain.UserState
}
func NewHumanPasswordWriteModel(userID string) *HumanPasswordWriteModel {
func NewHumanPasswordWriteModel(userID, resourceOwner string) *HumanPasswordWriteModel {
return &HumanPasswordWriteModel{
WriteModel: eventstore.WriteModel{
AggregateID: userID,
AggregateID: userID,
ResourceOwner: resourceOwner,
},
}
}
@ -66,5 +67,6 @@ func (wm *HumanPasswordWriteModel) Reduce() error {
func (wm *HumanPasswordWriteModel) Query() *eventstore.SearchQueryBuilder {
return eventstore.NewSearchQueryBuilder(eventstore.ColumnsEvent, user.AggregateType).
AggregateIDs(wm.AggregateID)
AggregateIDs(wm.AggregateID).
ResourceOwner(wm.ResourceOwner)
}

View File

@ -2,6 +2,7 @@ package command
import (
"context"
caos_errs "github.com/caos/zitadel/internal/errors"
"github.com/caos/zitadel/internal/telemetry/tracing"
"github.com/caos/zitadel/internal/v2/domain"
@ -13,7 +14,7 @@ func (r *CommandSide) ChangeHumanPhone(ctx context.Context, phone *domain.Phone)
return nil, caos_errs.ThrowPreconditionFailed(nil, "COMMAND-6M0ds", "Errors.Phone.Invalid")
}
existingPhone, err := r.phoneWriteModel(ctx, phone.AggregateID)
existingPhone, err := r.phoneWriteModel(ctx, phone.AggregateID, phone.ResourceOwner)
if err != nil {
return nil, err
}
@ -45,12 +46,12 @@ func (r *CommandSide) ChangeHumanPhone(ctx context.Context, phone *domain.Phone)
return writeModelToPhone(existingPhone), nil
}
func (r *CommandSide) CreateHumanPhoneVerificationCode(ctx context.Context, userID string) error {
func (r *CommandSide) CreateHumanPhoneVerificationCode(ctx context.Context, userID, resourceOwner string) error {
if userID == "" {
return caos_errs.ThrowPreconditionFailed(nil, "COMMAND-4M0ds", "Errors.User.UserIDMissing")
}
existingPhone, err := r.phoneWriteModel(ctx, userID)
existingPhone, err := r.phoneWriteModel(ctx, userID, resourceOwner)
if err != nil {
return err
}
@ -69,12 +70,12 @@ func (r *CommandSide) CreateHumanPhoneVerificationCode(ctx context.Context, user
return r.eventstore.PushAggregate(ctx, existingPhone, userAgg)
}
func (r *CommandSide) RemoveHumanPhone(ctx context.Context, userID string) error {
func (r *CommandSide) RemoveHumanPhone(ctx context.Context, userID, resourceOwner string) error {
if userID == "" {
return caos_errs.ThrowPreconditionFailed(nil, "COMMAND-6M0ds", "Errors.User.UserIDMissing")
}
existingPhone, err := r.phoneWriteModel(ctx, userID)
existingPhone, err := r.phoneWriteModel(ctx, userID, resourceOwner)
if err != nil {
return err
}
@ -88,11 +89,11 @@ func (r *CommandSide) RemoveHumanPhone(ctx context.Context, userID string) error
return r.eventstore.PushAggregate(ctx, existingPhone, userAgg)
}
func (r *CommandSide) phoneWriteModel(ctx context.Context, userID string) (writeModel *HumanPhoneWriteModel, err error) {
func (r *CommandSide) phoneWriteModel(ctx context.Context, userID, resourceOwner string) (writeModel *HumanPhoneWriteModel, err error) {
ctx, span := tracing.NewSpan(ctx)
defer func() { span.EndWithError(err) }()
writeModel = NewHumanPhoneWriteModel(userID)
writeModel = NewHumanPhoneWriteModel(userID, resourceOwner)
err = r.eventstore.FilterToQueryReducer(ctx, writeModel)
if err != nil {
return nil, err

View File

@ -2,6 +2,7 @@ package command
import (
"context"
"github.com/caos/zitadel/internal/eventstore/v2"
"github.com/caos/zitadel/internal/v2/domain"
"github.com/caos/zitadel/internal/v2/repository/user"
@ -16,10 +17,11 @@ type HumanPhoneWriteModel struct {
State domain.PhoneState
}
func NewHumanPhoneWriteModel(userID string) *HumanPhoneWriteModel {
func NewHumanPhoneWriteModel(userID, resourceOwner string) *HumanPhoneWriteModel {
return &HumanPhoneWriteModel{
WriteModel: eventstore.WriteModel{
AggregateID: userID,
AggregateID: userID,
ResourceOwner: resourceOwner,
},
}
}
@ -71,7 +73,8 @@ func (wm *HumanPhoneWriteModel) Reduce() error {
func (wm *HumanPhoneWriteModel) Query() *eventstore.SearchQueryBuilder {
return eventstore.NewSearchQueryBuilder(eventstore.ColumnsEvent, user.AggregateType).
AggregateIDs(wm.AggregateID)
AggregateIDs(wm.AggregateID).
ResourceOwner(wm.ResourceOwner)
}
func (wm *HumanPhoneWriteModel) NewChangedEvent(

View File

@ -12,7 +12,7 @@ func (r *CommandSide) ChangeHumanProfile(ctx context.Context, profile *domain.Pr
return nil, caos_errs.ThrowPreconditionFailed(nil, "COMMAND-8io0d", "Errors.User.Profile.Invalid")
}
existingProfile, err := r.profileWriteModelByID(ctx, profile.AggregateID)
existingProfile, err := r.profileWriteModelByID(ctx, profile.AggregateID, profile.ResourceOwner)
if err != nil {
return nil, err
}
@ -34,11 +34,11 @@ func (r *CommandSide) ChangeHumanProfile(ctx context.Context, profile *domain.Pr
return writeModelToProfile(existingProfile), nil
}
func (r *CommandSide) profileWriteModelByID(ctx context.Context, userID string) (writeModel *HumanProfileWriteModel, err error) {
func (r *CommandSide) profileWriteModelByID(ctx context.Context, userID, resourceOwner string) (writeModel *HumanProfileWriteModel, err error) {
ctx, span := tracing.NewSpan(ctx)
defer func() { span.EndWithError(err) }()
writeModel = NewHumanProfileWriteModel(userID)
writeModel = NewHumanProfileWriteModel(userID, resourceOwner)
err = r.eventstore.FilterToQueryReducer(ctx, writeModel)
if err != nil {
return nil, err

View File

@ -2,10 +2,12 @@ package command
import (
"context"
"golang.org/x/text/language"
"github.com/caos/zitadel/internal/eventstore/v2"
"github.com/caos/zitadel/internal/v2/domain"
"github.com/caos/zitadel/internal/v2/repository/user"
"golang.org/x/text/language"
)
type HumanProfileWriteModel struct {
@ -21,10 +23,11 @@ type HumanProfileWriteModel struct {
UserState domain.UserState
}
func NewHumanProfileWriteModel(userID string) *HumanProfileWriteModel {
func NewHumanProfileWriteModel(userID, resourceOwner string) *HumanProfileWriteModel {
return &HumanProfileWriteModel{
WriteModel: eventstore.WriteModel{
AggregateID: userID,
AggregateID: userID,
ResourceOwner: resourceOwner,
},
}
}
@ -89,7 +92,8 @@ func (wm *HumanProfileWriteModel) Reduce() error {
func (wm *HumanProfileWriteModel) Query() *eventstore.SearchQueryBuilder {
return eventstore.NewSearchQueryBuilder(eventstore.ColumnsEvent, user.AggregateType).
AggregateIDs(wm.AggregateID)
AggregateIDs(wm.AggregateID).
ResourceOwner(wm.ResourceOwner)
}
func (wm *HumanProfileWriteModel) NewChangedEvent(

View File

@ -9,22 +9,22 @@ import (
"github.com/caos/zitadel/internal/v2/repository/user"
)
func (r *CommandSide) RemoveHumanU2F(ctx context.Context, userID, webAuthNID string) error {
func (r *CommandSide) RemoveHumanU2F(ctx context.Context, userID, webAuthNID, resourceOwner string) error {
event := user.NewHumanU2FRemovedEvent(ctx, webAuthNID)
return r.removeHumanWebAuthN(ctx, userID, webAuthNID, event)
return r.removeHumanWebAuthN(ctx, userID, webAuthNID, resourceOwner, event)
}
func (r *CommandSide) RemoveHumanPasswordless(ctx context.Context, userID, webAuthNID string) error {
func (r *CommandSide) RemoveHumanPasswordless(ctx context.Context, userID, webAuthNID, resourceOwner string) error {
event := user.NewHumanPasswordlessRemovedEvent(ctx, webAuthNID)
return r.removeHumanWebAuthN(ctx, userID, webAuthNID, event)
return r.removeHumanWebAuthN(ctx, userID, webAuthNID, resourceOwner, event)
}
func (r *CommandSide) removeHumanWebAuthN(ctx context.Context, userID, webAuthNID string, event eventstore.EventPusher) error {
func (r *CommandSide) removeHumanWebAuthN(ctx context.Context, userID, webAuthNID, resourceOwner string, event eventstore.EventPusher) error {
if userID == "" || webAuthNID == "" {
return caos_errs.ThrowPreconditionFailed(nil, "COMMAND-6M9de", "Errors.IDMissing")
}
existingWebAuthN, err := r.webauthNWriteModelByID(ctx, userID, webAuthNID)
existingWebAuthN, err := r.webauthNWriteModelByID(ctx, userID, webAuthNID, resourceOwner)
if err != nil {
return err
}
@ -37,11 +37,11 @@ func (r *CommandSide) removeHumanWebAuthN(ctx context.Context, userID, webAuthNI
return r.eventstore.PushAggregate(ctx, existingWebAuthN, userAgg)
}
func (r *CommandSide) webauthNWriteModelByID(ctx context.Context, userID, webAuthNID string) (writeModel *HumanWebAuthNWriteModel, err error) {
func (r *CommandSide) webauthNWriteModelByID(ctx context.Context, userID, webAuthNID, resourceOwner string) (writeModel *HumanWebAuthNWriteModel, err error) {
ctx, span := tracing.NewSpan(ctx)
defer func() { span.EndWithError(err) }()
writeModel = NewHumanWebAuthNWriteModel(userID, webAuthNID)
writeModel = NewHumanWebAuthNWriteModel(userID, webAuthNID, resourceOwner)
err = r.eventstore.FilterToQueryReducer(ctx, writeModel)
if err != nil {
return nil, err

View File

@ -14,10 +14,11 @@ type HumanWebAuthNWriteModel struct {
State domain.WebAuthNState
}
func NewHumanWebAuthNWriteModel(userID, wbAuthNTokenID string) *HumanWebAuthNWriteModel {
func NewHumanWebAuthNWriteModel(userID, wbAuthNTokenID, resourceOwner string) *HumanWebAuthNWriteModel {
return &HumanWebAuthNWriteModel{
WriteModel: eventstore.WriteModel{
AggregateID: userID,
AggregateID: userID,
ResourceOwner: resourceOwner,
},
WebauthNTokenID: wbAuthNTokenID,
}
@ -57,5 +58,6 @@ func (wm *HumanWebAuthNWriteModel) Reduce() error {
func (wm *HumanWebAuthNWriteModel) Query() *eventstore.SearchQueryBuilder {
return eventstore.NewSearchQueryBuilder(eventstore.ColumnsEvent, user.AggregateType).
AggregateIDs(wm.AggregateID)
AggregateIDs(wm.AggregateID).
ResourceOwner(wm.ResourceOwner)
}

View File

@ -26,7 +26,7 @@ func (r *CommandSide) AddMachine(ctx context.Context, orgID, username string, ma
return nil, caos_errs.ThrowInvalidArgument(nil, "COMMAND-6M0ds", "Errors.User.Invalid")
}
addedMachine := NewMachineWriteModel(machine.AggregateID)
addedMachine := NewMachineWriteModel(machine.AggregateID, orgID)
userAgg := UserAggregateFromWriteModel(&addedMachine.WriteModel)
userAgg.PushEvents(
user.NewMachineAddedEvent(
@ -40,7 +40,7 @@ func (r *CommandSide) AddMachine(ctx context.Context, orgID, username string, ma
}
func (r *CommandSide) ChangeMachine(ctx context.Context, machine *domain.Machine) (*domain.Machine, error) {
existingUser, err := r.machineWriteModelByID(ctx, machine.AggregateID)
existingUser, err := r.machineWriteModelByID(ctx, machine.AggregateID, machine.ResourceOwner)
if err != nil {
return nil, err
}
@ -62,14 +62,14 @@ func (r *CommandSide) ChangeMachine(ctx context.Context, machine *domain.Machine
return writeModelToMachine(existingUser), nil
}
func (r *CommandSide) machineWriteModelByID(ctx context.Context, userID string) (writeModel *MachineWriteModel, err error) {
func (r *CommandSide) machineWriteModelByID(ctx context.Context, userID, resourceOwner string) (writeModel *MachineWriteModel, err error) {
if userID == "" {
return nil, caos_errs.ThrowInvalidArgument(nil, "COMMAND-5M0ds", "Errors.User.UserIDMissing")
}
ctx, span := tracing.NewSpan(ctx)
defer func() { span.EndWithError(err) }()
writeModel = NewMachineWriteModel(userID)
writeModel = NewMachineWriteModel(userID, resourceOwner)
err = r.eventstore.FilterToQueryReducer(ctx, writeModel)
if err != nil {
return nil, err

View File

@ -2,6 +2,7 @@ package command
import (
"context"
"github.com/caos/zitadel/internal/eventstore/v2"
"github.com/caos/zitadel/internal/v2/domain"
"github.com/caos/zitadel/internal/v2/repository/user"
@ -17,10 +18,11 @@ type MachineWriteModel struct {
UserState domain.UserState
}
func NewMachineWriteModel(userID string) *MachineWriteModel {
func NewMachineWriteModel(userID, resourceOwner string) *MachineWriteModel {
return &MachineWriteModel{
WriteModel: eventstore.WriteModel{
AggregateID: userID,
AggregateID: userID,
ResourceOwner: resourceOwner,
},
}
}
@ -91,7 +93,8 @@ func (wm *MachineWriteModel) Reduce() error {
func (wm *MachineWriteModel) Query() *eventstore.SearchQueryBuilder {
return eventstore.NewSearchQueryBuilder(eventstore.ColumnsEvent, user.AggregateType).
AggregateIDs(wm.AggregateID)
AggregateIDs(wm.AggregateID).
ResourceOwner(wm.ResourceOwner)
}
func (wm *MachineWriteModel) NewChangedEvent(

View File

@ -1,11 +1,12 @@
package command
import (
"strings"
caos_errors "github.com/caos/zitadel/internal/errors"
"github.com/caos/zitadel/internal/eventstore/v2"
"github.com/caos/zitadel/internal/v2/domain"
"github.com/caos/zitadel/internal/v2/repository/user"
"strings"
)
type UserWriteModel struct {
@ -15,10 +16,11 @@ type UserWriteModel struct {
UserState domain.UserState
}
func NewUserWriteModel(userID string) *UserWriteModel {
func NewUserWriteModel(userID, resourceOwner string) *UserWriteModel {
return &UserWriteModel{
WriteModel: eventstore.WriteModel{
AggregateID: userID,
AggregateID: userID,
ResourceOwner: resourceOwner,
},
}
}
@ -86,7 +88,8 @@ func (wm *UserWriteModel) Reduce() error {
func (wm *UserWriteModel) Query() *eventstore.SearchQueryBuilder {
return eventstore.NewSearchQueryBuilder(eventstore.ColumnsEvent, user.AggregateType).
AggregateIDs(wm.AggregateID)
AggregateIDs(wm.AggregateID).
ResourceOwner(wm.ResourceOwner)
}
func UserAggregateFromWriteModel(wm *eventstore.WriteModel) *user.Aggregate {

View File

@ -0,0 +1,49 @@
package domain
import (
"github.com/caos/zitadel/internal/eventstore/models"
)
type Application struct {
models.ObjectRoot
AppID string
State AppState
Name string
Type AppType
OIDCConfig *OIDCConfig
}
type AppState int32
const (
AppStateUnspecified AppState = iota
AppStateActive
AppStateInactive
AppStateRemoved
)
type AppType int32
const (
AppTypeUnspecified AppType = iota
AppTypeOIDC
AppTypeSAML
)
func NewApplication(projectID, appID string) *Application {
return &Application{ObjectRoot: models.ObjectRoot{AggregateID: projectID}, AppID: appID, State: AppStateActive}
}
func (a *Application) IsValid(includeConfig bool) bool {
if a.Name == "" || a.AggregateID == "" {
return false
}
if !includeConfig {
return true
}
if a.Type == AppTypeOIDC && !a.OIDCConfig.IsValid() {
return false
}
return true
}

View File

@ -4,6 +4,10 @@ import (
"github.com/caos/zitadel/internal/eventstore/models"
)
const (
IAMID = "IAM"
)
type IAM struct {
models.ObjectRoot

View File

@ -0,0 +1,152 @@
package domain
import (
"fmt"
"strings"
"time"
"github.com/caos/logging"
"github.com/caos/zitadel/internal/crypto"
"github.com/caos/zitadel/internal/errors"
"github.com/caos/zitadel/internal/eventstore/models"
"github.com/caos/zitadel/internal/id"
)
type OIDCConfig struct {
models.ObjectRoot
AppID string
ClientID string
ClientSecret *crypto.CryptoValue
ClientSecretString string
RedirectUris []string
ResponseTypes []OIDCResponseType
GrantTypes []OIDCGrantType
ApplicationType OIDCApplicationType
AuthMethodType OIDCAuthMethodType
PostLogoutRedirectUris []string
OIDCVersion OIDCVersion
Compliance *Compliance
DevMode bool
AccessTokenType OIDCTokenType
AccessTokenRoleAssertion bool
IDTokenRoleAssertion bool
IDTokenUserinfoAssertion bool
ClockSkew time.Duration
}
type OIDCVersion int32
const (
OIDCVersionV1 OIDCVersion = iota
)
type OIDCResponseType int32
const (
OIDCResponseTypeCode OIDCResponseType = iota
OIDCResponseTypeIDToken
OIDCResponseTypeIDTokenToken
)
type OIDCGrantType int32
const (
OIDCGrantTypeAuthorizationCode OIDCGrantType = iota
OIDCGrantTypeImplicit
OIDCGrantTypeRefreshToken
)
type OIDCApplicationType int32
const (
OIDCApplicationTypeWeb OIDCApplicationType = iota
OIDCApplicationTypeUserAgent
OIDCApplicationTypeNative
)
type OIDCAuthMethodType int32
const (
OIDCAuthMethodTypeBasic OIDCAuthMethodType = iota
OIDCAuthMethodTypePost
OIDCAuthMethodTypeNone
)
type Compliance struct {
NoneCompliant bool
Problems []string
}
type OIDCTokenType int32
const (
OIDCTokenTypeBearer OIDCTokenType = iota
OIDCTokenTypeJWT
)
func (c *OIDCConfig) IsValid() bool {
grantTypes := c.getRequiredGrantTypes()
for _, grantType := range grantTypes {
ok := containsOIDCGrantType(c.GrantTypes, grantType)
if !ok {
return false
}
}
return true
}
//ClientID random_number@projectname (eg. 495894098234@zitadel)
func (c *OIDCConfig) GenerateNewClientID(idGenerator id.Generator, project *Project) error {
rndID, err := idGenerator.Next()
if err != nil {
return err
}
c.ClientID = fmt.Sprintf("%v@%v", rndID, strings.ReplaceAll(strings.ToLower(project.Name), " ", "_"))
return nil
}
func (c *OIDCConfig) GenerateClientSecretIfNeeded(generator crypto.Generator) (string, error) {
if c.AuthMethodType == OIDCAuthMethodTypeNone {
return "", nil
}
return c.GenerateNewClientSecret(generator)
}
func (c *OIDCConfig) GenerateNewClientSecret(generator crypto.Generator) (string, error) {
cryptoValue, stringSecret, err := crypto.NewCode(generator)
if err != nil {
logging.Log("MODEL-UpnTI").OnError(err).Error("unable to create client secret")
return "", errors.ThrowInternal(err, "MODEL-gH2Wl", "Errors.Project.CouldNotGenerateClientSecret")
}
c.ClientSecret = cryptoValue
return stringSecret, nil
}
func (c *OIDCConfig) getRequiredGrantTypes() []OIDCGrantType {
grantTypes := make([]OIDCGrantType, 0)
implicit := false
for _, r := range c.ResponseTypes {
switch r {
case OIDCResponseTypeCode:
grantTypes = append(grantTypes, OIDCGrantTypeAuthorizationCode)
case OIDCResponseTypeIDToken, OIDCResponseTypeIDTokenToken:
if !implicit {
implicit = true
grantTypes = append(grantTypes, OIDCGrantTypeImplicit)
}
}
}
return grantTypes
}
func containsOIDCGrantType(grantTypes []OIDCGrantType, grantType OIDCGrantType) bool {
for _, gt := range grantTypes {
if gt == grantType {
return true
}
}
return false
}

View File

@ -0,0 +1,31 @@
package domain
import (
"github.com/caos/zitadel/internal/eventstore/models"
)
type Project struct {
models.ObjectRoot
State ProjectState
Name string
Members []*Member
Roles []*ProjectRole
//Applications []*Application
//Grants []*ProjectGrant
ProjectRoleAssertion bool
ProjectRoleCheck bool
}
type ProjectState int32
const (
ProjectStateUnspecified ProjectState = iota
ProjectStateActive
ProjectStateInactive
ProjectStateRemoved
)
func (o *Project) IsValid() bool {
return o.Name != ""
}

View File

@ -0,0 +1,21 @@
package domain
import (
"github.com/caos/zitadel/internal/eventstore/models"
)
type ProjectRole struct {
models.ObjectRoot
Key string
DisplayName string
Group string
}
func NewProjectRole(projectID, key string) *ProjectRole {
return &ProjectRole{ObjectRoot: models.ObjectRoot{AggregateID: projectID}, Key: key}
}
func (p *ProjectRole) IsValid() bool {
return p.AggregateID != "" && p.Key != ""
}

View File

@ -1,5 +1,8 @@
package domain
const (
OrgOwnerRole = "ORG_OWNER"
RoleOrgOwner = "ORG_OWNER"
RoleIAMOwner = "IAM_OWNER"
RoleProjectOwner = "PROJECT_OWNER"
RoleProjectOwnerGlobal = "PROJECT_OWNER_GLOBAL"
)

View File

@ -23,7 +23,7 @@ func (e *ProjectSetEvent) Data() interface{} {
return e
}
func NewProjectSetEvent(ctx context.Context, projectID string) *ProjectSetEvent {
func NewIAMProjectSetEvent(ctx context.Context, projectID string) *ProjectSetEvent {
return &ProjectSetEvent{
BaseEvent: *eventstore.NewBaseEventForPush(
ctx,

View File

@ -0,0 +1,31 @@
package project
import (
"github.com/caos/zitadel/internal/eventstore/v2"
)
const (
AggregateType = "project"
AggregateVersion = "v1"
)
type Aggregate struct {
eventstore.Aggregate
}
func NewAggregate(
id,
resourceOwner string,
previousSequence uint64,
) *Aggregate {
return &Aggregate{
Aggregate: *eventstore.NewAggregate(
id,
AggregateType,
resourceOwner,
AggregateVersion,
previousSequence,
),
}
}

View File

@ -0,0 +1,57 @@
package project
import (
"context"
"encoding/json"
"github.com/caos/zitadel/internal/errors"
"github.com/caos/zitadel/internal/eventstore/v2"
"github.com/caos/zitadel/internal/eventstore/v2/repository"
"github.com/caos/zitadel/internal/v2/domain"
)
const (
applicationEventTypePrefix = projectEventTypePrefix + "application."
ApplicationAdded = applicationEventTypePrefix + "added"
ApplicationChanged = applicationEventTypePrefix + "changed"
ApplicationDeactivated = applicationEventTypePrefix + "deactivated"
ApplicationReactivated = applicationEventTypePrefix + "reactivated"
ApplicationRemoved = applicationEventTypePrefix + "removed"
)
type ApplicationAddedEvent struct {
eventstore.BaseEvent `json:"-"`
AppID string `json:"appId,omitempty"`
Name string `json:"name,omitempty"`
AppType domain.AppType `json:"appType,omitempty"`
}
func (e *ApplicationAddedEvent) Data() interface{} {
return e
}
func NewApplicationAddedEvent(ctx context.Context, appID, name string, appType domain.AppType) *ApplicationAddedEvent {
return &ApplicationAddedEvent{
BaseEvent: *eventstore.NewBaseEventForPush(
ctx,
ApplicationAdded,
),
AppID: appID,
Name: name,
AppType: appType,
}
}
func ApplicationAddedEventMapper(event *repository.Event) (eventstore.EventReader, error) {
e := &ApplicationAddedEvent{
BaseEvent: *eventstore.BaseEventFromRepo(event),
}
err := json.Unmarshal(event.Data, e)
if err != nil {
return nil, errors.ThrowInternal(err, "APPLICATION-Nffg2", "unable to unmarshal application")
}
return e, nil
}

View File

@ -0,0 +1,76 @@
package project
import (
"context"
"github.com/caos/zitadel/internal/eventstore/v2"
"github.com/caos/zitadel/internal/v2/repository/member"
)
var (
MemberAddedEventType = projectEventTypePrefix + member.AddedEventType
MemberChangedEventType = projectEventTypePrefix + member.ChangedEventType
MemberRemovedEventType = projectEventTypePrefix + member.RemovedEventType
)
type MemberAddedEvent struct {
member.MemberAddedEvent
}
func NewMemberAddedEvent(
ctx context.Context,
userID string,
roles ...string,
) *MemberAddedEvent {
return &MemberAddedEvent{
MemberAddedEvent: *member.NewMemberAddedEvent(
eventstore.NewBaseEventForPush(
ctx,
MemberAddedEventType,
),
userID,
roles...,
),
}
}
type MemberChangedEvent struct {
member.MemberChangedEvent
}
func NewMemberChangedEvent(
ctx context.Context,
userID string,
roles ...string,
) *MemberChangedEvent {
return &MemberChangedEvent{
MemberChangedEvent: *member.NewMemberChangedEvent(
eventstore.NewBaseEventForPush(
ctx,
MemberChangedEventType,
),
userID,
roles...,
),
}
}
type MemberRemovedEvent struct {
member.MemberRemovedEvent
}
func NewMemberRemovedEvent(
ctx context.Context,
userID string,
) *MemberRemovedEvent {
return &MemberRemovedEvent{
MemberRemovedEvent: *member.NewRemovedEvent(
eventstore.NewBaseEventForPush(
ctx,
MemberRemovedEventType,
),
userID,
),
}
}

View File

@ -0,0 +1,102 @@
package project
import (
"context"
"encoding/json"
"time"
"github.com/caos/zitadel/internal/crypto"
"github.com/caos/zitadel/internal/errors"
"github.com/caos/zitadel/internal/eventstore/v2"
"github.com/caos/zitadel/internal/eventstore/v2/repository"
"github.com/caos/zitadel/internal/v2/domain"
)
const (
OIDCConfigAdded = applicationEventTypePrefix + "config.oidc.added"
OIDCConfigChanged = applicationEventTypePrefix + "config.oidc.changed"
OIDCConfigSecretChanged = applicationEventTypePrefix + "config.oidc.secret.changed"
OIDCClientSecretCheckSucceeded = applicationEventTypePrefix + "oidc.secret.check.succeeded"
OIDCClientSecretCheckFailed = applicationEventTypePrefix + "oidc.secret.check.failed"
)
type OIDCConfigAddedEvent struct {
eventstore.BaseEvent `json:"-"`
Version domain.OIDCVersion `json:"oidcVersion,omitempty"`
AppID string `json:"appId"`
ClientID string `json:"clientId,omitempty"`
ClientSecret *crypto.CryptoValue `json:"clientSecret,omitempty"`
RedirectUris []string `json:"redirectUris,omitempty"`
ResponseTypes []domain.OIDCResponseType `json:"responseTypes,omitempty"`
GrantTypes []domain.OIDCGrantType `json:"grantTypes,omitempty"`
ApplicationType domain.OIDCApplicationType `json:"applicationType,omitempty"`
AuthMethodType domain.OIDCAuthMethodType `json:"authMethodType,omitempty"`
PostLogoutRedirectUris []string `json:"postLogoutRedirectUris,omitempty"`
DevMode bool `json:"devMode,omitempty"`
AccessTokenType domain.OIDCTokenType `json:"accessTokenType,omitempty"`
AccessTokenRoleAssertion bool `json:"accessTokenRoleAssertion,omitempty"`
IDTokenRoleAssertion bool `json:"idTokenRoleAssertion,omitempty"`
IDTokenUserinfoAssertion bool `json:"idTokenUserinfoAssertion,omitempty"`
ClockSkew time.Duration `json:"clockSkew,omitempty"`
}
func (e *OIDCConfigAddedEvent) Data() interface{} {
return e
}
func NewOIDCConfigAddedEvent(
ctx context.Context,
version domain.OIDCVersion,
appID string,
clientID string,
clientSecret *crypto.CryptoValue,
redirectUris []string,
responseTypes []domain.OIDCResponseType,
grantTypes []domain.OIDCGrantType,
applicationType domain.OIDCApplicationType,
authMethodType domain.OIDCAuthMethodType,
postLogoutRedirectUris []string,
devMode bool,
accessTokenType domain.OIDCTokenType,
accessTokenRoleAssertion bool,
idTokenRoleAssertion bool,
idTokenUserinfoAssertion bool,
clockSkew time.Duration,
) *OIDCConfigAddedEvent {
return &OIDCConfigAddedEvent{
BaseEvent: *eventstore.NewBaseEventForPush(
ctx,
OIDCConfigAdded,
),
Version: version,
AppID: appID,
ClientID: clientID,
ClientSecret: clientSecret,
RedirectUris: redirectUris,
ResponseTypes: responseTypes,
GrantTypes: grantTypes,
ApplicationType: applicationType,
AuthMethodType: authMethodType,
PostLogoutRedirectUris: postLogoutRedirectUris,
DevMode: devMode,
AccessTokenType: accessTokenType,
AccessTokenRoleAssertion: accessTokenRoleAssertion,
IDTokenRoleAssertion: idTokenRoleAssertion,
IDTokenUserinfoAssertion: idTokenUserinfoAssertion,
ClockSkew: clockSkew,
}
}
func OIDCConfigAddedEventMapper(event *repository.Event) (eventstore.EventReader, error) {
e := &OIDCConfigAddedEvent{
BaseEvent: *eventstore.BaseEventFromRepo(event),
}
err := json.Unmarshal(event.Data, e)
if err != nil {
return nil, errors.ThrowInternal(err, "OIDC-BFd15", "unable to unmarshal oidc config")
}
return e, nil
}

View File

@ -0,0 +1,54 @@
package project
import (
"context"
"encoding/json"
"github.com/caos/zitadel/internal/errors"
"github.com/caos/zitadel/internal/eventstore/v2"
"github.com/caos/zitadel/internal/eventstore/v2/repository"
)
const (
projectEventTypePrefix = eventstore.EventType("project.")
ProjectAdded = projectEventTypePrefix + "added"
ProjectChanged = projectEventTypePrefix + "changed"
ProjectDeactivated = projectEventTypePrefix + "deactivated"
ProjectReactivated = projectEventTypePrefix + "reactivated"
ProjectRemoved = projectEventTypePrefix + "removed"
)
type ProjectAddedEvent struct {
eventstore.BaseEvent `json:"-"`
Name string `json:"name,omitempty"`
ProjectRoleAssertion bool `json:"projectRoleAssertion,omitempty"`
ProjectRoleCheck bool `json:"projectRoleCheck,omitempty"`
}
func (e *ProjectAddedEvent) Data() interface{} {
return e
}
func NewProjectAddedEvent(ctx context.Context, name string) *ProjectAddedEvent {
return &ProjectAddedEvent{
BaseEvent: *eventstore.NewBaseEventForPush(
ctx,
ProjectAdded,
),
Name: name,
}
}
func ProjectAddedEventMapper(event *repository.Event) (eventstore.EventReader, error) {
e := &ProjectAddedEvent{
BaseEvent: *eventstore.BaseEventFromRepo(event),
}
err := json.Unmarshal(event.Data, e)
if err != nil {
return nil, errors.ThrowInternal(err, "PROJECT-Bfg2f", "unable to unmarshal project")
}
return e, nil
}