mirror of
https://github.com/zitadel/zitadel.git
synced 2025-02-28 23:07:22 +00:00
feat: application commands (#50)
* feat: eventstore repository * fix: remove gorm * version * feat: pkg * feat: add some files for project * feat: eventstore without eventstore-lib * rename files * gnueg * fix: key json * fix: add object * fix: change imports * fix: internal models * fix: some imports * fix: global model * feat: add global view functions * fix: add some functions on repo * feat(eventstore): sdk * fix(eventstore): search query * fix(eventstore): rename app to eventstore * delete empty test * remove unused func * merge master * fix(eventstore): tests * fix(models): delete unused struct * fix: some funcitons * feat(eventstore): implemented push events * fix: move project eventstore to project package * fix: change project eventstore funcs * feat(eventstore): overwrite context data * fix: change project eventstore * fix: add project repo to mgmt server * feat(types): SQL-config * fix: commented code * feat(eventstore): options to overwrite editor * feat: auth interceptor and cockroach migrations * fix: migrations * fix: fix filter * fix: not found on getbyid * fix: use global sql config * fix: add sequence * fix: add some tests * fix(eventstore): nullable sequence * fix: add some tests * merge * fix: add some tests * fix(migrations): correct statements for sequence * fix: add some tests * fix: add some tests * fix: changes from mr * fix: changes from mr * fix: add some tests * Update internal/eventstore/models/field.go Co-Authored-By: livio-a <livio.a@gmail.com> * fix(eventstore): code quality * fix: add types to aggregate/Event-types * fix: try tests * fix(eventstore): rename modifier* to editor* * fix(eventstore): delete editor_org * fix(migrations): remove editor_org field, rename modifier_* to editor_* * fix: query tests * fix: use prepare funcs * fix: go mod * fix: generate files * fix(eventstore): tests * fix(eventstore): rename modifier to editor * fix(migrations): add cluster migration, fix(migrations): fix typo of host in clean clsuter * fix(eventstore): move health * fix(eventstore): AggregateTypeFilter aggregateType as param * code quality * fix: go tests * feat: add member funcs * feat: add member model * feat: add member events * feat: add member repo model * fix: better error func testing * fix: project member funcs * fix: add tests * fix: add tests * feat: implement member requests * fix: merge master * fix: merge master * fix: read existing in project repo * fix: fix tests * feat: add internal cache * feat: add cache mock * fix: return values of cache mock * feat: add project role * fix: add cache config * fix: add role to eventstore * fix: use eventstore sdk * fix: use eventstore sdk * fix: add project role grpc requests * fix: fix getby id * fix: changes for mr * fix: change value to interface * feat: add app event creations * fix: searchmethods * Update internal/project/model/project_member.go Co-Authored-By: Silvan <silvan.reusser@gmail.com> * fix: use get project func * fix: append events * fix: check if value is string on equal ignore case * fix: add changes test * fix: add go mod * fix: add some tests * fix: return err not nil * fix: return err not nil * fix: add aggregate funcs and tests * fix: add oidc aggregate funcs and tests * fix: add oidc * fix: add some tests * fix: tests * fix: oidc validation * fix: generate client secret * fix: generate client id * fix: test change app * fix: deactivate/reactivate application * fix: change oidc config * fix: change oidc config secret * fix: implement grpc app funcs * fix: add application requests * fix: converter * fix: converter * fix: converter and generate clientid * fix: tests * fix: some fixes * feat: mr changes * fix: remove state converted * fix: add default oidc config * fix: use crypto pw generator * fix: rename responsetype * create GeneratorConfig and refactor some crypto.Generator code (#70) * Update internal/project/model/project_role.go Co-Authored-By: Silvan <silvan.reusser@gmail.com> * fix: change objectroot id * fix: caos err id Co-authored-by: adlerhurst <silvan.reusser@gmail.com> Co-authored-by: livio-a <livio.a@gmail.com>
This commit is contained in:
parent
802bb56ea1
commit
04b4cd80b8
@ -31,6 +31,14 @@ Mgmt:
|
|||||||
Type: 'fastcache'
|
Type: 'fastcache'
|
||||||
Config:
|
Config:
|
||||||
MaxCacheSizeInByte: 10485760 #10mb
|
MaxCacheSizeInByte: 10485760 #10mb
|
||||||
|
PasswordSaltCost: 14
|
||||||
|
ClientSecretGenerator:
|
||||||
|
Length: 64
|
||||||
|
IncludeLowerLetters: true
|
||||||
|
IncludeUpperLetters: true
|
||||||
|
IncludeDigits: true
|
||||||
|
IncludeSymbols: true
|
||||||
|
|
||||||
|
|
||||||
Auth:
|
Auth:
|
||||||
API:
|
API:
|
||||||
|
1
go.mod
1
go.mod
@ -34,6 +34,7 @@ require (
|
|||||||
github.com/mitchellh/reflectwalk v1.0.1 // indirect
|
github.com/mitchellh/reflectwalk v1.0.1 // indirect
|
||||||
github.com/nicksnyder/go-i18n/v2 v2.0.3
|
github.com/nicksnyder/go-i18n/v2 v2.0.3
|
||||||
github.com/rs/cors v1.7.0
|
github.com/rs/cors v1.7.0
|
||||||
|
github.com/sethvargo/go-password v0.1.3
|
||||||
github.com/sirupsen/logrus v1.5.0 // indirect
|
github.com/sirupsen/logrus v1.5.0 // indirect
|
||||||
github.com/sony/sonyflake v1.0.0
|
github.com/sony/sonyflake v1.0.0
|
||||||
github.com/stretchr/testify v1.5.1
|
github.com/stretchr/testify v1.5.1
|
||||||
|
2
go.sum
2
go.sum
@ -254,6 +254,8 @@ github.com/rs/xid v1.2.1/go.mod h1:+uKXf+4Djp6Md1KODXJxgGQPKngRmWyn10oCKFzNHOQ=
|
|||||||
github.com/rs/zerolog v1.13.0/go.mod h1:YbFCdg8HfsridGWAh22vktObvhZbQsZXe4/zB0OKkWU=
|
github.com/rs/zerolog v1.13.0/go.mod h1:YbFCdg8HfsridGWAh22vktObvhZbQsZXe4/zB0OKkWU=
|
||||||
github.com/rs/zerolog v1.15.0/go.mod h1:xYTKnLHcpfU2225ny5qZjxnj9NvkumZYjJHlAThCjNc=
|
github.com/rs/zerolog v1.15.0/go.mod h1:xYTKnLHcpfU2225ny5qZjxnj9NvkumZYjJHlAThCjNc=
|
||||||
github.com/satori/go.uuid v1.2.0/go.mod h1:dA0hQrYB0VpLJoorglMZABFdXlWrHn1NEOzdhQKdks0=
|
github.com/satori/go.uuid v1.2.0/go.mod h1:dA0hQrYB0VpLJoorglMZABFdXlWrHn1NEOzdhQKdks0=
|
||||||
|
github.com/sethvargo/go-password v0.1.3 h1:18KkbGDkw8SuzeohAbWqBLNSfRQblVwEHOLbPa0PvWM=
|
||||||
|
github.com/sethvargo/go-password v0.1.3/go.mod h1:2tyaaoHK/AlXwh5WWQDYjqQbHcq4cjPj5qb/ciYvu/Q=
|
||||||
github.com/shopspring/decimal v0.0.0-20180709203117-cd690d0c9e24/go.mod h1:M+9NzErvs504Cn4c5DxATwIqPbtswREoFCre64PpcG4=
|
github.com/shopspring/decimal v0.0.0-20180709203117-cd690d0c9e24/go.mod h1:M+9NzErvs504Cn4c5DxATwIqPbtswREoFCre64PpcG4=
|
||||||
github.com/sirupsen/logrus v1.4.1/go.mod h1:ni0Sbl8bgC9z8RoU9G6nDWqqs/fq4eDPysMBDgk/93Q=
|
github.com/sirupsen/logrus v1.4.1/go.mod h1:ni0Sbl8bgC9z8RoU9G6nDWqqs/fq4eDPysMBDgk/93Q=
|
||||||
github.com/sirupsen/logrus v1.4.2 h1:SPIRibHv4MatM3XXNO2BJeFLZwZ2LvZgfQ5+UNI2im4=
|
github.com/sirupsen/logrus v1.4.2 h1:SPIRibHv4MatM3XXNO2BJeFLZwZ2LvZgfQ5+UNI2im4=
|
||||||
|
@ -4,16 +4,26 @@ import (
|
|||||||
"crypto/rand"
|
"crypto/rand"
|
||||||
"time"
|
"time"
|
||||||
|
|
||||||
|
"github.com/caos/zitadel/internal/config/types"
|
||||||
"github.com/caos/zitadel/internal/errors"
|
"github.com/caos/zitadel/internal/errors"
|
||||||
)
|
)
|
||||||
|
|
||||||
var (
|
var (
|
||||||
LowerLetters = []rune("abcdefghijklmnopqrstuvwxyz")
|
lowerLetters = []rune("abcdefghijklmnopqrstuvwxyz")
|
||||||
UpperLetters = []rune("ABCDEFGHIJKLMNOPQRSTUVWXYZ")
|
upperLetters = []rune("ABCDEFGHIJKLMNOPQRSTUVWXYZ")
|
||||||
Digits = []rune("0123456789")
|
digits = []rune("0123456789")
|
||||||
Symbols = []rune("~!@#$^&*()_+`-={}|[]:<>?,./")
|
symbols = []rune("~!@#$^&*()_+`-={}|[]:<>?,./")
|
||||||
)
|
)
|
||||||
|
|
||||||
|
type GeneratorConfig struct {
|
||||||
|
Length uint
|
||||||
|
Expiry types.Duration
|
||||||
|
IncludeLowerLetters bool
|
||||||
|
IncludeUpperLetters bool
|
||||||
|
IncludeDigits bool
|
||||||
|
IncludeSymbols bool
|
||||||
|
}
|
||||||
|
|
||||||
type Generator interface {
|
type Generator interface {
|
||||||
Length() uint
|
Length() uint
|
||||||
Expiry() time.Duration
|
Expiry() time.Duration
|
||||||
@ -21,66 +31,73 @@ type Generator interface {
|
|||||||
Runes() []rune
|
Runes() []rune
|
||||||
}
|
}
|
||||||
|
|
||||||
type EncryptionGenerator struct {
|
type generator struct {
|
||||||
length uint
|
length uint
|
||||||
expiry time.Duration
|
expiry time.Duration
|
||||||
alg EncryptionAlgorithm
|
|
||||||
runes []rune
|
runes []rune
|
||||||
}
|
}
|
||||||
|
|
||||||
func (g *EncryptionGenerator) Length() uint {
|
func (g *generator) Length() uint {
|
||||||
return g.length
|
return g.length
|
||||||
}
|
}
|
||||||
|
|
||||||
func (g *EncryptionGenerator) Expiry() time.Duration {
|
func (g *generator) Expiry() time.Duration {
|
||||||
return g.expiry
|
return g.expiry
|
||||||
}
|
}
|
||||||
|
|
||||||
func (g *EncryptionGenerator) Alg() Crypto {
|
func (g *generator) Runes() []rune {
|
||||||
return g.alg
|
|
||||||
}
|
|
||||||
|
|
||||||
func (g *EncryptionGenerator) Runes() []rune {
|
|
||||||
return g.runes
|
return g.runes
|
||||||
}
|
}
|
||||||
|
|
||||||
func NewEncryptionGenerator(length uint, expiry time.Duration, alg EncryptionAlgorithm, runes []rune) *EncryptionGenerator {
|
type encryptionGenerator struct {
|
||||||
return &EncryptionGenerator{
|
generator
|
||||||
length: length,
|
alg EncryptionAlgorithm
|
||||||
expiry: expiry,
|
}
|
||||||
alg: alg,
|
|
||||||
runes: runes,
|
func (g *encryptionGenerator) Alg() Crypto {
|
||||||
|
return g.alg
|
||||||
|
}
|
||||||
|
|
||||||
|
func NewEncryptionGenerator(config GeneratorConfig, algorithm EncryptionAlgorithm) Generator {
|
||||||
|
return &encryptionGenerator{
|
||||||
|
newGenerator(config),
|
||||||
|
algorithm,
|
||||||
}
|
}
|
||||||
}
|
}
|
||||||
|
|
||||||
type HashGenerator struct {
|
type hashGenerator struct {
|
||||||
length uint
|
generator
|
||||||
expiry time.Duration
|
|
||||||
alg HashAlgorithm
|
alg HashAlgorithm
|
||||||
runes []rune
|
|
||||||
}
|
}
|
||||||
|
|
||||||
func (g *HashGenerator) Length() uint {
|
func (g *hashGenerator) Alg() Crypto {
|
||||||
return g.length
|
|
||||||
}
|
|
||||||
|
|
||||||
func (g *HashGenerator) Expiry() time.Duration {
|
|
||||||
return g.expiry
|
|
||||||
}
|
|
||||||
|
|
||||||
func (g *HashGenerator) Alg() Crypto {
|
|
||||||
return g.alg
|
return g.alg
|
||||||
}
|
}
|
||||||
|
|
||||||
func (g *HashGenerator) Runes() []rune {
|
func NewHashGenerator(config GeneratorConfig, algorithm HashAlgorithm) Generator {
|
||||||
return g.runes
|
return &hashGenerator{
|
||||||
|
newGenerator(config),
|
||||||
|
algorithm,
|
||||||
|
}
|
||||||
}
|
}
|
||||||
|
|
||||||
func NewHashGenerator(length uint, expiry time.Duration, alg HashAlgorithm, runes []rune) *HashGenerator {
|
func newGenerator(config GeneratorConfig) generator {
|
||||||
return &HashGenerator{
|
var runes []rune
|
||||||
length: length,
|
if config.IncludeLowerLetters {
|
||||||
expiry: expiry,
|
runes = append(runes, lowerLetters...)
|
||||||
alg: alg,
|
}
|
||||||
|
if config.IncludeUpperLetters {
|
||||||
|
runes = append(runes, upperLetters...)
|
||||||
|
}
|
||||||
|
if config.IncludeDigits {
|
||||||
|
runes = append(runes, digits...)
|
||||||
|
}
|
||||||
|
if config.IncludeSymbols {
|
||||||
|
runes = append(runes, symbols...)
|
||||||
|
}
|
||||||
|
return generator{
|
||||||
|
length: config.Length,
|
||||||
|
expiry: config.Expiry.Duration,
|
||||||
runes: runes,
|
runes: runes,
|
||||||
}
|
}
|
||||||
}
|
}
|
||||||
@ -98,6 +115,9 @@ func NewCode(g Generator) (*CryptoValue, string, error) {
|
|||||||
}
|
}
|
||||||
|
|
||||||
func IsCodeExpired(creationDate time.Time, expiry time.Duration) bool {
|
func IsCodeExpired(creationDate time.Time, expiry time.Duration) bool {
|
||||||
|
if expiry == 0 {
|
||||||
|
return false
|
||||||
|
}
|
||||||
return creationDate.Add(expiry).Before(time.Now().UTC())
|
return creationDate.Add(expiry).Before(time.Now().UTC())
|
||||||
}
|
}
|
||||||
|
|
||||||
|
@ -79,6 +79,14 @@ func TestIsCodeExpired(t *testing.T) {
|
|||||||
},
|
},
|
||||||
false,
|
false,
|
||||||
},
|
},
|
||||||
|
{
|
||||||
|
"never expires",
|
||||||
|
args{
|
||||||
|
creationDate: time.Now().Add(-5 * time.Minute),
|
||||||
|
expiry: 0,
|
||||||
|
},
|
||||||
|
false,
|
||||||
|
},
|
||||||
{
|
{
|
||||||
"expired",
|
"expired",
|
||||||
args{
|
args{
|
||||||
|
@ -5,15 +5,15 @@ import (
|
|||||||
)
|
)
|
||||||
|
|
||||||
type ObjectRoot struct {
|
type ObjectRoot struct {
|
||||||
ID string `json:"-"`
|
AggregateID string `json:"-"`
|
||||||
Sequence uint64 `json:"-"`
|
Sequence uint64 `json:"-"`
|
||||||
CreationDate time.Time `json:"-"`
|
CreationDate time.Time `json:"-"`
|
||||||
ChangeDate time.Time `json:"-"`
|
ChangeDate time.Time `json:"-"`
|
||||||
}
|
}
|
||||||
|
|
||||||
func (o *ObjectRoot) AppendEvent(event *Event) {
|
func (o *ObjectRoot) AppendEvent(event *Event) {
|
||||||
if o.ID == "" {
|
if o.AggregateID == "" {
|
||||||
o.ID = event.AggregateID
|
o.AggregateID = event.AggregateID
|
||||||
}
|
}
|
||||||
|
|
||||||
o.ChangeDate = event.CreationDate
|
o.ChangeDate = event.CreationDate
|
||||||
|
@ -55,7 +55,7 @@ func TestObjectRoot_AppendEvent(t *testing.T) {
|
|||||||
for _, tt := range tests {
|
for _, tt := range tests {
|
||||||
t.Run(tt.name, func(t *testing.T) {
|
t.Run(tt.name, func(t *testing.T) {
|
||||||
o := &ObjectRoot{
|
o := &ObjectRoot{
|
||||||
ID: tt.fields.ID,
|
AggregateID: tt.fields.ID,
|
||||||
Sequence: tt.fields.Sequence,
|
Sequence: tt.fields.Sequence,
|
||||||
CreationDate: tt.fields.CreationDate,
|
CreationDate: tt.fields.CreationDate,
|
||||||
ChangeDate: tt.fields.ChangeDate,
|
ChangeDate: tt.fields.ChangeDate,
|
||||||
|
@ -50,3 +50,49 @@ func (repo *ProjectRepo) RemoveProjectMember(ctx context.Context, projectID, use
|
|||||||
member := proj_model.NewProjectMember(projectID, userID)
|
member := proj_model.NewProjectMember(projectID, userID)
|
||||||
return repo.ProjectEvents.RemoveProjectMember(ctx, member)
|
return repo.ProjectEvents.RemoveProjectMember(ctx, member)
|
||||||
}
|
}
|
||||||
|
|
||||||
|
func (repo *ProjectRepo) AddProjectRole(ctx context.Context, member *proj_model.ProjectRole) (*proj_model.ProjectRole, error) {
|
||||||
|
return repo.ProjectEvents.AddProjectRole(ctx, member)
|
||||||
|
}
|
||||||
|
|
||||||
|
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 {
|
||||||
|
member := proj_model.NewProjectRole(projectID, key)
|
||||||
|
return repo.ProjectEvents.RemoveProjectRole(ctx, member)
|
||||||
|
}
|
||||||
|
|
||||||
|
func (repo *ProjectRepo) ApplicationByID(ctx context.Context, projectID, appID string) (app *proj_model.Application, err error) {
|
||||||
|
return repo.ProjectEvents.ApplicationByIDs(ctx, projectID, appID)
|
||||||
|
}
|
||||||
|
|
||||||
|
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) 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) {
|
||||||
|
return repo.ProjectEvents.ChangeOIDCConfigSecret(ctx, projectID, appID)
|
||||||
|
}
|
||||||
|
@ -2,6 +2,8 @@ package eventsourcing
|
|||||||
|
|
||||||
import (
|
import (
|
||||||
"context"
|
"context"
|
||||||
|
|
||||||
|
"github.com/caos/zitadel/internal/crypto"
|
||||||
es_int "github.com/caos/zitadel/internal/eventstore"
|
es_int "github.com/caos/zitadel/internal/eventstore"
|
||||||
es_proj "github.com/caos/zitadel/internal/project/repository/eventsourcing"
|
es_proj "github.com/caos/zitadel/internal/project/repository/eventsourcing"
|
||||||
)
|
)
|
||||||
@ -10,6 +12,8 @@ type Config struct {
|
|||||||
Eventstore es_int.Config
|
Eventstore es_int.Config
|
||||||
//View view.ViewConfig
|
//View view.ViewConfig
|
||||||
//Spooler spooler.SpoolerConfig
|
//Spooler spooler.SpoolerConfig
|
||||||
|
PasswordSaltCost int
|
||||||
|
ClientSecretGenerator crypto.GeneratorConfig
|
||||||
}
|
}
|
||||||
|
|
||||||
type EsRepository struct {
|
type EsRepository struct {
|
||||||
@ -33,7 +37,12 @@ func Start(conf Config) (*EsRepository, error) {
|
|||||||
//conf.Spooler.SQL = sql
|
//conf.Spooler.SQL = sql
|
||||||
//spool := spooler.StartSpooler(conf.Spooler)
|
//spool := spooler.StartSpooler(conf.Spooler)
|
||||||
|
|
||||||
project, err := es_proj.StartProject(es_proj.ProjectConfig{Eventstore: es, Cache: conf.Eventstore.Cache})
|
project, err := es_proj.StartProject(es_proj.ProjectConfig{
|
||||||
|
Eventstore: es,
|
||||||
|
Cache: conf.Eventstore.Cache,
|
||||||
|
PasswordSaltCost: conf.PasswordSaltCost,
|
||||||
|
ClientSecretGenerator: conf.ClientSecretGenerator,
|
||||||
|
})
|
||||||
if err != nil {
|
if err != nil {
|
||||||
return nil, err
|
return nil, err
|
||||||
}
|
}
|
||||||
|
@ -16,4 +16,17 @@ type ProjectRepository interface {
|
|||||||
AddProjectMember(ctx context.Context, member *model.ProjectMember) (*model.ProjectMember, error)
|
AddProjectMember(ctx context.Context, member *model.ProjectMember) (*model.ProjectMember, error)
|
||||||
ChangeProjectMember(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
|
RemoveProjectMember(ctx context.Context, projectID, userID 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
|
||||||
|
|
||||||
|
ApplicationByID(ctx context.Context, projectID, appID string) (*model.Application, 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)
|
||||||
}
|
}
|
||||||
|
47
internal/project/model/application.go
Normal file
47
internal/project/model/application.go
Normal file
@ -0,0 +1,47 @@
|
|||||||
|
package model
|
||||||
|
|
||||||
|
import (
|
||||||
|
es_models "github.com/caos/zitadel/internal/eventstore/models"
|
||||||
|
)
|
||||||
|
|
||||||
|
type Application struct {
|
||||||
|
es_models.ObjectRoot
|
||||||
|
|
||||||
|
AppID string
|
||||||
|
State AppState
|
||||||
|
Name string
|
||||||
|
Type AppType
|
||||||
|
OIDCConfig *OIDCConfig
|
||||||
|
}
|
||||||
|
|
||||||
|
type AppState int32
|
||||||
|
|
||||||
|
const (
|
||||||
|
APPSTATE_ACTIVE AppState = iota
|
||||||
|
APPSTATE_INACTIVE
|
||||||
|
)
|
||||||
|
|
||||||
|
type AppType int32
|
||||||
|
|
||||||
|
const (
|
||||||
|
APPTYPE_UNDEFINED AppType = iota
|
||||||
|
APPTYPE_OIDC
|
||||||
|
APPTYPE_SAML
|
||||||
|
)
|
||||||
|
|
||||||
|
func NewApplication(projectID, appID string) *Application {
|
||||||
|
return &Application{ObjectRoot: es_models.ObjectRoot{AggregateID: projectID}, AppID: appID, State: APPSTATE_ACTIVE}
|
||||||
|
}
|
||||||
|
|
||||||
|
func (a *Application) IsValid(includeConfig bool) bool {
|
||||||
|
if a.Name == "" || a.AggregateID == "" {
|
||||||
|
return false
|
||||||
|
}
|
||||||
|
if !includeConfig {
|
||||||
|
return true
|
||||||
|
}
|
||||||
|
if a.Type == APPTYPE_OIDC && !a.OIDCConfig.IsValid() {
|
||||||
|
return false
|
||||||
|
}
|
||||||
|
return true
|
||||||
|
}
|
170
internal/project/model/application_test.go
Normal file
170
internal/project/model/application_test.go
Normal file
@ -0,0 +1,170 @@
|
|||||||
|
package model
|
||||||
|
|
||||||
|
import (
|
||||||
|
"github.com/caos/zitadel/internal/eventstore/models"
|
||||||
|
"testing"
|
||||||
|
)
|
||||||
|
|
||||||
|
func TestApplicationValid(t *testing.T) {
|
||||||
|
type args struct {
|
||||||
|
app *Application
|
||||||
|
}
|
||||||
|
tests := []struct {
|
||||||
|
name string
|
||||||
|
args args
|
||||||
|
result bool
|
||||||
|
}{
|
||||||
|
{
|
||||||
|
name: "valid oidc application: responsetype code",
|
||||||
|
args: args{
|
||||||
|
app: &Application{
|
||||||
|
ObjectRoot: models.ObjectRoot{AggregateID: "AggregateID"},
|
||||||
|
AppID: "AppID",
|
||||||
|
Name: "Name",
|
||||||
|
Type: APPTYPE_OIDC,
|
||||||
|
OIDCConfig: &OIDCConfig{
|
||||||
|
ResponseTypes: []OIDCResponseType{OIDCRESPONSETYPE_CODE},
|
||||||
|
GrantTypes: []OIDCGrantType{OIDCGRANTTYPE_AUTHORIZATION_CODE},
|
||||||
|
},
|
||||||
|
},
|
||||||
|
},
|
||||||
|
result: true,
|
||||||
|
},
|
||||||
|
{
|
||||||
|
name: "invalid oidc application: responsetype code",
|
||||||
|
args: args{
|
||||||
|
app: &Application{
|
||||||
|
ObjectRoot: models.ObjectRoot{AggregateID: "AggregateID"},
|
||||||
|
AppID: "AppID",
|
||||||
|
Name: "Name",
|
||||||
|
Type: APPTYPE_OIDC,
|
||||||
|
OIDCConfig: &OIDCConfig{
|
||||||
|
ResponseTypes: []OIDCResponseType{OIDCRESPONSETYPE_CODE},
|
||||||
|
GrantTypes: []OIDCGrantType{OIDCGRANTTYPE_IMPLICIT},
|
||||||
|
},
|
||||||
|
},
|
||||||
|
},
|
||||||
|
result: false,
|
||||||
|
},
|
||||||
|
{
|
||||||
|
name: "valid oidc application: responsetype id_token",
|
||||||
|
args: args{
|
||||||
|
app: &Application{
|
||||||
|
ObjectRoot: models.ObjectRoot{AggregateID: "AggregateID"},
|
||||||
|
AppID: "AppID",
|
||||||
|
Name: "Name",
|
||||||
|
Type: APPTYPE_OIDC,
|
||||||
|
OIDCConfig: &OIDCConfig{
|
||||||
|
ResponseTypes: []OIDCResponseType{OIDCRESPONSETYPE_ID_TOKEN},
|
||||||
|
GrantTypes: []OIDCGrantType{OIDCGRANTTYPE_IMPLICIT},
|
||||||
|
},
|
||||||
|
},
|
||||||
|
},
|
||||||
|
result: true,
|
||||||
|
},
|
||||||
|
{
|
||||||
|
name: "invalid oidc application: responsetype id_token",
|
||||||
|
args: args{
|
||||||
|
app: &Application{
|
||||||
|
ObjectRoot: models.ObjectRoot{AggregateID: "AggregateID"},
|
||||||
|
AppID: "AppID",
|
||||||
|
Name: "Name",
|
||||||
|
Type: APPTYPE_OIDC,
|
||||||
|
OIDCConfig: &OIDCConfig{
|
||||||
|
ResponseTypes: []OIDCResponseType{OIDCRESPONSETYPE_ID_TOKEN},
|
||||||
|
GrantTypes: []OIDCGrantType{OIDCGRANTTYPE_AUTHORIZATION_CODE},
|
||||||
|
},
|
||||||
|
},
|
||||||
|
},
|
||||||
|
result: false,
|
||||||
|
},
|
||||||
|
{
|
||||||
|
name: "valid oidc application: responsetype token_id_token",
|
||||||
|
args: args{
|
||||||
|
app: &Application{
|
||||||
|
ObjectRoot: models.ObjectRoot{AggregateID: "AggregateID"},
|
||||||
|
AppID: "AppID",
|
||||||
|
Name: "Name",
|
||||||
|
Type: APPTYPE_OIDC,
|
||||||
|
OIDCConfig: &OIDCConfig{
|
||||||
|
ResponseTypes: []OIDCResponseType{OIDCRESPONSETYPE_TOKEN},
|
||||||
|
GrantTypes: []OIDCGrantType{OIDCGRANTTYPE_IMPLICIT},
|
||||||
|
},
|
||||||
|
},
|
||||||
|
},
|
||||||
|
result: true,
|
||||||
|
},
|
||||||
|
{
|
||||||
|
name: "invalid oidc application: responsetype token_id_token",
|
||||||
|
args: args{
|
||||||
|
app: &Application{
|
||||||
|
ObjectRoot: models.ObjectRoot{AggregateID: "AggregateID"},
|
||||||
|
AppID: "AppID",
|
||||||
|
Name: "Name",
|
||||||
|
Type: APPTYPE_OIDC,
|
||||||
|
OIDCConfig: &OIDCConfig{
|
||||||
|
ResponseTypes: []OIDCResponseType{OIDCRESPONSETYPE_TOKEN},
|
||||||
|
GrantTypes: []OIDCGrantType{OIDCGRANTTYPE_AUTHORIZATION_CODE},
|
||||||
|
},
|
||||||
|
},
|
||||||
|
},
|
||||||
|
result: false,
|
||||||
|
},
|
||||||
|
{
|
||||||
|
name: "valid oidc application: responsetype code & id_token",
|
||||||
|
args: args{
|
||||||
|
app: &Application{
|
||||||
|
ObjectRoot: models.ObjectRoot{AggregateID: "AggregateID"},
|
||||||
|
AppID: "AppID",
|
||||||
|
Name: "Name",
|
||||||
|
Type: APPTYPE_OIDC,
|
||||||
|
OIDCConfig: &OIDCConfig{
|
||||||
|
ResponseTypes: []OIDCResponseType{OIDCRESPONSETYPE_CODE, OIDCRESPONSETYPE_ID_TOKEN},
|
||||||
|
GrantTypes: []OIDCGrantType{OIDCGRANTTYPE_AUTHORIZATION_CODE, OIDCGRANTTYPE_IMPLICIT},
|
||||||
|
},
|
||||||
|
},
|
||||||
|
},
|
||||||
|
result: true,
|
||||||
|
},
|
||||||
|
{
|
||||||
|
name: "valid oidc application: responsetype code & token_id_token",
|
||||||
|
args: args{
|
||||||
|
app: &Application{
|
||||||
|
ObjectRoot: models.ObjectRoot{AggregateID: "AggregateID"},
|
||||||
|
AppID: "AppID",
|
||||||
|
Name: "Name",
|
||||||
|
Type: APPTYPE_OIDC,
|
||||||
|
OIDCConfig: &OIDCConfig{
|
||||||
|
ResponseTypes: []OIDCResponseType{OIDCRESPONSETYPE_CODE, OIDCRESPONSETYPE_TOKEN},
|
||||||
|
GrantTypes: []OIDCGrantType{OIDCGRANTTYPE_AUTHORIZATION_CODE, OIDCGRANTTYPE_IMPLICIT},
|
||||||
|
},
|
||||||
|
},
|
||||||
|
},
|
||||||
|
result: true,
|
||||||
|
},
|
||||||
|
{
|
||||||
|
name: "valid oidc application: responsetype code & id_token & token_id_token",
|
||||||
|
args: args{
|
||||||
|
app: &Application{
|
||||||
|
ObjectRoot: models.ObjectRoot{AggregateID: "AggregateID"},
|
||||||
|
AppID: "AppID",
|
||||||
|
Name: "Name",
|
||||||
|
Type: APPTYPE_OIDC,
|
||||||
|
OIDCConfig: &OIDCConfig{
|
||||||
|
ResponseTypes: []OIDCResponseType{OIDCRESPONSETYPE_CODE, OIDCRESPONSETYPE_ID_TOKEN, OIDCRESPONSETYPE_TOKEN},
|
||||||
|
GrantTypes: []OIDCGrantType{OIDCGRANTTYPE_AUTHORIZATION_CODE, OIDCGRANTTYPE_IMPLICIT},
|
||||||
|
},
|
||||||
|
},
|
||||||
|
},
|
||||||
|
result: true,
|
||||||
|
},
|
||||||
|
}
|
||||||
|
for _, tt := range tests {
|
||||||
|
t.Run(tt.name, func(t *testing.T) {
|
||||||
|
result := tt.args.app.IsValid(true)
|
||||||
|
if result != tt.result {
|
||||||
|
t.Errorf("got wrong result: expected: %v, actual: %v ", tt.result, result)
|
||||||
|
}
|
||||||
|
})
|
||||||
|
}
|
||||||
|
}
|
88
internal/project/model/oidc_config.go
Normal file
88
internal/project/model/oidc_config.go
Normal file
@ -0,0 +1,88 @@
|
|||||||
|
package model
|
||||||
|
|
||||||
|
import (
|
||||||
|
"github.com/caos/zitadel/internal/crypto"
|
||||||
|
es_models "github.com/caos/zitadel/internal/eventstore/models"
|
||||||
|
)
|
||||||
|
|
||||||
|
type OIDCConfig struct {
|
||||||
|
es_models.ObjectRoot
|
||||||
|
AppID string
|
||||||
|
ClientID string
|
||||||
|
ClientSecret *crypto.CryptoValue
|
||||||
|
ClientSecretString string
|
||||||
|
RedirectUris []string
|
||||||
|
ResponseTypes []OIDCResponseType
|
||||||
|
GrantTypes []OIDCGrantType
|
||||||
|
ApplicationType OIDCApplicationType
|
||||||
|
AuthMethodType OIDCAuthMethodType
|
||||||
|
PostLogoutRedirectUris []string
|
||||||
|
}
|
||||||
|
|
||||||
|
type OIDCResponseType int32
|
||||||
|
|
||||||
|
const (
|
||||||
|
OIDCRESPONSETYPE_CODE OIDCResponseType = iota
|
||||||
|
OIDCRESPONSETYPE_ID_TOKEN
|
||||||
|
OIDCRESPONSETYPE_TOKEN
|
||||||
|
)
|
||||||
|
|
||||||
|
type OIDCGrantType int32
|
||||||
|
|
||||||
|
const (
|
||||||
|
OIDCGRANTTYPE_AUTHORIZATION_CODE OIDCGrantType = iota
|
||||||
|
OIDCGRANTTYPE_IMPLICIT
|
||||||
|
OIDCGRANTTYPE_REFRESH_TOKEN
|
||||||
|
)
|
||||||
|
|
||||||
|
type OIDCApplicationType int32
|
||||||
|
|
||||||
|
const (
|
||||||
|
OIDCAPPLICATIONTYPE_WEB OIDCApplicationType = iota
|
||||||
|
OIDCAPPLICATIONTYPE_USER_AGENT
|
||||||
|
OIDCAPPLICATIONTYPE_NATIVE
|
||||||
|
)
|
||||||
|
|
||||||
|
type OIDCAuthMethodType int32
|
||||||
|
|
||||||
|
const (
|
||||||
|
OIDCAUTHMETHODTYPE_BASIC OIDCAuthMethodType = iota
|
||||||
|
OIDCAUTHMETHODTYPE_POST
|
||||||
|
OIDCAUTHMETHODTYPE_NONE
|
||||||
|
)
|
||||||
|
|
||||||
|
func (c *OIDCConfig) IsValid() bool {
|
||||||
|
grantTypes := c.getRequiredGrantTypes()
|
||||||
|
for _, grantType := range grantTypes {
|
||||||
|
ok := c.containsGrantType(grantType)
|
||||||
|
if !ok {
|
||||||
|
return false
|
||||||
|
}
|
||||||
|
}
|
||||||
|
return true
|
||||||
|
}
|
||||||
|
|
||||||
|
func (c *OIDCConfig) getRequiredGrantTypes() []OIDCGrantType {
|
||||||
|
grantTypes := make([]OIDCGrantType, 0)
|
||||||
|
implicit := false
|
||||||
|
for _, r := range c.ResponseTypes {
|
||||||
|
switch r {
|
||||||
|
case OIDCRESPONSETYPE_CODE:
|
||||||
|
grantTypes = append(grantTypes, OIDCGRANTTYPE_AUTHORIZATION_CODE)
|
||||||
|
case OIDCRESPONSETYPE_ID_TOKEN, OIDCRESPONSETYPE_TOKEN:
|
||||||
|
if !implicit {
|
||||||
|
grantTypes = append(grantTypes, OIDCGRANTTYPE_IMPLICIT)
|
||||||
|
}
|
||||||
|
}
|
||||||
|
}
|
||||||
|
return grantTypes
|
||||||
|
}
|
||||||
|
|
||||||
|
func (c *OIDCConfig) containsGrantType(grantType OIDCGrantType) bool {
|
||||||
|
for _, t := range c.GrantTypes {
|
||||||
|
if t == grantType {
|
||||||
|
return true
|
||||||
|
}
|
||||||
|
}
|
||||||
|
return false
|
||||||
|
}
|
@ -2,7 +2,6 @@ package model
|
|||||||
|
|
||||||
import (
|
import (
|
||||||
es_models "github.com/caos/zitadel/internal/eventstore/models"
|
es_models "github.com/caos/zitadel/internal/eventstore/models"
|
||||||
in_model "github.com/caos/zitadel/internal/model"
|
|
||||||
)
|
)
|
||||||
|
|
||||||
type Project struct {
|
type Project struct {
|
||||||
@ -11,28 +10,27 @@ type Project struct {
|
|||||||
State ProjectState
|
State ProjectState
|
||||||
Name string
|
Name string
|
||||||
Members []*ProjectMember
|
Members []*ProjectMember
|
||||||
|
Roles []*ProjectRole
|
||||||
|
Applications []*Application
|
||||||
}
|
}
|
||||||
|
|
||||||
type ProjectState in_model.Enum
|
type ProjectState int32
|
||||||
|
|
||||||
var states = []string{"Active", "Inactive"}
|
const (
|
||||||
|
PROJECTSTATE_ACTIVE ProjectState = iota
|
||||||
|
PROJECTSTATE_INACTIVE
|
||||||
|
)
|
||||||
|
|
||||||
func NewProject(id string) *Project {
|
func NewProject(id string) *Project {
|
||||||
return &Project{ObjectRoot: es_models.ObjectRoot{ID: id}, State: Active}
|
return &Project{ObjectRoot: es_models.ObjectRoot{AggregateID: id}, State: PROJECTSTATE_ACTIVE}
|
||||||
}
|
}
|
||||||
|
|
||||||
func (p *Project) IsActive() bool {
|
func (p *Project) IsActive() bool {
|
||||||
if p.State == Active {
|
return p.State == PROJECTSTATE_ACTIVE
|
||||||
return true
|
|
||||||
}
|
|
||||||
return false
|
|
||||||
}
|
}
|
||||||
|
|
||||||
func (p *Project) IsValid() bool {
|
func (p *Project) IsValid() bool {
|
||||||
if p.Name == "" {
|
return p.Name != ""
|
||||||
return false
|
|
||||||
}
|
|
||||||
return true
|
|
||||||
}
|
}
|
||||||
|
|
||||||
func (p *Project) ContainsMember(member *ProjectMember) bool {
|
func (p *Project) ContainsMember(member *ProjectMember) bool {
|
||||||
@ -43,3 +41,21 @@ func (p *Project) ContainsMember(member *ProjectMember) bool {
|
|||||||
}
|
}
|
||||||
return false
|
return false
|
||||||
}
|
}
|
||||||
|
|
||||||
|
func (p *Project) ContainsRole(role *ProjectRole) bool {
|
||||||
|
for _, r := range p.Roles {
|
||||||
|
if r.Key == role.Key {
|
||||||
|
return true
|
||||||
|
}
|
||||||
|
}
|
||||||
|
return false
|
||||||
|
}
|
||||||
|
|
||||||
|
func (p *Project) ContainsApp(app *Application) (*Application, bool) {
|
||||||
|
for _, a := range p.Applications {
|
||||||
|
if a.AppID == app.AppID {
|
||||||
|
return a, true
|
||||||
|
}
|
||||||
|
}
|
||||||
|
return nil, false
|
||||||
|
}
|
||||||
|
@ -10,9 +10,9 @@ type ProjectMember struct {
|
|||||||
}
|
}
|
||||||
|
|
||||||
func NewProjectMember(projectID, userID string) *ProjectMember {
|
func NewProjectMember(projectID, userID string) *ProjectMember {
|
||||||
return &ProjectMember{ObjectRoot: es_models.ObjectRoot{ID: projectID}, UserID: userID}
|
return &ProjectMember{ObjectRoot: es_models.ObjectRoot{AggregateID: projectID}, UserID: userID}
|
||||||
}
|
}
|
||||||
|
|
||||||
func (p *ProjectMember) IsValid() bool {
|
func (p *ProjectMember) IsValid() bool {
|
||||||
return p.ID != "" && p.UserID != "" && len(p.Roles) != 0
|
return p.AggregateID != "" && p.UserID != "" && len(p.Roles) != 0
|
||||||
}
|
}
|
||||||
|
19
internal/project/model/project_role.go
Normal file
19
internal/project/model/project_role.go
Normal file
@ -0,0 +1,19 @@
|
|||||||
|
package model
|
||||||
|
|
||||||
|
import es_models "github.com/caos/zitadel/internal/eventstore/models"
|
||||||
|
|
||||||
|
type ProjectRole struct {
|
||||||
|
es_models.ObjectRoot
|
||||||
|
|
||||||
|
Key string
|
||||||
|
DisplayName string
|
||||||
|
Group string
|
||||||
|
}
|
||||||
|
|
||||||
|
func NewProjectRole(projectID, key string) *ProjectRole {
|
||||||
|
return &ProjectRole{ObjectRoot: es_models.ObjectRoot{AggregateID: projectID}, Key: key}
|
||||||
|
}
|
||||||
|
|
||||||
|
func (p *ProjectRole) IsValid() bool {
|
||||||
|
return p.AggregateID != "" && p.Key != ""
|
||||||
|
}
|
@ -1,23 +0,0 @@
|
|||||||
package model
|
|
||||||
|
|
||||||
type state int32
|
|
||||||
|
|
||||||
func (s state) String() string {
|
|
||||||
return states[s]
|
|
||||||
}
|
|
||||||
|
|
||||||
const (
|
|
||||||
Active state = iota
|
|
||||||
Inactive
|
|
||||||
)
|
|
||||||
|
|
||||||
func ProjectStateToInt(s ProjectState) int32 {
|
|
||||||
if s == nil {
|
|
||||||
return 0
|
|
||||||
}
|
|
||||||
return int32(s.(state))
|
|
||||||
}
|
|
||||||
|
|
||||||
func ProjectStateFromInt(index int32) ProjectState {
|
|
||||||
return state(index)
|
|
||||||
}
|
|
@ -15,6 +15,7 @@ const (
|
|||||||
ProjectMemberRemoved models.EventType = "project.member.removed"
|
ProjectMemberRemoved models.EventType = "project.member.removed"
|
||||||
|
|
||||||
ProjectRoleAdded models.EventType = "project.role.added"
|
ProjectRoleAdded models.EventType = "project.role.added"
|
||||||
|
ProjectRoleChanged models.EventType = "project.role.changed"
|
||||||
ProjectRoleRemoved models.EventType = "project.role.removed"
|
ProjectRoleRemoved models.EventType = "project.role.removed"
|
||||||
|
|
||||||
ProjectGrantAdded models.EventType = "project.grant.added"
|
ProjectGrantAdded models.EventType = "project.grant.added"
|
||||||
@ -28,6 +29,7 @@ const (
|
|||||||
|
|
||||||
ApplicationAdded models.EventType = "project.application.added"
|
ApplicationAdded models.EventType = "project.application.added"
|
||||||
ApplicationChanged models.EventType = "project.application.changed"
|
ApplicationChanged models.EventType = "project.application.changed"
|
||||||
|
ApplicationRemoved models.EventType = "project.application.removed"
|
||||||
ApplicationDeactivated models.EventType = "project.application.deactivated"
|
ApplicationDeactivated models.EventType = "project.application.deactivated"
|
||||||
ApplicationReactivated models.EventType = "project.application.reactivated"
|
ApplicationReactivated models.EventType = "project.application.reactivated"
|
||||||
|
|
||||||
|
@ -19,7 +19,7 @@ func StartCache(conf *config.CacheConfig) (*ProjectCache, error) {
|
|||||||
}
|
}
|
||||||
|
|
||||||
func (c *ProjectCache) getProject(ID string) (project *Project) {
|
func (c *ProjectCache) getProject(ID string) (project *Project) {
|
||||||
project = &Project{ObjectRoot: models.ObjectRoot{ID: ID}}
|
project = &Project{ObjectRoot: models.ObjectRoot{AggregateID: ID}}
|
||||||
if err := c.projectCache.Get(ID, project); err != nil {
|
if err := c.projectCache.Get(ID, project); err != nil {
|
||||||
logging.Log("EVENT-4eTZh").WithError(err).Debug("error in getting cache")
|
logging.Log("EVENT-4eTZh").WithError(err).Debug("error in getting cache")
|
||||||
}
|
}
|
||||||
@ -27,7 +27,7 @@ func (c *ProjectCache) getProject(ID string) (project *Project) {
|
|||||||
}
|
}
|
||||||
|
|
||||||
func (c *ProjectCache) cacheProject(project *Project) {
|
func (c *ProjectCache) cacheProject(project *Project) {
|
||||||
err := c.projectCache.Set(project.ID, project)
|
err := c.projectCache.Set(project.AggregateID, project)
|
||||||
if err != nil {
|
if err != nil {
|
||||||
logging.Log("EVENT-ThnBb").WithError(err).Debug("error in setting project cache")
|
logging.Log("EVENT-ThnBb").WithError(err).Debug("error in setting project cache")
|
||||||
}
|
}
|
||||||
|
@ -2,7 +2,12 @@ package eventsourcing
|
|||||||
|
|
||||||
import (
|
import (
|
||||||
"context"
|
"context"
|
||||||
|
"strconv"
|
||||||
|
|
||||||
|
"github.com/sony/sonyflake"
|
||||||
|
|
||||||
"github.com/caos/zitadel/internal/cache/config"
|
"github.com/caos/zitadel/internal/cache/config"
|
||||||
|
"github.com/caos/zitadel/internal/crypto"
|
||||||
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"
|
||||||
es_sdk "github.com/caos/zitadel/internal/eventstore/sdk"
|
es_sdk "github.com/caos/zitadel/internal/eventstore/sdk"
|
||||||
@ -12,11 +17,15 @@ import (
|
|||||||
type ProjectEventstore struct {
|
type ProjectEventstore struct {
|
||||||
es_int.Eventstore
|
es_int.Eventstore
|
||||||
projectCache *ProjectCache
|
projectCache *ProjectCache
|
||||||
|
pwGenerator crypto.Generator
|
||||||
|
idGenerator *sonyflake.Sonyflake
|
||||||
}
|
}
|
||||||
|
|
||||||
type ProjectConfig struct {
|
type ProjectConfig struct {
|
||||||
es_int.Eventstore
|
es_int.Eventstore
|
||||||
Cache *config.CacheConfig
|
Cache *config.CacheConfig
|
||||||
|
PasswordSaltCost int
|
||||||
|
ClientSecretGenerator crypto.GeneratorConfig
|
||||||
}
|
}
|
||||||
|
|
||||||
func StartProject(conf ProjectConfig) (*ProjectEventstore, error) {
|
func StartProject(conf ProjectConfig) (*ProjectEventstore, error) {
|
||||||
@ -24,21 +33,26 @@ func StartProject(conf ProjectConfig) (*ProjectEventstore, error) {
|
|||||||
if err != nil {
|
if err != nil {
|
||||||
return nil, err
|
return nil, err
|
||||||
}
|
}
|
||||||
|
passwordAlg := crypto.NewBCrypt(conf.PasswordSaltCost)
|
||||||
|
pwGenerator := crypto.NewHashGenerator(conf.ClientSecretGenerator, passwordAlg)
|
||||||
|
idGenerator := sonyflake.NewSonyflake(sonyflake.Settings{})
|
||||||
return &ProjectEventstore{
|
return &ProjectEventstore{
|
||||||
Eventstore: conf.Eventstore,
|
Eventstore: conf.Eventstore,
|
||||||
projectCache: projectCache,
|
projectCache: projectCache,
|
||||||
|
pwGenerator: pwGenerator,
|
||||||
|
idGenerator: idGenerator,
|
||||||
}, nil
|
}, nil
|
||||||
}
|
}
|
||||||
|
|
||||||
func (es *ProjectEventstore) ProjectByID(ctx context.Context, id string) (*proj_model.Project, error) {
|
func (es *ProjectEventstore) ProjectByID(ctx context.Context, id string) (*proj_model.Project, error) {
|
||||||
project := es.projectCache.getProject(id)
|
project := es.projectCache.getProject(id)
|
||||||
|
|
||||||
query, err := ProjectByIDQuery(project.ID, project.Sequence)
|
query, err := ProjectByIDQuery(project.AggregateID, project.Sequence)
|
||||||
if err != nil {
|
if err != nil {
|
||||||
return nil, err
|
return nil, err
|
||||||
}
|
}
|
||||||
err = es_sdk.Filter(ctx, es.FilterEvents, project.AppendEvents, query)
|
err = es_sdk.Filter(ctx, es.FilterEvents, project.AppendEvents, query)
|
||||||
if err != nil {
|
if err != nil && !(caos_errs.IsNotFound(err) && project.Sequence != 0) {
|
||||||
return nil, err
|
return nil, err
|
||||||
}
|
}
|
||||||
es.projectCache.cacheProject(project)
|
es.projectCache.cacheProject(project)
|
||||||
@ -49,11 +63,16 @@ func (es *ProjectEventstore) CreateProject(ctx context.Context, project *proj_mo
|
|||||||
if !project.IsValid() {
|
if !project.IsValid() {
|
||||||
return nil, caos_errs.ThrowPreconditionFailed(nil, "EVENT-9dk45", "Name is required")
|
return nil, caos_errs.ThrowPreconditionFailed(nil, "EVENT-9dk45", "Name is required")
|
||||||
}
|
}
|
||||||
project.State = proj_model.Active
|
id, err := es.idGenerator.NextID()
|
||||||
|
if err != nil {
|
||||||
|
return nil, err
|
||||||
|
}
|
||||||
|
project.AggregateID = strconv.FormatUint(id, 10)
|
||||||
|
project.State = proj_model.PROJECTSTATE_ACTIVE
|
||||||
repoProject := ProjectFromModel(project)
|
repoProject := ProjectFromModel(project)
|
||||||
|
|
||||||
createAggregate := ProjectCreateAggregate(es.AggregateCreator(), repoProject)
|
createAggregate := ProjectCreateAggregate(es.AggregateCreator(), repoProject)
|
||||||
err := es_sdk.Push(ctx, es.PushAggregates, repoProject.AppendEvents, createAggregate)
|
err = es_sdk.Push(ctx, es.PushAggregates, repoProject.AppendEvents, createAggregate)
|
||||||
if err != nil {
|
if err != nil {
|
||||||
return nil, err
|
return nil, err
|
||||||
}
|
}
|
||||||
@ -66,7 +85,7 @@ func (es *ProjectEventstore) UpdateProject(ctx context.Context, project *proj_mo
|
|||||||
if !project.IsValid() {
|
if !project.IsValid() {
|
||||||
return nil, caos_errs.ThrowPreconditionFailed(nil, "EVENT-9dk45", "Name is required")
|
return nil, caos_errs.ThrowPreconditionFailed(nil, "EVENT-9dk45", "Name is required")
|
||||||
}
|
}
|
||||||
existingProject, err := es.ProjectByID(ctx, project.ID)
|
existingProject, err := es.ProjectByID(ctx, project.AggregateID)
|
||||||
if err != nil {
|
if err != nil {
|
||||||
return nil, err
|
return nil, err
|
||||||
}
|
}
|
||||||
@ -121,7 +140,7 @@ func (es *ProjectEventstore) ProjectMemberByIDs(ctx context.Context, member *pro
|
|||||||
if member.UserID == "" {
|
if member.UserID == "" {
|
||||||
return nil, caos_errs.ThrowPreconditionFailed(nil, "EVENT-ld93d", "userID missing")
|
return nil, caos_errs.ThrowPreconditionFailed(nil, "EVENT-ld93d", "userID missing")
|
||||||
}
|
}
|
||||||
project, err := es.ProjectByID(ctx, member.ID)
|
project, err := es.ProjectByID(ctx, member.AggregateID)
|
||||||
if err != nil {
|
if err != nil {
|
||||||
return nil, err
|
return nil, err
|
||||||
}
|
}
|
||||||
@ -137,7 +156,7 @@ func (es *ProjectEventstore) AddProjectMember(ctx context.Context, member *proj_
|
|||||||
if !member.IsValid() {
|
if !member.IsValid() {
|
||||||
return nil, caos_errs.ThrowPreconditionFailed(nil, "EVENT-9dk45", "UserID and Roles are required")
|
return nil, caos_errs.ThrowPreconditionFailed(nil, "EVENT-9dk45", "UserID and Roles are required")
|
||||||
}
|
}
|
||||||
existing, err := es.ProjectByID(ctx, member.ID)
|
existing, err := es.ProjectByID(ctx, member.AggregateID)
|
||||||
if err != nil {
|
if err != nil {
|
||||||
return nil, err
|
return nil, err
|
||||||
}
|
}
|
||||||
@ -165,7 +184,7 @@ func (es *ProjectEventstore) ChangeProjectMember(ctx context.Context, member *pr
|
|||||||
if !member.IsValid() {
|
if !member.IsValid() {
|
||||||
return nil, caos_errs.ThrowPreconditionFailed(nil, "EVENT-9dk45", "UserID and Roles are required")
|
return nil, caos_errs.ThrowPreconditionFailed(nil, "EVENT-9dk45", "UserID and Roles are required")
|
||||||
}
|
}
|
||||||
existing, err := es.ProjectByID(ctx, member.ID)
|
existing, err := es.ProjectByID(ctx, member.AggregateID)
|
||||||
if err != nil {
|
if err != nil {
|
||||||
return nil, err
|
return nil, err
|
||||||
}
|
}
|
||||||
@ -190,7 +209,7 @@ func (es *ProjectEventstore) RemoveProjectMember(ctx context.Context, member *pr
|
|||||||
if member.UserID == "" {
|
if member.UserID == "" {
|
||||||
return caos_errs.ThrowPreconditionFailed(nil, "EVENT-d43fs", "UserID and Roles are required")
|
return caos_errs.ThrowPreconditionFailed(nil, "EVENT-d43fs", "UserID and Roles are required")
|
||||||
}
|
}
|
||||||
existing, err := es.ProjectByID(ctx, member.ID)
|
existing, err := es.ProjectByID(ctx, member.AggregateID)
|
||||||
if err != nil {
|
if err != nil {
|
||||||
return err
|
return err
|
||||||
}
|
}
|
||||||
@ -205,3 +224,307 @@ func (es *ProjectEventstore) RemoveProjectMember(ctx context.Context, member *pr
|
|||||||
es.projectCache.cacheProject(repoProject)
|
es.projectCache.cacheProject(repoProject)
|
||||||
return err
|
return err
|
||||||
}
|
}
|
||||||
|
|
||||||
|
func (es *ProjectEventstore) AddProjectRole(ctx context.Context, role *proj_model.ProjectRole) (*proj_model.ProjectRole, error) {
|
||||||
|
if !role.IsValid() {
|
||||||
|
return nil, caos_errs.ThrowPreconditionFailed(nil, "EVENT-idue3", "Key is required")
|
||||||
|
}
|
||||||
|
existing, err := es.ProjectByID(ctx, role.AggregateID)
|
||||||
|
if err != nil {
|
||||||
|
return nil, err
|
||||||
|
}
|
||||||
|
if existing.ContainsRole(role) {
|
||||||
|
return nil, caos_errs.ThrowAlreadyExists(nil, "EVENT-sk35t", "Project contains role with same key")
|
||||||
|
}
|
||||||
|
repoProject := ProjectFromModel(existing)
|
||||||
|
repoRole := ProjectRoleFromModel(role)
|
||||||
|
projectAggregate := ProjectRoleAddedAggregate(es.Eventstore.AggregateCreator(), repoProject, repoRole)
|
||||||
|
err = es_sdk.Push(ctx, es.PushAggregates, repoProject.AppendEvents, projectAggregate)
|
||||||
|
if err != nil {
|
||||||
|
return nil, err
|
||||||
|
}
|
||||||
|
|
||||||
|
es.projectCache.cacheProject(repoProject)
|
||||||
|
for _, r := range repoProject.Roles {
|
||||||
|
if r.Key == role.Key {
|
||||||
|
return ProjectRoleToModel(r), nil
|
||||||
|
}
|
||||||
|
}
|
||||||
|
return nil, caos_errs.ThrowInternal(nil, "EVENT-sie83", "Could not find role in list")
|
||||||
|
}
|
||||||
|
|
||||||
|
func (es *ProjectEventstore) ChangeProjectRole(ctx context.Context, role *proj_model.ProjectRole) (*proj_model.ProjectRole, error) {
|
||||||
|
if !role.IsValid() {
|
||||||
|
return nil, caos_errs.ThrowPreconditionFailed(nil, "EVENT-9die3", "Key is required")
|
||||||
|
}
|
||||||
|
existing, err := es.ProjectByID(ctx, role.AggregateID)
|
||||||
|
if err != nil {
|
||||||
|
return nil, err
|
||||||
|
}
|
||||||
|
if !existing.ContainsRole(role) {
|
||||||
|
return nil, caos_errs.ThrowPreconditionFailed(nil, "EVENT-die34", "Role doesn't exist on this project")
|
||||||
|
}
|
||||||
|
repoProject := ProjectFromModel(existing)
|
||||||
|
repoRole := ProjectRoleFromModel(role)
|
||||||
|
projectAggregate := ProjectRoleChangedAggregate(es.Eventstore.AggregateCreator(), repoProject, repoRole)
|
||||||
|
err = es_sdk.Push(ctx, es.PushAggregates, repoProject.AppendEvents, projectAggregate)
|
||||||
|
if err != nil {
|
||||||
|
return nil, err
|
||||||
|
}
|
||||||
|
|
||||||
|
es.projectCache.cacheProject(repoProject)
|
||||||
|
for _, r := range repoProject.Roles {
|
||||||
|
if r.Key == role.Key {
|
||||||
|
return ProjectRoleToModel(r), nil
|
||||||
|
}
|
||||||
|
}
|
||||||
|
return nil, caos_errs.ThrowInternal(nil, "EVENT-sl1or", "Could not find role in list")
|
||||||
|
}
|
||||||
|
|
||||||
|
func (es *ProjectEventstore) RemoveProjectRole(ctx context.Context, role *proj_model.ProjectRole) error {
|
||||||
|
if role.Key == "" {
|
||||||
|
return caos_errs.ThrowPreconditionFailed(nil, "EVENT-id823", "Key is required")
|
||||||
|
}
|
||||||
|
existing, err := es.ProjectByID(ctx, role.AggregateID)
|
||||||
|
if err != nil {
|
||||||
|
return err
|
||||||
|
}
|
||||||
|
if !existing.ContainsRole(role) {
|
||||||
|
return caos_errs.ThrowPreconditionFailed(nil, "EVENT-oe823", "Role doesn't exist on project")
|
||||||
|
}
|
||||||
|
repoProject := ProjectFromModel(existing)
|
||||||
|
repoRole := ProjectRoleFromModel(role)
|
||||||
|
projectAggregate := ProjectRoleRemovedAggregate(es.Eventstore.AggregateCreator(), repoProject, repoRole)
|
||||||
|
err = es_sdk.Push(ctx, es.PushAggregates, repoProject.AppendEvents, projectAggregate)
|
||||||
|
if err != nil {
|
||||||
|
return err
|
||||||
|
}
|
||||||
|
es.projectCache.cacheProject(repoProject)
|
||||||
|
return nil
|
||||||
|
}
|
||||||
|
|
||||||
|
func (es *ProjectEventstore) ApplicationByIDs(ctx context.Context, projectID, appID string) (*proj_model.Application, error) {
|
||||||
|
if projectID == "" || appID == "" {
|
||||||
|
return nil, caos_errs.ThrowPreconditionFailed(nil, "EVENT-ld93d", "project oder app AggregateID missing")
|
||||||
|
}
|
||||||
|
project, err := es.ProjectByID(ctx, projectID)
|
||||||
|
if err != nil {
|
||||||
|
return nil, err
|
||||||
|
}
|
||||||
|
for _, a := range project.Applications {
|
||||||
|
if a.AppID == appID {
|
||||||
|
return a, nil
|
||||||
|
}
|
||||||
|
}
|
||||||
|
return nil, caos_errs.ThrowNotFound(nil, "EVENT-8ei2s", "Could not find app")
|
||||||
|
}
|
||||||
|
|
||||||
|
func (es *ProjectEventstore) AddApplication(ctx context.Context, app *proj_model.Application) (*proj_model.Application, error) {
|
||||||
|
if app == nil || !app.IsValid(true) {
|
||||||
|
return nil, caos_errs.ThrowPreconditionFailed(nil, "EVENT-9eidw", "Some required fields are missing")
|
||||||
|
}
|
||||||
|
existing, err := es.ProjectByID(ctx, app.AggregateID)
|
||||||
|
if err != nil {
|
||||||
|
return nil, err
|
||||||
|
}
|
||||||
|
id, err := es.idGenerator.NextID()
|
||||||
|
if err != nil {
|
||||||
|
return nil, err
|
||||||
|
}
|
||||||
|
app.AppID = strconv.FormatUint(id, 10)
|
||||||
|
|
||||||
|
var stringPw string
|
||||||
|
var cryptoPw *crypto.CryptoValue
|
||||||
|
if app.OIDCConfig != nil {
|
||||||
|
app.OIDCConfig.AppID = strconv.FormatUint(id, 10)
|
||||||
|
stringPw, cryptoPw, err = generateNewClientSecret(es.pwGenerator)
|
||||||
|
if err != nil {
|
||||||
|
return nil, err
|
||||||
|
}
|
||||||
|
app.OIDCConfig.ClientSecret = cryptoPw
|
||||||
|
clientID, err := generateNewClientID(es.idGenerator, existing)
|
||||||
|
if err != nil {
|
||||||
|
return nil, err
|
||||||
|
}
|
||||||
|
app.OIDCConfig.ClientID = clientID
|
||||||
|
}
|
||||||
|
repoProject := ProjectFromModel(existing)
|
||||||
|
repoApp := AppFromModel(app)
|
||||||
|
|
||||||
|
addAggregate := ApplicationAddedAggregate(es.Eventstore.AggregateCreator(), repoProject, repoApp)
|
||||||
|
err = es_sdk.Push(ctx, es.PushAggregates, repoProject.AppendEvents, addAggregate)
|
||||||
|
es.projectCache.cacheProject(repoProject)
|
||||||
|
for _, a := range repoProject.Applications {
|
||||||
|
if a.AppID == app.AppID {
|
||||||
|
converted := AppToModel(a)
|
||||||
|
converted.OIDCConfig.ClientSecretString = stringPw
|
||||||
|
return converted, nil
|
||||||
|
}
|
||||||
|
}
|
||||||
|
return nil, caos_errs.ThrowInternal(nil, "EVENT-3udjs", "Could not find member in list")
|
||||||
|
}
|
||||||
|
|
||||||
|
func (es *ProjectEventstore) ChangeApplication(ctx context.Context, app *proj_model.Application) (*proj_model.Application, error) {
|
||||||
|
if app == nil || !app.IsValid(false) {
|
||||||
|
return nil, caos_errs.ThrowPreconditionFailed(nil, "EVENT-dieuw", "some required fields missing")
|
||||||
|
}
|
||||||
|
existing, err := es.ProjectByID(ctx, app.AggregateID)
|
||||||
|
if err != nil {
|
||||||
|
return nil, err
|
||||||
|
}
|
||||||
|
if _, ok := existing.ContainsApp(app); !ok {
|
||||||
|
return nil, caos_errs.ThrowPreconditionFailed(nil, "EVENT-die83", "App is not in this project")
|
||||||
|
}
|
||||||
|
repoProject := ProjectFromModel(existing)
|
||||||
|
repoApp := AppFromModel(app)
|
||||||
|
|
||||||
|
projectAggregate := ApplicationChangedAggregate(es.Eventstore.AggregateCreator(), repoProject, repoApp)
|
||||||
|
err = es_sdk.Push(ctx, es.PushAggregates, repoProject.AppendEvents, projectAggregate)
|
||||||
|
es.projectCache.cacheProject(repoProject)
|
||||||
|
for _, a := range repoProject.Applications {
|
||||||
|
if a.AppID == app.AppID {
|
||||||
|
return AppToModel(a), nil
|
||||||
|
}
|
||||||
|
}
|
||||||
|
return nil, caos_errs.ThrowInternal(nil, "EVENT-dksi8", "Could not find app in list")
|
||||||
|
}
|
||||||
|
|
||||||
|
func (es *ProjectEventstore) RemoveApplication(ctx context.Context, app *proj_model.Application) error {
|
||||||
|
if app.AppID == "" {
|
||||||
|
return caos_errs.ThrowPreconditionFailed(nil, "EVENT-id832", "AppID is required")
|
||||||
|
}
|
||||||
|
existing, err := es.ProjectByID(ctx, app.AggregateID)
|
||||||
|
if err != nil {
|
||||||
|
return err
|
||||||
|
}
|
||||||
|
if _, ok := existing.ContainsApp(app); !ok {
|
||||||
|
return caos_errs.ThrowPreconditionFailed(nil, "EVENT-di83s", "Application doesn't exist on project")
|
||||||
|
}
|
||||||
|
repoProject := ProjectFromModel(existing)
|
||||||
|
appRepo := AppFromModel(app)
|
||||||
|
projectAggregate := ApplicationRemovedAggregate(es.Eventstore.AggregateCreator(), repoProject, appRepo)
|
||||||
|
err = es_sdk.Push(ctx, es.PushAggregates, repoProject.AppendEvents, projectAggregate)
|
||||||
|
if err != nil {
|
||||||
|
return err
|
||||||
|
}
|
||||||
|
es.projectCache.cacheProject(repoProject)
|
||||||
|
return nil
|
||||||
|
}
|
||||||
|
|
||||||
|
func (es *ProjectEventstore) DeactivateApplication(ctx context.Context, projectID, appID string) (*proj_model.Application, error) {
|
||||||
|
if appID == "" {
|
||||||
|
return nil, caos_errs.ThrowPreconditionFailed(nil, "EVENT-dlp9e", "appID missing")
|
||||||
|
}
|
||||||
|
existing, err := es.ProjectByID(ctx, projectID)
|
||||||
|
if err != nil {
|
||||||
|
return nil, err
|
||||||
|
}
|
||||||
|
app := &proj_model.Application{AppID: appID}
|
||||||
|
if _, ok := existing.ContainsApp(app); !ok {
|
||||||
|
return nil, caos_errs.ThrowPreconditionFailed(nil, "EVENT-slpe9", "App is not in this project")
|
||||||
|
}
|
||||||
|
repoProject := ProjectFromModel(existing)
|
||||||
|
repoApp := AppFromModel(app)
|
||||||
|
|
||||||
|
projectAggregate := ApplicationDeactivatedAggregate(es.Eventstore.AggregateCreator(), repoProject, repoApp)
|
||||||
|
err = es_sdk.Push(ctx, es.PushAggregates, repoProject.AppendEvents, projectAggregate)
|
||||||
|
es.projectCache.cacheProject(repoProject)
|
||||||
|
for _, a := range repoProject.Applications {
|
||||||
|
if a.AppID == app.AppID {
|
||||||
|
return AppToModel(a), nil
|
||||||
|
}
|
||||||
|
}
|
||||||
|
return nil, caos_errs.ThrowInternal(nil, "EVENT-sie83", "Could not find app in list")
|
||||||
|
}
|
||||||
|
|
||||||
|
func (es *ProjectEventstore) ReactivateApplication(ctx context.Context, projectID, appID string) (*proj_model.Application, error) {
|
||||||
|
if appID == "" {
|
||||||
|
return nil, caos_errs.ThrowPreconditionFailed(nil, "EVENT-0odi2", "appID missing")
|
||||||
|
}
|
||||||
|
existing, err := es.ProjectByID(ctx, projectID)
|
||||||
|
if err != nil {
|
||||||
|
return nil, err
|
||||||
|
}
|
||||||
|
app := &proj_model.Application{AppID: appID}
|
||||||
|
if _, ok := existing.ContainsApp(app); !ok {
|
||||||
|
return nil, caos_errs.ThrowPreconditionFailed(nil, "EVENT-ld92d", "App is not in this project")
|
||||||
|
}
|
||||||
|
repoProject := ProjectFromModel(existing)
|
||||||
|
repoApp := AppFromModel(app)
|
||||||
|
|
||||||
|
projectAggregate := ApplicationReactivatedAggregate(es.Eventstore.AggregateCreator(), repoProject, repoApp)
|
||||||
|
err = es_sdk.Push(ctx, es.PushAggregates, repoProject.AppendEvents, projectAggregate)
|
||||||
|
es.projectCache.cacheProject(repoProject)
|
||||||
|
for _, a := range repoProject.Applications {
|
||||||
|
if a.AppID == app.AppID {
|
||||||
|
return AppToModel(a), nil
|
||||||
|
}
|
||||||
|
}
|
||||||
|
return nil, caos_errs.ThrowInternal(nil, "EVENT-sld93", "Could not find app in list")
|
||||||
|
}
|
||||||
|
|
||||||
|
func (es *ProjectEventstore) ChangeOIDCConfig(ctx context.Context, config *proj_model.OIDCConfig) (*proj_model.OIDCConfig, error) {
|
||||||
|
if config == nil || !config.IsValid() {
|
||||||
|
return nil, caos_errs.ThrowPreconditionFailed(nil, "EVENT-du834", "invalid oidc config")
|
||||||
|
}
|
||||||
|
existing, err := es.ProjectByID(ctx, config.AggregateID)
|
||||||
|
if err != nil {
|
||||||
|
return nil, err
|
||||||
|
}
|
||||||
|
var ok bool
|
||||||
|
var app *proj_model.Application
|
||||||
|
if app, ok = existing.ContainsApp(&proj_model.Application{AppID: config.AppID}); !ok {
|
||||||
|
return nil, caos_errs.ThrowPreconditionFailed(nil, "EVENT-dkso8", "App is not in this project")
|
||||||
|
}
|
||||||
|
if app.Type != proj_model.APPTYPE_OIDC {
|
||||||
|
return nil, caos_errs.ThrowPreconditionFailed(nil, "EVENT-98uje", "App is not an oidc application")
|
||||||
|
}
|
||||||
|
repoProject := ProjectFromModel(existing)
|
||||||
|
repoConfig := OIDCConfigFromModel(config)
|
||||||
|
|
||||||
|
projectAggregate := OIDCConfigChangedAggregate(es.Eventstore.AggregateCreator(), repoProject, repoConfig)
|
||||||
|
err = es_sdk.Push(ctx, es.PushAggregates, repoProject.AppendEvents, projectAggregate)
|
||||||
|
es.projectCache.cacheProject(repoProject)
|
||||||
|
for _, a := range repoProject.Applications {
|
||||||
|
if a.AppID == app.AppID {
|
||||||
|
return OIDCConfigToModel(a.OIDCConfig), nil
|
||||||
|
}
|
||||||
|
}
|
||||||
|
return nil, caos_errs.ThrowInternal(nil, "EVENT-dk87s", "Could not find app in list")
|
||||||
|
}
|
||||||
|
|
||||||
|
func (es *ProjectEventstore) ChangeOIDCConfigSecret(ctx context.Context, projectID, appID string) (*proj_model.OIDCConfig, error) {
|
||||||
|
if appID == "" {
|
||||||
|
return nil, caos_errs.ThrowPreconditionFailed(nil, "EVENT-7ue34", "some required fields missing")
|
||||||
|
}
|
||||||
|
existing, err := es.ProjectByID(ctx, projectID)
|
||||||
|
if err != nil {
|
||||||
|
return nil, err
|
||||||
|
}
|
||||||
|
var ok bool
|
||||||
|
var app *proj_model.Application
|
||||||
|
if app, ok = existing.ContainsApp(&proj_model.Application{AppID: appID}); !ok {
|
||||||
|
return nil, caos_errs.ThrowPreconditionFailed(nil, "EVENT-9odi4", "App is not in this project")
|
||||||
|
}
|
||||||
|
if app.Type != proj_model.APPTYPE_OIDC {
|
||||||
|
return nil, caos_errs.ThrowPreconditionFailed(nil, "EVENT-dile4", "App is not an oidc application")
|
||||||
|
}
|
||||||
|
repoProject := ProjectFromModel(existing)
|
||||||
|
|
||||||
|
stringPw, crypto, err := generateNewClientSecret(es.pwGenerator)
|
||||||
|
if err != nil {
|
||||||
|
return nil, err
|
||||||
|
}
|
||||||
|
|
||||||
|
projectAggregate := OIDCConfigSecretChangedAggregate(es.Eventstore.AggregateCreator(), repoProject, appID, crypto)
|
||||||
|
err = es_sdk.Push(ctx, es.PushAggregates, repoProject.AppendEvents, projectAggregate)
|
||||||
|
es.projectCache.cacheProject(repoProject)
|
||||||
|
for _, a := range repoProject.Applications {
|
||||||
|
if a.AppID == app.AppID {
|
||||||
|
config := OIDCConfigToModel(a.OIDCConfig)
|
||||||
|
config.ClientSecretString = stringPw
|
||||||
|
return config, nil
|
||||||
|
}
|
||||||
|
}
|
||||||
|
return nil, caos_errs.ThrowInternal(nil, "EVENT-dk87s", "Could not find app in list")
|
||||||
|
}
|
||||||
|
@ -3,12 +3,30 @@ package eventsourcing
|
|||||||
import (
|
import (
|
||||||
"encoding/json"
|
"encoding/json"
|
||||||
mock_cache "github.com/caos/zitadel/internal/cache/mock"
|
mock_cache "github.com/caos/zitadel/internal/cache/mock"
|
||||||
|
"github.com/caos/zitadel/internal/crypto"
|
||||||
"github.com/caos/zitadel/internal/eventstore/mock"
|
"github.com/caos/zitadel/internal/eventstore/mock"
|
||||||
es_models "github.com/caos/zitadel/internal/eventstore/models"
|
es_models "github.com/caos/zitadel/internal/eventstore/models"
|
||||||
"github.com/caos/zitadel/internal/project/model"
|
"github.com/caos/zitadel/internal/project/model"
|
||||||
"github.com/golang/mock/gomock"
|
"github.com/golang/mock/gomock"
|
||||||
|
"github.com/sony/sonyflake"
|
||||||
)
|
)
|
||||||
|
|
||||||
|
func GetMockedEventstore(ctrl *gomock.Controller, mockEs *mock.MockEventstore) *ProjectEventstore {
|
||||||
|
return &ProjectEventstore{
|
||||||
|
Eventstore: mockEs,
|
||||||
|
projectCache: GetMockCache(ctrl),
|
||||||
|
idGenerator: GetSonyFlacke(),
|
||||||
|
}
|
||||||
|
}
|
||||||
|
|
||||||
|
func GetMockedEventstoreWithPw(ctrl *gomock.Controller, mockEs *mock.MockEventstore) *ProjectEventstore {
|
||||||
|
return &ProjectEventstore{
|
||||||
|
Eventstore: mockEs,
|
||||||
|
projectCache: GetMockCache(ctrl),
|
||||||
|
idGenerator: GetSonyFlacke(),
|
||||||
|
pwGenerator: GetMockPwGenerator(ctrl),
|
||||||
|
}
|
||||||
|
}
|
||||||
func GetMockCache(ctrl *gomock.Controller) *ProjectCache {
|
func GetMockCache(ctrl *gomock.Controller) *ProjectCache {
|
||||||
mockCache := mock_cache.NewMockCache(ctrl)
|
mockCache := mock_cache.NewMockCache(ctrl)
|
||||||
mockCache.EXPECT().Get(gomock.Any(), gomock.Any()).Return(nil).AnyTimes()
|
mockCache.EXPECT().Get(gomock.Any(), gomock.Any()).Return(nil).AnyTimes()
|
||||||
@ -16,60 +34,133 @@ func GetMockCache(ctrl *gomock.Controller) *ProjectCache {
|
|||||||
return &ProjectCache{projectCache: mockCache}
|
return &ProjectCache{projectCache: mockCache}
|
||||||
}
|
}
|
||||||
|
|
||||||
|
func GetSonyFlacke() *sonyflake.Sonyflake {
|
||||||
|
return sonyflake.NewSonyflake(sonyflake.Settings{})
|
||||||
|
}
|
||||||
|
|
||||||
|
func GetMockPwGenerator(ctrl *gomock.Controller) crypto.Generator {
|
||||||
|
generator := crypto.NewMockGenerator(ctrl)
|
||||||
|
generator.EXPECT().Length().Return(uint(10))
|
||||||
|
generator.EXPECT().Runes().Return([]rune("abcdefghijklmnopqrstuvwxyz"))
|
||||||
|
generator.EXPECT().Alg().Return(crypto.NewBCrypt(10))
|
||||||
|
return generator
|
||||||
|
}
|
||||||
|
|
||||||
func GetMockProjectByIDOK(ctrl *gomock.Controller) *ProjectEventstore {
|
func GetMockProjectByIDOK(ctrl *gomock.Controller) *ProjectEventstore {
|
||||||
data, _ := json.Marshal(Project{Name: "Name"})
|
data, _ := json.Marshal(Project{Name: "Name"})
|
||||||
events := []*es_models.Event{
|
events := []*es_models.Event{
|
||||||
&es_models.Event{AggregateID: "ID", Sequence: 1, Type: model.ProjectAdded, Data: data},
|
&es_models.Event{AggregateID: "AggregateID", Sequence: 1, Type: model.ProjectAdded, Data: data},
|
||||||
}
|
}
|
||||||
mockEs := mock.NewMockEventstore(ctrl)
|
mockEs := mock.NewMockEventstore(ctrl)
|
||||||
mockEs.EXPECT().FilterEvents(gomock.Any(), gomock.Any()).Return(events, nil)
|
mockEs.EXPECT().FilterEvents(gomock.Any(), gomock.Any()).Return(events, nil)
|
||||||
return &ProjectEventstore{Eventstore: mockEs, projectCache: GetMockCache(ctrl)}
|
return GetMockedEventstore(ctrl, mockEs)
|
||||||
}
|
}
|
||||||
|
|
||||||
func GetMockProjectByIDNoEvents(ctrl *gomock.Controller) *ProjectEventstore {
|
func GetMockProjectByIDNoEvents(ctrl *gomock.Controller) *ProjectEventstore {
|
||||||
events := []*es_models.Event{}
|
events := []*es_models.Event{}
|
||||||
mockEs := mock.NewMockEventstore(ctrl)
|
mockEs := mock.NewMockEventstore(ctrl)
|
||||||
mockEs.EXPECT().FilterEvents(gomock.Any(), gomock.Any()).Return(events, nil)
|
mockEs.EXPECT().FilterEvents(gomock.Any(), gomock.Any()).Return(events, nil)
|
||||||
return &ProjectEventstore{Eventstore: mockEs, projectCache: GetMockCache(ctrl)}
|
return GetMockedEventstore(ctrl, mockEs)
|
||||||
}
|
}
|
||||||
|
|
||||||
func GetMockManipulateProject(ctrl *gomock.Controller) *ProjectEventstore {
|
func GetMockManipulateProject(ctrl *gomock.Controller) *ProjectEventstore {
|
||||||
data, _ := json.Marshal(Project{Name: "Name"})
|
data, _ := json.Marshal(Project{Name: "Name"})
|
||||||
events := []*es_models.Event{
|
events := []*es_models.Event{
|
||||||
&es_models.Event{AggregateID: "ID", Sequence: 1, Type: model.ProjectAdded, Data: data},
|
&es_models.Event{AggregateID: "AggregateID", Sequence: 1, Type: model.ProjectAdded, Data: data},
|
||||||
}
|
}
|
||||||
mockEs := mock.NewMockEventstore(ctrl)
|
mockEs := mock.NewMockEventstore(ctrl)
|
||||||
mockEs.EXPECT().FilterEvents(gomock.Any(), gomock.Any()).Return(events, nil)
|
mockEs.EXPECT().FilterEvents(gomock.Any(), gomock.Any()).Return(events, nil)
|
||||||
mockEs.EXPECT().AggregateCreator().Return(es_models.NewAggregateCreator("TEST"))
|
mockEs.EXPECT().AggregateCreator().Return(es_models.NewAggregateCreator("TEST"))
|
||||||
mockEs.EXPECT().PushAggregates(gomock.Any(), gomock.Any()).Return(nil)
|
mockEs.EXPECT().PushAggregates(gomock.Any(), gomock.Any()).Return(nil)
|
||||||
return &ProjectEventstore{Eventstore: mockEs, projectCache: GetMockCache(ctrl)}
|
return GetMockedEventstore(ctrl, mockEs)
|
||||||
|
}
|
||||||
|
|
||||||
|
func GetMockManipulateProjectWithPw(ctrl *gomock.Controller) *ProjectEventstore {
|
||||||
|
data, _ := json.Marshal(Project{Name: "Name"})
|
||||||
|
events := []*es_models.Event{
|
||||||
|
&es_models.Event{AggregateID: "AggregateID", Sequence: 1, Type: model.ProjectAdded, Data: data},
|
||||||
|
}
|
||||||
|
mockEs := mock.NewMockEventstore(ctrl)
|
||||||
|
mockEs.EXPECT().FilterEvents(gomock.Any(), gomock.Any()).Return(events, nil)
|
||||||
|
mockEs.EXPECT().AggregateCreator().Return(es_models.NewAggregateCreator("TEST"))
|
||||||
|
mockEs.EXPECT().PushAggregates(gomock.Any(), gomock.Any()).Return(nil)
|
||||||
|
return GetMockedEventstoreWithPw(ctrl, mockEs)
|
||||||
}
|
}
|
||||||
|
|
||||||
func GetMockManipulateInactiveProject(ctrl *gomock.Controller) *ProjectEventstore {
|
func GetMockManipulateInactiveProject(ctrl *gomock.Controller) *ProjectEventstore {
|
||||||
data, _ := json.Marshal(Project{Name: "Name"})
|
data, _ := json.Marshal(Project{Name: "Name"})
|
||||||
events := []*es_models.Event{
|
events := []*es_models.Event{
|
||||||
&es_models.Event{AggregateID: "ID", Sequence: 1, Type: model.ProjectAdded, Data: data},
|
&es_models.Event{AggregateID: "AggregateID", Sequence: 1, Type: model.ProjectAdded, Data: data},
|
||||||
&es_models.Event{AggregateID: "ID", Sequence: 2, Type: model.ProjectDeactivated, Data: data},
|
&es_models.Event{AggregateID: "AggregateID", Sequence: 2, Type: model.ProjectDeactivated, Data: data},
|
||||||
}
|
}
|
||||||
mockEs := mock.NewMockEventstore(ctrl)
|
mockEs := mock.NewMockEventstore(ctrl)
|
||||||
mockEs.EXPECT().FilterEvents(gomock.Any(), gomock.Any()).Return(events, nil)
|
mockEs.EXPECT().FilterEvents(gomock.Any(), gomock.Any()).Return(events, nil)
|
||||||
mockEs.EXPECT().AggregateCreator().Return(es_models.NewAggregateCreator("TEST"))
|
mockEs.EXPECT().AggregateCreator().Return(es_models.NewAggregateCreator("TEST"))
|
||||||
mockEs.EXPECT().PushAggregates(gomock.Any(), gomock.Any()).Return(nil)
|
mockEs.EXPECT().PushAggregates(gomock.Any(), gomock.Any()).Return(nil)
|
||||||
return &ProjectEventstore{Eventstore: mockEs, projectCache: GetMockCache(ctrl)}
|
return GetMockedEventstore(ctrl, mockEs)
|
||||||
}
|
}
|
||||||
|
|
||||||
func GetMockManipulateProjectWithMember(ctrl *gomock.Controller) *ProjectEventstore {
|
func GetMockManipulateProjectWithMember(ctrl *gomock.Controller) *ProjectEventstore {
|
||||||
data, _ := json.Marshal(Project{Name: "Name"})
|
data, _ := json.Marshal(Project{Name: "Name"})
|
||||||
memberData, _ := json.Marshal(ProjectMember{UserID: "UserID", Roles: []string{"Role"}})
|
memberData, _ := json.Marshal(ProjectMember{UserID: "UserID", Roles: []string{"Role"}})
|
||||||
events := []*es_models.Event{
|
events := []*es_models.Event{
|
||||||
&es_models.Event{AggregateID: "ID", Sequence: 1, Type: model.ProjectAdded, Data: data},
|
&es_models.Event{AggregateID: "AggregateID", Sequence: 1, Type: model.ProjectAdded, Data: data},
|
||||||
&es_models.Event{AggregateID: "ID", Sequence: 1, Type: model.ProjectMemberAdded, Data: memberData},
|
&es_models.Event{AggregateID: "AggregateID", Sequence: 1, Type: model.ProjectMemberAdded, Data: memberData},
|
||||||
}
|
}
|
||||||
mockEs := mock.NewMockEventstore(ctrl)
|
mockEs := mock.NewMockEventstore(ctrl)
|
||||||
mockEs.EXPECT().FilterEvents(gomock.Any(), gomock.Any()).Return(events, nil)
|
mockEs.EXPECT().FilterEvents(gomock.Any(), gomock.Any()).Return(events, nil)
|
||||||
mockEs.EXPECT().AggregateCreator().Return(es_models.NewAggregateCreator("TEST"))
|
mockEs.EXPECT().AggregateCreator().Return(es_models.NewAggregateCreator("TEST"))
|
||||||
mockEs.EXPECT().PushAggregates(gomock.Any(), gomock.Any()).Return(nil)
|
mockEs.EXPECT().PushAggregates(gomock.Any(), gomock.Any()).Return(nil)
|
||||||
return &ProjectEventstore{Eventstore: mockEs, projectCache: GetMockCache(ctrl)}
|
return GetMockedEventstore(ctrl, mockEs)
|
||||||
|
}
|
||||||
|
|
||||||
|
func GetMockManipulateProjectWithRole(ctrl *gomock.Controller) *ProjectEventstore {
|
||||||
|
data, _ := json.Marshal(Project{Name: "Name"})
|
||||||
|
roleData, _ := json.Marshal(ProjectRole{Key: "Key", DisplayName: "DisplayName", Group: "Group"})
|
||||||
|
events := []*es_models.Event{
|
||||||
|
&es_models.Event{AggregateID: "AggregateID", Sequence: 1, Type: model.ProjectAdded, Data: data},
|
||||||
|
&es_models.Event{AggregateID: "AggregateID", Sequence: 1, Type: model.ProjectRoleAdded, Data: roleData},
|
||||||
|
}
|
||||||
|
mockEs := mock.NewMockEventstore(ctrl)
|
||||||
|
mockEs.EXPECT().FilterEvents(gomock.Any(), gomock.Any()).Return(events, nil)
|
||||||
|
mockEs.EXPECT().AggregateCreator().Return(es_models.NewAggregateCreator("TEST"))
|
||||||
|
mockEs.EXPECT().PushAggregates(gomock.Any(), gomock.Any()).Return(nil)
|
||||||
|
return GetMockedEventstore(ctrl, mockEs)
|
||||||
|
}
|
||||||
|
|
||||||
|
func GetMockManipulateProjectWithOIDCApp(ctrl *gomock.Controller) *ProjectEventstore {
|
||||||
|
data, _ := json.Marshal(Project{Name: "Name"})
|
||||||
|
appData, _ := json.Marshal(Application{AppID: "AppID", Name: "Name"})
|
||||||
|
oidcData, _ := json.Marshal(OIDCConfig{
|
||||||
|
AppID: "AppID",
|
||||||
|
ResponseTypes: []int32{int32(model.OIDCRESPONSETYPE_CODE)},
|
||||||
|
GrantTypes: []int32{int32(model.OIDCGRANTTYPE_AUTHORIZATION_CODE)},
|
||||||
|
})
|
||||||
|
events := []*es_models.Event{
|
||||||
|
&es_models.Event{AggregateID: "AggregateID", Sequence: 1, Type: model.ProjectAdded, Data: data},
|
||||||
|
&es_models.Event{AggregateID: "AggregateID", Sequence: 1, Type: model.ApplicationAdded, Data: appData},
|
||||||
|
&es_models.Event{AggregateID: "AggregateID", Sequence: 1, Type: model.OIDCConfigAdded, Data: oidcData},
|
||||||
|
}
|
||||||
|
mockEs := mock.NewMockEventstore(ctrl)
|
||||||
|
mockEs.EXPECT().FilterEvents(gomock.Any(), gomock.Any()).Return(events, nil)
|
||||||
|
mockEs.EXPECT().AggregateCreator().Return(es_models.NewAggregateCreator("TEST"))
|
||||||
|
mockEs.EXPECT().PushAggregates(gomock.Any(), gomock.Any()).Return(nil)
|
||||||
|
return GetMockedEventstoreWithPw(ctrl, mockEs)
|
||||||
|
}
|
||||||
|
|
||||||
|
func GetMockManipulateProjectWithSAMLApp(ctrl *gomock.Controller) *ProjectEventstore {
|
||||||
|
data, _ := json.Marshal(Project{Name: "Name"})
|
||||||
|
appData, _ := json.Marshal(Application{AppID: "AppID", Name: "Name"})
|
||||||
|
|
||||||
|
events := []*es_models.Event{
|
||||||
|
&es_models.Event{AggregateID: "AggregateID", Sequence: 1, Type: model.ProjectAdded, Data: data},
|
||||||
|
&es_models.Event{AggregateID: "AggregateID", Sequence: 1, Type: model.ApplicationAdded, Data: appData},
|
||||||
|
}
|
||||||
|
mockEs := mock.NewMockEventstore(ctrl)
|
||||||
|
mockEs.EXPECT().FilterEvents(gomock.Any(), gomock.Any()).Return(events, nil)
|
||||||
|
mockEs.EXPECT().AggregateCreator().Return(es_models.NewAggregateCreator("TEST"))
|
||||||
|
mockEs.EXPECT().PushAggregates(gomock.Any(), gomock.Any()).Return(nil)
|
||||||
|
return GetMockedEventstore(ctrl, mockEs)
|
||||||
}
|
}
|
||||||
|
|
||||||
func GetMockManipulateProjectNoEvents(ctrl *gomock.Controller) *ProjectEventstore {
|
func GetMockManipulateProjectNoEvents(ctrl *gomock.Controller) *ProjectEventstore {
|
||||||
@ -78,17 +169,32 @@ func GetMockManipulateProjectNoEvents(ctrl *gomock.Controller) *ProjectEventstor
|
|||||||
mockEs.EXPECT().FilterEvents(gomock.Any(), gomock.Any()).Return(events, nil)
|
mockEs.EXPECT().FilterEvents(gomock.Any(), gomock.Any()).Return(events, nil)
|
||||||
mockEs.EXPECT().AggregateCreator().Return(es_models.NewAggregateCreator("TEST"))
|
mockEs.EXPECT().AggregateCreator().Return(es_models.NewAggregateCreator("TEST"))
|
||||||
mockEs.EXPECT().PushAggregates(gomock.Any(), gomock.Any()).Return(nil)
|
mockEs.EXPECT().PushAggregates(gomock.Any(), gomock.Any()).Return(nil)
|
||||||
return &ProjectEventstore{Eventstore: mockEs, projectCache: GetMockCache(ctrl)}
|
return GetMockedEventstore(ctrl, mockEs)
|
||||||
}
|
}
|
||||||
|
|
||||||
func GetMockProjectMemberByIDsOK(ctrl *gomock.Controller) *ProjectEventstore {
|
func GetMockProjectMemberByIDsOK(ctrl *gomock.Controller) *ProjectEventstore {
|
||||||
projectData, _ := json.Marshal(Project{Name: "Name"})
|
projectData, _ := json.Marshal(Project{Name: "Name"})
|
||||||
memberData, _ := json.Marshal(ProjectMember{UserID: "UserID", Roles: []string{"Role"}})
|
memberData, _ := json.Marshal(ProjectMember{UserID: "UserID", Roles: []string{"Role"}})
|
||||||
events := []*es_models.Event{
|
events := []*es_models.Event{
|
||||||
&es_models.Event{AggregateID: "ID", Sequence: 1, Type: model.ProjectAdded, Data: projectData},
|
&es_models.Event{AggregateID: "AggregateID", Sequence: 1, Type: model.ProjectAdded, Data: projectData},
|
||||||
&es_models.Event{AggregateID: "ID", Sequence: 1, Type: model.ProjectMemberAdded, Data: memberData},
|
&es_models.Event{AggregateID: "AggregateID", Sequence: 1, Type: model.ProjectMemberAdded, Data: memberData},
|
||||||
}
|
}
|
||||||
mockEs := mock.NewMockEventstore(ctrl)
|
mockEs := mock.NewMockEventstore(ctrl)
|
||||||
mockEs.EXPECT().FilterEvents(gomock.Any(), gomock.Any()).Return(events, nil)
|
mockEs.EXPECT().FilterEvents(gomock.Any(), gomock.Any()).Return(events, nil)
|
||||||
return &ProjectEventstore{Eventstore: mockEs, projectCache: GetMockCache(ctrl)}
|
return GetMockedEventstore(ctrl, mockEs)
|
||||||
|
}
|
||||||
|
|
||||||
|
func GetMockProjectAppsByIDsOK(ctrl *gomock.Controller) *ProjectEventstore {
|
||||||
|
projectData, _ := json.Marshal(Project{Name: "Name"})
|
||||||
|
appData, _ := json.Marshal(Application{AppID: "AppID", Name: "Name"})
|
||||||
|
oidcData, _ := json.Marshal(OIDCConfig{ClientID: "ClientID"})
|
||||||
|
|
||||||
|
events := []*es_models.Event{
|
||||||
|
&es_models.Event{AggregateID: "AggregateID", Sequence: 1, Type: model.ProjectAdded, Data: projectData},
|
||||||
|
&es_models.Event{AggregateID: "AggregateID", Sequence: 1, Type: model.ApplicationAdded, Data: appData},
|
||||||
|
&es_models.Event{AggregateID: "AggregateID", Sequence: 1, Type: model.OIDCConfigAdded, Data: oidcData},
|
||||||
|
}
|
||||||
|
mockEs := mock.NewMockEventstore(ctrl)
|
||||||
|
mockEs.EXPECT().FilterEvents(gomock.Any(), gomock.Any()).Return(events, nil)
|
||||||
|
return GetMockedEventstore(ctrl, mockEs)
|
||||||
}
|
}
|
||||||
|
File diff suppressed because it is too large
Load Diff
@ -2,11 +2,11 @@ package eventsourcing
|
|||||||
|
|
||||||
import (
|
import (
|
||||||
"encoding/json"
|
"encoding/json"
|
||||||
"github.com/caos/zitadel/internal/errors"
|
|
||||||
|
|
||||||
"github.com/caos/logging"
|
"github.com/caos/logging"
|
||||||
|
"github.com/caos/zitadel/internal/crypto"
|
||||||
es_models "github.com/caos/zitadel/internal/eventstore/models"
|
es_models "github.com/caos/zitadel/internal/eventstore/models"
|
||||||
"github.com/caos/zitadel/internal/project/model"
|
"github.com/caos/zitadel/internal/project/model"
|
||||||
|
"reflect"
|
||||||
)
|
)
|
||||||
|
|
||||||
const (
|
const (
|
||||||
@ -18,6 +18,8 @@ type Project struct {
|
|||||||
Name string `json:"name,omitempty"`
|
Name string `json:"name,omitempty"`
|
||||||
State int32 `json:"-"`
|
State int32 `json:"-"`
|
||||||
Members []*ProjectMember `json:"-"`
|
Members []*ProjectMember `json:"-"`
|
||||||
|
Roles []*ProjectRole `json:"-"`
|
||||||
|
Applications []*Application `json:"-"`
|
||||||
}
|
}
|
||||||
|
|
||||||
type ProjectMember struct {
|
type ProjectMember struct {
|
||||||
@ -26,6 +28,40 @@ type ProjectMember struct {
|
|||||||
Roles []string `json:"roles,omitempty"`
|
Roles []string `json:"roles,omitempty"`
|
||||||
}
|
}
|
||||||
|
|
||||||
|
type ProjectRole struct {
|
||||||
|
es_models.ObjectRoot
|
||||||
|
Key string `json:"key,omitempty"`
|
||||||
|
DisplayName string `json:"displayName,omitempty"`
|
||||||
|
Group string `json:"group,omitempty"`
|
||||||
|
}
|
||||||
|
|
||||||
|
type Application struct {
|
||||||
|
es_models.ObjectRoot
|
||||||
|
AppID string `json:"appId"`
|
||||||
|
State int32 `json:"-"`
|
||||||
|
Name string `json:"name,omitempty"`
|
||||||
|
Type int32 `json:"appType,omitempty"`
|
||||||
|
OIDCConfig *OIDCConfig `json:"-"`
|
||||||
|
}
|
||||||
|
|
||||||
|
type ApplicationID struct {
|
||||||
|
es_models.ObjectRoot
|
||||||
|
AppID string `json:"appId"`
|
||||||
|
}
|
||||||
|
|
||||||
|
type OIDCConfig struct {
|
||||||
|
es_models.ObjectRoot
|
||||||
|
AppID string `json:"appId"`
|
||||||
|
ClientID string `json:"clientId,omitempty"`
|
||||||
|
ClientSecret *crypto.CryptoValue `json:"clientSecret,omitempty"`
|
||||||
|
RedirectUris []string `json:"redirectUris,omitempty"`
|
||||||
|
ResponseTypes []int32 `json:"responseTypes,omitempty"`
|
||||||
|
GrantTypes []int32 `json:"grantTypes,omitempty"`
|
||||||
|
ApplicationType int32 `json:"applicationType,omitempty"`
|
||||||
|
AuthMethodType int32 `json:"authMethodType,omitempty"`
|
||||||
|
PostLogoutRedirectUris []string `json:"postLogoutRedirectUris,omitempty"`
|
||||||
|
}
|
||||||
|
|
||||||
func (p *Project) Changes(changed *Project) map[string]interface{} {
|
func (p *Project) Changes(changed *Project) map[string]interface{} {
|
||||||
changes := make(map[string]interface{}, 1)
|
changes := make(map[string]interface{}, 1)
|
||||||
if changed.Name != "" && p.Name != changed.Name {
|
if changed.Name != "" && p.Name != changed.Name {
|
||||||
@ -34,33 +70,74 @@ func (p *Project) Changes(changed *Project) map[string]interface{} {
|
|||||||
return changes
|
return changes
|
||||||
}
|
}
|
||||||
|
|
||||||
|
func (a *Application) Changes(changed *Application) map[string]interface{} {
|
||||||
|
changes := make(map[string]interface{}, 1)
|
||||||
|
changes["appId"] = a.AppID
|
||||||
|
if changed.Name != "" && a.Name != changed.Name {
|
||||||
|
changes["name"] = changed.Name
|
||||||
|
}
|
||||||
|
return changes
|
||||||
|
}
|
||||||
|
|
||||||
|
func (c *OIDCConfig) Changes(changed *OIDCConfig) map[string]interface{} {
|
||||||
|
changes := make(map[string]interface{}, 1)
|
||||||
|
changes["appId"] = c.AppID
|
||||||
|
if !reflect.DeepEqual(c.RedirectUris, changed.RedirectUris) {
|
||||||
|
changes["redirectUris"] = changed.RedirectUris
|
||||||
|
}
|
||||||
|
if !reflect.DeepEqual(c.ResponseTypes, changed.ResponseTypes) {
|
||||||
|
changes["responseTypes"] = changed.ResponseTypes
|
||||||
|
}
|
||||||
|
if !reflect.DeepEqual(c.GrantTypes, changed.GrantTypes) {
|
||||||
|
changes["grantTypes"] = changed.GrantTypes
|
||||||
|
}
|
||||||
|
if c.ApplicationType != changed.ApplicationType {
|
||||||
|
changes["applicationType"] = changed.ApplicationType
|
||||||
|
}
|
||||||
|
if c.AuthMethodType != changed.AuthMethodType {
|
||||||
|
changes["authMethodType"] = changed.AuthMethodType
|
||||||
|
}
|
||||||
|
if !reflect.DeepEqual(c.PostLogoutRedirectUris, changed.PostLogoutRedirectUris) {
|
||||||
|
changes["postLogoutRedirectUris"] = changed.PostLogoutRedirectUris
|
||||||
|
}
|
||||||
|
return changes
|
||||||
|
}
|
||||||
|
|
||||||
func ProjectFromModel(project *model.Project) *Project {
|
func ProjectFromModel(project *model.Project) *Project {
|
||||||
members := ProjectMembersFromModel(project.Members)
|
members := ProjectMembersFromModel(project.Members)
|
||||||
|
roles := ProjectRolesFromModel(project.Roles)
|
||||||
|
apps := AppsFromModel(project.Applications)
|
||||||
return &Project{
|
return &Project{
|
||||||
ObjectRoot: es_models.ObjectRoot{
|
ObjectRoot: es_models.ObjectRoot{
|
||||||
ID: project.ObjectRoot.ID,
|
AggregateID: project.ObjectRoot.AggregateID,
|
||||||
Sequence: project.Sequence,
|
Sequence: project.Sequence,
|
||||||
ChangeDate: project.ChangeDate,
|
ChangeDate: project.ChangeDate,
|
||||||
CreationDate: project.CreationDate,
|
CreationDate: project.CreationDate,
|
||||||
},
|
},
|
||||||
Name: project.Name,
|
Name: project.Name,
|
||||||
State: model.ProjectStateToInt(project.State),
|
State: int32(project.State),
|
||||||
Members: members,
|
Members: members,
|
||||||
|
Roles: roles,
|
||||||
|
Applications: apps,
|
||||||
}
|
}
|
||||||
}
|
}
|
||||||
|
|
||||||
func ProjectToModel(project *Project) *model.Project {
|
func ProjectToModel(project *Project) *model.Project {
|
||||||
members := ProjectMembersToModel(project.Members)
|
members := ProjectMembersToModel(project.Members)
|
||||||
|
roles := ProjectRolesToModel(project.Roles)
|
||||||
|
apps := AppsToModel(project.Applications)
|
||||||
return &model.Project{
|
return &model.Project{
|
||||||
ObjectRoot: es_models.ObjectRoot{
|
ObjectRoot: es_models.ObjectRoot{
|
||||||
ID: project.ID,
|
AggregateID: project.AggregateID,
|
||||||
ChangeDate: project.ChangeDate,
|
ChangeDate: project.ChangeDate,
|
||||||
CreationDate: project.CreationDate,
|
CreationDate: project.CreationDate,
|
||||||
Sequence: project.Sequence,
|
Sequence: project.Sequence,
|
||||||
},
|
},
|
||||||
Name: project.Name,
|
Name: project.Name,
|
||||||
State: model.ProjectStateFromInt(project.State),
|
State: model.ProjectState(project.State),
|
||||||
Members: members,
|
Members: members,
|
||||||
|
Roles: roles,
|
||||||
|
Applications: apps,
|
||||||
}
|
}
|
||||||
}
|
}
|
||||||
|
|
||||||
@ -83,7 +160,7 @@ func ProjectMembersFromModel(members []*model.ProjectMember) []*ProjectMember {
|
|||||||
func ProjectMemberFromModel(member *model.ProjectMember) *ProjectMember {
|
func ProjectMemberFromModel(member *model.ProjectMember) *ProjectMember {
|
||||||
return &ProjectMember{
|
return &ProjectMember{
|
||||||
ObjectRoot: es_models.ObjectRoot{
|
ObjectRoot: es_models.ObjectRoot{
|
||||||
ID: member.ObjectRoot.ID,
|
AggregateID: member.ObjectRoot.AggregateID,
|
||||||
Sequence: member.Sequence,
|
Sequence: member.Sequence,
|
||||||
ChangeDate: member.ChangeDate,
|
ChangeDate: member.ChangeDate,
|
||||||
CreationDate: member.CreationDate,
|
CreationDate: member.CreationDate,
|
||||||
@ -96,7 +173,7 @@ func ProjectMemberFromModel(member *model.ProjectMember) *ProjectMember {
|
|||||||
func ProjectMemberToModel(member *ProjectMember) *model.ProjectMember {
|
func ProjectMemberToModel(member *ProjectMember) *model.ProjectMember {
|
||||||
return &model.ProjectMember{
|
return &model.ProjectMember{
|
||||||
ObjectRoot: es_models.ObjectRoot{
|
ObjectRoot: es_models.ObjectRoot{
|
||||||
ID: member.ID,
|
AggregateID: member.AggregateID,
|
||||||
ChangeDate: member.ChangeDate,
|
ChangeDate: member.ChangeDate,
|
||||||
CreationDate: member.CreationDate,
|
CreationDate: member.CreationDate,
|
||||||
Sequence: member.Sequence,
|
Sequence: member.Sequence,
|
||||||
@ -106,6 +183,160 @@ func ProjectMemberToModel(member *ProjectMember) *model.ProjectMember {
|
|||||||
}
|
}
|
||||||
}
|
}
|
||||||
|
|
||||||
|
func ProjectRolesToModel(roles []*ProjectRole) []*model.ProjectRole {
|
||||||
|
convertedRoles := make([]*model.ProjectRole, len(roles))
|
||||||
|
for i, r := range roles {
|
||||||
|
convertedRoles[i] = ProjectRoleToModel(r)
|
||||||
|
}
|
||||||
|
return convertedRoles
|
||||||
|
}
|
||||||
|
|
||||||
|
func ProjectRolesFromModel(roles []*model.ProjectRole) []*ProjectRole {
|
||||||
|
convertedRoles := make([]*ProjectRole, len(roles))
|
||||||
|
for i, r := range roles {
|
||||||
|
convertedRoles[i] = ProjectRoleFromModel(r)
|
||||||
|
}
|
||||||
|
return convertedRoles
|
||||||
|
}
|
||||||
|
|
||||||
|
func ProjectRoleFromModel(role *model.ProjectRole) *ProjectRole {
|
||||||
|
return &ProjectRole{
|
||||||
|
ObjectRoot: es_models.ObjectRoot{
|
||||||
|
AggregateID: role.ObjectRoot.AggregateID,
|
||||||
|
Sequence: role.Sequence,
|
||||||
|
ChangeDate: role.ChangeDate,
|
||||||
|
CreationDate: role.CreationDate,
|
||||||
|
},
|
||||||
|
Key: role.Key,
|
||||||
|
DisplayName: role.DisplayName,
|
||||||
|
Group: role.Group,
|
||||||
|
}
|
||||||
|
}
|
||||||
|
|
||||||
|
func ProjectRoleToModel(role *ProjectRole) *model.ProjectRole {
|
||||||
|
return &model.ProjectRole{
|
||||||
|
ObjectRoot: es_models.ObjectRoot{
|
||||||
|
AggregateID: role.AggregateID,
|
||||||
|
ChangeDate: role.ChangeDate,
|
||||||
|
CreationDate: role.CreationDate,
|
||||||
|
Sequence: role.Sequence,
|
||||||
|
},
|
||||||
|
Key: role.Key,
|
||||||
|
DisplayName: role.DisplayName,
|
||||||
|
Group: role.Group,
|
||||||
|
}
|
||||||
|
}
|
||||||
|
|
||||||
|
func AppsToModel(apps []*Application) []*model.Application {
|
||||||
|
convertedApps := make([]*model.Application, len(apps))
|
||||||
|
for i, a := range apps {
|
||||||
|
convertedApps[i] = AppToModel(a)
|
||||||
|
}
|
||||||
|
return convertedApps
|
||||||
|
}
|
||||||
|
|
||||||
|
func AppsFromModel(apps []*model.Application) []*Application {
|
||||||
|
convertedApps := make([]*Application, len(apps))
|
||||||
|
for i, a := range apps {
|
||||||
|
convertedApps[i] = AppFromModel(a)
|
||||||
|
}
|
||||||
|
return convertedApps
|
||||||
|
}
|
||||||
|
|
||||||
|
func AppFromModel(app *model.Application) *Application {
|
||||||
|
converted := &Application{
|
||||||
|
ObjectRoot: es_models.ObjectRoot{
|
||||||
|
AggregateID: app.ObjectRoot.AggregateID,
|
||||||
|
Sequence: app.Sequence,
|
||||||
|
ChangeDate: app.ChangeDate,
|
||||||
|
CreationDate: app.CreationDate,
|
||||||
|
},
|
||||||
|
AppID: app.AppID,
|
||||||
|
Name: app.Name,
|
||||||
|
State: int32(app.State),
|
||||||
|
Type: int32(app.Type),
|
||||||
|
}
|
||||||
|
if app.OIDCConfig != nil {
|
||||||
|
converted.OIDCConfig = OIDCConfigFromModel(app.OIDCConfig)
|
||||||
|
}
|
||||||
|
return converted
|
||||||
|
}
|
||||||
|
|
||||||
|
func AppToModel(app *Application) *model.Application {
|
||||||
|
converted := &model.Application{
|
||||||
|
ObjectRoot: es_models.ObjectRoot{
|
||||||
|
AggregateID: app.AggregateID,
|
||||||
|
ChangeDate: app.ChangeDate,
|
||||||
|
CreationDate: app.CreationDate,
|
||||||
|
Sequence: app.Sequence,
|
||||||
|
},
|
||||||
|
AppID: app.AppID,
|
||||||
|
Name: app.Name,
|
||||||
|
State: model.AppState(app.State),
|
||||||
|
Type: model.AppType(app.Type),
|
||||||
|
}
|
||||||
|
if app.OIDCConfig != nil {
|
||||||
|
converted.OIDCConfig = OIDCConfigToModel(app.OIDCConfig)
|
||||||
|
}
|
||||||
|
return converted
|
||||||
|
}
|
||||||
|
|
||||||
|
func OIDCConfigFromModel(config *model.OIDCConfig) *OIDCConfig {
|
||||||
|
responseTypes := make([]int32, len(config.ResponseTypes))
|
||||||
|
for i, rt := range config.ResponseTypes {
|
||||||
|
responseTypes[i] = int32(rt)
|
||||||
|
}
|
||||||
|
grantTypes := make([]int32, len(config.GrantTypes))
|
||||||
|
for i, rt := range config.GrantTypes {
|
||||||
|
grantTypes[i] = int32(rt)
|
||||||
|
}
|
||||||
|
return &OIDCConfig{
|
||||||
|
ObjectRoot: es_models.ObjectRoot{
|
||||||
|
AggregateID: config.ObjectRoot.AggregateID,
|
||||||
|
Sequence: config.Sequence,
|
||||||
|
ChangeDate: config.ChangeDate,
|
||||||
|
CreationDate: config.CreationDate,
|
||||||
|
},
|
||||||
|
AppID: config.AppID,
|
||||||
|
ClientID: config.ClientID,
|
||||||
|
ClientSecret: config.ClientSecret,
|
||||||
|
RedirectUris: config.RedirectUris,
|
||||||
|
ResponseTypes: responseTypes,
|
||||||
|
GrantTypes: grantTypes,
|
||||||
|
ApplicationType: int32(config.ApplicationType),
|
||||||
|
AuthMethodType: int32(config.AuthMethodType),
|
||||||
|
PostLogoutRedirectUris: config.PostLogoutRedirectUris,
|
||||||
|
}
|
||||||
|
}
|
||||||
|
|
||||||
|
func OIDCConfigToModel(config *OIDCConfig) *model.OIDCConfig {
|
||||||
|
responseTypes := make([]model.OIDCResponseType, len(config.ResponseTypes))
|
||||||
|
for i, rt := range config.ResponseTypes {
|
||||||
|
responseTypes[i] = model.OIDCResponseType(rt)
|
||||||
|
}
|
||||||
|
grantTypes := make([]model.OIDCGrantType, len(config.GrantTypes))
|
||||||
|
for i, rt := range config.GrantTypes {
|
||||||
|
grantTypes[i] = model.OIDCGrantType(rt)
|
||||||
|
}
|
||||||
|
return &model.OIDCConfig{
|
||||||
|
ObjectRoot: es_models.ObjectRoot{
|
||||||
|
AggregateID: config.ObjectRoot.AggregateID,
|
||||||
|
Sequence: config.Sequence,
|
||||||
|
ChangeDate: config.ChangeDate,
|
||||||
|
CreationDate: config.CreationDate,
|
||||||
|
},
|
||||||
|
AppID: config.AppID,
|
||||||
|
ClientID: config.ClientID,
|
||||||
|
ClientSecret: config.ClientSecret,
|
||||||
|
RedirectUris: config.RedirectUris,
|
||||||
|
ResponseTypes: responseTypes,
|
||||||
|
GrantTypes: grantTypes,
|
||||||
|
ApplicationType: model.OIDCApplicationType(config.ApplicationType),
|
||||||
|
AuthMethodType: model.OIDCAuthMethodType(config.AuthMethodType),
|
||||||
|
PostLogoutRedirectUris: config.PostLogoutRedirectUris,
|
||||||
|
}
|
||||||
|
}
|
||||||
|
|
||||||
func ProjectFromEvents(project *Project, events ...*es_models.Event) (*Project, error) {
|
func ProjectFromEvents(project *Project, events ...*es_models.Event) (*Project, error) {
|
||||||
if project == nil {
|
if project == nil {
|
||||||
project = &Project{}
|
project = &Project{}
|
||||||
@ -132,7 +363,7 @@ func (p *Project) AppendEvent(event *es_models.Event) error {
|
|||||||
logging.Log("EVEN-idl93").WithError(err).Error("could not unmarshal event data")
|
logging.Log("EVEN-idl93").WithError(err).Error("could not unmarshal event data")
|
||||||
return err
|
return err
|
||||||
}
|
}
|
||||||
p.State = model.ProjectStateToInt(model.Active)
|
p.State = int32(model.PROJECTSTATE_ACTIVE)
|
||||||
return nil
|
return nil
|
||||||
case model.ProjectDeactivated:
|
case model.ProjectDeactivated:
|
||||||
return p.appendDeactivatedEvent()
|
return p.appendDeactivatedEvent()
|
||||||
@ -144,22 +375,43 @@ func (p *Project) AppendEvent(event *es_models.Event) error {
|
|||||||
return p.appendChangeMemberEvent(event)
|
return p.appendChangeMemberEvent(event)
|
||||||
case model.ProjectMemberRemoved:
|
case model.ProjectMemberRemoved:
|
||||||
return p.appendRemoveMemberEvent(event)
|
return p.appendRemoveMemberEvent(event)
|
||||||
|
case model.ProjectRoleAdded:
|
||||||
|
return p.appendAddRoleEvent(event)
|
||||||
|
case model.ProjectRoleChanged:
|
||||||
|
return p.appendChangeRoleEvent(event)
|
||||||
|
case model.ProjectRoleRemoved:
|
||||||
|
return p.appendRemoveRoleEvent(event)
|
||||||
|
case model.ApplicationAdded:
|
||||||
|
return p.appendAddAppEvent(event)
|
||||||
|
case model.ApplicationChanged:
|
||||||
|
return p.appendChangeAppEvent(event)
|
||||||
|
case model.ApplicationRemoved:
|
||||||
|
return p.appendRemoveAppEvent(event)
|
||||||
|
case model.ApplicationDeactivated:
|
||||||
|
return p.appendAppStateEvent(event, model.APPSTATE_INACTIVE)
|
||||||
|
case model.ApplicationReactivated:
|
||||||
|
return p.appendAppStateEvent(event, model.APPSTATE_ACTIVE)
|
||||||
|
case model.OIDCConfigAdded:
|
||||||
|
return p.appendAddOIDCConfigEvent(event)
|
||||||
|
case model.OIDCConfigChanged, model.OIDCConfigSecretChanged:
|
||||||
|
return p.appendChangeOIDCConfigEvent(event)
|
||||||
}
|
}
|
||||||
return nil
|
return nil
|
||||||
}
|
}
|
||||||
|
|
||||||
func (p *Project) appendDeactivatedEvent() error {
|
func (p *Project) appendDeactivatedEvent() error {
|
||||||
p.State = model.ProjectStateToInt(model.Inactive)
|
p.State = int32(model.PROJECTSTATE_INACTIVE)
|
||||||
return nil
|
return nil
|
||||||
}
|
}
|
||||||
|
|
||||||
func (p *Project) appendReactivatedEvent() error {
|
func (p *Project) appendReactivatedEvent() error {
|
||||||
p.State = model.ProjectStateToInt(model.Active)
|
p.State = int32(model.PROJECTSTATE_ACTIVE)
|
||||||
return nil
|
return nil
|
||||||
}
|
}
|
||||||
|
|
||||||
func (p *Project) appendAddMemberEvent(event *es_models.Event) error {
|
func (p *Project) appendAddMemberEvent(event *es_models.Event) error {
|
||||||
member, err := getMemberData(event)
|
member := &ProjectMember{}
|
||||||
|
err := member.setData(event)
|
||||||
if err != nil {
|
if err != nil {
|
||||||
return err
|
return err
|
||||||
}
|
}
|
||||||
@ -169,7 +421,8 @@ func (p *Project) appendAddMemberEvent(event *es_models.Event) error {
|
|||||||
}
|
}
|
||||||
|
|
||||||
func (p *Project) appendChangeMemberEvent(event *es_models.Event) error {
|
func (p *Project) appendChangeMemberEvent(event *es_models.Event) error {
|
||||||
member, err := getMemberData(event)
|
member := &ProjectMember{}
|
||||||
|
err := member.setData(event)
|
||||||
if err != nil {
|
if err != nil {
|
||||||
return err
|
return err
|
||||||
}
|
}
|
||||||
@ -182,7 +435,8 @@ func (p *Project) appendChangeMemberEvent(event *es_models.Event) error {
|
|||||||
}
|
}
|
||||||
|
|
||||||
func (p *Project) appendRemoveMemberEvent(event *es_models.Event) error {
|
func (p *Project) appendRemoveMemberEvent(event *es_models.Event) error {
|
||||||
member, err := getMemberData(event)
|
member := &ProjectMember{}
|
||||||
|
err := member.setData(event)
|
||||||
if err != nil {
|
if err != nil {
|
||||||
return err
|
return err
|
||||||
}
|
}
|
||||||
@ -196,12 +450,165 @@ func (p *Project) appendRemoveMemberEvent(event *es_models.Event) error {
|
|||||||
return nil
|
return nil
|
||||||
}
|
}
|
||||||
|
|
||||||
func getMemberData(event *es_models.Event) (*ProjectMember, error) {
|
func (m *ProjectMember) setData(event *es_models.Event) error {
|
||||||
member := &ProjectMember{}
|
m.ObjectRoot.AppendEvent(event)
|
||||||
member.ObjectRoot.AppendEvent(event)
|
if err := json.Unmarshal(event.Data, m); err != nil {
|
||||||
if err := json.Unmarshal(event.Data, member); err != nil {
|
|
||||||
logging.Log("EVEN-e4dkp").WithError(err).Error("could not unmarshal event data")
|
logging.Log("EVEN-e4dkp").WithError(err).Error("could not unmarshal event data")
|
||||||
return nil, errors.ThrowInternal(err, "EVENT-83js6", "could not unmarshal event data")
|
return err
|
||||||
}
|
}
|
||||||
return member, nil
|
return nil
|
||||||
|
}
|
||||||
|
|
||||||
|
func (p *Project) appendAddRoleEvent(event *es_models.Event) error {
|
||||||
|
role := new(ProjectRole)
|
||||||
|
err := role.setData(event)
|
||||||
|
if err != nil {
|
||||||
|
return err
|
||||||
|
}
|
||||||
|
role.ObjectRoot.CreationDate = event.CreationDate
|
||||||
|
p.Roles = append(p.Roles, role)
|
||||||
|
return nil
|
||||||
|
}
|
||||||
|
|
||||||
|
func (p *Project) appendChangeRoleEvent(event *es_models.Event) error {
|
||||||
|
role := new(ProjectRole)
|
||||||
|
err := role.setData(event)
|
||||||
|
if err != nil {
|
||||||
|
return err
|
||||||
|
}
|
||||||
|
for i, r := range p.Roles {
|
||||||
|
if r.Key == role.Key {
|
||||||
|
p.Roles[i] = role
|
||||||
|
}
|
||||||
|
}
|
||||||
|
return nil
|
||||||
|
}
|
||||||
|
|
||||||
|
func (p *Project) appendRemoveRoleEvent(event *es_models.Event) error {
|
||||||
|
role := new(ProjectRole)
|
||||||
|
err := role.setData(event)
|
||||||
|
if err != nil {
|
||||||
|
return err
|
||||||
|
}
|
||||||
|
for i, r := range p.Roles {
|
||||||
|
if r.Key == role.Key {
|
||||||
|
p.Roles[i] = p.Roles[len(p.Roles)-1]
|
||||||
|
p.Roles[len(p.Roles)-1] = nil
|
||||||
|
p.Roles = p.Roles[:len(p.Roles)-1]
|
||||||
|
}
|
||||||
|
}
|
||||||
|
return nil
|
||||||
|
}
|
||||||
|
|
||||||
|
func (r *ProjectRole) setData(event *es_models.Event) error {
|
||||||
|
r.ObjectRoot.AppendEvent(event)
|
||||||
|
if err := json.Unmarshal(event.Data, r); err != nil {
|
||||||
|
logging.Log("EVEN-d9euw").WithError(err).Error("could not unmarshal event data")
|
||||||
|
return err
|
||||||
|
}
|
||||||
|
return nil
|
||||||
|
}
|
||||||
|
|
||||||
|
func (p *Project) appendAddAppEvent(event *es_models.Event) error {
|
||||||
|
app := new(Application)
|
||||||
|
err := app.setData(event)
|
||||||
|
if err != nil {
|
||||||
|
return err
|
||||||
|
}
|
||||||
|
app.ObjectRoot.CreationDate = event.CreationDate
|
||||||
|
p.Applications = append(p.Applications, app)
|
||||||
|
return nil
|
||||||
|
}
|
||||||
|
|
||||||
|
func (p *Project) appendChangeAppEvent(event *es_models.Event) error {
|
||||||
|
app := new(Application)
|
||||||
|
err := app.setData(event)
|
||||||
|
if err != nil {
|
||||||
|
return err
|
||||||
|
}
|
||||||
|
for i, a := range p.Applications {
|
||||||
|
if a.AppID == app.AppID {
|
||||||
|
p.Applications[i].setData(event)
|
||||||
|
}
|
||||||
|
}
|
||||||
|
return nil
|
||||||
|
}
|
||||||
|
|
||||||
|
func (p *Project) appendRemoveAppEvent(event *es_models.Event) error {
|
||||||
|
app := new(Application)
|
||||||
|
err := app.setData(event)
|
||||||
|
if err != nil {
|
||||||
|
return err
|
||||||
|
}
|
||||||
|
for i, a := range p.Applications {
|
||||||
|
if a.AppID == app.AppID {
|
||||||
|
p.Applications[i] = p.Applications[len(p.Applications)-1]
|
||||||
|
p.Applications[len(p.Applications)-1] = nil
|
||||||
|
p.Applications = p.Applications[:len(p.Applications)-1]
|
||||||
|
}
|
||||||
|
}
|
||||||
|
return nil
|
||||||
|
}
|
||||||
|
|
||||||
|
func (p *Project) appendAppStateEvent(event *es_models.Event, state model.AppState) error {
|
||||||
|
app := new(Application)
|
||||||
|
err := app.setData(event)
|
||||||
|
if err != nil {
|
||||||
|
return err
|
||||||
|
}
|
||||||
|
for i, a := range p.Applications {
|
||||||
|
if a.AppID == app.AppID {
|
||||||
|
a.State = int32(state)
|
||||||
|
p.Applications[i] = a
|
||||||
|
}
|
||||||
|
}
|
||||||
|
return nil
|
||||||
|
}
|
||||||
|
|
||||||
|
func (a *Application) setData(event *es_models.Event) error {
|
||||||
|
a.ObjectRoot.AppendEvent(event)
|
||||||
|
if err := json.Unmarshal(event.Data, a); err != nil {
|
||||||
|
logging.Log("EVEN-8die3").WithError(err).Error("could not unmarshal event data")
|
||||||
|
return err
|
||||||
|
}
|
||||||
|
return nil
|
||||||
|
}
|
||||||
|
|
||||||
|
func (p *Project) appendAddOIDCConfigEvent(event *es_models.Event) error {
|
||||||
|
config := new(OIDCConfig)
|
||||||
|
err := config.setData(event)
|
||||||
|
if err != nil {
|
||||||
|
return err
|
||||||
|
}
|
||||||
|
config.ObjectRoot.CreationDate = event.CreationDate
|
||||||
|
for i, a := range p.Applications {
|
||||||
|
if a.AppID == config.AppID {
|
||||||
|
p.Applications[i].Type = int32(model.APPTYPE_OIDC)
|
||||||
|
p.Applications[i].OIDCConfig = config
|
||||||
|
}
|
||||||
|
}
|
||||||
|
return nil
|
||||||
|
}
|
||||||
|
|
||||||
|
func (p *Project) appendChangeOIDCConfigEvent(event *es_models.Event) error {
|
||||||
|
config := new(OIDCConfig)
|
||||||
|
err := config.setData(event)
|
||||||
|
if err != nil {
|
||||||
|
return err
|
||||||
|
}
|
||||||
|
for i, a := range p.Applications {
|
||||||
|
if a.AppID == config.AppID {
|
||||||
|
p.Applications[i].OIDCConfig.setData(event)
|
||||||
|
}
|
||||||
|
}
|
||||||
|
return nil
|
||||||
|
}
|
||||||
|
|
||||||
|
func (o *OIDCConfig) setData(event *es_models.Event) error {
|
||||||
|
o.ObjectRoot.AppendEvent(event)
|
||||||
|
if err := json.Unmarshal(event.Data, o); err != nil {
|
||||||
|
logging.Log("EVEN-d8e3s").WithError(err).Error("could not unmarshal event data")
|
||||||
|
return err
|
||||||
|
}
|
||||||
|
return nil
|
||||||
}
|
}
|
||||||
|
@ -8,168 +8,7 @@ import (
|
|||||||
"github.com/caos/zitadel/internal/project/model"
|
"github.com/caos/zitadel/internal/project/model"
|
||||||
)
|
)
|
||||||
|
|
||||||
func TestProjectFromEvents(t *testing.T) {
|
func TestProjectChanges(t *testing.T) {
|
||||||
type args struct {
|
|
||||||
event []*es_models.Event
|
|
||||||
project *Project
|
|
||||||
}
|
|
||||||
tests := []struct {
|
|
||||||
name string
|
|
||||||
args args
|
|
||||||
result *Project
|
|
||||||
}{
|
|
||||||
{
|
|
||||||
name: "project from events, ok",
|
|
||||||
args: args{
|
|
||||||
event: []*es_models.Event{
|
|
||||||
&es_models.Event{AggregateID: "ID", Sequence: 1, Type: model.ProjectAdded},
|
|
||||||
},
|
|
||||||
project: &Project{Name: "ProjectName"},
|
|
||||||
},
|
|
||||||
result: &Project{ObjectRoot: es_models.ObjectRoot{ID: "ID"}, State: int32(model.Active), Name: "ProjectName"},
|
|
||||||
},
|
|
||||||
{
|
|
||||||
name: "project from events, nil project",
|
|
||||||
args: args{
|
|
||||||
event: []*es_models.Event{
|
|
||||||
&es_models.Event{AggregateID: "ID", Sequence: 1, Type: model.ProjectAdded},
|
|
||||||
},
|
|
||||||
project: nil,
|
|
||||||
},
|
|
||||||
result: &Project{ObjectRoot: es_models.ObjectRoot{ID: "ID"}, State: int32(model.Active)},
|
|
||||||
},
|
|
||||||
}
|
|
||||||
for _, tt := range tests {
|
|
||||||
t.Run(tt.name, func(t *testing.T) {
|
|
||||||
if tt.args.project != nil {
|
|
||||||
data, _ := json.Marshal(tt.args.project)
|
|
||||||
tt.args.event[0].Data = data
|
|
||||||
}
|
|
||||||
result, _ := ProjectFromEvents(tt.args.project, tt.args.event...)
|
|
||||||
if result.Name != tt.result.Name {
|
|
||||||
t.Errorf("got wrong result name: expected: %v, actual: %v ", tt.result.Name, result.Name)
|
|
||||||
}
|
|
||||||
})
|
|
||||||
}
|
|
||||||
}
|
|
||||||
|
|
||||||
func TestAppendEvent(t *testing.T) {
|
|
||||||
type args struct {
|
|
||||||
event *es_models.Event
|
|
||||||
project *Project
|
|
||||||
}
|
|
||||||
tests := []struct {
|
|
||||||
name string
|
|
||||||
args args
|
|
||||||
result *Project
|
|
||||||
}{
|
|
||||||
{
|
|
||||||
name: "append added event",
|
|
||||||
args: args{
|
|
||||||
event: &es_models.Event{AggregateID: "ID", Sequence: 1, Type: model.ProjectAdded},
|
|
||||||
project: &Project{Name: "ProjectName"},
|
|
||||||
},
|
|
||||||
result: &Project{ObjectRoot: es_models.ObjectRoot{ID: "ID"}, State: int32(model.Active), Name: "ProjectName"},
|
|
||||||
},
|
|
||||||
{
|
|
||||||
name: "append change event",
|
|
||||||
args: args{
|
|
||||||
event: &es_models.Event{AggregateID: "ID", Sequence: 1, Type: model.ProjectChanged},
|
|
||||||
project: &Project{Name: "ProjectName"},
|
|
||||||
},
|
|
||||||
result: &Project{ObjectRoot: es_models.ObjectRoot{ID: "ID"}, State: int32(model.Active), Name: "ProjectName"},
|
|
||||||
},
|
|
||||||
{
|
|
||||||
name: "append deactivate event",
|
|
||||||
args: args{
|
|
||||||
event: &es_models.Event{AggregateID: "ID", Sequence: 1, Type: model.ProjectDeactivated},
|
|
||||||
},
|
|
||||||
result: &Project{ObjectRoot: es_models.ObjectRoot{ID: "ID"}, State: int32(model.Inactive)},
|
|
||||||
},
|
|
||||||
{
|
|
||||||
name: "append reactivate event",
|
|
||||||
args: args{
|
|
||||||
event: &es_models.Event{AggregateID: "ID", Sequence: 1, Type: model.ProjectReactivated},
|
|
||||||
},
|
|
||||||
result: &Project{ObjectRoot: es_models.ObjectRoot{ID: "ID"}, State: int32(model.Active)},
|
|
||||||
},
|
|
||||||
}
|
|
||||||
for _, tt := range tests {
|
|
||||||
t.Run(tt.name, func(t *testing.T) {
|
|
||||||
if tt.args.project != nil {
|
|
||||||
data, _ := json.Marshal(tt.args.project)
|
|
||||||
tt.args.event.Data = data
|
|
||||||
}
|
|
||||||
result := &Project{}
|
|
||||||
result.AppendEvent(tt.args.event)
|
|
||||||
if result.State != tt.result.State {
|
|
||||||
t.Errorf("got wrong result state: expected: %v, actual: %v ", tt.result.State, result.State)
|
|
||||||
}
|
|
||||||
if result.Name != tt.result.Name {
|
|
||||||
t.Errorf("got wrong result name: expected: %v, actual: %v ", tt.result.Name, result.Name)
|
|
||||||
}
|
|
||||||
if result.ObjectRoot.ID != tt.result.ObjectRoot.ID {
|
|
||||||
t.Errorf("got wrong result id: expected: %v, actual: %v ", tt.result.ObjectRoot.ID, result.ObjectRoot.ID)
|
|
||||||
}
|
|
||||||
})
|
|
||||||
}
|
|
||||||
}
|
|
||||||
|
|
||||||
func TestAppendDeactivatedEvent(t *testing.T) {
|
|
||||||
type args struct {
|
|
||||||
project *Project
|
|
||||||
}
|
|
||||||
tests := []struct {
|
|
||||||
name string
|
|
||||||
args args
|
|
||||||
result *Project
|
|
||||||
}{
|
|
||||||
{
|
|
||||||
name: "append reactivate event",
|
|
||||||
args: args{
|
|
||||||
project: &Project{},
|
|
||||||
},
|
|
||||||
result: &Project{State: int32(model.Inactive)},
|
|
||||||
},
|
|
||||||
}
|
|
||||||
for _, tt := range tests {
|
|
||||||
t.Run(tt.name, func(t *testing.T) {
|
|
||||||
tt.args.project.appendDeactivatedEvent()
|
|
||||||
if tt.args.project.State != tt.result.State {
|
|
||||||
t.Errorf("got wrong result: expected: %v, actual: %v ", tt.result, tt.args.project)
|
|
||||||
}
|
|
||||||
})
|
|
||||||
}
|
|
||||||
}
|
|
||||||
|
|
||||||
func TestAppendReactivatedEvent(t *testing.T) {
|
|
||||||
type args struct {
|
|
||||||
project *Project
|
|
||||||
}
|
|
||||||
tests := []struct {
|
|
||||||
name string
|
|
||||||
args args
|
|
||||||
result *Project
|
|
||||||
}{
|
|
||||||
{
|
|
||||||
name: "append reactivate event",
|
|
||||||
args: args{
|
|
||||||
project: &Project{},
|
|
||||||
},
|
|
||||||
result: &Project{State: int32(model.Active)},
|
|
||||||
},
|
|
||||||
}
|
|
||||||
for _, tt := range tests {
|
|
||||||
t.Run(tt.name, func(t *testing.T) {
|
|
||||||
tt.args.project.appendReactivatedEvent()
|
|
||||||
if tt.args.project.State != tt.result.State {
|
|
||||||
t.Errorf("got wrong result: expected: %v, actual: %v ", tt.result, tt.args.project)
|
|
||||||
}
|
|
||||||
})
|
|
||||||
}
|
|
||||||
}
|
|
||||||
|
|
||||||
func TestChanges(t *testing.T) {
|
|
||||||
type args struct {
|
type args struct {
|
||||||
existing *Project
|
existing *Project
|
||||||
new *Project
|
new *Project
|
||||||
@ -213,6 +52,302 @@ func TestChanges(t *testing.T) {
|
|||||||
}
|
}
|
||||||
}
|
}
|
||||||
|
|
||||||
|
func TestApplicationChanges(t *testing.T) {
|
||||||
|
type args struct {
|
||||||
|
existing *Application
|
||||||
|
new *Application
|
||||||
|
}
|
||||||
|
type res struct {
|
||||||
|
changesLen int
|
||||||
|
}
|
||||||
|
tests := []struct {
|
||||||
|
name string
|
||||||
|
args args
|
||||||
|
res res
|
||||||
|
}{
|
||||||
|
{
|
||||||
|
name: "application name changes",
|
||||||
|
args: args{
|
||||||
|
existing: &Application{AppID: "AppID", Name: "Name"},
|
||||||
|
new: &Application{AppID: "AppID", Name: "NameChanged"},
|
||||||
|
},
|
||||||
|
res: res{
|
||||||
|
changesLen: 2,
|
||||||
|
},
|
||||||
|
},
|
||||||
|
{
|
||||||
|
name: "no changes",
|
||||||
|
args: args{
|
||||||
|
existing: &Application{AppID: "AppID", Name: "Name"},
|
||||||
|
new: &Application{AppID: "AppID", Name: "Name"},
|
||||||
|
},
|
||||||
|
res: res{
|
||||||
|
changesLen: 1,
|
||||||
|
},
|
||||||
|
},
|
||||||
|
}
|
||||||
|
for _, tt := range tests {
|
||||||
|
t.Run(tt.name, func(t *testing.T) {
|
||||||
|
changes := tt.args.existing.Changes(tt.args.new)
|
||||||
|
if len(changes) != tt.res.changesLen {
|
||||||
|
t.Errorf("got wrong changes len: expected: %v, actual: %v ", tt.res.changesLen, len(changes))
|
||||||
|
}
|
||||||
|
})
|
||||||
|
}
|
||||||
|
}
|
||||||
|
|
||||||
|
func TestOIDCConfigChanges(t *testing.T) {
|
||||||
|
type args struct {
|
||||||
|
existing *OIDCConfig
|
||||||
|
new *OIDCConfig
|
||||||
|
}
|
||||||
|
type res struct {
|
||||||
|
changesLen int
|
||||||
|
}
|
||||||
|
tests := []struct {
|
||||||
|
name string
|
||||||
|
args args
|
||||||
|
res res
|
||||||
|
}{
|
||||||
|
{
|
||||||
|
name: "all possible values change",
|
||||||
|
args: args{
|
||||||
|
existing: &OIDCConfig{
|
||||||
|
AppID: "AppID",
|
||||||
|
RedirectUris: []string{"RedirectUris"},
|
||||||
|
ResponseTypes: []int32{1},
|
||||||
|
GrantTypes: []int32{1},
|
||||||
|
ApplicationType: 1,
|
||||||
|
AuthMethodType: 1,
|
||||||
|
PostLogoutRedirectUris: []string{"PostLogoutRedirectUris"},
|
||||||
|
},
|
||||||
|
new: &OIDCConfig{
|
||||||
|
AppID: "AppID",
|
||||||
|
RedirectUris: []string{"RedirectUrisChanged"},
|
||||||
|
ResponseTypes: []int32{2},
|
||||||
|
GrantTypes: []int32{2},
|
||||||
|
ApplicationType: 2,
|
||||||
|
AuthMethodType: 2,
|
||||||
|
PostLogoutRedirectUris: []string{"PostLogoutRedirectUrisChanged"},
|
||||||
|
},
|
||||||
|
},
|
||||||
|
res: res{
|
||||||
|
changesLen: 7,
|
||||||
|
},
|
||||||
|
},
|
||||||
|
{
|
||||||
|
name: "no changes",
|
||||||
|
args: args{
|
||||||
|
existing: &OIDCConfig{
|
||||||
|
AppID: "AppID",
|
||||||
|
RedirectUris: []string{"RedirectUris"},
|
||||||
|
ResponseTypes: []int32{1},
|
||||||
|
GrantTypes: []int32{1},
|
||||||
|
ApplicationType: 1,
|
||||||
|
AuthMethodType: 1,
|
||||||
|
PostLogoutRedirectUris: []string{"PostLogoutRedirectUris"},
|
||||||
|
},
|
||||||
|
new: &OIDCConfig{
|
||||||
|
AppID: "AppID",
|
||||||
|
RedirectUris: []string{"RedirectUris"},
|
||||||
|
ResponseTypes: []int32{1},
|
||||||
|
GrantTypes: []int32{1},
|
||||||
|
ApplicationType: 1,
|
||||||
|
AuthMethodType: 1,
|
||||||
|
PostLogoutRedirectUris: []string{"PostLogoutRedirectUris"},
|
||||||
|
},
|
||||||
|
},
|
||||||
|
res: res{
|
||||||
|
changesLen: 1,
|
||||||
|
},
|
||||||
|
},
|
||||||
|
{
|
||||||
|
name: "change not changeable attributes",
|
||||||
|
args: args{
|
||||||
|
existing: &OIDCConfig{
|
||||||
|
AppID: "AppID",
|
||||||
|
ClientID: "ClientID",
|
||||||
|
},
|
||||||
|
new: &OIDCConfig{
|
||||||
|
AppID: "AppIDChange",
|
||||||
|
ClientID: "ClientIDChange",
|
||||||
|
},
|
||||||
|
},
|
||||||
|
res: res{
|
||||||
|
changesLen: 1,
|
||||||
|
},
|
||||||
|
},
|
||||||
|
}
|
||||||
|
for _, tt := range tests {
|
||||||
|
t.Run(tt.name, func(t *testing.T) {
|
||||||
|
changes := tt.args.existing.Changes(tt.args.new)
|
||||||
|
if len(changes) != tt.res.changesLen {
|
||||||
|
t.Errorf("got wrong changes len: expected: %v, actual: %v ", tt.res.changesLen, len(changes))
|
||||||
|
}
|
||||||
|
})
|
||||||
|
}
|
||||||
|
}
|
||||||
|
|
||||||
|
func TestProjectFromEvents(t *testing.T) {
|
||||||
|
type args struct {
|
||||||
|
event []*es_models.Event
|
||||||
|
project *Project
|
||||||
|
}
|
||||||
|
tests := []struct {
|
||||||
|
name string
|
||||||
|
args args
|
||||||
|
result *Project
|
||||||
|
}{
|
||||||
|
{
|
||||||
|
name: "project from events, ok",
|
||||||
|
args: args{
|
||||||
|
event: []*es_models.Event{
|
||||||
|
&es_models.Event{AggregateID: "AggregateID", Sequence: 1, Type: model.ProjectAdded},
|
||||||
|
},
|
||||||
|
project: &Project{Name: "ProjectName"},
|
||||||
|
},
|
||||||
|
result: &Project{ObjectRoot: es_models.ObjectRoot{AggregateID: "AggregateID"}, State: int32(model.PROJECTSTATE_ACTIVE), Name: "ProjectName"},
|
||||||
|
},
|
||||||
|
{
|
||||||
|
name: "project from events, nil project",
|
||||||
|
args: args{
|
||||||
|
event: []*es_models.Event{
|
||||||
|
&es_models.Event{AggregateID: "AggregateID", Sequence: 1, Type: model.ProjectAdded},
|
||||||
|
},
|
||||||
|
project: nil,
|
||||||
|
},
|
||||||
|
result: &Project{ObjectRoot: es_models.ObjectRoot{AggregateID: "AggregateID"}, State: int32(model.PROJECTSTATE_ACTIVE)},
|
||||||
|
},
|
||||||
|
}
|
||||||
|
for _, tt := range tests {
|
||||||
|
t.Run(tt.name, func(t *testing.T) {
|
||||||
|
if tt.args.project != nil {
|
||||||
|
data, _ := json.Marshal(tt.args.project)
|
||||||
|
tt.args.event[0].Data = data
|
||||||
|
}
|
||||||
|
result, _ := ProjectFromEvents(tt.args.project, tt.args.event...)
|
||||||
|
if result.Name != tt.result.Name {
|
||||||
|
t.Errorf("got wrong result name: expected: %v, actual: %v ", tt.result.Name, result.Name)
|
||||||
|
}
|
||||||
|
})
|
||||||
|
}
|
||||||
|
}
|
||||||
|
|
||||||
|
func TestAppendEvent(t *testing.T) {
|
||||||
|
type args struct {
|
||||||
|
event *es_models.Event
|
||||||
|
project *Project
|
||||||
|
}
|
||||||
|
tests := []struct {
|
||||||
|
name string
|
||||||
|
args args
|
||||||
|
result *Project
|
||||||
|
}{
|
||||||
|
{
|
||||||
|
name: "append added event",
|
||||||
|
args: args{
|
||||||
|
event: &es_models.Event{AggregateID: "AggregateID", Sequence: 1, Type: model.ProjectAdded},
|
||||||
|
project: &Project{Name: "ProjectName"},
|
||||||
|
},
|
||||||
|
result: &Project{ObjectRoot: es_models.ObjectRoot{AggregateID: "AggregateID"}, State: int32(model.PROJECTSTATE_ACTIVE), Name: "ProjectName"},
|
||||||
|
},
|
||||||
|
{
|
||||||
|
name: "append change event",
|
||||||
|
args: args{
|
||||||
|
event: &es_models.Event{AggregateID: "AggregateID", Sequence: 1, Type: model.ProjectChanged},
|
||||||
|
project: &Project{Name: "ProjectName"},
|
||||||
|
},
|
||||||
|
result: &Project{ObjectRoot: es_models.ObjectRoot{AggregateID: "AggregateID"}, State: int32(model.PROJECTSTATE_ACTIVE), Name: "ProjectName"},
|
||||||
|
},
|
||||||
|
{
|
||||||
|
name: "append deactivate event",
|
||||||
|
args: args{
|
||||||
|
event: &es_models.Event{AggregateID: "AggregateID", Sequence: 1, Type: model.ProjectDeactivated},
|
||||||
|
},
|
||||||
|
result: &Project{ObjectRoot: es_models.ObjectRoot{AggregateID: "AggregateID"}, State: int32(model.PROJECTSTATE_INACTIVE)},
|
||||||
|
},
|
||||||
|
{
|
||||||
|
name: "append reactivate event",
|
||||||
|
args: args{
|
||||||
|
event: &es_models.Event{AggregateID: "AggregateID", Sequence: 1, Type: model.ProjectReactivated},
|
||||||
|
},
|
||||||
|
result: &Project{ObjectRoot: es_models.ObjectRoot{AggregateID: "AggregateID"}, State: int32(model.PROJECTSTATE_ACTIVE)},
|
||||||
|
},
|
||||||
|
}
|
||||||
|
for _, tt := range tests {
|
||||||
|
t.Run(tt.name, func(t *testing.T) {
|
||||||
|
if tt.args.project != nil {
|
||||||
|
data, _ := json.Marshal(tt.args.project)
|
||||||
|
tt.args.event.Data = data
|
||||||
|
}
|
||||||
|
result := new(Project)
|
||||||
|
result.AppendEvent(tt.args.event)
|
||||||
|
if result.State != tt.result.State {
|
||||||
|
t.Errorf("got wrong result state: expected: %v, actual: %v ", tt.result.State, result.State)
|
||||||
|
}
|
||||||
|
if result.Name != tt.result.Name {
|
||||||
|
t.Errorf("got wrong result name: expected: %v, actual: %v ", tt.result.Name, result.Name)
|
||||||
|
}
|
||||||
|
if result.ObjectRoot.AggregateID != tt.result.ObjectRoot.AggregateID {
|
||||||
|
t.Errorf("got wrong result id: expected: %v, actual: %v ", tt.result.ObjectRoot.AggregateID, result.ObjectRoot.AggregateID)
|
||||||
|
}
|
||||||
|
})
|
||||||
|
}
|
||||||
|
}
|
||||||
|
|
||||||
|
func TestAppendDeactivatedEvent(t *testing.T) {
|
||||||
|
type args struct {
|
||||||
|
project *Project
|
||||||
|
}
|
||||||
|
tests := []struct {
|
||||||
|
name string
|
||||||
|
args args
|
||||||
|
result *Project
|
||||||
|
}{
|
||||||
|
{
|
||||||
|
name: "append reactivate event",
|
||||||
|
args: args{
|
||||||
|
project: &Project{},
|
||||||
|
},
|
||||||
|
result: &Project{State: int32(model.PROJECTSTATE_INACTIVE)},
|
||||||
|
},
|
||||||
|
}
|
||||||
|
for _, tt := range tests {
|
||||||
|
t.Run(tt.name, func(t *testing.T) {
|
||||||
|
tt.args.project.appendDeactivatedEvent()
|
||||||
|
if tt.args.project.State != tt.result.State {
|
||||||
|
t.Errorf("got wrong result: expected: %v, actual: %v ", tt.result, tt.args.project)
|
||||||
|
}
|
||||||
|
})
|
||||||
|
}
|
||||||
|
}
|
||||||
|
|
||||||
|
func TestAppendReactivatedEvent(t *testing.T) {
|
||||||
|
type args struct {
|
||||||
|
project *Project
|
||||||
|
}
|
||||||
|
tests := []struct {
|
||||||
|
name string
|
||||||
|
args args
|
||||||
|
result *Project
|
||||||
|
}{
|
||||||
|
{
|
||||||
|
name: "append reactivate event",
|
||||||
|
args: args{
|
||||||
|
project: &Project{},
|
||||||
|
},
|
||||||
|
result: &Project{State: int32(model.PROJECTSTATE_ACTIVE)},
|
||||||
|
},
|
||||||
|
}
|
||||||
|
for _, tt := range tests {
|
||||||
|
t.Run(tt.name, func(t *testing.T) {
|
||||||
|
tt.args.project.appendReactivatedEvent()
|
||||||
|
if tt.args.project.State != tt.result.State {
|
||||||
|
t.Errorf("got wrong result: expected: %v, actual: %v ", tt.result, tt.args.project)
|
||||||
|
}
|
||||||
|
})
|
||||||
|
}
|
||||||
|
}
|
||||||
|
|
||||||
func TestAppendAddMemberEvent(t *testing.T) {
|
func TestAppendAddMemberEvent(t *testing.T) {
|
||||||
type args struct {
|
type args struct {
|
||||||
@ -319,7 +454,361 @@ func TestAppendRemoveMemberEvent(t *testing.T) {
|
|||||||
}
|
}
|
||||||
tt.args.project.appendRemoveMemberEvent(tt.args.event)
|
tt.args.project.appendRemoveMemberEvent(tt.args.event)
|
||||||
if len(tt.args.project.Members) != 0 {
|
if len(tt.args.project.Members) != 0 {
|
||||||
t.Errorf("got wrong result should have one member actual: %v ", len(tt.args.project.Members))
|
t.Errorf("got wrong result should have no member actual: %v ", len(tt.args.project.Members))
|
||||||
|
}
|
||||||
|
})
|
||||||
|
}
|
||||||
|
}
|
||||||
|
|
||||||
|
func TestAppendAddRoleEvent(t *testing.T) {
|
||||||
|
type args struct {
|
||||||
|
project *Project
|
||||||
|
role *ProjectRole
|
||||||
|
event *es_models.Event
|
||||||
|
}
|
||||||
|
tests := []struct {
|
||||||
|
name string
|
||||||
|
args args
|
||||||
|
result *Project
|
||||||
|
}{
|
||||||
|
{
|
||||||
|
name: "append add role event",
|
||||||
|
args: args{
|
||||||
|
project: &Project{},
|
||||||
|
role: &ProjectRole{Key: "Key", DisplayName: "DisplayName", Group: "Group"},
|
||||||
|
event: &es_models.Event{},
|
||||||
|
},
|
||||||
|
result: &Project{Roles: []*ProjectRole{&ProjectRole{Key: "Key", DisplayName: "DisplayName", Group: "Group"}}},
|
||||||
|
},
|
||||||
|
}
|
||||||
|
for _, tt := range tests {
|
||||||
|
t.Run(tt.name, func(t *testing.T) {
|
||||||
|
if tt.args.role != nil {
|
||||||
|
data, _ := json.Marshal(tt.args.role)
|
||||||
|
tt.args.event.Data = data
|
||||||
|
}
|
||||||
|
tt.args.project.appendAddRoleEvent(tt.args.event)
|
||||||
|
if len(tt.args.project.Roles) != 1 {
|
||||||
|
t.Errorf("got wrong result should have one role actual: %v ", len(tt.args.project.Roles))
|
||||||
|
}
|
||||||
|
if tt.args.project.Roles[0] == tt.result.Roles[0] {
|
||||||
|
t.Errorf("got wrong result: expected: %v, actual: %v ", tt.result.Roles[0], tt.args.project.Roles[0])
|
||||||
|
}
|
||||||
|
})
|
||||||
|
}
|
||||||
|
}
|
||||||
|
|
||||||
|
func TestAppendChangeRoleEvent(t *testing.T) {
|
||||||
|
type args struct {
|
||||||
|
project *Project
|
||||||
|
role *ProjectRole
|
||||||
|
event *es_models.Event
|
||||||
|
}
|
||||||
|
tests := []struct {
|
||||||
|
name string
|
||||||
|
args args
|
||||||
|
result *Project
|
||||||
|
}{
|
||||||
|
{
|
||||||
|
name: "append change role event",
|
||||||
|
args: args{
|
||||||
|
project: &Project{Roles: []*ProjectRole{&ProjectRole{Key: "Key", DisplayName: "DisplayName", Group: "Group"}}},
|
||||||
|
role: &ProjectRole{Key: "Key", DisplayName: "DisplayNameChanged", Group: "Group"},
|
||||||
|
event: &es_models.Event{},
|
||||||
|
},
|
||||||
|
result: &Project{Roles: []*ProjectRole{&ProjectRole{Key: "Key", DisplayName: "DisplayNameChanged", Group: "Group"}}},
|
||||||
|
},
|
||||||
|
}
|
||||||
|
for _, tt := range tests {
|
||||||
|
t.Run(tt.name, func(t *testing.T) {
|
||||||
|
if tt.args.role != nil {
|
||||||
|
data, _ := json.Marshal(tt.args.role)
|
||||||
|
tt.args.event.Data = data
|
||||||
|
}
|
||||||
|
tt.args.project.appendChangeRoleEvent(tt.args.event)
|
||||||
|
if len(tt.args.project.Roles) != 1 {
|
||||||
|
t.Errorf("got wrong result should have one role actual: %v ", len(tt.args.project.Roles))
|
||||||
|
}
|
||||||
|
if tt.args.project.Roles[0] == tt.result.Roles[0] {
|
||||||
|
t.Errorf("got wrong result: expected: %v, actual: %v ", tt.result.Roles[0], tt.args.project.Roles[0])
|
||||||
|
}
|
||||||
|
})
|
||||||
|
}
|
||||||
|
}
|
||||||
|
|
||||||
|
func TestAppendRemoveRoleEvent(t *testing.T) {
|
||||||
|
type args struct {
|
||||||
|
project *Project
|
||||||
|
role *ProjectRole
|
||||||
|
event *es_models.Event
|
||||||
|
}
|
||||||
|
tests := []struct {
|
||||||
|
name string
|
||||||
|
args args
|
||||||
|
result *Project
|
||||||
|
}{
|
||||||
|
{
|
||||||
|
name: "append remove role event",
|
||||||
|
args: args{
|
||||||
|
project: &Project{Roles: []*ProjectRole{&ProjectRole{Key: "Key", DisplayName: "DisplayName", Group: "Group"}}},
|
||||||
|
role: &ProjectRole{Key: "Key"},
|
||||||
|
event: &es_models.Event{},
|
||||||
|
},
|
||||||
|
result: &Project{Roles: []*ProjectRole{}},
|
||||||
|
},
|
||||||
|
}
|
||||||
|
for _, tt := range tests {
|
||||||
|
t.Run(tt.name, func(t *testing.T) {
|
||||||
|
if tt.args.role != nil {
|
||||||
|
data, _ := json.Marshal(tt.args.role)
|
||||||
|
tt.args.event.Data = data
|
||||||
|
}
|
||||||
|
tt.args.project.appendRemoveRoleEvent(tt.args.event)
|
||||||
|
if len(tt.args.project.Roles) != 0 {
|
||||||
|
t.Errorf("got wrong result should have no role actual: %v ", len(tt.args.project.Roles))
|
||||||
|
}
|
||||||
|
})
|
||||||
|
}
|
||||||
|
}
|
||||||
|
|
||||||
|
func TestAppendAddAppEvent(t *testing.T) {
|
||||||
|
type args struct {
|
||||||
|
project *Project
|
||||||
|
app *Application
|
||||||
|
event *es_models.Event
|
||||||
|
}
|
||||||
|
tests := []struct {
|
||||||
|
name string
|
||||||
|
args args
|
||||||
|
result *Project
|
||||||
|
}{
|
||||||
|
{
|
||||||
|
name: "append add application event",
|
||||||
|
args: args{
|
||||||
|
project: &Project{},
|
||||||
|
app: &Application{Name: "Application"},
|
||||||
|
event: &es_models.Event{},
|
||||||
|
},
|
||||||
|
result: &Project{Applications: []*Application{&Application{Name: "Application"}}},
|
||||||
|
},
|
||||||
|
}
|
||||||
|
for _, tt := range tests {
|
||||||
|
t.Run(tt.name, func(t *testing.T) {
|
||||||
|
if tt.args.app != nil {
|
||||||
|
data, _ := json.Marshal(tt.args.app)
|
||||||
|
tt.args.event.Data = data
|
||||||
|
}
|
||||||
|
tt.args.project.appendAddAppEvent(tt.args.event)
|
||||||
|
if len(tt.args.project.Applications) != 1 {
|
||||||
|
t.Errorf("got wrong result should have one app actual: %v ", len(tt.args.project.Applications))
|
||||||
|
}
|
||||||
|
if tt.args.project.Applications[0] == tt.result.Applications[0] {
|
||||||
|
t.Errorf("got wrong result: expected: %v, actual: %v ", tt.result.Applications[0], tt.args.project.Applications[0])
|
||||||
|
}
|
||||||
|
})
|
||||||
|
}
|
||||||
|
}
|
||||||
|
|
||||||
|
func TestAppendChangeAppEvent(t *testing.T) {
|
||||||
|
type args struct {
|
||||||
|
project *Project
|
||||||
|
app *Application
|
||||||
|
event *es_models.Event
|
||||||
|
}
|
||||||
|
tests := []struct {
|
||||||
|
name string
|
||||||
|
args args
|
||||||
|
result *Project
|
||||||
|
}{
|
||||||
|
{
|
||||||
|
name: "append change application event",
|
||||||
|
args: args{
|
||||||
|
project: &Project{Applications: []*Application{&Application{Name: "Application"}}},
|
||||||
|
app: &Application{Name: "Application Change"},
|
||||||
|
event: &es_models.Event{},
|
||||||
|
},
|
||||||
|
result: &Project{Applications: []*Application{&Application{Name: "Application Change"}}},
|
||||||
|
},
|
||||||
|
}
|
||||||
|
for _, tt := range tests {
|
||||||
|
t.Run(tt.name, func(t *testing.T) {
|
||||||
|
if tt.args.app != nil {
|
||||||
|
data, _ := json.Marshal(tt.args.app)
|
||||||
|
tt.args.event.Data = data
|
||||||
|
}
|
||||||
|
tt.args.project.appendChangeAppEvent(tt.args.event)
|
||||||
|
if len(tt.args.project.Applications) != 1 {
|
||||||
|
t.Errorf("got wrong result should have one app actual: %v ", len(tt.args.project.Applications))
|
||||||
|
}
|
||||||
|
if tt.args.project.Applications[0] == tt.result.Applications[0] {
|
||||||
|
t.Errorf("got wrong result: expected: %v, actual: %v ", tt.result.Applications[0], tt.args.project.Applications[0])
|
||||||
|
}
|
||||||
|
})
|
||||||
|
}
|
||||||
|
}
|
||||||
|
|
||||||
|
func TestAppendRemoveAppEvent(t *testing.T) {
|
||||||
|
type args struct {
|
||||||
|
project *Project
|
||||||
|
app *Application
|
||||||
|
event *es_models.Event
|
||||||
|
}
|
||||||
|
tests := []struct {
|
||||||
|
name string
|
||||||
|
args args
|
||||||
|
result *Project
|
||||||
|
}{
|
||||||
|
{
|
||||||
|
name: "append remove application event",
|
||||||
|
args: args{
|
||||||
|
project: &Project{Applications: []*Application{&Application{AppID: "AppID", Name: "Application"}}},
|
||||||
|
app: &Application{AppID: "AppID", Name: "Application"},
|
||||||
|
event: &es_models.Event{},
|
||||||
|
},
|
||||||
|
result: &Project{Applications: []*Application{}},
|
||||||
|
},
|
||||||
|
}
|
||||||
|
for _, tt := range tests {
|
||||||
|
t.Run(tt.name, func(t *testing.T) {
|
||||||
|
if tt.args.app != nil {
|
||||||
|
data, _ := json.Marshal(tt.args.app)
|
||||||
|
tt.args.event.Data = data
|
||||||
|
}
|
||||||
|
tt.args.project.appendRemoveAppEvent(tt.args.event)
|
||||||
|
if len(tt.args.project.Applications) != 0 {
|
||||||
|
t.Errorf("got wrong result should have no apps actual: %v ", len(tt.args.project.Applications))
|
||||||
|
}
|
||||||
|
})
|
||||||
|
}
|
||||||
|
}
|
||||||
|
|
||||||
|
func TestAppendAppStateEvent(t *testing.T) {
|
||||||
|
type args struct {
|
||||||
|
project *Project
|
||||||
|
app *ApplicationID
|
||||||
|
event *es_models.Event
|
||||||
|
state model.AppState
|
||||||
|
}
|
||||||
|
tests := []struct {
|
||||||
|
name string
|
||||||
|
args args
|
||||||
|
result *Project
|
||||||
|
}{
|
||||||
|
{
|
||||||
|
name: "append deactivate application event",
|
||||||
|
args: args{
|
||||||
|
project: &Project{Applications: []*Application{&Application{AppID: "AppID", Name: "Application", State: int32(model.APPSTATE_ACTIVE)}}},
|
||||||
|
app: &ApplicationID{AppID: "AppID"},
|
||||||
|
event: &es_models.Event{},
|
||||||
|
state: model.APPSTATE_INACTIVE,
|
||||||
|
},
|
||||||
|
result: &Project{Applications: []*Application{&Application{AppID: "AppID", Name: "Application", State: int32(model.APPSTATE_INACTIVE)}}},
|
||||||
|
},
|
||||||
|
{
|
||||||
|
name: "append reactivate application event",
|
||||||
|
args: args{
|
||||||
|
project: &Project{Applications: []*Application{&Application{AppID: "AppID", Name: "Application", State: int32(model.APPSTATE_INACTIVE)}}},
|
||||||
|
app: &ApplicationID{AppID: "AppID"},
|
||||||
|
event: &es_models.Event{},
|
||||||
|
state: model.APPSTATE_ACTIVE,
|
||||||
|
},
|
||||||
|
result: &Project{Applications: []*Application{&Application{AppID: "AppID", Name: "Application", State: int32(model.APPSTATE_ACTIVE)}}},
|
||||||
|
},
|
||||||
|
}
|
||||||
|
for _, tt := range tests {
|
||||||
|
t.Run(tt.name, func(t *testing.T) {
|
||||||
|
if tt.args.app != nil {
|
||||||
|
data, _ := json.Marshal(tt.args.app)
|
||||||
|
tt.args.event.Data = data
|
||||||
|
}
|
||||||
|
tt.args.project.appendAppStateEvent(tt.args.event, tt.args.state)
|
||||||
|
if len(tt.args.project.Applications) != 1 {
|
||||||
|
t.Errorf("got wrong result should have one app actual: %v ", len(tt.args.project.Applications))
|
||||||
|
}
|
||||||
|
if tt.args.project.Applications[0] == tt.result.Applications[0] {
|
||||||
|
t.Errorf("got wrong result: expected: %v, actual: %v ", tt.result.Applications[0], tt.args.project.Applications[0])
|
||||||
|
}
|
||||||
|
})
|
||||||
|
}
|
||||||
|
}
|
||||||
|
|
||||||
|
func TestAppendAddOIDCConfigEvent(t *testing.T) {
|
||||||
|
type args struct {
|
||||||
|
project *Project
|
||||||
|
config *OIDCConfig
|
||||||
|
event *es_models.Event
|
||||||
|
}
|
||||||
|
tests := []struct {
|
||||||
|
name string
|
||||||
|
args args
|
||||||
|
result *Project
|
||||||
|
}{
|
||||||
|
{
|
||||||
|
name: "append add application event",
|
||||||
|
args: args{
|
||||||
|
project: &Project{Applications: []*Application{&Application{AppID: "AppID"}}},
|
||||||
|
config: &OIDCConfig{AppID: "AppID", ClientID: "ClientID"},
|
||||||
|
event: &es_models.Event{},
|
||||||
|
},
|
||||||
|
result: &Project{Applications: []*Application{&Application{AppID: "AppID", OIDCConfig: &OIDCConfig{AppID: "AppID", ClientID: "ClientID"}}}},
|
||||||
|
},
|
||||||
|
}
|
||||||
|
for _, tt := range tests {
|
||||||
|
t.Run(tt.name, func(t *testing.T) {
|
||||||
|
if tt.args.config != nil {
|
||||||
|
data, _ := json.Marshal(tt.args.config)
|
||||||
|
tt.args.event.Data = data
|
||||||
|
}
|
||||||
|
tt.args.project.appendAddOIDCConfigEvent(tt.args.event)
|
||||||
|
if len(tt.args.project.Applications) != 1 {
|
||||||
|
t.Errorf("got wrong result should have one app actual: %v ", len(tt.args.project.Applications))
|
||||||
|
}
|
||||||
|
if tt.args.project.Applications[0].OIDCConfig == nil {
|
||||||
|
t.Errorf("got wrong result should have oidc config actual: %v ", tt.args.project.Applications[0].OIDCConfig)
|
||||||
|
}
|
||||||
|
if tt.args.project.Applications[0] == tt.result.Applications[0] {
|
||||||
|
t.Errorf("got wrong result: expected: %v, actual: %v ", tt.result.Applications[0], tt.args.project.Applications[0])
|
||||||
|
}
|
||||||
|
})
|
||||||
|
}
|
||||||
|
}
|
||||||
|
|
||||||
|
func TestAppendChangeOIDCConfigEvent(t *testing.T) {
|
||||||
|
type args struct {
|
||||||
|
project *Project
|
||||||
|
config *OIDCConfig
|
||||||
|
event *es_models.Event
|
||||||
|
}
|
||||||
|
tests := []struct {
|
||||||
|
name string
|
||||||
|
args args
|
||||||
|
result *Project
|
||||||
|
}{
|
||||||
|
{
|
||||||
|
name: "append change application event",
|
||||||
|
args: args{
|
||||||
|
project: &Project{Applications: []*Application{&Application{AppID: "AppID", OIDCConfig: &OIDCConfig{AppID: "AppID", ClientID: "ClientID"}}}},
|
||||||
|
config: &OIDCConfig{AppID: "AppID", ClientID: "ClientID Changed"},
|
||||||
|
event: &es_models.Event{},
|
||||||
|
},
|
||||||
|
result: &Project{Applications: []*Application{&Application{AppID: "AppID", OIDCConfig: &OIDCConfig{AppID: "AppID", ClientID: "ClientID Changed"}}}},
|
||||||
|
},
|
||||||
|
}
|
||||||
|
for _, tt := range tests {
|
||||||
|
t.Run(tt.name, func(t *testing.T) {
|
||||||
|
if tt.args.config != nil {
|
||||||
|
data, _ := json.Marshal(tt.args.config)
|
||||||
|
tt.args.event.Data = data
|
||||||
|
}
|
||||||
|
tt.args.project.appendChangeOIDCConfigEvent(tt.args.event)
|
||||||
|
if len(tt.args.project.Applications) != 1 {
|
||||||
|
t.Errorf("got wrong result should have one app actual: %v ", len(tt.args.project.Applications))
|
||||||
|
}
|
||||||
|
if tt.args.project.Applications[0].OIDCConfig == nil {
|
||||||
|
t.Errorf("got wrong result should have oidc config actual: %v ", tt.args.project.Applications[0].OIDCConfig)
|
||||||
|
}
|
||||||
|
if tt.args.project.Applications[0] == tt.result.Applications[0] {
|
||||||
|
t.Errorf("got wrong result: expected: %v, actual: %v ", tt.result.Applications[0], tt.args.project.Applications[0])
|
||||||
}
|
}
|
||||||
})
|
})
|
||||||
}
|
}
|
||||||
|
30
internal/project/repository/eventsourcing/oidc.go
Normal file
30
internal/project/repository/eventsourcing/oidc.go
Normal file
@ -0,0 +1,30 @@
|
|||||||
|
package eventsourcing
|
||||||
|
|
||||||
|
import (
|
||||||
|
"fmt"
|
||||||
|
"github.com/caos/logging"
|
||||||
|
"github.com/caos/zitadel/internal/crypto"
|
||||||
|
"github.com/caos/zitadel/internal/errors"
|
||||||
|
"github.com/caos/zitadel/internal/project/model"
|
||||||
|
"github.com/sony/sonyflake"
|
||||||
|
"strings"
|
||||||
|
)
|
||||||
|
|
||||||
|
//ClientID random_number@projectname (eg. 495894098234@zitadel)
|
||||||
|
func generateNewClientID(idGenerator *sonyflake.Sonyflake, project *model.Project) (string, error) {
|
||||||
|
rndID, err := idGenerator.NextID()
|
||||||
|
if err != nil {
|
||||||
|
return "", err
|
||||||
|
}
|
||||||
|
|
||||||
|
return fmt.Sprintf("%v@%v", rndID, strings.ReplaceAll(strings.ToLower(project.Name), " ", "_")), nil
|
||||||
|
}
|
||||||
|
|
||||||
|
func generateNewClientSecret(pwGenerator crypto.Generator) (string, *crypto.CryptoValue, error) {
|
||||||
|
cryptoValue, stringSecret, err := crypto.NewCode(pwGenerator)
|
||||||
|
if err != nil {
|
||||||
|
logging.Log("APP-UpnTI").OnError(err).Error("unable to create client secret")
|
||||||
|
return "", nil, errors.ThrowInternal(err, "APP-gH2Wl", "unable to create password")
|
||||||
|
}
|
||||||
|
return stringSecret, cryptoValue, nil
|
||||||
|
}
|
@ -2,17 +2,13 @@ package eventsourcing
|
|||||||
|
|
||||||
import (
|
import (
|
||||||
"context"
|
"context"
|
||||||
"strconv"
|
"github.com/caos/zitadel/internal/crypto"
|
||||||
|
|
||||||
"github.com/caos/zitadel/internal/errors"
|
"github.com/caos/zitadel/internal/errors"
|
||||||
"github.com/caos/zitadel/internal/eventstore/models"
|
"github.com/caos/zitadel/internal/eventstore/models"
|
||||||
es_models "github.com/caos/zitadel/internal/eventstore/models"
|
es_models "github.com/caos/zitadel/internal/eventstore/models"
|
||||||
"github.com/caos/zitadel/internal/project/model"
|
"github.com/caos/zitadel/internal/project/model"
|
||||||
"github.com/sony/sonyflake"
|
|
||||||
)
|
)
|
||||||
|
|
||||||
var idGenerator = sonyflake.NewSonyflake(sonyflake.Settings{})
|
|
||||||
|
|
||||||
func ProjectByIDQuery(id string, latestSequence uint64) (*es_models.SearchQuery, error) {
|
func ProjectByIDQuery(id string, latestSequence uint64) (*es_models.SearchQuery, error) {
|
||||||
if id == "" {
|
if id == "" {
|
||||||
return nil, errors.ThrowPreconditionFailed(nil, "EVENT-dke74", "id should be filled")
|
return nil, errors.ThrowPreconditionFailed(nil, "EVENT-dke74", "id should be filled")
|
||||||
@ -27,8 +23,11 @@ func ProjectQuery(latestSequence uint64) *es_models.SearchQuery {
|
|||||||
LatestSequenceFilter(latestSequence)
|
LatestSequenceFilter(latestSequence)
|
||||||
}
|
}
|
||||||
|
|
||||||
func ProjectAggregate(ctx context.Context, aggCreator *es_models.AggregateCreator, id string, sequence uint64) (*es_models.Aggregate, error) {
|
func ProjectAggregate(ctx context.Context, aggCreator *es_models.AggregateCreator, project *Project) (*es_models.Aggregate, error) {
|
||||||
return aggCreator.NewAggregate(ctx, id, model.ProjectAggregate, projectVersion, sequence)
|
if project == nil {
|
||||||
|
return nil, errors.ThrowPreconditionFailed(nil, "EVENT-doe93", "existing project should not be nil")
|
||||||
|
}
|
||||||
|
return aggCreator.NewAggregate(ctx, project.AggregateID, model.ProjectAggregate, projectVersion, project.Sequence)
|
||||||
}
|
}
|
||||||
|
|
||||||
func ProjectCreateAggregate(aggCreator *es_models.AggregateCreator, project *Project) func(ctx context.Context) (*es_models.Aggregate, error) {
|
func ProjectCreateAggregate(aggCreator *es_models.AggregateCreator, project *Project) func(ctx context.Context) (*es_models.Aggregate, error) {
|
||||||
@ -36,14 +35,8 @@ func ProjectCreateAggregate(aggCreator *es_models.AggregateCreator, project *Pro
|
|||||||
if project == nil {
|
if project == nil {
|
||||||
return nil, errors.ThrowPreconditionFailed(nil, "EVENT-kdie6", "project should not be nil")
|
return nil, errors.ThrowPreconditionFailed(nil, "EVENT-kdie6", "project should not be nil")
|
||||||
}
|
}
|
||||||
var err error
|
|
||||||
id, err := idGenerator.NextID()
|
|
||||||
if err != nil {
|
|
||||||
return nil, err
|
|
||||||
}
|
|
||||||
project.ID = strconv.FormatUint(id, 10)
|
|
||||||
|
|
||||||
agg, err := ProjectAggregate(ctx, aggCreator, project.ID, project.Sequence)
|
agg, err := ProjectAggregate(ctx, aggCreator, project)
|
||||||
if err != nil {
|
if err != nil {
|
||||||
return nil, err
|
return nil, err
|
||||||
}
|
}
|
||||||
@ -54,13 +47,10 @@ func ProjectCreateAggregate(aggCreator *es_models.AggregateCreator, project *Pro
|
|||||||
|
|
||||||
func ProjectUpdateAggregate(aggCreator *es_models.AggregateCreator, existing *Project, new *Project) func(ctx context.Context) (*es_models.Aggregate, error) {
|
func ProjectUpdateAggregate(aggCreator *es_models.AggregateCreator, existing *Project, new *Project) func(ctx context.Context) (*es_models.Aggregate, error) {
|
||||||
return func(ctx context.Context) (*es_models.Aggregate, error) {
|
return func(ctx context.Context) (*es_models.Aggregate, error) {
|
||||||
if existing == nil {
|
|
||||||
return nil, errors.ThrowPreconditionFailed(nil, "EVENT-dk93d", "existing project should not be nil")
|
|
||||||
}
|
|
||||||
if new == nil {
|
if new == nil {
|
||||||
return nil, errors.ThrowPreconditionFailed(nil, "EVENT-dhr74", "new project should not be nil")
|
return nil, errors.ThrowPreconditionFailed(nil, "EVENT-dhr74", "new project should not be nil")
|
||||||
}
|
}
|
||||||
agg, err := ProjectAggregate(ctx, aggCreator, existing.ID, existing.Sequence)
|
agg, err := ProjectAggregate(ctx, aggCreator, existing)
|
||||||
if err != nil {
|
if err != nil {
|
||||||
return nil, err
|
return nil, err
|
||||||
}
|
}
|
||||||
@ -79,10 +69,7 @@ func ProjectReactivateAggregate(aggCreator *es_models.AggregateCreator, project
|
|||||||
|
|
||||||
func projectStateAggregate(aggCreator *es_models.AggregateCreator, project *Project, state models.EventType) func(ctx context.Context) (*es_models.Aggregate, error) {
|
func projectStateAggregate(aggCreator *es_models.AggregateCreator, project *Project, state models.EventType) func(ctx context.Context) (*es_models.Aggregate, error) {
|
||||||
return func(ctx context.Context) (*es_models.Aggregate, error) {
|
return func(ctx context.Context) (*es_models.Aggregate, error) {
|
||||||
if project == nil {
|
agg, err := ProjectAggregate(ctx, aggCreator, project)
|
||||||
return nil, errors.ThrowPreconditionFailed(nil, "EVENT-37dur", "existing project should not be nil")
|
|
||||||
}
|
|
||||||
agg, err := ProjectAggregate(ctx, aggCreator, project.ID, project.Sequence)
|
|
||||||
if err != nil {
|
if err != nil {
|
||||||
return nil, err
|
return nil, err
|
||||||
}
|
}
|
||||||
@ -92,10 +79,10 @@ func projectStateAggregate(aggCreator *es_models.AggregateCreator, project *Proj
|
|||||||
|
|
||||||
func ProjectMemberAddedAggregate(aggCreator *es_models.AggregateCreator, existing *Project, member *ProjectMember) func(ctx context.Context) (*es_models.Aggregate, error) {
|
func ProjectMemberAddedAggregate(aggCreator *es_models.AggregateCreator, existing *Project, member *ProjectMember) func(ctx context.Context) (*es_models.Aggregate, error) {
|
||||||
return func(ctx context.Context) (*es_models.Aggregate, error) {
|
return func(ctx context.Context) (*es_models.Aggregate, error) {
|
||||||
if existing == nil {
|
if member == nil {
|
||||||
return nil, errors.ThrowPreconditionFailed(nil, "EVENT-di38f", "existing project should not be nil")
|
return nil, errors.ThrowPreconditionFailed(nil, "EVENT-ie34f", "member should not be nil")
|
||||||
}
|
}
|
||||||
agg, err := ProjectAggregate(ctx, aggCreator, existing.ID, existing.Sequence)
|
agg, err := ProjectAggregate(ctx, aggCreator, existing)
|
||||||
if err != nil {
|
if err != nil {
|
||||||
return nil, err
|
return nil, err
|
||||||
}
|
}
|
||||||
@ -105,11 +92,11 @@ func ProjectMemberAddedAggregate(aggCreator *es_models.AggregateCreator, existin
|
|||||||
|
|
||||||
func ProjectMemberChangedAggregate(aggCreator *es_models.AggregateCreator, existing *Project, member *ProjectMember) func(ctx context.Context) (*es_models.Aggregate, error) {
|
func ProjectMemberChangedAggregate(aggCreator *es_models.AggregateCreator, existing *Project, member *ProjectMember) func(ctx context.Context) (*es_models.Aggregate, error) {
|
||||||
return func(ctx context.Context) (*es_models.Aggregate, error) {
|
return func(ctx context.Context) (*es_models.Aggregate, error) {
|
||||||
if existing == nil {
|
if member == nil {
|
||||||
return nil, errors.ThrowPreconditionFailed(nil, "EVENT-sle3d", "existing project should not be nil")
|
return nil, errors.ThrowPreconditionFailed(nil, "EVENT-d34fs", "member should not be nil")
|
||||||
}
|
}
|
||||||
|
|
||||||
agg, err := ProjectAggregate(ctx, aggCreator, existing.ID, existing.Sequence)
|
agg, err := ProjectAggregate(ctx, aggCreator, existing)
|
||||||
if err != nil {
|
if err != nil {
|
||||||
return nil, err
|
return nil, err
|
||||||
}
|
}
|
||||||
@ -119,13 +106,174 @@ func ProjectMemberChangedAggregate(aggCreator *es_models.AggregateCreator, exist
|
|||||||
|
|
||||||
func ProjectMemberRemovedAggregate(aggCreator *es_models.AggregateCreator, existing *Project, member *ProjectMember) func(ctx context.Context) (*es_models.Aggregate, error) {
|
func ProjectMemberRemovedAggregate(aggCreator *es_models.AggregateCreator, existing *Project, member *ProjectMember) func(ctx context.Context) (*es_models.Aggregate, error) {
|
||||||
return func(ctx context.Context) (*es_models.Aggregate, error) {
|
return func(ctx context.Context) (*es_models.Aggregate, error) {
|
||||||
if existing == nil {
|
if member == nil {
|
||||||
return nil, errors.ThrowPreconditionFailed(nil, "EVENT-slo9e", "existing project should not be nil")
|
return nil, errors.ThrowPreconditionFailed(nil, "EVENT-dieu7", "member should not be nil")
|
||||||
}
|
}
|
||||||
agg, err := ProjectAggregate(ctx, aggCreator, existing.ID, existing.Sequence)
|
agg, err := ProjectAggregate(ctx, aggCreator, existing)
|
||||||
if err != nil {
|
if err != nil {
|
||||||
return nil, err
|
return nil, err
|
||||||
}
|
}
|
||||||
return agg.AppendEvent(model.ProjectMemberRemoved, member)
|
return agg.AppendEvent(model.ProjectMemberRemoved, member)
|
||||||
}
|
}
|
||||||
}
|
}
|
||||||
|
|
||||||
|
func ProjectRoleAddedAggregate(aggCreator *es_models.AggregateCreator, existing *Project, role *ProjectRole) func(ctx context.Context) (*es_models.Aggregate, error) {
|
||||||
|
return func(ctx context.Context) (*es_models.Aggregate, error) {
|
||||||
|
if role == nil {
|
||||||
|
return nil, errors.ThrowPreconditionFailed(nil, "EVENT-sleo9", "role should not be nil")
|
||||||
|
}
|
||||||
|
agg, err := ProjectAggregate(ctx, aggCreator, existing)
|
||||||
|
if err != nil {
|
||||||
|
return nil, err
|
||||||
|
}
|
||||||
|
return agg.AppendEvent(model.ProjectRoleAdded, role)
|
||||||
|
}
|
||||||
|
}
|
||||||
|
|
||||||
|
func ProjectRoleChangedAggregate(aggCreator *es_models.AggregateCreator, existing *Project, role *ProjectRole) func(ctx context.Context) (*es_models.Aggregate, error) {
|
||||||
|
return func(ctx context.Context) (*es_models.Aggregate, error) {
|
||||||
|
if role == nil {
|
||||||
|
return nil, errors.ThrowPreconditionFailed(nil, "EVENT-oe8sf", "member should not be nil")
|
||||||
|
}
|
||||||
|
agg, err := ProjectAggregate(ctx, aggCreator, existing)
|
||||||
|
if err != nil {
|
||||||
|
return nil, err
|
||||||
|
}
|
||||||
|
return agg.AppendEvent(model.ProjectRoleChanged, role)
|
||||||
|
}
|
||||||
|
}
|
||||||
|
|
||||||
|
func ProjectRoleRemovedAggregate(aggCreator *es_models.AggregateCreator, existing *Project, role *ProjectRole) func(ctx context.Context) (*es_models.Aggregate, error) {
|
||||||
|
return func(ctx context.Context) (*es_models.Aggregate, error) {
|
||||||
|
if role == nil {
|
||||||
|
return nil, errors.ThrowPreconditionFailed(nil, "EVENT-d8eis", "member should not be nil")
|
||||||
|
}
|
||||||
|
agg, err := ProjectAggregate(ctx, aggCreator, existing)
|
||||||
|
if err != nil {
|
||||||
|
return nil, err
|
||||||
|
}
|
||||||
|
return agg.AppendEvent(model.ProjectRoleRemoved, role)
|
||||||
|
}
|
||||||
|
}
|
||||||
|
|
||||||
|
func ApplicationAddedAggregate(aggCreator *es_models.AggregateCreator, existing *Project, app *Application) func(ctx context.Context) (*es_models.Aggregate, error) {
|
||||||
|
return func(ctx context.Context) (*es_models.Aggregate, error) {
|
||||||
|
if app == nil {
|
||||||
|
return nil, errors.ThrowPreconditionFailed(nil, "EVENT-09du7", "app should not be nil")
|
||||||
|
}
|
||||||
|
agg, err := ProjectAggregate(ctx, aggCreator, existing)
|
||||||
|
if err != nil {
|
||||||
|
return nil, err
|
||||||
|
}
|
||||||
|
agg.AppendEvent(model.ApplicationAdded, app)
|
||||||
|
if app.OIDCConfig != nil {
|
||||||
|
agg.AppendEvent(model.OIDCConfigAdded, app.OIDCConfig)
|
||||||
|
}
|
||||||
|
return agg, nil
|
||||||
|
}
|
||||||
|
}
|
||||||
|
|
||||||
|
func ApplicationChangedAggregate(aggCreator *es_models.AggregateCreator, existing *Project, app *Application) func(ctx context.Context) (*es_models.Aggregate, error) {
|
||||||
|
return func(ctx context.Context) (*es_models.Aggregate, error) {
|
||||||
|
if app == nil {
|
||||||
|
return nil, errors.ThrowPreconditionFailed(nil, "EVENT-sleo9", "app should not be nil")
|
||||||
|
}
|
||||||
|
agg, err := ProjectAggregate(ctx, aggCreator, existing)
|
||||||
|
if err != nil {
|
||||||
|
return nil, err
|
||||||
|
}
|
||||||
|
var changes map[string]interface{}
|
||||||
|
for _, a := range existing.Applications {
|
||||||
|
if a.AppID == app.AppID {
|
||||||
|
changes = a.Changes(app)
|
||||||
|
}
|
||||||
|
}
|
||||||
|
agg.AppendEvent(model.ApplicationChanged, changes)
|
||||||
|
|
||||||
|
return agg, nil
|
||||||
|
}
|
||||||
|
}
|
||||||
|
|
||||||
|
func ApplicationRemovedAggregate(aggCreator *es_models.AggregateCreator, existing *Project, app *Application) func(ctx context.Context) (*es_models.Aggregate, error) {
|
||||||
|
return func(ctx context.Context) (*es_models.Aggregate, error) {
|
||||||
|
if app == nil {
|
||||||
|
return nil, errors.ThrowPreconditionFailed(nil, "EVENT-se23g", "app should not be nil")
|
||||||
|
}
|
||||||
|
agg, err := ProjectAggregate(ctx, aggCreator, existing)
|
||||||
|
if err != nil {
|
||||||
|
return nil, err
|
||||||
|
}
|
||||||
|
agg.AppendEvent(model.ApplicationRemoved, &ApplicationID{AppID: app.AppID})
|
||||||
|
|
||||||
|
return agg, nil
|
||||||
|
}
|
||||||
|
}
|
||||||
|
|
||||||
|
func ApplicationDeactivatedAggregate(aggCreator *es_models.AggregateCreator, existing *Project, app *Application) func(ctx context.Context) (*es_models.Aggregate, error) {
|
||||||
|
return func(ctx context.Context) (*es_models.Aggregate, error) {
|
||||||
|
if app == nil {
|
||||||
|
return nil, errors.ThrowPreconditionFailed(nil, "EVENT-slfi3", "app should not be nil")
|
||||||
|
}
|
||||||
|
agg, err := ProjectAggregate(ctx, aggCreator, existing)
|
||||||
|
if err != nil {
|
||||||
|
return nil, err
|
||||||
|
}
|
||||||
|
agg.AppendEvent(model.ApplicationDeactivated, &ApplicationID{AppID: app.AppID})
|
||||||
|
|
||||||
|
return agg, nil
|
||||||
|
}
|
||||||
|
}
|
||||||
|
|
||||||
|
func ApplicationReactivatedAggregate(aggCreator *es_models.AggregateCreator, existing *Project, app *Application) func(ctx context.Context) (*es_models.Aggregate, error) {
|
||||||
|
return func(ctx context.Context) (*es_models.Aggregate, error) {
|
||||||
|
if app == nil {
|
||||||
|
return nil, errors.ThrowPreconditionFailed(nil, "EVENT-slf32", "app should not be nil")
|
||||||
|
}
|
||||||
|
agg, err := ProjectAggregate(ctx, aggCreator, existing)
|
||||||
|
if err != nil {
|
||||||
|
return nil, err
|
||||||
|
}
|
||||||
|
agg.AppendEvent(model.ApplicationReactivated, &ApplicationID{AppID: app.AppID})
|
||||||
|
|
||||||
|
return agg, nil
|
||||||
|
}
|
||||||
|
}
|
||||||
|
|
||||||
|
func OIDCConfigChangedAggregate(aggCreator *es_models.AggregateCreator, existing *Project, config *OIDCConfig) func(ctx context.Context) (*es_models.Aggregate, error) {
|
||||||
|
return func(ctx context.Context) (*es_models.Aggregate, error) {
|
||||||
|
if config == nil {
|
||||||
|
return nil, errors.ThrowPreconditionFailed(nil, "EVENT-slf32", "config should not be nil")
|
||||||
|
}
|
||||||
|
agg, err := ProjectAggregate(ctx, aggCreator, existing)
|
||||||
|
if err != nil {
|
||||||
|
return nil, err
|
||||||
|
}
|
||||||
|
var changes map[string]interface{}
|
||||||
|
for _, a := range existing.Applications {
|
||||||
|
if a.AppID == config.AppID {
|
||||||
|
if a.OIDCConfig != nil {
|
||||||
|
changes = a.OIDCConfig.Changes(config)
|
||||||
|
}
|
||||||
|
}
|
||||||
|
}
|
||||||
|
agg.AppendEvent(model.OIDCConfigChanged, changes)
|
||||||
|
|
||||||
|
return agg, nil
|
||||||
|
}
|
||||||
|
}
|
||||||
|
|
||||||
|
func OIDCConfigSecretChangedAggregate(aggCreator *es_models.AggregateCreator, existing *Project, appID string, secret *crypto.CryptoValue) func(ctx context.Context) (*es_models.Aggregate, error) {
|
||||||
|
return func(ctx context.Context) (*es_models.Aggregate, error) {
|
||||||
|
agg, err := ProjectAggregate(ctx, aggCreator, existing)
|
||||||
|
if err != nil {
|
||||||
|
return nil, err
|
||||||
|
}
|
||||||
|
changes := make(map[string]interface{}, 1)
|
||||||
|
changes["appId"] = appID
|
||||||
|
changes["clientSecret"] = secret
|
||||||
|
|
||||||
|
agg.AppendEvent(model.OIDCConfigSecretChanged, changes)
|
||||||
|
|
||||||
|
return agg, nil
|
||||||
|
}
|
||||||
|
}
|
||||||
|
File diff suppressed because it is too large
Load Diff
@ -8,7 +8,7 @@ import (
|
|||||||
|
|
||||||
func Test_ToPBStruct(t *testing.T) {
|
func Test_ToPBStruct(t *testing.T) {
|
||||||
type obj struct {
|
type obj struct {
|
||||||
ID string
|
AggregateID string
|
||||||
Seq uint64
|
Seq uint64
|
||||||
}
|
}
|
||||||
type args struct {
|
type args struct {
|
||||||
@ -24,11 +24,11 @@ func Test_ToPBStruct(t *testing.T) {
|
|||||||
{
|
{
|
||||||
name: "to pb stuct",
|
name: "to pb stuct",
|
||||||
args: args{
|
args: args{
|
||||||
obj: obj{ID: "ID", Seq: 12345},
|
obj: obj{AggregateID: "AggregateID", Seq: 12345},
|
||||||
},
|
},
|
||||||
wantErr: false,
|
wantErr: false,
|
||||||
length: 2,
|
length: 2,
|
||||||
result: obj{ID: "ID", Seq: 12345},
|
result: obj{AggregateID: "AggregateID", Seq: 12345},
|
||||||
},
|
},
|
||||||
{
|
{
|
||||||
name: "empty struct",
|
name: "empty struct",
|
||||||
@ -37,7 +37,7 @@ func Test_ToPBStruct(t *testing.T) {
|
|||||||
},
|
},
|
||||||
wantErr: false,
|
wantErr: false,
|
||||||
length: 2,
|
length: 2,
|
||||||
result: obj{ID: "", Seq: 0},
|
result: obj{AggregateID: "", Seq: 0},
|
||||||
},
|
},
|
||||||
}
|
}
|
||||||
for _, tt := range tests {
|
for _, tt := range tests {
|
||||||
@ -49,8 +49,8 @@ func Test_ToPBStruct(t *testing.T) {
|
|||||||
if !tt.wantErr && len(fields.Fields) != tt.length {
|
if !tt.wantErr && len(fields.Fields) != tt.length {
|
||||||
t.Errorf("got wrong result length, expecting: %v, actual: %v ", tt.length, len(fields.Fields))
|
t.Errorf("got wrong result length, expecting: %v, actual: %v ", tt.length, len(fields.Fields))
|
||||||
}
|
}
|
||||||
if !tt.wantErr && tt.result.ID != fields.Fields["ID"].GetStringValue() {
|
if !tt.wantErr && tt.result.AggregateID != fields.Fields["AggregateID"].GetStringValue() {
|
||||||
t.Errorf("got wrong result, ID should be same: expecting: %v, actual: %v ", tt.result.ID, fields.Fields["ID"].GetStringValue())
|
t.Errorf("got wrong result, AggregateID should be same: expecting: %v, actual: %v ", tt.result.AggregateID, fields.Fields["AggregateID"].GetStringValue())
|
||||||
}
|
}
|
||||||
if !tt.wantErr && int(tt.result.Seq) != int(fields.Fields["Seq"].GetNumberValue()) {
|
if !tt.wantErr && int(tt.result.Seq) != int(fields.Fields["Seq"].GetNumberValue()) {
|
||||||
t.Errorf("got wrong result, Seq should be same: expecting: %v, actual: %v ", tt.result.Seq, fields.Fields["Seq"].GetStringValue())
|
t.Errorf("got wrong result, Seq should be same: expecting: %v, actual: %v ", tt.result.Seq, fields.Fields["Seq"].GetStringValue())
|
||||||
@ -61,7 +61,7 @@ func Test_ToPBStruct(t *testing.T) {
|
|||||||
|
|
||||||
func Test_FromPBStruct(t *testing.T) {
|
func Test_FromPBStruct(t *testing.T) {
|
||||||
type obj struct {
|
type obj struct {
|
||||||
ID string
|
AggregateID string
|
||||||
Seq uint64
|
Seq uint64
|
||||||
}
|
}
|
||||||
type args struct {
|
type args struct {
|
||||||
@ -79,23 +79,22 @@ func Test_FromPBStruct(t *testing.T) {
|
|||||||
args: args{
|
args: args{
|
||||||
obj: &obj{},
|
obj: &obj{},
|
||||||
fields: &pb_struct.Struct{Fields: map[string]*pb_struct.Value{
|
fields: &pb_struct.Struct{Fields: map[string]*pb_struct.Value{
|
||||||
"ID": &pb_struct.Value{Kind: &pb_struct.Value_StringValue{StringValue: "ID"}},
|
"AggregateID": &pb_struct.Value{Kind: &pb_struct.Value_StringValue{StringValue: "AggregateID"}},
|
||||||
"Seq": &pb_struct.Value{Kind: &pb_struct.Value_NumberValue{NumberValue: 12345}},
|
"Seq": &pb_struct.Value{Kind: &pb_struct.Value_NumberValue{NumberValue: 12345}},
|
||||||
},
|
},
|
||||||
},
|
},
|
||||||
},
|
},
|
||||||
wantErr: false,
|
wantErr: false,
|
||||||
result: obj{ID: "ID", Seq: 12345},
|
result: obj{AggregateID: "AggregateID", Seq: 12345},
|
||||||
},
|
},
|
||||||
{
|
{
|
||||||
name: "no fields",
|
name: "no fields",
|
||||||
args: args{
|
args: args{
|
||||||
obj: &obj{},
|
obj: &obj{},
|
||||||
fields: &pb_struct.Struct{Fields: map[string]*pb_struct.Value{},
|
fields: &pb_struct.Struct{Fields: map[string]*pb_struct.Value{}},
|
||||||
},
|
|
||||||
},
|
},
|
||||||
wantErr: false,
|
wantErr: false,
|
||||||
result: obj{ID: "", Seq: 0},
|
result: obj{AggregateID: "", Seq: 0},
|
||||||
},
|
},
|
||||||
}
|
}
|
||||||
for _, tt := range tests {
|
for _, tt := range tests {
|
||||||
@ -104,8 +103,8 @@ func Test_FromPBStruct(t *testing.T) {
|
|||||||
if tt.wantErr && err == nil {
|
if tt.wantErr && err == nil {
|
||||||
t.Errorf("got wrong result, should get err: actual: %v ", err)
|
t.Errorf("got wrong result, should get err: actual: %v ", err)
|
||||||
}
|
}
|
||||||
if !tt.wantErr && tt.result.ID != tt.args.obj.ID {
|
if !tt.wantErr && tt.result.AggregateID != tt.args.obj.AggregateID {
|
||||||
t.Errorf("got wrong result, ID should be same: expecting: %v, actual: %v ", tt.result.ID, tt.args.obj.ID)
|
t.Errorf("got wrong result, AggregateID should be same: expecting: %v, actual: %v ", tt.result.AggregateID, tt.args.obj.AggregateID)
|
||||||
}
|
}
|
||||||
if !tt.wantErr && int(tt.result.Seq) != int(tt.args.obj.Seq) {
|
if !tt.wantErr && int(tt.result.Seq) != int(tt.args.obj.Seq) {
|
||||||
t.Errorf("got wrong result, Seq should be same: expecting: %v, actual: %v ", tt.result.Seq, tt.args.obj.Seq)
|
t.Errorf("got wrong result, Seq should be same: expecting: %v, actual: %v ", tt.result.Seq, tt.args.obj.Seq)
|
||||||
|
@ -91,10 +91,10 @@ func TestPrepareSearchQuery(t *testing.T) {
|
|||||||
{
|
{
|
||||||
"search with search query",
|
"search with search query",
|
||||||
mockDB(t).
|
mockDB(t).
|
||||||
expectGetSearchRequestWithSearchQuery("TESTTABLE", TestSearchKey_ID.ToColumnName(), "=", "ID", 2, 2),
|
expectGetSearchRequestWithSearchQuery("TESTTABLE", TestSearchKey_ID.ToColumnName(), "=", "AggregateID", 2, 2),
|
||||||
args{
|
args{
|
||||||
table: "TESTTABLE",
|
table: "TESTTABLE",
|
||||||
searchRequest: TestSearchRequest{queries: []SearchQuery{TestSearchQuery{key: TestSearchKey_ID, method: model.SEARCHMETHOD_EQUALS_IGNORE_CASE, value: "ID"}}},
|
searchRequest: TestSearchRequest{queries: []SearchQuery{TestSearchQuery{key: TestSearchKey_ID, method: model.SEARCHMETHOD_EQUALS_IGNORE_CASE, value: "AggregateID"}}},
|
||||||
},
|
},
|
||||||
res{
|
res{
|
||||||
count: 2,
|
count: 2,
|
||||||
@ -104,10 +104,10 @@ func TestPrepareSearchQuery(t *testing.T) {
|
|||||||
{
|
{
|
||||||
"search with all params",
|
"search with all params",
|
||||||
mockDB(t).
|
mockDB(t).
|
||||||
expectGetSearchRequestWithAllParams("TESTTABLE", TestSearchKey_ID.ToColumnName(), "=", "ID", "ASC", TestSearchKey_ID, 2, 2, 2, 5),
|
expectGetSearchRequestWithAllParams("TESTTABLE", TestSearchKey_ID.ToColumnName(), "=", "AggregateID", "ASC", TestSearchKey_ID, 2, 2, 2, 5),
|
||||||
args{
|
args{
|
||||||
table: "TESTTABLE",
|
table: "TESTTABLE",
|
||||||
searchRequest: TestSearchRequest{limit: 2, offset: 2, sortingColumn: TestSearchKey_ID, asc: true, queries: []SearchQuery{TestSearchQuery{key: TestSearchKey_ID, method: model.SEARCHMETHOD_EQUALS_IGNORE_CASE, value: "ID"}}},
|
searchRequest: TestSearchRequest{limit: 2, offset: 2, sortingColumn: TestSearchKey_ID, asc: true, queries: []SearchQuery{TestSearchQuery{key: TestSearchKey_ID, method: model.SEARCHMETHOD_EQUALS_IGNORE_CASE, value: "AggregateID"}}},
|
||||||
},
|
},
|
||||||
res{
|
res{
|
||||||
count: 5,
|
count: 5,
|
||||||
|
@ -20,7 +20,7 @@ func PrepareGetByKey(table string, key ColumnKey, id string) func(db *gorm.DB, r
|
|||||||
if errors.Is(err, gorm.ErrRecordNotFound) {
|
if errors.Is(err, gorm.ErrRecordNotFound) {
|
||||||
return caos_errs.ThrowNotFound(err, "VIEW-XRI9c", "object not found")
|
return caos_errs.ThrowNotFound(err, "VIEW-XRI9c", "object not found")
|
||||||
}
|
}
|
||||||
logging.LogWithFields("VIEW-xVShS", "ID", id).WithError(err).Warn("get from view error")
|
logging.LogWithFields("VIEW-xVShS", "AggregateID", id).WithError(err).Warn("get from view error")
|
||||||
return caos_errs.ThrowInternal(err, "VIEW-J92Td", "view error")
|
return caos_errs.ThrowInternal(err, "VIEW-J92Td", "view error")
|
||||||
}
|
}
|
||||||
}
|
}
|
||||||
|
@ -270,11 +270,11 @@ func TestPreparePut(t *testing.T) {
|
|||||||
"ok",
|
"ok",
|
||||||
mockDB(t).
|
mockDB(t).
|
||||||
expectBegin(nil).
|
expectBegin(nil).
|
||||||
expectSave("TESTTABLE", Test{ID: "ID", Test: "VALUE"}).
|
expectSave("TESTTABLE", Test{ID: "AggregateID", Test: "VALUE"}).
|
||||||
expectCommit(nil),
|
expectCommit(nil),
|
||||||
args{
|
args{
|
||||||
table: "TESTTABLE",
|
table: "TESTTABLE",
|
||||||
object: &Test{ID: "ID", Test: "VALUE"},
|
object: &Test{ID: "AggregateID", Test: "VALUE"},
|
||||||
},
|
},
|
||||||
res{
|
res{
|
||||||
result: Test{ID: "VALUE"},
|
result: Test{ID: "VALUE"},
|
||||||
@ -285,11 +285,11 @@ func TestPreparePut(t *testing.T) {
|
|||||||
"db error",
|
"db error",
|
||||||
mockDB(t).
|
mockDB(t).
|
||||||
expectBegin(nil).
|
expectBegin(nil).
|
||||||
expectSaveErr("TESTTABLE", Test{ID: "ID", Test: "VALUE"}, gorm.ErrUnaddressable).
|
expectSaveErr("TESTTABLE", Test{ID: "AggregateID", Test: "VALUE"}, gorm.ErrUnaddressable).
|
||||||
expectCommit(nil),
|
expectCommit(nil),
|
||||||
args{
|
args{
|
||||||
table: "TESTTABLE",
|
table: "TESTTABLE",
|
||||||
object: &Test{ID: "ID", Test: "VALUE"},
|
object: &Test{ID: "AggregateID", Test: "VALUE"},
|
||||||
},
|
},
|
||||||
res{
|
res{
|
||||||
result: Test{ID: "VALUE"},
|
result: Test{ID: "VALUE"},
|
||||||
|
@ -3,33 +3,69 @@ package grpc
|
|||||||
import (
|
import (
|
||||||
"context"
|
"context"
|
||||||
"github.com/caos/zitadel/internal/errors"
|
"github.com/caos/zitadel/internal/errors"
|
||||||
|
"github.com/golang/protobuf/ptypes/empty"
|
||||||
)
|
)
|
||||||
|
|
||||||
func (s *Server) SearchApplications(ctx context.Context, request *ApplicationSearchRequest) (*ApplicationSearchResponse, error) {
|
func (s *Server) SearchApplications(ctx context.Context, in *ApplicationSearchRequest) (*ApplicationSearchResponse, error) {
|
||||||
return nil, errors.ThrowUnimplemented(nil, "GRPC-yW23f", "Not implemented")
|
return nil, errors.ThrowUnimplemented(nil, "GRPC-yW23f", "Not implemented")
|
||||||
}
|
}
|
||||||
|
|
||||||
func (s *Server) ApplicationByID(ctx context.Context, request *ApplicationID) (*Application, error) {
|
func (s *Server) ApplicationByID(ctx context.Context, in *ApplicationID) (*Application, error) {
|
||||||
return nil, errors.ThrowUnimplemented(nil, "GRPC-bmr6X", "Not implemented")
|
app, err := s.project.ApplicationByID(ctx, in.ProjectId, in.Id)
|
||||||
|
if err != nil {
|
||||||
|
return nil, err
|
||||||
|
}
|
||||||
|
return appFromModel(app), nil
|
||||||
}
|
}
|
||||||
|
|
||||||
func (s *Server) CreateOIDCApplication(ctx context.Context, in *OIDCApplicationCreate) (*Application, error) {
|
func (s *Server) CreateOIDCApplication(ctx context.Context, in *OIDCApplicationCreate) (*Application, error) {
|
||||||
return nil, errors.ThrowUnimplemented(nil, "GRPC-poe4d", "Not implemented")
|
app, err := s.project.AddApplication(ctx, oidcAppCreateToModel(in))
|
||||||
|
if err != nil {
|
||||||
|
return nil, err
|
||||||
|
}
|
||||||
|
return appFromModel(app), nil
|
||||||
}
|
}
|
||||||
func (s *Server) UpdateApplication(ctx context.Context, in *ApplicationUpdate) (*Application, error) {
|
func (s *Server) UpdateApplication(ctx context.Context, in *ApplicationUpdate) (*Application, error) {
|
||||||
return nil, errors.ThrowUnimplemented(nil, "GRPC-bmt6J", "Not implemented")
|
app, err := s.project.ChangeApplication(ctx, appUpdateToModel(in))
|
||||||
|
if err != nil {
|
||||||
|
return nil, err
|
||||||
|
}
|
||||||
|
return appFromModel(app), nil
|
||||||
}
|
}
|
||||||
func (s *Server) DeactivateApplication(ctx context.Context, in *ApplicationID) (*Application, error) {
|
func (s *Server) DeactivateApplication(ctx context.Context, in *ApplicationID) (*Application, error) {
|
||||||
return nil, errors.ThrowUnimplemented(nil, "GRPC-cD34f", "Not implemented")
|
app, err := s.project.DeactivateApplication(ctx, in.ProjectId, in.Id)
|
||||||
|
if err != nil {
|
||||||
|
return nil, err
|
||||||
|
}
|
||||||
|
return appFromModel(app), nil
|
||||||
}
|
}
|
||||||
func (s *Server) ReactivateApplication(ctx context.Context, in *ApplicationID) (*Application, error) {
|
func (s *Server) ReactivateApplication(ctx context.Context, in *ApplicationID) (*Application, error) {
|
||||||
return nil, errors.ThrowUnimplemented(nil, "GRPC-mo98S", "Not implemented")
|
app, err := s.project.ReactivateApplication(ctx, in.ProjectId, in.Id)
|
||||||
|
if err != nil {
|
||||||
|
return nil, err
|
||||||
|
}
|
||||||
|
return appFromModel(app), nil
|
||||||
}
|
}
|
||||||
|
|
||||||
|
func (s *Server) RemoveApplication(ctx context.Context, in *ApplicationID) (*empty.Empty, error) {
|
||||||
|
err := s.project.RemoveApplication(ctx, in.ProjectId, in.Id)
|
||||||
|
return &empty.Empty{}, err
|
||||||
|
}
|
||||||
|
|
||||||
func (s *Server) UpdateApplicationOIDCConfig(ctx context.Context, in *OIDCConfigUpdate) (*OIDCConfig, error) {
|
func (s *Server) UpdateApplicationOIDCConfig(ctx context.Context, in *OIDCConfigUpdate) (*OIDCConfig, error) {
|
||||||
return nil, errors.ThrowUnimplemented(nil, "GRPC-xm56g", "Not implemented")
|
config, err := s.project.ChangeOIDCConfig(ctx, oidcConfigUpdateToModel(in))
|
||||||
|
if err != nil {
|
||||||
|
return nil, err
|
||||||
|
}
|
||||||
|
return oidcConfigFromModel(config), nil
|
||||||
}
|
}
|
||||||
|
|
||||||
func (s *Server) RegenerateOIDCClientSecret(ctx context.Context, in *ApplicationID) (*ClientSecret, error) {
|
func (s *Server) RegenerateOIDCClientSecret(ctx context.Context, in *ApplicationID) (*ClientSecret, error) {
|
||||||
return nil, errors.ThrowUnimplemented(nil, "GRPC-dlwp3", "Not implemented")
|
config, err := s.project.ChangeOIDConfigSecret(ctx, in.ProjectId, in.Id)
|
||||||
|
if err != nil {
|
||||||
|
return nil, err
|
||||||
|
}
|
||||||
|
return &ClientSecret{ClientSecret: config.ClientSecretString}, nil
|
||||||
}
|
}
|
||||||
|
|
||||||
func (s *Server) ApplicationChanges(ctx context.Context, changesRequest *ChangeRequest) (*Changes, error) {
|
func (s *Server) ApplicationChanges(ctx context.Context, changesRequest *ChangeRequest) (*Changes, error) {
|
||||||
|
225
pkg/management/api/grpc/application_converter.go
Normal file
225
pkg/management/api/grpc/application_converter.go
Normal file
@ -0,0 +1,225 @@
|
|||||||
|
package grpc
|
||||||
|
|
||||||
|
import (
|
||||||
|
"github.com/caos/logging"
|
||||||
|
"github.com/caos/zitadel/internal/eventstore/models"
|
||||||
|
proj_model "github.com/caos/zitadel/internal/project/model"
|
||||||
|
"github.com/golang/protobuf/ptypes"
|
||||||
|
)
|
||||||
|
|
||||||
|
func appFromModel(app *proj_model.Application) *Application {
|
||||||
|
creationDate, err := ptypes.TimestampProto(app.CreationDate)
|
||||||
|
logging.Log("GRPC-iejs3").OnError(err).Debug("unable to parse timestamp")
|
||||||
|
|
||||||
|
changeDate, err := ptypes.TimestampProto(app.ChangeDate)
|
||||||
|
logging.Log("GRPC-di7rw").OnError(err).Debug("unable to parse timestamp")
|
||||||
|
|
||||||
|
return &Application{
|
||||||
|
Id: app.AppID,
|
||||||
|
State: appStateFromModel(app.State),
|
||||||
|
CreationDate: creationDate,
|
||||||
|
ChangeDate: changeDate,
|
||||||
|
Name: app.Name,
|
||||||
|
Sequence: app.Sequence,
|
||||||
|
AppConfig: appConfigFromModel(app),
|
||||||
|
}
|
||||||
|
}
|
||||||
|
|
||||||
|
func appConfigFromModel(app *proj_model.Application) isApplication_AppConfig {
|
||||||
|
if app.Type == proj_model.APPTYPE_OIDC {
|
||||||
|
return &Application_OidcConfig{
|
||||||
|
OidcConfig: oidcConfigFromModel(app.OIDCConfig),
|
||||||
|
}
|
||||||
|
}
|
||||||
|
return nil
|
||||||
|
}
|
||||||
|
|
||||||
|
func oidcConfigFromModel(config *proj_model.OIDCConfig) *OIDCConfig {
|
||||||
|
return &OIDCConfig{
|
||||||
|
RedirectUris: config.RedirectUris,
|
||||||
|
ResponseTypes: oidcResponseTypesFromModel(config.ResponseTypes),
|
||||||
|
GrantTypes: oidcGrantTypesFromModel(config.GrantTypes),
|
||||||
|
ApplicationType: oidcApplicationTypeFromModel(config.ApplicationType),
|
||||||
|
ClientId: config.ClientID,
|
||||||
|
ClientSecret: config.ClientSecretString,
|
||||||
|
AuthMethodType: oidcAuthMethodTypeFromModel(config.AuthMethodType),
|
||||||
|
PostLogoutRedirectUris: config.PostLogoutRedirectUris,
|
||||||
|
}
|
||||||
|
}
|
||||||
|
|
||||||
|
func oidcAppCreateToModel(app *OIDCApplicationCreate) *proj_model.Application {
|
||||||
|
return &proj_model.Application{
|
||||||
|
ObjectRoot: models.ObjectRoot{
|
||||||
|
AggregateID: app.ProjectId,
|
||||||
|
},
|
||||||
|
Name: app.Name,
|
||||||
|
Type: proj_model.APPTYPE_OIDC,
|
||||||
|
OIDCConfig: &proj_model.OIDCConfig{
|
||||||
|
RedirectUris: app.RedirectUris,
|
||||||
|
ResponseTypes: oidcResponseTypesToModel(app.ResponseTypes),
|
||||||
|
GrantTypes: oidcGrantTypesToModel(app.GrantTypes),
|
||||||
|
ApplicationType: oidcApplicationTypeToModel(app.ApplicationType),
|
||||||
|
AuthMethodType: oidcAuthMethodTypeToModel(app.AuthMethodType),
|
||||||
|
PostLogoutRedirectUris: app.PostLogoutRedirectUris,
|
||||||
|
},
|
||||||
|
}
|
||||||
|
}
|
||||||
|
|
||||||
|
func appUpdateToModel(app *ApplicationUpdate) *proj_model.Application {
|
||||||
|
return &proj_model.Application{
|
||||||
|
ObjectRoot: models.ObjectRoot{
|
||||||
|
AggregateID: app.ProjectId,
|
||||||
|
},
|
||||||
|
AppID: app.Id,
|
||||||
|
Name: app.Name,
|
||||||
|
}
|
||||||
|
}
|
||||||
|
|
||||||
|
func oidcConfigUpdateToModel(app *OIDCConfigUpdate) *proj_model.OIDCConfig {
|
||||||
|
return &proj_model.OIDCConfig{
|
||||||
|
ObjectRoot: models.ObjectRoot{
|
||||||
|
AggregateID: app.ProjectId,
|
||||||
|
},
|
||||||
|
AppID: app.ApplicationId,
|
||||||
|
RedirectUris: app.RedirectUris,
|
||||||
|
ResponseTypes: oidcResponseTypesToModel(app.ResponseTypes),
|
||||||
|
GrantTypes: oidcGrantTypesToModel(app.GrantTypes),
|
||||||
|
ApplicationType: oidcApplicationTypeToModel(app.ApplicationType),
|
||||||
|
AuthMethodType: oidcAuthMethodTypeToModel(app.AuthMethodType),
|
||||||
|
PostLogoutRedirectUris: app.PostLogoutRedirectUris,
|
||||||
|
}
|
||||||
|
}
|
||||||
|
|
||||||
|
func appStateFromModel(state proj_model.AppState) AppState {
|
||||||
|
switch state {
|
||||||
|
case proj_model.APPSTATE_ACTIVE:
|
||||||
|
return AppState_APPSTATE_ACTIVE
|
||||||
|
case proj_model.APPSTATE_INACTIVE:
|
||||||
|
return AppState_APPSTATE_INACTIVE
|
||||||
|
default:
|
||||||
|
return AppState_APPSTATE_UNSPECIFIED
|
||||||
|
}
|
||||||
|
}
|
||||||
|
|
||||||
|
func oidcResponseTypesToModel(responseTypes []OIDCResponseType) []proj_model.OIDCResponseType {
|
||||||
|
if responseTypes == nil || len(responseTypes) == 0 {
|
||||||
|
return []proj_model.OIDCResponseType{proj_model.OIDCRESPONSETYPE_CODE}
|
||||||
|
}
|
||||||
|
oidcResponseTypes := make([]proj_model.OIDCResponseType, len(responseTypes))
|
||||||
|
|
||||||
|
for i, responseType := range responseTypes {
|
||||||
|
switch responseType {
|
||||||
|
case OIDCResponseType_OIDCRESPONSETYPE_CODE:
|
||||||
|
oidcResponseTypes[i] = proj_model.OIDCRESPONSETYPE_CODE
|
||||||
|
case OIDCResponseType_OIDCRESPONSETYPE_ID_TOKEN:
|
||||||
|
oidcResponseTypes[i] = proj_model.OIDCRESPONSETYPE_ID_TOKEN
|
||||||
|
case OIDCResponseType_OIDCRESPONSETYPE_TOKEN:
|
||||||
|
oidcResponseTypes[i] = proj_model.OIDCRESPONSETYPE_TOKEN
|
||||||
|
}
|
||||||
|
}
|
||||||
|
|
||||||
|
return oidcResponseTypes
|
||||||
|
}
|
||||||
|
|
||||||
|
func oidcResponseTypesFromModel(responseTypes []proj_model.OIDCResponseType) []OIDCResponseType {
|
||||||
|
oidcResponseTypes := make([]OIDCResponseType, len(responseTypes))
|
||||||
|
|
||||||
|
for i, responseType := range responseTypes {
|
||||||
|
switch responseType {
|
||||||
|
case proj_model.OIDCRESPONSETYPE_CODE:
|
||||||
|
oidcResponseTypes[i] = OIDCResponseType_OIDCRESPONSETYPE_CODE
|
||||||
|
case proj_model.OIDCRESPONSETYPE_ID_TOKEN:
|
||||||
|
oidcResponseTypes[i] = OIDCResponseType_OIDCRESPONSETYPE_ID_TOKEN
|
||||||
|
case proj_model.OIDCRESPONSETYPE_TOKEN:
|
||||||
|
oidcResponseTypes[i] = OIDCResponseType_OIDCRESPONSETYPE_TOKEN
|
||||||
|
}
|
||||||
|
}
|
||||||
|
|
||||||
|
return oidcResponseTypes
|
||||||
|
}
|
||||||
|
|
||||||
|
func oidcGrantTypesToModel(grantTypes []OIDCGrantType) []proj_model.OIDCGrantType {
|
||||||
|
if grantTypes == nil || len(grantTypes) == 0 {
|
||||||
|
return []proj_model.OIDCGrantType{proj_model.OIDCGRANTTYPE_AUTHORIZATION_CODE}
|
||||||
|
}
|
||||||
|
oidcGrantTypes := make([]proj_model.OIDCGrantType, len(grantTypes))
|
||||||
|
|
||||||
|
for i, grantType := range grantTypes {
|
||||||
|
switch grantType {
|
||||||
|
case OIDCGrantType_OIDCGRANTTYPE_AUTHORIZATION_CODE:
|
||||||
|
oidcGrantTypes[i] = proj_model.OIDCGRANTTYPE_AUTHORIZATION_CODE
|
||||||
|
case OIDCGrantType_OIDCGRANTTYPE_IMPLICIT:
|
||||||
|
oidcGrantTypes[i] = proj_model.OIDCGRANTTYPE_IMPLICIT
|
||||||
|
case OIDCGrantType_OIDCGRANTTYPE_REFRESH_TOKEN:
|
||||||
|
oidcGrantTypes[i] = proj_model.OIDCGRANTTYPE_REFRESH_TOKEN
|
||||||
|
}
|
||||||
|
}
|
||||||
|
return oidcGrantTypes
|
||||||
|
}
|
||||||
|
|
||||||
|
func oidcGrantTypesFromModel(grantTypes []proj_model.OIDCGrantType) []OIDCGrantType {
|
||||||
|
oidcGrantTypes := make([]OIDCGrantType, len(grantTypes))
|
||||||
|
|
||||||
|
for i, grantType := range grantTypes {
|
||||||
|
switch grantType {
|
||||||
|
case proj_model.OIDCGRANTTYPE_AUTHORIZATION_CODE:
|
||||||
|
oidcGrantTypes[i] = OIDCGrantType_OIDCGRANTTYPE_AUTHORIZATION_CODE
|
||||||
|
case proj_model.OIDCGRANTTYPE_IMPLICIT:
|
||||||
|
oidcGrantTypes[i] = OIDCGrantType_OIDCGRANTTYPE_IMPLICIT
|
||||||
|
case proj_model.OIDCGRANTTYPE_REFRESH_TOKEN:
|
||||||
|
oidcGrantTypes[i] = OIDCGrantType_OIDCGRANTTYPE_REFRESH_TOKEN
|
||||||
|
}
|
||||||
|
}
|
||||||
|
return oidcGrantTypes
|
||||||
|
}
|
||||||
|
|
||||||
|
func oidcApplicationTypeToModel(appType OIDCApplicationType) proj_model.OIDCApplicationType {
|
||||||
|
switch appType {
|
||||||
|
case OIDCApplicationType_OIDCAPPLICATIONTYPE_WEB:
|
||||||
|
return proj_model.OIDCAPPLICATIONTYPE_WEB
|
||||||
|
case OIDCApplicationType_OIDCAPPLICATIONTYPE_USER_AGENT:
|
||||||
|
return proj_model.OIDCAPPLICATIONTYPE_USER_AGENT
|
||||||
|
case OIDCApplicationType_OIDCAPPLICATIONTYPE_NATIVE:
|
||||||
|
return proj_model.OIDCAPPLICATIONTYPE_NATIVE
|
||||||
|
}
|
||||||
|
return proj_model.OIDCAPPLICATIONTYPE_WEB
|
||||||
|
}
|
||||||
|
|
||||||
|
func oidcApplicationTypeFromModel(appType proj_model.OIDCApplicationType) OIDCApplicationType {
|
||||||
|
switch appType {
|
||||||
|
case proj_model.OIDCAPPLICATIONTYPE_WEB:
|
||||||
|
return OIDCApplicationType_OIDCAPPLICATIONTYPE_WEB
|
||||||
|
case proj_model.OIDCAPPLICATIONTYPE_USER_AGENT:
|
||||||
|
return OIDCApplicationType_OIDCAPPLICATIONTYPE_USER_AGENT
|
||||||
|
case proj_model.OIDCAPPLICATIONTYPE_NATIVE:
|
||||||
|
return OIDCApplicationType_OIDCAPPLICATIONTYPE_NATIVE
|
||||||
|
default:
|
||||||
|
return OIDCApplicationType_OIDCAPPLICATIONTYPE_WEB
|
||||||
|
}
|
||||||
|
}
|
||||||
|
|
||||||
|
func oidcAuthMethodTypeToModel(authType OIDCAuthMethodType) proj_model.OIDCAuthMethodType {
|
||||||
|
switch authType {
|
||||||
|
case OIDCAuthMethodType_OIDCAUTHMETHODTYPE_BASIC:
|
||||||
|
return proj_model.OIDCAUTHMETHODTYPE_BASIC
|
||||||
|
case OIDCAuthMethodType_OIDCAUTHMETHODTYPE_POST:
|
||||||
|
return proj_model.OIDCAUTHMETHODTYPE_POST
|
||||||
|
case OIDCAuthMethodType_OIDCAUTHMETHODTYPE_NONE:
|
||||||
|
return proj_model.OIDCAUTHMETHODTYPE_NONE
|
||||||
|
default:
|
||||||
|
return proj_model.OIDCAUTHMETHODTYPE_BASIC
|
||||||
|
}
|
||||||
|
}
|
||||||
|
|
||||||
|
func oidcAuthMethodTypeFromModel(authType proj_model.OIDCAuthMethodType) OIDCAuthMethodType {
|
||||||
|
switch authType {
|
||||||
|
case proj_model.OIDCAUTHMETHODTYPE_BASIC:
|
||||||
|
return OIDCAuthMethodType_OIDCAUTHMETHODTYPE_BASIC
|
||||||
|
case proj_model.OIDCAUTHMETHODTYPE_POST:
|
||||||
|
return OIDCAuthMethodType_OIDCAUTHMETHODTYPE_POST
|
||||||
|
case proj_model.OIDCAUTHMETHODTYPE_NONE:
|
||||||
|
return OIDCAuthMethodType_OIDCAUTHMETHODTYPE_NONE
|
||||||
|
default:
|
||||||
|
return OIDCAuthMethodType_OIDCAUTHMETHODTYPE_BASIC
|
||||||
|
}
|
||||||
|
}
|
@ -325,6 +325,11 @@ var ManagementService_AuthMethods = utils_auth.MethodMapping{
|
|||||||
CheckParam: "Id",
|
CheckParam: "Id",
|
||||||
},
|
},
|
||||||
|
|
||||||
|
"/caos.zitadel.management.api.v1.ManagementService/ChangeProjectRole": utils_auth.Option{
|
||||||
|
Permission: "project.role.write",
|
||||||
|
CheckParam: "Id",
|
||||||
|
},
|
||||||
|
|
||||||
"/caos.zitadel.management.api.v1.ManagementService/RemoveProjectRole": utils_auth.Option{
|
"/caos.zitadel.management.api.v1.ManagementService/RemoveProjectRole": utils_auth.Option{
|
||||||
Permission: "project.role.delete",
|
Permission: "project.role.delete",
|
||||||
CheckParam: "Id",
|
CheckParam: "Id",
|
||||||
@ -360,6 +365,11 @@ var ManagementService_AuthMethods = utils_auth.MethodMapping{
|
|||||||
CheckParam: "ProjectId",
|
CheckParam: "ProjectId",
|
||||||
},
|
},
|
||||||
|
|
||||||
|
"/caos.zitadel.management.api.v1.ManagementService/RemoveApplication": utils_auth.Option{
|
||||||
|
Permission: "project.app.delete",
|
||||||
|
CheckParam: "ProjectId",
|
||||||
|
},
|
||||||
|
|
||||||
"/caos.zitadel.management.api.v1.ManagementService/UpdateApplicationOIDCConfig": utils_auth.Option{
|
"/caos.zitadel.management.api.v1.ManagementService/UpdateApplicationOIDCConfig": utils_auth.Option{
|
||||||
Permission: "project.app.write",
|
Permission: "project.app.write",
|
||||||
CheckParam: "ProjectId",
|
CheckParam: "ProjectId",
|
||||||
|
File diff suppressed because it is too large
Load Diff
@ -1860,6 +1860,52 @@ func request_ManagementService_AddProjectRole_0(ctx context.Context, marshaler r
|
|||||||
|
|
||||||
}
|
}
|
||||||
|
|
||||||
|
func request_ManagementService_ChangeProjectRole_0(ctx context.Context, marshaler runtime.Marshaler, client ManagementServiceClient, req *http.Request, pathParams map[string]string) (proto.Message, runtime.ServerMetadata, error) {
|
||||||
|
var protoReq ProjectRoleChange
|
||||||
|
var metadata runtime.ServerMetadata
|
||||||
|
|
||||||
|
newReader, berr := utilities.IOReaderFactory(req.Body)
|
||||||
|
if berr != nil {
|
||||||
|
return nil, metadata, status.Errorf(codes.InvalidArgument, "%v", berr)
|
||||||
|
}
|
||||||
|
if err := marshaler.NewDecoder(newReader()).Decode(&protoReq); err != nil && err != io.EOF {
|
||||||
|
return nil, metadata, status.Errorf(codes.InvalidArgument, "%v", err)
|
||||||
|
}
|
||||||
|
|
||||||
|
var (
|
||||||
|
val string
|
||||||
|
ok bool
|
||||||
|
err error
|
||||||
|
_ = err
|
||||||
|
)
|
||||||
|
|
||||||
|
val, ok = pathParams["id"]
|
||||||
|
if !ok {
|
||||||
|
return nil, metadata, status.Errorf(codes.InvalidArgument, "missing parameter %s", "id")
|
||||||
|
}
|
||||||
|
|
||||||
|
protoReq.Id, err = runtime.String(val)
|
||||||
|
|
||||||
|
if err != nil {
|
||||||
|
return nil, metadata, status.Errorf(codes.InvalidArgument, "type mismatch, parameter: %s, error: %v", "id", err)
|
||||||
|
}
|
||||||
|
|
||||||
|
val, ok = pathParams["key"]
|
||||||
|
if !ok {
|
||||||
|
return nil, metadata, status.Errorf(codes.InvalidArgument, "missing parameter %s", "key")
|
||||||
|
}
|
||||||
|
|
||||||
|
protoReq.Key, err = runtime.String(val)
|
||||||
|
|
||||||
|
if err != nil {
|
||||||
|
return nil, metadata, status.Errorf(codes.InvalidArgument, "type mismatch, parameter: %s, error: %v", "key", err)
|
||||||
|
}
|
||||||
|
|
||||||
|
msg, err := client.ChangeProjectRole(ctx, &protoReq, grpc.Header(&metadata.HeaderMD), grpc.Trailer(&metadata.TrailerMD))
|
||||||
|
return msg, metadata, err
|
||||||
|
|
||||||
|
}
|
||||||
|
|
||||||
func request_ManagementService_RemoveProjectRole_0(ctx context.Context, marshaler runtime.Marshaler, client ManagementServiceClient, req *http.Request, pathParams map[string]string) (proto.Message, runtime.ServerMetadata, error) {
|
func request_ManagementService_RemoveProjectRole_0(ctx context.Context, marshaler runtime.Marshaler, client ManagementServiceClient, req *http.Request, pathParams map[string]string) (proto.Message, runtime.ServerMetadata, error) {
|
||||||
var protoReq ProjectRoleRemove
|
var protoReq ProjectRoleRemove
|
||||||
var metadata runtime.ServerMetadata
|
var metadata runtime.ServerMetadata
|
||||||
@ -1882,15 +1928,15 @@ func request_ManagementService_RemoveProjectRole_0(ctx context.Context, marshale
|
|||||||
return nil, metadata, status.Errorf(codes.InvalidArgument, "type mismatch, parameter: %s, error: %v", "id", err)
|
return nil, metadata, status.Errorf(codes.InvalidArgument, "type mismatch, parameter: %s, error: %v", "id", err)
|
||||||
}
|
}
|
||||||
|
|
||||||
val, ok = pathParams["name"]
|
val, ok = pathParams["key"]
|
||||||
if !ok {
|
if !ok {
|
||||||
return nil, metadata, status.Errorf(codes.InvalidArgument, "missing parameter %s", "name")
|
return nil, metadata, status.Errorf(codes.InvalidArgument, "missing parameter %s", "key")
|
||||||
}
|
}
|
||||||
|
|
||||||
protoReq.Name, err = runtime.String(val)
|
protoReq.Key, err = runtime.String(val)
|
||||||
|
|
||||||
if err != nil {
|
if err != nil {
|
||||||
return nil, metadata, status.Errorf(codes.InvalidArgument, "type mismatch, parameter: %s, error: %v", "name", err)
|
return nil, metadata, status.Errorf(codes.InvalidArgument, "type mismatch, parameter: %s, error: %v", "key", err)
|
||||||
}
|
}
|
||||||
|
|
||||||
msg, err := client.RemoveProjectRole(ctx, &protoReq, grpc.Header(&metadata.HeaderMD), grpc.Trailer(&metadata.TrailerMD))
|
msg, err := client.RemoveProjectRole(ctx, &protoReq, grpc.Header(&metadata.HeaderMD), grpc.Trailer(&metadata.TrailerMD))
|
||||||
@ -2144,6 +2190,44 @@ func request_ManagementService_ReactivateApplication_0(ctx context.Context, mars
|
|||||||
|
|
||||||
}
|
}
|
||||||
|
|
||||||
|
func request_ManagementService_RemoveApplication_0(ctx context.Context, marshaler runtime.Marshaler, client ManagementServiceClient, req *http.Request, pathParams map[string]string) (proto.Message, runtime.ServerMetadata, error) {
|
||||||
|
var protoReq ApplicationID
|
||||||
|
var metadata runtime.ServerMetadata
|
||||||
|
|
||||||
|
var (
|
||||||
|
val string
|
||||||
|
ok bool
|
||||||
|
err error
|
||||||
|
_ = err
|
||||||
|
)
|
||||||
|
|
||||||
|
val, ok = pathParams["project_id"]
|
||||||
|
if !ok {
|
||||||
|
return nil, metadata, status.Errorf(codes.InvalidArgument, "missing parameter %s", "project_id")
|
||||||
|
}
|
||||||
|
|
||||||
|
protoReq.ProjectId, err = runtime.String(val)
|
||||||
|
|
||||||
|
if err != nil {
|
||||||
|
return nil, metadata, status.Errorf(codes.InvalidArgument, "type mismatch, parameter: %s, error: %v", "project_id", err)
|
||||||
|
}
|
||||||
|
|
||||||
|
val, ok = pathParams["id"]
|
||||||
|
if !ok {
|
||||||
|
return nil, metadata, status.Errorf(codes.InvalidArgument, "missing parameter %s", "id")
|
||||||
|
}
|
||||||
|
|
||||||
|
protoReq.Id, err = runtime.String(val)
|
||||||
|
|
||||||
|
if err != nil {
|
||||||
|
return nil, metadata, status.Errorf(codes.InvalidArgument, "type mismatch, parameter: %s, error: %v", "id", err)
|
||||||
|
}
|
||||||
|
|
||||||
|
msg, err := client.RemoveApplication(ctx, &protoReq, grpc.Header(&metadata.HeaderMD), grpc.Trailer(&metadata.TrailerMD))
|
||||||
|
return msg, metadata, err
|
||||||
|
|
||||||
|
}
|
||||||
|
|
||||||
func request_ManagementService_UpdateApplicationOIDCConfig_0(ctx context.Context, marshaler runtime.Marshaler, client ManagementServiceClient, req *http.Request, pathParams map[string]string) (proto.Message, runtime.ServerMetadata, error) {
|
func request_ManagementService_UpdateApplicationOIDCConfig_0(ctx context.Context, marshaler runtime.Marshaler, client ManagementServiceClient, req *http.Request, pathParams map[string]string) (proto.Message, runtime.ServerMetadata, error) {
|
||||||
var protoReq OIDCConfigUpdate
|
var protoReq OIDCConfigUpdate
|
||||||
var metadata runtime.ServerMetadata
|
var metadata runtime.ServerMetadata
|
||||||
@ -4874,6 +4958,26 @@ func RegisterManagementServiceHandlerClient(ctx context.Context, mux *runtime.Se
|
|||||||
|
|
||||||
})
|
})
|
||||||
|
|
||||||
|
mux.Handle("PUT", pattern_ManagementService_ChangeProjectRole_0, func(w http.ResponseWriter, req *http.Request, pathParams map[string]string) {
|
||||||
|
ctx, cancel := context.WithCancel(req.Context())
|
||||||
|
defer cancel()
|
||||||
|
inboundMarshaler, outboundMarshaler := runtime.MarshalerForRequest(mux, req)
|
||||||
|
rctx, err := runtime.AnnotateContext(ctx, mux, req)
|
||||||
|
if err != nil {
|
||||||
|
runtime.HTTPError(ctx, mux, outboundMarshaler, w, req, err)
|
||||||
|
return
|
||||||
|
}
|
||||||
|
resp, md, err := request_ManagementService_ChangeProjectRole_0(rctx, inboundMarshaler, client, req, pathParams)
|
||||||
|
ctx = runtime.NewServerMetadataContext(ctx, md)
|
||||||
|
if err != nil {
|
||||||
|
runtime.HTTPError(ctx, mux, outboundMarshaler, w, req, err)
|
||||||
|
return
|
||||||
|
}
|
||||||
|
|
||||||
|
forward_ManagementService_ChangeProjectRole_0(ctx, mux, outboundMarshaler, w, req, resp, mux.GetForwardResponseOptions()...)
|
||||||
|
|
||||||
|
})
|
||||||
|
|
||||||
mux.Handle("DELETE", pattern_ManagementService_RemoveProjectRole_0, func(w http.ResponseWriter, req *http.Request, pathParams map[string]string) {
|
mux.Handle("DELETE", pattern_ManagementService_RemoveProjectRole_0, func(w http.ResponseWriter, req *http.Request, pathParams map[string]string) {
|
||||||
ctx, cancel := context.WithCancel(req.Context())
|
ctx, cancel := context.WithCancel(req.Context())
|
||||||
defer cancel()
|
defer cancel()
|
||||||
@ -5014,6 +5118,26 @@ func RegisterManagementServiceHandlerClient(ctx context.Context, mux *runtime.Se
|
|||||||
|
|
||||||
})
|
})
|
||||||
|
|
||||||
|
mux.Handle("DELETE", pattern_ManagementService_RemoveApplication_0, func(w http.ResponseWriter, req *http.Request, pathParams map[string]string) {
|
||||||
|
ctx, cancel := context.WithCancel(req.Context())
|
||||||
|
defer cancel()
|
||||||
|
inboundMarshaler, outboundMarshaler := runtime.MarshalerForRequest(mux, req)
|
||||||
|
rctx, err := runtime.AnnotateContext(ctx, mux, req)
|
||||||
|
if err != nil {
|
||||||
|
runtime.HTTPError(ctx, mux, outboundMarshaler, w, req, err)
|
||||||
|
return
|
||||||
|
}
|
||||||
|
resp, md, err := request_ManagementService_RemoveApplication_0(rctx, inboundMarshaler, client, req, pathParams)
|
||||||
|
ctx = runtime.NewServerMetadataContext(ctx, md)
|
||||||
|
if err != nil {
|
||||||
|
runtime.HTTPError(ctx, mux, outboundMarshaler, w, req, err)
|
||||||
|
return
|
||||||
|
}
|
||||||
|
|
||||||
|
forward_ManagementService_RemoveApplication_0(ctx, mux, outboundMarshaler, w, req, resp, mux.GetForwardResponseOptions()...)
|
||||||
|
|
||||||
|
})
|
||||||
|
|
||||||
mux.Handle("PUT", pattern_ManagementService_UpdateApplicationOIDCConfig_0, func(w http.ResponseWriter, req *http.Request, pathParams map[string]string) {
|
mux.Handle("PUT", pattern_ManagementService_UpdateApplicationOIDCConfig_0, func(w http.ResponseWriter, req *http.Request, pathParams map[string]string) {
|
||||||
ctx, cancel := context.WithCancel(req.Context())
|
ctx, cancel := context.WithCancel(req.Context())
|
||||||
defer cancel()
|
defer cancel()
|
||||||
@ -5788,7 +5912,9 @@ var (
|
|||||||
|
|
||||||
pattern_ManagementService_AddProjectRole_0 = runtime.MustPattern(runtime.NewPattern(1, []int{2, 0, 1, 0, 4, 1, 5, 1, 2, 2}, []string{"projects", "id", "roles"}, ""))
|
pattern_ManagementService_AddProjectRole_0 = runtime.MustPattern(runtime.NewPattern(1, []int{2, 0, 1, 0, 4, 1, 5, 1, 2, 2}, []string{"projects", "id", "roles"}, ""))
|
||||||
|
|
||||||
pattern_ManagementService_RemoveProjectRole_0 = runtime.MustPattern(runtime.NewPattern(1, []int{2, 0, 1, 0, 4, 1, 5, 1, 2, 2, 1, 0, 4, 1, 5, 3}, []string{"projects", "id", "roles", "name"}, ""))
|
pattern_ManagementService_ChangeProjectRole_0 = runtime.MustPattern(runtime.NewPattern(1, []int{2, 0, 1, 0, 4, 1, 5, 1, 2, 2, 1, 0, 4, 1, 5, 3}, []string{"projects", "id", "roles", "key"}, ""))
|
||||||
|
|
||||||
|
pattern_ManagementService_RemoveProjectRole_0 = runtime.MustPattern(runtime.NewPattern(1, []int{2, 0, 1, 0, 4, 1, 5, 1, 2, 2, 1, 0, 4, 1, 5, 3}, []string{"projects", "id", "roles", "key"}, ""))
|
||||||
|
|
||||||
pattern_ManagementService_SearchApplications_0 = runtime.MustPattern(runtime.NewPattern(1, []int{2, 0, 1, 0, 4, 1, 5, 1, 2, 2, 2, 3}, []string{"projects", "project_id", "applications", "_search"}, ""))
|
pattern_ManagementService_SearchApplications_0 = runtime.MustPattern(runtime.NewPattern(1, []int{2, 0, 1, 0, 4, 1, 5, 1, 2, 2, 2, 3}, []string{"projects", "project_id", "applications", "_search"}, ""))
|
||||||
|
|
||||||
@ -5802,6 +5928,8 @@ var (
|
|||||||
|
|
||||||
pattern_ManagementService_ReactivateApplication_0 = runtime.MustPattern(runtime.NewPattern(1, []int{2, 0, 1, 0, 4, 1, 5, 1, 2, 2, 1, 0, 4, 1, 5, 3, 2, 4}, []string{"projects", "project_id", "applications", "id", "_reactivate"}, ""))
|
pattern_ManagementService_ReactivateApplication_0 = runtime.MustPattern(runtime.NewPattern(1, []int{2, 0, 1, 0, 4, 1, 5, 1, 2, 2, 1, 0, 4, 1, 5, 3, 2, 4}, []string{"projects", "project_id", "applications", "id", "_reactivate"}, ""))
|
||||||
|
|
||||||
|
pattern_ManagementService_RemoveApplication_0 = runtime.MustPattern(runtime.NewPattern(1, []int{2, 0, 1, 0, 4, 1, 5, 1, 2, 2, 1, 0, 4, 1, 5, 3}, []string{"projects", "project_id", "applications", "id"}, ""))
|
||||||
|
|
||||||
pattern_ManagementService_UpdateApplicationOIDCConfig_0 = runtime.MustPattern(runtime.NewPattern(1, []int{2, 0, 1, 0, 4, 1, 5, 1, 2, 2, 1, 0, 4, 1, 5, 3, 2, 4}, []string{"projects", "project_id", "applications", "application_id", "oidcconfig"}, ""))
|
pattern_ManagementService_UpdateApplicationOIDCConfig_0 = runtime.MustPattern(runtime.NewPattern(1, []int{2, 0, 1, 0, 4, 1, 5, 1, 2, 2, 1, 0, 4, 1, 5, 3, 2, 4}, []string{"projects", "project_id", "applications", "application_id", "oidcconfig"}, ""))
|
||||||
|
|
||||||
pattern_ManagementService_RegenerateOIDCClientSecret_0 = runtime.MustPattern(runtime.NewPattern(1, []int{2, 0, 1, 0, 4, 1, 5, 1, 2, 2, 1, 0, 4, 1, 5, 3, 2, 4, 2, 5}, []string{"projects", "project_id", "applications", "id", "oidcconfig", "_changeclientsecret"}, ""))
|
pattern_ManagementService_RegenerateOIDCClientSecret_0 = runtime.MustPattern(runtime.NewPattern(1, []int{2, 0, 1, 0, 4, 1, 5, 1, 2, 2, 1, 0, 4, 1, 5, 3, 2, 4, 2, 5}, []string{"projects", "project_id", "applications", "id", "oidcconfig", "_changeclientsecret"}, ""))
|
||||||
@ -5998,6 +6126,8 @@ var (
|
|||||||
|
|
||||||
forward_ManagementService_AddProjectRole_0 = runtime.ForwardResponseMessage
|
forward_ManagementService_AddProjectRole_0 = runtime.ForwardResponseMessage
|
||||||
|
|
||||||
|
forward_ManagementService_ChangeProjectRole_0 = runtime.ForwardResponseMessage
|
||||||
|
|
||||||
forward_ManagementService_RemoveProjectRole_0 = runtime.ForwardResponseMessage
|
forward_ManagementService_RemoveProjectRole_0 = runtime.ForwardResponseMessage
|
||||||
|
|
||||||
forward_ManagementService_SearchApplications_0 = runtime.ForwardResponseMessage
|
forward_ManagementService_SearchApplications_0 = runtime.ForwardResponseMessage
|
||||||
@ -6012,6 +6142,8 @@ var (
|
|||||||
|
|
||||||
forward_ManagementService_ReactivateApplication_0 = runtime.ForwardResponseMessage
|
forward_ManagementService_ReactivateApplication_0 = runtime.ForwardResponseMessage
|
||||||
|
|
||||||
|
forward_ManagementService_RemoveApplication_0 = runtime.ForwardResponseMessage
|
||||||
|
|
||||||
forward_ManagementService_UpdateApplicationOIDCConfig_0 = runtime.ForwardResponseMessage
|
forward_ManagementService_UpdateApplicationOIDCConfig_0 = runtime.ForwardResponseMessage
|
||||||
|
|
||||||
forward_ManagementService_RegenerateOIDCClientSecret_0 = runtime.ForwardResponseMessage
|
forward_ManagementService_RegenerateOIDCClientSecret_0 = runtime.ForwardResponseMessage
|
||||||
|
@ -1318,7 +1318,7 @@
|
|||||||
"200": {
|
"200": {
|
||||||
"description": "A successful response.",
|
"description": "A successful response.",
|
||||||
"schema": {
|
"schema": {
|
||||||
"properties": {}
|
"$ref": "#/definitions/v1ProjectRole"
|
||||||
}
|
}
|
||||||
}
|
}
|
||||||
},
|
},
|
||||||
@ -1343,7 +1343,7 @@
|
|||||||
]
|
]
|
||||||
}
|
}
|
||||||
},
|
},
|
||||||
"/projects/{id}/roles/{name}": {
|
"/projects/{id}/roles/{key}": {
|
||||||
"delete": {
|
"delete": {
|
||||||
"operationId": "RemoveProjectRole",
|
"operationId": "RemoveProjectRole",
|
||||||
"responses": {
|
"responses": {
|
||||||
@ -1362,7 +1362,7 @@
|
|||||||
"type": "string"
|
"type": "string"
|
||||||
},
|
},
|
||||||
{
|
{
|
||||||
"name": "name",
|
"name": "key",
|
||||||
"in": "path",
|
"in": "path",
|
||||||
"required": true,
|
"required": true,
|
||||||
"type": "string"
|
"type": "string"
|
||||||
@ -1371,6 +1371,42 @@
|
|||||||
"tags": [
|
"tags": [
|
||||||
"ManagementService"
|
"ManagementService"
|
||||||
]
|
]
|
||||||
|
},
|
||||||
|
"put": {
|
||||||
|
"operationId": "ChangeProjectRole",
|
||||||
|
"responses": {
|
||||||
|
"200": {
|
||||||
|
"description": "A successful response.",
|
||||||
|
"schema": {
|
||||||
|
"$ref": "#/definitions/v1ProjectRole"
|
||||||
|
}
|
||||||
|
}
|
||||||
|
},
|
||||||
|
"parameters": [
|
||||||
|
{
|
||||||
|
"name": "id",
|
||||||
|
"in": "path",
|
||||||
|
"required": true,
|
||||||
|
"type": "string"
|
||||||
|
},
|
||||||
|
{
|
||||||
|
"name": "key",
|
||||||
|
"in": "path",
|
||||||
|
"required": true,
|
||||||
|
"type": "string"
|
||||||
|
},
|
||||||
|
{
|
||||||
|
"name": "body",
|
||||||
|
"in": "body",
|
||||||
|
"required": true,
|
||||||
|
"schema": {
|
||||||
|
"$ref": "#/definitions/v1ProjectRoleChange"
|
||||||
|
}
|
||||||
|
}
|
||||||
|
],
|
||||||
|
"tags": [
|
||||||
|
"ManagementService"
|
||||||
|
]
|
||||||
}
|
}
|
||||||
},
|
},
|
||||||
"/projects/{project_id}/applications/_search": {
|
"/projects/{project_id}/applications/_search": {
|
||||||
@ -1473,6 +1509,34 @@
|
|||||||
"ManagementService"
|
"ManagementService"
|
||||||
]
|
]
|
||||||
},
|
},
|
||||||
|
"delete": {
|
||||||
|
"operationId": "RemoveApplication",
|
||||||
|
"responses": {
|
||||||
|
"200": {
|
||||||
|
"description": "A successful response.",
|
||||||
|
"schema": {
|
||||||
|
"properties": {}
|
||||||
|
}
|
||||||
|
}
|
||||||
|
},
|
||||||
|
"parameters": [
|
||||||
|
{
|
||||||
|
"name": "project_id",
|
||||||
|
"in": "path",
|
||||||
|
"required": true,
|
||||||
|
"type": "string"
|
||||||
|
},
|
||||||
|
{
|
||||||
|
"name": "id",
|
||||||
|
"in": "path",
|
||||||
|
"required": true,
|
||||||
|
"type": "string"
|
||||||
|
}
|
||||||
|
],
|
||||||
|
"tags": [
|
||||||
|
"ManagementService"
|
||||||
|
]
|
||||||
|
},
|
||||||
"put": {
|
"put": {
|
||||||
"operationId": "UpdateApplication",
|
"operationId": "UpdateApplication",
|
||||||
"responses": {
|
"responses": {
|
||||||
@ -3868,7 +3932,7 @@
|
|||||||
"enum": [
|
"enum": [
|
||||||
"OIDCRESPONSETYPE_CODE",
|
"OIDCRESPONSETYPE_CODE",
|
||||||
"OIDCRESPONSETYPE_ID_TOKEN",
|
"OIDCRESPONSETYPE_ID_TOKEN",
|
||||||
"OIDCRESPONSETYPE_TOKEN_ID_TOKEN"
|
"OIDCRESPONSETYPE_TOKEN"
|
||||||
],
|
],
|
||||||
"default": "OIDCRESPONSETYPE_CODE"
|
"default": "OIDCRESPONSETYPE_CODE"
|
||||||
},
|
},
|
||||||
@ -4898,7 +4962,7 @@
|
|||||||
"project_id": {
|
"project_id": {
|
||||||
"type": "string"
|
"type": "string"
|
||||||
},
|
},
|
||||||
"name": {
|
"key": {
|
||||||
"type": "string"
|
"type": "string"
|
||||||
},
|
},
|
||||||
"display_name": {
|
"display_name": {
|
||||||
@ -4908,6 +4972,10 @@
|
|||||||
"type": "string",
|
"type": "string",
|
||||||
"format": "date-time"
|
"format": "date-time"
|
||||||
},
|
},
|
||||||
|
"change_date": {
|
||||||
|
"type": "string",
|
||||||
|
"format": "date-time"
|
||||||
|
},
|
||||||
"group": {
|
"group": {
|
||||||
"type": "string"
|
"type": "string"
|
||||||
},
|
},
|
||||||
@ -4923,7 +4991,24 @@
|
|||||||
"id": {
|
"id": {
|
||||||
"type": "string"
|
"type": "string"
|
||||||
},
|
},
|
||||||
"name": {
|
"key": {
|
||||||
|
"type": "string"
|
||||||
|
},
|
||||||
|
"display_name": {
|
||||||
|
"type": "string"
|
||||||
|
},
|
||||||
|
"group": {
|
||||||
|
"type": "string"
|
||||||
|
}
|
||||||
|
}
|
||||||
|
},
|
||||||
|
"v1ProjectRoleChange": {
|
||||||
|
"type": "object",
|
||||||
|
"properties": {
|
||||||
|
"id": {
|
||||||
|
"type": "string"
|
||||||
|
},
|
||||||
|
"key": {
|
||||||
"type": "string"
|
"type": "string"
|
||||||
},
|
},
|
||||||
"display_name": {
|
"display_name": {
|
||||||
@ -4938,7 +5023,7 @@
|
|||||||
"type": "string",
|
"type": "string",
|
||||||
"enum": [
|
"enum": [
|
||||||
"PROJECTROLESEARCHKEY_UNSPECIFIED",
|
"PROJECTROLESEARCHKEY_UNSPECIFIED",
|
||||||
"PROJECTROLESEARCHKEY_NAME",
|
"PROJECTROLESEARCHKEY_KEY",
|
||||||
"PROJECTROLESEARCHKEY_DISPLAY_NAME"
|
"PROJECTROLESEARCHKEY_DISPLAY_NAME"
|
||||||
],
|
],
|
||||||
"default": "PROJECTROLESEARCHKEY_UNSPECIFIED"
|
"default": "PROJECTROLESEARCHKEY_UNSPECIFIED"
|
||||||
|
@ -98,14 +98,14 @@ func (mr *MockManagementServiceClientMockRecorder) AddProjectMember(arg0, arg1 i
|
|||||||
}
|
}
|
||||||
|
|
||||||
// AddProjectRole mocks base method
|
// AddProjectRole mocks base method
|
||||||
func (m *MockManagementServiceClient) AddProjectRole(arg0 context.Context, arg1 *grpc.ProjectRoleAdd, arg2 ...grpc0.CallOption) (*emptypb.Empty, error) {
|
func (m *MockManagementServiceClient) AddProjectRole(arg0 context.Context, arg1 *grpc.ProjectRoleAdd, arg2 ...grpc0.CallOption) (*grpc.ProjectRole, error) {
|
||||||
m.ctrl.T.Helper()
|
m.ctrl.T.Helper()
|
||||||
varargs := []interface{}{arg0, arg1}
|
varargs := []interface{}{arg0, arg1}
|
||||||
for _, a := range arg2 {
|
for _, a := range arg2 {
|
||||||
varargs = append(varargs, a)
|
varargs = append(varargs, a)
|
||||||
}
|
}
|
||||||
ret := m.ctrl.Call(m, "AddProjectRole", varargs...)
|
ret := m.ctrl.Call(m, "AddProjectRole", varargs...)
|
||||||
ret0, _ := ret[0].(*emptypb.Empty)
|
ret0, _ := ret[0].(*grpc.ProjectRole)
|
||||||
ret1, _ := ret[1].(error)
|
ret1, _ := ret[1].(error)
|
||||||
return ret0, ret1
|
return ret0, ret1
|
||||||
}
|
}
|
||||||
@ -217,6 +217,26 @@ func (mr *MockManagementServiceClientMockRecorder) ChangeProjectMember(arg0, arg
|
|||||||
return mr.mock.ctrl.RecordCallWithMethodType(mr.mock, "ChangeProjectMember", reflect.TypeOf((*MockManagementServiceClient)(nil).ChangeProjectMember), varargs...)
|
return mr.mock.ctrl.RecordCallWithMethodType(mr.mock, "ChangeProjectMember", reflect.TypeOf((*MockManagementServiceClient)(nil).ChangeProjectMember), varargs...)
|
||||||
}
|
}
|
||||||
|
|
||||||
|
// ChangeProjectRole mocks base method
|
||||||
|
func (m *MockManagementServiceClient) ChangeProjectRole(arg0 context.Context, arg1 *grpc.ProjectRoleChange, arg2 ...grpc0.CallOption) (*grpc.ProjectRole, error) {
|
||||||
|
m.ctrl.T.Helper()
|
||||||
|
varargs := []interface{}{arg0, arg1}
|
||||||
|
for _, a := range arg2 {
|
||||||
|
varargs = append(varargs, a)
|
||||||
|
}
|
||||||
|
ret := m.ctrl.Call(m, "ChangeProjectRole", varargs...)
|
||||||
|
ret0, _ := ret[0].(*grpc.ProjectRole)
|
||||||
|
ret1, _ := ret[1].(error)
|
||||||
|
return ret0, ret1
|
||||||
|
}
|
||||||
|
|
||||||
|
// ChangeProjectRole indicates an expected call of ChangeProjectRole
|
||||||
|
func (mr *MockManagementServiceClientMockRecorder) ChangeProjectRole(arg0, arg1 interface{}, arg2 ...interface{}) *gomock.Call {
|
||||||
|
mr.mock.ctrl.T.Helper()
|
||||||
|
varargs := append([]interface{}{arg0, arg1}, arg2...)
|
||||||
|
return mr.mock.ctrl.RecordCallWithMethodType(mr.mock, "ChangeProjectRole", reflect.TypeOf((*MockManagementServiceClient)(nil).ChangeProjectRole), varargs...)
|
||||||
|
}
|
||||||
|
|
||||||
// ChangeUserEmail mocks base method
|
// ChangeUserEmail mocks base method
|
||||||
func (m *MockManagementServiceClient) ChangeUserEmail(arg0 context.Context, arg1 *grpc.UpdateUserEmailRequest, arg2 ...grpc0.CallOption) (*grpc.UserEmail, error) {
|
func (m *MockManagementServiceClient) ChangeUserEmail(arg0 context.Context, arg1 *grpc.UpdateUserEmailRequest, arg2 ...grpc0.CallOption) (*grpc.UserEmail, error) {
|
||||||
m.ctrl.T.Helper()
|
m.ctrl.T.Helper()
|
||||||
|
@ -51,11 +51,24 @@ func (s *Server) GetGrantedProjectGrantByID(ctx context.Context, request *Grante
|
|||||||
return nil, errors.ThrowUnimplemented(nil, "GRPC-974vd", "Not implemented")
|
return nil, errors.ThrowUnimplemented(nil, "GRPC-974vd", "Not implemented")
|
||||||
}
|
}
|
||||||
|
|
||||||
func (s *Server) AddProjectRole(ctx context.Context, in *ProjectRoleAdd) (*empty.Empty, error) {
|
func (s *Server) AddProjectRole(ctx context.Context, in *ProjectRoleAdd) (*ProjectRole, error) {
|
||||||
return nil, errors.ThrowUnimplemented(nil, "GRPC-0ow2C", "Not implemented")
|
role, err := s.project.AddProjectRole(ctx, projectRoleAddToModel(in))
|
||||||
|
if err != nil {
|
||||||
|
return nil, err
|
||||||
|
}
|
||||||
|
return projectRoleFromModel(role), nil
|
||||||
}
|
}
|
||||||
|
func (s *Server) ChangeProjectRole(ctx context.Context, in *ProjectRoleChange) (*ProjectRole, error) {
|
||||||
|
role, err := s.project.ChangeProjectRole(ctx, projectRoleChangeToModel(in))
|
||||||
|
if err != nil {
|
||||||
|
return nil, err
|
||||||
|
}
|
||||||
|
return projectRoleFromModel(role), nil
|
||||||
|
}
|
||||||
|
|
||||||
func (s *Server) RemoveProjectRole(ctx context.Context, in *ProjectRoleRemove) (*empty.Empty, error) {
|
func (s *Server) RemoveProjectRole(ctx context.Context, in *ProjectRoleRemove) (*empty.Empty, error) {
|
||||||
return nil, errors.ThrowUnimplemented(nil, "GRPC-bm6iB", "Not implemented")
|
err := s.project.RemoveProjectRole(ctx, in.Id, in.Key)
|
||||||
|
return &empty.Empty{}, err
|
||||||
}
|
}
|
||||||
|
|
||||||
func (s *Server) SearchProjectRoles(ctx context.Context, in *ProjectRoleSearchRequest) (*ProjectRoleSearchResponse, error) {
|
func (s *Server) SearchProjectRoles(ctx context.Context, in *ProjectRoleSearchRequest) (*ProjectRoleSearchResponse, error) {
|
||||||
|
@ -15,7 +15,7 @@ func projectFromModel(project *proj_model.Project) *Project {
|
|||||||
logging.Log("GRPC-di7rw").OnError(err).Debug("unable to parse timestamp")
|
logging.Log("GRPC-di7rw").OnError(err).Debug("unable to parse timestamp")
|
||||||
|
|
||||||
return &Project{
|
return &Project{
|
||||||
Id: project.ID,
|
Id: project.AggregateID,
|
||||||
State: projectStateFromModel(project.State),
|
State: projectStateFromModel(project.State),
|
||||||
CreationDate: creationDate,
|
CreationDate: creationDate,
|
||||||
ChangeDate: changeDate,
|
ChangeDate: changeDate,
|
||||||
@ -26,9 +26,9 @@ func projectFromModel(project *proj_model.Project) *Project {
|
|||||||
|
|
||||||
func projectStateFromModel(state proj_model.ProjectState) ProjectState {
|
func projectStateFromModel(state proj_model.ProjectState) ProjectState {
|
||||||
switch state {
|
switch state {
|
||||||
case proj_model.Active:
|
case proj_model.PROJECTSTATE_ACTIVE:
|
||||||
return ProjectState_PROJECTSTATE_ACTIVE
|
return ProjectState_PROJECTSTATE_ACTIVE
|
||||||
case proj_model.Inactive:
|
case proj_model.PROJECTSTATE_INACTIVE:
|
||||||
return ProjectState_PROJECTSTATE_INACTIVE
|
return ProjectState_PROJECTSTATE_INACTIVE
|
||||||
default:
|
default:
|
||||||
return ProjectState_PROJECTSTATE_UNSPECIFIED
|
return ProjectState_PROJECTSTATE_UNSPECIFIED
|
||||||
@ -38,8 +38,47 @@ func projectStateFromModel(state proj_model.ProjectState) ProjectState {
|
|||||||
func projectUpdateToModel(project *ProjectUpdateRequest) *proj_model.Project {
|
func projectUpdateToModel(project *ProjectUpdateRequest) *proj_model.Project {
|
||||||
return &proj_model.Project{
|
return &proj_model.Project{
|
||||||
ObjectRoot: models.ObjectRoot{
|
ObjectRoot: models.ObjectRoot{
|
||||||
ID: project.Id,
|
AggregateID: project.Id,
|
||||||
},
|
},
|
||||||
Name: project.Name,
|
Name: project.Name,
|
||||||
}
|
}
|
||||||
}
|
}
|
||||||
|
|
||||||
|
func projectRoleFromModel(role *proj_model.ProjectRole) *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 &ProjectRole{
|
||||||
|
CreationDate: creationDate,
|
||||||
|
ChangeDate: changeDate,
|
||||||
|
Sequence: role.Sequence,
|
||||||
|
Key: role.Key,
|
||||||
|
DisplayName: role.DisplayName,
|
||||||
|
Group: role.Group,
|
||||||
|
}
|
||||||
|
}
|
||||||
|
|
||||||
|
func projectRoleAddToModel(role *ProjectRoleAdd) *proj_model.ProjectRole {
|
||||||
|
return &proj_model.ProjectRole{
|
||||||
|
ObjectRoot: models.ObjectRoot{
|
||||||
|
AggregateID: role.Id,
|
||||||
|
},
|
||||||
|
Key: role.Key,
|
||||||
|
DisplayName: role.DisplayName,
|
||||||
|
Group: role.Group,
|
||||||
|
}
|
||||||
|
}
|
||||||
|
|
||||||
|
func projectRoleChangeToModel(role *ProjectRoleChange) *proj_model.ProjectRole {
|
||||||
|
return &proj_model.ProjectRole{
|
||||||
|
ObjectRoot: models.ObjectRoot{
|
||||||
|
AggregateID: role.Id,
|
||||||
|
},
|
||||||
|
Key: role.Key,
|
||||||
|
DisplayName: role.DisplayName,
|
||||||
|
Group: role.Group,
|
||||||
|
}
|
||||||
|
}
|
||||||
|
@ -26,7 +26,7 @@ func projectMemberFromModel(member *proj_model.ProjectMember) *ProjectMember {
|
|||||||
func projectMemberAddToModel(member *ProjectMemberAdd) *proj_model.ProjectMember {
|
func projectMemberAddToModel(member *ProjectMemberAdd) *proj_model.ProjectMember {
|
||||||
return &proj_model.ProjectMember{
|
return &proj_model.ProjectMember{
|
||||||
ObjectRoot: models.ObjectRoot{
|
ObjectRoot: models.ObjectRoot{
|
||||||
ID: member.Id,
|
AggregateID: member.Id,
|
||||||
},
|
},
|
||||||
UserID: member.UserId,
|
UserID: member.UserId,
|
||||||
Roles: member.Roles,
|
Roles: member.Roles,
|
||||||
@ -36,7 +36,7 @@ func projectMemberAddToModel(member *ProjectMemberAdd) *proj_model.ProjectMember
|
|||||||
func projectMemberChangeToModel(member *ProjectMemberChange) *proj_model.ProjectMember {
|
func projectMemberChangeToModel(member *ProjectMemberChange) *proj_model.ProjectMember {
|
||||||
return &proj_model.ProjectMember{
|
return &proj_model.ProjectMember{
|
||||||
ObjectRoot: models.ObjectRoot{
|
ObjectRoot: models.ObjectRoot{
|
||||||
ID: member.Id,
|
AggregateID: member.Id,
|
||||||
},
|
},
|
||||||
UserID: member.UserId,
|
UserID: member.UserId,
|
||||||
Roles: member.Roles,
|
Roles: member.Roles,
|
||||||
|
@ -722,7 +722,7 @@ service ManagementService {
|
|||||||
};
|
};
|
||||||
}
|
}
|
||||||
|
|
||||||
rpc AddProjectRole(ProjectRoleAdd) returns (google.protobuf.Empty) {
|
rpc AddProjectRole(ProjectRoleAdd) returns (ProjectRole) {
|
||||||
option (google.api.http) = {
|
option (google.api.http) = {
|
||||||
post: "/projects/{id}/roles"
|
post: "/projects/{id}/roles"
|
||||||
body: "*"
|
body: "*"
|
||||||
@ -734,9 +734,21 @@ service ManagementService {
|
|||||||
};
|
};
|
||||||
}
|
}
|
||||||
|
|
||||||
|
rpc ChangeProjectRole(ProjectRoleChange) returns (ProjectRole) {
|
||||||
|
option (google.api.http) = {
|
||||||
|
put: "/projects/{id}/roles/{key}"
|
||||||
|
body: "*"
|
||||||
|
};
|
||||||
|
|
||||||
|
option (caos.zitadel.utils.v1.auth_option) = {
|
||||||
|
permission: "project.role.write"
|
||||||
|
check_field_name: "Id"
|
||||||
|
};
|
||||||
|
}
|
||||||
|
|
||||||
rpc RemoveProjectRole(ProjectRoleRemove) returns (google.protobuf.Empty) {
|
rpc RemoveProjectRole(ProjectRoleRemove) returns (google.protobuf.Empty) {
|
||||||
option (google.api.http) = {
|
option (google.api.http) = {
|
||||||
delete: "/projects/{id}/roles/{name}"
|
delete: "/projects/{id}/roles/{key}"
|
||||||
};
|
};
|
||||||
|
|
||||||
option (caos.zitadel.utils.v1.auth_option) = {
|
option (caos.zitadel.utils.v1.auth_option) = {
|
||||||
@ -817,6 +829,17 @@ service ManagementService {
|
|||||||
};
|
};
|
||||||
}
|
}
|
||||||
|
|
||||||
|
rpc RemoveApplication(ApplicationID) returns (google.protobuf.Empty) {
|
||||||
|
option (google.api.http) = {
|
||||||
|
delete: "/projects/{project_id}/applications/{id}"
|
||||||
|
};
|
||||||
|
|
||||||
|
option (caos.zitadel.utils.v1.auth_option) = {
|
||||||
|
permission: "project.app.delete"
|
||||||
|
check_field_name: "ProjectId"
|
||||||
|
};
|
||||||
|
}
|
||||||
|
|
||||||
rpc UpdateApplicationOIDCConfig(OIDCConfigUpdate) returns (OIDCConfig) {
|
rpc UpdateApplicationOIDCConfig(OIDCConfigUpdate) returns (OIDCConfig) {
|
||||||
option (google.api.http) = {
|
option (google.api.http) = {
|
||||||
put: "/projects/{project_id}/applications/{application_id}/oidcconfig"
|
put: "/projects/{project_id}/applications/{application_id}/oidcconfig"
|
||||||
@ -1725,23 +1748,31 @@ message ProjectMemberRemove {
|
|||||||
|
|
||||||
message ProjectRoleAdd {
|
message ProjectRoleAdd {
|
||||||
string id = 1;
|
string id = 1;
|
||||||
string name = 2;
|
string key = 2;
|
||||||
|
string display_name = 3;
|
||||||
|
string group = 4;
|
||||||
|
}
|
||||||
|
|
||||||
|
message ProjectRoleChange {
|
||||||
|
string id = 1;
|
||||||
|
string key = 2;
|
||||||
string display_name = 3;
|
string display_name = 3;
|
||||||
string group = 4;
|
string group = 4;
|
||||||
}
|
}
|
||||||
|
|
||||||
message ProjectRole {
|
message ProjectRole {
|
||||||
string project_id = 1;
|
string project_id = 1;
|
||||||
string name = 2;
|
string key = 2;
|
||||||
string display_name = 3;
|
string display_name = 3;
|
||||||
google.protobuf.Timestamp creation_date = 4;
|
google.protobuf.Timestamp creation_date = 4;
|
||||||
string group = 5;
|
google.protobuf.Timestamp change_date = 5;
|
||||||
uint64 sequence = 6;
|
string group = 6;
|
||||||
|
uint64 sequence = 7;
|
||||||
}
|
}
|
||||||
|
|
||||||
message ProjectRoleRemove {
|
message ProjectRoleRemove {
|
||||||
string id = 1;
|
string id = 1;
|
||||||
string name = 2;
|
string key = 2;
|
||||||
}
|
}
|
||||||
|
|
||||||
message ProjectRoleSearchResponse {
|
message ProjectRoleSearchResponse {
|
||||||
@ -1766,7 +1797,7 @@ message ProjectRoleSearchQuery {
|
|||||||
|
|
||||||
enum ProjectRoleSearchKey {
|
enum ProjectRoleSearchKey {
|
||||||
PROJECTROLESEARCHKEY_UNSPECIFIED = 0;
|
PROJECTROLESEARCHKEY_UNSPECIFIED = 0;
|
||||||
PROJECTROLESEARCHKEY_NAME = 1;
|
PROJECTROLESEARCHKEY_KEY = 1;
|
||||||
PROJECTROLESEARCHKEY_DISPLAY_NAME = 2;
|
PROJECTROLESEARCHKEY_DISPLAY_NAME = 2;
|
||||||
}
|
}
|
||||||
|
|
||||||
@ -1859,7 +1890,7 @@ message OIDCConfigUpdate {
|
|||||||
enum OIDCResponseType {
|
enum OIDCResponseType {
|
||||||
OIDCRESPONSETYPE_CODE = 0;
|
OIDCRESPONSETYPE_CODE = 0;
|
||||||
OIDCRESPONSETYPE_ID_TOKEN = 1;
|
OIDCRESPONSETYPE_ID_TOKEN = 1;
|
||||||
OIDCRESPONSETYPE_TOKEN_ID_TOKEN = 2;
|
OIDCRESPONSETYPE_TOKEN = 2;
|
||||||
}
|
}
|
||||||
|
|
||||||
enum OIDCGrantType {
|
enum OIDCGrantType {
|
||||||
|
Loading…
x
Reference in New Issue
Block a user