fix: todos (#1346)

* fix: pub sub in new eventstore

* fix: todos

* fix: todos

* fix: todos

* fix: todos

* fix: todos
This commit is contained in:
Fabi
2021-03-01 08:48:50 +01:00
committed by GitHub
parent c0f55e7209
commit 3c07a186fc
145 changed files with 645 additions and 575 deletions

View File

@@ -2,7 +2,9 @@ package command
import (
"context"
"github.com/caos/zitadel/internal/api/authz"
"github.com/caos/zitadel/internal/config/types"
"github.com/caos/zitadel/internal/domain"
"github.com/caos/zitadel/internal/eventstore"
"time"
@@ -10,7 +12,6 @@ import (
sd "github.com/caos/zitadel/internal/config/systemdefaults"
"github.com/caos/zitadel/internal/crypto"
"github.com/caos/zitadel/internal/id"
global_model "github.com/caos/zitadel/internal/model"
iam_repo "github.com/caos/zitadel/internal/repository/iam"
keypair "github.com/caos/zitadel/internal/repository/keypair"
"github.com/caos/zitadel/internal/repository/org"
@@ -22,9 +23,10 @@ import (
)
type Commands struct {
eventstore *eventstore.Eventstore
idGenerator id.Generator
iamDomain string
eventstore *eventstore.Eventstore
idGenerator id.Generator
iamDomain string
zitadelRoles []authz.RoleMapping
idpConfigSecretCrypto crypto.Crypto
@@ -40,8 +42,7 @@ type Commands struct {
domainVerificationAlg *crypto.AESCrypto
domainVerificationGenerator crypto.Generator
domainVerificationValidator func(domain, token, verifier string, checkType http.CheckType) error
//TODO: remove global model, or move to domain
multifactors global_model.Multifactors
multifactors domain.MultifactorConfigs
webauthn *webauthn_helper.WebAuthN
keySize int
@@ -54,11 +55,12 @@ type Config struct {
Eventstore types.SQLUser
}
func StartCommands(eventstore *eventstore.Eventstore, defaults sd.SystemDefaults) (repo *Commands, err error) {
func StartCommands(eventstore *eventstore.Eventstore, defaults sd.SystemDefaults, authZConfig authz.Config) (repo *Commands, err error) {
repo = &Commands{
eventstore: eventstore,
idGenerator: id.SonyFlakeGenerator,
iamDomain: defaults.Domain,
zitadelRoles: authZConfig.RolePermissionMappings,
keySize: defaults.KeyConfig.Size,
privateKeyLifetime: defaults.KeyConfig.PrivateKeyLifetime.Duration,
publicKeyLifetime: defaults.KeyConfig.PublicKeyLifetime.Duration,
@@ -70,7 +72,6 @@ func StartCommands(eventstore *eventstore.Eventstore, defaults sd.SystemDefaults
proj_repo.RegisterEventMappers(repo.eventstore)
keypair.RegisterEventMappers(repo.eventstore)
//TODO: simplify!!!!
repo.idpConfigSecretCrypto, err = crypto.NewAESCrypto(defaults.IDPConfigVerificationKey)
if err != nil {
return nil, err
@@ -92,8 +93,8 @@ func StartCommands(eventstore *eventstore.Eventstore, defaults sd.SystemDefaults
if err != nil {
return nil, err
}
repo.multifactors = global_model.Multifactors{
OTP: global_model.OTP{
repo.multifactors = domain.MultifactorConfigs{
OTP: domain.OTPConfig{
CryptoMFA: aesOTPCrypto,
Issuer: defaults.Multifactors.OTP.Issuer,
},

View File

@@ -8,7 +8,7 @@ import (
"github.com/caos/zitadel/internal/repository/iam"
)
//TODO: private
//TODO: private as soon as setup uses query
func (c *Commands) GetIAM(ctx context.Context) (*domain.IAM, error) {
iamWriteModel := NewIAMWriteModel()
err := c.eventstore.FilterToQueryReducer(ctx, iamWriteModel)

View File

@@ -132,7 +132,6 @@ func writeModelToPasswordLockoutPolicy(wm *PasswordLockoutPolicyWriteModel) *dom
func writeModelToIDPConfig(wm *IDPConfigWriteModel) *domain.IDPConfig {
return &domain.IDPConfig{
ObjectRoot: writeModelToObjectRoot(wm.WriteModel),
OIDCConfig: writeModelToIDPOIDCConfig(wm.OIDCConfig),
IDPConfigID: wm.ConfigID,
Name: wm.Name,
State: wm.State,

View File

@@ -141,6 +141,17 @@ func (c *Commands) RemoveDefaultIDPConfig(ctx context.Context, idpID string, idp
return err
}
func (c *Commands) getIAMIDPConfigByID(ctx context.Context, idpID string) (*domain.IDPConfig, error) {
config, err := c.iamIDPConfigWriteModelByID(ctx, idpID)
if err != nil {
return nil, err
}
if !config.State.Exists() {
return nil, caos_errs.ThrowNotFound(nil, "IAM-4M9so", "Errors.IAM.IDPConfig.NotExisting")
}
return writeModelToIDPConfig(&config.IDPConfigWriteModel), nil
}
func (c *Commands) iamIDPConfigWriteModelByID(ctx context.Context, idpID string) (policy *IAMIDPConfigWriteModel, err error) {
ctx, span := tracing.NewSpan(ctx)
defer func() { span.EndWithError(err) }()

View File

@@ -32,11 +32,12 @@ func (c *Commands) AddIAMMember(ctx context.Context, member *domain.Member) (*do
}
func (c *Commands) addIAMMember(ctx context.Context, iamAgg *eventstore.Aggregate, addedMember *IAMMemberWriteModel, member *domain.Member) (eventstore.EventPusher, error) {
//TODO: check if roles valid
if !member.IsValid() {
return nil, caos_errs.ThrowPreconditionFailed(nil, "IAM-GR34U", "Errors.IAM.MemberInvalid")
}
if len(domain.CheckForInvalidRoles(member.Roles, domain.IAMRolePrefix, c.zitadelRoles)) > 0 {
return nil, caos_errs.ThrowPreconditionFailed(nil, "IAM-4m0fS", "Errors.IAM.MemberInvalid")
}
err := c.eventstore.FilterToQueryReducer(ctx, addedMember)
if err != nil {
@@ -51,11 +52,12 @@ func (c *Commands) addIAMMember(ctx context.Context, iamAgg *eventstore.Aggregat
//ChangeIAMMember updates an existing member
func (c *Commands) ChangeIAMMember(ctx context.Context, member *domain.Member) (*domain.Member, error) {
//TODO: check if roles valid
if !member.IsValid() {
return nil, caos_errs.ThrowPreconditionFailed(nil, "IAM-LiaZi", "Errors.IAM.MemberInvalid")
}
if len(domain.CheckForInvalidRoles(member.Roles, domain.IAMRolePrefix, c.zitadelRoles)) > 0 {
return nil, caos_errs.ThrowPreconditionFailed(nil, "IAM-3m9fs", "Errors.IAM.MemberInvalid")
}
existingMember, err := c.iamMemberWriteModelByID(ctx, member.UserID)
if err != nil {

View File

@@ -14,22 +14,10 @@ type IDPConfigWriteModel struct {
ConfigID string
Name string
StylingType domain.IDPConfigStylingType
//TODO: sub writemodels not used anymore?
OIDCConfig *OIDCConfigWriteModel
}
func (rm *IDPConfigWriteModel) AppendEvents(events ...eventstore.EventReader) {
rm.WriteModel.AppendEvents(events...)
for _, event := range events {
switch event.(type) {
case *idpconfig.OIDCConfigAddedEvent:
rm.OIDCConfig = new(OIDCConfigWriteModel)
rm.OIDCConfig.AppendEvents(event)
case *idpconfig.OIDCConfigChangedEvent:
rm.OIDCConfig.AppendEvents(event)
}
}
}
func (rm *IDPConfigWriteModel) Reduce() error {
@@ -47,11 +35,6 @@ func (rm *IDPConfigWriteModel) Reduce() error {
rm.reduceConfigStateChanged(e.ConfigID, domain.IDPConfigStateRemoved)
}
}
if rm.OIDCConfig != nil {
if err := rm.OIDCConfig.Reduce(); err != nil {
return err
}
}
return rm.WriteModel.Reduce()
}

View File

@@ -72,8 +72,6 @@ func (wm *OrgDomainWriteModel) Reduce() error {
case *org.DomainVerificationAddedEvent:
wm.ValidationType = e.ValidationType
wm.ValidationCode = e.ValidationCode
case *org.DomainVerificationFailedEvent:
//TODO: not handled in v1
case *org.DomainVerifiedEvent:
wm.Verified = true
case *org.DomainPrimarySetEvent:

View File

@@ -143,6 +143,17 @@ func (c *Commands) RemoveIDPConfig(ctx context.Context, idpID, orgID string, cas
return err
}
func (c *Commands) getOrgIDPConfigByID(ctx context.Context, idpID, orgID string) (*domain.IDPConfig, error) {
config, err := c.orgIDPConfigWriteModelByID(ctx, idpID, orgID)
if err != nil {
return nil, err
}
if !config.State.Exists() {
return nil, caos_errs.ThrowNotFound(nil, "IAM-4M9so", "Errors.Org.IDPConfig.NotExisting")
}
return writeModelToIDPConfig(&config.IDPConfigWriteModel), nil
}
func (c *Commands) orgIDPConfigWriteModelByID(ctx context.Context, idpID, orgID string) (policy *OrgIDPConfigWriteModel, err error) {
ctx, span := tracing.NewSpan(ctx)
defer func() { span.EndWithError(err) }()

View File

@@ -32,11 +32,12 @@ func (c *Commands) AddOrgMember(ctx context.Context, member *domain.Member) (*do
}
func (c *Commands) addOrgMember(ctx context.Context, orgAgg *eventstore.Aggregate, addedMember *OrgMemberWriteModel, member *domain.Member) (eventstore.EventPusher, error) {
//TODO: check if roles valid
if !member.IsValid() {
return nil, caos_errs.ThrowPreconditionFailed(nil, "Org-W8m4l", "Errors.Org.MemberInvalid")
}
if len(domain.CheckForInvalidRoles(member.Roles, domain.OrgRolePrefix, c.zitadelRoles)) > 0 {
return nil, caos_errs.ThrowPreconditionFailed(nil, "IAM-3m9fs", "Errors.Org.MemberInvalid")
}
err := c.eventstore.FilterToQueryReducer(ctx, addedMember)
if err != nil {
@@ -51,11 +52,12 @@ func (c *Commands) addOrgMember(ctx context.Context, orgAgg *eventstore.Aggregat
//ChangeOrgMember updates an existing member
func (c *Commands) ChangeOrgMember(ctx context.Context, member *domain.Member) (*domain.Member, error) {
//TODO: check if roles valid
if !member.IsValid() {
return nil, caos_errs.ThrowPreconditionFailed(nil, "Org-LiaZi", "Errors.Org.MemberInvalid")
}
if len(domain.CheckForInvalidRoles(member.Roles, domain.OrgRolePrefix, c.zitadelRoles)) > 0 {
return nil, caos_errs.ThrowPreconditionFailed(nil, "IAM-m9fG8", "Errors.Org.MemberInvalid")
}
existingMember, err := c.orgMemberWriteModelByID(ctx, member.AggregateID, member.UserID)
if err != nil {

View File

@@ -44,11 +44,12 @@ func (c *Commands) AddProjectGrantMember(ctx context.Context, member *domain.Pro
//ChangeProjectGrantMember updates an existing member
func (c *Commands) ChangeProjectGrantMember(ctx context.Context, member *domain.ProjectGrantMember, resourceOwner string) (*domain.ProjectGrantMember, error) {
//TODO: check if roles valid
if !member.IsValid() {
return nil, caos_errs.ThrowPreconditionFailed(nil, "PROJECT-109fs", "Errors.Project.Member.Invalid")
}
if len(domain.CheckForInvalidRoles(member.Roles, domain.ProjectGrantRolePrefix, c.zitadelRoles)) > 0 {
return nil, caos_errs.ThrowPreconditionFailed(nil, "PROJECT-m0sDf", "Errors.Project.Member.Invalid")
}
existingMember, err := c.projectGrantMemberWriteModelByID(ctx, member.AggregateID, member.UserID, member.GrantID)
if err != nil {

View File

@@ -33,11 +33,12 @@ func (c *Commands) AddProjectMember(ctx context.Context, member *domain.Member,
}
func (c *Commands) addProjectMember(ctx context.Context, projectAgg *eventstore.Aggregate, addedMember *ProjectMemberWriteModel, member *domain.Member) (eventstore.EventPusher, error) {
//TODO: check if roles valid
if !member.IsValid() {
return nil, caos_errs.ThrowPreconditionFailed(nil, "PROJECT-W8m4l", "Errors.Project.Member.Invalid")
}
if len(domain.CheckForInvalidRoles(member.Roles, domain.ProjectRolePrefix, c.zitadelRoles)) > 0 {
return nil, caos_errs.ThrowPreconditionFailed(nil, "PROJECT-3m9ds", "Errors.Project.Member.Invalid")
}
err := c.checkUserExists(ctx, addedMember.UserID, "")
if err != nil {
@@ -56,11 +57,12 @@ func (c *Commands) addProjectMember(ctx context.Context, projectAgg *eventstore.
//ChangeProjectMember updates an existing member
func (c *Commands) 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.Member.Invalid")
}
if len(domain.CheckForInvalidRoles(member.Roles, domain.ProjectRolePrefix, c.zitadelRoles)) > 0 {
return nil, caos_errs.ThrowPreconditionFailed(nil, "PROJECT-3m9d", "Errors.Project.Member.Invalid")
}
existingMember, err := c.projectMemberWriteModelByID(ctx, member.AggregateID, member.UserID, resourceOwner)
if err != nil {

View File

@@ -30,12 +30,18 @@ func (c *Commands) BulkAddedHumanExternalIDP(ctx context.Context, userID, resour
return err
}
func (c *Commands) addHumanExternalIDP(ctx context.Context, aggregate *eventstore.Aggregate, externalIDP *domain.ExternalIDP) (eventstore.EventPusher, error) {
func (c *Commands) addHumanExternalIDP(ctx context.Context, humanAgg *eventstore.Aggregate, externalIDP *domain.ExternalIDP) (eventstore.EventPusher, error) {
if !externalIDP.IsValid() {
return nil, caos_errs.ThrowPreconditionFailed(nil, "COMMAND-6m9Kd", "Errors.User.ExternalIDP.Invalid")
}
//TODO: check if idpconfig exists
return user.NewHumanExternalIDPAddedEvent(ctx, aggregate, externalIDP.IDPConfigID, externalIDP.DisplayName, externalIDP.ExternalUserID), nil
_, err := c.getOrgIDPConfigByID(ctx, externalIDP.IDPConfigID, humanAgg.ResourceOwner)
if caos_errs.IsNotFound(err) {
_, err = c.getIAMIDPConfigByID(ctx, externalIDP.IDPConfigID)
}
if err != nil {
return nil, err
}
return user.NewHumanExternalIDPAddedEvent(ctx, humanAgg, externalIDP.IDPConfigID, externalIDP.DisplayName, externalIDP.ExternalUserID), nil
}
func (c *Commands) RemoveHumanExternalIDP(ctx context.Context, externalIDP *domain.ExternalIDP) error {

View File

@@ -21,7 +21,7 @@ func (c *Commands) ChangeHumanPhone(ctx context.Context, phone *domain.Phone) (*
if err != nil {
return nil, err
}
if existingPhone.State == domain.PhoneStateUnspecified || existingPhone.State == domain.PhoneStateRemoved {
if !existingPhone.State.Exists() {
return nil, caos_errs.ThrowNotFound(nil, "COMMAND-aM9cs", "Errors.User.Phone.NotFound")
}
@@ -66,7 +66,7 @@ func (c *Commands) VerifyHumanPhone(ctx context.Context, userID, code, resourceo
if err != nil {
return err
}
if existingCode.Code == nil || existingCode.State == domain.PhoneStateUnspecified || existingCode.State == domain.PhoneStateRemoved {
if !existingCode.State.Exists() {
return caos_errs.ThrowNotFound(nil, "COMMAND-Rsj8c", "Errors.User.Code.NotFound")
}
@@ -92,8 +92,7 @@ func (c *Commands) CreateHumanPhoneVerificationCode(ctx context.Context, userID,
return err
}
//TODO: code like the following if is written many times find way to simplify
if existingPhone.State == domain.PhoneStateUnspecified || existingPhone.State == domain.PhoneStateRemoved {
if !existingPhone.State.Exists() {
return caos_errs.ThrowNotFound(nil, "COMMAND-2b7Hf", "Errors.User.Phone.NotFound")
}
if existingPhone.IsPhoneVerified {
@@ -115,7 +114,7 @@ func (c *Commands) HumanPhoneVerificationCodeSent(ctx context.Context, orgID, us
if err != nil {
return err
}
if existingPhone.State == domain.PhoneStateUnspecified || existingPhone.State == domain.PhoneStateRemoved {
if !existingPhone.State.Exists() {
return caos_errs.ThrowNotFound(nil, "COMMAND-66n8J", "Errors.User.Phone.NotFound")
}
@@ -133,7 +132,7 @@ func (c *Commands) RemoveHumanPhone(ctx context.Context, userID, resourceOwner s
if err != nil {
return err
}
if existingPhone.State == domain.PhoneStateUnspecified || existingPhone.State == domain.PhoneStateRemoved {
if !existingPhone.State.Exists() {
return caos_errs.ThrowNotFound(nil, "COMMAND-p6rsc", "Errors.User.Phone.NotFound")
}

View File

@@ -2,6 +2,7 @@ package command
import (
"context"
"github.com/caos/logging"
"github.com/caos/zitadel/internal/eventstore"
"github.com/caos/zitadel/internal/domain"
@@ -165,7 +166,7 @@ func (c *Commands) HumanVerifyU2FSetup(ctx context.Context, userID, resourceowne
usr_repo.NewHumanU2FVerifiedEvent(
ctx,
userAgg,
verifyWebAuthN.WebauthNTokenID, //TODO: webAuthN andverifyWebAuthN same TokenID?
verifyWebAuthN.WebauthNTokenID,
webAuthN.WebAuthNTokenName,
webAuthN.AttestationType,
webAuthN.KeyID,
@@ -191,7 +192,7 @@ func (c *Commands) HumanHumanPasswordlessSetup(ctx context.Context, userID, reso
usr_repo.NewHumanPasswordlessVerifiedEvent(
ctx,
userAgg,
verifyWebAuthN.WebauthNTokenID, //TODO: webAuthN andverifyWebAuthN same TokenID?
verifyWebAuthN.WebauthNTokenID,
webAuthN.WebAuthNTokenName,
webAuthN.AttestationType,
webAuthN.KeyID,
@@ -305,10 +306,23 @@ func (c *Commands) HumanFinishU2FLogin(ctx context.Context, userID, resourceOwne
userAgg, token, signCount, err := c.finishWebAuthNLogin(ctx, userID, resourceOwner, credentialData, webAuthNLogin, u2fTokens, isLoginUI)
if err != nil {
_, pushErr := c.eventstore.PushEvents(ctx,
usr_repo.NewHumanU2FCheckFailedEvent(
ctx,
userAgg,
authRequestDomainToAuthRequestInfo(authRequest),
),
)
logging.Log("EVENT-33M9f").OnError(pushErr).WithField("userID", userID).Warn("could not push failed passwordless check event")
return err
}
_, err = c.eventstore.PushEvents(ctx,
usr_repo.NewHumanU2FCheckSucceededEvent(
ctx,
userAgg,
authRequestDomainToAuthRequestInfo(authRequest),
),
usr_repo.NewHumanU2FSignCountChangedEvent(
ctx,
userAgg,
@@ -333,10 +347,23 @@ func (c *Commands) HumanFinishPasswordlessLogin(ctx context.Context, userID, res
userAgg, token, signCount, err := c.finishWebAuthNLogin(ctx, userID, resourceOwner, credentialData, webAuthNLogin, passwordlessTokens, isLoginUI)
if err != nil {
_, pushErr := c.eventstore.PushEvents(ctx,
usr_repo.NewHumanPasswordlessCheckFailedEvent(
ctx,
userAgg,
authRequestDomainToAuthRequestInfo(authRequest),
),
)
logging.Log("EVENT-33M9f").OnError(pushErr).WithField("userID", userID).Warn("could not push failed passwordless check event")
return err
}
_, err = c.eventstore.PushEvents(ctx,
usr_repo.NewHumanU2FCheckSucceededEvent(
ctx,
userAgg,
authRequestDomainToAuthRequestInfo(authRequest),
),
usr_repo.NewHumanPasswordlessSignCountChangedEvent(
ctx,
userAgg,

View File

@@ -24,7 +24,6 @@ func (c *Commands) AddMachine(ctx context.Context, orgID string, machine *domain
if err != nil {
return nil, err
}
//TODO: adlerhurst are no machines allowed in global org? or what if I create an org which allowes all suffixes?
if !orgIAMPolicy.UserLoginMustBeDomain {
return nil, caos_errs.ThrowInvalidArgument(nil, "COMMAND-6M0ds", "Errors.User.Invalid")
}