feat: idp and login policy configurations (#619)

* feat: oidc config

* fix: oidc configurations

* feat: oidc idp config

* feat: add oidc config test

* fix: tests

* fix: tests

* feat: translate new events

* feat: idp eventstore

* feat: idp eventstore

* fix: tests

* feat: command side idp

* feat: query side idp

* feat: idp config on org

* fix: tests

* feat: authz idp on org

* feat: org idps

* feat: login policy

* feat: login policy

* feat: login policy

* feat: add idp func on login policy

* feat: add validation to loginpolicy and idp provider

* feat: add default login policy

* feat: login policy on org

* feat: login policy on org

* fix: id config handlers

* fix: id config handlers

* fix: create idp on org

* fix: create idp on org

* fix: not existing idp config

* fix: default login policy

* fix: add login policy on org

* fix: idp provider search on org

* fix: test

* fix: remove idp on org

* fix: test

* fix: test

* fix: remove admin idp

* fix: logo src as byte

* fix: migration

* fix: tests

* Update internal/iam/repository/eventsourcing/iam.go

Co-authored-by: Silvan <silvan.reusser@gmail.com>

* Update internal/iam/repository/eventsourcing/iam_test.go

Co-authored-by: Silvan <silvan.reusser@gmail.com>

* Update internal/iam/repository/eventsourcing/iam_test.go

Co-authored-by: Silvan <silvan.reusser@gmail.com>

* Update internal/iam/repository/eventsourcing/model/login_policy.go

Co-authored-by: Silvan <silvan.reusser@gmail.com>

* Update internal/iam/repository/eventsourcing/model/login_policy.go

Co-authored-by: Silvan <silvan.reusser@gmail.com>

* Update internal/org/repository/eventsourcing/org_test.go

Co-authored-by: Silvan <silvan.reusser@gmail.com>

* Update internal/iam/repository/eventsourcing/model/login_policy_test.go

Co-authored-by: Silvan <silvan.reusser@gmail.com>

* Update internal/iam/repository/eventsourcing/model/login_policy_test.go

Co-authored-by: Silvan <silvan.reusser@gmail.com>

* fix: pr comments

* fix: tests

* Update types.go

* fix: merge request changes

* fix: reduce optimization

Co-authored-by: Silvan <silvan.reusser@gmail.com>
Co-authored-by: Livio Amstutz <livio.a@gmail.com>
This commit is contained in:
Fabi
2020-08-26 09:56:23 +02:00
committed by GitHub
parent f05c5bae24
commit db1d8f4efe
157 changed files with 37510 additions and 15698 deletions

View File

@@ -4,16 +4,18 @@ import (
es_models "github.com/caos/zitadel/internal/eventstore/models"
)
type Iam struct {
type IAM struct {
es_models.ObjectRoot
GlobalOrgID string
IamProjectID string
SetUpDone bool
SetUpStarted bool
Members []*IamMember
GlobalOrgID string
IAMProjectID string
SetUpDone bool
SetUpStarted bool
Members []*IAMMember
IDPs []*IDPConfig
DefaultLoginPolicy *LoginPolicy
}
func (iam *Iam) GetMember(userID string) (int, *IamMember) {
func (iam *IAM) GetMember(userID string) (int, *IAMMember) {
for i, m := range iam.Members {
if m.UserID == userID {
return i, m
@@ -21,3 +23,12 @@ func (iam *Iam) GetMember(userID string) (int, *IamMember) {
}
return -1, nil
}
func (iam *IAM) GetIDP(idpID string) (int, *IDPConfig) {
for i, idp := range iam.IDPs {
if idp.IDPConfigID == idpID {
return i, idp
}
}
return -1, nil
}

View File

@@ -2,17 +2,17 @@ package model
import es_models "github.com/caos/zitadel/internal/eventstore/models"
type IamMember struct {
type IAMMember struct {
es_models.ObjectRoot
UserID string
Roles []string
}
func NewIamMember(iamID, userID string) *IamMember {
return &IamMember{ObjectRoot: es_models.ObjectRoot{AggregateID: iamID}, UserID: userID}
func NewIAMMember(iamID, userID string) *IAMMember {
return &IAMMember{ObjectRoot: es_models.ObjectRoot{AggregateID: iamID}, UserID: userID}
}
func (i *IamMember) IsValid() bool {
func (i *IAMMember) IsValid() bool {
return i.AggregateID != "" && i.UserID != "" && len(i.Roles) != 0
}

View File

@@ -5,9 +5,9 @@ import (
"time"
)
type IamMemberView struct {
type IAMMemberView struct {
UserID string
IamID string
IAMID string
UserName string
Email string
FirstName string
@@ -19,42 +19,42 @@ type IamMemberView struct {
Sequence uint64
}
type IamMemberSearchRequest struct {
type IAMMemberSearchRequest struct {
Offset uint64
Limit uint64
SortingColumn IamMemberSearchKey
SortingColumn IAMMemberSearchKey
Asc bool
Queries []*IamMemberSearchQuery
Queries []*IAMMemberSearchQuery
}
type IamMemberSearchKey int32
type IAMMemberSearchKey int32
const (
IamMemberSearchKeyUnspecified IamMemberSearchKey = iota
IamMemberSearchKeyUserName
IamMemberSearchKeyEmail
IamMemberSearchKeyFirstName
IamMemberSearchKeyLastName
IamMemberSearchKeyIamID
IamMemberSearchKeyUserID
IAMMemberSearchKeyUnspecified IAMMemberSearchKey = iota
IAMMemberSearchKeyUserName
IAMMemberSearchKeyEmail
IAMMemberSearchKeyFirstName
IAMMemberSearchKeyLastName
IAMMemberSearchKeyIamID
IAMMemberSearchKeyUserID
)
type IamMemberSearchQuery struct {
Key IamMemberSearchKey
type IAMMemberSearchQuery struct {
Key IAMMemberSearchKey
Method model.SearchMethod
Value interface{}
}
type IamMemberSearchResponse struct {
type IAMMemberSearchResponse struct {
Offset uint64
Limit uint64
TotalResult uint64
Result []*IamMemberView
Result []*IAMMemberView
Sequence uint64
Timestamp time.Time
}
func (r *IamMemberSearchRequest) EnsureLimit(limit uint64) {
func (r *IAMMemberSearchRequest) EnsureLimit(limit uint64) {
if r.Limit == 0 || r.Limit > limit {
r.Limit = limit
}

View File

@@ -0,0 +1,74 @@
package model
import (
"github.com/caos/zitadel/internal/crypto"
es_models "github.com/caos/zitadel/internal/eventstore/models"
)
type IDPConfig struct {
es_models.ObjectRoot
IDPConfigID string
Type IdpConfigType
Name string
LogoSrc []byte
State IDPConfigState
OIDCConfig *OIDCIDPConfig
}
type OIDCIDPConfig struct {
es_models.ObjectRoot
IDPConfigID string
ClientID string
ClientSecret *crypto.CryptoValue
ClientSecretString string
Issuer string
Scopes []string
}
type IdpConfigType int32
const (
IDPConfigTypeOIDC IdpConfigType = iota
IDPConfigTypeSAML
)
type IDPConfigState int32
const (
IDPConfigStateActive IDPConfigState = iota
IDPConfigStateInactive
IDPConfigStateRemoved
)
func NewIDPConfig(iamID, idpID string) *IDPConfig {
return &IDPConfig{ObjectRoot: es_models.ObjectRoot{AggregateID: iamID}, IDPConfigID: idpID}
}
func (idp *IDPConfig) IsValid(includeConfig bool) bool {
if idp.Name == "" || idp.AggregateID == "" {
return false
}
if !includeConfig {
return true
}
if idp.Type == IDPConfigTypeOIDC && !idp.OIDCConfig.IsValid(true) {
return false
}
return true
}
func (oi *OIDCIDPConfig) IsValid(withSecret bool) bool {
if withSecret {
return oi.ClientID != "" && oi.Issuer != "" && oi.ClientSecretString != ""
}
return oi.ClientID != "" && oi.Issuer != ""
}
func (oi *OIDCIDPConfig) CryptSecret(crypt crypto.Crypto) error {
cryptedSecret, err := crypto.Crypt([]byte(oi.ClientSecretString), crypt)
if err != nil {
return err
}
oi.ClientSecret = cryptedSecret
return nil
}

View File

@@ -0,0 +1,68 @@
package model
import (
"github.com/caos/zitadel/internal/crypto"
"github.com/caos/zitadel/internal/model"
"time"
)
type IDPConfigView struct {
AggregateID string
IDPConfigID string
Name string
LogoSrc []byte
State IDPConfigState
CreationDate time.Time
ChangeDate time.Time
Sequence uint64
IDPProviderType IDPProviderType
IsOIDC bool
OIDCClientID string
OIDCClientSecret *crypto.CryptoValue
OIDCIssuer string
OIDCScopes []string
}
type IDPConfigSearchRequest struct {
Offset uint64
Limit uint64
SortingColumn IDPConfigSearchKey
Asc bool
Queries []*IDPConfigSearchQuery
}
type IDPConfigSearchKey int32
const (
IDPConfigSearchKeyUnspecified IDPConfigSearchKey = iota
IDPConfigSearchKeyName
IDPConfigSearchKeyAggregateID
IDPConfigSearchKeyIdpConfigID
IDPConfigSearchKeyIdpProviderType
)
type IDPConfigSearchQuery struct {
Key IDPConfigSearchKey
Method model.SearchMethod
Value interface{}
}
type IDPConfigSearchResponse struct {
Offset uint64
Limit uint64
TotalResult uint64
Result []*IDPConfigView
Sequence uint64
Timestamp time.Time
}
func (r *IDPConfigSearchRequest) EnsureLimit(limit uint64) {
if r.Limit == 0 || r.Limit > limit {
r.Limit = limit
}
}
func (r *IDPConfigSearchRequest) AppendMyOrgQuery(orgID, iamID string) {
r.Queries = append(r.Queries, &IDPConfigSearchQuery{Key: IDPConfigSearchKeyAggregateID, Method: model.SearchMethodIsOneOf, Value: []string{orgID, iamID}})
}

View File

@@ -0,0 +1,59 @@
package model
import (
"github.com/caos/zitadel/internal/model"
"time"
)
type IDPProviderView struct {
AggregateID string
IDPConfigID string
IDPProviderType IDPProviderType
Name string
IDPConfigType IdpConfigType
CreationDate time.Time
ChangeDate time.Time
Sequence uint64
}
type IDPProviderSearchRequest struct {
Offset uint64
Limit uint64
SortingColumn IDPProviderSearchKey
Asc bool
Queries []*IDPProviderSearchQuery
}
type IDPProviderSearchKey int32
const (
IDPProviderSearchKeyUnspecified IDPProviderSearchKey = iota
IDPProviderSearchKeyAggregateID
IDPProviderSearchKeyIdpConfigID
)
type IDPProviderSearchQuery struct {
Key IDPProviderSearchKey
Method model.SearchMethod
Value interface{}
}
type IDPProviderSearchResponse struct {
Offset uint64
Limit uint64
TotalResult uint64
Result []*IDPProviderView
Sequence uint64
Timestamp time.Time
}
func (r *IDPProviderSearchRequest) EnsureLimit(limit uint64) {
if r.Limit == 0 || r.Limit > limit {
r.Limit = limit
}
}
func (r *IDPProviderSearchRequest) AppendAggregateIDQuery(aggregateID string) {
r.Queries = append(r.Queries, &IDPProviderSearchQuery{Key: IDPProviderSearchKeyAggregateID, Method: model.SearchMethodEquals, Value: aggregateID})
}

View File

@@ -0,0 +1,53 @@
package model
import (
"github.com/caos/zitadel/internal/eventstore/models"
)
type LoginPolicy struct {
models.ObjectRoot
State PolicyState
Default bool
AllowUsernamePassword bool
AllowRegister bool
AllowExternalIdp bool
IDPProviders []*IDPProvider
}
type IDPProvider struct {
models.ObjectRoot
Type IDPProviderType
IdpConfigID string
}
type PolicyState int32
const (
PolicyStateActive PolicyState = iota
PolicyStateRemoved
)
type IDPProviderType int32
const (
IDPProviderTypeSystem IDPProviderType = iota
IDPProviderTypeOrg
)
func (p *LoginPolicy) IsValid() bool {
return p.ObjectRoot.AggregateID != ""
}
func (p *IDPProvider) IsValid() bool {
return p.ObjectRoot.AggregateID != "" && p.IdpConfigID != ""
}
func (p *LoginPolicy) GetIdpProvider(id string) (int, *IDPProvider) {
for i, m := range p.IDPProviders {
if m.IdpConfigID == id {
return i, m
}
}
return -1, nil
}

View File

@@ -0,0 +1,48 @@
package model
import (
"github.com/caos/zitadel/internal/model"
"time"
)
type LoginPolicyView struct {
AggregateID string
AllowUsernamePassword bool
AllowRegister bool
AllowExternalIDP bool
Default bool
CreationDate time.Time
ChangeDate time.Time
Sequence uint64
}
type LoginPolicySearchRequest struct {
Offset uint64
Limit uint64
SortingColumn LoginPolicySearchKey
Asc bool
Queries []*LoginPolicySearchQuery
}
type LoginPolicySearchKey int32
const (
LoginPolicySearchKeyUnspecified LoginPolicySearchKey = iota
LoginPolicySearchKeyAggregateID
)
type LoginPolicySearchQuery struct {
Key LoginPolicySearchKey
Method model.SearchMethod
Value interface{}
}
type LoginPolicySearchResponse struct {
Offset uint64
Limit uint64
TotalResult uint64
Result []*LoginPolicyView
Sequence uint64
Timestamp time.Time
}