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:
Fabi
2020-04-21 17:00:32 +02:00
committed by GitHub
parent 802bb56ea1
commit 04b4cd80b8
42 changed files with 7857 additions and 2951 deletions

View 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
}

View 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)
}
})
}
}

View 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
}

View File

@@ -2,37 +2,35 @@ package model
import (
es_models "github.com/caos/zitadel/internal/eventstore/models"
in_model "github.com/caos/zitadel/internal/model"
)
type Project struct {
es_models.ObjectRoot
State ProjectState
Name string
Members []*ProjectMember
State ProjectState
Name string
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 {
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 {
if p.State == Active {
return true
}
return false
return p.State == PROJECTSTATE_ACTIVE
}
func (p *Project) IsValid() bool {
if p.Name == "" {
return false
}
return true
return p.Name != ""
}
func (p *Project) ContainsMember(member *ProjectMember) bool {
@@ -43,3 +41,21 @@ func (p *Project) ContainsMember(member *ProjectMember) bool {
}
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
}

View File

@@ -10,9 +10,9 @@ type ProjectMember struct {
}
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 {
return p.ID != "" && p.UserID != "" && len(p.Roles) != 0
return p.AggregateID != "" && p.UserID != "" && len(p.Roles) != 0
}

View 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 != ""
}

View File

@@ -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)
}

View File

@@ -15,6 +15,7 @@ const (
ProjectMemberRemoved models.EventType = "project.member.removed"
ProjectRoleAdded models.EventType = "project.role.added"
ProjectRoleChanged models.EventType = "project.role.changed"
ProjectRoleRemoved models.EventType = "project.role.removed"
ProjectGrantAdded models.EventType = "project.grant.added"
@@ -28,6 +29,7 @@ const (
ApplicationAdded models.EventType = "project.application.added"
ApplicationChanged models.EventType = "project.application.changed"
ApplicationRemoved models.EventType = "project.application.removed"
ApplicationDeactivated models.EventType = "project.application.deactivated"
ApplicationReactivated models.EventType = "project.application.reactivated"