feat: new projects (#1207)

* fix: project events

* fix: project events

* fix: project events

* fix: eventmapper

* fix: project commands

* fix: project role commands

* fix: project command side

* fix: oidc application

* fix: oidc application

* fix: reduce

* fix: reduce

* fix: project member

* fix: project grant command side

* fix: application command side

* fix: project grant member remove

* Update internal/v2/command/project.go

Co-authored-by: Livio Amstutz <livio.a@gmail.com>

* Update internal/v2/command/project.go

Co-authored-by: Livio Amstutz <livio.a@gmail.com>

* Update internal/v2/command/project_application.go

Co-authored-by: Livio Amstutz <livio.a@gmail.com>

* Update internal/v2/command/project_application.go

Co-authored-by: Livio Amstutz <livio.a@gmail.com>

* Update internal/v2/command/project_application.go

Co-authored-by: Livio Amstutz <livio.a@gmail.com>

* fix: oidc application string pw

* fix: project events

* fix: project grant member

* feat: change application to interface

Co-authored-by: Livio Amstutz <livio.a@gmail.com>
This commit is contained in:
Fabi 2021-01-28 06:35:26 +01:00 committed by GitHub
parent dfcb96d6a3
commit c65331df1a
No known key found for this signature in database
GPG Key ID: 4AEE18F83AFDEB23
58 changed files with 3746 additions and 965 deletions

View File

@ -2,6 +2,7 @@ package management
import ( import (
"context" "context"
"github.com/caos/zitadel/internal/api/authz"
"github.com/golang/protobuf/ptypes/empty" "github.com/golang/protobuf/ptypes/empty"
@ -25,49 +26,43 @@ func (s *Server) ApplicationByID(ctx context.Context, in *management.Application
} }
func (s *Server) CreateOIDCApplication(ctx context.Context, in *management.OIDCApplicationCreate) (*management.Application, error) { func (s *Server) CreateOIDCApplication(ctx context.Context, in *management.OIDCApplicationCreate) (*management.Application, error) {
app, err := s.project.AddApplication(ctx, oidcAppCreateToModel(in)) app, err := s.command.AddOIDCApplication(ctx, oidcAppCreateToDomain(in), authz.GetCtxData(ctx).OrgID)
if err != nil { if err != nil {
return nil, err return nil, err
} }
return appFromModel(app), nil return oidcAppFromDomain(app), nil
} }
func (s *Server) UpdateApplication(ctx context.Context, in *management.ApplicationUpdate) (*management.Application, error) { func (s *Server) UpdateApplication(ctx context.Context, in *management.ApplicationUpdate) (*management.Application, error) {
app, err := s.project.ChangeApplication(ctx, appUpdateToModel(in)) app, err := s.command.ChangeApplication(ctx, in.ProjectId, appUpdateToDomain(in), authz.GetCtxData(ctx).OrgID)
if err != nil { if err != nil {
return nil, err return nil, err
} }
return appFromModel(app), nil return appFromDomain(app), nil
} }
func (s *Server) DeactivateApplication(ctx context.Context, in *management.ApplicationID) (*management.Application, error) { func (s *Server) DeactivateApplication(ctx context.Context, in *management.ApplicationID) (*empty.Empty, error) {
app, err := s.project.DeactivateApplication(ctx, in.ProjectId, in.Id) err := s.command.DeactivateApplication(ctx, in.ProjectId, in.Id, authz.GetCtxData(ctx).OrgID)
if err != nil { return &empty.Empty{}, err
return nil, err
}
return appFromModel(app), nil
} }
func (s *Server) ReactivateApplication(ctx context.Context, in *management.ApplicationID) (*management.Application, error) { func (s *Server) ReactivateApplication(ctx context.Context, in *management.ApplicationID) (*empty.Empty, error) {
app, err := s.project.ReactivateApplication(ctx, in.ProjectId, in.Id) err := s.command.ReactivateApplication(ctx, in.ProjectId, in.Id, authz.GetCtxData(ctx).OrgID)
if err != nil { return &empty.Empty{}, err
return nil, err
}
return appFromModel(app), nil
} }
func (s *Server) RemoveApplication(ctx context.Context, in *management.ApplicationID) (*empty.Empty, error) { func (s *Server) RemoveApplication(ctx context.Context, in *management.ApplicationID) (*empty.Empty, error) {
err := s.project.RemoveApplication(ctx, in.ProjectId, in.Id) err := s.command.RemoveApplication(ctx, in.ProjectId, in.Id, authz.GetCtxData(ctx).OrgID)
return &empty.Empty{}, err return &empty.Empty{}, err
} }
func (s *Server) UpdateApplicationOIDCConfig(ctx context.Context, in *management.OIDCConfigUpdate) (*management.OIDCConfig, error) { func (s *Server) UpdateApplicationOIDCConfig(ctx context.Context, in *management.OIDCConfigUpdate) (*management.OIDCConfig, error) {
config, err := s.project.ChangeOIDCConfig(ctx, oidcConfigUpdateToModel(in)) config, err := s.command.ChangeOIDCApplication(ctx, oidcConfigUpdateToDomain(in), authz.GetCtxData(ctx).OrgID)
if err != nil { if err != nil {
return nil, err return nil, err
} }
return oidcConfigFromModel(config), nil return oidcConfigFromDomain(config), nil
} }
func (s *Server) RegenerateOIDCClientSecret(ctx context.Context, in *management.ApplicationID) (*management.ClientSecret, error) { func (s *Server) RegenerateOIDCClientSecret(ctx context.Context, in *management.ApplicationID) (*management.ClientSecret, error) {
config, err := s.project.ChangeOIDConfigSecret(ctx, in.ProjectId, in.Id) config, err := s.command.ChangeOIDCApplicationSecret(ctx, in.ProjectId, in.Id, authz.GetCtxData(ctx).ResourceOwner)
if err != nil { if err != nil {
return nil, err return nil, err
} }

View File

@ -2,6 +2,8 @@ package management
import ( import (
"encoding/json" "encoding/json"
"github.com/caos/zitadel/internal/v2/domain"
"google.golang.org/protobuf/types/known/timestamppb"
"github.com/caos/logging" "github.com/caos/logging"
"github.com/golang/protobuf/ptypes" "github.com/golang/protobuf/ptypes"
@ -16,44 +18,46 @@ import (
"github.com/caos/zitadel/pkg/grpc/message" "github.com/caos/zitadel/pkg/grpc/message"
) )
func appFromModel(app *proj_model.Application) *management.Application { func appFromDomain(app domain.Application) *management.Application {
changeDate, err := ptypes.TimestampProto(app.ChangeDate) return &management.Application{
logging.Log("GRPC-di7rw").OnError(err).Debug("unable to parse timestamp") Id: app.GetAppID(),
State: appStateFromDomain(app.GetState()),
Name: app.GetApplicationName(),
}
}
func oidcAppFromDomain(app *domain.OIDCApp) *management.Application {
return &management.Application{ return &management.Application{
Id: app.AppID, Id: app.AppID,
State: appStateFromModel(app.State), State: appStateFromDomain(app.State),
ChangeDate: changeDate, ChangeDate: timestamppb.New(app.ChangeDate),
Name: app.Name, Name: app.AppName,
Sequence: app.Sequence, Sequence: app.Sequence,
AppConfig: appConfigFromModel(app), AppConfig: oidcAppConfigFromDomain(app),
} }
} }
func appConfigFromModel(app *proj_model.Application) management.AppConfig { func oidcAppConfigFromDomain(app *domain.OIDCApp) management.AppConfig {
if app.Type == proj_model.AppTypeOIDC { return &management.Application_OidcConfig{
return &management.Application_OidcConfig{ OidcConfig: oidcConfigFromDomain(app),
OidcConfig: oidcConfigFromModel(app.OIDCConfig),
}
} }
return nil
} }
func oidcConfigFromModel(config *proj_model.OIDCConfig) *management.OIDCConfig { func oidcConfigFromDomain(config *domain.OIDCApp) *management.OIDCConfig {
return &management.OIDCConfig{ return &management.OIDCConfig{
RedirectUris: config.RedirectUris, RedirectUris: config.RedirectUris,
ResponseTypes: oidcResponseTypesFromModel(config.ResponseTypes), ResponseTypes: oidcResponseTypesFromDomain(config.ResponseTypes),
GrantTypes: oidcGrantTypesFromModel(config.GrantTypes), GrantTypes: oidcGrantTypesFromDomain(config.GrantTypes),
ApplicationType: oidcApplicationTypeFromModel(config.ApplicationType), ApplicationType: oidcApplicationTypeFromDomain(config.ApplicationType),
ClientId: config.ClientID, ClientId: config.ClientID,
ClientSecret: config.ClientSecretString, ClientSecret: config.ClientSecretString,
AuthMethodType: oidcAuthMethodTypeFromModel(config.AuthMethodType), AuthMethodType: oidcAuthMethodTypeFromDomain(config.AuthMethodType),
PostLogoutRedirectUris: config.PostLogoutRedirectUris, PostLogoutRedirectUris: config.PostLogoutRedirectUris,
Version: oidcVersionFromModel(config.OIDCVersion), Version: oidcVersionFromDomain(config.OIDCVersion),
NoneCompliant: config.Compliance.NoneCompliant, NoneCompliant: config.Compliance.NoneCompliant,
ComplianceProblems: complianceProblemsToLocalizedMessages(config.Compliance.Problems), ComplianceProblems: complianceProblemsToLocalizedMessages(config.Compliance.Problems),
DevMode: config.DevMode, DevMode: config.DevMode,
AccessTokenType: oidcTokenTypeFromModel(config.AccessTokenType), AccessTokenType: oidcTokenTypeFromDomain(config.AccessTokenType),
AccessTokenRoleAssertion: config.AccessTokenRoleAssertion, AccessTokenRoleAssertion: config.AccessTokenRoleAssertion,
IdTokenRoleAssertion: config.IDTokenRoleAssertion, IdTokenRoleAssertion: config.IDTokenRoleAssertion,
IdTokenUserinfoAssertion: config.IDTokenUserinfoAssertion, IdTokenUserinfoAssertion: config.IDTokenUserinfoAssertion,
@ -91,55 +95,49 @@ func complianceProblemsToLocalizedMessages(problems []string) []*message.Localiz
} }
func oidcAppCreateToModel(app *management.OIDCApplicationCreate) *proj_model.Application { func oidcAppCreateToDomain(app *management.OIDCApplicationCreate) *domain.OIDCApp {
return &proj_model.Application{ return &domain.OIDCApp{
ObjectRoot: models.ObjectRoot{ ObjectRoot: models.ObjectRoot{
AggregateID: app.ProjectId, AggregateID: app.ProjectId,
}, },
Name: app.Name, AppName: app.Name,
Type: proj_model.AppTypeOIDC, OIDCVersion: oidcVersionToDomain(app.Version),
OIDCConfig: &proj_model.OIDCConfig{ RedirectUris: app.RedirectUris,
OIDCVersion: oidcVersionToModel(app.Version), ResponseTypes: oidcResponseTypesToDomain(app.ResponseTypes),
RedirectUris: app.RedirectUris, GrantTypes: oidcGrantTypesToDomain(app.GrantTypes),
ResponseTypes: oidcResponseTypesToModel(app.ResponseTypes), ApplicationType: oidcApplicationTypeToDomain(app.ApplicationType),
GrantTypes: oidcGrantTypesToModel(app.GrantTypes), AuthMethodType: oidcAuthMethodTypeToDomain(app.AuthMethodType),
ApplicationType: oidcApplicationTypeToModel(app.ApplicationType), PostLogoutRedirectUris: app.PostLogoutRedirectUris,
AuthMethodType: oidcAuthMethodTypeToModel(app.AuthMethodType), DevMode: app.DevMode,
PostLogoutRedirectUris: app.PostLogoutRedirectUris, AccessTokenType: oidcTokenTypeToDomain(app.AccessTokenType),
DevMode: app.DevMode, AccessTokenRoleAssertion: app.AccessTokenRoleAssertion,
AccessTokenType: oidcTokenTypeToModel(app.AccessTokenType), IDTokenRoleAssertion: app.IdTokenRoleAssertion,
AccessTokenRoleAssertion: app.AccessTokenRoleAssertion, IDTokenUserinfoAssertion: app.IdTokenUserinfoAssertion,
IDTokenRoleAssertion: app.IdTokenRoleAssertion, ClockSkew: app.ClockSkew.AsDuration(),
IDTokenUserinfoAssertion: app.IdTokenUserinfoAssertion,
ClockSkew: app.ClockSkew.AsDuration(),
},
} }
} }
func appUpdateToModel(app *management.ApplicationUpdate) *proj_model.Application { func appUpdateToDomain(app *management.ApplicationUpdate) domain.Application {
return &proj_model.Application{ return &domain.ChangeApp{
ObjectRoot: models.ObjectRoot{ AppID: app.Id,
AggregateID: app.ProjectId, AppName: app.Name,
},
AppID: app.Id,
Name: app.Name,
} }
} }
func oidcConfigUpdateToModel(app *management.OIDCConfigUpdate) *proj_model.OIDCConfig { func oidcConfigUpdateToDomain(app *management.OIDCConfigUpdate) *domain.OIDCApp {
return &proj_model.OIDCConfig{ return &domain.OIDCApp{
ObjectRoot: models.ObjectRoot{ ObjectRoot: models.ObjectRoot{
AggregateID: app.ProjectId, AggregateID: app.ProjectId,
}, },
AppID: app.ApplicationId, AppID: app.ApplicationId,
RedirectUris: app.RedirectUris, RedirectUris: app.RedirectUris,
ResponseTypes: oidcResponseTypesToModel(app.ResponseTypes), ResponseTypes: oidcResponseTypesToDomain(app.ResponseTypes),
GrantTypes: oidcGrantTypesToModel(app.GrantTypes), GrantTypes: oidcGrantTypesToDomain(app.GrantTypes),
ApplicationType: oidcApplicationTypeToModel(app.ApplicationType), ApplicationType: oidcApplicationTypeToDomain(app.ApplicationType),
AuthMethodType: oidcAuthMethodTypeToModel(app.AuthMethodType), AuthMethodType: oidcAuthMethodTypeToDomain(app.AuthMethodType),
PostLogoutRedirectUris: app.PostLogoutRedirectUris, PostLogoutRedirectUris: app.PostLogoutRedirectUris,
DevMode: app.DevMode, DevMode: app.DevMode,
AccessTokenType: oidcTokenTypeToModel(app.AccessTokenType), AccessTokenType: oidcTokenTypeToDomain(app.AccessTokenType),
AccessTokenRoleAssertion: app.AccessTokenRoleAssertion, AccessTokenRoleAssertion: app.AccessTokenRoleAssertion,
IDTokenRoleAssertion: app.IdTokenRoleAssertion, IDTokenRoleAssertion: app.IdTokenRoleAssertion,
IDTokenUserinfoAssertion: app.IdTokenUserinfoAssertion, IDTokenUserinfoAssertion: app.IdTokenUserinfoAssertion,
@ -226,6 +224,17 @@ func applicationViewFromModel(application *proj_model.ApplicationView) *manageme
return converted return converted
} }
func appStateFromDomain(state domain.AppState) management.AppState {
switch state {
case domain.AppStateActive:
return management.AppState_APPSTATE_ACTIVE
case domain.AppStateInactive:
return management.AppState_APPSTATE_INACTIVE
default:
return management.AppState_APPSTATE_UNSPECIFIED
}
}
func appStateFromModel(state proj_model.AppState) management.AppState { func appStateFromModel(state proj_model.AppState) management.AppState {
switch state { switch state {
case proj_model.AppStateActive: case proj_model.AppStateActive:
@ -237,26 +246,42 @@ func appStateFromModel(state proj_model.AppState) management.AppState {
} }
} }
func oidcResponseTypesToModel(responseTypes []management.OIDCResponseType) []proj_model.OIDCResponseType { func oidcResponseTypesToDomain(responseTypes []management.OIDCResponseType) []domain.OIDCResponseType {
if responseTypes == nil || len(responseTypes) == 0 { if responseTypes == nil || len(responseTypes) == 0 {
return []proj_model.OIDCResponseType{proj_model.OIDCResponseTypeCode} return []domain.OIDCResponseType{domain.OIDCResponseTypeCode}
} }
oidcResponseTypes := make([]proj_model.OIDCResponseType, len(responseTypes)) oidcResponseTypes := make([]domain.OIDCResponseType, len(responseTypes))
for i, responseType := range responseTypes { for i, responseType := range responseTypes {
switch responseType { switch responseType {
case management.OIDCResponseType_OIDCRESPONSETYPE_CODE: case management.OIDCResponseType_OIDCRESPONSETYPE_CODE:
oidcResponseTypes[i] = proj_model.OIDCResponseTypeCode oidcResponseTypes[i] = domain.OIDCResponseTypeCode
case management.OIDCResponseType_OIDCRESPONSETYPE_ID_TOKEN: case management.OIDCResponseType_OIDCRESPONSETYPE_ID_TOKEN:
oidcResponseTypes[i] = proj_model.OIDCResponseTypeIDToken oidcResponseTypes[i] = domain.OIDCResponseTypeIDToken
case management.OIDCResponseType_OIDCRESPONSETYPE_ID_TOKEN_TOKEN: case management.OIDCResponseType_OIDCRESPONSETYPE_ID_TOKEN_TOKEN:
oidcResponseTypes[i] = proj_model.OIDCResponseTypeIDTokenToken oidcResponseTypes[i] = domain.OIDCResponseTypeIDTokenToken
} }
} }
return oidcResponseTypes return oidcResponseTypes
} }
func oidcResponseTypesFromDomain(responseTypes []domain.OIDCResponseType) []management.OIDCResponseType {
oidcResponseTypes := make([]management.OIDCResponseType, len(responseTypes))
for i, responseType := range responseTypes {
switch responseType {
case domain.OIDCResponseTypeCode:
oidcResponseTypes[i] = management.OIDCResponseType_OIDCRESPONSETYPE_CODE
case domain.OIDCResponseTypeIDToken:
oidcResponseTypes[i] = management.OIDCResponseType_OIDCRESPONSETYPE_ID_TOKEN
case domain.OIDCResponseTypeIDTokenToken:
oidcResponseTypes[i] = management.OIDCResponseType_OIDCRESPONSETYPE_ID_TOKEN_TOKEN
}
}
return oidcResponseTypes
}
func oidcResponseTypesFromModel(responseTypes []proj_model.OIDCResponseType) []management.OIDCResponseType { func oidcResponseTypesFromModel(responseTypes []proj_model.OIDCResponseType) []management.OIDCResponseType {
oidcResponseTypes := make([]management.OIDCResponseType, len(responseTypes)) oidcResponseTypes := make([]management.OIDCResponseType, len(responseTypes))
@ -274,20 +299,36 @@ func oidcResponseTypesFromModel(responseTypes []proj_model.OIDCResponseType) []m
return oidcResponseTypes return oidcResponseTypes
} }
func oidcGrantTypesToModel(grantTypes []management.OIDCGrantType) []proj_model.OIDCGrantType { func oidcGrantTypesToDomain(grantTypes []management.OIDCGrantType) []domain.OIDCGrantType {
if grantTypes == nil || len(grantTypes) == 0 { if grantTypes == nil || len(grantTypes) == 0 {
return []proj_model.OIDCGrantType{proj_model.OIDCGrantTypeAuthorizationCode} return []domain.OIDCGrantType{domain.OIDCGrantTypeAuthorizationCode}
} }
oidcGrantTypes := make([]proj_model.OIDCGrantType, len(grantTypes)) oidcGrantTypes := make([]domain.OIDCGrantType, len(grantTypes))
for i, grantType := range grantTypes { for i, grantType := range grantTypes {
switch grantType { switch grantType {
case management.OIDCGrantType_OIDCGRANTTYPE_AUTHORIZATION_CODE: case management.OIDCGrantType_OIDCGRANTTYPE_AUTHORIZATION_CODE:
oidcGrantTypes[i] = proj_model.OIDCGrantTypeAuthorizationCode oidcGrantTypes[i] = domain.OIDCGrantTypeAuthorizationCode
case management.OIDCGrantType_OIDCGRANTTYPE_IMPLICIT: case management.OIDCGrantType_OIDCGRANTTYPE_IMPLICIT:
oidcGrantTypes[i] = proj_model.OIDCGrantTypeImplicit oidcGrantTypes[i] = domain.OIDCGrantTypeImplicit
case management.OIDCGrantType_OIDCGRANTTYPE_REFRESH_TOKEN: case management.OIDCGrantType_OIDCGRANTTYPE_REFRESH_TOKEN:
oidcGrantTypes[i] = proj_model.OIDCGrantTypeRefreshToken oidcGrantTypes[i] = domain.OIDCGrantTypeRefreshToken
}
}
return oidcGrantTypes
}
func oidcGrantTypesFromDomain(grantTypes []domain.OIDCGrantType) []management.OIDCGrantType {
oidcGrantTypes := make([]management.OIDCGrantType, len(grantTypes))
for i, grantType := range grantTypes {
switch grantType {
case domain.OIDCGrantTypeAuthorizationCode:
oidcGrantTypes[i] = management.OIDCGrantType_OIDCGRANTTYPE_AUTHORIZATION_CODE
case domain.OIDCGrantTypeImplicit:
oidcGrantTypes[i] = management.OIDCGrantType_OIDCGRANTTYPE_IMPLICIT
case domain.OIDCGrantTypeRefreshToken:
oidcGrantTypes[i] = management.OIDCGrantType_OIDCGRANTTYPE_REFRESH_TOKEN
} }
} }
return oidcGrantTypes return oidcGrantTypes
@ -309,24 +350,37 @@ func oidcGrantTypesFromModel(grantTypes []proj_model.OIDCGrantType) []management
return oidcGrantTypes return oidcGrantTypes
} }
func oidcApplicationTypeToModel(appType management.OIDCApplicationType) proj_model.OIDCApplicationType { func oidcApplicationTypeToDomain(appType management.OIDCApplicationType) domain.OIDCApplicationType {
switch appType { switch appType {
case management.OIDCApplicationType_OIDCAPPLICATIONTYPE_WEB: case management.OIDCApplicationType_OIDCAPPLICATIONTYPE_WEB:
return proj_model.OIDCApplicationTypeWeb return domain.OIDCApplicationTypeWeb
case management.OIDCApplicationType_OIDCAPPLICATIONTYPE_USER_AGENT: case management.OIDCApplicationType_OIDCAPPLICATIONTYPE_USER_AGENT:
return proj_model.OIDCApplicationTypeUserAgent return domain.OIDCApplicationTypeUserAgent
case management.OIDCApplicationType_OIDCAPPLICATIONTYPE_NATIVE: case management.OIDCApplicationType_OIDCAPPLICATIONTYPE_NATIVE:
return proj_model.OIDCApplicationTypeNative return domain.OIDCApplicationTypeNative
} }
return proj_model.OIDCApplicationTypeWeb return domain.OIDCApplicationTypeWeb
} }
func oidcVersionToModel(version management.OIDCVersion) proj_model.OIDCVersion { func oidcVersionToDomain(version management.OIDCVersion) domain.OIDCVersion {
switch version { switch version {
case management.OIDCVersion_OIDCV1_0: case management.OIDCVersion_OIDCV1_0:
return proj_model.OIDCVersionV1 return domain.OIDCVersionV1
}
return domain.OIDCVersionV1
}
func oidcApplicationTypeFromDomain(appType domain.OIDCApplicationType) management.OIDCApplicationType {
switch appType {
case domain.OIDCApplicationTypeWeb:
return management.OIDCApplicationType_OIDCAPPLICATIONTYPE_WEB
case domain.OIDCApplicationTypeUserAgent:
return management.OIDCApplicationType_OIDCAPPLICATIONTYPE_USER_AGENT
case domain.OIDCApplicationTypeNative:
return management.OIDCApplicationType_OIDCAPPLICATIONTYPE_NATIVE
default:
return management.OIDCApplicationType_OIDCAPPLICATIONTYPE_WEB
} }
return proj_model.OIDCVersionV1
} }
func oidcApplicationTypeFromModel(appType proj_model.OIDCApplicationType) management.OIDCApplicationType { func oidcApplicationTypeFromModel(appType proj_model.OIDCApplicationType) management.OIDCApplicationType {
@ -342,16 +396,29 @@ func oidcApplicationTypeFromModel(appType proj_model.OIDCApplicationType) manage
} }
} }
func oidcAuthMethodTypeToModel(authType management.OIDCAuthMethodType) proj_model.OIDCAuthMethodType { func oidcAuthMethodTypeToDomain(authType management.OIDCAuthMethodType) domain.OIDCAuthMethodType {
switch authType { switch authType {
case management.OIDCAuthMethodType_OIDCAUTHMETHODTYPE_BASIC: case management.OIDCAuthMethodType_OIDCAUTHMETHODTYPE_BASIC:
return proj_model.OIDCAuthMethodTypeBasic return domain.OIDCAuthMethodTypeBasic
case management.OIDCAuthMethodType_OIDCAUTHMETHODTYPE_POST: case management.OIDCAuthMethodType_OIDCAUTHMETHODTYPE_POST:
return proj_model.OIDCAuthMethodTypePost return domain.OIDCAuthMethodTypePost
case management.OIDCAuthMethodType_OIDCAUTHMETHODTYPE_NONE: case management.OIDCAuthMethodType_OIDCAUTHMETHODTYPE_NONE:
return proj_model.OIDCAuthMethodTypeNone return domain.OIDCAuthMethodTypeNone
default: default:
return proj_model.OIDCAuthMethodTypeBasic return domain.OIDCAuthMethodTypeBasic
}
}
func oidcAuthMethodTypeFromDomain(authType domain.OIDCAuthMethodType) management.OIDCAuthMethodType {
switch authType {
case domain.OIDCAuthMethodTypeBasic:
return management.OIDCAuthMethodType_OIDCAUTHMETHODTYPE_BASIC
case domain.OIDCAuthMethodTypePost:
return management.OIDCAuthMethodType_OIDCAUTHMETHODTYPE_POST
case domain.OIDCAuthMethodTypeNone:
return management.OIDCAuthMethodType_OIDCAUTHMETHODTYPE_NONE
default:
return management.OIDCAuthMethodType_OIDCAUTHMETHODTYPE_BASIC
} }
} }
@ -368,14 +435,25 @@ func oidcAuthMethodTypeFromModel(authType proj_model.OIDCAuthMethodType) managem
} }
} }
func oidcTokenTypeToModel(tokenType management.OIDCTokenType) proj_model.OIDCTokenType { func oidcTokenTypeToDomain(tokenType management.OIDCTokenType) domain.OIDCTokenType {
switch tokenType { switch tokenType {
case management.OIDCTokenType_OIDCTokenType_Bearer: case management.OIDCTokenType_OIDCTokenType_Bearer:
return proj_model.OIDCTokenTypeBearer return domain.OIDCTokenTypeBearer
case management.OIDCTokenType_OIDCTokenType_JWT: case management.OIDCTokenType_OIDCTokenType_JWT:
return proj_model.OIDCTokenTypeJWT return domain.OIDCTokenTypeJWT
default: default:
return proj_model.OIDCTokenTypeBearer return domain.OIDCTokenTypeBearer
}
}
func oidcTokenTypeFromDomain(tokenType domain.OIDCTokenType) management.OIDCTokenType {
switch tokenType {
case domain.OIDCTokenTypeBearer:
return management.OIDCTokenType_OIDCTokenType_Bearer
case domain.OIDCTokenTypeJWT:
return management.OIDCTokenType_OIDCTokenType_JWT
default:
return management.OIDCTokenType_OIDCTokenType_Bearer
} }
} }
@ -390,6 +468,15 @@ func oidcTokenTypeFromModel(tokenType proj_model.OIDCTokenType) management.OIDCT
} }
} }
func oidcVersionFromDomain(version domain.OIDCVersion) management.OIDCVersion {
switch version {
case domain.OIDCVersionV1:
return management.OIDCVersion_OIDCV1_0
default:
return management.OIDCVersion_OIDCV1_0
}
}
func oidcVersionFromModel(version proj_model.OIDCVersion) management.OIDCVersion { func oidcVersionFromModel(version proj_model.OIDCVersion) management.OIDCVersion {
switch version { switch version {
case proj_model.OIDCVersionV1: case proj_model.OIDCVersionV1:

View File

@ -12,36 +12,31 @@ import (
) )
func (s *Server) CreateProject(ctx context.Context, in *management.ProjectCreateRequest) (*management.Project, error) { func (s *Server) CreateProject(ctx context.Context, in *management.ProjectCreateRequest) (*management.Project, error) {
project, err := s.project.CreateProject(ctx, projectCreateToModel(in)) ctxData := authz.GetCtxData(ctx)
project, err := s.command.AddProject(ctx, projectCreateToDomain(in), ctxData.ResourceOwner, ctxData.UserID)
if err != nil { if err != nil {
return nil, err return nil, err
} }
return projectFromModel(project), nil return projectFromDomain(project), nil
} }
func (s *Server) UpdateProject(ctx context.Context, in *management.ProjectUpdateRequest) (*management.Project, error) { func (s *Server) UpdateProject(ctx context.Context, in *management.ProjectUpdateRequest) (*management.Project, error) {
project, err := s.project.UpdateProject(ctx, projectUpdateToModel(in)) project, err := s.command.ChangeProject(ctx, projectUpdateToDomain(in), authz.GetCtxData(ctx).ResourceOwner)
if err != nil { if err != nil {
return nil, err return nil, err
} }
return projectFromModel(project), nil return projectFromDomain(project), nil
} }
func (s *Server) DeactivateProject(ctx context.Context, in *management.ProjectID) (*management.Project, error) { func (s *Server) DeactivateProject(ctx context.Context, in *management.ProjectID) (*empty.Empty, error) {
project, err := s.project.DeactivateProject(ctx, in.Id) err := s.command.DeactivateProject(ctx, in.Id, authz.GetCtxData(ctx).ResourceOwner)
if err != nil { return &empty.Empty{}, err
return nil, err
}
return projectFromModel(project), nil
} }
func (s *Server) ReactivateProject(ctx context.Context, in *management.ProjectID) (*management.Project, error) { func (s *Server) ReactivateProject(ctx context.Context, in *management.ProjectID) (*empty.Empty, error) {
project, err := s.project.ReactivateProject(ctx, in.Id) err := s.command.ReactivateProject(ctx, in.Id, authz.GetCtxData(ctx).ResourceOwner)
if err != nil { return &empty.Empty{}, err
return nil, err
}
return projectFromModel(project), nil
} }
func (s *Server) RemoveProject(ctx context.Context, in *management.ProjectID) (*empty.Empty, error) { func (s *Server) RemoveProject(ctx context.Context, in *management.ProjectID) (*empty.Empty, error) {
err := s.project.RemoveProject(ctx, in.Id) err := s.command.RemoveProject(ctx, in.Id, authz.GetCtxData(ctx).OrgID)
return &empty.Empty{}, err return &empty.Empty{}, err
} }
@ -82,28 +77,28 @@ func (s *Server) GetGrantedProjectByID(ctx context.Context, in *management.Proje
} }
func (s *Server) AddProjectRole(ctx context.Context, in *management.ProjectRoleAdd) (*management.ProjectRole, error) { func (s *Server) AddProjectRole(ctx context.Context, in *management.ProjectRoleAdd) (*management.ProjectRole, error) {
role, err := s.project.AddProjectRole(ctx, projectRoleAddToModel(in)) role, err := s.command.AddProjectRole(ctx, projectRoleAddToDomain(in), authz.GetCtxData(ctx).OrgID)
if err != nil { if err != nil {
return nil, err return nil, err
} }
return projectRoleFromModel(role), nil return projectRoleFromDomain(role), nil
} }
func (s *Server) BulkAddProjectRole(ctx context.Context, in *management.ProjectRoleAddBulk) (*empty.Empty, error) { func (s *Server) BulkAddProjectRole(ctx context.Context, in *management.ProjectRoleAddBulk) (*empty.Empty, error) {
err := s.project.BulkAddProjectRole(ctx, projectRoleAddBulkToModel(in)) err := s.command.BulkAddProjectRole(ctx, in.Id, authz.GetCtxData(ctx).OrgID, projectRoleAddBulkToDomain(in))
return &empty.Empty{}, err return &empty.Empty{}, err
} }
func (s *Server) ChangeProjectRole(ctx context.Context, in *management.ProjectRoleChange) (*management.ProjectRole, error) { func (s *Server) ChangeProjectRole(ctx context.Context, in *management.ProjectRoleChange) (*management.ProjectRole, error) {
role, err := s.project.ChangeProjectRole(ctx, projectRoleChangeToModel(in)) role, err := s.command.ChangeProjectRole(ctx, projectRoleChangeToDomain(in), authz.GetCtxData(ctx).OrgID)
if err != nil { if err != nil {
return nil, err return nil, err
} }
return projectRoleFromModel(role), nil return projectRoleFromDomain(role), nil
} }
func (s *Server) RemoveProjectRole(ctx context.Context, in *management.ProjectRoleRemove) (*empty.Empty, error) { func (s *Server) RemoveProjectRole(ctx context.Context, in *management.ProjectRoleRemove) (*empty.Empty, error) {
err := s.project.RemoveProjectRole(ctx, in.Id, in.Key) err := s.command.RemoveProjectRole(ctx, in.Id, in.Key, authz.GetCtxData(ctx).OrgID)
return &empty.Empty{}, err return &empty.Empty{}, err
} }

View File

@ -2,6 +2,8 @@ package management
import ( import (
"encoding/json" "encoding/json"
"github.com/caos/zitadel/internal/v2/domain"
"google.golang.org/protobuf/types/known/timestamppb"
"github.com/caos/logging" "github.com/caos/logging"
"github.com/golang/protobuf/ptypes" "github.com/golang/protobuf/ptypes"
@ -14,18 +16,11 @@ import (
"github.com/caos/zitadel/pkg/grpc/message" "github.com/caos/zitadel/pkg/grpc/message"
) )
func projectFromModel(project *proj_model.Project) *management.Project { func projectFromDomain(project *domain.Project) *management.Project {
creationDate, err := ptypes.TimestampProto(project.CreationDate)
logging.Log("GRPC-iejs3").OnError(err).Debug("unable to parse timestamp")
changeDate, err := ptypes.TimestampProto(project.ChangeDate)
logging.Log("GRPC-di7rw").OnError(err).Debug("unable to parse timestamp")
return &management.Project{ return &management.Project{
Id: project.AggregateID, Id: project.AggregateID,
State: projectStateFromModel(project.State), State: projectStateFromDomain(project.State),
CreationDate: creationDate, ChangeDate: timestamppb.New(project.ChangeDate),
ChangeDate: changeDate,
Name: project.Name, Name: project.Name,
Sequence: project.Sequence, Sequence: project.Sequence,
ProjectRoleAssertion: project.ProjectRoleAssertion, ProjectRoleAssertion: project.ProjectRoleAssertion,
@ -110,6 +105,17 @@ func projectRoleViewFromModel(role *proj_model.ProjectRoleView) *management.Proj
} }
} }
func projectStateFromDomain(state domain.ProjectState) management.ProjectState {
switch state {
case domain.ProjectStateActive:
return management.ProjectState_PROJECTSTATE_ACTIVE
case domain.ProjectStateInactive:
return management.ProjectState_PROJECTSTATE_INACTIVE
default:
return management.ProjectState_PROJECTSTATE_UNSPECIFIED
}
}
func projectStateFromModel(state proj_model.ProjectState) management.ProjectState { func projectStateFromModel(state proj_model.ProjectState) management.ProjectState {
switch state { switch state {
case proj_model.ProjectStateActive: case proj_model.ProjectStateActive:
@ -121,16 +127,16 @@ func projectStateFromModel(state proj_model.ProjectState) management.ProjectStat
} }
} }
func projectCreateToModel(project *management.ProjectCreateRequest) *proj_model.Project { func projectCreateToDomain(project *management.ProjectCreateRequest) *domain.Project {
return &proj_model.Project{ return &domain.Project{
Name: project.Name, Name: project.Name,
ProjectRoleAssertion: project.ProjectRoleAssertion, ProjectRoleAssertion: project.ProjectRoleAssertion,
ProjectRoleCheck: project.ProjectRoleCheck, ProjectRoleCheck: project.ProjectRoleCheck,
} }
} }
func projectUpdateToModel(project *management.ProjectUpdateRequest) *proj_model.Project { func projectUpdateToDomain(project *management.ProjectUpdateRequest) *domain.Project {
return &proj_model.Project{ return &domain.Project{
ObjectRoot: models.ObjectRoot{ ObjectRoot: models.ObjectRoot{
AggregateID: project.Id, AggregateID: project.Id,
}, },
@ -140,27 +146,20 @@ func projectUpdateToModel(project *management.ProjectUpdateRequest) *proj_model.
} }
} }
func projectRoleFromModel(role *proj_model.ProjectRole) *management.ProjectRole { func projectRoleFromDomain(role *domain.ProjectRole) *management.ProjectRole {
creationDate, err := ptypes.TimestampProto(role.CreationDate)
logging.Log("GRPC-due83").OnError(err).Debug("unable to parse timestamp")
changeDate, err := ptypes.TimestampProto(role.ChangeDate)
logging.Log("GRPC-id93s").OnError(err).Debug("unable to parse timestamp")
return &management.ProjectRole{ return &management.ProjectRole{
CreationDate: creationDate, ChangeDate: timestamppb.New(role.ChangeDate),
ChangeDate: changeDate, Sequence: role.Sequence,
Sequence: role.Sequence, Key: role.Key,
Key: role.Key, DisplayName: role.DisplayName,
DisplayName: role.DisplayName, Group: role.Group,
Group: role.Group,
} }
} }
func projectRoleAddBulkToModel(bulk *management.ProjectRoleAddBulk) []*proj_model.ProjectRole { func projectRoleAddBulkToDomain(bulk *management.ProjectRoleAddBulk) []*domain.ProjectRole {
roles := make([]*proj_model.ProjectRole, len(bulk.ProjectRoles)) roles := make([]*domain.ProjectRole, len(bulk.ProjectRoles))
for i, role := range bulk.ProjectRoles { for i, role := range bulk.ProjectRoles {
roles[i] = &proj_model.ProjectRole{ roles[i] = &domain.ProjectRole{
ObjectRoot: models.ObjectRoot{ ObjectRoot: models.ObjectRoot{
AggregateID: bulk.Id, AggregateID: bulk.Id,
}, },
@ -172,8 +171,8 @@ func projectRoleAddBulkToModel(bulk *management.ProjectRoleAddBulk) []*proj_mode
return roles return roles
} }
func projectRoleAddToModel(role *management.ProjectRoleAdd) *proj_model.ProjectRole { func projectRoleAddToDomain(role *management.ProjectRoleAdd) *domain.ProjectRole {
return &proj_model.ProjectRole{ return &domain.ProjectRole{
ObjectRoot: models.ObjectRoot{ ObjectRoot: models.ObjectRoot{
AggregateID: role.Id, AggregateID: role.Id,
}, },
@ -183,8 +182,8 @@ func projectRoleAddToModel(role *management.ProjectRoleAdd) *proj_model.ProjectR
} }
} }
func projectRoleChangeToModel(role *management.ProjectRoleChange) *proj_model.ProjectRole { func projectRoleChangeToDomain(role *management.ProjectRoleChange) *domain.ProjectRole {
return &proj_model.ProjectRole{ return &domain.ProjectRole{
ObjectRoot: models.ObjectRoot{ ObjectRoot: models.ObjectRoot{
AggregateID: role.Id, AggregateID: role.Id,
}, },

View File

@ -29,36 +29,30 @@ func (s *Server) ProjectGrantByID(ctx context.Context, in *management.ProjectGra
} }
func (s *Server) CreateProjectGrant(ctx context.Context, in *management.ProjectGrantCreate) (*management.ProjectGrant, error) { func (s *Server) CreateProjectGrant(ctx context.Context, in *management.ProjectGrantCreate) (*management.ProjectGrant, error) {
grant, err := s.project.AddProjectGrant(ctx, projectGrantCreateToModel(in)) grant, err := s.command.AddProjectGrant(ctx, projectGrantCreateToDomain(in), authz.GetCtxData(ctx).OrgID)
if err != nil { if err != nil {
return nil, err return nil, err
} }
return projectGrantFromModel(grant), nil return projectGrantFromDomain(grant), nil
} }
func (s *Server) UpdateProjectGrant(ctx context.Context, in *management.ProjectGrantUpdate) (*management.ProjectGrant, error) { func (s *Server) UpdateProjectGrant(ctx context.Context, in *management.ProjectGrantUpdate) (*management.ProjectGrant, error) {
grant, err := s.project.ChangeProjectGrant(ctx, projectGrantUpdateToModel(in)) grant, err := s.command.ChangeProjectGrant(ctx, projectGrantUpdateToDomain(in), authz.GetCtxData(ctx).OrgID)
if err != nil { if err != nil {
return nil, err return nil, err
} }
return projectGrantFromModel(grant), nil return projectGrantFromDomain(grant), nil
} }
func (s *Server) DeactivateProjectGrant(ctx context.Context, in *management.ProjectGrantID) (*management.ProjectGrant, error) { func (s *Server) DeactivateProjectGrant(ctx context.Context, in *management.ProjectGrantID) (*empty.Empty, error) {
grant, err := s.project.DeactivateProjectGrant(ctx, in.ProjectId, in.Id) err := s.command.DeactivateProjectGrant(ctx, in.ProjectId, in.Id, authz.GetCtxData(ctx).OrgID)
if err != nil { return &empty.Empty{}, err
return nil, err
}
return projectGrantFromModel(grant), nil
} }
func (s *Server) ReactivateProjectGrant(ctx context.Context, in *management.ProjectGrantID) (*management.ProjectGrant, error) { func (s *Server) ReactivateProjectGrant(ctx context.Context, in *management.ProjectGrantID) (*empty.Empty, error) {
grant, err := s.project.ReactivateProjectGrant(ctx, in.ProjectId, in.Id) err := s.command.ReactivateProjectGrant(ctx, in.ProjectId, in.Id, authz.GetCtxData(ctx).OrgID)
if err != nil { return &empty.Empty{}, err
return nil, err
}
return projectGrantFromModel(grant), nil
} }
func (s *Server) RemoveProjectGrant(ctx context.Context, in *management.ProjectGrantID) (*empty.Empty, error) { func (s *Server) RemoveProjectGrant(ctx context.Context, in *management.ProjectGrantID) (*empty.Empty, error) {
err := s.project.RemoveProjectGrant(ctx, in.ProjectId, in.Id) err := s.command.RemoveProjectGrant(ctx, in.ProjectId, in.Id, authz.GetCtxData(ctx).OrgID)
return &empty.Empty{}, err return &empty.Empty{}, err
} }

View File

@ -2,6 +2,8 @@ package management
import ( import (
"github.com/caos/logging" "github.com/caos/logging"
"github.com/caos/zitadel/internal/v2/domain"
"google.golang.org/protobuf/types/known/timestamppb"
"github.com/golang/protobuf/ptypes" "github.com/golang/protobuf/ptypes"
@ -11,6 +13,19 @@ import (
"github.com/caos/zitadel/pkg/grpc/management" "github.com/caos/zitadel/pkg/grpc/management"
) )
func projectGrantFromDomain(grant *domain.ProjectGrant) *management.ProjectGrant {
return &management.ProjectGrant{
Id: grant.GrantID,
State: projectGrantStateFromDomain(grant.State),
CreationDate: timestamppb.New(grant.CreationDate),
ChangeDate: timestamppb.New(grant.ChangeDate),
GrantedOrgId: grant.GrantedOrgID,
RoleKeys: grant.RoleKeys,
Sequence: grant.Sequence,
ProjectId: grant.AggregateID,
}
}
func projectGrantFromModel(grant *proj_model.ProjectGrant) *management.ProjectGrant { func projectGrantFromModel(grant *proj_model.ProjectGrant) *management.ProjectGrant {
creationDate, err := ptypes.TimestampProto(grant.CreationDate) creationDate, err := ptypes.TimestampProto(grant.CreationDate)
logging.Log("GRPC-8d73s").OnError(err).Debug("unable to parse timestamp") logging.Log("GRPC-8d73s").OnError(err).Debug("unable to parse timestamp")
@ -30,8 +45,8 @@ func projectGrantFromModel(grant *proj_model.ProjectGrant) *management.ProjectGr
} }
} }
func projectGrantCreateToModel(grant *management.ProjectGrantCreate) *proj_model.ProjectGrant { func projectGrantCreateToDomain(grant *management.ProjectGrantCreate) *domain.ProjectGrant {
return &proj_model.ProjectGrant{ return &domain.ProjectGrant{
ObjectRoot: models.ObjectRoot{ ObjectRoot: models.ObjectRoot{
AggregateID: grant.ProjectId, AggregateID: grant.ProjectId,
}, },
@ -40,8 +55,8 @@ func projectGrantCreateToModel(grant *management.ProjectGrantCreate) *proj_model
} }
} }
func projectGrantUpdateToModel(grant *management.ProjectGrantUpdate) *proj_model.ProjectGrant { func projectGrantUpdateToDomain(grant *management.ProjectGrantUpdate) *domain.ProjectGrant {
return &proj_model.ProjectGrant{ return &domain.ProjectGrant{
ObjectRoot: models.ObjectRoot{ ObjectRoot: models.ObjectRoot{
AggregateID: grant.ProjectId, AggregateID: grant.ProjectId,
}, },
@ -134,6 +149,16 @@ func projectGrantFromGrantedProjectModel(project *proj_model.ProjectGrantView) *
} }
} }
func projectGrantStateFromDomain(state domain.ProjectGrantState) management.ProjectGrantState {
switch state {
case domain.ProjectGrantStateActive:
return management.ProjectGrantState_PROJECTGRANTSTATE_ACTIVE
case domain.ProjectGrantStateInactive:
return management.ProjectGrantState_PROJECTGRANTSTATE_INACTIVE
default:
return management.ProjectGrantState_PROJECTGRANTSTATE_UNSPECIFIED
}
}
func projectGrantStateFromModel(state proj_model.ProjectGrantState) management.ProjectGrantState { func projectGrantStateFromModel(state proj_model.ProjectGrantState) management.ProjectGrantState {
switch state { switch state {
case proj_model.ProjectGrantStateActive: case proj_model.ProjectGrantStateActive:

View File

@ -2,6 +2,7 @@ package management
import ( import (
"context" "context"
"github.com/caos/zitadel/internal/api/authz"
"github.com/golang/protobuf/ptypes/empty" "github.com/golang/protobuf/ptypes/empty"
@ -21,22 +22,22 @@ func (s *Server) SearchProjectGrantMembers(ctx context.Context, in *management.P
} }
func (s *Server) AddProjectGrantMember(ctx context.Context, in *management.ProjectGrantMemberAdd) (*management.ProjectGrantMember, error) { func (s *Server) AddProjectGrantMember(ctx context.Context, in *management.ProjectGrantMemberAdd) (*management.ProjectGrantMember, error) {
member, err := s.project.AddProjectGrantMember(ctx, projectGrantMemberAddToModel(in)) member, err := s.command.AddProjectGrantMember(ctx, projectGrantMemberAddToDomain(in), authz.GetCtxData(ctx).OrgID)
if err != nil { if err != nil {
return nil, err return nil, err
} }
return projectGrantMemberFromModel(member), nil return projectGrantMemberFromDomain(member), nil
} }
func (s *Server) ChangeProjectGrantMember(ctx context.Context, in *management.ProjectGrantMemberChange) (*management.ProjectGrantMember, error) { func (s *Server) ChangeProjectGrantMember(ctx context.Context, in *management.ProjectGrantMemberChange) (*management.ProjectGrantMember, error) {
member, err := s.project.ChangeProjectGrantMember(ctx, projectGrantMemberChangeToModel(in)) member, err := s.command.ChangeProjectGrantMember(ctx, projectGrantMemberChangeToDomain(in), authz.GetCtxData(ctx).OrgID)
if err != nil { if err != nil {
return nil, err return nil, err
} }
return projectGrantMemberFromModel(member), nil return projectGrantMemberFromDomain(member), nil
} }
func (s *Server) RemoveProjectGrantMember(ctx context.Context, in *management.ProjectGrantMemberRemove) (*empty.Empty, error) { func (s *Server) RemoveProjectGrantMember(ctx context.Context, in *management.ProjectGrantMemberRemove) (*empty.Empty, error) {
err := s.project.RemoveProjectGrantMember(ctx, in.ProjectId, in.GrantId, in.UserId) err := s.command.RemoveProjectGrantMember(ctx, in.ProjectId, in.UserId, in.GrantId, authz.GetCtxData(ctx).OrgID)
return &empty.Empty{}, err return &empty.Empty{}, err
} }

View File

@ -3,13 +3,25 @@ package management
import ( import (
"github.com/caos/logging" "github.com/caos/logging"
"github.com/caos/zitadel/internal/model" "github.com/caos/zitadel/internal/model"
"github.com/caos/zitadel/internal/v2/domain"
"github.com/golang/protobuf/ptypes" "github.com/golang/protobuf/ptypes"
"google.golang.org/protobuf/types/known/timestamppb"
"github.com/caos/zitadel/internal/eventstore/models" "github.com/caos/zitadel/internal/eventstore/models"
proj_model "github.com/caos/zitadel/internal/project/model" proj_model "github.com/caos/zitadel/internal/project/model"
"github.com/caos/zitadel/pkg/grpc/management" "github.com/caos/zitadel/pkg/grpc/management"
) )
func projectGrantMemberFromDomain(member *domain.ProjectGrantMember) *management.ProjectGrantMember {
return &management.ProjectGrantMember{
CreationDate: timestamppb.New(member.CreationDate),
ChangeDate: timestamppb.New(member.ChangeDate),
Sequence: member.Sequence,
UserId: member.UserID,
Roles: member.Roles,
}
}
func projectGrantMemberFromModel(member *proj_model.ProjectGrantMember) *management.ProjectGrantMember { func projectGrantMemberFromModel(member *proj_model.ProjectGrantMember) *management.ProjectGrantMember {
creationDate, err := ptypes.TimestampProto(member.CreationDate) creationDate, err := ptypes.TimestampProto(member.CreationDate)
logging.Log("GRPC-7du3s").OnError(err).Debug("unable to parse timestamp") logging.Log("GRPC-7du3s").OnError(err).Debug("unable to parse timestamp")
@ -26,8 +38,8 @@ func projectGrantMemberFromModel(member *proj_model.ProjectGrantMember) *managem
} }
} }
func projectGrantMemberAddToModel(member *management.ProjectGrantMemberAdd) *proj_model.ProjectGrantMember { func projectGrantMemberAddToDomain(member *management.ProjectGrantMemberAdd) *domain.ProjectGrantMember {
return &proj_model.ProjectGrantMember{ return &domain.ProjectGrantMember{
ObjectRoot: models.ObjectRoot{ ObjectRoot: models.ObjectRoot{
AggregateID: member.ProjectId, AggregateID: member.ProjectId,
}, },
@ -37,8 +49,8 @@ func projectGrantMemberAddToModel(member *management.ProjectGrantMemberAdd) *pro
} }
} }
func projectGrantMemberChangeToModel(member *management.ProjectGrantMemberChange) *proj_model.ProjectGrantMember { func projectGrantMemberChangeToDomain(member *management.ProjectGrantMemberChange) *domain.ProjectGrantMember {
return &proj_model.ProjectGrantMember{ return &domain.ProjectGrantMember{
ObjectRoot: models.ObjectRoot{ ObjectRoot: models.ObjectRoot{
AggregateID: member.ProjectId, AggregateID: member.ProjectId,
}, },

View File

@ -2,6 +2,7 @@ package management
import ( import (
"context" "context"
"github.com/caos/zitadel/internal/api/authz"
"github.com/golang/protobuf/ptypes/empty" "github.com/golang/protobuf/ptypes/empty"
@ -27,22 +28,22 @@ func (s *Server) SearchProjectMembers(ctx context.Context, in *management.Projec
} }
func (s *Server) AddProjectMember(ctx context.Context, in *management.ProjectMemberAdd) (*management.ProjectMember, error) { func (s *Server) AddProjectMember(ctx context.Context, in *management.ProjectMemberAdd) (*management.ProjectMember, error) {
member, err := s.project.AddProjectMember(ctx, projectMemberAddToModel(in)) member, err := s.command.AddProjectMember(ctx, projectMemberAddToDomain(in), authz.GetCtxData(ctx).OrgID)
if err != nil { if err != nil {
return nil, err return nil, err
} }
return projectMemberFromModel(member), nil return projectMemberFromDomain(member), nil
} }
func (s *Server) ChangeProjectMember(ctx context.Context, in *management.ProjectMemberChange) (*management.ProjectMember, error) { func (s *Server) ChangeProjectMember(ctx context.Context, in *management.ProjectMemberChange) (*management.ProjectMember, error) {
member, err := s.project.ChangeProjectMember(ctx, projectMemberChangeToModel(in)) member, err := s.command.ChangeProjectMember(ctx, projectMemberChangeToDomain(in), authz.GetCtxData(ctx).OrgID)
if err != nil { if err != nil {
return nil, err return nil, err
} }
return projectMemberFromModel(member), nil return projectMemberFromDomain(member), nil
} }
func (s *Server) RemoveProjectMember(ctx context.Context, in *management.ProjectMemberRemove) (*empty.Empty, error) { func (s *Server) RemoveProjectMember(ctx context.Context, in *management.ProjectMemberRemove) (*empty.Empty, error) {
err := s.project.RemoveProjectMember(ctx, in.Id, in.UserId) err := s.command.RemoveProjectMember(ctx, in.Id, in.UserId, authz.GetCtxData(ctx).OrgID)
return &empty.Empty{}, err return &empty.Empty{}, err
} }

View File

@ -2,31 +2,27 @@ package management
import ( import (
"github.com/caos/logging" "github.com/caos/logging"
"github.com/caos/zitadel/internal/v2/domain"
"github.com/golang/protobuf/ptypes" "github.com/golang/protobuf/ptypes"
"google.golang.org/protobuf/types/known/timestamppb"
"github.com/caos/zitadel/internal/eventstore/models" "github.com/caos/zitadel/internal/eventstore/models"
proj_model "github.com/caos/zitadel/internal/project/model" proj_model "github.com/caos/zitadel/internal/project/model"
"github.com/caos/zitadel/pkg/grpc/management" "github.com/caos/zitadel/pkg/grpc/management"
) )
func projectMemberFromModel(member *proj_model.ProjectMember) *management.ProjectMember { func projectMemberFromDomain(member *domain.Member) *management.ProjectMember {
creationDate, err := ptypes.TimestampProto(member.CreationDate)
logging.Log("GRPC-kd8re").OnError(err).Debug("unable to parse timestamp")
changeDate, err := ptypes.TimestampProto(member.ChangeDate)
logging.Log("GRPC-dlei3").OnError(err).Debug("unable to parse timestamp")
return &management.ProjectMember{ return &management.ProjectMember{
CreationDate: creationDate, CreationDate: timestamppb.New(member.CreationDate),
ChangeDate: changeDate, ChangeDate: timestamppb.New(member.ChangeDate),
Sequence: member.Sequence, Sequence: member.Sequence,
UserId: member.UserID, UserId: member.UserID,
Roles: member.Roles, Roles: member.Roles,
} }
} }
func projectMemberAddToModel(member *management.ProjectMemberAdd) *proj_model.ProjectMember { func projectMemberAddToDomain(member *management.ProjectMemberAdd) *domain.Member {
return &proj_model.ProjectMember{ return &domain.Member{
ObjectRoot: models.ObjectRoot{ ObjectRoot: models.ObjectRoot{
AggregateID: member.Id, AggregateID: member.Id,
}, },
@ -35,8 +31,8 @@ func projectMemberAddToModel(member *management.ProjectMemberAdd) *proj_model.Pr
} }
} }
func projectMemberChangeToModel(member *management.ProjectMemberChange) *proj_model.ProjectMember { func projectMemberChangeToDomain(member *management.ProjectMemberChange) *domain.Member {
return &proj_model.ProjectMember{ return &domain.Member{
ObjectRoot: models.ObjectRoot{ ObjectRoot: models.ObjectRoot{
AggregateID: member.Id, AggregateID: member.Id,
}, },

View File

@ -115,7 +115,7 @@ func (factory *SearchQueryBuilder) build() (*repository.SearchQuery, error) {
} }
return &repository.SearchQuery{ return &repository.SearchQuery{
Columns: repository.Columns(factory.columns), Columns: factory.columns,
Limit: factory.limit, Limit: factory.limit,
Desc: factory.desc, Desc: factory.desc,
Filters: filters, Filters: filters,

View File

@ -9,18 +9,13 @@ import (
"github.com/caos/zitadel/internal/api/authz" "github.com/caos/zitadel/internal/api/authz"
caos_errs "github.com/caos/zitadel/internal/errors" caos_errs "github.com/caos/zitadel/internal/errors"
es_int "github.com/caos/zitadel/internal/eventstore" es_int "github.com/caos/zitadel/internal/eventstore"
"github.com/caos/zitadel/internal/eventstore/models"
es_models "github.com/caos/zitadel/internal/eventstore/models"
es_sdk "github.com/caos/zitadel/internal/eventstore/sdk"
iam_event "github.com/caos/zitadel/internal/iam/repository/eventsourcing" iam_event "github.com/caos/zitadel/internal/iam/repository/eventsourcing"
"github.com/caos/zitadel/internal/management/repository/eventsourcing/view" "github.com/caos/zitadel/internal/management/repository/eventsourcing/view"
global_model "github.com/caos/zitadel/internal/model" global_model "github.com/caos/zitadel/internal/model"
proj_model "github.com/caos/zitadel/internal/project/model" proj_model "github.com/caos/zitadel/internal/project/model"
proj_event "github.com/caos/zitadel/internal/project/repository/eventsourcing" proj_event "github.com/caos/zitadel/internal/project/repository/eventsourcing"
es_proj_model "github.com/caos/zitadel/internal/project/repository/eventsourcing/model"
"github.com/caos/zitadel/internal/project/repository/view/model" "github.com/caos/zitadel/internal/project/repository/view/model"
usr_event "github.com/caos/zitadel/internal/user/repository/eventsourcing" usr_event "github.com/caos/zitadel/internal/user/repository/eventsourcing"
usr_grant_model "github.com/caos/zitadel/internal/usergrant/model"
usr_grant_event "github.com/caos/zitadel/internal/usergrant/repository/eventsourcing" usr_grant_event "github.com/caos/zitadel/internal/usergrant/repository/eventsourcing"
) )
@ -68,54 +63,6 @@ func (repo *ProjectRepo) ProjectByID(ctx context.Context, id string) (*proj_mode
return model.ProjectToModel(project), nil return model.ProjectToModel(project), nil
} }
func (repo *ProjectRepo) CreateProject(ctx context.Context, project *proj_model.Project) (*proj_model.Project, error) {
ctxData := authz.GetCtxData(ctx)
iam, err := repo.IAMEvents.IAMByID(ctx, repo.IAMID)
if err != nil {
return nil, err
}
return repo.ProjectEvents.CreateProject(ctx, project, iam.GlobalOrgID == ctxData.OrgID)
}
func (repo *ProjectRepo) UpdateProject(ctx context.Context, project *proj_model.Project) (*proj_model.Project, error) {
return repo.ProjectEvents.UpdateProject(ctx, project)
}
func (repo *ProjectRepo) DeactivateProject(ctx context.Context, id string) (*proj_model.Project, error) {
return repo.ProjectEvents.DeactivateProject(ctx, id)
}
func (repo *ProjectRepo) ReactivateProject(ctx context.Context, id string) (*proj_model.Project, error) {
return repo.ProjectEvents.ReactivateProject(ctx, id)
}
func (repo *ProjectRepo) RemoveProject(ctx context.Context, projectID string) error {
proj := proj_model.NewProject(projectID)
aggregates := make([]*es_models.Aggregate, 0)
project, agg, err := repo.ProjectEvents.PrepareRemoveProject(ctx, proj)
if err != nil {
return err
}
aggregates = append(aggregates, agg)
// remove user_grants
usergrants, err := repo.View.UserGrantsByProjectID(projectID)
if err != nil {
return err
}
for _, grant := range usergrants {
_, aggs, err := repo.UserGrantEvents.PrepareRemoveUserGrant(ctx, grant.ID, true)
if err != nil {
return err
}
for _, agg := range aggs {
aggregates = append(aggregates, agg)
}
}
return es_sdk.PushAggregates(ctx, repo.Eventstore.PushAggregates, project.AppendEvents, aggregates...)
}
func (repo *ProjectRepo) SearchProjects(ctx context.Context, request *proj_model.ProjectViewSearchRequest) (*proj_model.ProjectViewSearchResponse, error) { func (repo *ProjectRepo) SearchProjects(ctx context.Context, request *proj_model.ProjectViewSearchRequest) (*proj_model.ProjectViewSearchResponse, error) {
request.EnsureLimit(repo.SearchLimit) request.EnsureLimit(repo.SearchLimit)
sequence, sequenceErr := repo.View.GetLatestProjectSequence("") sequence, sequenceErr := repo.View.GetLatestProjectSequence("")
@ -183,19 +130,6 @@ func (repo *ProjectRepo) ProjectMemberByID(ctx context.Context, projectID, userI
return model.ProjectMemberToModel(member), nil return model.ProjectMemberToModel(member), nil
} }
func (repo *ProjectRepo) AddProjectMember(ctx context.Context, member *proj_model.ProjectMember) (*proj_model.ProjectMember, error) {
return repo.ProjectEvents.AddProjectMember(ctx, member)
}
func (repo *ProjectRepo) ChangeProjectMember(ctx context.Context, member *proj_model.ProjectMember) (*proj_model.ProjectMember, error) {
return repo.ProjectEvents.ChangeProjectMember(ctx, member)
}
func (repo *ProjectRepo) RemoveProjectMember(ctx context.Context, projectID, userID string) error {
member := proj_model.NewProjectMember(projectID, userID)
return repo.ProjectEvents.RemoveProjectMember(ctx, member)
}
func (repo *ProjectRepo) SearchProjectMembers(ctx context.Context, request *proj_model.ProjectMemberSearchRequest) (*proj_model.ProjectMemberSearchResponse, error) { func (repo *ProjectRepo) SearchProjectMembers(ctx context.Context, request *proj_model.ProjectMemberSearchRequest) (*proj_model.ProjectMemberSearchResponse, error) {
request.EnsureLimit(repo.SearchLimit) request.EnsureLimit(repo.SearchLimit)
sequence, sequenceErr := repo.View.GetLatestProjectMemberSequence("") sequence, sequenceErr := repo.View.GetLatestProjectMemberSequence("")
@ -217,56 +151,6 @@ func (repo *ProjectRepo) SearchProjectMembers(ctx context.Context, request *proj
return result, nil return result, nil
} }
func (repo *ProjectRepo) AddProjectRole(ctx context.Context, role *proj_model.ProjectRole) (*proj_model.ProjectRole, error) {
return repo.ProjectEvents.AddProjectRoles(ctx, role)
}
func (repo *ProjectRepo) BulkAddProjectRole(ctx context.Context, roles []*proj_model.ProjectRole) error {
_, err := repo.ProjectEvents.AddProjectRoles(ctx, roles...)
return err
}
func (repo *ProjectRepo) ChangeProjectRole(ctx context.Context, member *proj_model.ProjectRole) (*proj_model.ProjectRole, error) {
return repo.ProjectEvents.ChangeProjectRole(ctx, member)
}
func (repo *ProjectRepo) RemoveProjectRole(ctx context.Context, projectID, key string) error {
role := proj_model.NewProjectRole(projectID, key)
aggregates := make([]*es_models.Aggregate, 0)
project, agg, err := repo.ProjectEvents.PrepareRemoveProjectRole(ctx, role)
if err != nil {
return err
}
aggregates = append(aggregates, agg)
usergrants, err := repo.View.UserGrantsByProjectIDAndRoleKey(projectID, key)
if err != nil {
return err
}
for _, grant := range usergrants {
changed := &usr_grant_model.UserGrant{
ObjectRoot: models.ObjectRoot{AggregateID: grant.ID, Sequence: grant.Sequence, ResourceOwner: grant.ResourceOwner},
RoleKeys: grant.RoleKeys,
ProjectID: grant.ProjectID,
UserID: grant.UserID,
}
changed.RemoveRoleKeyIfExisting(key)
_, agg, err := repo.UserGrantEvents.PrepareChangeUserGrant(ctx, changed, true)
if err != nil {
return err
}
aggregates = append(aggregates, agg)
}
if err != nil {
return err
}
err = es_sdk.PushAggregates(ctx, repo.Eventstore.PushAggregates, project.AppendEvents, aggregates...)
if err != nil {
return err
}
return nil
}
func (repo *ProjectRepo) SearchProjectRoles(ctx context.Context, projectID string, request *proj_model.ProjectRoleSearchRequest) (*proj_model.ProjectRoleSearchResponse, error) { func (repo *ProjectRepo) SearchProjectRoles(ctx context.Context, projectID string, request *proj_model.ProjectRoleSearchRequest) (*proj_model.ProjectRoleSearchResponse, error) {
request.EnsureLimit(repo.SearchLimit) request.EnsureLimit(repo.SearchLimit)
request.AppendProjectQuery(projectID) request.AppendProjectQuery(projectID)
@ -343,27 +227,6 @@ func (repo *ProjectRepo) ApplicationByID(ctx context.Context, projectID, appID s
return model.ApplicationViewToModel(app), nil return model.ApplicationViewToModel(app), nil
} }
func (repo *ProjectRepo) AddApplication(ctx context.Context, app *proj_model.Application) (*proj_model.Application, error) {
return repo.ProjectEvents.AddApplication(ctx, app)
}
func (repo *ProjectRepo) ChangeApplication(ctx context.Context, app *proj_model.Application) (*proj_model.Application, error) {
return repo.ProjectEvents.ChangeApplication(ctx, app)
}
func (repo *ProjectRepo) DeactivateApplication(ctx context.Context, projectID, appID string) (*proj_model.Application, error) {
return repo.ProjectEvents.DeactivateApplication(ctx, projectID, appID)
}
func (repo *ProjectRepo) ReactivateApplication(ctx context.Context, projectID, appID string) (*proj_model.Application, error) {
return repo.ProjectEvents.ReactivateApplication(ctx, projectID, appID)
}
func (repo *ProjectRepo) RemoveApplication(ctx context.Context, projectID, appID string) error {
app := proj_model.NewApplication(projectID, appID)
return repo.ProjectEvents.RemoveApplication(ctx, app)
}
func (repo *ProjectRepo) SearchApplications(ctx context.Context, request *proj_model.ApplicationSearchRequest) (*proj_model.ApplicationSearchResponse, error) { func (repo *ProjectRepo) SearchApplications(ctx context.Context, request *proj_model.ApplicationSearchRequest) (*proj_model.ApplicationSearchResponse, error) {
request.EnsureLimit(repo.SearchLimit) request.EnsureLimit(repo.SearchLimit)
sequence, sequenceErr := repo.View.GetLatestApplicationSequence("") sequence, sequenceErr := repo.View.GetLatestApplicationSequence("")
@ -405,10 +268,6 @@ func (repo *ProjectRepo) ApplicationChanges(ctx context.Context, id string, appI
return changes, nil return changes, nil
} }
func (repo *ProjectRepo) ChangeOIDCConfig(ctx context.Context, config *proj_model.OIDCConfig) (*proj_model.OIDCConfig, error) {
return repo.ProjectEvents.ChangeOIDCConfig(ctx, config)
}
func (repo *ProjectRepo) ChangeOIDConfigSecret(ctx context.Context, projectID, appID string) (*proj_model.OIDCConfig, error) { func (repo *ProjectRepo) ChangeOIDConfigSecret(ctx context.Context, projectID, appID string) (*proj_model.OIDCConfig, error) {
return repo.ProjectEvents.ChangeOIDCConfigSecret(ctx, projectID, appID) return repo.ProjectEvents.ChangeOIDCConfigSecret(ctx, projectID, appID)
} }
@ -493,102 +352,6 @@ func (repo *ProjectRepo) SearchGrantedProjects(ctx context.Context, request *pro
return result, nil return result, nil
} }
func (repo *ProjectRepo) AddProjectGrant(ctx context.Context, grant *proj_model.ProjectGrant) (*proj_model.ProjectGrant, error) {
return repo.ProjectEvents.AddProjectGrant(ctx, grant)
}
func (repo *ProjectRepo) ChangeProjectGrant(ctx context.Context, grant *proj_model.ProjectGrant) (*proj_model.ProjectGrant, error) {
project, aggFunc, removedRoles, err := repo.ProjectEvents.PrepareChangeProjectGrant(ctx, grant)
if err != nil {
return nil, err
}
agg, err := aggFunc(ctx)
if err != nil {
return nil, err
}
aggregates := make([]*es_models.Aggregate, 0)
aggregates = append(aggregates, agg)
usergrants, err := repo.View.UserGrantsByProjectID(grant.AggregateID)
if err != nil {
return nil, err
}
for _, grant := range usergrants {
changed := &usr_grant_model.UserGrant{
ObjectRoot: models.ObjectRoot{AggregateID: grant.ID, Sequence: grant.Sequence, ResourceOwner: grant.ResourceOwner},
RoleKeys: grant.RoleKeys,
ProjectID: grant.ProjectID,
UserID: grant.UserID,
}
roleDeleted := changed.RemoveRoleKeysIfExisting(removedRoles)
if roleDeleted {
_, agg, err := repo.UserGrantEvents.PrepareChangeUserGrant(ctx, changed, true)
if err != nil {
return nil, err
}
aggregates = append(aggregates, agg)
}
}
if err != nil {
return nil, err
}
err = es_sdk.PushAggregates(ctx, repo.Eventstore.PushAggregates, project.AppendEvents, aggregates...)
if err != nil {
return nil, err
}
if _, g := es_proj_model.GetProjectGrant(project.Grants, grant.GrantID); g != nil {
return es_proj_model.GrantToModel(g), nil
}
return nil, caos_errs.ThrowInternal(nil, "EVENT-dksi8", "Could not find app in list")
}
func (repo *ProjectRepo) DeactivateProjectGrant(ctx context.Context, projectID, grantID string) (*proj_model.ProjectGrant, error) {
return repo.ProjectEvents.DeactivateProjectGrant(ctx, projectID, grantID)
}
func (repo *ProjectRepo) ReactivateProjectGrant(ctx context.Context, projectID, grantID string) (*proj_model.ProjectGrant, error) {
return repo.ProjectEvents.ReactivateProjectGrant(ctx, projectID, grantID)
}
func (repo *ProjectRepo) RemoveProjectGrant(ctx context.Context, projectID, grantID string) error {
grant, err := repo.ProjectEvents.ProjectGrantByIDs(ctx, projectID, grantID)
if err != nil {
return err
}
aggregates := make([]*es_models.Aggregate, 0)
project, aggFunc, err := repo.ProjectEvents.PrepareRemoveProjectGrant(ctx, grant)
if err != nil {
return err
}
agg, err := aggFunc(ctx)
if err != nil {
return err
}
aggregates = append(aggregates, agg)
usergrants, err := repo.View.UserGrantsByOrgIDAndProjectID(grant.GrantedOrgID, projectID)
if err != nil {
return err
}
for _, grant := range usergrants {
_, grantAggregates, err := repo.UserGrantEvents.PrepareRemoveUserGrant(ctx, grant.ID, true)
if err != nil {
return err
}
for _, agg := range grantAggregates {
aggregates = append(aggregates, agg)
}
}
if err != nil {
return err
}
err = es_sdk.PushAggregates(ctx, repo.Eventstore.PushAggregates, project.AppendEvents, aggregates...)
if err != nil {
return err
}
return nil
}
func (repo *ProjectRepo) ProjectGrantMemberByID(ctx context.Context, projectID, userID string) (*proj_model.ProjectGrantMemberView, error) { func (repo *ProjectRepo) ProjectGrantMemberByID(ctx context.Context, projectID, userID string) (*proj_model.ProjectGrantMemberView, error) {
member, err := repo.View.ProjectGrantMemberByIDs(projectID, userID) member, err := repo.View.ProjectGrantMemberByIDs(projectID, userID)
if err != nil { if err != nil {
@ -597,19 +360,6 @@ func (repo *ProjectRepo) ProjectGrantMemberByID(ctx context.Context, projectID,
return model.ProjectGrantMemberToModel(member), nil return model.ProjectGrantMemberToModel(member), nil
} }
func (repo *ProjectRepo) AddProjectGrantMember(ctx context.Context, member *proj_model.ProjectGrantMember) (*proj_model.ProjectGrantMember, error) {
return repo.ProjectEvents.AddProjectGrantMember(ctx, member)
}
func (repo *ProjectRepo) ChangeProjectGrantMember(ctx context.Context, member *proj_model.ProjectGrantMember) (*proj_model.ProjectGrantMember, error) {
return repo.ProjectEvents.ChangeProjectGrantMember(ctx, member)
}
func (repo *ProjectRepo) RemoveProjectGrantMember(ctx context.Context, projectID, grantID, userID string) error {
member := proj_model.NewProjectGrantMember(projectID, grantID, userID)
return repo.ProjectEvents.RemoveProjectGrantMember(ctx, member)
}
func (repo *ProjectRepo) SearchProjectGrantMembers(ctx context.Context, request *proj_model.ProjectGrantMemberSearchRequest) (*proj_model.ProjectGrantMemberSearchResponse, error) { func (repo *ProjectRepo) SearchProjectGrantMembers(ctx context.Context, request *proj_model.ProjectGrantMemberSearchRequest) (*proj_model.ProjectGrantMemberSearchResponse, error) {
request.EnsureLimit(repo.SearchLimit) request.EnsureLimit(repo.SearchLimit)
sequence, sequenceErr := repo.View.GetLatestProjectGrantMemberSequence("") sequence, sequenceErr := repo.View.GetLatestProjectGrantMemberSequence("")

View File

@ -8,52 +8,26 @@ import (
type ProjectRepository interface { type ProjectRepository interface {
ProjectByID(ctx context.Context, id string) (*model.ProjectView, error) ProjectByID(ctx context.Context, id string) (*model.ProjectView, error)
CreateProject(ctx context.Context, project *model.Project) (*model.Project, error)
UpdateProject(ctx context.Context, project *model.Project) (*model.Project, error)
DeactivateProject(ctx context.Context, id string) (*model.Project, error)
ReactivateProject(ctx context.Context, id string) (*model.Project, error)
RemoveProject(ctx context.Context, id string) error
SearchProjects(ctx context.Context, request *model.ProjectViewSearchRequest) (*model.ProjectViewSearchResponse, error) SearchProjects(ctx context.Context, request *model.ProjectViewSearchRequest) (*model.ProjectViewSearchResponse, error)
SearchProjectGrants(ctx context.Context, request *model.ProjectGrantViewSearchRequest) (*model.ProjectGrantViewSearchResponse, error) SearchProjectGrants(ctx context.Context, request *model.ProjectGrantViewSearchRequest) (*model.ProjectGrantViewSearchResponse, error)
SearchGrantedProjects(ctx context.Context, request *model.ProjectGrantViewSearchRequest) (*model.ProjectGrantViewSearchResponse, error) SearchGrantedProjects(ctx context.Context, request *model.ProjectGrantViewSearchRequest) (*model.ProjectGrantViewSearchResponse, error)
ProjectGrantViewByID(ctx context.Context, grantID string) (*model.ProjectGrantView, error) ProjectGrantViewByID(ctx context.Context, grantID string) (*model.ProjectGrantView, error)
ProjectMemberByID(ctx context.Context, projectID, userID string) (*model.ProjectMemberView, error) ProjectMemberByID(ctx context.Context, projectID, userID string) (*model.ProjectMemberView, error)
AddProjectMember(ctx context.Context, member *model.ProjectMember) (*model.ProjectMember, error)
ChangeProjectMember(ctx context.Context, member *model.ProjectMember) (*model.ProjectMember, error)
RemoveProjectMember(ctx context.Context, projectID, userID string) error
SearchProjectMembers(ctx context.Context, request *model.ProjectMemberSearchRequest) (*model.ProjectMemberSearchResponse, error) SearchProjectMembers(ctx context.Context, request *model.ProjectMemberSearchRequest) (*model.ProjectMemberSearchResponse, error)
GetProjectMemberRoles(ctx context.Context) ([]string, error) GetProjectMemberRoles(ctx context.Context) ([]string, error)
AddProjectRole(ctx context.Context, role *model.ProjectRole) (*model.ProjectRole, error)
ChangeProjectRole(ctx context.Context, role *model.ProjectRole) (*model.ProjectRole, error)
RemoveProjectRole(ctx context.Context, projectID, key string) error
SearchProjectRoles(ctx context.Context, projectId string, request *model.ProjectRoleSearchRequest) (*model.ProjectRoleSearchResponse, error) SearchProjectRoles(ctx context.Context, projectId string, request *model.ProjectRoleSearchRequest) (*model.ProjectRoleSearchResponse, error)
ProjectChanges(ctx context.Context, id string, lastSequence uint64, limit uint64, sortAscending bool) (*model.ProjectChanges, error) ProjectChanges(ctx context.Context, id string, lastSequence uint64, limit uint64, sortAscending bool) (*model.ProjectChanges, error)
BulkAddProjectRole(ctx context.Context, role []*model.ProjectRole) error
ApplicationByID(ctx context.Context, projectID, appID string) (*model.ApplicationView, error) ApplicationByID(ctx context.Context, projectID, appID string) (*model.ApplicationView, error)
AddApplication(ctx context.Context, app *model.Application) (*model.Application, error)
ChangeApplication(ctx context.Context, app *model.Application) (*model.Application, error)
DeactivateApplication(ctx context.Context, projectID, appID string) (*model.Application, error)
ReactivateApplication(ctx context.Context, projectID, appID string) (*model.Application, error)
RemoveApplication(ctx context.Context, projectID, appID string) error
ChangeOIDCConfig(ctx context.Context, config *model.OIDCConfig) (*model.OIDCConfig, error)
ChangeOIDConfigSecret(ctx context.Context, projectID, appID string) (*model.OIDCConfig, error) ChangeOIDConfigSecret(ctx context.Context, projectID, appID string) (*model.OIDCConfig, error)
SearchApplications(ctx context.Context, request *model.ApplicationSearchRequest) (*model.ApplicationSearchResponse, error) SearchApplications(ctx context.Context, request *model.ApplicationSearchRequest) (*model.ApplicationSearchResponse, error)
ApplicationChanges(ctx context.Context, id string, secId string, lastSequence uint64, limit uint64, sortAscending bool) (*model.ApplicationChanges, error) ApplicationChanges(ctx context.Context, id string, secId string, lastSequence uint64, limit uint64, sortAscending bool) (*model.ApplicationChanges, error)
ProjectGrantByID(ctx context.Context, grantID string) (*model.ProjectGrantView, error) ProjectGrantByID(ctx context.Context, grantID string) (*model.ProjectGrantView, error)
AddProjectGrant(ctx context.Context, grant *model.ProjectGrant) (*model.ProjectGrant, error)
ChangeProjectGrant(ctx context.Context, grant *model.ProjectGrant) (*model.ProjectGrant, error)
DeactivateProjectGrant(ctx context.Context, projectID, grantID string) (*model.ProjectGrant, error)
ReactivateProjectGrant(ctx context.Context, projectID, grantID string) (*model.ProjectGrant, error)
RemoveProjectGrant(ctx context.Context, projectID, grantID string) error
SearchProjectGrantMembers(ctx context.Context, request *model.ProjectGrantMemberSearchRequest) (*model.ProjectGrantMemberSearchResponse, error) SearchProjectGrantMembers(ctx context.Context, request *model.ProjectGrantMemberSearchRequest) (*model.ProjectGrantMemberSearchResponse, error)
ProjectGrantMemberByID(ctx context.Context, projectID, userID string) (*model.ProjectGrantMemberView, error) ProjectGrantMemberByID(ctx context.Context, projectID, userID string) (*model.ProjectGrantMemberView, error)
AddProjectGrantMember(ctx context.Context, member *model.ProjectGrantMember) (*model.ProjectGrantMember, error)
ChangeProjectGrantMember(ctx context.Context, member *model.ProjectGrantMember) (*model.ProjectGrantMember, error)
RemoveProjectGrantMember(ctx context.Context, projectID, grantID, userID string) error
GetProjectGrantMemberRoles() []string GetProjectGrantMemberRoles() []string
} }

View File

@ -213,19 +213,19 @@ func (es *ProjectEventstore) ProjectMemberByIDs(ctx context.Context, member *pro
if _, m := project.GetMember(member.UserID); m != nil { if _, m := project.GetMember(member.UserID); m != nil {
return m, nil return m, nil
} }
return nil, caos_errs.ThrowNotFound(nil, "EVENT-3udjs", "Errors.Project.MemberNotFound") return nil, caos_errs.ThrowNotFound(nil, "EVENT-3udjs", "Errors.Project.Member.NotFound")
} }
func (es *ProjectEventstore) AddProjectMember(ctx context.Context, member *proj_model.ProjectMember) (*proj_model.ProjectMember, error) { func (es *ProjectEventstore) AddProjectMember(ctx context.Context, member *proj_model.ProjectMember) (*proj_model.ProjectMember, error) {
if !member.IsValid() { if !member.IsValid() {
return nil, caos_errs.ThrowPreconditionFailed(nil, "EVENT-2OWkC", "Errors.Project.MemberInvalid") return nil, caos_errs.ThrowPreconditionFailed(nil, "EVENT-2OWkC", "Errors.Project.Member.Invalid")
} }
existingProject, err := es.ProjectByID(ctx, member.AggregateID) existingProject, err := es.ProjectByID(ctx, member.AggregateID)
if err != nil { if err != nil {
return nil, err return nil, err
} }
if _, m := existingProject.GetMember(member.UserID); m != nil { if _, m := existingProject.GetMember(member.UserID); m != nil {
return nil, caos_errs.ThrowAlreadyExists(nil, "EVENT-idke6", "Errors.Project.MemberAlreadyExists") return nil, caos_errs.ThrowAlreadyExists(nil, "EVENT-idke6", "Errors.Project.Member.AlreadyExists")
} }
repoProject := model.ProjectFromModel(existingProject) repoProject := model.ProjectFromModel(existingProject)
repoMember := model.ProjectMemberFromModel(member) repoMember := model.ProjectMemberFromModel(member)
@ -245,14 +245,14 @@ func (es *ProjectEventstore) AddProjectMember(ctx context.Context, member *proj_
func (es *ProjectEventstore) ChangeProjectMember(ctx context.Context, member *proj_model.ProjectMember) (*proj_model.ProjectMember, error) { func (es *ProjectEventstore) ChangeProjectMember(ctx context.Context, member *proj_model.ProjectMember) (*proj_model.ProjectMember, error) {
if !member.IsValid() { if !member.IsValid() {
return nil, caos_errs.ThrowPreconditionFailed(nil, "EVENT-Buh04", "Errors.Project.MemberInvalid") return nil, caos_errs.ThrowPreconditionFailed(nil, "EVENT-Buh04", "Errors.Project.Member.Invalid")
} }
existingProject, err := es.ProjectByID(ctx, member.AggregateID) existingProject, err := es.ProjectByID(ctx, member.AggregateID)
if err != nil { if err != nil {
return nil, err return nil, err
} }
if _, m := existingProject.GetMember(member.UserID); m == nil { if _, m := existingProject.GetMember(member.UserID); m == nil {
return nil, caos_errs.ThrowPreconditionFailed(nil, "EVENT-oe39f", "Errors.Project.MemberNotExisting") return nil, caos_errs.ThrowPreconditionFailed(nil, "EVENT-oe39f", "Errors.Project.Member.NotExisting")
} }
repoProject := model.ProjectFromModel(existingProject) repoProject := model.ProjectFromModel(existingProject)
repoMember := model.ProjectMemberFromModel(member) repoMember := model.ProjectMemberFromModel(member)
@ -272,14 +272,14 @@ func (es *ProjectEventstore) ChangeProjectMember(ctx context.Context, member *pr
func (es *ProjectEventstore) RemoveProjectMember(ctx context.Context, member *proj_model.ProjectMember) error { func (es *ProjectEventstore) RemoveProjectMember(ctx context.Context, member *proj_model.ProjectMember) error {
if member.UserID == "" { if member.UserID == "" {
return caos_errs.ThrowPreconditionFailed(nil, "EVENT-d43fs", "Errors.Project.MemberInvalid") return caos_errs.ThrowPreconditionFailed(nil, "EVENT-d43fs", "Errors.Project.Member.Invalid")
} }
existingProject, err := es.ProjectByID(ctx, member.AggregateID) existingProject, err := es.ProjectByID(ctx, member.AggregateID)
if err != nil { if err != nil {
return err return err
} }
if _, m := existingProject.GetMember(member.UserID); m == nil { if _, m := existingProject.GetMember(member.UserID); m == nil {
return caos_errs.ThrowPreconditionFailed(nil, "EVENT-swf34", "Errors.Project.MemberNotExisting") return caos_errs.ThrowPreconditionFailed(nil, "EVENT-swf34", "Errors.Project.Member.NotExisting")
} }
repoProject := model.ProjectFromModel(existingProject) repoProject := model.ProjectFromModel(existingProject)
repoMember := model.ProjectMemberFromModel(member) repoMember := model.ProjectMemberFromModel(member)
@ -295,14 +295,14 @@ func (es *ProjectEventstore) RemoveProjectMember(ctx context.Context, member *pr
func (es *ProjectEventstore) PrepareRemoveProjectMember(ctx context.Context, member *proj_model.ProjectMember) (*model.ProjectMember, *es_models.Aggregate, error) { func (es *ProjectEventstore) PrepareRemoveProjectMember(ctx context.Context, member *proj_model.ProjectMember) (*model.ProjectMember, *es_models.Aggregate, error) {
if member.UserID == "" { if member.UserID == "" {
return nil, nil, caos_errs.ThrowPreconditionFailed(nil, "EVENT-tCXHE", "Errors.Project.MemberInvalid") return nil, nil, caos_errs.ThrowPreconditionFailed(nil, "EVENT-tCXHE", "Errors.Project.Member.Invalid")
} }
existingProject, err := es.ProjectByID(ctx, member.AggregateID) existingProject, err := es.ProjectByID(ctx, member.AggregateID)
if err != nil { if err != nil {
return nil, nil, err return nil, nil, err
} }
if _, m := existingProject.GetMember(member.UserID); m == nil { if _, m := existingProject.GetMember(member.UserID); m == nil {
return nil, nil, caos_errs.ThrowPreconditionFailed(nil, "EVENT-wPcg5", "Errors.Project.MemberNotExisting") return nil, nil, caos_errs.ThrowPreconditionFailed(nil, "EVENT-wPcg5", "Errors.Project.Member.NotExisting")
} }
repoProject := model.ProjectFromModel(existingProject) repoProject := model.ProjectFromModel(existingProject)
repoMember := model.ProjectMemberFromModel(member) repoMember := model.ProjectMemberFromModel(member)
@ -322,7 +322,7 @@ func (es *ProjectEventstore) AddProjectRoles(ctx context.Context, roles ...*proj
} }
for _, role := range roles { for _, role := range roles {
if !role.IsValid() { if !role.IsValid() {
return nil, caos_errs.ThrowPreconditionFailed(nil, "EVENT-iduG4", "Errors.Project.RoleInvalid") return nil, caos_errs.ThrowPreconditionFailed(nil, "EVENT-iduG4", "Errors.Project.Role.Invalid")
} }
} }
existingProject, err := es.ProjectByID(ctx, roles[0].AggregateID) existingProject, err := es.ProjectByID(ctx, roles[0].AggregateID)
@ -331,7 +331,7 @@ func (es *ProjectEventstore) AddProjectRoles(ctx context.Context, roles ...*proj
} }
for _, role := range roles { for _, role := range roles {
if existingProject.ContainsRole(role) { if existingProject.ContainsRole(role) {
return nil, caos_errs.ThrowAlreadyExists(nil, "EVENT-sk35t", "Errors.Project.RoleAlreadyExists") return nil, caos_errs.ThrowAlreadyExists(nil, "EVENT-sk35t", "Errors.Project.Role.AlreadyExists")
} }
} }
@ -354,14 +354,14 @@ func (es *ProjectEventstore) AddProjectRoles(ctx context.Context, roles ...*proj
func (es *ProjectEventstore) ChangeProjectRole(ctx context.Context, role *proj_model.ProjectRole) (*proj_model.ProjectRole, error) { func (es *ProjectEventstore) ChangeProjectRole(ctx context.Context, role *proj_model.ProjectRole) (*proj_model.ProjectRole, error) {
if !role.IsValid() { if !role.IsValid() {
return nil, caos_errs.ThrowPreconditionFailed(nil, "EVENT-9die3", "Errors.Project.RoleInvalid") return nil, caos_errs.ThrowPreconditionFailed(nil, "EVENT-9die3", "Errors.Project.Role.Invalid")
} }
existingProject, err := es.ProjectByID(ctx, role.AggregateID) existingProject, err := es.ProjectByID(ctx, role.AggregateID)
if err != nil { if err != nil {
return nil, err return nil, err
} }
if !existingProject.ContainsRole(role) { if !existingProject.ContainsRole(role) {
return nil, caos_errs.ThrowPreconditionFailed(nil, "EVENT-die34", "Errors.Project.RoleNotExisting") return nil, caos_errs.ThrowPreconditionFailed(nil, "EVENT-die34", "Errors.Project.Role.NotExisting")
} }
repoProject := model.ProjectFromModel(existingProject) repoProject := model.ProjectFromModel(existingProject)
repoRole := model.ProjectRoleFromModel(role) repoRole := model.ProjectRoleFromModel(role)
@ -381,14 +381,14 @@ func (es *ProjectEventstore) ChangeProjectRole(ctx context.Context, role *proj_m
func (es *ProjectEventstore) PrepareRemoveProjectRole(ctx context.Context, role *proj_model.ProjectRole) (*model.Project, *es_models.Aggregate, error) { func (es *ProjectEventstore) PrepareRemoveProjectRole(ctx context.Context, role *proj_model.ProjectRole) (*model.Project, *es_models.Aggregate, error) {
if role.Key == "" { if role.Key == "" {
return nil, nil, caos_errs.ThrowPreconditionFailed(nil, "EVENT-id823", "Errors.Project.RoleInvalid") return nil, nil, caos_errs.ThrowPreconditionFailed(nil, "EVENT-id823", "Errors.Project.Role.Invalid")
} }
existingProject, err := es.ProjectByID(ctx, role.AggregateID) existingProject, err := es.ProjectByID(ctx, role.AggregateID)
if err != nil { if err != nil {
return nil, nil, err return nil, nil, err
} }
if !existingProject.ContainsRole(role) { if !existingProject.ContainsRole(role) {
return nil, nil, caos_errs.ThrowPreconditionFailed(nil, "EVENT-oe823", "Errors.Project.RoleNotExisting") return nil, nil, caos_errs.ThrowPreconditionFailed(nil, "EVENT-oe823", "Errors.Project.Role.NotExisting")
} }
repoProject := model.ProjectFromModel(existingProject) repoProject := model.ProjectFromModel(existingProject)
repoRole := model.ProjectRoleFromModel(role) repoRole := model.ProjectRoleFromModel(role)
@ -502,12 +502,12 @@ func (es *ProjectEventstore) ApplicationByIDs(ctx context.Context, projectID, ap
if _, a := project.GetApp(appID); a != nil { if _, a := project.GetApp(appID); a != nil {
return a, nil return a, nil
} }
return nil, caos_errs.ThrowNotFound(nil, "EVENT-8ei2s", "Errors.Project.AppNotFound") return nil, caos_errs.ThrowNotFound(nil, "EVENT-8ei2s", "Errors.Project.App.NotFound")
} }
func (es *ProjectEventstore) AddApplication(ctx context.Context, app *proj_model.Application) (*proj_model.Application, error) { func (es *ProjectEventstore) AddApplication(ctx context.Context, app *proj_model.Application) (*proj_model.Application, error) {
if app == nil || !app.IsValid(true) { if app == nil || !app.IsValid(true) {
return nil, caos_errs.ThrowPreconditionFailed(nil, "EVENT-9eidw", "Errors.Project.AppInvalid") return nil, caos_errs.ThrowPreconditionFailed(nil, "EVENT-9eidw", "Errors.Project.App.Invalid")
} }
existingProject, err := es.ProjectByID(ctx, app.AggregateID) existingProject, err := es.ProjectByID(ctx, app.AggregateID)
if err != nil { if err != nil {
@ -551,14 +551,14 @@ func (es *ProjectEventstore) AddApplication(ctx context.Context, app *proj_model
func (es *ProjectEventstore) ChangeApplication(ctx context.Context, app *proj_model.Application) (*proj_model.Application, error) { func (es *ProjectEventstore) ChangeApplication(ctx context.Context, app *proj_model.Application) (*proj_model.Application, error) {
if app == nil || !app.IsValid(false) { if app == nil || !app.IsValid(false) {
return nil, caos_errs.ThrowPreconditionFailed(nil, "EVENT-dieuw", "Errors.Project.AppInvalid") return nil, caos_errs.ThrowPreconditionFailed(nil, "EVENT-dieuw", "Errors.Project.App.Invalid")
} }
existingProject, err := es.ProjectByID(ctx, app.AggregateID) existingProject, err := es.ProjectByID(ctx, app.AggregateID)
if err != nil { if err != nil {
return nil, err return nil, err
} }
if _, app := existingProject.GetApp(app.AppID); app == nil { if _, app := existingProject.GetApp(app.AppID); app == nil {
return nil, caos_errs.ThrowPreconditionFailed(nil, "EVENT-die83", "Errors.Project.AppNotExisting") return nil, caos_errs.ThrowPreconditionFailed(nil, "EVENT-die83", "Errors.Project.App.NotExisting")
} }
repoProject := model.ProjectFromModel(existingProject) repoProject := model.ProjectFromModel(existingProject)
repoApp := model.AppFromModel(app) repoApp := model.AppFromModel(app)
@ -584,7 +584,7 @@ func (es *ProjectEventstore) RemoveApplication(ctx context.Context, app *proj_mo
return err return err
} }
if _, app := existingProject.GetApp(app.AppID); app == nil { if _, app := existingProject.GetApp(app.AppID); app == nil {
return caos_errs.ThrowPreconditionFailed(nil, "EVENT-di83s", "Errors.Project.AppNotExisting") return caos_errs.ThrowPreconditionFailed(nil, "EVENT-di83s", "Errors.Project.App.NotExisting")
} }
repoProject := model.ProjectFromModel(existingProject) repoProject := model.ProjectFromModel(existingProject)
appRepo := model.AppFromModel(app) appRepo := model.AppFromModel(app)
@ -606,7 +606,7 @@ func (es *ProjectEventstore) PrepareRemoveApplication(ctx context.Context, app *
return nil, nil, err return nil, nil, err
} }
if _, app := existingProject.GetApp(app.AppID); app == nil { if _, app := existingProject.GetApp(app.AppID); app == nil {
return nil, nil, caos_errs.ThrowPreconditionFailed(nil, "EVENT-gaOD2", "Errors.Project.AppNotExisting") return nil, nil, caos_errs.ThrowPreconditionFailed(nil, "EVENT-gaOD2", "Errors.Project.App.NotExisting")
} }
repoProject := model.ProjectFromModel(existingProject) repoProject := model.ProjectFromModel(existingProject)
appRepo := model.AppFromModel(app) appRepo := model.AppFromModel(app)
@ -674,7 +674,7 @@ func (es *ProjectEventstore) DeactivateApplication(ctx context.Context, projectI
} }
app := &proj_model.Application{AppID: appID} app := &proj_model.Application{AppID: appID}
if _, app := existingProject.GetApp(app.AppID); app == nil { if _, app := existingProject.GetApp(app.AppID); app == nil {
return nil, caos_errs.ThrowPreconditionFailed(nil, "EVENT-slpe9", "Errors.Project.AppNotExisting") return nil, caos_errs.ThrowPreconditionFailed(nil, "EVENT-slpe9", "Errors.Project.App.NotExisting")
} }
repoProject := model.ProjectFromModel(existingProject) repoProject := model.ProjectFromModel(existingProject)
repoApp := model.AppFromModel(app) repoApp := model.AppFromModel(app)
@ -701,7 +701,7 @@ func (es *ProjectEventstore) ReactivateApplication(ctx context.Context, projectI
} }
app := &proj_model.Application{AppID: appID} app := &proj_model.Application{AppID: appID}
if _, app := existingProject.GetApp(app.AppID); app == nil { if _, app := existingProject.GetApp(app.AppID); app == nil {
return nil, caos_errs.ThrowPreconditionFailed(nil, "EVENT-ld92d", "Errors.Project.AppNotExisting") return nil, caos_errs.ThrowPreconditionFailed(nil, "EVENT-ld92d", "Errors.Project.App.NotExisting")
} }
repoProject := model.ProjectFromModel(existingProject) repoProject := model.ProjectFromModel(existingProject)
repoApp := model.AppFromModel(app) repoApp := model.AppFromModel(app)
@ -720,7 +720,7 @@ func (es *ProjectEventstore) ReactivateApplication(ctx context.Context, projectI
func (es *ProjectEventstore) ChangeOIDCConfig(ctx context.Context, config *proj_model.OIDCConfig) (*proj_model.OIDCConfig, error) { func (es *ProjectEventstore) ChangeOIDCConfig(ctx context.Context, config *proj_model.OIDCConfig) (*proj_model.OIDCConfig, error) {
if config == nil || !config.IsValid() { if config == nil || !config.IsValid() {
return nil, caos_errs.ThrowPreconditionFailed(nil, "EVENT-du834", "Errors.Project.OIDCConfigInvalid") return nil, caos_errs.ThrowPreconditionFailed(nil, "EVENT-du834", "Errors.Project.App.OIDCConfigInvalid")
} }
existingProject, err := es.ProjectByID(ctx, config.AggregateID) existingProject, err := es.ProjectByID(ctx, config.AggregateID)
if err != nil { if err != nil {
@ -731,7 +731,7 @@ func (es *ProjectEventstore) ChangeOIDCConfig(ctx context.Context, config *proj_
return nil, caos_errs.ThrowPreconditionFailed(nil, "EVENT-dkso8", "Errors.Project.AppNoExisting") return nil, caos_errs.ThrowPreconditionFailed(nil, "EVENT-dkso8", "Errors.Project.AppNoExisting")
} }
if app.Type != proj_model.AppTypeOIDC { if app.Type != proj_model.AppTypeOIDC {
return nil, caos_errs.ThrowPreconditionFailed(nil, "EVENT-98uje", "Errors.Project.AppIsNotOIDC") return nil, caos_errs.ThrowPreconditionFailed(nil, "EVENT-98uje", "Errors.Project.App.IsNotOIDC")
} }
repoProject := model.ProjectFromModel(existingProject) repoProject := model.ProjectFromModel(existingProject)
repoConfig := model.OIDCConfigFromModel(config) repoConfig := model.OIDCConfigFromModel(config)
@ -750,7 +750,7 @@ func (es *ProjectEventstore) ChangeOIDCConfig(ctx context.Context, config *proj_
func (es *ProjectEventstore) ChangeOIDCConfigSecret(ctx context.Context, projectID, appID string) (*proj_model.OIDCConfig, error) { func (es *ProjectEventstore) ChangeOIDCConfigSecret(ctx context.Context, projectID, appID string) (*proj_model.OIDCConfig, error) {
if appID == "" { if appID == "" {
return nil, caos_errs.ThrowPreconditionFailed(nil, "EVENT-7ue34", "Errors.Project.OIDCConfigInvalid") return nil, caos_errs.ThrowPreconditionFailed(nil, "EVENT-7ue34", "Errors.Project.App.OIDCConfigInvalid")
} }
existingProject, err := es.ProjectByID(ctx, projectID) existingProject, err := es.ProjectByID(ctx, projectID)
if err != nil { if err != nil {
@ -758,10 +758,10 @@ func (es *ProjectEventstore) ChangeOIDCConfigSecret(ctx context.Context, project
} }
var app *proj_model.Application var app *proj_model.Application
if _, app = existingProject.GetApp(appID); app == nil { if _, app = existingProject.GetApp(appID); app == nil {
return nil, caos_errs.ThrowPreconditionFailed(nil, "EVENT-9odi4", "Errors.Project.AppNotExisting") return nil, caos_errs.ThrowPreconditionFailed(nil, "EVENT-9odi4", "Errors.Project.App.NotExisting")
} }
if app.Type != proj_model.AppTypeOIDC { if app.Type != proj_model.AppTypeOIDC {
return nil, caos_errs.ThrowPreconditionFailed(nil, "EVENT-dile4", "Errors.Project.AppIsNotOIDC") return nil, caos_errs.ThrowPreconditionFailed(nil, "EVENT-dile4", "Errors.Project.App.IsNotOIDC")
} }
if app.OIDCConfig.AuthMethodType == proj_model.OIDCAuthMethodTypeNone { if app.OIDCConfig.AuthMethodType == proj_model.OIDCAuthMethodTypeNone {
return nil, caos_errs.ThrowPreconditionFailed(nil, "EVENT-GDrg2", "Errors.Project.OIDCAuthMethodNoneSecret") return nil, caos_errs.ThrowPreconditionFailed(nil, "EVENT-GDrg2", "Errors.Project.OIDCAuthMethodNoneSecret")
@ -804,7 +804,7 @@ func (es *ProjectEventstore) VerifyOIDCClientSecret(ctx context.Context, project
return caos_errs.ThrowPreconditionFailed(nil, "EVENT-D6hba", "Errors.Project.AppNoExisting") return caos_errs.ThrowPreconditionFailed(nil, "EVENT-D6hba", "Errors.Project.AppNoExisting")
} }
if app.Type != proj_model.AppTypeOIDC { if app.Type != proj_model.AppTypeOIDC {
return caos_errs.ThrowPreconditionFailed(nil, "EVENT-huywq", "Errors.Project.AppIsNotOIDC") return caos_errs.ThrowPreconditionFailed(nil, "EVENT-huywq", "Errors.Project.App.IsNotOIDC")
} }
ctx, spanHash := tracing.NewSpan(ctx) ctx, spanHash := tracing.NewSpan(ctx)
@ -842,22 +842,22 @@ func (es *ProjectEventstore) ProjectGrantByIDs(ctx context.Context, projectID, g
if _, g := project.GetGrant(grantID); g != nil { if _, g := project.GetGrant(grantID); g != nil {
return g, nil return g, nil
} }
return nil, caos_errs.ThrowNotFound(nil, "EVENT-slo45", "Errors.Project.GrantNotFound") return nil, caos_errs.ThrowNotFound(nil, "EVENT-slo45", "Errors.Project.Grant.NotFound")
} }
func (es *ProjectEventstore) AddProjectGrant(ctx context.Context, grant *proj_model.ProjectGrant) (*proj_model.ProjectGrant, error) { func (es *ProjectEventstore) AddProjectGrant(ctx context.Context, grant *proj_model.ProjectGrant) (*proj_model.ProjectGrant, error) {
if grant == nil || !grant.IsValid() { if grant == nil || !grant.IsValid() {
return nil, caos_errs.ThrowPreconditionFailed(nil, "EVENT-37dhs", "Errors.Project.GrantInvalid") return nil, caos_errs.ThrowPreconditionFailed(nil, "EVENT-37dhs", "Errors.Project.Grant.Invalid")
} }
project, err := es.ProjectByID(ctx, grant.AggregateID) project, err := es.ProjectByID(ctx, grant.AggregateID)
if err != nil { if err != nil {
return nil, err return nil, err
} }
if project.ContainsGrantForOrg(grant.GrantedOrgID) { if project.ContainsGrantForOrg(grant.GrantedOrgID) {
return nil, caos_errs.ThrowPreconditionFailed(nil, "EVENT-7ug4g", "Errors.Project.GrantAlreadyExists") return nil, caos_errs.ThrowPreconditionFailed(nil, "EVENT-7ug4g", "Errors.Project.Grant.AlreadyExists")
} }
if !project.ContainsRoles(grant.RoleKeys) { if !project.ContainsRoles(grant.RoleKeys) {
return nil, caos_errs.ThrowPreconditionFailed(nil, "EVENT-di83d", "Errors.Project.GrantHasNotExistingRole") return nil, caos_errs.ThrowPreconditionFailed(nil, "EVENT-di83d", "Errors.Project.Grant.HasNotExistingRole")
} }
id, err := es.idGenerator.Next() id, err := es.idGenerator.Next()
if err != nil { if err != nil {
@ -881,7 +881,7 @@ func (es *ProjectEventstore) AddProjectGrant(ctx context.Context, grant *proj_mo
func (es *ProjectEventstore) PrepareChangeProjectGrant(ctx context.Context, grant *proj_model.ProjectGrant) (*model.Project, func(ctx context.Context) (*es_models.Aggregate, error), []string, error) { func (es *ProjectEventstore) PrepareChangeProjectGrant(ctx context.Context, grant *proj_model.ProjectGrant) (*model.Project, func(ctx context.Context) (*es_models.Aggregate, error), []string, error) {
if grant == nil && grant.GrantID == "" { if grant == nil && grant.GrantID == "" {
return nil, nil, nil, caos_errs.ThrowPreconditionFailed(nil, "EVENT-8sie3", "Errors.Project.GrantInvalid") return nil, nil, nil, caos_errs.ThrowPreconditionFailed(nil, "EVENT-8sie3", "Errors.Project.Grant.Invalid")
} }
existingProject, err := es.ProjectByID(ctx, grant.AggregateID) existingProject, err := es.ProjectByID(ctx, grant.AggregateID)
if err != nil { if err != nil {
@ -889,10 +889,10 @@ func (es *ProjectEventstore) PrepareChangeProjectGrant(ctx context.Context, gran
} }
_, existingGrant := existingProject.GetGrant(grant.GrantID) _, existingGrant := existingProject.GetGrant(grant.GrantID)
if existingGrant == nil { if existingGrant == nil {
return nil, nil, nil, caos_errs.ThrowPreconditionFailed(nil, "EVENT-die83", "Errors.Project.GrantNotExisting") return nil, nil, nil, caos_errs.ThrowPreconditionFailed(nil, "EVENT-die83", "Errors.Project.Grant.NotExisting")
} }
if !existingProject.ContainsRoles(grant.RoleKeys) { if !existingProject.ContainsRoles(grant.RoleKeys) {
return nil, nil, nil, caos_errs.ThrowPreconditionFailed(nil, "EVENT-di83d", "Error.Project.GrantHasNotExistingRole") return nil, nil, nil, caos_errs.ThrowPreconditionFailed(nil, "EVENT-di83d", "Error.Project.Grant.HasNotExistingRole")
} }
removedRoles := existingGrant.GetRemovedRoles(grant.RoleKeys) removedRoles := existingGrant.GetRemovedRoles(grant.RoleKeys)
repoProject := model.ProjectFromModel(existingProject) repoProject := model.ProjectFromModel(existingProject)
@ -940,7 +940,7 @@ func (es *ProjectEventstore) PrepareRemoveProjectGrant(ctx context.Context, gran
return nil, nil, err return nil, nil, err
} }
if _, g := existingProject.GetGrant(grant.GrantID); g == nil { if _, g := existingProject.GetGrant(grant.GrantID); g == nil {
return nil, nil, caos_errs.ThrowPreconditionFailed(nil, "EVENT-9ie3s", "Errors.Project.GrantNotExisting") return nil, nil, caos_errs.ThrowPreconditionFailed(nil, "EVENT-9ie3s", "Errors.Project.Grant.NotExisting")
} }
repoProject := model.ProjectFromModel(existingProject) repoProject := model.ProjectFromModel(existingProject)
grantRepo := model.GrantFromModel(grant) grantRepo := model.GrantFromModel(grant)
@ -958,7 +958,7 @@ func (es *ProjectEventstore) DeactivateProjectGrant(ctx context.Context, project
} }
grant := &proj_model.ProjectGrant{GrantID: grantID} grant := &proj_model.ProjectGrant{GrantID: grantID}
if _, g := existingProject.GetGrant(grant.GrantID); g == nil { if _, g := existingProject.GetGrant(grant.GrantID); g == nil {
return nil, caos_errs.ThrowPreconditionFailed(nil, "EVENT-slpe9", "Errors.Project.GrantNotExisting") return nil, caos_errs.ThrowPreconditionFailed(nil, "EVENT-slpe9", "Errors.Project.Grant.NotExisting")
} }
repoProject := model.ProjectFromModel(existingProject) repoProject := model.ProjectFromModel(existingProject)
repoGrant := model.GrantFromModel(grant) repoGrant := model.GrantFromModel(grant)
@ -985,7 +985,7 @@ func (es *ProjectEventstore) ReactivateProjectGrant(ctx context.Context, project
} }
grant := &proj_model.ProjectGrant{GrantID: grantID} grant := &proj_model.ProjectGrant{GrantID: grantID}
if _, g := existingProject.GetGrant(grant.GrantID); g == nil { if _, g := existingProject.GetGrant(grant.GrantID); g == nil {
return nil, caos_errs.ThrowPreconditionFailed(nil, "EVENT-0spew", "Errors.Project.GrantNotExisting") return nil, caos_errs.ThrowPreconditionFailed(nil, "EVENT-0spew", "Errors.Project.Grant.NotExisting")
} }
repoProject := model.ProjectFromModel(existingProject) repoProject := model.ProjectFromModel(existingProject)
repoGrant := model.GrantFromModel(grant) repoGrant := model.GrantFromModel(grant)
@ -1016,19 +1016,19 @@ func (es *ProjectEventstore) ProjectGrantMemberByIDs(ctx context.Context, member
return m, nil return m, nil
} }
} }
return nil, caos_errs.ThrowNotFound(nil, "EVENT-LxiBI", "Errors.Project.MemberNotFound") return nil, caos_errs.ThrowNotFound(nil, "EVENT-LxiBI", "Errors.Project.Member.NotFound")
} }
func (es *ProjectEventstore) AddProjectGrantMember(ctx context.Context, member *proj_model.ProjectGrantMember) (*proj_model.ProjectGrantMember, error) { func (es *ProjectEventstore) AddProjectGrantMember(ctx context.Context, member *proj_model.ProjectGrantMember) (*proj_model.ProjectGrantMember, error) {
if !member.IsValid() { if !member.IsValid() {
return nil, caos_errs.ThrowPreconditionFailed(nil, "EVENT-0dor4", "Errors.Project.MemberInvalid") return nil, caos_errs.ThrowPreconditionFailed(nil, "EVENT-0dor4", "Errors.Project.Member.Invalid")
} }
existingProject, err := es.ProjectByID(ctx, member.AggregateID) existingProject, err := es.ProjectByID(ctx, member.AggregateID)
if err != nil { if err != nil {
return nil, err return nil, err
} }
if existingProject.ContainsGrantMember(member) { if existingProject.ContainsGrantMember(member) {
return nil, caos_errs.ThrowAlreadyExists(nil, "EVENT-8die3", "Errors.Project.MemberAlreadyExists") return nil, caos_errs.ThrowAlreadyExists(nil, "EVENT-8die3", "Errors.Project.Member.AlreadyExists")
} }
repoProject := model.ProjectFromModel(existingProject) repoProject := model.ProjectFromModel(existingProject)
repoMember := model.GrantMemberFromModel(member) repoMember := model.GrantMemberFromModel(member)
@ -1049,14 +1049,14 @@ func (es *ProjectEventstore) AddProjectGrantMember(ctx context.Context, member *
func (es *ProjectEventstore) ChangeProjectGrantMember(ctx context.Context, member *proj_model.ProjectGrantMember) (*proj_model.ProjectGrantMember, error) { func (es *ProjectEventstore) ChangeProjectGrantMember(ctx context.Context, member *proj_model.ProjectGrantMember) (*proj_model.ProjectGrantMember, error) {
if !member.IsValid() { if !member.IsValid() {
return nil, caos_errs.ThrowPreconditionFailed(nil, "EVENT-dkw35", "Errors.Project.MemberInvalid") return nil, caos_errs.ThrowPreconditionFailed(nil, "EVENT-dkw35", "Errors.Project.Member.Invalid")
} }
existingProject, err := es.ProjectByID(ctx, member.AggregateID) existingProject, err := es.ProjectByID(ctx, member.AggregateID)
if err != nil { if err != nil {
return nil, err return nil, err
} }
if !existingProject.ContainsGrantMember(member) { if !existingProject.ContainsGrantMember(member) {
return nil, caos_errs.ThrowPreconditionFailed(nil, "EVENT-8dj4s", "Errors.Project.MemberNotExisting") return nil, caos_errs.ThrowPreconditionFailed(nil, "EVENT-8dj4s", "Errors.Project.Member.NotExisting")
} }
repoProject := model.ProjectFromModel(existingProject) repoProject := model.ProjectFromModel(existingProject)
repoMember := model.GrantMemberFromModel(member) repoMember := model.GrantMemberFromModel(member)
@ -1077,14 +1077,14 @@ func (es *ProjectEventstore) ChangeProjectGrantMember(ctx context.Context, membe
func (es *ProjectEventstore) RemoveProjectGrantMember(ctx context.Context, member *proj_model.ProjectGrantMember) error { func (es *ProjectEventstore) RemoveProjectGrantMember(ctx context.Context, member *proj_model.ProjectGrantMember) error {
if member.UserID == "" { if member.UserID == "" {
return caos_errs.ThrowPreconditionFailed(nil, "EVENT-8su4r", "Errors.Project.MemberInvalid") return caos_errs.ThrowPreconditionFailed(nil, "EVENT-8su4r", "Errors.Project.Member.Invalid")
} }
existingProject, err := es.ProjectByID(ctx, member.AggregateID) existingProject, err := es.ProjectByID(ctx, member.AggregateID)
if err != nil { if err != nil {
return err return err
} }
if !existingProject.ContainsGrantMember(member) { if !existingProject.ContainsGrantMember(member) {
return caos_errs.ThrowPreconditionFailed(nil, "EVENT-9ode4", "Errors.Project.MemberNotExisting") return caos_errs.ThrowPreconditionFailed(nil, "EVENT-9ode4", "Errors.Project.Member.NotExisting")
} }
repoProject := model.ProjectFromModel(existingProject) repoProject := model.ProjectFromModel(existingProject)
repoMember := model.GrantMemberFromModel(member) repoMember := model.GrantMemberFromModel(member)

View File

@ -40,7 +40,7 @@ func ApplicationByOIDCClientID(db *gorm.DB, table, clientID string) (*model.Appl
query := repository.PrepareGetByQuery(table, clientIDQuery) query := repository.PrepareGetByQuery(table, clientIDQuery)
err := query(db, app) err := query(db, app)
if caos_errs.IsNotFound(err) { if caos_errs.IsNotFound(err) {
return nil, caos_errs.ThrowNotFound(nil, "VIEW-DG1qh", "Errors.Project.AppNotFound") return nil, caos_errs.ThrowNotFound(nil, "VIEW-DG1qh", "Errors.Project.App.NotFound")
} }
return app, err return app, err
} }
@ -52,7 +52,7 @@ func ApplicationByProjectIDAndAppName(db *gorm.DB, table, projectID, appName str
query := repository.PrepareGetByQuery(table, projectIDQuery, appNameQuery) query := repository.PrepareGetByQuery(table, projectIDQuery, appNameQuery)
err := query(db, app) err := query(db, app)
if caos_errs.IsNotFound(err) { if caos_errs.IsNotFound(err) {
return nil, caos_errs.ThrowNotFound(nil, "VIEW-Jqw1z", "Errors.Project.AppNotFound") return nil, caos_errs.ThrowNotFound(nil, "VIEW-Jqw1z", "Errors.Project.App.NotFound")
} }
return app, err return app, err
} }

View File

@ -17,7 +17,7 @@ func ProjectGrantMemberByIDs(db *gorm.DB, table, grantID, userID string) (*model
query := repository.PrepareGetByQuery(table, grantIDQuery, userIDQuery) query := repository.PrepareGetByQuery(table, grantIDQuery, userIDQuery)
err := query(db, grant) err := query(db, grant)
if caos_errs.IsNotFound(err) { if caos_errs.IsNotFound(err) {
return nil, caos_errs.ThrowNotFound(nil, "VIEW-Sgr32", "Errors.Project.MemberNotExisting") return nil, caos_errs.ThrowNotFound(nil, "VIEW-Sgr32", "Errors.Project.Member.NotExisting")
} }
return grant, err return grant, err
} }

View File

@ -17,7 +17,7 @@ func ProjectGrantByProjectAndOrg(db *gorm.DB, table, projectID, orgID string) (*
query := repository.PrepareGetByQuery(table, projectIDQuery, orgIDQuery) query := repository.PrepareGetByQuery(table, projectIDQuery, orgIDQuery)
err := query(db, projectGrant) err := query(db, projectGrant)
if caos_errs.IsNotFound(err) { if caos_errs.IsNotFound(err) {
return nil, caos_errs.ThrowNotFound(nil, "VIEW-WR3z2", "Errors.Project.GrantNotExists") return nil, caos_errs.ThrowNotFound(nil, "VIEW-WR3z2", "Errors.Project.Grant.NotExisting")
} }
return projectGrant, err return projectGrant, err
} }
@ -28,7 +28,7 @@ func ProjectGrantByID(db *gorm.DB, table, grantID string) (*model.ProjectGrantVi
query := repository.PrepareGetByQuery(table, grantIDQuery) query := repository.PrepareGetByQuery(table, grantIDQuery)
err := query(db, projectGrant) err := query(db, projectGrant)
if caos_errs.IsNotFound(err) { if caos_errs.IsNotFound(err) {
return nil, caos_errs.ThrowNotFound(nil, "VIEW-EGdh4", "Errors.Project.GrantNotFound") return nil, caos_errs.ThrowNotFound(nil, "VIEW-EGdh4", "Errors.Project.Grant.NotFound")
} }
return projectGrant, err return projectGrant, err
} }

View File

@ -17,7 +17,7 @@ func ProjectMemberByIDs(db *gorm.DB, table, projectID, userID string) (*model.Pr
query := repository.PrepareGetByQuery(table, projectIDQuery, userIDQuery) query := repository.PrepareGetByQuery(table, projectIDQuery, userIDQuery)
err := query(db, role) err := query(db, role)
if caos_errs.IsNotFound(err) { if caos_errs.IsNotFound(err) {
return nil, caos_errs.ThrowNotFound(nil, "VIEW-EgWQ2", "Errors.Project.MemberNotExisting") return nil, caos_errs.ThrowNotFound(nil, "VIEW-EgWQ2", "Errors.Project.Member.NotExisting")
} }
return role, err return role, err
} }

View File

@ -18,7 +18,7 @@ func ProjectRoleByIDs(db *gorm.DB, table, projectID, orgID, key string) (*model.
query := repository.PrepareGetByQuery(table, projectIDQuery, grantIDQuery, keyQuery) query := repository.PrepareGetByQuery(table, projectIDQuery, grantIDQuery, keyQuery)
err := query(db, role) err := query(db, role)
if caos_errs.IsNotFound(err) { if caos_errs.IsNotFound(err) {
return nil, caos_errs.ThrowNotFound(nil, "VIEW-Wtg72", "Errors.Project.RoleNotExisting") return nil, caos_errs.ThrowNotFound(nil, "VIEW-Wtg72", "Errors.Project.Role.NotExisting")
} }
return role, err return role, err
} }

View File

@ -158,27 +158,36 @@ Errors:
NotInactive: Projekt ist nicht deaktiviert NotInactive: Projekt ist nicht deaktiviert
NotFound: Project konnte nicht gefunden werden NotFound: Project konnte nicht gefunden werden
UserIDMissing: User ID fehlt UserIDMissing: User ID fehlt
MemberNotFound: Member konnte nicht gefunden werden Member:
MemberInvalid: Member ist ungültig Invalid: Member ist ungültig
MemberAlreadyExists: Member existiert bereits AlreadyExists: Member existiert bereits
MemberNotExisting: Member existiert nicht NotExisting: Member existiert nicht
NotFound: Member konnte nicht gefunden werden
MinimumOneRoleNeeded: Es muss mindestend eine Rolle hinzugefügt werden MinimumOneRoleNeeded: Es muss mindestend eine Rolle hinzugefügt werden
RoleAlreadyExists: Rolle existiert bereits Role:
RoleInvalid: Rolle ist ungültig AlreadyExists: Rolle existiert bereits
RoleNotExisting: Rolle existiert nicht Invalid: Rolle ist ungültig
NotExisting: Rolle existiert nicht
IDMissing: ID fehlt IDMissing: ID fehlt
AppNotFound: Applikation nicht gefunden App:
AppInvalid: Applikation ist ungültig AlreadyExists: Applikation existiert bereits
AppNotExisting: Applikation exisitert nicht NotFound: Applikation nicht gefunden
OIDCConfigInvalid: OIDC Konfiguration ist ungültig Invalid: Applikation ist ungültig
AppIsNotOIDC: Applikation ist nicht vom Typ OIDC NotExisting: Applikation exisitert nicht
IsNotOIDC: Applikation ist nicht vom Typ OIDC
NotActive: Applikation ist nicht aktiv
NotInactive: Applikation ist nickt inaktiv
OIDCConfigInvalid: OIDC Konfiguration ist ungültig
OIDCAuthMethodNoneSecret: OIDC Auth Method None benötigt kein Secret OIDCAuthMethodNoneSecret: OIDC Auth Method None benötigt kein Secret
RequiredFieldsMissing: Benötigte Felder fehlen RequiredFieldsMissing: Benötigte Felder fehlen
GrantNotFound: Grant konnte nicht gefunden werden Grant:
GrantInvalid: Projekt Grant ist ungültig AlreadyExists: Projekt Grant existiert bereits
GrantAlreadyExists: Projekt Grant existiert bereits Invalid: Projekt Grant ist ungültig
GrantNotExists: Projekt Grant existiert nicht NotFound: Grant konnte nicht gefunden werden
GrantHasNotExistingRole: Eine der Rollen existiert nicht auf dem Projekt NotExisting: Projekt Grant existiert nicht
HasNotExistingRole: Eine der Rollen existiert nicht auf dem Projekt
NotActive: Projekt Grant ist nicht aktiv
NotInactive: Projekt Grant ist nicht inaktiv
UserIDMisisng: User ID fehlt UserIDMisisng: User ID fehlt
OIDCSecretInvalid: Client Secret ist ungültig OIDCSecretInvalid: Client Secret ist ungültig
IAM: IAM:

View File

@ -158,27 +158,35 @@ Errors:
NotInactive: Project is not deactivated NotInactive: Project is not deactivated
NotFound: Porject not found NotFound: Porject not found
UserIDMissing: User ID missing UserIDMissing: User ID missing
MemberNotFound: Project member not found Member:
MemberInvalid: Project member is invalid NotFound: Project member not found
MemberAlreadyExists: Project member already exists Invalid: Project member is invalid
MemberNotExisting: Project member doesn't exist AlreadyExists: Project member already exists
NotExisting: Project member doesn't exist
MinimumOneRoleNeeded: At least one role must be added MinimumOneRoleNeeded: At least one role must be added
RoleAlreadyExists: Role already exists Role:
RoleInvalid: Role is invalid AlreadyExists: Role already exists
RoleNotExisting: Role doesn't exist Invalid: Role is invalid
NotExisting: Role doesn't exist
IDMissing: ID missing IDMissing: ID missing
AppNotFound: Application not found App:
AppInvalid: Application invalid AlreadyExists: Application already exists
AppNotExisting: Application doesn't exist Invalid: Application invalid
NotExisting: Application doesn't exist
IsNotOIDC: Application is not type oidc
NotActive:: Application is not active
NotInactive: Application is not inactive
OIDCConfigInvalid: OIDC configuration is invalid OIDCConfigInvalid: OIDC configuration is invalid
AppIsNotOIDC: Application is not type oidc
OIDCAuthMethodNoneSecret: OIDC Auth Method None does not require a secret OIDCAuthMethodNoneSecret: OIDC Auth Method None does not require a secret
RequiredFieldsMissing: Some required fields are missing RequiredFieldsMissing: Some required fields are missing
GrantNotFound: Grant not found Grant:
GrantInvalid: Project grant is invalid AlreadyExists: Project grant already exists
GrantAlreadyExists: Project grant already exists NotFound: Grant not found
GrantNotExists: Project grant doesn't exist Invalid: Project grant is invalid
GrantHasNotExistingRole: One role doesn't exist on project NotExisting: Project grant doesn't exist
HasNotExistingRole: One role doesn't exist on project
NotActive: Project grant is not active
NotInactive: Project grant is not inactive
UserIDMisisng: User ID missing UserIDMisisng: User ID missing
OIDCSecretInvalid: Client Secret is invalid OIDCSecretInvalid: Client Secret is invalid
IAM: IAM:

View File

@ -14,12 +14,23 @@ func (r *CommandSide) getOrg(ctx context.Context, orgID string) (*domain.Org, er
if err != nil { if err != nil {
return nil, err return nil, err
} }
if writeModel.State == domain.OrgStateActive { if writeModel.State == domain.OrgStateUnspecified || writeModel.State == domain.OrgStateRemoved {
return nil, caos_errs.ThrowInternal(err, "COMMAND-4M9sf", "Errors.Org.NotFound") return nil, caos_errs.ThrowInternal(err, "COMMAND-4M9sf", "Errors.Org.NotFound")
} }
return orgWriteModelToOrg(writeModel), nil return orgWriteModelToOrg(writeModel), nil
} }
func (r *CommandSide) checkOrgExists(ctx context.Context, orgID string) error {
orgWriteModel, err := r.getOrgWriteModelByID(ctx, orgID)
if err != nil {
return err
}
if orgWriteModel.State == domain.OrgStateUnspecified || orgWriteModel.State == domain.OrgStateRemoved {
return caos_errs.ThrowPreconditionFailed(nil, "COMMAND-4M0fs", "Errors.Org.NotFound")
}
return nil
}
func (r *CommandSide) SetUpOrg(ctx context.Context, organisation *domain.Org, admin *domain.Human) error { func (r *CommandSide) SetUpOrg(ctx context.Context, organisation *domain.Org, admin *domain.Human) error {
orgAgg, userAgg, orgMemberAgg, err := r.setUpOrg(ctx, organisation, admin) orgAgg, userAgg, orgMemberAgg, err := r.setUpOrg(ctx, organisation, admin)
if err != nil { if err != nil {
@ -36,13 +47,10 @@ func (r *CommandSide) AddOrg(ctx context.Context, name, userID, resourceOwner st
return nil, err return nil, err
} }
active, err := r.checkUserExists(ctx, userID, resourceOwner) err = r.checkUserExists(ctx, userID, resourceOwner)
if err != nil { if err != nil {
return nil, err return nil, err
} }
if !active {
return nil, caos_errs.ThrowPreconditionFailed(err, "ORG-HBR2z", "Errors.User.NotFound")
}
addedMember := NewOrgMemberWriteModel(orgAgg.ID(), userID) addedMember := NewOrgMemberWriteModel(orgAgg.ID(), userID)
err = r.addOrgMember(ctx, orgAgg, addedMember, domain.NewMember(orgAgg.ID(), userID, domain.RoleOrgOwner)) err = r.addOrgMember(ctx, orgAgg, addedMember, domain.NewMember(orgAgg.ID(), userID, domain.RoleOrgOwner))
if err != nil { if err != nil {

View File

@ -32,13 +32,17 @@ func (r *CommandSide) addProject(ctx context.Context, projectAdd *domain.Project
addedProject := NewProjectWriteModel(projectAdd.AggregateID, resourceOwner) addedProject := NewProjectWriteModel(projectAdd.AggregateID, resourceOwner)
projectAgg := ProjectAggregateFromWriteModel(&addedProject.WriteModel) projectAgg := ProjectAggregateFromWriteModel(&addedProject.WriteModel)
projectRole := domain.RoleOrgOwner projectRole := domain.RoleProjectOwner
//if global { //TODO: ! iam, err := r.GetIAM(ctx)
// projectRole = domain.RoleProjectOwnerGlobal if err != nil {
//} return nil, nil, err
}
if iam.GlobalOrgID == resourceOwner {
projectRole = domain.RoleProjectOwnerGlobal
}
projectAgg.PushEvents( projectAgg.PushEvents(
project.NewProjectAddedEvent(ctx, projectAdd.Name, resourceOwner), project.NewProjectAddedEvent(ctx, projectAdd.Name, resourceOwner),
project.NewMemberAddedEvent(ctx, ownerUserID, projectRole), project.NewProjectMemberAddedEvent(ctx, ownerUserID, projectRole),
) )
return projectAgg, addedProject, nil return projectAgg, addedProject, nil
} }
@ -65,6 +69,101 @@ func (r *CommandSide) checkProjectExists(ctx context.Context, projectID, resourc
return nil return nil
} }
func (r *CommandSide) ChangeProject(ctx context.Context, projectChange *domain.Project, resourceOwner string) (*domain.Project, error) {
if !projectChange.IsValid() && projectChange.AggregateID != "" {
return nil, caos_errs.ThrowPreconditionFailed(nil, "COMMAND-4m9vS", "Errors.Project.Invalid")
}
existingProject, err := r.getProjectWriteModelByID(ctx, projectChange.AggregateID, resourceOwner)
if err != nil {
return nil, err
}
if existingProject.State == domain.ProjectStateUnspecified || existingProject.State == domain.ProjectStateRemoved {
return nil, caos_errs.ThrowNotFound(nil, "COMMAND-3M9sd", "Errors.Project.NotFound")
}
changedEvent, hasChanged, err := existingProject.NewChangedEvent(ctx, projectChange.Name, projectChange.ProjectRoleAssertion, projectChange.ProjectRoleCheck)
if err != nil {
return nil, err
}
if !hasChanged {
return nil, caos_errs.ThrowPreconditionFailed(nil, "COMMAND-2M0fs", "Errors.NoChangesFound")
}
projectAgg := ProjectAggregateFromWriteModel(&existingProject.WriteModel)
projectAgg.PushEvents(changedEvent)
err = r.eventstore.PushAggregate(ctx, existingProject, projectAgg)
if err != nil {
return nil, err
}
return projectWriteModelToProject(existingProject), nil
}
func (r *CommandSide) DeactivateProject(ctx context.Context, projectID string, resourceOwner string) error {
if projectID == "" || resourceOwner == "" {
return caos_errs.ThrowPreconditionFailed(nil, "COMMAND-88iF0", "Errors.Project.ProjectIDMissing")
}
existingProject, err := r.getProjectWriteModelByID(ctx, projectID, resourceOwner)
if err != nil {
return err
}
if existingProject.State == domain.ProjectStateUnspecified || existingProject.State == domain.ProjectStateRemoved {
return caos_errs.ThrowNotFound(nil, "COMMAND-112M9", "Errors.Project.NotFound")
}
if existingProject.State != domain.ProjectStateActive {
return caos_errs.ThrowPreconditionFailed(nil, "COMMAND-mki55", "Errors.Project.NotActive")
}
projectAgg := ProjectAggregateFromWriteModel(&existingProject.WriteModel)
projectAgg.PushEvents(project.NewProjectDeactivatedEvent(ctx))
return r.eventstore.PushAggregate(ctx, existingProject, projectAgg)
}
func (r *CommandSide) ReactivateProject(ctx context.Context, projectID string, resourceOwner string) error {
if projectID == "" || resourceOwner == "" {
return caos_errs.ThrowPreconditionFailed(nil, "COMMAND-4m9vS", "Errors.Project.ProjectIDMissing")
}
existingProject, err := r.getProjectWriteModelByID(ctx, projectID, resourceOwner)
if err != nil {
return err
}
if existingProject.State == domain.ProjectStateUnspecified || existingProject.State == domain.ProjectStateRemoved {
return caos_errs.ThrowNotFound(nil, "COMMAND-3M9sd", "Errors.Project.NotFound")
}
if existingProject.State != domain.ProjectStateInactive {
return caos_errs.ThrowPreconditionFailed(nil, "COMMAND-5M9bs", "Errors.Project.NotInctive")
}
projectAgg := ProjectAggregateFromWriteModel(&existingProject.WriteModel)
projectAgg.PushEvents(project.NewProjectDeactivatedEvent(ctx))
return r.eventstore.PushAggregate(ctx, existingProject, projectAgg)
}
func (r *CommandSide) RemoveProject(ctx context.Context, projectID, resourceOwner string) error {
if projectID == "" || resourceOwner == "" {
return caos_errs.ThrowPreconditionFailed(nil, "COMMAND-66hM9", "Errors.Project.ProjectIDMissing")
}
existingProject, err := r.getProjectWriteModelByID(ctx, projectID, resourceOwner)
if err != nil {
return err
}
if existingProject.State == domain.ProjectStateUnspecified || existingProject.State == domain.ProjectStateRemoved {
return caos_errs.ThrowNotFound(nil, "COMMAND-3M9sd", "Errors.Project.NotFound")
}
projectAgg := ProjectAggregateFromWriteModel(&existingProject.WriteModel)
projectAgg.PushEvents(project.NewProjectRemovedEvent(ctx, existingProject.Name, existingProject.ResourceOwner))
//TODO: Remove User Grants by ProjectID
return r.eventstore.PushAggregate(ctx, existingProject, projectAgg)
}
func (r *CommandSide) getProjectWriteModelByID(ctx context.Context, projectID, resourceOwner string) (*ProjectWriteModel, error) { func (r *CommandSide) getProjectWriteModelByID(ctx context.Context, projectID, resourceOwner string) (*ProjectWriteModel, error) {
projectWriteModel := NewProjectWriteModel(projectID, resourceOwner) projectWriteModel := NewProjectWriteModel(projectID, resourceOwner)
err := r.eventstore.FilterToQueryReducer(ctx, projectWriteModel) err := r.eventstore.FilterToQueryReducer(ctx, projectWriteModel)

View File

@ -8,66 +8,99 @@ import (
"github.com/caos/zitadel/internal/v2/repository/project" "github.com/caos/zitadel/internal/v2/repository/project"
) )
func (r *CommandSide) AddApplication(ctx context.Context, application *domain.Application, resourceOwner string) (_ *domain.Application, err error) { func (r *CommandSide) ChangeApplication(ctx context.Context, projectID string, appChange domain.Application, resourceOwner string) (domain.Application, error) {
project, err := r.getProjectByID(ctx, application.AggregateID, resourceOwner) if appChange.GetAppID() == "" || appChange.GetApplicationName() == "" {
return nil, caos_errs.ThrowPreconditionFailed(nil, "COMMAND-4m9vS", "Errors.Project.App.Invalid")
}
existingApp, err := r.getApplicationWriteModel(ctx, projectID, appChange.GetAppID(), resourceOwner)
if err != nil { if err != nil {
return nil, err return nil, err
} }
addedApplication := NewApplicationWriteModel(application.AggregateID, resourceOwner) if existingApp.State == domain.AppStateUnspecified || existingApp.State == domain.AppStateRemoved {
projectAgg := ProjectAggregateFromWriteModel(&addedApplication.WriteModel) return nil, caos_errs.ThrowNotFound(nil, "COMMAND-28di9", "Errors.Project.App.NotExisting")
err = r.addApplication(ctx, projectAgg, project, application)
if err != nil {
return nil, err
} }
err = r.eventstore.PushAggregate(ctx, addedApplication, projectAgg) if existingApp.Name == appChange.GetApplicationName() {
return nil, caos_errs.ThrowPreconditionFailed(nil, "COMMAND-2m8vx", "Errors.NoChangesFound")
}
projectAgg := ProjectAggregateFromWriteModel(&existingApp.WriteModel)
projectAgg.PushEvents(
project.NewApplicationChangedEvent(ctx, appChange.GetAppID(), existingApp.Name, appChange.GetApplicationName(), projectID),
)
err = r.eventstore.PushAggregate(ctx, existingApp, projectAgg)
if err != nil { if err != nil {
return nil, err return nil, err
} }
return applicationWriteModelToApplication(addedApplication), nil return applicationWriteModelToApplication(existingApp), nil
} }
func (r *CommandSide) addApplication(ctx context.Context, projectAgg *project.Aggregate, proj *domain.Project, application *domain.Application) (err error) { func (r *CommandSide) DeactivateApplication(ctx context.Context, projectID, appID, resourceOwner string) error {
if !application.IsValid(true) { if projectID == "" || appID == "" {
return caos_errs.ThrowPreconditionFailed(nil, "PROJECT-Bff2g", "Errors.Application.Invalid") return caos_errs.ThrowPreconditionFailed(nil, "COMMAND-88fi0", "Errors.IDMissing")
} }
application.AppID, err = r.idGenerator.Next()
existingApp, err := r.getApplicationWriteModel(ctx, projectID, appID, resourceOwner)
if err != nil { if err != nil {
return err return err
} }
if existingApp.State == domain.AppStateUnspecified || existingApp.State == domain.AppStateRemoved {
projectAgg.PushEvents(project.NewApplicationAddedEvent(ctx, application.AppID, application.Name, application.Type)) return caos_errs.ThrowNotFound(nil, "COMMAND-ov9d3", "Errors.Project.App.NotExisting")
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 if existingApp.State != domain.AppStateActive {
return caos_errs.ThrowPreconditionFailed(nil, "COMMAND-dsh35", "Errors.Project.App.NotActive")
}
projectAgg := ProjectAggregateFromWriteModel(&existingApp.WriteModel)
projectAgg.PushEvents(project.NewApplicationDeactivatedEvent(ctx, appID))
return nil return r.eventstore.PushAggregate(ctx, existingApp, projectAgg)
}
func (r *CommandSide) ReactivateApplication(ctx context.Context, projectID, appID, resourceOwner string) error {
if projectID == "" || appID == "" {
return caos_errs.ThrowPreconditionFailed(nil, "COMMAND-983dF", "Errors.IDMissing")
}
existingApp, err := r.getApplicationWriteModel(ctx, projectID, appID, resourceOwner)
if err != nil {
return err
}
if existingApp.State == domain.AppStateUnspecified || existingApp.State == domain.AppStateRemoved {
return caos_errs.ThrowNotFound(nil, "COMMAND-ov9d3", "Errors.Project.App.NotExisting")
}
if existingApp.State != domain.AppStateInactive {
return caos_errs.ThrowPreconditionFailed(nil, "COMMAND-1n8cM", "Errors.Project.App.NotInactive")
}
projectAgg := ProjectAggregateFromWriteModel(&existingApp.WriteModel)
projectAgg.PushEvents(project.NewApplicationReactivatedEvent(ctx, appID))
return r.eventstore.PushAggregate(ctx, existingApp, projectAgg)
}
func (r *CommandSide) RemoveApplication(ctx context.Context, projectID, appID, resourceOwner string) error {
if projectID == "" || appID == "" {
return caos_errs.ThrowPreconditionFailed(nil, "COMMAND-1b7Jf", "Errors.IDMissing")
}
existingApp, err := r.getApplicationWriteModel(ctx, projectID, appID, resourceOwner)
if err != nil {
return err
}
if existingApp.State == domain.AppStateUnspecified || existingApp.State == domain.AppStateRemoved {
return caos_errs.ThrowNotFound(nil, "COMMAND-0po9s", "Errors.Project.App.NotExisting")
}
projectAgg := ProjectAggregateFromWriteModel(&existingApp.WriteModel)
projectAgg.PushEvents(project.NewApplicationRemovedEvent(ctx, appID, existingApp.Name, projectID))
return r.eventstore.PushAggregate(ctx, existingApp, projectAgg)
}
func (r *CommandSide) getApplicationWriteModel(ctx context.Context, projectID, appID, resourceOwner string) (*ApplicationWriteModel, error) {
appWriteModel := NewApplicationWriteModelWithAppIDC(projectID, appID, resourceOwner)
err := r.eventstore.FilterToQueryReducer(ctx, appWriteModel)
if err != nil {
return nil, err
}
return appWriteModel, nil
} }

View File

@ -9,11 +9,19 @@ import (
type ApplicationWriteModel struct { type ApplicationWriteModel struct {
eventstore.WriteModel eventstore.WriteModel
AppID string AppID string
State domain.AppState State domain.AppState
Name string Name string
Type domain.AppType }
OIDCConfig *domain.OIDCConfig
func NewApplicationWriteModelWithAppIDC(projectID, appID, resourceOwner string) *ApplicationWriteModel {
return &ApplicationWriteModel{
WriteModel: eventstore.WriteModel{
AggregateID: projectID,
ResourceOwner: resourceOwner,
},
AppID: appID,
}
} }
func NewApplicationWriteModel(projectID, resourceOwner string) *ApplicationWriteModel { func NewApplicationWriteModel(projectID, resourceOwner string) *ApplicationWriteModel {
@ -24,12 +32,35 @@ func NewApplicationWriteModel(projectID, resourceOwner string) *ApplicationWrite
}, },
} }
} }
func (wm *ApplicationWriteModel) AppendEvents(events ...eventstore.EventReader) { func (wm *ApplicationWriteModel) AppendEvents(events ...eventstore.EventReader) {
wm.WriteModel.AppendEvents(events...)
for _, event := range events { for _, event := range events {
switch e := event.(type) { switch e := event.(type) {
case *project.ApplicationAddedEvent: case *project.ApplicationAddedEvent:
if e.AppID != wm.AppID {
continue
}
wm.WriteModel.AppendEvents(e)
case *project.ApplicationChangedEvent:
if e.AppID != wm.AppID {
continue
}
wm.WriteModel.AppendEvents(e)
case *project.ApplicationDeactivatedEvent:
if e.AppID != wm.AppID {
continue
}
wm.WriteModel.AppendEvents(e)
case *project.ApplicationReactivatedEvent:
if e.AppID != wm.AppID {
continue
}
wm.WriteModel.AppendEvents(e)
case *project.ApplicationRemovedEvent:
if e.AppID != wm.AppID {
continue
}
wm.WriteModel.AppendEvents(e)
case *project.ProjectRemovedEvent:
wm.WriteModel.AppendEvents(e) wm.WriteModel.AppendEvents(e)
} }
} }
@ -41,15 +72,37 @@ func (wm *ApplicationWriteModel) Reduce() error {
case *project.ApplicationAddedEvent: case *project.ApplicationAddedEvent:
wm.Name = e.Name wm.Name = e.Name
wm.State = domain.AppStateActive wm.State = domain.AppStateActive
//case *project.ApplicationChangedEvent: case *project.ApplicationChangedEvent:
// wm.Name = e.Name wm.Name = e.Name
case *project.ApplicationDeactivatedEvent:
if wm.State == domain.AppStateRemoved {
continue
}
wm.State = domain.AppStateInactive
case *project.ApplicationReactivatedEvent:
if wm.State == domain.AppStateRemoved {
continue
}
wm.State = domain.AppStateActive
case *project.ApplicationRemovedEvent:
wm.State = domain.AppStateRemoved
case *project.ProjectRemovedEvent:
wm.State = domain.AppStateRemoved
} }
} }
return nil return wm.WriteModel.Reduce()
} }
func (wm *ApplicationWriteModel) Query() *eventstore.SearchQueryBuilder { func (wm *ApplicationWriteModel) Query() *eventstore.SearchQueryBuilder {
return eventstore.NewSearchQueryBuilder(eventstore.ColumnsEvent, project.AggregateType). return eventstore.NewSearchQueryBuilder(eventstore.ColumnsEvent, project.AggregateType).
AggregateIDs(wm.AggregateID). AggregateIDs(wm.AggregateID).
ResourceOwner(wm.ResourceOwner) ResourceOwner(wm.ResourceOwner)
//EventTypes(
// project.ApplicationAddedType,
// project.ApplicationChangedType,
// project.ApplicationDeactivatedType,
// project.ApplicationReactivatedType,
// project.ApplicationRemovedType,
// project.ProjectRemovedType,
//)
} }

View File

@ -0,0 +1,157 @@
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) AddOIDCApplication(ctx context.Context, application *domain.OIDCApp, resourceOwner string) (_ *domain.OIDCApp, err error) {
project, err := r.getProjectByID(ctx, application.AggregateID, resourceOwner)
if err != nil {
return nil, err
}
addedApplication := NewOIDCApplicationWriteModel(application.AggregateID, resourceOwner)
projectAgg := ProjectAggregateFromWriteModel(&addedApplication.WriteModel)
stringPw, err := r.addOIDCApplication(ctx, projectAgg, project, application, resourceOwner)
if err != nil {
return nil, err
}
addedApplication.AppID = application.AppID
err = r.eventstore.PushAggregate(ctx, addedApplication, projectAgg)
if err != nil {
return nil, err
}
result := oidcWriteModelToOIDCConfig(addedApplication)
result.ClientSecretString = stringPw
result.FillCompliance()
return result, nil
}
func (r *CommandSide) addOIDCApplication(ctx context.Context, projectAgg *project.Aggregate, proj *domain.Project, oidcApp *domain.OIDCApp, resourceOwner string) (stringPW string, err error) {
if !oidcApp.IsValid() {
return "", caos_errs.ThrowPreconditionFailed(nil, "PROJECT-Bff2g", "Errors.Application.Invalid")
}
oidcApp.AppID, err = r.idGenerator.Next()
if err != nil {
return "", err
}
projectAgg.PushEvents(project.NewApplicationAddedEvent(ctx, oidcApp.AppID, oidcApp.AppName, resourceOwner))
var stringPw string
err = oidcApp.GenerateNewClientID(r.idGenerator, proj)
if err != nil {
return "", err
}
stringPw, err = oidcApp.GenerateClientSecretIfNeeded(r.applicationSecretGenerator)
if err != nil {
return "", err
}
projectAgg.PushEvents(project.NewOIDCConfigAddedEvent(ctx,
oidcApp.OIDCVersion,
oidcApp.AppID,
oidcApp.ClientID,
oidcApp.ClientSecret,
oidcApp.RedirectUris,
oidcApp.ResponseTypes,
oidcApp.GrantTypes,
oidcApp.ApplicationType,
oidcApp.AuthMethodType,
oidcApp.PostLogoutRedirectUris,
oidcApp.DevMode,
oidcApp.AccessTokenType,
oidcApp.AccessTokenRoleAssertion,
oidcApp.IDTokenRoleAssertion,
oidcApp.IDTokenUserinfoAssertion,
oidcApp.ClockSkew))
return stringPw, nil
}
func (r *CommandSide) ChangeOIDCApplication(ctx context.Context, oidc *domain.OIDCApp, resourceOwner string) (*domain.OIDCApp, error) {
if !oidc.IsValid() {
return nil, caos_errs.ThrowPreconditionFailed(nil, "COMMAND-1m900", "Errors.Project.App.OIDCConfigInvalid")
}
existingOIDC, err := r.getOIDCAppWriteModel(ctx, oidc.AggregateID, oidc.AppID, resourceOwner)
if err != nil {
return nil, err
}
if existingOIDC.State == domain.AppStateUnspecified || existingOIDC.State == domain.AppStateRemoved {
return nil, caos_errs.ThrowNotFound(nil, "COMMAND-2n8uU", "Errors.Project.App.NotExisting")
}
changedEvent, hasChanged, err := existingOIDC.NewChangedEvent(
ctx,
oidc.AppID,
oidc.ClientID,
oidc.RedirectUris,
oidc.PostLogoutRedirectUris,
oidc.ResponseTypes,
oidc.GrantTypes,
oidc.ApplicationType,
oidc.AuthMethodType,
oidc.OIDCVersion,
oidc.AccessTokenType,
oidc.DevMode,
oidc.AccessTokenRoleAssertion,
oidc.IDTokenRoleAssertion,
oidc.IDTokenUserinfoAssertion,
oidc.ClockSkew)
if err != nil {
return nil, err
}
if !hasChanged {
return nil, caos_errs.ThrowPreconditionFailed(nil, "COMMAND-1m88i", "Errors.NoChangesFound")
}
projectAgg := ProjectAggregateFromWriteModel(&existingOIDC.WriteModel)
projectAgg.PushEvents(changedEvent)
err = r.eventstore.PushAggregate(ctx, existingOIDC, projectAgg)
if err != nil {
return nil, err
}
result := oidcWriteModelToOIDCConfig(existingOIDC)
result.FillCompliance()
return result, nil
}
func (r *CommandSide) ChangeOIDCApplicationSecret(ctx context.Context, projectID, appID, resourceOwner string) (*domain.OIDCApp, error) {
if projectID == "" || appID == "" {
return nil, caos_errs.ThrowPreconditionFailed(nil, "COMMAND-99i83", "Errors.IDMissing")
}
existingOIDC, err := r.getOIDCAppWriteModel(ctx, projectID, appID, resourceOwner)
if err != nil {
return nil, err
}
if existingOIDC.State == domain.AppStateUnspecified || existingOIDC.State == domain.AppStateRemoved {
return nil, caos_errs.ThrowNotFound(nil, "COMMAND-2g66f", "Errors.Project.App.NotExisting")
}
cryptoSecret, stringPW, err := domain.NewClientSecret(r.applicationSecretGenerator)
if err != nil {
return nil, err
}
projectAgg := ProjectAggregateFromWriteModel(&existingOIDC.WriteModel)
projectAgg.PushEvents(project.NewOIDCConfigSecretChangedEvent(ctx, appID, cryptoSecret))
err = r.eventstore.PushAggregate(ctx, existingOIDC, projectAgg)
if err != nil {
return nil, err
}
result := oidcWriteModelToOIDCConfig(existingOIDC)
result.ClientSecretString = stringPW
return result, err
}
func (r *CommandSide) getOIDCAppWriteModel(ctx context.Context, projectID, appID, resourceOwner string) (*OIDCApplicationWriteModel, error) {
appWriteModel := NewOIDCApplicationWriteModelWithAppIDC(projectID, appID, resourceOwner)
err := r.eventstore.FilterToQueryReducer(ctx, appWriteModel)
if err != nil {
return nil, err
}
return appWriteModel, nil
}

View File

@ -0,0 +1,289 @@
package command
import (
"context"
"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/project"
"reflect"
"time"
)
type OIDCApplicationWriteModel struct {
eventstore.WriteModel
AppID string
AppName string
ClientID string
ClientSecret *crypto.CryptoValue
ClientSecretString string
RedirectUris []string
ResponseTypes []domain.OIDCResponseType
GrantTypes []domain.OIDCGrantType
ApplicationType domain.OIDCApplicationType
AuthMethodType domain.OIDCAuthMethodType
PostLogoutRedirectUris []string
OIDCVersion domain.OIDCVersion
Compliance *domain.Compliance
DevMode bool
AccessTokenType domain.OIDCTokenType
AccessTokenRoleAssertion bool
IDTokenRoleAssertion bool
IDTokenUserinfoAssertion bool
ClockSkew time.Duration
State domain.AppState
}
func NewOIDCApplicationWriteModelWithAppIDC(projectID, appID, resourceOwner string) *OIDCApplicationWriteModel {
return &OIDCApplicationWriteModel{
WriteModel: eventstore.WriteModel{
AggregateID: projectID,
ResourceOwner: resourceOwner,
},
AppID: appID,
}
}
func NewOIDCApplicationWriteModel(projectID, resourceOwner string) *OIDCApplicationWriteModel {
return &OIDCApplicationWriteModel{
WriteModel: eventstore.WriteModel{
AggregateID: projectID,
ResourceOwner: resourceOwner,
},
}
}
func (wm *OIDCApplicationWriteModel) AppendEvents(events ...eventstore.EventReader) {
for _, event := range events {
switch e := event.(type) {
case *project.ApplicationAddedEvent:
if e.AppID != wm.AppID {
continue
}
wm.WriteModel.AppendEvents(e)
case *project.ApplicationChangedEvent:
if e.AppID != wm.AppID {
continue
}
wm.WriteModel.AppendEvents(e)
case *project.ApplicationDeactivatedEvent:
if e.AppID != wm.AppID {
continue
}
wm.WriteModel.AppendEvents(e)
case *project.ApplicationReactivatedEvent:
if e.AppID != wm.AppID {
continue
}
wm.WriteModel.AppendEvents(e)
case *project.ApplicationRemovedEvent:
if e.AppID != wm.AppID {
continue
}
wm.WriteModel.AppendEvents(e)
case *project.OIDCConfigAddedEvent:
if e.AppID != wm.AppID {
continue
}
wm.WriteModel.AppendEvents(e)
case *project.OIDCConfigChangedEvent:
if e.AppID != wm.AppID {
continue
}
wm.WriteModel.AppendEvents(e)
case *project.OIDCConfigSecretChangedEvent:
if e.AppID != wm.AppID {
continue
}
wm.WriteModel.AppendEvents(e)
case *project.ProjectRemovedEvent:
wm.WriteModel.AppendEvents(e)
}
}
}
func (wm *OIDCApplicationWriteModel) Reduce() error {
for _, event := range wm.Events {
switch e := event.(type) {
case *project.ApplicationAddedEvent:
wm.AppName = e.Name
wm.State = domain.AppStateActive
case *project.ApplicationChangedEvent:
wm.AppName = e.Name
case *project.ApplicationDeactivatedEvent:
if wm.State == domain.AppStateRemoved {
continue
}
wm.State = domain.AppStateInactive
case *project.ApplicationReactivatedEvent:
if wm.State == domain.AppStateRemoved {
continue
}
wm.State = domain.AppStateActive
case *project.ApplicationRemovedEvent:
wm.State = domain.AppStateRemoved
case *project.OIDCConfigAddedEvent:
wm.appendAddOIDCEvent(e)
case *project.OIDCConfigChangedEvent:
wm.appendChangeOIDCEvent(e)
case *project.OIDCConfigSecretChangedEvent:
wm.ClientSecret = e.ClientSecret
case *project.ProjectRemovedEvent:
wm.State = domain.AppStateRemoved
}
}
return wm.WriteModel.Reduce()
}
func (wm *OIDCApplicationWriteModel) appendAddOIDCEvent(e *project.OIDCConfigAddedEvent) {
wm.ClientID = e.ClientID
wm.ClientSecret = e.ClientSecret
wm.RedirectUris = e.RedirectUris
wm.ResponseTypes = e.ResponseTypes
wm.GrantTypes = e.GrantTypes
wm.ApplicationType = e.ApplicationType
wm.AuthMethodType = e.AuthMethodType
wm.PostLogoutRedirectUris = e.PostLogoutRedirectUris
wm.OIDCVersion = e.Version
wm.DevMode = e.DevMode
wm.AccessTokenType = e.AccessTokenType
wm.AccessTokenRoleAssertion = e.AccessTokenRoleAssertion
wm.IDTokenRoleAssertion = e.IDTokenRoleAssertion
wm.IDTokenUserinfoAssertion = e.IDTokenUserinfoAssertion
wm.ClockSkew = e.ClockSkew
}
func (wm *OIDCApplicationWriteModel) appendChangeOIDCEvent(e *project.OIDCConfigChangedEvent) {
if e.ClientID != nil {
wm.ClientID = *e.ClientID
}
if e.RedirectUris != nil {
wm.RedirectUris = *e.RedirectUris
}
if e.ResponseTypes != nil {
wm.ResponseTypes = *e.ResponseTypes
}
if e.GrantTypes != nil {
wm.GrantTypes = *e.GrantTypes
}
if e.ApplicationType != nil {
wm.ApplicationType = *e.ApplicationType
}
if e.AuthMethodType != nil {
wm.AuthMethodType = *e.AuthMethodType
}
if e.PostLogoutRedirectUris != nil {
wm.PostLogoutRedirectUris = *e.PostLogoutRedirectUris
}
if e.Version != nil {
wm.OIDCVersion = *e.Version
}
if e.DevMode != nil {
wm.DevMode = *e.DevMode
}
if e.AccessTokenType != nil {
wm.AccessTokenType = *e.AccessTokenType
}
if e.AccessTokenRoleAssertion != nil {
wm.AccessTokenRoleAssertion = *e.AccessTokenRoleAssertion
}
if e.IDTokenRoleAssertion != nil {
wm.IDTokenRoleAssertion = *e.IDTokenRoleAssertion
}
if e.IDTokenUserinfoAssertion != nil {
wm.IDTokenUserinfoAssertion = *e.IDTokenUserinfoAssertion
}
if e.ClockSkew != nil {
wm.ClockSkew = *e.ClockSkew
}
}
func (wm *OIDCApplicationWriteModel) Query() *eventstore.SearchQueryBuilder {
return eventstore.NewSearchQueryBuilder(eventstore.ColumnsEvent, project.AggregateType).
AggregateIDs(wm.AggregateID).
ResourceOwner(wm.ResourceOwner)
//EventTypes(
// project.ApplicationAddedType,
// project.ApplicationChangedType,
// project.ApplicationDeactivatedType,
// project.ApplicationReactivatedType,
// project.ApplicationRemovedType,
// project.OIDCConfigAddedType,
// project.OIDCConfigChangedType,
// project.OIDCConfigSecretChangedType,
// project.ProjectRemovedType,
//)
}
func (wm *OIDCApplicationWriteModel) NewChangedEvent(
ctx context.Context,
appID,
clientID string,
redirectURIS,
postLogoutRedirectURIs []string,
responseTypes []domain.OIDCResponseType,
grantTypes []domain.OIDCGrantType,
appType domain.OIDCApplicationType,
authMethodType domain.OIDCAuthMethodType,
oidcVersion domain.OIDCVersion,
accessTokenType domain.OIDCTokenType,
devMode,
accessTokenRoleAssertion,
idTokenRoleAssertion,
idTokenUserinfoAssertion bool,
clockSkew time.Duration,
) (*project.OIDCConfigChangedEvent, bool, error) {
changes := make([]project.OIDCConfigChanges, 0)
var err error
if wm.ClientID != clientID {
changes = append(changes, project.ChangeClientID(clientID))
}
if !reflect.DeepEqual(wm.RedirectUris, redirectURIS) {
changes = append(changes, project.ChangeRedirectURIs(redirectURIS))
}
if !reflect.DeepEqual(wm.ResponseTypes, responseTypes) {
changes = append(changes, project.ChangeResponseTypes(responseTypes))
}
if !reflect.DeepEqual(wm.GrantTypes, grantTypes) {
changes = append(changes, project.ChangeGrantTypes(grantTypes))
}
if wm.ApplicationType != appType {
changes = append(changes, project.ChangeApplicationType(appType))
}
if wm.AuthMethodType != authMethodType {
changes = append(changes, project.ChangeAuthMethodType(authMethodType))
}
if !reflect.DeepEqual(wm.PostLogoutRedirectUris, postLogoutRedirectURIs) {
changes = append(changes, project.ChangePostLogoutRedirectURIs(postLogoutRedirectURIs))
}
if wm.OIDCVersion != oidcVersion {
changes = append(changes, project.ChangeVersion(oidcVersion))
}
if wm.DevMode != devMode {
changes = append(changes, project.ChangeDevMode(devMode))
}
if wm.AccessTokenType != accessTokenType {
changes = append(changes, project.ChangeAccessTokenType(accessTokenType))
}
if wm.AccessTokenRoleAssertion != accessTokenRoleAssertion {
changes = append(changes, project.ChangeAccessTokenRoleAssertion(accessTokenRoleAssertion))
}
if wm.IDTokenRoleAssertion != idTokenRoleAssertion {
changes = append(changes, project.ChangeIDTokenRoleAssertion(idTokenRoleAssertion))
}
if wm.IDTokenUserinfoAssertion != idTokenUserinfoAssertion {
changes = append(changes, project.ChangeIDTokenUserinfoAssertion(idTokenUserinfoAssertion))
}
if wm.ClockSkew != clockSkew {
changes = append(changes, project.ChangeClockSkew(clockSkew))
}
if len(changes) == 0 {
return nil, false, nil
}
changeEvent, err := project.NewOIDCConfigChangedEvent(ctx, appID, changes)
if err != nil {
return nil, false, err
}
return changeEvent, true, nil
}

View File

@ -13,13 +13,62 @@ func projectWriteModelToProject(writeModel *ProjectWriteModel) *domain.Project {
} }
} }
func applicationWriteModelToApplication(writeModel *ApplicationWriteModel) *domain.Application { func projectGrantWriteModelToProjectGrant(writeModel *ProjectGrantWriteModel) *domain.ProjectGrant {
return &domain.Application{ return &domain.ProjectGrant{
ObjectRoot: writeModelToObjectRoot(writeModel.WriteModel), ObjectRoot: writeModelToObjectRoot(writeModel.WriteModel),
AppID: writeModel.AggregateID, GrantID: writeModel.GrantID,
State: writeModel.State, GrantedOrgID: writeModel.GrantedOrgID,
Name: writeModel.Name, RoleKeys: writeModel.RoleKeys,
Type: writeModel.Type, State: writeModel.State,
//TODO: OIDC Config }
}
func applicationWriteModelToApplication(writeModel *ApplicationWriteModel) domain.Application {
return &domain.ChangeApp{
AppID: writeModel.AppID,
AppName: writeModel.Name,
State: writeModel.State,
}
}
func oidcWriteModelToOIDCConfig(writeModel *OIDCApplicationWriteModel) *domain.OIDCApp {
return &domain.OIDCApp{
ObjectRoot: writeModelToObjectRoot(writeModel.WriteModel),
AppID: writeModel.AggregateID,
AppName: writeModel.AppName,
State: writeModel.State,
ClientID: writeModel.ClientID,
ClientSecret: writeModel.ClientSecret,
RedirectUris: writeModel.RedirectUris,
ResponseTypes: writeModel.ResponseTypes,
GrantTypes: writeModel.GrantTypes,
ApplicationType: writeModel.ApplicationType,
AuthMethodType: writeModel.AuthMethodType,
PostLogoutRedirectUris: writeModel.PostLogoutRedirectUris,
OIDCVersion: writeModel.OIDCVersion,
DevMode: writeModel.DevMode,
AccessTokenType: writeModel.AccessTokenType,
AccessTokenRoleAssertion: writeModel.AccessTokenRoleAssertion,
IDTokenRoleAssertion: writeModel.IDTokenRoleAssertion,
IDTokenUserinfoAssertion: writeModel.IDTokenUserinfoAssertion,
ClockSkew: writeModel.ClockSkew,
}
}
func roleWriteModelToRole(writeModel *ProjectRoleWriteModel) *domain.ProjectRole {
return &domain.ProjectRole{
ObjectRoot: writeModelToObjectRoot(writeModel.WriteModel),
Key: writeModel.Key,
DisplayName: writeModel.DisplayName,
Group: writeModel.Group,
}
}
func memberWriteModelToProjectGrantMember(writeModel *ProjectGrantMemberWriteModel) *domain.ProjectGrantMember {
return &domain.ProjectGrantMember{
ObjectRoot: writeModelToObjectRoot(writeModel.WriteModel),
Roles: writeModel.Roles,
GrantID: writeModel.GrantID,
UserID: writeModel.UserID,
} }
} }

View File

@ -0,0 +1,145 @@
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"
"github.com/caos/zitadel/internal/v2/repository/project"
"reflect"
)
func (r *CommandSide) AddProjectGrant(ctx context.Context, grant *domain.ProjectGrant, resourceOwner string) (_ *domain.ProjectGrant, err error) {
if !grant.IsValid() {
return nil, caos_errs.ThrowPreconditionFailed(nil, "PROJECT-Bff2g", "Errors.Project.Grant.Invalid")
}
grant.GrantID, err = r.idGenerator.Next()
if err != nil {
return nil, err
}
err = r.checkProjectExists(ctx, grant.AggregateID, resourceOwner)
if err != nil {
return nil, err
}
err = r.checkOrgExists(ctx, grant.GrantedOrgID)
if err != nil {
return nil, err
}
addedGrant := NewProjectGrantWriteModel(grant.GrantID, grant.AggregateID, resourceOwner)
projectAgg := ProjectAggregateFromWriteModel(&addedGrant.WriteModel)
projectAgg.PushEvents(project.NewGrantAddedEvent(ctx, grant.GrantID, grant.GrantedOrgID, grant.AggregateID, grant.RoleKeys))
if err != nil {
return nil, err
}
err = r.eventstore.PushAggregate(ctx, addedGrant, projectAgg)
if err != nil {
return nil, err
}
return projectGrantWriteModelToProjectGrant(addedGrant), nil
}
func (r *CommandSide) ChangeProjectGrant(ctx context.Context, grant *domain.ProjectGrant, resourceOwner string) (_ *domain.ProjectGrant, err error) {
if grant.GrantID == "" {
return nil, caos_errs.ThrowPreconditionFailed(nil, "PROJECT-1j83s", "Errors.IDMissing")
}
err = r.checkProjectExists(ctx, grant.AggregateID, resourceOwner)
if err != nil {
return nil, err
}
existingGrant, err := r.projectGrantWriteModelByID(ctx, grant.GrantID, grant.AggregateID, resourceOwner)
if err != nil {
return nil, err
}
projectAgg := ProjectAggregateFromWriteModel(&existingGrant.WriteModel)
if reflect.DeepEqual(existingGrant.RoleKeys, grant.RoleKeys) {
return nil, caos_errs.ThrowPreconditionFailed(nil, "PROJECT-0o0pL", "Errors.NoChangesFoundc")
}
projectAgg.PushEvents(project.NewGrantChangedEvent(ctx, grant.GrantID, grant.RoleKeys))
//TODO: Change UserGrants (if role removed should be removed from user grant)
err = r.eventstore.PushAggregate(ctx, existingGrant, projectAgg)
if err != nil {
return nil, err
}
return projectGrantWriteModelToProjectGrant(existingGrant), nil
}
func (r *CommandSide) DeactivateProjectGrant(ctx context.Context, projectID, grantID, resourceOwner string) (err error) {
if grantID == "" || projectID == "" {
return caos_errs.ThrowPreconditionFailed(nil, "PROJECT-p0s4V", "Errors.IDMissing")
}
err = r.checkProjectExists(ctx, projectID, resourceOwner)
if err != nil {
return err
}
existingGrant, err := r.projectGrantWriteModelByID(ctx, grantID, projectID, resourceOwner)
if err != nil {
return err
}
if existingGrant.State != domain.ProjectGrantStateActive {
return caos_errs.ThrowPreconditionFailed(nil, "PROJECT-47fu8", "Errors.Project.Grant.NotActive")
}
projectAgg := ProjectAggregateFromWriteModel(&existingGrant.WriteModel)
projectAgg.PushEvents(project.NewGrantDeactivateEvent(ctx, grantID))
return r.eventstore.PushAggregate(ctx, existingGrant, projectAgg)
}
func (r *CommandSide) ReactivateProjectGrant(ctx context.Context, projectID, grantID, resourceOwner string) (err error) {
if grantID == "" || projectID == "" {
return caos_errs.ThrowPreconditionFailed(nil, "PROJECT-p0s4V", "Errors.IDMissing")
}
err = r.checkProjectExists(ctx, projectID, resourceOwner)
if err != nil {
return err
}
existingGrant, err := r.projectGrantWriteModelByID(ctx, grantID, projectID, resourceOwner)
if err != nil {
return err
}
if existingGrant.State != domain.ProjectGrantStateInactive {
return caos_errs.ThrowPreconditionFailed(nil, "PROJECT-47fu8", "Errors.Project.Grant.NotInactive")
}
projectAgg := ProjectAggregateFromWriteModel(&existingGrant.WriteModel)
projectAgg.PushEvents(project.NewGrantReactivatedEvent(ctx, grantID))
return r.eventstore.PushAggregate(ctx, existingGrant, projectAgg)
}
func (r *CommandSide) RemoveProjectGrant(ctx context.Context, projectID, grantID, resourceOwner string) (err error) {
if grantID == "" || projectID == "" {
return caos_errs.ThrowPreconditionFailed(nil, "PROJECT-1m9fJ", "Errors.IDMissing")
}
err = r.checkProjectExists(ctx, projectID, resourceOwner)
if err != nil {
return err
}
existingGrant, err := r.projectGrantWriteModelByID(ctx, grantID, projectID, resourceOwner)
if err != nil {
return err
}
projectAgg := ProjectAggregateFromWriteModel(&existingGrant.WriteModel)
projectAgg.PushEvents(project.NewGrantRemovedEvent(ctx, grantID, existingGrant.GrantedOrgID, projectID))
//TODO: Cascade Remove usergrants
return r.eventstore.PushAggregate(ctx, existingGrant, projectAgg)
}
func (r *CommandSide) projectGrantWriteModelByID(ctx context.Context, grantID, projectID, resourceOwner string) (member *ProjectGrantWriteModel, err error) {
ctx, span := tracing.NewSpan(ctx)
defer func() { span.EndWithError(err) }()
writeModel := NewProjectGrantWriteModel(grantID, projectID, resourceOwner)
err = r.eventstore.FilterToQueryReducer(ctx, writeModel)
if err != nil {
return nil, err
}
if writeModel.State == domain.ProjectGrantStateUnspecified || writeModel.State == domain.ProjectGrantStateRemoved {
return nil, caos_errs.ThrowNotFound(nil, "PROJECT-D8JxR", "Errors.Project.Grant.NotFound")
}
return writeModel, nil
}

View File

@ -0,0 +1,100 @@
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) AddProjectGrantMember(ctx context.Context, member *domain.ProjectGrantMember, resourceOwner string) (*domain.ProjectGrantMember, error) {
if !member.IsValid() {
return nil, caos_errs.ThrowPreconditionFailed(nil, "PROJECT-8fi7G", "Errors.Project.Member.Invalid")
}
err := r.checkUserExists(ctx, member.UserID, "")
if err != nil {
return nil, err
}
addedMember := NewProjectGrantMemberWriteModel(member.AggregateID, member.UserID, member.GrantID)
err = r.eventstore.FilterToQueryReducer(ctx, addedMember)
if err != nil {
return nil, err
}
if addedMember.State == domain.MemberStateActive {
return nil, caos_errs.ThrowPreconditionFailed(nil, "PROJECT-16dVN", "Errors.Project.Member.AlreadyExists")
}
projectAgg := ProjectAggregateFromWriteModel(&addedMember.WriteModel)
projectAgg.PushEvents(project.NewProjectGrantMemberAddedEvent(ctx, member.AggregateID, member.UserID, member.GrantID, member.Roles...))
err = r.eventstore.PushAggregate(ctx, addedMember, projectAgg)
if err != nil {
return nil, err
}
return memberWriteModelToProjectGrantMember(addedMember), nil
}
//ChangeProjectGrantMember updates an existing member
func (r *CommandSide) 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")
}
existingMember, err := r.projectGrantMemberWriteModelByID(ctx, member.AggregateID, member.UserID, member.GrantID)
if err != nil {
return nil, err
}
if reflect.DeepEqual(existingMember.Roles, member.Roles) {
return nil, caos_errs.ThrowPreconditionFailed(nil, "PROJECT-2n8vx", "Errors.Project.Member.RolesNotChanged")
}
projectAgg := ProjectAggregateFromWriteModel(&existingMember.WriteModel)
projectAgg.PushEvents(project.NewProjectGrantMemberChangedEvent(ctx, member.UserID, member.GrantID, 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 memberWriteModelToProjectGrantMember(existingMember), nil
}
func (r *CommandSide) RemoveProjectGrantMember(ctx context.Context, projectID, userID, grantID, resourceOwner string) error {
m, err := r.projectGrantMemberWriteModelByID(ctx, projectID, userID, grantID)
if err != nil {
return err
}
projectAgg := ProjectAggregateFromWriteModel(&m.WriteModel)
projectAgg.PushEvents(project.NewProjectGrantMemberRemovedEvent(ctx, projectID, userID, grantID))
return r.eventstore.PushAggregate(ctx, m, projectAgg)
}
func (r *CommandSide) projectGrantMemberWriteModelByID(ctx context.Context, projectID, userID, grantID string) (member *ProjectGrantMemberWriteModel, err error) {
ctx, span := tracing.NewSpan(ctx)
defer func() { span.EndWithError(err) }()
writeModel := NewProjectGrantMemberWriteModel(projectID, userID, grantID)
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-37fug", "Errors.NotFound")
}
return writeModel, nil
}

View File

@ -0,0 +1,82 @@
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 ProjectGrantMemberWriteModel struct {
eventstore.WriteModel
GrantID string
UserID string
Roles []string
State domain.MemberState
}
func NewProjectGrantMemberWriteModel(projectID, userID, grantID string) *ProjectGrantMemberWriteModel {
return &ProjectGrantMemberWriteModel{
WriteModel: eventstore.WriteModel{
AggregateID: projectID,
},
UserID: userID,
GrantID: grantID,
}
}
func (wm *ProjectGrantMemberWriteModel) AppendEvents(events ...eventstore.EventReader) {
for _, event := range events {
switch e := event.(type) {
case *project.GrantMemberAddedEvent:
if e.UserID != wm.UserID || e.GrantID != wm.GrantID {
continue
}
wm.WriteModel.AppendEvents(e)
case *project.GrantMemberChangedEvent:
if e.UserID != wm.UserID || e.GrantID != wm.GrantID {
continue
}
wm.WriteModel.AppendEvents(e)
case *project.GrantMemberRemovedEvent:
if e.UserID != wm.UserID || e.GrantID != wm.GrantID {
continue
}
wm.WriteModel.AppendEvents(e)
case *project.GrantRemovedEvent:
if e.GrantID != wm.GrantID {
continue
}
wm.WriteModel.AppendEvents(e)
}
}
}
func (wm *ProjectGrantMemberWriteModel) Reduce() error {
for _, event := range wm.Events {
switch e := event.(type) {
case *project.GrantMemberAddedEvent:
wm.Roles = e.Roles
wm.State = domain.MemberStateActive
case *project.GrantMemberChangedEvent:
wm.Roles = e.Roles
case *project.GrantMemberRemovedEvent:
wm.State = domain.MemberStateRemoved
case *project.GrantRemovedEvent, *project.ProjectRemovedEvent:
wm.State = domain.MemberStateRemoved
}
}
return wm.WriteModel.Reduce()
}
func (wm *ProjectGrantMemberWriteModel) Query() *eventstore.SearchQueryBuilder {
return eventstore.NewSearchQueryBuilder(eventstore.ColumnsEvent, project.AggregateType).
AggregateIDs(wm.AggregateID)
//EventTypes(
// project.GrantMemberAddedType,
// project.GrantMemberChangedType,
// project.GrantMemberRemovedType,
// project.GrantRemovedType,
// project.ProjectRemovedType)
}

View File

@ -0,0 +1,104 @@
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 ProjectGrantWriteModel struct {
eventstore.WriteModel
GrantID string
GrantedOrgID string
RoleKeys []string
State domain.ProjectGrantState
}
func NewProjectGrantWriteModel(grantID, projectID, resourceOwner string) *ProjectGrantWriteModel {
return &ProjectGrantWriteModel{
WriteModel: eventstore.WriteModel{
AggregateID: projectID,
ResourceOwner: resourceOwner,
},
GrantID: grantID,
}
}
func (wm *ProjectGrantWriteModel) AppendEvents(events ...eventstore.EventReader) {
for _, event := range events {
switch e := event.(type) {
case *project.GrantAddedEvent:
if e.GrantID == wm.GrantID {
wm.WriteModel.AppendEvents(e)
}
case *project.GrantChangedEvent:
if e.GrantID == wm.GrantID {
wm.WriteModel.AppendEvents(e)
}
case *project.GrantCascadeChangedEvent:
if e.GrantID == wm.GrantID {
wm.WriteModel.AppendEvents(e)
}
case *project.GrantDeactivateEvent:
if e.GrantID == wm.GrantID {
wm.WriteModel.AppendEvents(e)
}
case *project.GrantReactivatedEvent:
if e.GrantID == wm.GrantID {
wm.WriteModel.AppendEvents(e)
}
case *project.GrantRemovedEvent:
if e.GrantID == wm.GrantID {
wm.WriteModel.AppendEvents(e)
}
case *project.ProjectRemovedEvent:
wm.WriteModel.AppendEvents(e)
}
}
}
func (wm *ProjectGrantWriteModel) Reduce() error {
for _, event := range wm.Events {
switch e := event.(type) {
case *project.GrantAddedEvent:
wm.GrantID = e.GrantID
wm.GrantedOrgID = e.GrantedOrgID
wm.RoleKeys = e.RoleKeys
wm.State = domain.ProjectGrantStateActive
case *project.GrantChangedEvent:
wm.RoleKeys = e.RoleKeys
case *project.GrantCascadeChangedEvent:
wm.RoleKeys = e.RoleKeys
case *project.GrantDeactivateEvent:
if wm.State == domain.ProjectGrantStateRemoved {
continue
}
wm.State = domain.ProjectGrantStateInactive
case *project.GrantReactivatedEvent:
if wm.State == domain.ProjectGrantStateRemoved {
continue
}
wm.State = domain.ProjectGrantStateActive
case *project.GrantRemovedEvent:
wm.State = domain.ProjectGrantStateRemoved
case *project.ProjectRemovedEvent:
wm.State = domain.ProjectGrantStateRemoved
}
}
return wm.WriteModel.Reduce()
}
func (wm *ProjectGrantWriteModel) Query() *eventstore.SearchQueryBuilder {
return eventstore.NewSearchQueryBuilder(eventstore.ColumnsEvent, project.AggregateType).
AggregateIDs(wm.AggregateID).
ResourceOwner(wm.ResourceOwner)
//EventTypes(
// project.GrantAddedType,
// project.GrantChangedType,
// project.GrantCascadeChangedType,
// project.GrantDeactivatedType,
// project.GrantReactivatedType,
// project.GrantRemovedType,
// project.ProjectRemovedType)
}

View File

@ -31,10 +31,14 @@ func (r *CommandSide) addProjectMember(ctx context.Context, projectAgg *project.
//TODO: check if roles valid //TODO: check if roles valid
if !member.IsValid() { if !member.IsValid() {
return caos_errs.ThrowPreconditionFailed(nil, "PROJECT-W8m4l", "Errors.Project.MemberInvalid") return caos_errs.ThrowPreconditionFailed(nil, "PROJECT-W8m4l", "Errors.Project.Member.Invalid")
} }
err := r.eventstore.FilterToQueryReducer(ctx, addedMember) err := r.checkUserExists(ctx, addedMember.UserID, "")
if err != nil {
return err
}
err = r.eventstore.FilterToQueryReducer(ctx, addedMember)
if err != nil { if err != nil {
return err return err
} }
@ -42,7 +46,7 @@ func (r *CommandSide) addProjectMember(ctx context.Context, projectAgg *project.
return errors.ThrowAlreadyExists(nil, "PROJECT-PtXi1", "Errors.Project.Member.AlreadyExists") return errors.ThrowAlreadyExists(nil, "PROJECT-PtXi1", "Errors.Project.Member.AlreadyExists")
} }
projectAgg.PushEvents(project.NewMemberAddedEvent(ctx, member.UserID, member.Roles...)) projectAgg.PushEvents(project.NewProjectMemberAddedEvent(ctx, member.UserID, member.Roles...))
return nil return nil
} }
@ -52,7 +56,7 @@ func (r *CommandSide) ChangeProjectMember(ctx context.Context, member *domain.Me
//TODO: check if roles valid //TODO: check if roles valid
if !member.IsValid() { if !member.IsValid() {
return nil, caos_errs.ThrowPreconditionFailed(nil, "PROJECT-LiaZi", "Errors.Project.MemberInvalid") return nil, caos_errs.ThrowPreconditionFailed(nil, "PROJECT-LiaZi", "Errors.Project.Member.Invalid")
} }
existingMember, err := r.projectMemberWriteModelByID(ctx, member.AggregateID, member.UserID, resourceOwner) existingMember, err := r.projectMemberWriteModelByID(ctx, member.AggregateID, member.UserID, resourceOwner)
@ -64,7 +68,7 @@ func (r *CommandSide) ChangeProjectMember(ctx context.Context, member *domain.Me
return nil, caos_errs.ThrowPreconditionFailed(nil, "PROJECT-LiaZi", "Errors.Project.Member.RolesNotChanged") return nil, caos_errs.ThrowPreconditionFailed(nil, "PROJECT-LiaZi", "Errors.Project.Member.RolesNotChanged")
} }
projectAgg := ProjectAggregateFromWriteModel(&existingMember.MemberWriteModel.WriteModel) projectAgg := ProjectAggregateFromWriteModel(&existingMember.MemberWriteModel.WriteModel)
projectAgg.PushEvents(project.NewMemberChangedEvent(ctx, member.UserID, member.Roles...)) projectAgg.PushEvents(project.NewProjectMemberChangedEvent(ctx, member.UserID, member.Roles...))
events, err := r.eventstore.PushAggregates(ctx, projectAgg) events, err := r.eventstore.PushAggregates(ctx, projectAgg)
if err != nil { if err != nil {
@ -89,7 +93,7 @@ func (r *CommandSide) RemoveProjectMember(ctx context.Context, projectID, userID
} }
projectAgg := ProjectAggregateFromWriteModel(&m.MemberWriteModel.WriteModel) projectAgg := ProjectAggregateFromWriteModel(&m.MemberWriteModel.WriteModel)
projectAgg.PushEvents(project.NewMemberRemovedEvent(ctx, userID)) projectAgg.PushEvents(project.NewProjectMemberRemovedEvent(ctx, userID))
return r.eventstore.PushAggregate(ctx, m, projectAgg) return r.eventstore.PushAggregate(ctx, m, projectAgg)
} }

View File

@ -1,6 +1,7 @@
package command package command
import ( import (
"context"
"github.com/caos/zitadel/internal/eventstore/v2" "github.com/caos/zitadel/internal/eventstore/v2"
"github.com/caos/zitadel/internal/v2/domain" "github.com/caos/zitadel/internal/v2/domain"
"github.com/caos/zitadel/internal/v2/repository/project" "github.com/caos/zitadel/internal/v2/repository/project"
@ -33,12 +34,34 @@ func (wm *ProjectWriteModel) Reduce() error {
switch e := event.(type) { switch e := event.(type) {
case *project.ProjectAddedEvent: case *project.ProjectAddedEvent:
wm.Name = e.Name wm.Name = e.Name
wm.ProjectRoleAssertion = e.ProjectRoleAssertion
wm.ProjectRoleCheck = e.ProjectRoleCheck
wm.State = domain.ProjectStateActive wm.State = domain.ProjectStateActive
//case *project.ProjectChangedEvent: case *project.ProjectChangeEvent:
// wm.Name = e.Name if e.Name != nil {
wm.Name = *e.Name
}
if e.ProjectRoleAssertion != nil {
wm.ProjectRoleAssertion = *e.ProjectRoleAssertion
}
if e.ProjectRoleCheck != nil {
wm.ProjectRoleCheck = *e.ProjectRoleCheck
}
case *project.ProjectDeactivatedEvent:
if wm.State == domain.ProjectStateRemoved {
continue
}
wm.State = domain.ProjectStateInactive
case *project.ProjectReactivatedEvent:
if wm.State == domain.ProjectStateRemoved {
continue
}
wm.State = domain.ProjectStateActive
case *project.ProjectRemovedEvent:
wm.State = domain.ProjectStateRemoved
} }
} }
return nil return wm.WriteModel.Reduce()
} }
func (wm *ProjectWriteModel) Query() *eventstore.SearchQueryBuilder { func (wm *ProjectWriteModel) Query() *eventstore.SearchQueryBuilder {
@ -47,6 +70,34 @@ func (wm *ProjectWriteModel) Query() *eventstore.SearchQueryBuilder {
ResourceOwner(wm.ResourceOwner) ResourceOwner(wm.ResourceOwner)
} }
func (wm *ProjectWriteModel) NewChangedEvent(
ctx context.Context,
name string,
projectRoleAssertion,
projectRoleCheck bool,
) (*project.ProjectChangeEvent, bool, error) {
changes := make([]project.ProjectChanges, 0)
var err error
if wm.Name != name {
changes = append(changes, project.ChangeName(name))
}
if wm.ProjectRoleAssertion != projectRoleAssertion {
changes = append(changes, project.ChangeProjectRoleAssertion(projectRoleAssertion))
}
if wm.ProjectRoleCheck != projectRoleCheck {
changes = append(changes, project.ChangeProjectRoleCheck(projectRoleCheck))
}
if len(changes) == 0 {
return nil, false, nil
}
changeEvent, err := project.NewProjectChangeEvent(ctx, changes)
if err != nil {
return nil, false, err
}
return changeEvent, true, nil
}
func ProjectAggregateFromWriteModel(wm *eventstore.WriteModel) *project.Aggregate { func ProjectAggregateFromWriteModel(wm *eventstore.WriteModel) *project.Aggregate {
return &project.Aggregate{ return &project.Aggregate{
Aggregate: *eventstore.AggregateFromWriteModel(wm, project.AggregateType, project.AggregateVersion), Aggregate: *eventstore.AggregateFromWriteModel(wm, project.AggregateType, project.AggregateVersion),

View File

@ -0,0 +1,121 @@
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) AddProjectRole(ctx context.Context, projectRole *domain.ProjectRole, resourceOwner string) (_ *domain.ProjectRole, err error) {
err = r.checkProjectExists(ctx, projectRole.AggregateID, resourceOwner)
if err != nil {
return nil, err
}
roleWriteModel := NewProjectRoleWriteModelWithKey(projectRole.Key, projectRole.AggregateID, resourceOwner)
projectAgg := ProjectAggregateFromWriteModel(&roleWriteModel.WriteModel)
r.addProjectRoles(ctx, projectAgg, projectRole.AggregateID, resourceOwner, projectRole)
err = r.eventstore.PushAggregate(ctx, roleWriteModel, projectAgg)
if err != nil {
return nil, err
}
return roleWriteModelToRole(roleWriteModel), nil
}
func (r *CommandSide) BulkAddProjectRole(ctx context.Context, projectID, resourceOwner string, projectRoles []*domain.ProjectRole) (err error) {
err = r.checkProjectExists(ctx, projectID, resourceOwner)
if err != nil {
return err
}
roleWriteModel := NewProjectRoleWriteModel(projectID, resourceOwner)
projectAgg := ProjectAggregateFromWriteModel(&roleWriteModel.WriteModel)
r.addProjectRoles(ctx, projectAgg, projectID, resourceOwner, projectRoles...)
return r.eventstore.PushAggregate(ctx, roleWriteModel, projectAgg)
}
func (r *CommandSide) addProjectRoles(ctx context.Context, projectAgg *project.Aggregate, projectID, resourceOwner string, projectRoles ...*domain.ProjectRole) error {
for _, projectRole := range projectRoles {
if !projectRole.IsValid() {
return caos_errs.ThrowPreconditionFailed(nil, "COMMAND-4m9vS", "Errors.Project.Invalid")
}
projectAgg.PushEvents(
project.NewRoleAddedEvent(
ctx,
projectRole.Key,
projectRole.DisplayName,
projectRole.Group,
projectID,
resourceOwner,
),
)
}
return nil
}
func (r *CommandSide) ChangeProjectRole(ctx context.Context, projectRole *domain.ProjectRole, resourceOwner string) (_ *domain.ProjectRole, err error) {
if !projectRole.IsValid() {
return nil, caos_errs.ThrowPreconditionFailed(nil, "COMMAND-4m9vS", "Errors.Project.Invalid")
}
err = r.checkProjectExists(ctx, projectRole.AggregateID, resourceOwner)
if err != nil {
return nil, err
}
existingRole, err := r.getProjectRoleWriteModelByID(ctx, projectRole.Key, projectRole.AggregateID, resourceOwner)
if err != nil {
return nil, err
}
if existingRole.State == domain.ProjectRoleStateUnspecified || existingRole.State == domain.ProjectRoleStateRemoved {
return nil, caos_errs.ThrowNotFound(nil, "COMMAND-vv8M9", "Errors.Project.Role.NotExisting")
}
projectAgg := ProjectAggregateFromWriteModel(&existingRole.WriteModel)
changeEvent, changed, err := existingRole.NewProjectRoleChangedEvent(ctx, projectRole.Key, projectRole.DisplayName, projectRole.Group)
if err != nil {
return nil, err
}
if !changed {
return nil, caos_errs.ThrowPreconditionFailed(nil, "COMMAND-5M0cs", "Errors.NoChangesFound")
}
projectAgg.PushEvents(changeEvent)
err = r.eventstore.PushAggregate(ctx, existingRole, projectAgg)
if err != nil {
return nil, err
}
return roleWriteModelToRole(existingRole), nil
}
func (r *CommandSide) RemoveProjectRole(ctx context.Context, projectID, key, resourceOwner string) (err error) {
if projectID == "" || key == "" {
return caos_errs.ThrowPreconditionFailed(nil, "COMMAND-4m9vS", "Errors.Project.Role.Invalid")
}
existingRole, err := r.getProjectRoleWriteModelByID(ctx, key, projectID, resourceOwner)
if err != nil {
return err
}
if existingRole.State == domain.ProjectRoleStateUnspecified || existingRole.State == domain.ProjectRoleStateRemoved {
return caos_errs.ThrowNotFound(nil, "COMMAND-m9vMf", "Errors.Project.Role.NotExisting")
}
projectAgg := ProjectAggregateFromWriteModel(&existingRole.WriteModel)
projectAgg.PushEvents(project.NewRoleRemovedEvent(ctx, key, projectID, existingRole.ResourceOwner))
//TODO: Update UserGrants (remove roles if on usergrants)
return r.eventstore.PushAggregate(ctx, existingRole, projectAgg)
}
func (r *CommandSide) getProjectRoleWriteModelByID(ctx context.Context, key, projectID, resourceOwner string) (*ProjectRoleWriteModel, error) {
projectRoleWriteModel := NewProjectRoleWriteModelWithKey(key, projectID, resourceOwner)
err := r.eventstore.FilterToQueryReducer(ctx, projectRoleWriteModel)
if err != nil {
return nil, err
}
return projectRoleWriteModel, nil
}

View File

@ -0,0 +1,121 @@
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/project"
)
type ProjectRoleWriteModel struct {
eventstore.WriteModel
Key string
DisplayName string
Group string
State domain.ProjectRoleState
}
func NewProjectRoleWriteModelWithKey(key, projectID, resourceOwner string) *ProjectRoleWriteModel {
return &ProjectRoleWriteModel{
WriteModel: eventstore.WriteModel{
AggregateID: projectID,
ResourceOwner: resourceOwner,
},
Key: key,
}
}
func NewProjectRoleWriteModel(projectID, resourceOwner string) *ProjectRoleWriteModel {
return &ProjectRoleWriteModel{
WriteModel: eventstore.WriteModel{
AggregateID: projectID,
ResourceOwner: resourceOwner,
},
}
}
func (wm *ProjectRoleWriteModel) AppendEvents(events ...eventstore.EventReader) {
for _, event := range events {
switch e := event.(type) {
case *project.RoleAddedEvent:
if e.Key == wm.Key {
wm.WriteModel.AppendEvents(e)
}
case *project.RoleChangedEvent:
if e.Key == wm.Key {
wm.WriteModel.AppendEvents(e)
}
case *project.RoleRemovedEvent:
if e.Key == wm.Key {
wm.WriteModel.AppendEvents(e)
}
case *project.ProjectRemovedEvent:
wm.WriteModel.AppendEvents(e)
}
}
}
func (wm *ProjectRoleWriteModel) Reduce() error {
for _, event := range wm.Events {
switch e := event.(type) {
case *project.RoleAddedEvent:
wm.Key = e.Key
wm.DisplayName = e.DisplayName
wm.Group = e.Group
wm.State = domain.ProjectRoleStateActive
case *project.RoleChangedEvent:
wm.Key = e.Key
if e.DisplayName != nil {
wm.DisplayName = *e.DisplayName
}
if e.Group != nil {
wm.Group = *e.Group
}
case *project.RoleRemovedEvent:
wm.State = domain.ProjectRoleStateRemoved
case *project.ProjectRemovedEvent:
wm.State = domain.ProjectRoleStateRemoved
}
}
return wm.WriteModel.Reduce()
}
func (wm *ProjectRoleWriteModel) Query() *eventstore.SearchQueryBuilder {
//types := []eventstore.EventType{
// project.RoleAddedType,
// project.RoleChangedType,
// project.RoleRemovedType,
// project.ProjectRemovedType,
//}
return eventstore.NewSearchQueryBuilder(eventstore.ColumnsEvent, project.AggregateType).
AggregateIDs(wm.AggregateID).
ResourceOwner(wm.ResourceOwner)
//EventTypes(types...)
}
func (wm *ProjectRoleWriteModel) NewProjectRoleChangedEvent(
ctx context.Context,
key,
displayName,
group string,
) (*project.RoleChangedEvent, bool, error) {
changes := make([]project.RoleChanges, 0)
var err error
changes = append(changes, project.ChangeKey(key))
if wm.DisplayName != displayName {
changes = append(changes, project.ChangeDisplayName(displayName))
}
if wm.Group != group {
changes = append(changes, project.ChangeGroup(group))
}
if len(changes) == 0 {
return nil, false, nil
}
changeEvent, err := project.NewRoleChangedEvent(ctx, changes)
if err != nil {
return nil, false, err
}
return changeEvent, true, nil
}

View File

@ -2,11 +2,11 @@ package command
import ( import (
"context" "context"
"github.com/caos/zitadel/internal/eventstore/models"
"github.com/caos/logging" "github.com/caos/logging"
caos_errs "github.com/caos/zitadel/internal/errors" 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/eventstore/v2"
"github.com/caos/zitadel/internal/v2/domain" "github.com/caos/zitadel/internal/v2/domain"
iam_repo "github.com/caos/zitadel/internal/v2/repository/iam" iam_repo "github.com/caos/zitadel/internal/v2/repository/iam"
@ -159,7 +159,7 @@ func (r *CommandSide) SetupStep1(ctx context.Context, step1 *Step1) error {
} }
//create applications //create applications
for _, app := range proj.OIDCApps { for _, app := range proj.OIDCApps {
err = setUpApplication(ctx, r, projectAgg, project, app) err = setUpApplication(ctx, r, projectAgg, project, app, orgAgg.ID())
if err != nil { if err != nil {
return err return err
} }
@ -177,27 +177,25 @@ func (r *CommandSide) SetupStep1(ctx context.Context, step1 *Step1) error {
return nil return nil
} }
func setUpApplication(ctx context.Context, r *CommandSide, projectAgg *project.Aggregate, project *domain.Project, oidcApp OIDCApp) error { func setUpApplication(ctx context.Context, r *CommandSide, projectAgg *project.Aggregate, project *domain.Project, oidcApp OIDCApp, resourceOwner string) error {
app := &domain.Application{ app := &domain.OIDCApp{
ObjectRoot: models.ObjectRoot{ ObjectRoot: models.ObjectRoot{
AggregateID: projectAgg.ID(), AggregateID: projectAgg.ID(),
}, },
Name: oidcApp.Name, AppName: oidcApp.Name,
Type: domain.AppTypeOIDC, RedirectUris: oidcApp.RedirectUris,
OIDCConfig: &domain.OIDCConfig{ ResponseTypes: getOIDCResponseTypes(oidcApp.ResponseTypes),
RedirectUris: oidcApp.RedirectUris, GrantTypes: getOIDCGrantTypes(oidcApp.GrantTypes),
ResponseTypes: getOIDCResponseTypes(oidcApp.ResponseTypes), ApplicationType: getOIDCApplicationType(oidcApp.ApplicationType),
GrantTypes: getOIDCGrantTypes(oidcApp.GrantTypes), AuthMethodType: getOIDCAuthMethod(oidcApp.AuthMethodType),
ApplicationType: getOIDCApplicationType(oidcApp.ApplicationType), DevMode: oidcApp.DevMode,
AuthMethodType: getOIDCAuthMethod(oidcApp.AuthMethodType),
DevMode: oidcApp.DevMode,
},
} }
err := r.addApplication(ctx, projectAgg, project, app)
_, err := r.addOIDCApplication(ctx, projectAgg, project, app, resourceOwner)
if err != nil { if err != nil {
return err return err
} }
logging.LogWithFields("SETUP-Edgw4", "name", app.Name, "clientID", app.OIDCConfig.ClientID).Info("application set up") logging.LogWithFields("SETUP-Edgw4", "name", app.AppName, "clientID", app.ClientID).Info("application set up")
return nil return nil
} }

View File

@ -139,12 +139,15 @@ func (r *CommandSide) RemoveUser(ctx context.Context, userID, resourceOwner stri
return r.eventstore.PushAggregate(ctx, existingUser, userAgg) return r.eventstore.PushAggregate(ctx, existingUser, userAgg)
} }
func (r *CommandSide) checkUserExists(ctx context.Context, userID, resourceOwner string) (bool, error) { func (r *CommandSide) checkUserExists(ctx context.Context, userID, resourceOwner string) error {
userWriteModel, err := r.userWriteModelByID(ctx, userID, resourceOwner) userWriteModel, err := r.userWriteModelByID(ctx, userID, resourceOwner)
if err != nil { if err != nil {
return false, err return err
} }
return userWriteModel.UserState != domain.UserStateUnspecified && userWriteModel.UserState != domain.UserStateDeleted, nil if userWriteModel.UserState == domain.UserStateUnspecified || userWriteModel.UserState == domain.UserStateDeleted {
return caos_errs.ThrowPreconditionFailed(nil, "COMMAND-4M0fs", "Errors.User.NotFound")
}
return nil
} }
func (r *CommandSide) userWriteModelByID(ctx context.Context, userID, resourceOwner string) (writeModel *UserWriteModel, err error) { func (r *CommandSide) userWriteModelByID(ctx context.Context, userID, resourceOwner string) (writeModel *UserWriteModel, err error) {

View File

@ -31,13 +31,10 @@ func (r *CommandSide) addUserGrant(ctx context.Context, userGrant *domain.UserGr
if !userGrant.IsValid() { if !userGrant.IsValid() {
return nil, nil, caos_errs.ThrowPreconditionFailed(nil, "COMMAND-4M0fs", "Errors.UserGrant.Invalid") return nil, nil, caos_errs.ThrowPreconditionFailed(nil, "COMMAND-4M0fs", "Errors.UserGrant.Invalid")
} }
exists, err := r.checkUserExists(ctx, userGrant.UserID, resourceOwner) err = r.checkUserExists(ctx, userGrant.UserID, "")
if err != nil { if err != nil {
return nil, nil, err return nil, nil, err
} }
if !exists {
return nil, nil, caos_errs.ThrowPreconditionFailed(nil, "COMMAND-4M0fs", "Errors.User.NotFound")
}
err = r.checkProjectExists(ctx, userGrant.ProjectID, resourceOwner) err = r.checkProjectExists(ctx, userGrant.ProjectID, resourceOwner)
if err != nil { if err != nil {
return nil, nil, err return nil, nil, err

View File

@ -58,7 +58,7 @@ func (wm *UserGrantWriteModel) Reduce() error {
wm.State = domain.UserGrantStateRemoved wm.State = domain.UserGrantStateRemoved
} }
} }
return nil return wm.WriteModel.Reduce()
} }
func (wm *UserGrantWriteModel) Query() *eventstore.SearchQueryBuilder { func (wm *UserGrantWriteModel) Query() *eventstore.SearchQueryBuilder {

View File

@ -68,9 +68,12 @@ func (wm *UserWriteModel) Reduce() error {
} }
func (wm *UserWriteModel) Query() *eventstore.SearchQueryBuilder { func (wm *UserWriteModel) Query() *eventstore.SearchQueryBuilder {
return eventstore.NewSearchQueryBuilder(eventstore.ColumnsEvent, user.AggregateType). query := eventstore.NewSearchQueryBuilder(eventstore.ColumnsEvent, user.AggregateType).
AggregateIDs(wm.AggregateID). AggregateIDs(wm.AggregateID)
ResourceOwner(wm.ResourceOwner) if wm.ResourceOwner != "" {
query.ResourceOwner(wm.ResourceOwner)
}
return query
} }
func UserAggregateFromWriteModel(wm *eventstore.WriteModel) *user.Aggregate { func UserAggregateFromWriteModel(wm *eventstore.WriteModel) *user.Aggregate {

View File

@ -1,17 +1,9 @@
package domain package domain
import ( type Application interface {
"github.com/caos/zitadel/internal/eventstore/models" GetAppID() string
) GetApplicationName() string
GetState() AppState
type Application struct {
models.ObjectRoot
AppID string
State AppState
Name string
Type AppType
OIDCConfig *OIDCConfig
} }
type AppState int32 type AppState int32
@ -23,27 +15,20 @@ const (
AppStateRemoved AppStateRemoved
) )
type AppType int32 type ChangeApp struct {
AppID string
const ( AppName string
AppTypeUnspecified AppType = iota State AppState
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 { func (a *ChangeApp) GetAppID() string {
if a.Name == "" || a.AggregateID == "" { return a.AppID
return false }
}
if !includeConfig { func (a *ChangeApp) GetApplicationName() string {
return true return a.AppName
} }
if a.Type == AppTypeOIDC && !a.OIDCConfig.IsValid() {
return false func (a *ChangeApp) GetState() AppState {
} return a.State
return true
} }

View File

@ -0,0 +1,327 @@
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"
)
const (
http = "http://"
httpLocalhost = "http://localhost:"
httpLocalhost2 = "http://localhost/"
https = "https://"
)
type OIDCApp struct {
models.ObjectRoot
AppID string
AppName 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
State AppState
}
func (h OIDCApp) GetUsername() string {
return h.AppName
}
func (h OIDCApp) GetState() AppState {
return h.State
}
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 *OIDCApp) 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 *OIDCApp) 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 *OIDCApp) GenerateClientSecretIfNeeded(generator crypto.Generator) (string, error) {
if c.AuthMethodType == OIDCAuthMethodTypeNone {
return "", nil
}
return c.GenerateNewClientSecret(generator)
}
func (c *OIDCApp) GenerateNewClientSecret(generator crypto.Generator) (string, error) {
cryptoValue, stringSecret, err := NewClientSecret(generator)
if err != nil {
return "", err
}
c.ClientSecret = cryptoValue
return stringSecret, nil
}
func NewClientSecret(generator crypto.Generator) (*crypto.CryptoValue, string, error) {
cryptoValue, stringSecret, err := crypto.NewCode(generator)
if err != nil {
logging.Log("MODEL-UpnTI").OnError(err).Error("unable to create client secret")
return nil, "", errors.ThrowInternal(err, "MODEL-gH2Wl", "Errors.Project.CouldNotGenerateClientSecret")
}
return cryptoValue, stringSecret, nil
}
func (c *OIDCApp) 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
}
func (c *OIDCApp) FillCompliance() {
c.Compliance = GetOIDCCompliance(c.OIDCVersion, c.ApplicationType, c.GrantTypes, c.ResponseTypes, c.AuthMethodType, c.RedirectUris)
}
func GetOIDCCompliance(version OIDCVersion, appType OIDCApplicationType, grantTypes []OIDCGrantType, responseTypes []OIDCResponseType, authMethod OIDCAuthMethodType, redirectUris []string) *Compliance {
switch version {
case OIDCVersionV1:
return GetOIDCV1Compliance(appType, grantTypes, authMethod, redirectUris)
}
return nil
}
func GetOIDCV1Compliance(appType OIDCApplicationType, grantTypes []OIDCGrantType, authMethod OIDCAuthMethodType, redirectUris []string) *Compliance {
compliance := &Compliance{NoneCompliant: false}
if redirectUris == nil || len(redirectUris) == 0 {
compliance.NoneCompliant = true
compliance.Problems = append([]string{"Application.OIDC.V1.NoRedirectUris"}, compliance.Problems...)
}
if containsOIDCGrantType(grantTypes, OIDCGrantTypeImplicit) && containsOIDCGrantType(grantTypes, OIDCGrantTypeAuthorizationCode) {
CheckRedirectUrisImplicitAndCode(compliance, appType, redirectUris)
} else {
if containsOIDCGrantType(grantTypes, OIDCGrantTypeImplicit) {
CheckRedirectUrisImplicit(compliance, appType, redirectUris)
}
if containsOIDCGrantType(grantTypes, OIDCGrantTypeAuthorizationCode) {
CheckRedirectUrisCode(compliance, appType, redirectUris)
}
}
switch appType {
case OIDCApplicationTypeNative:
GetOIDCV1NativeApplicationCompliance(compliance, authMethod)
case OIDCApplicationTypeUserAgent:
GetOIDCV1UserAgentApplicationCompliance(compliance, authMethod)
}
if compliance.NoneCompliant {
compliance.Problems = append([]string{"Application.OIDC.V1.NotCompliant"}, compliance.Problems...)
}
return compliance
}
func GetOIDCV1NativeApplicationCompliance(compliance *Compliance, authMethod OIDCAuthMethodType) {
if authMethod != OIDCAuthMethodTypeNone {
compliance.NoneCompliant = true
compliance.Problems = append(compliance.Problems, "Application.OIDC.V1.Native.AuthMethodType.NotNone")
}
}
func GetOIDCV1UserAgentApplicationCompliance(compliance *Compliance, authMethod OIDCAuthMethodType) {
if authMethod != OIDCAuthMethodTypeNone {
compliance.NoneCompliant = true
compliance.Problems = append(compliance.Problems, "Application.OIDC.V1.UserAgent.AuthMethodType.NotNone")
}
}
func CheckRedirectUrisCode(compliance *Compliance, appType OIDCApplicationType, redirectUris []string) {
if urlsAreHttps(redirectUris) {
return
}
if urlContainsPrefix(redirectUris, http) && appType != OIDCApplicationTypeWeb {
compliance.NoneCompliant = true
compliance.Problems = append(compliance.Problems, "Application.OIDC.V1.Code.RedirectUris.HttpOnlyForWeb")
}
if containsCustom(redirectUris) && appType != OIDCApplicationTypeNative {
compliance.NoneCompliant = true
compliance.Problems = append(compliance.Problems, "Application.OIDC.V1.Code.RedirectUris.CustomOnlyForNative")
}
}
func CheckRedirectUrisImplicit(compliance *Compliance, appType OIDCApplicationType, redirectUris []string) {
if urlsAreHttps(redirectUris) {
return
}
if containsCustom(redirectUris) {
compliance.NoneCompliant = true
compliance.Problems = append(compliance.Problems, "Application.OIDC.V1.Implicit.RedirectUris.CustomNotAllowed")
}
if urlContainsPrefix(redirectUris, http) {
if appType == OIDCApplicationTypeNative {
if !onlyLocalhostIsHttp(redirectUris) {
compliance.NoneCompliant = true
compliance.Problems = append(compliance.Problems, "Application.OIDC.V1.Implicit.RedirectUris.NativeShouldBeHttpLocalhost")
}
return
}
compliance.NoneCompliant = true
compliance.Problems = append(compliance.Problems, "Application.OIDC.V1.Implicit.RedirectUris.HttpNotAllowed")
}
}
func CheckRedirectUrisImplicitAndCode(compliance *Compliance, appType OIDCApplicationType, redirectUris []string) {
if urlsAreHttps(redirectUris) {
return
}
if containsCustom(redirectUris) && appType != OIDCApplicationTypeNative {
compliance.NoneCompliant = true
compliance.Problems = append(compliance.Problems, "Application.OIDC.V1.Implicit.RedirectUris.CustomNotAllowed")
}
if (urlContainsPrefix(redirectUris, httpLocalhost) || urlContainsPrefix(redirectUris, httpLocalhost2)) && appType != OIDCApplicationTypeNative {
compliance.NoneCompliant = true
compliance.Problems = append(compliance.Problems, "Application.OIDC.V1.Implicit.RedirectUris.HttpLocalhostOnlyForNative")
}
if urlContainsPrefix(redirectUris, http) && !(urlContainsPrefix(redirectUris, httpLocalhost) || urlContainsPrefix(redirectUris, httpLocalhost2)) && appType != OIDCApplicationTypeWeb {
compliance.NoneCompliant = true
compliance.Problems = append(compliance.Problems, "Application.OIDC.V1.Code.RedirectUris.HttpOnlyForWeb")
}
if !compliance.NoneCompliant {
compliance.Problems = append(compliance.Problems, "Application.OIDC.V1.NotAllCombinationsAreAllowed")
}
}
func urlsAreHttps(uris []string) bool {
for _, uri := range uris {
if !strings.HasPrefix(uri, https) {
return false
}
}
return true
}
func urlContainsPrefix(uris []string, prefix string) bool {
for _, uri := range uris {
if strings.HasPrefix(uri, prefix) {
return true
}
}
return false
}
func containsCustom(uris []string) bool {
for _, uri := range uris {
if !strings.HasPrefix(uri, http) && !strings.HasPrefix(uri, https) {
return true
}
}
return false
}
func onlyLocalhostIsHttp(uris []string) bool {
for _, uri := range uris {
if strings.HasPrefix(uri, http) {
if !strings.HasPrefix(uri, httpLocalhost) && !strings.HasPrefix(uri, httpLocalhost2) {
return false
}
}
}
return true
}

View File

@ -1,152 +0,0 @@
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,30 @@
package domain
import es_models "github.com/caos/zitadel/internal/eventstore/models"
type ProjectGrant struct {
es_models.ObjectRoot
GrantID string
GrantedOrgID string
State ProjectGrantState
RoleKeys []string
}
type ProjectGrantIDs struct {
ProjectID string
GrantID string
}
type ProjectGrantState int32
const (
ProjectGrantStateUnspecified ProjectGrantState = iota
ProjectGrantStateActive
ProjectGrantStateInactive
ProjectGrantStateRemoved
)
func (p *ProjectGrant) IsValid() bool {
return p.GrantedOrgID != ""
}

View File

@ -0,0 +1,28 @@
package domain
import (
es_models "github.com/caos/zitadel/internal/eventstore/models"
)
type ProjectGrantMember struct {
es_models.ObjectRoot
GrantID string
UserID string
Roles []string
}
func NewProjectGrantMember(aggregateID, userID, grantID string, roles ...string) *ProjectGrantMember {
return &ProjectGrantMember{
ObjectRoot: es_models.ObjectRoot{
AggregateID: aggregateID,
},
GrantID: grantID,
UserID: userID,
Roles: roles,
}
}
func (i *ProjectGrantMember) IsValid() bool {
return i.AggregateID != "" && i.GrantID != "" && i.UserID != "" && len(i.Roles) != 0
}

View File

@ -12,6 +12,14 @@ type ProjectRole struct {
Group string Group string
} }
type ProjectRoleState int32
const (
ProjectRoleStateUnspecified ProjectRoleState = iota
ProjectRoleStateActive
ProjectRoleStateRemoved
)
func NewProjectRole(projectID, key string) *ProjectRole { func NewProjectRole(projectID, key string) *ProjectRole {
return &ProjectRole{ObjectRoot: models.ObjectRoot{AggregateID: projectID}, Key: key} return &ProjectRole{ObjectRoot: models.ObjectRoot{AggregateID: projectID}, Key: key}
} }

View File

@ -24,14 +24,14 @@ type OrgnameUniqueConstraint struct {
action eventstore.UniqueConstraintAction action eventstore.UniqueConstraintAction
} }
func NewAddOrgnameUniqueConstraint(orgName string) *eventstore.EventUniqueConstraint { func NewAddOrgNameUniqueConstraint(orgName string) *eventstore.EventUniqueConstraint {
return eventstore.NewAddEventUniqueConstraint( return eventstore.NewAddEventUniqueConstraint(
uniqueOrgname, uniqueOrgname,
orgName, orgName,
"Errors.Org.AlreadyExists") "Errors.Org.AlreadyExists")
} }
func NewRemoveUsernameUniqueConstraint(orgName string) *eventstore.EventUniqueConstraint { func NewRemoveOrgNameUniqueConstraint(orgName string) *eventstore.EventUniqueConstraint {
return eventstore.NewRemoveEventUniqueConstraint( return eventstore.NewRemoveEventUniqueConstraint(
uniqueOrgname, uniqueOrgname,
orgName) orgName)
@ -48,7 +48,7 @@ func (e *OrgAddedEvent) Data() interface{} {
} }
func (e *OrgAddedEvent) UniqueConstraints() []*eventstore.EventUniqueConstraint { func (e *OrgAddedEvent) UniqueConstraints() []*eventstore.EventUniqueConstraint {
return []*eventstore.EventUniqueConstraint{NewAddOrgnameUniqueConstraint(e.Name)} return []*eventstore.EventUniqueConstraint{NewAddOrgNameUniqueConstraint(e.Name)}
} }
func NewOrgAddedEvent(ctx context.Context, name string) *OrgAddedEvent { func NewOrgAddedEvent(ctx context.Context, name string) *OrgAddedEvent {
@ -174,3 +174,38 @@ func OrgReactivatedEventMapper(event *repository.Event) (eventstore.EventReader,
return orgChanged, nil return orgChanged, nil
} }
type OrgRemovedEvent struct {
eventstore.BaseEvent `json:"-"`
name string
}
func (e *OrgRemovedEvent) Data() interface{} {
return e
}
func (e *OrgRemovedEvent) UniqueConstraints() []*eventstore.EventUniqueConstraint {
return []*eventstore.EventUniqueConstraint{NewRemoveOrgNameUniqueConstraint(e.name)}
}
func NewOrgRemovedEvent(ctx context.Context, name string) *OrgRemovedEvent {
return &OrgRemovedEvent{
BaseEvent: *eventstore.NewBaseEventForPush(
ctx,
OrgRemovedEventType,
),
name: name,
}
}
func OrgRemovedEventMapper(event *repository.Event) (eventstore.EventReader, error) {
orgChanged := &OrgRemovedEvent{
BaseEvent: *eventstore.BaseEventFromRepo(event),
}
err := json.Unmarshal(event.Data, orgChanged)
if err != nil {
return nil, errors.ThrowInternal(err, "ORG-DAfbs", "unable to unmarshal org deactivated")
}
return orgChanged, nil
}

View File

@ -3,28 +3,42 @@ package project
import ( import (
"context" "context"
"encoding/json" "encoding/json"
"fmt"
"github.com/caos/zitadel/internal/errors" "github.com/caos/zitadel/internal/errors"
"github.com/caos/zitadel/internal/eventstore/v2" "github.com/caos/zitadel/internal/eventstore/v2"
"github.com/caos/zitadel/internal/eventstore/v2/repository" "github.com/caos/zitadel/internal/eventstore/v2/repository"
"github.com/caos/zitadel/internal/v2/domain"
) )
const ( const (
uniqueAppNameType = "appname"
applicationEventTypePrefix = projectEventTypePrefix + "application." applicationEventTypePrefix = projectEventTypePrefix + "application."
ApplicationAdded = applicationEventTypePrefix + "added" ApplicationAddedType = applicationEventTypePrefix + "added"
ApplicationChanged = applicationEventTypePrefix + "changed" ApplicationChangedType = applicationEventTypePrefix + "changed"
ApplicationDeactivated = applicationEventTypePrefix + "deactivated" ApplicationDeactivatedType = applicationEventTypePrefix + "deactivated"
ApplicationReactivated = applicationEventTypePrefix + "reactivated" ApplicationReactivatedType = applicationEventTypePrefix + "reactivated"
ApplicationRemoved = applicationEventTypePrefix + "removed" ApplicationRemovedType = applicationEventTypePrefix + "removed"
) )
func NewAddApplicationUniqueConstraint(name, projectID string) *eventstore.EventUniqueConstraint {
return eventstore.NewAddEventUniqueConstraint(
uniqueAppNameType,
fmt.Sprintf("%s:%s", name, projectID),
"Errors.Project.App.AlreadyExists")
}
func NewRemoveApplicationUniqueConstraint(name, projectID string) *eventstore.EventUniqueConstraint {
return eventstore.NewRemoveEventUniqueConstraint(
uniqueAppNameType,
fmt.Sprintf("%s:%s", name, projectID))
}
type ApplicationAddedEvent struct { type ApplicationAddedEvent struct {
eventstore.BaseEvent `json:"-"` eventstore.BaseEvent `json:"-"`
AppID string `json:"appId,omitempty"` AppID string `json:"appId,omitempty"`
Name string `json:"name,omitempty"` Name string `json:"name,omitempty"`
AppType domain.AppType `json:"appType,omitempty"` projectID string
} }
func (e *ApplicationAddedEvent) Data() interface{} { func (e *ApplicationAddedEvent) Data() interface{} {
@ -32,18 +46,18 @@ func (e *ApplicationAddedEvent) Data() interface{} {
} }
func (e *ApplicationAddedEvent) UniqueConstraints() []*eventstore.EventUniqueConstraint { func (e *ApplicationAddedEvent) UniqueConstraints() []*eventstore.EventUniqueConstraint {
return nil return []*eventstore.EventUniqueConstraint{NewAddApplicationUniqueConstraint(e.Name, e.projectID)}
} }
func NewApplicationAddedEvent(ctx context.Context, appID, name string, appType domain.AppType) *ApplicationAddedEvent { func NewApplicationAddedEvent(ctx context.Context, appID, name, projectID string) *ApplicationAddedEvent {
return &ApplicationAddedEvent{ return &ApplicationAddedEvent{
BaseEvent: *eventstore.NewBaseEventForPush( BaseEvent: *eventstore.NewBaseEventForPush(
ctx, ctx,
ApplicationAdded, ApplicationAddedType,
), ),
AppID: appID, AppID: appID,
Name: name, Name: name,
AppType: appType, projectID: projectID,
} }
} }
@ -59,3 +73,164 @@ func ApplicationAddedEventMapper(event *repository.Event) (eventstore.EventReade
return e, nil return e, nil
} }
type ApplicationChangedEvent struct {
eventstore.BaseEvent `json:"-"`
AppID string `json:"appId,omitempty"`
Name string `json:"name,omitempty"`
oldName string
projectID string
}
func (e *ApplicationChangedEvent) Data() interface{} {
return e
}
func (e *ApplicationChangedEvent) UniqueConstraints() []*eventstore.EventUniqueConstraint {
return []*eventstore.EventUniqueConstraint{
NewRemoveApplicationUniqueConstraint(e.oldName, e.projectID),
NewAddApplicationUniqueConstraint(e.Name, e.projectID),
}
}
func NewApplicationChangedEvent(ctx context.Context, appID, oldName, newName, projectID string) *ApplicationChangedEvent {
return &ApplicationChangedEvent{
BaseEvent: *eventstore.NewBaseEventForPush(
ctx,
ApplicationChangedType,
),
AppID: appID,
Name: newName,
oldName: oldName,
projectID: projectID,
}
}
func ApplicationChangedEventMapper(event *repository.Event) (eventstore.EventReader, error) {
e := &ApplicationChangedEvent{
BaseEvent: *eventstore.BaseEventFromRepo(event),
}
err := json.Unmarshal(event.Data, e)
if err != nil {
return nil, errors.ThrowInternal(err, "APPLICATION-9l0cs", "unable to unmarshal application")
}
return e, nil
}
type ApplicationDeactivatedEvent struct {
eventstore.BaseEvent `json:"-"`
AppID string `json:"appId,omitempty"`
}
func (e *ApplicationDeactivatedEvent) Data() interface{} {
return e
}
func (e *ApplicationDeactivatedEvent) UniqueConstraints() []*eventstore.EventUniqueConstraint {
return nil
}
func NewApplicationDeactivatedEvent(ctx context.Context, appID string) *ApplicationDeactivatedEvent {
return &ApplicationDeactivatedEvent{
BaseEvent: *eventstore.NewBaseEventForPush(
ctx,
ApplicationDeactivatedType,
),
AppID: appID,
}
}
func ApplicationDeactivatedEventMapper(event *repository.Event) (eventstore.EventReader, error) {
e := &ApplicationDeactivatedEvent{
BaseEvent: *eventstore.BaseEventFromRepo(event),
}
err := json.Unmarshal(event.Data, e)
if err != nil {
return nil, errors.ThrowInternal(err, "APPLICATION-0p9fB", "unable to unmarshal application")
}
return e, nil
}
type ApplicationReactivatedEvent struct {
eventstore.BaseEvent `json:"-"`
AppID string `json:"appId,omitempty"`
}
func (e *ApplicationReactivatedEvent) Data() interface{} {
return e
}
func (e *ApplicationReactivatedEvent) UniqueConstraints() []*eventstore.EventUniqueConstraint {
return nil
}
func NewApplicationReactivatedEvent(ctx context.Context, appID string) *ApplicationReactivatedEvent {
return &ApplicationReactivatedEvent{
BaseEvent: *eventstore.NewBaseEventForPush(
ctx,
ApplicationReactivatedType,
),
AppID: appID,
}
}
func ApplicationReactivatedEventMapper(event *repository.Event) (eventstore.EventReader, error) {
e := &ApplicationReactivatedEvent{
BaseEvent: *eventstore.BaseEventFromRepo(event),
}
err := json.Unmarshal(event.Data, e)
if err != nil {
return nil, errors.ThrowInternal(err, "APPLICATION-1m9e3", "unable to unmarshal application")
}
return e, nil
}
type ApplicationRemovedEvent struct {
eventstore.BaseEvent `json:"-"`
AppID string `json:"appId,omitempty"`
name string
projectID string
}
func (e *ApplicationRemovedEvent) Data() interface{} {
return e
}
func (e *ApplicationRemovedEvent) UniqueConstraints() []*eventstore.EventUniqueConstraint {
return []*eventstore.EventUniqueConstraint{NewRemoveApplicationUniqueConstraint(e.name, e.projectID)}
}
func NewApplicationRemovedEvent(ctx context.Context, appID, name, projectID string) *ApplicationRemovedEvent {
return &ApplicationRemovedEvent{
BaseEvent: *eventstore.NewBaseEventForPush(
ctx,
ApplicationRemovedType,
),
AppID: appID,
name: name,
projectID: projectID,
}
}
func ApplicationRemovedEventMapper(event *repository.Event) (eventstore.EventReader, error) {
e := &ApplicationRemovedEvent{
BaseEvent: *eventstore.BaseEventFromRepo(event),
}
err := json.Unmarshal(event.Data, e)
if err != nil {
return nil, errors.ThrowInternal(err, "APPLICATION-1m9e3", "unable to unmarshal application")
}
return e, nil
}

View File

@ -5,5 +5,34 @@ import (
) )
func RegisterEventMappers(es *eventstore.Eventstore) { func RegisterEventMappers(es *eventstore.Eventstore) {
es.RegisterFilterEventMapper(ProjectAddedType, ProjectAddedEventMapper) es.RegisterFilterEventMapper(ProjectAddedType, ProjectAddedEventMapper).
RegisterFilterEventMapper(ProjectChangedType, ProjectChangeEventMapper).
RegisterFilterEventMapper(ProjectDeactivatedType, ProjectDeactivatedEventMapper).
RegisterFilterEventMapper(ProjectReactivatedType, ProjectReactivatedEventMapper).
RegisterFilterEventMapper(ProjectRemovedType, ProjectRemovedEventMapper).
RegisterFilterEventMapper(MemberAddedType, MemberAddedEventMapper).
RegisterFilterEventMapper(MemberChangedType, MemberChangedEventMapper).
RegisterFilterEventMapper(MemberRemovedType, MemberRemovedEventMapper).
RegisterFilterEventMapper(RoleAddedType, RoleAddedEventMapper).
RegisterFilterEventMapper(RoleChangedType, RoleChangedEventMapper).
RegisterFilterEventMapper(RoleRemovedType, RoleRemovedEventMapper).
RegisterFilterEventMapper(GrantAddedType, GrantAddedEventMapper).
RegisterFilterEventMapper(GrantChangedType, GrantChangedEventMapper).
RegisterFilterEventMapper(GrantCascadeChangedType, GrantChangedEventMapper).
RegisterFilterEventMapper(GrantDeactivatedType, GrantDeactivateEventMapper).
RegisterFilterEventMapper(GrantReactivatedType, GrantReactivatedEventMapper).
RegisterFilterEventMapper(GrantRemovedType, GrantRemovedEventMapper).
RegisterFilterEventMapper(GrantMemberAddedType, GrantMemberAddedEventMapper).
RegisterFilterEventMapper(GrantMemberChangedType, GrantMemberChangedEventMapper).
RegisterFilterEventMapper(GrantMemberRemovedType, GrantMemberRemovedEventMapper).
RegisterFilterEventMapper(ApplicationAddedType, ApplicationAddedEventMapper).
RegisterFilterEventMapper(ApplicationChangedType, ApplicationAddedEventMapper).
RegisterFilterEventMapper(ApplicationRemovedType, ApplicationRemovedEventMapper).
RegisterFilterEventMapper(ApplicationDeactivatedType, ApplicationDeactivatedEventMapper).
RegisterFilterEventMapper(ApplicationReactivatedType, ApplicationReactivatedEventMapper).
RegisterFilterEventMapper(OIDCConfigAddedType, OIDCConfigAddedEventMapper).
RegisterFilterEventMapper(OIDCConfigChangedType, OIDCConfigChangedEventMapper).
RegisterFilterEventMapper(OIDCConfigSecretChangedType, OIDCConfigSecretChangedEventMapper).
RegisterFilterEventMapper(OIDCClientSecretCheckSucceededType, OIDCConfigSecretCheckSucceededEventMapper).
RegisterFilterEventMapper(OIDCClientSecretCheckFailedType, OIDCConfigSecretCheckFailedEventMapper)
} }

View File

@ -0,0 +1,270 @@
package project
import (
"context"
"encoding/json"
"fmt"
"github.com/caos/zitadel/internal/errors"
"github.com/caos/zitadel/internal/eventstore/v2"
"github.com/caos/zitadel/internal/eventstore/v2/repository"
)
var (
uniqueGrantType = "project_Grant"
grantEventTypePrefix = projectEventTypePrefix + "grant."
GrantAddedType = grantEventTypePrefix + "added"
GrantChangedType = grantEventTypePrefix + "changed"
GrantCascadeChangedType = grantEventTypePrefix + "cascade.changed"
GrantDeactivatedType = grantEventTypePrefix + "deactivated"
GrantReactivatedType = grantEventTypePrefix + "reactivated"
GrantRemovedType = grantEventTypePrefix + "removed"
)
func NewAddProjectGrantUniqueConstraint(grantedOrgID, projectID string) *eventstore.EventUniqueConstraint {
return eventstore.NewAddEventUniqueConstraint(
uniqueRoleType,
fmt.Sprintf("%s:%s", grantedOrgID, projectID),
"Errors.Project.Grant.AlreadyExists")
}
func NewRemoveProjectGrantUniqueConstraint(grantedOrgID, projectID string) *eventstore.EventUniqueConstraint {
return eventstore.NewRemoveEventUniqueConstraint(
uniqueRoleType,
fmt.Sprintf("%s:%s", grantedOrgID, projectID))
}
type GrantAddedEvent struct {
eventstore.BaseEvent `json:"-"`
GrantID string `json:"grantId,omitempty"`
GrantedOrgID string `json:"grantedOrgId,omitempty"`
RoleKeys []string `json:"roleKeys,omitempty"`
projectID string
}
func (e *GrantAddedEvent) Data() interface{} {
return e
}
func (e *GrantAddedEvent) UniqueConstraints() []*eventstore.EventUniqueConstraint {
return []*eventstore.EventUniqueConstraint{NewAddProjectGrantUniqueConstraint(e.GrantedOrgID, e.projectID)}
}
func NewGrantAddedEvent(ctx context.Context, grantID, grantedOrgID, projectID string, roleKeys []string) *GrantAddedEvent {
return &GrantAddedEvent{
BaseEvent: *eventstore.NewBaseEventForPush(
ctx,
GrantAddedType,
),
GrantID: grantID,
GrantedOrgID: grantedOrgID,
RoleKeys: roleKeys,
projectID: projectID,
}
}
func GrantAddedEventMapper(event *repository.Event) (eventstore.EventReader, error) {
e := &GrantAddedEvent{
BaseEvent: *eventstore.BaseEventFromRepo(event),
}
err := json.Unmarshal(event.Data, e)
if err != nil {
return nil, errors.ThrowInternal(err, "PROJECT-mL0vs", "unable to unmarshal project grant")
}
return e, nil
}
type GrantChangedEvent struct {
eventstore.BaseEvent `json:"-"`
GrantID string `json:"grantId,omitempty"`
RoleKeys []string `json:"roleKeys,omitempty"`
}
func (e *GrantChangedEvent) Data() interface{} {
return e
}
func (e *GrantChangedEvent) UniqueConstraints() []*eventstore.EventUniqueConstraint {
return nil
}
func NewGrantChangedEvent(ctx context.Context, grantID string, roleKeys []string) *GrantChangedEvent {
return &GrantChangedEvent{
BaseEvent: *eventstore.NewBaseEventForPush(
ctx,
GrantChangedType,
),
GrantID: grantID,
RoleKeys: roleKeys,
}
}
func GrantChangedEventMapper(event *repository.Event) (eventstore.EventReader, error) {
e := &GrantChangedEvent{
BaseEvent: *eventstore.BaseEventFromRepo(event),
}
err := json.Unmarshal(event.Data, e)
if err != nil {
return nil, errors.ThrowInternal(err, "PROJECT-mL0vs", "unable to unmarshal project grant")
}
return e, nil
}
type GrantCascadeChangedEvent struct {
eventstore.BaseEvent `json:"-"`
GrantID string `json:"grantId,omitempty"`
RoleKeys []string `json:"roleKeys,omitempty"`
}
func (e *GrantCascadeChangedEvent) Data() interface{} {
return e
}
func (e *GrantCascadeChangedEvent) UniqueConstraints() []*eventstore.EventUniqueConstraint {
return nil
}
func NewGrantCascadeChangedEvent(ctx context.Context, grantID string, roleKeys []string) *GrantCascadeChangedEvent {
return &GrantCascadeChangedEvent{
BaseEvent: *eventstore.NewBaseEventForPush(
ctx,
GrantCascadeChangedType,
),
GrantID: grantID,
RoleKeys: roleKeys,
}
}
func GrantCascadeChangedEventMapper(event *repository.Event) (eventstore.EventReader, error) {
e := &GrantCascadeChangedEvent{
BaseEvent: *eventstore.BaseEventFromRepo(event),
}
err := json.Unmarshal(event.Data, e)
if err != nil {
return nil, errors.ThrowInternal(err, "PROJECT-9o0se", "unable to unmarshal project grant")
}
return e, nil
}
type GrantDeactivateEvent struct {
eventstore.BaseEvent `json:"-"`
GrantID string `json:"grantId,omitempty"`
}
func (e *GrantDeactivateEvent) Data() interface{} {
return e
}
func (e *GrantDeactivateEvent) UniqueConstraints() []*eventstore.EventUniqueConstraint {
return nil
}
func NewGrantDeactivateEvent(ctx context.Context, grantID string) *GrantDeactivateEvent {
return &GrantDeactivateEvent{
BaseEvent: *eventstore.NewBaseEventForPush(
ctx,
GrantDeactivatedType,
),
GrantID: grantID,
}
}
func GrantDeactivateEventMapper(event *repository.Event) (eventstore.EventReader, error) {
e := &GrantDeactivateEvent{
BaseEvent: *eventstore.BaseEventFromRepo(event),
}
err := json.Unmarshal(event.Data, e)
if err != nil {
return nil, errors.ThrowInternal(err, "PROJECT-9o0se", "unable to unmarshal project grant")
}
return e, nil
}
type GrantReactivatedEvent struct {
eventstore.BaseEvent `json:"-"`
GrantID string `json:"grantId,omitempty"`
}
func (e *GrantReactivatedEvent) Data() interface{} {
return e
}
func (e *GrantReactivatedEvent) UniqueConstraints() []*eventstore.EventUniqueConstraint {
return nil
}
func NewGrantReactivatedEvent(ctx context.Context, grantID string) *GrantReactivatedEvent {
return &GrantReactivatedEvent{
BaseEvent: *eventstore.NewBaseEventForPush(
ctx,
GrantReactivatedType,
),
GrantID: grantID,
}
}
func GrantReactivatedEventMapper(event *repository.Event) (eventstore.EventReader, error) {
e := &GrantReactivatedEvent{
BaseEvent: *eventstore.BaseEventFromRepo(event),
}
err := json.Unmarshal(event.Data, e)
if err != nil {
return nil, errors.ThrowInternal(err, "PROJECT-78f7D", "unable to unmarshal project grant")
}
return e, nil
}
type GrantRemovedEvent struct {
eventstore.BaseEvent `json:"-"`
GrantID string `json:"grantId,omitempty"`
grantedOrgID string
projectID string
}
func (e *GrantRemovedEvent) Data() interface{} {
return e
}
func (e *GrantRemovedEvent) UniqueConstraints() []*eventstore.EventUniqueConstraint {
return []*eventstore.EventUniqueConstraint{NewRemoveProjectGrantUniqueConstraint(e.grantedOrgID, e.projectID)}
}
func NewGrantRemovedEvent(ctx context.Context, grantID, grantedOrgID, projectID string) *GrantRemovedEvent {
return &GrantRemovedEvent{
BaseEvent: *eventstore.NewBaseEventForPush(
ctx,
GrantRemovedType,
),
GrantID: grantID,
projectID: projectID,
grantedOrgID: grantedOrgID,
}
}
func GrantRemovedEventMapper(event *repository.Event) (eventstore.EventReader, error) {
e := &GrantRemovedEvent{
BaseEvent: *eventstore.BaseEventFromRepo(event),
}
err := json.Unmarshal(event.Data, e)
if err != nil {
return nil, errors.ThrowInternal(err, "PROJECT-28jM8", "unable to unmarshal project grant")
}
return e, nil
}

View File

@ -0,0 +1,173 @@
package project
import (
"context"
"encoding/json"
"fmt"
"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/repository/member"
)
var (
uniqueProjectGrantType = "project_grant"
GrantMemberAddedType = grantEventTypePrefix + member.AddedEventType
GrantMemberChangedType = grantEventTypePrefix + member.ChangedEventType
GrantMemberRemovedType = grantEventTypePrefix + member.RemovedEventType
)
func NewAddProjectGrantMemberUniqueConstraint(projectID, userID, grantID string) *eventstore.EventUniqueConstraint {
return eventstore.NewAddEventUniqueConstraint(
uniqueProjectGrantType,
fmt.Sprintf("%s:%s:%s", projectID, userID, grantID),
"Errors.Project.Member.AlreadyExists")
}
func NewRemoveProjectGrantMemberUniqueConstraint(projectID, userID, grantID string) *eventstore.EventUniqueConstraint {
return eventstore.NewRemoveEventUniqueConstraint(
uniqueProjectGrantType,
fmt.Sprintf("%s:%s:%s", projectID, userID, grantID),
)
}
type GrantMemberAddedEvent struct {
eventstore.BaseEvent `json:"-"`
Roles []string `json:"roles"`
UserID string `json:"userId"`
GrantID string `json:"grantId"`
projectID string
}
func (e *GrantMemberAddedEvent) Data() interface{} {
return e
}
func (e *GrantMemberAddedEvent) UniqueConstraints() []*eventstore.EventUniqueConstraint {
return []*eventstore.EventUniqueConstraint{NewAddProjectGrantMemberUniqueConstraint(e.projectID, e.UserID, e.GrantID)}
}
func NewProjectGrantMemberAddedEvent(
ctx context.Context,
projectID,
userID,
grantID string,
roles ...string,
) *GrantMemberAddedEvent {
return &GrantMemberAddedEvent{
BaseEvent: *eventstore.NewBaseEventForPush(
ctx,
GrantMemberAddedType,
),
projectID: projectID,
UserID: userID,
GrantID: grantID,
Roles: roles,
}
}
func GrantMemberAddedEventMapper(event *repository.Event) (eventstore.EventReader, error) {
e := &GrantMemberAddedEvent{
BaseEvent: *eventstore.BaseEventFromRepo(event),
}
err := json.Unmarshal(event.Data, e)
if err != nil {
return nil, errors.ThrowInternal(err, "PROJECT-9f0sf", "unable to unmarshal label policy")
}
return e, nil
}
type GrantMemberChangedEvent struct {
eventstore.BaseEvent `json:"-"`
Roles []string `json:"roles"`
GrantID string `json:"grantId"`
UserID string `json:"userId"`
}
func (e *GrantMemberChangedEvent) Data() interface{} {
return e
}
func (e *GrantMemberChangedEvent) UniqueConstraints() []*eventstore.EventUniqueConstraint {
return nil
}
func NewProjectGrantMemberChangedEvent(
ctx context.Context,
userID,
grantID string,
roles ...string,
) *GrantMemberChangedEvent {
return &GrantMemberChangedEvent{
BaseEvent: *eventstore.NewBaseEventForPush(
ctx,
GrantMemberAddedType,
),
UserID: userID,
GrantID: grantID,
Roles: roles,
}
}
func GrantMemberChangedEventMapper(event *repository.Event) (eventstore.EventReader, error) {
e := &GrantMemberChangedEvent{
BaseEvent: *eventstore.BaseEventFromRepo(event),
}
err := json.Unmarshal(event.Data, e)
if err != nil {
return nil, errors.ThrowInternal(err, "PROJECT-39fi8", "unable to unmarshal label policy")
}
return e, nil
}
type GrantMemberRemovedEvent struct {
eventstore.BaseEvent `json:"-"`
UserID string `json:"userId"`
GrantID string `json:"grantId"`
projectID string
}
func (e *GrantMemberRemovedEvent) Data() interface{} {
return e
}
func (e *GrantMemberRemovedEvent) UniqueConstraints() []*eventstore.EventUniqueConstraint {
return []*eventstore.EventUniqueConstraint{NewRemoveProjectGrantMemberUniqueConstraint(e.projectID, e.UserID, e.GrantID)}
}
func NewProjectGrantMemberRemovedEvent(
ctx context.Context,
projectID,
userID,
grantID string,
) *GrantMemberRemovedEvent {
return &GrantMemberRemovedEvent{
BaseEvent: *eventstore.NewBaseEventForPush(
ctx,
GrantMemberRemovedType,
),
UserID: userID,
GrantID: grantID,
projectID: projectID,
}
}
func GrantMemberRemovedEventMapper(event *repository.Event) (eventstore.EventReader, error) {
e := &GrantMemberRemovedEvent{
BaseEvent: *eventstore.BaseEventFromRepo(event),
}
err := json.Unmarshal(event.Data, e)
if err != nil {
return nil, errors.ThrowInternal(err, "PROJECT-173fM", "unable to unmarshal label policy")
}
return e, nil
}

View File

@ -3,20 +3,21 @@ package project
import ( import (
"context" "context"
"github.com/caos/zitadel/internal/eventstore/v2" "github.com/caos/zitadel/internal/eventstore/v2"
"github.com/caos/zitadel/internal/eventstore/v2/repository"
"github.com/caos/zitadel/internal/v2/repository/member" "github.com/caos/zitadel/internal/v2/repository/member"
) )
var ( var (
MemberAddedEventType = projectEventTypePrefix + member.AddedEventType MemberAddedType = projectEventTypePrefix + member.AddedEventType
MemberChangedEventType = projectEventTypePrefix + member.ChangedEventType MemberChangedType = projectEventTypePrefix + member.ChangedEventType
MemberRemovedEventType = projectEventTypePrefix + member.RemovedEventType MemberRemovedType = projectEventTypePrefix + member.RemovedEventType
) )
type MemberAddedEvent struct { type MemberAddedEvent struct {
member.MemberAddedEvent member.MemberAddedEvent
} }
func NewMemberAddedEvent( func NewProjectMemberAddedEvent(
ctx context.Context, ctx context.Context,
userID string, userID string,
roles ...string, roles ...string,
@ -25,7 +26,7 @@ func NewMemberAddedEvent(
MemberAddedEvent: *member.NewMemberAddedEvent( MemberAddedEvent: *member.NewMemberAddedEvent(
eventstore.NewBaseEventForPush( eventstore.NewBaseEventForPush(
ctx, ctx,
MemberAddedEventType, MemberAddedType,
), ),
userID, userID,
roles..., roles...,
@ -33,11 +34,20 @@ func NewMemberAddedEvent(
} }
} }
func MemberAddedEventMapper(event *repository.Event) (eventstore.EventReader, error) {
e, err := member.MemberAddedEventMapper(event)
if err != nil {
return nil, err
}
return &MemberAddedEvent{MemberAddedEvent: *e.(*member.MemberAddedEvent)}, nil
}
type MemberChangedEvent struct { type MemberChangedEvent struct {
member.MemberChangedEvent member.MemberChangedEvent
} }
func NewMemberChangedEvent( func NewProjectMemberChangedEvent(
ctx context.Context, ctx context.Context,
userID string, userID string,
roles ...string, roles ...string,
@ -47,7 +57,7 @@ func NewMemberChangedEvent(
MemberChangedEvent: *member.NewMemberChangedEvent( MemberChangedEvent: *member.NewMemberChangedEvent(
eventstore.NewBaseEventForPush( eventstore.NewBaseEventForPush(
ctx, ctx,
MemberChangedEventType, MemberChangedType,
), ),
userID, userID,
roles..., roles...,
@ -55,11 +65,20 @@ func NewMemberChangedEvent(
} }
} }
func MemberChangedEventMapper(event *repository.Event) (eventstore.EventReader, error) {
e, err := member.ChangedEventMapper(event)
if err != nil {
return nil, err
}
return &MemberChangedEvent{MemberChangedEvent: *e.(*member.MemberChangedEvent)}, nil
}
type MemberRemovedEvent struct { type MemberRemovedEvent struct {
member.MemberRemovedEvent member.MemberRemovedEvent
} }
func NewMemberRemovedEvent( func NewProjectMemberRemovedEvent(
ctx context.Context, ctx context.Context,
userID string, userID string,
) *MemberRemovedEvent { ) *MemberRemovedEvent {
@ -68,9 +87,18 @@ func NewMemberRemovedEvent(
MemberRemovedEvent: *member.NewRemovedEvent( MemberRemovedEvent: *member.NewRemovedEvent(
eventstore.NewBaseEventForPush( eventstore.NewBaseEventForPush(
ctx, ctx,
MemberRemovedEventType, MemberRemovedType,
), ),
userID, userID,
), ),
} }
} }
func MemberRemovedEventMapper(event *repository.Event) (eventstore.EventReader, error) {
e, err := member.RemovedEventMapper(event)
if err != nil {
return nil, err
}
return &MemberRemovedEvent{MemberRemovedEvent: *e.(*member.MemberRemovedEvent)}, nil
}

View File

@ -13,11 +13,11 @@ import (
) )
const ( const (
OIDCConfigAdded = applicationEventTypePrefix + "config.oidc.added" OIDCConfigAddedType = applicationEventTypePrefix + "config.oidc.added"
OIDCConfigChanged = applicationEventTypePrefix + "config.oidc.changed" OIDCConfigChangedType = applicationEventTypePrefix + "config.oidc.changed"
OIDCConfigSecretChanged = applicationEventTypePrefix + "config.oidc.secret.changed" OIDCConfigSecretChangedType = applicationEventTypePrefix + "config.oidc.secret.changed"
OIDCClientSecretCheckSucceeded = applicationEventTypePrefix + "oidc.secret.check.succeeded" OIDCClientSecretCheckSucceededType = applicationEventTypePrefix + "oidc.secret.check.succeeded"
OIDCClientSecretCheckFailed = applicationEventTypePrefix + "oidc.secret.check.failed" OIDCClientSecretCheckFailedType = applicationEventTypePrefix + "oidc.secret.check.failed"
) )
type OIDCConfigAddedEvent struct { type OIDCConfigAddedEvent struct {
@ -71,7 +71,7 @@ func NewOIDCConfigAddedEvent(
return &OIDCConfigAddedEvent{ return &OIDCConfigAddedEvent{
BaseEvent: *eventstore.NewBaseEventForPush( BaseEvent: *eventstore.NewBaseEventForPush(
ctx, ctx,
OIDCConfigAdded, OIDCConfigAddedType,
), ),
Version: version, Version: version,
AppID: appID, AppID: appID,
@ -104,3 +104,276 @@ func OIDCConfigAddedEventMapper(event *repository.Event) (eventstore.EventReader
return e, nil return e, nil
} }
type OIDCConfigChangedEvent 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 *OIDCConfigChangedEvent) Data() interface{} {
return e
}
func (e *OIDCConfigChangedEvent) UniqueConstraints() []*eventstore.EventUniqueConstraint {
return nil
}
func NewOIDCConfigChangedEvent(
ctx context.Context,
appID string,
changes []OIDCConfigChanges,
) (*OIDCConfigChangedEvent, error) {
if len(changes) == 0 {
return nil, errors.ThrowPreconditionFailed(nil, "OIDC-i8idç", "Errors.NoChangesFound")
}
changeEvent := &OIDCConfigChangedEvent{
BaseEvent: *eventstore.NewBaseEventForPush(
ctx,
OIDCConfigChangedType,
),
AppID: appID,
}
for _, change := range changes {
change(changeEvent)
}
return changeEvent, nil
}
type OIDCConfigChanges func(event *OIDCConfigChangedEvent)
func ChangeVersion(version domain.OIDCVersion) func(event *OIDCConfigChangedEvent) {
return func(e *OIDCConfigChangedEvent) {
e.Version = &version
}
}
func ChangeClientID(clientID string) func(event *OIDCConfigChangedEvent) {
return func(e *OIDCConfigChangedEvent) {
e.ClientID = &clientID
}
}
func ChangeRedirectURIs(uris []string) func(event *OIDCConfigChangedEvent) {
return func(e *OIDCConfigChangedEvent) {
e.RedirectUris = &uris
}
}
func ChangeResponseTypes(responseTypes []domain.OIDCResponseType) func(event *OIDCConfigChangedEvent) {
return func(e *OIDCConfigChangedEvent) {
e.ResponseTypes = &responseTypes
}
}
func ChangeGrantTypes(grantTypes []domain.OIDCGrantType) func(event *OIDCConfigChangedEvent) {
return func(e *OIDCConfigChangedEvent) {
e.GrantTypes = &grantTypes
}
}
func ChangeApplicationType(appType domain.OIDCApplicationType) func(event *OIDCConfigChangedEvent) {
return func(e *OIDCConfigChangedEvent) {
e.ApplicationType = &appType
}
}
func ChangeAuthMethodType(authMethodType domain.OIDCAuthMethodType) func(event *OIDCConfigChangedEvent) {
return func(e *OIDCConfigChangedEvent) {
e.AuthMethodType = &authMethodType
}
}
func ChangePostLogoutRedirectURIs(logoutRedirects []string) func(event *OIDCConfigChangedEvent) {
return func(e *OIDCConfigChangedEvent) {
e.PostLogoutRedirectUris = &logoutRedirects
}
}
func ChangeDevMode(devMode bool) func(event *OIDCConfigChangedEvent) {
return func(e *OIDCConfigChangedEvent) {
e.DevMode = &devMode
}
}
func ChangeAccessTokenType(accessTokenType domain.OIDCTokenType) func(event *OIDCConfigChangedEvent) {
return func(e *OIDCConfigChangedEvent) {
e.AccessTokenType = &accessTokenType
}
}
func ChangeAccessTokenRoleAssertion(accessTokenRoleAssertion bool) func(event *OIDCConfigChangedEvent) {
return func(e *OIDCConfigChangedEvent) {
e.AccessTokenRoleAssertion = &accessTokenRoleAssertion
}
}
func ChangeIDTokenRoleAssertion(idTokenRoleAssertion bool) func(event *OIDCConfigChangedEvent) {
return func(e *OIDCConfigChangedEvent) {
e.IDTokenRoleAssertion = &idTokenRoleAssertion
}
}
func ChangeIDTokenUserinfoAssertion(idTokenUserinfoAssertion bool) func(event *OIDCConfigChangedEvent) {
return func(e *OIDCConfigChangedEvent) {
e.IDTokenUserinfoAssertion = &idTokenUserinfoAssertion
}
}
func ChangeClockSkew(clockSkew time.Duration) func(event *OIDCConfigChangedEvent) {
return func(e *OIDCConfigChangedEvent) {
e.ClockSkew = &clockSkew
}
}
func OIDCConfigChangedEventMapper(event *repository.Event) (eventstore.EventReader, error) {
e := &OIDCConfigChangedEvent{
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
}
type OIDCConfigSecretChangedEvent struct {
eventstore.BaseEvent `json:"-"`
AppID string `json:"appId"`
ClientSecret *crypto.CryptoValue `json:"clientSecret,omitempty"`
}
func (e *OIDCConfigSecretChangedEvent) Data() interface{} {
return e
}
func (e *OIDCConfigSecretChangedEvent) UniqueConstraints() []*eventstore.EventUniqueConstraint {
return nil
}
func NewOIDCConfigSecretChangedEvent(
ctx context.Context,
appID string,
clientSecret *crypto.CryptoValue,
) *OIDCConfigSecretChangedEvent {
return &OIDCConfigSecretChangedEvent{
BaseEvent: *eventstore.NewBaseEventForPush(
ctx,
OIDCConfigSecretChangedType,
),
AppID: appID,
ClientSecret: clientSecret,
}
}
func OIDCConfigSecretChangedEventMapper(event *repository.Event) (eventstore.EventReader, error) {
e := &OIDCConfigSecretChangedEvent{
BaseEvent: *eventstore.BaseEventFromRepo(event),
}
err := json.Unmarshal(event.Data, e)
if err != nil {
return nil, errors.ThrowInternal(err, "OIDC-M893d", "unable to unmarshal oidc config")
}
return e, nil
}
type OIDCConfigSecretCheckSucceededEvent struct {
eventstore.BaseEvent `json:"-"`
AppID string `json:"appId"`
}
func (e *OIDCConfigSecretCheckSucceededEvent) Data() interface{} {
return e
}
func (e *OIDCConfigSecretCheckSucceededEvent) UniqueConstraints() []*eventstore.EventUniqueConstraint {
return nil
}
func NewOIDCConfigSecretCheckSucceededEvent(
ctx context.Context,
appID string,
) *OIDCConfigSecretCheckSucceededEvent {
return &OIDCConfigSecretCheckSucceededEvent{
BaseEvent: *eventstore.NewBaseEventForPush(
ctx,
OIDCClientSecretCheckSucceededType,
),
AppID: appID,
}
}
func OIDCConfigSecretCheckSucceededEventMapper(event *repository.Event) (eventstore.EventReader, error) {
e := &OIDCConfigSecretCheckSucceededEvent{
BaseEvent: *eventstore.BaseEventFromRepo(event),
}
err := json.Unmarshal(event.Data, e)
if err != nil {
return nil, errors.ThrowInternal(err, "OIDC-837gV", "unable to unmarshal oidc config")
}
return e, nil
}
type OIDCConfigSecretCheckFailedEvent struct {
eventstore.BaseEvent `json:"-"`
AppID string `json:"appId"`
}
func (e *OIDCConfigSecretCheckFailedEvent) Data() interface{} {
return e
}
func (e *OIDCConfigSecretCheckFailedEvent) UniqueConstraints() []*eventstore.EventUniqueConstraint {
return nil
}
func NewOIDCConfigSecretCheckFailedEvent(
ctx context.Context,
appID string,
) *OIDCConfigSecretCheckFailedEvent {
return &OIDCConfigSecretCheckFailedEvent{
BaseEvent: *eventstore.NewBaseEventForPush(
ctx,
OIDCClientSecretCheckFailedType,
),
AppID: appID,
}
}
func OIDCConfigSecretCheckFailedEventMapper(event *repository.Event) (eventstore.EventReader, error) {
e := &OIDCConfigSecretCheckFailedEvent{
BaseEvent: *eventstore.BaseEventFromRepo(event),
}
err := json.Unmarshal(event.Data, e)
if err != nil {
return nil, errors.ThrowInternal(err, "OIDC-987g%", "unable to unmarshal oidc config")
}
return e, nil
}

View File

@ -10,25 +10,25 @@ import (
) )
const ( const (
uniqueProjectnameTable = "project_names" uniqueProjectnameType = "project_names"
projectEventTypePrefix = eventstore.EventType("project.") projectEventTypePrefix = eventstore.EventType("project.")
ProjectAddedType = projectEventTypePrefix + "added" ProjectAddedType = projectEventTypePrefix + "added"
ProjectChanged = projectEventTypePrefix + "changed" ProjectChangedType = projectEventTypePrefix + "changed"
ProjectDeactivated = projectEventTypePrefix + "deactivated" ProjectDeactivatedType = projectEventTypePrefix + "deactivated"
ProjectReactivated = projectEventTypePrefix + "reactivated" ProjectReactivatedType = projectEventTypePrefix + "reactivated"
ProjectRemoved = projectEventTypePrefix + "removed" ProjectRemovedType = projectEventTypePrefix + "removed"
) )
func NewAddProjectNameUniqueConstraint(projectName, resourceOwner string) *eventstore.EventUniqueConstraint { func NewAddProjectNameUniqueConstraint(projectName, resourceOwner string) *eventstore.EventUniqueConstraint {
return eventstore.NewAddEventUniqueConstraint( return eventstore.NewAddEventUniqueConstraint(
uniqueProjectnameTable, uniqueProjectnameType,
projectName+resourceOwner, projectName+resourceOwner,
"Errors.Project.AlreadyExists") "Errors.Project.AlreadyExists")
} }
func NewRemoveProjectNameUniqueConstraint(projectName, resourceOwner string) *eventstore.EventUniqueConstraint { func NewRemoveProjectNameUniqueConstraint(projectName, resourceOwner string) *eventstore.EventUniqueConstraint {
return eventstore.NewRemoveEventUniqueConstraint( return eventstore.NewRemoveEventUniqueConstraint(
uniqueProjectnameTable, uniqueProjectnameType,
projectName+resourceOwner) projectName+resourceOwner)
} }
@ -71,3 +71,155 @@ func ProjectAddedEventMapper(event *repository.Event) (eventstore.EventReader, e
return e, nil return e, nil
} }
type ProjectChangeEvent struct {
eventstore.BaseEvent `json:"-"`
Name *string `json:"name,omitempty"`
ProjectRoleAssertion *bool `json:"projectRoleAssertion,omitempty"`
ProjectRoleCheck *bool `json:"projectRoleCheck,omitempty"`
}
func (e *ProjectChangeEvent) Data() interface{} {
return e
}
func (e *ProjectChangeEvent) UniqueConstraints() []*eventstore.EventUniqueConstraint {
return nil
}
func NewProjectChangeEvent(
ctx context.Context,
changes []ProjectChanges) (*ProjectChangeEvent, error) {
if len(changes) == 0 {
return nil, errors.ThrowPreconditionFailed(nil, "PROJECT-mV9xc", "Errors.NoChangesFound")
}
changeEvent := &ProjectChangeEvent{
BaseEvent: *eventstore.NewBaseEventForPush(
ctx,
ProjectChangedType,
),
}
for _, change := range changes {
change(changeEvent)
}
return changeEvent, nil
}
type ProjectChanges func(event *ProjectChangeEvent)
func ChangeName(name string) func(event *ProjectChangeEvent) {
return func(e *ProjectChangeEvent) {
e.Name = &name
}
}
func ChangeProjectRoleAssertion(projectRoleAssertion bool) func(event *ProjectChangeEvent) {
return func(e *ProjectChangeEvent) {
e.ProjectRoleAssertion = &projectRoleAssertion
}
}
func ChangeProjectRoleCheck(projectRoleCheck bool) func(event *ProjectChangeEvent) {
return func(e *ProjectChangeEvent) {
e.ProjectRoleCheck = &projectRoleCheck
}
}
func ProjectChangeEventMapper(event *repository.Event) (eventstore.EventReader, error) {
e := &ProjectChangeEvent{
BaseEvent: *eventstore.BaseEventFromRepo(event),
}
err := json.Unmarshal(event.Data, e)
if err != nil {
return nil, errors.ThrowInternal(err, "PROJECT-M9osd", "unable to unmarshal project")
}
return e, nil
}
type ProjectDeactivatedEvent struct {
eventstore.BaseEvent `json:"-"`
}
func (e *ProjectDeactivatedEvent) Data() interface{} {
return nil
}
func (e *ProjectDeactivatedEvent) UniqueConstraints() []*eventstore.EventUniqueConstraint {
return nil
}
func NewProjectDeactivatedEvent(ctx context.Context) *ProjectDeactivatedEvent {
return &ProjectDeactivatedEvent{
BaseEvent: *eventstore.NewBaseEventForPush(
ctx,
ProjectDeactivatedType,
),
}
}
func ProjectDeactivatedEventMapper(event *repository.Event) (eventstore.EventReader, error) {
return &ProjectDeactivatedEvent{
BaseEvent: *eventstore.BaseEventFromRepo(event),
}, nil
}
type ProjectReactivatedEvent struct {
eventstore.BaseEvent `json:"-"`
}
func (e *ProjectReactivatedEvent) Data() interface{} {
return nil
}
func (e *ProjectReactivatedEvent) UniqueConstraints() []*eventstore.EventUniqueConstraint {
return nil
}
func NewProjectReactivatedEvent(ctx context.Context) *ProjectReactivatedEvent {
return &ProjectReactivatedEvent{
BaseEvent: *eventstore.NewBaseEventForPush(
ctx,
ProjectReactivatedType,
),
}
}
func ProjectReactivatedEventMapper(event *repository.Event) (eventstore.EventReader, error) {
return &ProjectReactivatedEvent{
BaseEvent: *eventstore.BaseEventFromRepo(event),
}, nil
}
type ProjectRemovedEvent struct {
eventstore.BaseEvent `json:"-"`
Name string
}
func (e *ProjectRemovedEvent) Data() interface{} {
return nil
}
func (e *ProjectRemovedEvent) UniqueConstraints() []*eventstore.EventUniqueConstraint {
return []*eventstore.EventUniqueConstraint{NewRemoveProjectNameUniqueConstraint(e.Name, e.ResourceOwner())}
}
func NewProjectRemovedEvent(ctx context.Context, name, resourceOwner string) *ProjectRemovedEvent {
return &ProjectRemovedEvent{
BaseEvent: *eventstore.NewBaseEventForPushWithResourceOwner(
ctx,
ProjectRemovedType,
resourceOwner,
),
Name: name,
}
}
func ProjectRemovedEventMapper(event *repository.Event) (eventstore.EventReader, error) {
return &ProjectRemovedEvent{
BaseEvent: *eventstore.BaseEventFromRepo(event),
}, nil
}

View File

@ -0,0 +1,181 @@
package project
import (
"context"
"encoding/json"
"fmt"
"github.com/caos/zitadel/internal/errors"
"github.com/caos/zitadel/internal/eventstore/v2"
"github.com/caos/zitadel/internal/eventstore/v2/repository"
)
var (
uniqueRoleType = "project_role"
roleEventTypePrefix = projectEventTypePrefix + "role."
RoleAddedType = roleEventTypePrefix + "added"
RoleChangedType = roleEventTypePrefix + "changed"
RoleRemovedType = roleEventTypePrefix + "removed"
)
func NewAddProjectRoleUniqueConstraint(roleKey, projectID, resourceOwner string) *eventstore.EventUniqueConstraint {
return eventstore.NewAddEventUniqueConstraint(
uniqueRoleType,
fmt.Sprintf("%s:%s:%s", roleKey, projectID, resourceOwner),
"Errors.Project.Role.AlreadyExists")
}
func NewRemoveProjectRoleUniqueConstraint(roleKey, projectID, resourceOwner string) *eventstore.EventUniqueConstraint {
return eventstore.NewRemoveEventUniqueConstraint(
uniqueRoleType,
fmt.Sprintf("%s:%s:%s", roleKey, projectID, resourceOwner))
}
type RoleAddedEvent struct {
eventstore.BaseEvent `json:"-"`
Key string `json:"key,omitempty"`
DisplayName string `json:"displayName,omitempty"`
Group string `json:"group,omitempty"`
projectID string
}
func (e *RoleAddedEvent) Data() interface{} {
return e
}
func (e *RoleAddedEvent) UniqueConstraints() []*eventstore.EventUniqueConstraint {
return []*eventstore.EventUniqueConstraint{NewAddProjectRoleUniqueConstraint(e.Key, e.projectID, e.ResourceOwner())}
}
func NewRoleAddedEvent(ctx context.Context, key, displayName, group, projectID, resourceOwner string) *RoleAddedEvent {
return &RoleAddedEvent{
BaseEvent: *eventstore.NewBaseEventForPushWithResourceOwner(
ctx,
RoleAddedType,
resourceOwner,
),
Key: key,
DisplayName: displayName,
Group: group,
projectID: projectID,
}
}
func RoleAddedEventMapper(event *repository.Event) (eventstore.EventReader, error) {
e := &RoleAddedEvent{
BaseEvent: *eventstore.BaseEventFromRepo(event),
}
err := json.Unmarshal(event.Data, e)
if err != nil {
return nil, errors.ThrowInternal(err, "PROJECT-2M0xy", "unable to unmarshal project role")
}
return e, nil
}
type RoleChangedEvent struct {
eventstore.BaseEvent `json:"-"`
Key string `json:"key,omitempty"`
DisplayName *string `json:"displayName,omitempty"`
Group *string `json:"group,omitempty"`
}
func (e *RoleChangedEvent) Data() interface{} {
return e
}
func (e *RoleChangedEvent) UniqueConstraints() []*eventstore.EventUniqueConstraint {
return nil
}
func NewRoleChangedEvent(
ctx context.Context,
changes []RoleChanges) (*RoleChangedEvent, error) {
if len(changes) == 0 {
return nil, errors.ThrowPreconditionFailed(nil, "PROJECT-eR9vx", "Errors.NoChangesFound")
}
changeEvent := &RoleChangedEvent{
BaseEvent: *eventstore.NewBaseEventForPush(
ctx,
RoleChangedType,
),
}
for _, change := range changes {
change(changeEvent)
}
return changeEvent, nil
}
type RoleChanges func(event *RoleChangedEvent)
func ChangeKey(key string) func(event *RoleChangedEvent) {
return func(e *RoleChangedEvent) {
e.Key = key
}
}
func ChangeDisplayName(displayName string) func(event *RoleChangedEvent) {
return func(e *RoleChangedEvent) {
e.DisplayName = &displayName
}
}
func ChangeGroup(group string) func(event *RoleChangedEvent) {
return func(e *RoleChangedEvent) {
e.Group = &group
}
}
func RoleChangedEventMapper(event *repository.Event) (eventstore.EventReader, error) {
e := &RoleChangedEvent{
BaseEvent: *eventstore.BaseEventFromRepo(event),
}
err := json.Unmarshal(event.Data, e)
if err != nil {
return nil, errors.ThrowInternal(err, "PROJECT-3M0vx", "unable to unmarshal project role")
}
return e, nil
}
type RoleRemovedEvent struct {
eventstore.BaseEvent `json:"-"`
Key string `json:"key,omitempty"`
projectID string
}
func (e *RoleRemovedEvent) Data() interface{} {
return e
}
func (e *RoleRemovedEvent) UniqueConstraints() []*eventstore.EventUniqueConstraint {
return []*eventstore.EventUniqueConstraint{NewRemoveProjectRoleUniqueConstraint(e.Key, e.projectID, e.ResourceOwner())}
}
func NewRoleRemovedEvent(ctx context.Context, key, projectID, resourceOwner string) *RoleRemovedEvent {
return &RoleRemovedEvent{
BaseEvent: *eventstore.NewBaseEventForPushWithResourceOwner(
ctx,
RoleRemovedType,
resourceOwner,
),
Key: key,
projectID: projectID,
}
}
func RoleRemovedEventMapper(event *repository.Event) (eventstore.EventReader, error) {
e := &RoleRemovedEvent{
BaseEvent: *eventstore.BaseEventFromRepo(event),
}
err := json.Unmarshal(event.Data, e)
if err != nil {
return nil, errors.ThrowInternal(err, "PROJECT-1M0xs", "unable to unmarshal project role")
}
return e, nil
}

View File

@ -167,7 +167,7 @@ type UserGrantRemovedEvent struct {
} }
func (e *UserGrantRemovedEvent) Data() interface{} { func (e *UserGrantRemovedEvent) Data() interface{} {
return e return nil
} }
func (e *UserGrantRemovedEvent) UniqueConstraints() []*eventstore.EventUniqueConstraint { func (e *UserGrantRemovedEvent) UniqueConstraints() []*eventstore.EventUniqueConstraint {
@ -187,16 +187,9 @@ func NewUserGrantRemovedEvent(ctx context.Context, resourceOwner, userID, projec
} }
func UserGrantRemovedEventMapper(event *repository.Event) (eventstore.EventReader, error) { func UserGrantRemovedEventMapper(event *repository.Event) (eventstore.EventReader, error) {
e := &UserGrantRemovedEvent{ return &UserGrantRemovedEvent{
BaseEvent: *eventstore.BaseEventFromRepo(event), BaseEvent: *eventstore.BaseEventFromRepo(event),
} }, nil
err := json.Unmarshal(event.Data, e)
if err != nil {
return nil, errors.ThrowInternal(err, "UGRANT-M0sdf", "unable to unmarshal user grant")
}
return e, nil
} }
type UserGrantCascadeRemovedEvent struct { type UserGrantCascadeRemovedEvent struct {
@ -206,18 +199,18 @@ type UserGrantCascadeRemovedEvent struct {
} }
func (e *UserGrantCascadeRemovedEvent) Data() interface{} { func (e *UserGrantCascadeRemovedEvent) Data() interface{} {
return e return nil
} }
func (e *UserGrantCascadeRemovedEvent) UniqueConstraints() []*eventstore.EventUniqueConstraint { func (e *UserGrantCascadeRemovedEvent) UniqueConstraints() []*eventstore.EventUniqueConstraint {
return []*eventstore.EventUniqueConstraint{NewRemoveUserGrantUniqueConstraint(e.ResourceOwner(), e.userID, e.projectID)} return []*eventstore.EventUniqueConstraint{NewRemoveUserGrantUniqueConstraint(e.ResourceOwner(), e.userID, e.projectID)}
} }
func NewUserGrantCascadeRemovedEvent(ctx context.Context, resourceOwner, userID, projectID string) *UserGrantRemovedEvent { func NewUserGrantCascadeRemovedEvent(ctx context.Context, resourceOwner, userID, projectID string) *UserGrantCascadeRemovedEvent {
return &UserGrantRemovedEvent{ return &UserGrantCascadeRemovedEvent{
BaseEvent: *eventstore.NewBaseEventForPushWithResourceOwner( BaseEvent: *eventstore.NewBaseEventForPushWithResourceOwner(
ctx, ctx,
UserGrantRemovedType, UserGrantCascadeRemovedType,
resourceOwner, resourceOwner,
), ),
userID: userID, userID: userID,
@ -226,16 +219,9 @@ func NewUserGrantCascadeRemovedEvent(ctx context.Context, resourceOwner, userID,
} }
func UserGrantCascadeRemovedEventMapper(event *repository.Event) (eventstore.EventReader, error) { func UserGrantCascadeRemovedEventMapper(event *repository.Event) (eventstore.EventReader, error) {
e := &UserGrantRemovedEvent{ return &UserGrantCascadeRemovedEvent{
BaseEvent: *eventstore.BaseEventFromRepo(event), BaseEvent: *eventstore.BaseEventFromRepo(event),
} }, nil
err := json.Unmarshal(event.Data, e)
if err != nil {
return nil, errors.ThrowInternal(err, "UGRANT-E7urs", "unable to unmarshal user grant")
}
return e, nil
} }
type UserGrantDeactivatedEvent struct { type UserGrantDeactivatedEvent struct {
@ -243,7 +229,7 @@ type UserGrantDeactivatedEvent struct {
} }
func (e *UserGrantDeactivatedEvent) Data() interface{} { func (e *UserGrantDeactivatedEvent) Data() interface{} {
return e return nil
} }
func (e *UserGrantDeactivatedEvent) UniqueConstraints() []*eventstore.EventUniqueConstraint { func (e *UserGrantDeactivatedEvent) UniqueConstraints() []*eventstore.EventUniqueConstraint {
@ -260,16 +246,9 @@ func NewUserGrantDeactivatedEvent(ctx context.Context) *UserGrantDeactivatedEven
} }
func UserGrantDeactivatedEventMapper(event *repository.Event) (eventstore.EventReader, error) { func UserGrantDeactivatedEventMapper(event *repository.Event) (eventstore.EventReader, error) {
e := &UserGrantDeactivatedEvent{ return &UserGrantDeactivatedEvent{
BaseEvent: *eventstore.BaseEventFromRepo(event), BaseEvent: *eventstore.BaseEventFromRepo(event),
} }, nil
err := json.Unmarshal(event.Data, e)
if err != nil {
return nil, errors.ThrowInternal(err, "UGRANT-pL0ds", "unable to unmarshal user grant")
}
return e, nil
} }
type UserGrantReactivatedEvent struct { type UserGrantReactivatedEvent struct {
@ -277,7 +256,7 @@ type UserGrantReactivatedEvent struct {
} }
func (e *UserGrantReactivatedEvent) Data() interface{} { func (e *UserGrantReactivatedEvent) Data() interface{} {
return e return nil
} }
func (e *UserGrantReactivatedEvent) UniqueConstraints() []*eventstore.EventUniqueConstraint { func (e *UserGrantReactivatedEvent) UniqueConstraints() []*eventstore.EventUniqueConstraint {
@ -294,14 +273,7 @@ func NewUserGrantReactivatedEvent(ctx context.Context) *UserGrantReactivatedEven
} }
func UserGrantReactivatedEventMapper(event *repository.Event) (eventstore.EventReader, error) { func UserGrantReactivatedEventMapper(event *repository.Event) (eventstore.EventReader, error) {
e := &UserGrantReactivatedEvent{ return &UserGrantReactivatedEvent{
BaseEvent: *eventstore.BaseEventFromRepo(event), BaseEvent: *eventstore.BaseEventFromRepo(event),
} }, nil
err := json.Unmarshal(event.Data, e)
if err != nil {
return nil, errors.ThrowInternal(err, "UGRANT-M0sdf", "unable to unmarshal user grant")
}
return e, nil
} }

View File

@ -723,7 +723,7 @@ service ManagementService {
}; };
} }
rpc DeactivateProject(ProjectID) returns (Project) { rpc DeactivateProject(ProjectID) returns (google.protobuf.Empty) {
option (google.api.http) = { option (google.api.http) = {
put: "/projects/{id}/_deactivate" put: "/projects/{id}/_deactivate"
body: "*" body: "*"
@ -735,7 +735,7 @@ service ManagementService {
}; };
} }
rpc ReactivateProject(ProjectID) returns (Project) { rpc ReactivateProject(ProjectID) returns (google.protobuf.Empty) {
option (google.api.http) = { option (google.api.http) = {
put: "/projects/{id}/_reactivate" put: "/projects/{id}/_reactivate"
body: "*" body: "*"
@ -957,7 +957,7 @@ service ManagementService {
}; };
} }
rpc DeactivateApplication(ApplicationID) returns (Application) { rpc DeactivateApplication(ApplicationID) returns (google.protobuf.Empty) {
option (google.api.http) = { option (google.api.http) = {
put: "/projects/{project_id}/applications/{id}/_deactivate" put: "/projects/{project_id}/applications/{id}/_deactivate"
body: "*" body: "*"
@ -969,7 +969,7 @@ service ManagementService {
}; };
} }
rpc ReactivateApplication(ApplicationID) returns (Application) { rpc ReactivateApplication(ApplicationID) returns (google.protobuf.Empty) {
option (google.api.http) = { option (google.api.http) = {
put: "/projects/{project_id}/applications/{id}/_reactivate" put: "/projects/{project_id}/applications/{id}/_reactivate"
body: "*" body: "*"
@ -1060,7 +1060,7 @@ service ManagementService {
}; };
} }
rpc DeactivateProjectGrant(ProjectGrantID) returns (ProjectGrant) { rpc DeactivateProjectGrant(ProjectGrantID) returns (google.protobuf.Empty) {
option (google.api.http) = { option (google.api.http) = {
put: "/projects/{project_id}/grants/{id}/_deactivate" put: "/projects/{project_id}/grants/{id}/_deactivate"
body: "*" body: "*"
@ -1071,7 +1071,7 @@ service ManagementService {
}; };
} }
rpc ReactivateProjectGrant(ProjectGrantID) returns (ProjectGrant) { rpc ReactivateProjectGrant(ProjectGrantID) returns (google.protobuf.Empty) {
option (google.api.http) = { option (google.api.http) = {
put: "/projects/{project_id}/grants/{id}/_reactivate" put: "/projects/{project_id}/grants/{id}/_reactivate"
body: "*" body: "*"
@ -2355,10 +2355,9 @@ message Project {
string name = 2; string name = 2;
ProjectState state = 3; ProjectState state = 3;
google.protobuf.Timestamp change_date = 4; google.protobuf.Timestamp change_date = 4;
google.protobuf.Timestamp creation_date = 5; uint64 sequence = 5;
uint64 sequence = 6; bool project_role_assertion = 6;
bool project_role_assertion = 7; bool project_role_check = 7;
bool project_role_check = 8;
} }
enum ProjectState { enum ProjectState {
@ -2398,14 +2397,20 @@ message ProjectMemberRemove {
message ProjectRoleAdd { message ProjectRoleAdd {
string id = 1 [(validate.rules).string = {min_len: 1}]; string id = 1 [(validate.rules).string = {min_len: 1}];
string key = 2; string key = 2 [(validate.rules).string = {min_len: 1}];
string display_name = 3; string display_name = 3;
string group = 4; string group = 4;
} }
message ProjectRoleAddBulk { message ProjectRoleAddBulk {
string id = 1 [(validate.rules).string = {min_len: 1}]; string id = 1 [(validate.rules).string = {min_len: 1}];
repeated ProjectRoleAdd project_roles = 2; repeated ProjectRoleBulkAdd project_roles = 2;
}
message ProjectRoleBulkAdd {
string key = 1 [(validate.rules).string = {min_len: 1}];
string display_name = 2;
string group = 3;
} }
message ProjectRoleChange { message ProjectRoleChange {
@ -2419,10 +2424,9 @@ message ProjectRole {
string project_id = 1; string project_id = 1;
string key = 2; string key = 2;
string display_name = 3; string display_name = 3;
google.protobuf.Timestamp creation_date = 4; google.protobuf.Timestamp change_date = 4;
google.protobuf.Timestamp change_date = 5; string group = 5;
string group = 6; uint64 sequence = 6;
uint64 sequence = 7;
} }
message ProjectRoleView { message ProjectRoleView {