mirror of
https://github.com/zitadel/zitadel.git
synced 2025-08-12 07:07:32 +00:00
feat: OIDC setting (#3245)
* feat: add oidc config struct * feat: oidc config command side * feat: oidc configuration query side * feat: add translations * feat: add tests * feat: add translations * feat: rename oidc config to oidc settings * feat: rename oidc config to oidc settings
This commit is contained in:
@@ -188,6 +188,30 @@ Update twilio sms provider token
|
|||||||
PUT: /sms/twilio/{id}/token
|
PUT: /sms/twilio/{id}/token
|
||||||
|
|
||||||
|
|
||||||
|
### GetOIDCSettings
|
||||||
|
|
||||||
|
> **rpc** GetOIDCSettings([GetOIDCSettingsRequest](#getoidcsettingsrequest))
|
||||||
|
[GetOIDCSettingsResponse](#getoidcsettingsresponse)
|
||||||
|
|
||||||
|
Get OIDC settings (e.g token lifetimes, etc.)
|
||||||
|
|
||||||
|
|
||||||
|
|
||||||
|
GET: /settings/oidc
|
||||||
|
|
||||||
|
|
||||||
|
### UpdateOIDCSettings
|
||||||
|
|
||||||
|
> **rpc** UpdateOIDCSettings([UpdateOIDCSettingsRequest](#updateoidcsettingsrequest))
|
||||||
|
[UpdateOIDCSettingsResponse](#updateoidcsettingsresponse)
|
||||||
|
|
||||||
|
Update oidc settings (e.g token lifetimes, etc)
|
||||||
|
|
||||||
|
|
||||||
|
|
||||||
|
PUT: /settings/oidc
|
||||||
|
|
||||||
|
|
||||||
### GetOrgByID
|
### GetOrgByID
|
||||||
|
|
||||||
> **rpc** GetOrgByID([GetOrgByIDRequest](#getorgbyidrequest))
|
> **rpc** GetOrgByID([GetOrgByIDRequest](#getorgbyidrequest))
|
||||||
@@ -2046,6 +2070,23 @@ This is an empty request
|
|||||||
|
|
||||||
|
|
||||||
|
|
||||||
|
### GetOIDCSettingsRequest
|
||||||
|
This is an empty request
|
||||||
|
|
||||||
|
|
||||||
|
|
||||||
|
|
||||||
|
### GetOIDCSettingsResponse
|
||||||
|
|
||||||
|
|
||||||
|
|
||||||
|
| Field | Type | Description | Validation |
|
||||||
|
| ----- | ---- | ----------- | ----------- |
|
||||||
|
| settings | zitadel.settings.v1.OIDCSettings | - | |
|
||||||
|
|
||||||
|
|
||||||
|
|
||||||
|
|
||||||
### GetOrgByIDRequest
|
### GetOrgByIDRequest
|
||||||
|
|
||||||
|
|
||||||
@@ -3613,6 +3654,31 @@ This is an empty request
|
|||||||
|
|
||||||
|
|
||||||
|
|
||||||
|
### UpdateOIDCSettingsRequest
|
||||||
|
|
||||||
|
|
||||||
|
|
||||||
|
| Field | Type | Description | Validation |
|
||||||
|
| ----- | ---- | ----------- | ----------- |
|
||||||
|
| access_token_lifetime | google.protobuf.Duration | - | |
|
||||||
|
| id_token_lifetime | google.protobuf.Duration | - | |
|
||||||
|
| refresh_token_idle_expiration | google.protobuf.Duration | - | |
|
||||||
|
| refresh_token_expiration | google.protobuf.Duration | - | |
|
||||||
|
|
||||||
|
|
||||||
|
|
||||||
|
|
||||||
|
### UpdateOIDCSettingsResponse
|
||||||
|
|
||||||
|
|
||||||
|
|
||||||
|
| Field | Type | Description | Validation |
|
||||||
|
| ----- | ---- | ----------- | ----------- |
|
||||||
|
| details | zitadel.v1.ObjectDetails | - | |
|
||||||
|
|
||||||
|
|
||||||
|
|
||||||
|
|
||||||
### UpdateOrgIAMPolicyRequest
|
### UpdateOrgIAMPolicyRequest
|
||||||
|
|
||||||
|
|
||||||
|
29
internal/api/grpc/admin/oidc_settings.go
Normal file
29
internal/api/grpc/admin/oidc_settings.go
Normal file
@@ -0,0 +1,29 @@
|
|||||||
|
package admin
|
||||||
|
|
||||||
|
import (
|
||||||
|
"context"
|
||||||
|
|
||||||
|
"github.com/caos/zitadel/internal/api/grpc/object"
|
||||||
|
"github.com/caos/zitadel/internal/domain"
|
||||||
|
admin_pb "github.com/caos/zitadel/pkg/grpc/admin"
|
||||||
|
)
|
||||||
|
|
||||||
|
func (s *Server) GetOIDCSettings(ctx context.Context, _ *admin_pb.GetOIDCSettingsRequest) (*admin_pb.GetOIDCSettingsResponse, error) {
|
||||||
|
result, err := s.query.OIDCSettingsByAggID(ctx, domain.IAMID)
|
||||||
|
if err != nil {
|
||||||
|
return nil, err
|
||||||
|
}
|
||||||
|
return &admin_pb.GetOIDCSettingsResponse{
|
||||||
|
Settings: OIDCSettingsToPb(result),
|
||||||
|
}, nil
|
||||||
|
}
|
||||||
|
|
||||||
|
func (s *Server) UpdateOIDCSettings(ctx context.Context, req *admin_pb.UpdateOIDCSettingsRequest) (*admin_pb.UpdateOIDCSettingsResponse, error) {
|
||||||
|
result, err := s.command.ChangeOIDCSettings(ctx, UpdateOIDCConfigToConfig(req))
|
||||||
|
if err != nil {
|
||||||
|
return nil, err
|
||||||
|
}
|
||||||
|
return &admin_pb.UpdateOIDCSettingsResponse{
|
||||||
|
Details: object.DomainToChangeDetailsPb(result),
|
||||||
|
}, nil
|
||||||
|
}
|
29
internal/api/grpc/admin/oidc_settings_converter.go
Normal file
29
internal/api/grpc/admin/oidc_settings_converter.go
Normal file
@@ -0,0 +1,29 @@
|
|||||||
|
package admin
|
||||||
|
|
||||||
|
import (
|
||||||
|
obj_grpc "github.com/caos/zitadel/internal/api/grpc/object"
|
||||||
|
"github.com/caos/zitadel/internal/domain"
|
||||||
|
"github.com/caos/zitadel/internal/query"
|
||||||
|
admin_pb "github.com/caos/zitadel/pkg/grpc/admin"
|
||||||
|
settings_pb "github.com/caos/zitadel/pkg/grpc/settings"
|
||||||
|
"google.golang.org/protobuf/types/known/durationpb"
|
||||||
|
)
|
||||||
|
|
||||||
|
func OIDCSettingsToPb(config *query.OIDCSettings) *settings_pb.OIDCSettings {
|
||||||
|
return &settings_pb.OIDCSettings{
|
||||||
|
Details: obj_grpc.ToViewDetailsPb(config.Sequence, config.CreationDate, config.ChangeDate, config.AggregateID),
|
||||||
|
AccessTokenLifetime: durationpb.New(config.AccessTokenLifetime),
|
||||||
|
IdTokenLifetime: durationpb.New(config.IdTokenLifetime),
|
||||||
|
RefreshTokenIdleExpiration: durationpb.New(config.RefreshTokenIdleExpiration),
|
||||||
|
RefreshTokenExpiration: durationpb.New(config.RefreshTokenExpiration),
|
||||||
|
}
|
||||||
|
}
|
||||||
|
|
||||||
|
func UpdateOIDCConfigToConfig(req *admin_pb.UpdateOIDCSettingsRequest) *domain.OIDCSettings {
|
||||||
|
return &domain.OIDCSettings{
|
||||||
|
AccessTokenLifetime: req.AccessTokenLifetime.AsDuration(),
|
||||||
|
IdTokenLifetime: req.IdTokenLifetime.AsDuration(),
|
||||||
|
RefreshTokenIdleExpiration: req.RefreshTokenIdleExpiration.AsDuration(),
|
||||||
|
RefreshTokenExpiration: req.RefreshTokenExpiration.AsDuration(),
|
||||||
|
}
|
||||||
|
}
|
79
internal/command/iam_oidc_settings.go
Normal file
79
internal/command/iam_oidc_settings.go
Normal file
@@ -0,0 +1,79 @@
|
|||||||
|
package command
|
||||||
|
|
||||||
|
import (
|
||||||
|
"context"
|
||||||
|
|
||||||
|
"github.com/caos/zitadel/internal/domain"
|
||||||
|
caos_errs "github.com/caos/zitadel/internal/errors"
|
||||||
|
"github.com/caos/zitadel/internal/repository/iam"
|
||||||
|
)
|
||||||
|
|
||||||
|
func (c *Commands) AddOIDCSettings(ctx context.Context, settings *domain.OIDCSettings) (*domain.ObjectDetails, error) {
|
||||||
|
oidcSettingWriteModel, err := c.getOIDCSettings(ctx)
|
||||||
|
if err != nil {
|
||||||
|
return nil, err
|
||||||
|
}
|
||||||
|
if oidcSettingWriteModel.State.Exists() {
|
||||||
|
return nil, caos_errs.ThrowAlreadyExists(nil, "COMMAND-d9nlw", "Errors.OIDCSettings.AlreadyExists")
|
||||||
|
}
|
||||||
|
iamAgg := IAMAggregateFromWriteModel(&oidcSettingWriteModel.WriteModel)
|
||||||
|
pushedEvents, err := c.eventstore.Push(ctx, iam.NewOIDCSettingsAddedEvent(
|
||||||
|
ctx,
|
||||||
|
iamAgg,
|
||||||
|
settings.AccessTokenLifetime,
|
||||||
|
settings.IdTokenLifetime,
|
||||||
|
settings.RefreshTokenIdleExpiration,
|
||||||
|
settings.RefreshTokenExpiration))
|
||||||
|
if err != nil {
|
||||||
|
return nil, err
|
||||||
|
}
|
||||||
|
err = AppendAndReduce(oidcSettingWriteModel, pushedEvents...)
|
||||||
|
if err != nil {
|
||||||
|
return nil, err
|
||||||
|
}
|
||||||
|
return writeModelToObjectDetails(&oidcSettingWriteModel.WriteModel), nil
|
||||||
|
}
|
||||||
|
|
||||||
|
func (c *Commands) ChangeOIDCSettings(ctx context.Context, settings *domain.OIDCSettings) (*domain.ObjectDetails, error) {
|
||||||
|
oidcSettingWriteModel, err := c.getOIDCSettings(ctx)
|
||||||
|
if err != nil {
|
||||||
|
return nil, err
|
||||||
|
}
|
||||||
|
if !oidcSettingWriteModel.State.Exists() {
|
||||||
|
return nil, caos_errs.ThrowNotFound(nil, "COMMAND-8snEr", "Errors.OIDCSettings.NotFound")
|
||||||
|
}
|
||||||
|
iamAgg := IAMAggregateFromWriteModel(&oidcSettingWriteModel.WriteModel)
|
||||||
|
|
||||||
|
changedEvent, hasChanged, err := oidcSettingWriteModel.NewChangedEvent(
|
||||||
|
ctx,
|
||||||
|
iamAgg,
|
||||||
|
settings.AccessTokenLifetime,
|
||||||
|
settings.IdTokenLifetime,
|
||||||
|
settings.RefreshTokenIdleExpiration,
|
||||||
|
settings.RefreshTokenExpiration)
|
||||||
|
if err != nil {
|
||||||
|
return nil, err
|
||||||
|
}
|
||||||
|
if !hasChanged {
|
||||||
|
return nil, caos_errs.ThrowPreconditionFailed(nil, "COMMAND-398uF", "Errors.NoChangesFound")
|
||||||
|
}
|
||||||
|
pushedEvents, err := c.eventstore.Push(ctx, changedEvent)
|
||||||
|
if err != nil {
|
||||||
|
return nil, err
|
||||||
|
}
|
||||||
|
err = AppendAndReduce(oidcSettingWriteModel, pushedEvents...)
|
||||||
|
if err != nil {
|
||||||
|
return nil, err
|
||||||
|
}
|
||||||
|
return writeModelToObjectDetails(&oidcSettingWriteModel.WriteModel), nil
|
||||||
|
}
|
||||||
|
|
||||||
|
func (c *Commands) getOIDCSettings(ctx context.Context) (_ *IAMOIDCSettingsWriteModel, err error) {
|
||||||
|
writeModel := NewIAMOIDCSettingsWriteModel()
|
||||||
|
err = c.eventstore.FilterToQueryReducer(ctx, writeModel)
|
||||||
|
if err != nil {
|
||||||
|
return nil, err
|
||||||
|
}
|
||||||
|
|
||||||
|
return writeModel, nil
|
||||||
|
}
|
101
internal/command/iam_oidc_settings_model.go
Normal file
101
internal/command/iam_oidc_settings_model.go
Normal file
@@ -0,0 +1,101 @@
|
|||||||
|
package command
|
||||||
|
|
||||||
|
import (
|
||||||
|
"context"
|
||||||
|
"time"
|
||||||
|
|
||||||
|
"github.com/caos/zitadel/internal/domain"
|
||||||
|
"github.com/caos/zitadel/internal/eventstore"
|
||||||
|
"github.com/caos/zitadel/internal/repository/iam"
|
||||||
|
)
|
||||||
|
|
||||||
|
type IAMOIDCSettingsWriteModel struct {
|
||||||
|
eventstore.WriteModel
|
||||||
|
|
||||||
|
AccessTokenLifetime time.Duration
|
||||||
|
IdTokenLifetime time.Duration
|
||||||
|
RefreshTokenIdleExpiration time.Duration
|
||||||
|
RefreshTokenExpiration time.Duration
|
||||||
|
State domain.OIDCSettingsState
|
||||||
|
}
|
||||||
|
|
||||||
|
func NewIAMOIDCSettingsWriteModel() *IAMOIDCSettingsWriteModel {
|
||||||
|
return &IAMOIDCSettingsWriteModel{
|
||||||
|
WriteModel: eventstore.WriteModel{
|
||||||
|
AggregateID: domain.IAMID,
|
||||||
|
ResourceOwner: domain.IAMID,
|
||||||
|
},
|
||||||
|
}
|
||||||
|
}
|
||||||
|
|
||||||
|
func (wm *IAMOIDCSettingsWriteModel) Reduce() error {
|
||||||
|
for _, event := range wm.Events {
|
||||||
|
switch e := event.(type) {
|
||||||
|
case *iam.OIDCSettingsAddedEvent:
|
||||||
|
wm.AccessTokenLifetime = e.AccessTokenLifetime
|
||||||
|
wm.IdTokenLifetime = e.IdTokenLifetime
|
||||||
|
wm.RefreshTokenIdleExpiration = e.RefreshTokenIdleExpiration
|
||||||
|
wm.RefreshTokenExpiration = e.RefreshTokenExpiration
|
||||||
|
wm.State = domain.OIDCSettingsStateActive
|
||||||
|
case *iam.OIDCSettingsChangedEvent:
|
||||||
|
if e.AccessTokenLifetime != nil {
|
||||||
|
wm.AccessTokenLifetime = *e.AccessTokenLifetime
|
||||||
|
}
|
||||||
|
if e.IdTokenLifetime != nil {
|
||||||
|
wm.IdTokenLifetime = *e.IdTokenLifetime
|
||||||
|
}
|
||||||
|
if e.RefreshTokenIdleExpiration != nil {
|
||||||
|
wm.RefreshTokenIdleExpiration = *e.RefreshTokenIdleExpiration
|
||||||
|
}
|
||||||
|
if e.RefreshTokenExpiration != nil {
|
||||||
|
wm.RefreshTokenExpiration = *e.RefreshTokenExpiration
|
||||||
|
}
|
||||||
|
}
|
||||||
|
}
|
||||||
|
return wm.WriteModel.Reduce()
|
||||||
|
}
|
||||||
|
|
||||||
|
func (wm *IAMOIDCSettingsWriteModel) Query() *eventstore.SearchQueryBuilder {
|
||||||
|
return eventstore.NewSearchQueryBuilder(eventstore.ColumnsEvent).
|
||||||
|
ResourceOwner(wm.ResourceOwner).
|
||||||
|
AddQuery().
|
||||||
|
AggregateTypes(iam.AggregateType).
|
||||||
|
AggregateIDs(wm.AggregateID).
|
||||||
|
EventTypes(
|
||||||
|
iam.OIDCSettingsAddedEventType,
|
||||||
|
iam.OIDCSettingsChangedEventType).
|
||||||
|
Builder()
|
||||||
|
}
|
||||||
|
|
||||||
|
func (wm *IAMOIDCSettingsWriteModel) NewChangedEvent(
|
||||||
|
ctx context.Context,
|
||||||
|
aggregate *eventstore.Aggregate,
|
||||||
|
accessTokenLifetime,
|
||||||
|
idTokenLifetime,
|
||||||
|
refreshTokenIdleExpiration,
|
||||||
|
refreshTokenExpiration time.Duration,
|
||||||
|
) (*iam.OIDCSettingsChangedEvent, bool, error) {
|
||||||
|
changes := make([]iam.OIDCSettingsChanges, 0, 4)
|
||||||
|
var err error
|
||||||
|
|
||||||
|
if wm.AccessTokenLifetime != accessTokenLifetime {
|
||||||
|
changes = append(changes, iam.ChangeOIDCSettingsAccessTokenLifetime(accessTokenLifetime))
|
||||||
|
}
|
||||||
|
if wm.IdTokenLifetime != idTokenLifetime {
|
||||||
|
changes = append(changes, iam.ChangeOIDCSettingsIdTokenLifetime(idTokenLifetime))
|
||||||
|
}
|
||||||
|
if wm.RefreshTokenIdleExpiration != refreshTokenIdleExpiration {
|
||||||
|
changes = append(changes, iam.ChangeOIDCSettingsRefreshTokenIdleExpiration(refreshTokenIdleExpiration))
|
||||||
|
}
|
||||||
|
if wm.RefreshTokenExpiration != refreshTokenExpiration {
|
||||||
|
changes = append(changes, iam.ChangeOIDCSettingsRefreshTokenExpiration(refreshTokenExpiration))
|
||||||
|
}
|
||||||
|
if len(changes) == 0 {
|
||||||
|
return nil, false, nil
|
||||||
|
}
|
||||||
|
changeEvent, err := iam.NewOIDCSettingsChangeEvent(ctx, aggregate, changes)
|
||||||
|
if err != nil {
|
||||||
|
return nil, false, err
|
||||||
|
}
|
||||||
|
return changeEvent, true, nil
|
||||||
|
}
|
264
internal/command/iam_oidc_settings_test.go
Normal file
264
internal/command/iam_oidc_settings_test.go
Normal file
@@ -0,0 +1,264 @@
|
|||||||
|
package command
|
||||||
|
|
||||||
|
import (
|
||||||
|
"context"
|
||||||
|
"testing"
|
||||||
|
"time"
|
||||||
|
|
||||||
|
"github.com/stretchr/testify/assert"
|
||||||
|
|
||||||
|
"github.com/caos/zitadel/internal/domain"
|
||||||
|
caos_errs "github.com/caos/zitadel/internal/errors"
|
||||||
|
"github.com/caos/zitadel/internal/eventstore"
|
||||||
|
"github.com/caos/zitadel/internal/eventstore/repository"
|
||||||
|
"github.com/caos/zitadel/internal/repository/iam"
|
||||||
|
)
|
||||||
|
|
||||||
|
func TestCommandSide_AddOIDCConfig(t *testing.T) {
|
||||||
|
type fields struct {
|
||||||
|
eventstore *eventstore.Eventstore
|
||||||
|
}
|
||||||
|
type args struct {
|
||||||
|
ctx context.Context
|
||||||
|
oidcConfig *domain.OIDCSettings
|
||||||
|
}
|
||||||
|
type res struct {
|
||||||
|
want *domain.ObjectDetails
|
||||||
|
err func(error) bool
|
||||||
|
}
|
||||||
|
tests := []struct {
|
||||||
|
name string
|
||||||
|
fields fields
|
||||||
|
args args
|
||||||
|
res res
|
||||||
|
}{
|
||||||
|
{
|
||||||
|
name: "oidc config, error already exists",
|
||||||
|
fields: fields{
|
||||||
|
eventstore: eventstoreExpect(
|
||||||
|
t,
|
||||||
|
expectFilter(
|
||||||
|
eventFromEventPusher(
|
||||||
|
iam.NewOIDCSettingsAddedEvent(context.Background(),
|
||||||
|
&iam.NewAggregate().Aggregate,
|
||||||
|
time.Hour*1,
|
||||||
|
time.Hour*1,
|
||||||
|
time.Hour*1,
|
||||||
|
time.Hour*1,
|
||||||
|
),
|
||||||
|
),
|
||||||
|
),
|
||||||
|
),
|
||||||
|
},
|
||||||
|
args: args{
|
||||||
|
ctx: context.Background(),
|
||||||
|
oidcConfig: &domain.OIDCSettings{
|
||||||
|
AccessTokenLifetime: 1 * time.Hour,
|
||||||
|
IdTokenLifetime: 1 * time.Hour,
|
||||||
|
RefreshTokenIdleExpiration: 1 * time.Hour,
|
||||||
|
RefreshTokenExpiration: 1 * time.Hour,
|
||||||
|
},
|
||||||
|
},
|
||||||
|
res: res{
|
||||||
|
err: caos_errs.IsErrorAlreadyExists,
|
||||||
|
},
|
||||||
|
},
|
||||||
|
{
|
||||||
|
name: "add secret generator, ok",
|
||||||
|
fields: fields{
|
||||||
|
eventstore: eventstoreExpect(
|
||||||
|
t,
|
||||||
|
expectFilter(),
|
||||||
|
expectPush(
|
||||||
|
[]*repository.Event{
|
||||||
|
eventFromEventPusher(iam.NewOIDCSettingsAddedEvent(
|
||||||
|
context.Background(),
|
||||||
|
&iam.NewAggregate().Aggregate,
|
||||||
|
time.Hour*1,
|
||||||
|
time.Hour*1,
|
||||||
|
time.Hour*1,
|
||||||
|
time.Hour*1,
|
||||||
|
),
|
||||||
|
),
|
||||||
|
},
|
||||||
|
),
|
||||||
|
),
|
||||||
|
},
|
||||||
|
args: args{
|
||||||
|
ctx: context.Background(),
|
||||||
|
oidcConfig: &domain.OIDCSettings{
|
||||||
|
AccessTokenLifetime: 1 * time.Hour,
|
||||||
|
IdTokenLifetime: 1 * time.Hour,
|
||||||
|
RefreshTokenIdleExpiration: 1 * time.Hour,
|
||||||
|
RefreshTokenExpiration: 1 * time.Hour,
|
||||||
|
},
|
||||||
|
},
|
||||||
|
res: res{
|
||||||
|
want: &domain.ObjectDetails{
|
||||||
|
ResourceOwner: "IAM",
|
||||||
|
},
|
||||||
|
},
|
||||||
|
},
|
||||||
|
}
|
||||||
|
for _, tt := range tests {
|
||||||
|
t.Run(tt.name, func(t *testing.T) {
|
||||||
|
r := &Commands{
|
||||||
|
eventstore: tt.fields.eventstore,
|
||||||
|
}
|
||||||
|
got, err := r.AddOIDCSettings(tt.args.ctx, tt.args.oidcConfig)
|
||||||
|
if tt.res.err == nil {
|
||||||
|
assert.NoError(t, err)
|
||||||
|
}
|
||||||
|
if tt.res.err != nil && !tt.res.err(err) {
|
||||||
|
t.Errorf("got wrong err: %v ", err)
|
||||||
|
}
|
||||||
|
if tt.res.err == nil {
|
||||||
|
assert.Equal(t, tt.res.want, got)
|
||||||
|
}
|
||||||
|
})
|
||||||
|
}
|
||||||
|
}
|
||||||
|
|
||||||
|
func TestCommandSide_ChangeOIDCConfig(t *testing.T) {
|
||||||
|
type fields struct {
|
||||||
|
eventstore *eventstore.Eventstore
|
||||||
|
}
|
||||||
|
type args struct {
|
||||||
|
ctx context.Context
|
||||||
|
oidcConfig *domain.OIDCSettings
|
||||||
|
}
|
||||||
|
type res struct {
|
||||||
|
want *domain.ObjectDetails
|
||||||
|
err func(error) bool
|
||||||
|
}
|
||||||
|
tests := []struct {
|
||||||
|
name string
|
||||||
|
fields fields
|
||||||
|
args args
|
||||||
|
res res
|
||||||
|
}{
|
||||||
|
{
|
||||||
|
name: "oidc config not existing, not found error",
|
||||||
|
fields: fields{
|
||||||
|
eventstore: eventstoreExpect(
|
||||||
|
t,
|
||||||
|
expectFilter(),
|
||||||
|
),
|
||||||
|
},
|
||||||
|
args: args{
|
||||||
|
ctx: context.Background(),
|
||||||
|
},
|
||||||
|
res: res{
|
||||||
|
err: caos_errs.IsNotFound,
|
||||||
|
},
|
||||||
|
},
|
||||||
|
{
|
||||||
|
name: "no changes, precondition error",
|
||||||
|
fields: fields{
|
||||||
|
eventstore: eventstoreExpect(
|
||||||
|
t,
|
||||||
|
expectFilter(
|
||||||
|
eventFromEventPusher(
|
||||||
|
iam.NewOIDCSettingsAddedEvent(
|
||||||
|
context.Background(),
|
||||||
|
&iam.NewAggregate().Aggregate,
|
||||||
|
time.Hour*1,
|
||||||
|
time.Hour*1,
|
||||||
|
time.Hour*1,
|
||||||
|
time.Hour*1,
|
||||||
|
),
|
||||||
|
),
|
||||||
|
),
|
||||||
|
),
|
||||||
|
},
|
||||||
|
args: args{
|
||||||
|
ctx: context.Background(),
|
||||||
|
oidcConfig: &domain.OIDCSettings{
|
||||||
|
AccessTokenLifetime: 1 * time.Hour,
|
||||||
|
IdTokenLifetime: 1 * time.Hour,
|
||||||
|
RefreshTokenIdleExpiration: 1 * time.Hour,
|
||||||
|
RefreshTokenExpiration: 1 * time.Hour,
|
||||||
|
},
|
||||||
|
},
|
||||||
|
res: res{
|
||||||
|
err: caos_errs.IsPreconditionFailed,
|
||||||
|
},
|
||||||
|
},
|
||||||
|
{
|
||||||
|
name: "secret generator change, ok",
|
||||||
|
fields: fields{
|
||||||
|
eventstore: eventstoreExpect(
|
||||||
|
t,
|
||||||
|
expectFilter(
|
||||||
|
eventFromEventPusher(
|
||||||
|
iam.NewOIDCSettingsAddedEvent(
|
||||||
|
context.Background(),
|
||||||
|
&iam.NewAggregate().Aggregate,
|
||||||
|
time.Hour*1,
|
||||||
|
time.Hour*1,
|
||||||
|
time.Hour*1,
|
||||||
|
time.Hour*1,
|
||||||
|
),
|
||||||
|
),
|
||||||
|
),
|
||||||
|
expectPush(
|
||||||
|
[]*repository.Event{
|
||||||
|
eventFromEventPusher(
|
||||||
|
newOIDCConfigChangedEvent(context.Background(),
|
||||||
|
time.Hour*2,
|
||||||
|
time.Hour*2,
|
||||||
|
time.Hour*2,
|
||||||
|
time.Hour*2),
|
||||||
|
),
|
||||||
|
},
|
||||||
|
),
|
||||||
|
),
|
||||||
|
},
|
||||||
|
args: args{
|
||||||
|
ctx: context.Background(),
|
||||||
|
oidcConfig: &domain.OIDCSettings{
|
||||||
|
AccessTokenLifetime: 2 * time.Hour,
|
||||||
|
IdTokenLifetime: 2 * time.Hour,
|
||||||
|
RefreshTokenIdleExpiration: 2 * time.Hour,
|
||||||
|
RefreshTokenExpiration: 2 * time.Hour,
|
||||||
|
},
|
||||||
|
},
|
||||||
|
res: res{
|
||||||
|
want: &domain.ObjectDetails{
|
||||||
|
ResourceOwner: "IAM",
|
||||||
|
},
|
||||||
|
},
|
||||||
|
},
|
||||||
|
}
|
||||||
|
for _, tt := range tests {
|
||||||
|
t.Run(tt.name, func(t *testing.T) {
|
||||||
|
r := &Commands{
|
||||||
|
eventstore: tt.fields.eventstore,
|
||||||
|
}
|
||||||
|
got, err := r.ChangeOIDCSettings(tt.args.ctx, tt.args.oidcConfig)
|
||||||
|
if tt.res.err == nil {
|
||||||
|
assert.NoError(t, err)
|
||||||
|
}
|
||||||
|
if tt.res.err != nil && !tt.res.err(err) {
|
||||||
|
t.Errorf("got wrong err: %v ", err)
|
||||||
|
}
|
||||||
|
if tt.res.err == nil {
|
||||||
|
assert.Equal(t, tt.res.want, got)
|
||||||
|
}
|
||||||
|
})
|
||||||
|
}
|
||||||
|
}
|
||||||
|
|
||||||
|
func newOIDCConfigChangedEvent(ctx context.Context, accessTokenLifetime, idTokenLifetime, refreshTokenIdleExpiration, refreshTokenExpiration time.Duration) *iam.OIDCSettingsChangedEvent {
|
||||||
|
changes := []iam.OIDCSettingsChanges{
|
||||||
|
iam.ChangeOIDCSettingsAccessTokenLifetime(accessTokenLifetime),
|
||||||
|
iam.ChangeOIDCSettingsIdTokenLifetime(idTokenLifetime),
|
||||||
|
iam.ChangeOIDCSettingsRefreshTokenIdleExpiration(refreshTokenIdleExpiration),
|
||||||
|
iam.ChangeOIDCSettingsRefreshTokenExpiration(refreshTokenExpiration),
|
||||||
|
}
|
||||||
|
event, _ := iam.NewOIDCSettingsChangeEvent(ctx,
|
||||||
|
&iam.NewAggregate().Aggregate,
|
||||||
|
changes,
|
||||||
|
)
|
||||||
|
return event
|
||||||
|
}
|
37
internal/domain/oidc_settings.go
Normal file
37
internal/domain/oidc_settings.go
Normal file
@@ -0,0 +1,37 @@
|
|||||||
|
package domain
|
||||||
|
|
||||||
|
import (
|
||||||
|
"time"
|
||||||
|
|
||||||
|
"github.com/caos/zitadel/internal/eventstore/v1/models"
|
||||||
|
)
|
||||||
|
|
||||||
|
type OIDCSettings struct {
|
||||||
|
models.ObjectRoot
|
||||||
|
|
||||||
|
State OIDCSettingsState
|
||||||
|
Default bool
|
||||||
|
|
||||||
|
AccessTokenLifetime time.Duration
|
||||||
|
IdTokenLifetime time.Duration
|
||||||
|
RefreshTokenIdleExpiration time.Duration
|
||||||
|
RefreshTokenExpiration time.Duration
|
||||||
|
}
|
||||||
|
|
||||||
|
type OIDCSettingsState int32
|
||||||
|
|
||||||
|
const (
|
||||||
|
OIDCSettingsStateUnspecified OIDCSettingsState = iota
|
||||||
|
OIDCSettingsStateActive
|
||||||
|
OIDCSettingsStateRemoved
|
||||||
|
|
||||||
|
oidcSettingsStateCount
|
||||||
|
)
|
||||||
|
|
||||||
|
func (c OIDCSettingsState) Valid() bool {
|
||||||
|
return c >= 0 && c < oidcSettingsStateCount
|
||||||
|
}
|
||||||
|
|
||||||
|
func (s OIDCSettingsState) Exists() bool {
|
||||||
|
return s != OIDCSettingsStateUnspecified && s != OIDCSettingsStateRemoved
|
||||||
|
}
|
115
internal/query/oidc_settings.go
Normal file
115
internal/query/oidc_settings.go
Normal file
@@ -0,0 +1,115 @@
|
|||||||
|
package query
|
||||||
|
|
||||||
|
import (
|
||||||
|
"context"
|
||||||
|
"database/sql"
|
||||||
|
errs "errors"
|
||||||
|
"time"
|
||||||
|
|
||||||
|
sq "github.com/Masterminds/squirrel"
|
||||||
|
"github.com/caos/zitadel/internal/errors"
|
||||||
|
"github.com/caos/zitadel/internal/query/projection"
|
||||||
|
)
|
||||||
|
|
||||||
|
var (
|
||||||
|
oidcSettingsTable = table{
|
||||||
|
name: projection.OIDCSettingsProjectionTable,
|
||||||
|
}
|
||||||
|
OIDCSettingsColumnAggregateID = Column{
|
||||||
|
name: projection.OIDCSettingsColumnAggregateID,
|
||||||
|
table: oidcSettingsTable,
|
||||||
|
}
|
||||||
|
OIDCSettingsColumnCreationDate = Column{
|
||||||
|
name: projection.OIDCSettingsColumnCreationDate,
|
||||||
|
table: oidcSettingsTable,
|
||||||
|
}
|
||||||
|
OIDCSettingsColumnChangeDate = Column{
|
||||||
|
name: projection.OIDCSettingsColumnChangeDate,
|
||||||
|
table: oidcSettingsTable,
|
||||||
|
}
|
||||||
|
OIDCSettingsColumnResourceOwner = Column{
|
||||||
|
name: projection.OIDCSettingsColumnResourceOwner,
|
||||||
|
table: oidcSettingsTable,
|
||||||
|
}
|
||||||
|
OIDCSettingsColumnSequence = Column{
|
||||||
|
name: projection.OIDCSettingsColumnSequence,
|
||||||
|
table: oidcSettingsTable,
|
||||||
|
}
|
||||||
|
OIDCSettingsColumnAccessTokenLifetime = Column{
|
||||||
|
name: projection.OIDCSettingsColumnAccessTokenLifetime,
|
||||||
|
table: oidcSettingsTable,
|
||||||
|
}
|
||||||
|
OIDCSettingsColumnIdTokenLifetime = Column{
|
||||||
|
name: projection.OIDCSettingsColumnIdTokenLifetime,
|
||||||
|
table: oidcSettingsTable,
|
||||||
|
}
|
||||||
|
OIDCSettingsColumnRefreshTokenIdleExpiration = Column{
|
||||||
|
name: projection.OIDCSettingsColumnRefreshTokenIdleExpiration,
|
||||||
|
table: oidcSettingsTable,
|
||||||
|
}
|
||||||
|
OIDCSettingsColumnRefreshTokenExpiration = Column{
|
||||||
|
name: projection.OIDCSettingsColumnRefreshTokenExpiration,
|
||||||
|
table: oidcSettingsTable,
|
||||||
|
}
|
||||||
|
)
|
||||||
|
|
||||||
|
type OIDCSettings struct {
|
||||||
|
AggregateID string
|
||||||
|
CreationDate time.Time
|
||||||
|
ChangeDate time.Time
|
||||||
|
ResourceOwner string
|
||||||
|
Sequence uint64
|
||||||
|
|
||||||
|
AccessTokenLifetime time.Duration
|
||||||
|
IdTokenLifetime time.Duration
|
||||||
|
RefreshTokenIdleExpiration time.Duration
|
||||||
|
RefreshTokenExpiration time.Duration
|
||||||
|
}
|
||||||
|
|
||||||
|
func (q *Queries) OIDCSettingsByAggID(ctx context.Context, aggregateID string) (*OIDCSettings, error) {
|
||||||
|
stmt, scan := prepareOIDCSettingsQuery()
|
||||||
|
query, args, err := stmt.Where(sq.Eq{
|
||||||
|
OIDCSettingsColumnAggregateID.identifier(): aggregateID,
|
||||||
|
}).ToSql()
|
||||||
|
if err != nil {
|
||||||
|
return nil, errors.ThrowInternal(err, "QUERY-s9nle", "Errors.Query.SQLStatment")
|
||||||
|
}
|
||||||
|
|
||||||
|
row := q.client.QueryRowContext(ctx, query, args...)
|
||||||
|
return scan(row)
|
||||||
|
}
|
||||||
|
|
||||||
|
func prepareOIDCSettingsQuery() (sq.SelectBuilder, func(*sql.Row) (*OIDCSettings, error)) {
|
||||||
|
return sq.Select(
|
||||||
|
OIDCSettingsColumnAggregateID.identifier(),
|
||||||
|
OIDCSettingsColumnCreationDate.identifier(),
|
||||||
|
OIDCSettingsColumnChangeDate.identifier(),
|
||||||
|
OIDCSettingsColumnResourceOwner.identifier(),
|
||||||
|
OIDCSettingsColumnSequence.identifier(),
|
||||||
|
OIDCSettingsColumnAccessTokenLifetime.identifier(),
|
||||||
|
OIDCSettingsColumnIdTokenLifetime.identifier(),
|
||||||
|
OIDCSettingsColumnRefreshTokenIdleExpiration.identifier(),
|
||||||
|
OIDCSettingsColumnRefreshTokenExpiration.identifier()).
|
||||||
|
From(oidcSettingsTable.identifier()).PlaceholderFormat(sq.Dollar),
|
||||||
|
func(row *sql.Row) (*OIDCSettings, error) {
|
||||||
|
oidcSettings := new(OIDCSettings)
|
||||||
|
err := row.Scan(
|
||||||
|
&oidcSettings.AggregateID,
|
||||||
|
&oidcSettings.CreationDate,
|
||||||
|
&oidcSettings.ChangeDate,
|
||||||
|
&oidcSettings.ResourceOwner,
|
||||||
|
&oidcSettings.Sequence,
|
||||||
|
&oidcSettings.AccessTokenLifetime,
|
||||||
|
&oidcSettings.IdTokenLifetime,
|
||||||
|
&oidcSettings.RefreshTokenIdleExpiration,
|
||||||
|
&oidcSettings.RefreshTokenExpiration,
|
||||||
|
)
|
||||||
|
if err != nil {
|
||||||
|
if errs.Is(err, sql.ErrNoRows) {
|
||||||
|
return nil, errors.ThrowNotFound(err, "QUERY-s9nlw", "Errors.OIDCSettings.NotFound")
|
||||||
|
}
|
||||||
|
return nil, errors.ThrowInternal(err, "QUERY-9bf8s", "Errors.Internal")
|
||||||
|
}
|
||||||
|
return oidcSettings, nil
|
||||||
|
}
|
||||||
|
}
|
136
internal/query/oidc_settings_test.go
Normal file
136
internal/query/oidc_settings_test.go
Normal file
@@ -0,0 +1,136 @@
|
|||||||
|
package query
|
||||||
|
|
||||||
|
import (
|
||||||
|
"database/sql"
|
||||||
|
"database/sql/driver"
|
||||||
|
"errors"
|
||||||
|
"fmt"
|
||||||
|
"regexp"
|
||||||
|
"testing"
|
||||||
|
"time"
|
||||||
|
|
||||||
|
errs "github.com/caos/zitadel/internal/errors"
|
||||||
|
)
|
||||||
|
|
||||||
|
func Test_OIDCConfigsPrepares(t *testing.T) {
|
||||||
|
type want struct {
|
||||||
|
sqlExpectations sqlExpectation
|
||||||
|
err checkErr
|
||||||
|
}
|
||||||
|
tests := []struct {
|
||||||
|
name string
|
||||||
|
prepare interface{}
|
||||||
|
want want
|
||||||
|
object interface{}
|
||||||
|
}{
|
||||||
|
{
|
||||||
|
name: "prepareOIDCSettingsQuery no result",
|
||||||
|
prepare: prepareOIDCSettingsQuery,
|
||||||
|
want: want{
|
||||||
|
sqlExpectations: mockQueries(
|
||||||
|
`SELECT zitadel.projections.oidc_settings.aggregate_id,`+
|
||||||
|
` zitadel.projections.oidc_settings.creation_date,`+
|
||||||
|
` zitadel.projections.oidc_settings.change_date,`+
|
||||||
|
` zitadel.projections.oidc_settings.resource_owner,`+
|
||||||
|
` zitadel.projections.oidc_settings.sequence,`+
|
||||||
|
` zitadel.projections.oidc_settings.access_token_lifetime,`+
|
||||||
|
` zitadel.projections.oidc_settings.id_token_lifetime,`+
|
||||||
|
` zitadel.projections.oidc_settings.refresh_token_idle_expiration,`+
|
||||||
|
` zitadel.projections.oidc_settings.refresh_token_expiration`+
|
||||||
|
` FROM zitadel.projections.oidc_settings`,
|
||||||
|
nil,
|
||||||
|
nil,
|
||||||
|
),
|
||||||
|
err: func(err error) (error, bool) {
|
||||||
|
if !errs.IsNotFound(err) {
|
||||||
|
return fmt.Errorf("err should be zitadel.NotFoundError got: %w", err), false
|
||||||
|
}
|
||||||
|
return nil, true
|
||||||
|
},
|
||||||
|
},
|
||||||
|
object: (*OIDCSettings)(nil),
|
||||||
|
},
|
||||||
|
{
|
||||||
|
name: "prepareOIDCSettingsQuery found",
|
||||||
|
prepare: prepareOIDCSettingsQuery,
|
||||||
|
want: want{
|
||||||
|
sqlExpectations: mockQuery(
|
||||||
|
regexp.QuoteMeta(`SELECT zitadel.projections.oidc_settings.aggregate_id,`+
|
||||||
|
` zitadel.projections.oidc_settings.creation_date,`+
|
||||||
|
` zitadel.projections.oidc_settings.change_date,`+
|
||||||
|
` zitadel.projections.oidc_settings.resource_owner,`+
|
||||||
|
` zitadel.projections.oidc_settings.sequence,`+
|
||||||
|
` zitadel.projections.oidc_settings.access_token_lifetime,`+
|
||||||
|
` zitadel.projections.oidc_settings.id_token_lifetime,`+
|
||||||
|
` zitadel.projections.oidc_settings.refresh_token_idle_expiration,`+
|
||||||
|
` zitadel.projections.oidc_settings.refresh_token_expiration`+
|
||||||
|
` FROM zitadel.projections.oidc_settings`),
|
||||||
|
[]string{
|
||||||
|
"aggregate_id",
|
||||||
|
"creation_date",
|
||||||
|
"change_date",
|
||||||
|
"resource_owner",
|
||||||
|
"sequence",
|
||||||
|
"access_token_lifetime",
|
||||||
|
"id_token_lifetime",
|
||||||
|
"refresh_token_idle_expiration",
|
||||||
|
"refresh_token_expiration",
|
||||||
|
},
|
||||||
|
[]driver.Value{
|
||||||
|
"agg-id",
|
||||||
|
testNow,
|
||||||
|
testNow,
|
||||||
|
"ro",
|
||||||
|
uint64(20211108),
|
||||||
|
time.Minute * 1,
|
||||||
|
time.Minute * 2,
|
||||||
|
time.Minute * 3,
|
||||||
|
time.Minute * 4,
|
||||||
|
},
|
||||||
|
),
|
||||||
|
},
|
||||||
|
object: &OIDCSettings{
|
||||||
|
AggregateID: "agg-id",
|
||||||
|
CreationDate: testNow,
|
||||||
|
ChangeDate: testNow,
|
||||||
|
ResourceOwner: "ro",
|
||||||
|
Sequence: 20211108,
|
||||||
|
AccessTokenLifetime: time.Minute * 1,
|
||||||
|
IdTokenLifetime: time.Minute * 2,
|
||||||
|
RefreshTokenIdleExpiration: time.Minute * 3,
|
||||||
|
RefreshTokenExpiration: time.Minute * 4,
|
||||||
|
},
|
||||||
|
},
|
||||||
|
{
|
||||||
|
name: "prepareOIDCSettingsQuery sql err",
|
||||||
|
prepare: prepareOIDCSettingsQuery,
|
||||||
|
want: want{
|
||||||
|
sqlExpectations: mockQueryErr(
|
||||||
|
regexp.QuoteMeta(`SELECT zitadel.projections.oidc_settings.aggregate_id,`+
|
||||||
|
` zitadel.projections.oidc_settings.creation_date,`+
|
||||||
|
` zitadel.projections.oidc_settings.change_date,`+
|
||||||
|
` zitadel.projections.oidc_settings.resource_owner,`+
|
||||||
|
` zitadel.projections.oidc_settings.sequence,`+
|
||||||
|
` zitadel.projections.oidc_settings.access_token_lifetime,`+
|
||||||
|
` zitadel.projections.oidc_settings.id_token_lifetime,`+
|
||||||
|
` zitadel.projections.oidc_settings.refresh_token_idle_expiration,`+
|
||||||
|
` zitadel.projections.oidc_settings.refresh_token_expiration`+
|
||||||
|
` FROM zitadel.projections.oidc_settings`),
|
||||||
|
sql.ErrConnDone,
|
||||||
|
),
|
||||||
|
err: func(err error) (error, bool) {
|
||||||
|
if !errors.Is(err, sql.ErrConnDone) {
|
||||||
|
return fmt.Errorf("err should be sql.ErrConnDone got: %w", err), false
|
||||||
|
}
|
||||||
|
return nil, true
|
||||||
|
},
|
||||||
|
},
|
||||||
|
object: nil,
|
||||||
|
},
|
||||||
|
}
|
||||||
|
for _, tt := range tests {
|
||||||
|
t.Run(tt.name, func(t *testing.T) {
|
||||||
|
assertPrepare(t, tt.prepare, tt.object, tt.want.sqlExpectations, tt.want.err)
|
||||||
|
})
|
||||||
|
}
|
||||||
|
}
|
@@ -32,7 +32,7 @@ type ActionProjection struct {
|
|||||||
}
|
}
|
||||||
|
|
||||||
func NewActionProjection(ctx context.Context, config crdb.StatementHandlerConfig) *ActionProjection {
|
func NewActionProjection(ctx context.Context, config crdb.StatementHandlerConfig) *ActionProjection {
|
||||||
p := &ActionProjection{}
|
p := new(ActionProjection)
|
||||||
config.ProjectionName = ActionTable
|
config.ProjectionName = ActionTable
|
||||||
config.Reducers = p.reducers()
|
config.Reducers = p.reducers()
|
||||||
p.StatementHandler = crdb.NewStatementHandler(ctx, config)
|
p.StatementHandler = crdb.NewStatementHandler(ctx, config)
|
||||||
|
@@ -25,7 +25,7 @@ const (
|
|||||||
)
|
)
|
||||||
|
|
||||||
func NewAppProjection(ctx context.Context, config crdb.StatementHandlerConfig) *AppProjection {
|
func NewAppProjection(ctx context.Context, config crdb.StatementHandlerConfig) *AppProjection {
|
||||||
p := &AppProjection{}
|
p := new(AppProjection)
|
||||||
config.ProjectionName = AppProjectionTable
|
config.ProjectionName = AppProjectionTable
|
||||||
config.Reducers = p.reducers()
|
config.Reducers = p.reducers()
|
||||||
p.StatementHandler = crdb.NewStatementHandler(ctx, config)
|
p.StatementHandler = crdb.NewStatementHandler(ctx, config)
|
||||||
|
@@ -35,7 +35,7 @@ type AuthNKeyProjection struct {
|
|||||||
}
|
}
|
||||||
|
|
||||||
func NewAuthNKeyProjection(ctx context.Context, config crdb.StatementHandlerConfig) *AuthNKeyProjection {
|
func NewAuthNKeyProjection(ctx context.Context, config crdb.StatementHandlerConfig) *AuthNKeyProjection {
|
||||||
p := &AuthNKeyProjection{}
|
p := new(AuthNKeyProjection)
|
||||||
config.ProjectionName = AuthNKeyTable
|
config.ProjectionName = AuthNKeyTable
|
||||||
config.Reducers = p.reducers()
|
config.Reducers = p.reducers()
|
||||||
p.StatementHandler = crdb.NewStatementHandler(ctx, config)
|
p.StatementHandler = crdb.NewStatementHandler(ctx, config)
|
||||||
|
@@ -33,7 +33,7 @@ const (
|
|||||||
)
|
)
|
||||||
|
|
||||||
func NewCustomTextProjection(ctx context.Context, config crdb.StatementHandlerConfig) *CustomTextProjection {
|
func NewCustomTextProjection(ctx context.Context, config crdb.StatementHandlerConfig) *CustomTextProjection {
|
||||||
p := &CustomTextProjection{}
|
p := new(CustomTextProjection)
|
||||||
config.ProjectionName = CustomTextTable
|
config.ProjectionName = CustomTextTable
|
||||||
config.Reducers = p.reducers()
|
config.Reducers = p.reducers()
|
||||||
p.StatementHandler = crdb.NewStatementHandler(ctx, config)
|
p.StatementHandler = crdb.NewStatementHandler(ctx, config)
|
||||||
|
@@ -25,7 +25,7 @@ const (
|
|||||||
)
|
)
|
||||||
|
|
||||||
func NewFeatureProjection(ctx context.Context, config crdb.StatementHandlerConfig) *FeatureProjection {
|
func NewFeatureProjection(ctx context.Context, config crdb.StatementHandlerConfig) *FeatureProjection {
|
||||||
p := &FeatureProjection{}
|
p := new(FeatureProjection)
|
||||||
config.ProjectionName = FeatureTable
|
config.ProjectionName = FeatureTable
|
||||||
config.Reducers = p.reducers()
|
config.Reducers = p.reducers()
|
||||||
p.StatementHandler = crdb.NewStatementHandler(ctx, config)
|
p.StatementHandler = crdb.NewStatementHandler(ctx, config)
|
||||||
|
@@ -26,7 +26,7 @@ type FlowProjection struct {
|
|||||||
}
|
}
|
||||||
|
|
||||||
func NewFlowProjection(ctx context.Context, config crdb.StatementHandlerConfig) *FlowProjection {
|
func NewFlowProjection(ctx context.Context, config crdb.StatementHandlerConfig) *FlowProjection {
|
||||||
p := &FlowProjection{}
|
p := new(FlowProjection)
|
||||||
config.ProjectionName = FlowTriggerTable
|
config.ProjectionName = FlowTriggerTable
|
||||||
config.Reducers = p.reducers()
|
config.Reducers = p.reducers()
|
||||||
p.StatementHandler = crdb.NewStatementHandler(ctx, config)
|
p.StatementHandler = crdb.NewStatementHandler(ctx, config)
|
||||||
|
@@ -20,7 +20,7 @@ const (
|
|||||||
)
|
)
|
||||||
|
|
||||||
func NewIAMProjection(ctx context.Context, config crdb.StatementHandlerConfig) *IAMProjection {
|
func NewIAMProjection(ctx context.Context, config crdb.StatementHandlerConfig) *IAMProjection {
|
||||||
p := &IAMProjection{}
|
p := new(IAMProjection)
|
||||||
config.ProjectionName = IAMProjectionTable
|
config.ProjectionName = IAMProjectionTable
|
||||||
config.Reducers = p.reducers()
|
config.Reducers = p.reducers()
|
||||||
p.StatementHandler = crdb.NewStatementHandler(ctx, config)
|
p.StatementHandler = crdb.NewStatementHandler(ctx, config)
|
||||||
|
@@ -22,7 +22,7 @@ const (
|
|||||||
)
|
)
|
||||||
|
|
||||||
func NewIAMMemberProjection(ctx context.Context, config crdb.StatementHandlerConfig) *IAMMemberProjection {
|
func NewIAMMemberProjection(ctx context.Context, config crdb.StatementHandlerConfig) *IAMMemberProjection {
|
||||||
p := &IAMMemberProjection{}
|
p := new(IAMMemberProjection)
|
||||||
config.ProjectionName = IAMMemberProjectionTable
|
config.ProjectionName = IAMMemberProjectionTable
|
||||||
config.Reducers = p.reducers()
|
config.Reducers = p.reducers()
|
||||||
p.StatementHandler = crdb.NewStatementHandler(ctx, config)
|
p.StatementHandler = crdb.NewStatementHandler(ctx, config)
|
||||||
|
@@ -26,7 +26,7 @@ const (
|
|||||||
)
|
)
|
||||||
|
|
||||||
func NewIDPProjection(ctx context.Context, config crdb.StatementHandlerConfig) *IDPProjection {
|
func NewIDPProjection(ctx context.Context, config crdb.StatementHandlerConfig) *IDPProjection {
|
||||||
p := &IDPProjection{}
|
p := new(IDPProjection)
|
||||||
config.ProjectionName = IDPTable
|
config.ProjectionName = IDPTable
|
||||||
config.Reducers = p.reducers()
|
config.Reducers = p.reducers()
|
||||||
p.StatementHandler = crdb.NewStatementHandler(ctx, config)
|
p.StatementHandler = crdb.NewStatementHandler(ctx, config)
|
||||||
|
@@ -23,7 +23,7 @@ const (
|
|||||||
)
|
)
|
||||||
|
|
||||||
func NewIDPLoginPolicyLinkProjection(ctx context.Context, config crdb.StatementHandlerConfig) *IDPLoginPolicyLinkProjection {
|
func NewIDPLoginPolicyLinkProjection(ctx context.Context, config crdb.StatementHandlerConfig) *IDPLoginPolicyLinkProjection {
|
||||||
p := &IDPLoginPolicyLinkProjection{}
|
p := new(IDPLoginPolicyLinkProjection)
|
||||||
config.ProjectionName = IDPLoginPolicyLinkTable
|
config.ProjectionName = IDPLoginPolicyLinkTable
|
||||||
config.Reducers = p.reducers()
|
config.Reducers = p.reducers()
|
||||||
p.StatementHandler = crdb.NewStatementHandler(ctx, config)
|
p.StatementHandler = crdb.NewStatementHandler(ctx, config)
|
||||||
|
@@ -18,7 +18,7 @@ type IDPUserLinkProjection struct {
|
|||||||
}
|
}
|
||||||
|
|
||||||
func NewIDPUserLinkProjection(ctx context.Context, config crdb.StatementHandlerConfig) *IDPUserLinkProjection {
|
func NewIDPUserLinkProjection(ctx context.Context, config crdb.StatementHandlerConfig) *IDPUserLinkProjection {
|
||||||
p := &IDPUserLinkProjection{}
|
p := new(IDPUserLinkProjection)
|
||||||
config.ProjectionName = IDPUserLinkTable
|
config.ProjectionName = IDPUserLinkTable
|
||||||
config.Reducers = p.reducers()
|
config.Reducers = p.reducers()
|
||||||
p.StatementHandler = crdb.NewStatementHandler(ctx, config)
|
p.StatementHandler = crdb.NewStatementHandler(ctx, config)
|
||||||
|
@@ -27,7 +27,7 @@ const (
|
|||||||
)
|
)
|
||||||
|
|
||||||
func NewKeyProjection(ctx context.Context, config crdb.StatementHandlerConfig, keyConfig *crypto.KeyConfig, keyChan chan<- interface{}) (_ *KeyProjection, err error) {
|
func NewKeyProjection(ctx context.Context, config crdb.StatementHandlerConfig, keyConfig *crypto.KeyConfig, keyChan chan<- interface{}) (_ *KeyProjection, err error) {
|
||||||
p := &KeyProjection{}
|
p := new(KeyProjection)
|
||||||
config.ProjectionName = KeyProjectionTable
|
config.ProjectionName = KeyProjectionTable
|
||||||
config.Reducers = p.reducers()
|
config.Reducers = p.reducers()
|
||||||
p.StatementHandler = crdb.NewStatementHandler(ctx, config)
|
p.StatementHandler = crdb.NewStatementHandler(ctx, config)
|
||||||
|
@@ -23,7 +23,7 @@ const (
|
|||||||
)
|
)
|
||||||
|
|
||||||
func NewLabelPolicyProjection(ctx context.Context, config crdb.StatementHandlerConfig) *LabelPolicyProjection {
|
func NewLabelPolicyProjection(ctx context.Context, config crdb.StatementHandlerConfig) *LabelPolicyProjection {
|
||||||
p := &LabelPolicyProjection{}
|
p := new(LabelPolicyProjection)
|
||||||
config.ProjectionName = LabelPolicyTable
|
config.ProjectionName = LabelPolicyTable
|
||||||
config.Reducers = p.reducers()
|
config.Reducers = p.reducers()
|
||||||
p.StatementHandler = crdb.NewStatementHandler(ctx, config)
|
p.StatementHandler = crdb.NewStatementHandler(ctx, config)
|
||||||
|
@@ -33,7 +33,7 @@ const (
|
|||||||
)
|
)
|
||||||
|
|
||||||
func NewLockoutPolicyProjection(ctx context.Context, config crdb.StatementHandlerConfig) *LockoutPolicyProjection {
|
func NewLockoutPolicyProjection(ctx context.Context, config crdb.StatementHandlerConfig) *LockoutPolicyProjection {
|
||||||
p := &LockoutPolicyProjection{}
|
p := new(LockoutPolicyProjection)
|
||||||
config.ProjectionName = LockoutPolicyTable
|
config.ProjectionName = LockoutPolicyTable
|
||||||
config.Reducers = p.reducers()
|
config.Reducers = p.reducers()
|
||||||
p.StatementHandler = crdb.NewStatementHandler(ctx, config)
|
p.StatementHandler = crdb.NewStatementHandler(ctx, config)
|
||||||
|
@@ -26,7 +26,7 @@ const (
|
|||||||
)
|
)
|
||||||
|
|
||||||
func NewLoginNameProjection(ctx context.Context, config crdb.StatementHandlerConfig) *LoginNameProjection {
|
func NewLoginNameProjection(ctx context.Context, config crdb.StatementHandlerConfig) *LoginNameProjection {
|
||||||
p := &LoginNameProjection{}
|
p := new(LoginNameProjection)
|
||||||
config.ProjectionName = LoginNameProjectionTable
|
config.ProjectionName = LoginNameProjectionTable
|
||||||
config.Reducers = p.reducers()
|
config.Reducers = p.reducers()
|
||||||
p.StatementHandler = crdb.NewStatementHandler(ctx, config)
|
p.StatementHandler = crdb.NewStatementHandler(ctx, config)
|
||||||
|
@@ -23,7 +23,7 @@ const (
|
|||||||
)
|
)
|
||||||
|
|
||||||
func NewLoginPolicyProjection(ctx context.Context, config crdb.StatementHandlerConfig) *LoginPolicyProjection {
|
func NewLoginPolicyProjection(ctx context.Context, config crdb.StatementHandlerConfig) *LoginPolicyProjection {
|
||||||
p := &LoginPolicyProjection{}
|
p := new(LoginPolicyProjection)
|
||||||
config.ProjectionName = LoginPolicyTable
|
config.ProjectionName = LoginPolicyTable
|
||||||
config.Reducers = p.reducers()
|
config.Reducers = p.reducers()
|
||||||
p.StatementHandler = crdb.NewStatementHandler(ctx, config)
|
p.StatementHandler = crdb.NewStatementHandler(ctx, config)
|
||||||
|
@@ -31,7 +31,7 @@ const (
|
|||||||
)
|
)
|
||||||
|
|
||||||
func NewMailTemplateProjection(ctx context.Context, config crdb.StatementHandlerConfig) *MailTemplateProjection {
|
func NewMailTemplateProjection(ctx context.Context, config crdb.StatementHandlerConfig) *MailTemplateProjection {
|
||||||
p := &MailTemplateProjection{}
|
p := new(MailTemplateProjection)
|
||||||
config.ProjectionName = MailTemplateTable
|
config.ProjectionName = MailTemplateTable
|
||||||
config.Reducers = p.reducers()
|
config.Reducers = p.reducers()
|
||||||
p.StatementHandler = crdb.NewStatementHandler(ctx, config)
|
p.StatementHandler = crdb.NewStatementHandler(ctx, config)
|
||||||
|
@@ -39,7 +39,7 @@ const (
|
|||||||
)
|
)
|
||||||
|
|
||||||
func NewMessageTextProjection(ctx context.Context, config crdb.StatementHandlerConfig) *MessageTextProjection {
|
func NewMessageTextProjection(ctx context.Context, config crdb.StatementHandlerConfig) *MessageTextProjection {
|
||||||
p := &MessageTextProjection{}
|
p := new(MessageTextProjection)
|
||||||
config.ProjectionName = MessageTextTable
|
config.ProjectionName = MessageTextTable
|
||||||
config.Reducers = p.reducers()
|
config.Reducers = p.reducers()
|
||||||
p.StatementHandler = crdb.NewStatementHandler(ctx, config)
|
p.StatementHandler = crdb.NewStatementHandler(ctx, config)
|
||||||
|
114
internal/query/projection/oidc_settings.go
Normal file
114
internal/query/projection/oidc_settings.go
Normal file
@@ -0,0 +1,114 @@
|
|||||||
|
package projection
|
||||||
|
|
||||||
|
import (
|
||||||
|
"context"
|
||||||
|
|
||||||
|
"github.com/caos/logging"
|
||||||
|
"github.com/caos/zitadel/internal/errors"
|
||||||
|
"github.com/caos/zitadel/internal/eventstore"
|
||||||
|
"github.com/caos/zitadel/internal/eventstore/handler"
|
||||||
|
"github.com/caos/zitadel/internal/eventstore/handler/crdb"
|
||||||
|
"github.com/caos/zitadel/internal/repository/iam"
|
||||||
|
"github.com/caos/zitadel/internal/repository/project"
|
||||||
|
)
|
||||||
|
|
||||||
|
type OIDCSettingsProjection struct {
|
||||||
|
crdb.StatementHandler
|
||||||
|
}
|
||||||
|
|
||||||
|
const (
|
||||||
|
OIDCSettingsProjectionTable = "zitadel.projections.oidc_settings"
|
||||||
|
)
|
||||||
|
|
||||||
|
func NewOIDCSettingsProjection(ctx context.Context, config crdb.StatementHandlerConfig) *OIDCSettingsProjection {
|
||||||
|
p := new(OIDCSettingsProjection)
|
||||||
|
config.ProjectionName = OIDCSettingsProjectionTable
|
||||||
|
config.Reducers = p.reducers()
|
||||||
|
p.StatementHandler = crdb.NewStatementHandler(ctx, config)
|
||||||
|
return p
|
||||||
|
}
|
||||||
|
|
||||||
|
func (p *OIDCSettingsProjection) reducers() []handler.AggregateReducer {
|
||||||
|
return []handler.AggregateReducer{
|
||||||
|
{
|
||||||
|
Aggregate: project.AggregateType,
|
||||||
|
EventRedusers: []handler.EventReducer{
|
||||||
|
{
|
||||||
|
Event: iam.OIDCSettingsAddedEventType,
|
||||||
|
Reduce: p.reduceOIDCSettingsAdded,
|
||||||
|
},
|
||||||
|
{
|
||||||
|
Event: iam.OIDCSettingsChangedEventType,
|
||||||
|
Reduce: p.reduceOIDCSettingsChanged,
|
||||||
|
},
|
||||||
|
},
|
||||||
|
},
|
||||||
|
}
|
||||||
|
}
|
||||||
|
|
||||||
|
const (
|
||||||
|
OIDCSettingsColumnAggregateID = "aggregate_id"
|
||||||
|
OIDCSettingsColumnCreationDate = "creation_date"
|
||||||
|
OIDCSettingsColumnChangeDate = "change_date"
|
||||||
|
OIDCSettingsColumnResourceOwner = "resource_owner"
|
||||||
|
OIDCSettingsColumnSequence = "sequence"
|
||||||
|
OIDCSettingsColumnAccessTokenLifetime = "access_token_lifetime"
|
||||||
|
OIDCSettingsColumnIdTokenLifetime = "id_token_lifetime"
|
||||||
|
OIDCSettingsColumnRefreshTokenIdleExpiration = "refresh_token_idle_expiration"
|
||||||
|
OIDCSettingsColumnRefreshTokenExpiration = "refresh_token_expiration"
|
||||||
|
)
|
||||||
|
|
||||||
|
func (p *OIDCSettingsProjection) reduceOIDCSettingsAdded(event eventstore.Event) (*handler.Statement, error) {
|
||||||
|
e, ok := event.(*iam.OIDCSettingsAddedEvent)
|
||||||
|
if !ok {
|
||||||
|
logging.WithFields("seq", event.Sequence(), "expectedType", iam.OIDCSettingsAddedEventType).Error("wrong event type")
|
||||||
|
return nil, errors.ThrowInvalidArgument(nil, "HANDL-f9nwf", "reduce.wrong.event.type")
|
||||||
|
}
|
||||||
|
return crdb.NewCreateStatement(
|
||||||
|
e,
|
||||||
|
[]handler.Column{
|
||||||
|
handler.NewCol(OIDCSettingsColumnAggregateID, e.Aggregate().ID),
|
||||||
|
handler.NewCol(OIDCSettingsColumnCreationDate, e.CreationDate()),
|
||||||
|
handler.NewCol(OIDCSettingsColumnChangeDate, e.CreationDate()),
|
||||||
|
handler.NewCol(OIDCSettingsColumnResourceOwner, e.Aggregate().ResourceOwner),
|
||||||
|
handler.NewCol(OIDCSettingsColumnSequence, e.Sequence()),
|
||||||
|
handler.NewCol(OIDCSettingsColumnAccessTokenLifetime, e.AccessTokenLifetime),
|
||||||
|
handler.NewCol(OIDCSettingsColumnIdTokenLifetime, e.IdTokenLifetime),
|
||||||
|
handler.NewCol(OIDCSettingsColumnRefreshTokenIdleExpiration, e.RefreshTokenIdleExpiration),
|
||||||
|
handler.NewCol(OIDCSettingsColumnRefreshTokenExpiration, e.RefreshTokenExpiration),
|
||||||
|
},
|
||||||
|
), nil
|
||||||
|
}
|
||||||
|
|
||||||
|
func (p *OIDCSettingsProjection) reduceOIDCSettingsChanged(event eventstore.Event) (*handler.Statement, error) {
|
||||||
|
e, ok := event.(*iam.OIDCSettingsChangedEvent)
|
||||||
|
if !ok {
|
||||||
|
logging.WithFields("seq", event.Sequence(), "expected", iam.OIDCSettingsChangedEventType).Error("wrong event type")
|
||||||
|
return nil, errors.ThrowInvalidArgument(nil, "HANDL-8JJ2d", "reduce.wrong.event.type")
|
||||||
|
}
|
||||||
|
|
||||||
|
columns := make([]handler.Column, 0, 6)
|
||||||
|
columns = append(columns,
|
||||||
|
handler.NewCol(OIDCSettingsColumnChangeDate, e.CreationDate()),
|
||||||
|
handler.NewCol(OIDCSettingsColumnSequence, e.Sequence()),
|
||||||
|
)
|
||||||
|
if e.AccessTokenLifetime != nil {
|
||||||
|
columns = append(columns, handler.NewCol(OIDCSettingsColumnAccessTokenLifetime, *e.AccessTokenLifetime))
|
||||||
|
}
|
||||||
|
if e.IdTokenLifetime != nil {
|
||||||
|
columns = append(columns, handler.NewCol(OIDCSettingsColumnIdTokenLifetime, *e.IdTokenLifetime))
|
||||||
|
}
|
||||||
|
if e.RefreshTokenIdleExpiration != nil {
|
||||||
|
columns = append(columns, handler.NewCol(OIDCSettingsColumnRefreshTokenIdleExpiration, *e.RefreshTokenIdleExpiration))
|
||||||
|
}
|
||||||
|
if e.RefreshTokenExpiration != nil {
|
||||||
|
columns = append(columns, handler.NewCol(OIDCSettingsColumnRefreshTokenExpiration, *e.RefreshTokenExpiration))
|
||||||
|
}
|
||||||
|
return crdb.NewUpdateStatement(
|
||||||
|
e,
|
||||||
|
columns,
|
||||||
|
[]handler.Condition{
|
||||||
|
handler.NewCond(OIDCSettingsColumnAggregateID, e.Aggregate().ID),
|
||||||
|
},
|
||||||
|
), nil
|
||||||
|
}
|
106
internal/query/projection/oidc_settings_test.go
Normal file
106
internal/query/projection/oidc_settings_test.go
Normal file
@@ -0,0 +1,106 @@
|
|||||||
|
package projection
|
||||||
|
|
||||||
|
import (
|
||||||
|
"testing"
|
||||||
|
"time"
|
||||||
|
|
||||||
|
"github.com/caos/zitadel/internal/errors"
|
||||||
|
"github.com/caos/zitadel/internal/eventstore"
|
||||||
|
"github.com/caos/zitadel/internal/eventstore/handler"
|
||||||
|
"github.com/caos/zitadel/internal/eventstore/repository"
|
||||||
|
"github.com/caos/zitadel/internal/repository/iam"
|
||||||
|
)
|
||||||
|
|
||||||
|
func TestOIDCSettingsProjection_reduces(t *testing.T) {
|
||||||
|
type args struct {
|
||||||
|
event func(t *testing.T) eventstore.Event
|
||||||
|
}
|
||||||
|
tests := []struct {
|
||||||
|
name string
|
||||||
|
args args
|
||||||
|
reduce func(event eventstore.Event) (*handler.Statement, error)
|
||||||
|
want wantReduce
|
||||||
|
}{
|
||||||
|
{
|
||||||
|
name: "reduceOIDCSettingsChanged",
|
||||||
|
args: args{
|
||||||
|
event: getEvent(testEvent(
|
||||||
|
repository.EventType(iam.OIDCSettingsChangedEventType),
|
||||||
|
iam.AggregateType,
|
||||||
|
[]byte(`{"accessTokenLifetime": 10000000, "idTokenLifetime": 10000000, "refreshTokenIdleExpiration": 10000000, "refreshTokenExpiration": 10000000}`),
|
||||||
|
), iam.OIDCSettingsChangedEventMapper),
|
||||||
|
},
|
||||||
|
reduce: (&OIDCSettingsProjection{}).reduceOIDCSettingsChanged,
|
||||||
|
want: wantReduce{
|
||||||
|
projection: OIDCSettingsProjectionTable,
|
||||||
|
aggregateType: eventstore.AggregateType("iam"),
|
||||||
|
sequence: 15,
|
||||||
|
previousSequence: 10,
|
||||||
|
executer: &testExecuter{
|
||||||
|
executions: []execution{
|
||||||
|
{
|
||||||
|
expectedStmt: "UPDATE zitadel.projections.oidc_settings SET (change_date, sequence, access_token_lifetime, id_token_lifetime, refresh_token_idle_expiration, refresh_token_expiration) = ($1, $2, $3, $4, $5, $6) WHERE (aggregate_id = $7)",
|
||||||
|
expectedArgs: []interface{}{
|
||||||
|
anyArg{},
|
||||||
|
uint64(15),
|
||||||
|
time.Millisecond * 10,
|
||||||
|
time.Millisecond * 10,
|
||||||
|
time.Millisecond * 10,
|
||||||
|
time.Millisecond * 10,
|
||||||
|
"agg-id",
|
||||||
|
},
|
||||||
|
},
|
||||||
|
},
|
||||||
|
},
|
||||||
|
},
|
||||||
|
},
|
||||||
|
{
|
||||||
|
name: "reduceOIDCSettingsAdded",
|
||||||
|
args: args{
|
||||||
|
event: getEvent(testEvent(
|
||||||
|
repository.EventType(iam.OIDCSettingsAddedEventType),
|
||||||
|
iam.AggregateType,
|
||||||
|
[]byte(`{"accessTokenLifetime": 10000000, "idTokenLifetime": 10000000, "refreshTokenIdleExpiration": 10000000, "refreshTokenExpiration": 10000000}`),
|
||||||
|
), iam.OIDCSettingsAddedEventMapper),
|
||||||
|
},
|
||||||
|
reduce: (&OIDCSettingsProjection{}).reduceOIDCSettingsAdded,
|
||||||
|
want: wantReduce{
|
||||||
|
projection: OIDCSettingsProjectionTable,
|
||||||
|
aggregateType: eventstore.AggregateType("iam"),
|
||||||
|
sequence: 15,
|
||||||
|
previousSequence: 10,
|
||||||
|
executer: &testExecuter{
|
||||||
|
executions: []execution{
|
||||||
|
{
|
||||||
|
expectedStmt: "INSERT INTO zitadel.projections.oidc_settings (aggregate_id, creation_date, change_date, resource_owner, sequence, access_token_lifetime, id_token_lifetime, refresh_token_idle_expiration, refresh_token_expiration) VALUES ($1, $2, $3, $4, $5, $6, $7, $8, $9)",
|
||||||
|
expectedArgs: []interface{}{
|
||||||
|
"agg-id",
|
||||||
|
anyArg{},
|
||||||
|
anyArg{},
|
||||||
|
"ro-id",
|
||||||
|
uint64(15),
|
||||||
|
time.Millisecond * 10,
|
||||||
|
time.Millisecond * 10,
|
||||||
|
time.Millisecond * 10,
|
||||||
|
time.Millisecond * 10,
|
||||||
|
},
|
||||||
|
},
|
||||||
|
},
|
||||||
|
},
|
||||||
|
},
|
||||||
|
},
|
||||||
|
}
|
||||||
|
for _, tt := range tests {
|
||||||
|
t.Run(tt.name, func(t *testing.T) {
|
||||||
|
event := baseEvent(t)
|
||||||
|
got, err := tt.reduce(event)
|
||||||
|
if _, ok := err.(errors.InvalidArgument); !ok {
|
||||||
|
t.Errorf("no wrong event mapping: %v, got: %v", err, got)
|
||||||
|
}
|
||||||
|
|
||||||
|
event = tt.args.event(t)
|
||||||
|
got, err = tt.reduce(event)
|
||||||
|
assertReduce(t, got, err, tt.want)
|
||||||
|
})
|
||||||
|
}
|
||||||
|
}
|
@@ -22,7 +22,7 @@ const (
|
|||||||
)
|
)
|
||||||
|
|
||||||
func NewOrgProjection(ctx context.Context, config crdb.StatementHandlerConfig) *OrgProjection {
|
func NewOrgProjection(ctx context.Context, config crdb.StatementHandlerConfig) *OrgProjection {
|
||||||
p := &OrgProjection{}
|
p := new(OrgProjection)
|
||||||
config.ProjectionName = OrgProjectionTable
|
config.ProjectionName = OrgProjectionTable
|
||||||
config.Reducers = p.reducers()
|
config.Reducers = p.reducers()
|
||||||
p.StatementHandler = crdb.NewStatementHandler(ctx, config)
|
p.StatementHandler = crdb.NewStatementHandler(ctx, config)
|
||||||
|
@@ -22,7 +22,7 @@ const (
|
|||||||
)
|
)
|
||||||
|
|
||||||
func NewOrgDomainProjection(ctx context.Context, config crdb.StatementHandlerConfig) *OrgDomainProjection {
|
func NewOrgDomainProjection(ctx context.Context, config crdb.StatementHandlerConfig) *OrgDomainProjection {
|
||||||
p := &OrgDomainProjection{}
|
p := new(OrgDomainProjection)
|
||||||
config.ProjectionName = OrgDomainTable
|
config.ProjectionName = OrgDomainTable
|
||||||
config.Reducers = p.reducers()
|
config.Reducers = p.reducers()
|
||||||
p.StatementHandler = crdb.NewStatementHandler(ctx, config)
|
p.StatementHandler = crdb.NewStatementHandler(ctx, config)
|
||||||
|
@@ -32,7 +32,7 @@ const (
|
|||||||
)
|
)
|
||||||
|
|
||||||
func NewOrgIAMPolicyProjection(ctx context.Context, config crdb.StatementHandlerConfig) *OrgIAMPolicyProjection {
|
func NewOrgIAMPolicyProjection(ctx context.Context, config crdb.StatementHandlerConfig) *OrgIAMPolicyProjection {
|
||||||
p := &OrgIAMPolicyProjection{}
|
p := new(OrgIAMPolicyProjection)
|
||||||
config.ProjectionName = OrgIAMPolicyTable
|
config.ProjectionName = OrgIAMPolicyTable
|
||||||
config.Reducers = p.reducers()
|
config.Reducers = p.reducers()
|
||||||
p.StatementHandler = crdb.NewStatementHandler(ctx, config)
|
p.StatementHandler = crdb.NewStatementHandler(ctx, config)
|
||||||
|
@@ -22,7 +22,7 @@ const (
|
|||||||
)
|
)
|
||||||
|
|
||||||
func NewOrgMemberProjection(ctx context.Context, config crdb.StatementHandlerConfig) *OrgMemberProjection {
|
func NewOrgMemberProjection(ctx context.Context, config crdb.StatementHandlerConfig) *OrgMemberProjection {
|
||||||
p := &OrgMemberProjection{}
|
p := new(OrgMemberProjection)
|
||||||
config.ProjectionName = OrgMemberProjectionTable
|
config.ProjectionName = OrgMemberProjectionTable
|
||||||
config.Reducers = p.reducers()
|
config.Reducers = p.reducers()
|
||||||
p.StatementHandler = crdb.NewStatementHandler(ctx, config)
|
p.StatementHandler = crdb.NewStatementHandler(ctx, config)
|
||||||
|
@@ -23,7 +23,7 @@ const (
|
|||||||
)
|
)
|
||||||
|
|
||||||
func NewPasswordAgeProjection(ctx context.Context, config crdb.StatementHandlerConfig) *PasswordAgeProjection {
|
func NewPasswordAgeProjection(ctx context.Context, config crdb.StatementHandlerConfig) *PasswordAgeProjection {
|
||||||
p := &PasswordAgeProjection{}
|
p := new(PasswordAgeProjection)
|
||||||
config.ProjectionName = PasswordAgeTable
|
config.ProjectionName = PasswordAgeTable
|
||||||
config.Reducers = p.reducers()
|
config.Reducers = p.reducers()
|
||||||
p.StatementHandler = crdb.NewStatementHandler(ctx, config)
|
p.StatementHandler = crdb.NewStatementHandler(ctx, config)
|
||||||
|
@@ -23,7 +23,7 @@ const (
|
|||||||
)
|
)
|
||||||
|
|
||||||
func NewPasswordComplexityProjection(ctx context.Context, config crdb.StatementHandlerConfig) *PasswordComplexityProjection {
|
func NewPasswordComplexityProjection(ctx context.Context, config crdb.StatementHandlerConfig) *PasswordComplexityProjection {
|
||||||
p := &PasswordComplexityProjection{}
|
p := new(PasswordComplexityProjection)
|
||||||
config.ProjectionName = PasswordComplexityTable
|
config.ProjectionName = PasswordComplexityTable
|
||||||
config.Reducers = p.reducers()
|
config.Reducers = p.reducers()
|
||||||
p.StatementHandler = crdb.NewStatementHandler(ctx, config)
|
p.StatementHandler = crdb.NewStatementHandler(ctx, config)
|
||||||
|
@@ -33,7 +33,7 @@ const (
|
|||||||
)
|
)
|
||||||
|
|
||||||
func NewPrivacyPolicyProjection(ctx context.Context, config crdb.StatementHandlerConfig) *PrivacyPolicyProjection {
|
func NewPrivacyPolicyProjection(ctx context.Context, config crdb.StatementHandlerConfig) *PrivacyPolicyProjection {
|
||||||
p := &PrivacyPolicyProjection{}
|
p := new(PrivacyPolicyProjection)
|
||||||
config.ProjectionName = PrivacyPolicyTable
|
config.ProjectionName = PrivacyPolicyTable
|
||||||
config.Reducers = p.reducers()
|
config.Reducers = p.reducers()
|
||||||
p.StatementHandler = crdb.NewStatementHandler(ctx, config)
|
p.StatementHandler = crdb.NewStatementHandler(ctx, config)
|
||||||
|
@@ -21,7 +21,7 @@ const (
|
|||||||
)
|
)
|
||||||
|
|
||||||
func NewProjectProjection(ctx context.Context, config crdb.StatementHandlerConfig) *ProjectProjection {
|
func NewProjectProjection(ctx context.Context, config crdb.StatementHandlerConfig) *ProjectProjection {
|
||||||
p := &ProjectProjection{}
|
p := new(ProjectProjection)
|
||||||
config.ProjectionName = ProjectProjectionTable
|
config.ProjectionName = ProjectProjectionTable
|
||||||
config.Reducers = p.reducers()
|
config.Reducers = p.reducers()
|
||||||
p.StatementHandler = crdb.NewStatementHandler(ctx, config)
|
p.StatementHandler = crdb.NewStatementHandler(ctx, config)
|
||||||
|
@@ -20,7 +20,7 @@ type ProjectGrantProjection struct {
|
|||||||
const ProjectGrantProjectionTable = "zitadel.projections.project_grants"
|
const ProjectGrantProjectionTable = "zitadel.projections.project_grants"
|
||||||
|
|
||||||
func NewProjectGrantProjection(ctx context.Context, config crdb.StatementHandlerConfig) *ProjectGrantProjection {
|
func NewProjectGrantProjection(ctx context.Context, config crdb.StatementHandlerConfig) *ProjectGrantProjection {
|
||||||
p := &ProjectGrantProjection{}
|
p := new(ProjectGrantProjection)
|
||||||
config.ProjectionName = ProjectGrantProjectionTable
|
config.ProjectionName = ProjectGrantProjectionTable
|
||||||
config.Reducers = p.reducers()
|
config.Reducers = p.reducers()
|
||||||
p.StatementHandler = crdb.NewStatementHandler(ctx, config)
|
p.StatementHandler = crdb.NewStatementHandler(ctx, config)
|
||||||
|
@@ -24,7 +24,7 @@ const (
|
|||||||
)
|
)
|
||||||
|
|
||||||
func NewProjectGrantMemberProjection(ctx context.Context, config crdb.StatementHandlerConfig) *ProjectGrantMemberProjection {
|
func NewProjectGrantMemberProjection(ctx context.Context, config crdb.StatementHandlerConfig) *ProjectGrantMemberProjection {
|
||||||
p := &ProjectGrantMemberProjection{}
|
p := new(ProjectGrantMemberProjection)
|
||||||
config.ProjectionName = ProjectGrantMemberProjectionTable
|
config.ProjectionName = ProjectGrantMemberProjectionTable
|
||||||
config.Reducers = p.reducers()
|
config.Reducers = p.reducers()
|
||||||
p.StatementHandler = crdb.NewStatementHandler(ctx, config)
|
p.StatementHandler = crdb.NewStatementHandler(ctx, config)
|
||||||
|
@@ -24,7 +24,7 @@ const (
|
|||||||
)
|
)
|
||||||
|
|
||||||
func NewProjectMemberProjection(ctx context.Context, config crdb.StatementHandlerConfig) *ProjectMemberProjection {
|
func NewProjectMemberProjection(ctx context.Context, config crdb.StatementHandlerConfig) *ProjectMemberProjection {
|
||||||
p := &ProjectMemberProjection{}
|
p := new(ProjectMemberProjection)
|
||||||
config.ProjectionName = ProjectMemberProjectionTable
|
config.ProjectionName = ProjectMemberProjectionTable
|
||||||
config.Reducers = p.reducers()
|
config.Reducers = p.reducers()
|
||||||
p.StatementHandler = crdb.NewStatementHandler(ctx, config)
|
p.StatementHandler = crdb.NewStatementHandler(ctx, config)
|
||||||
|
@@ -18,7 +18,7 @@ type ProjectRoleProjection struct {
|
|||||||
const ProjectRoleProjectionTable = "zitadel.projections.project_roles"
|
const ProjectRoleProjectionTable = "zitadel.projections.project_roles"
|
||||||
|
|
||||||
func NewProjectRoleProjection(ctx context.Context, config crdb.StatementHandlerConfig) *ProjectRoleProjection {
|
func NewProjectRoleProjection(ctx context.Context, config crdb.StatementHandlerConfig) *ProjectRoleProjection {
|
||||||
p := &ProjectRoleProjection{}
|
p := new(ProjectRoleProjection)
|
||||||
config.ProjectionName = ProjectRoleProjectionTable
|
config.ProjectionName = ProjectRoleProjectionTable
|
||||||
config.Reducers = p.reducers()
|
config.Reducers = p.reducers()
|
||||||
p.StatementHandler = crdb.NewStatementHandler(ctx, config)
|
p.StatementHandler = crdb.NewStatementHandler(ctx, config)
|
||||||
|
@@ -72,6 +72,7 @@ func Start(ctx context.Context, sqlClient *sql.DB, es *eventstore.Eventstore, co
|
|||||||
NewSecretGeneratorProjection(ctx, applyCustomConfig(projectionConfig, config.Customizations["secret_generators"]))
|
NewSecretGeneratorProjection(ctx, applyCustomConfig(projectionConfig, config.Customizations["secret_generators"]))
|
||||||
NewSMTPConfigProjection(ctx, applyCustomConfig(projectionConfig, config.Customizations["smtp_configs"]))
|
NewSMTPConfigProjection(ctx, applyCustomConfig(projectionConfig, config.Customizations["smtp_configs"]))
|
||||||
NewSMSConfigProjection(ctx, applyCustomConfig(projectionConfig, config.Customizations["sms_config"]))
|
NewSMSConfigProjection(ctx, applyCustomConfig(projectionConfig, config.Customizations["sms_config"]))
|
||||||
|
NewOIDCSettingsProjection(ctx, applyCustomConfig(projectionConfig, config.Customizations["oidc_settings"]))
|
||||||
_, err := NewKeyProjection(ctx, applyCustomConfig(projectionConfig, config.Customizations["keys"]), keyConfig, keyChan)
|
_, err := NewKeyProjection(ctx, applyCustomConfig(projectionConfig, config.Customizations["keys"]), keyConfig, keyChan)
|
||||||
|
|
||||||
return err
|
return err
|
||||||
|
@@ -21,7 +21,7 @@ const (
|
|||||||
)
|
)
|
||||||
|
|
||||||
func NewSecretGeneratorProjection(ctx context.Context, config crdb.StatementHandlerConfig) *SecretGeneratorProjection {
|
func NewSecretGeneratorProjection(ctx context.Context, config crdb.StatementHandlerConfig) *SecretGeneratorProjection {
|
||||||
p := &SecretGeneratorProjection{}
|
p := new(SecretGeneratorProjection)
|
||||||
config.ProjectionName = SecretGeneratorProjectionTable
|
config.ProjectionName = SecretGeneratorProjectionTable
|
||||||
config.Reducers = p.reducers()
|
config.Reducers = p.reducers()
|
||||||
p.StatementHandler = crdb.NewStatementHandler(ctx, config)
|
p.StatementHandler = crdb.NewStatementHandler(ctx, config)
|
||||||
|
@@ -22,7 +22,7 @@ const (
|
|||||||
)
|
)
|
||||||
|
|
||||||
func NewSMSConfigProjection(ctx context.Context, config crdb.StatementHandlerConfig) *SMSConfigProjection {
|
func NewSMSConfigProjection(ctx context.Context, config crdb.StatementHandlerConfig) *SMSConfigProjection {
|
||||||
p := &SMSConfigProjection{}
|
p := new(SMSConfigProjection)
|
||||||
config.ProjectionName = SMSConfigProjectionTable
|
config.ProjectionName = SMSConfigProjectionTable
|
||||||
config.Reducers = p.reducers()
|
config.Reducers = p.reducers()
|
||||||
p.StatementHandler = crdb.NewStatementHandler(ctx, config)
|
p.StatementHandler = crdb.NewStatementHandler(ctx, config)
|
||||||
|
@@ -21,7 +21,7 @@ const (
|
|||||||
)
|
)
|
||||||
|
|
||||||
func NewSMTPConfigProjection(ctx context.Context, config crdb.StatementHandlerConfig) *SMTPConfigProjection {
|
func NewSMTPConfigProjection(ctx context.Context, config crdb.StatementHandlerConfig) *SMTPConfigProjection {
|
||||||
p := &SMTPConfigProjection{}
|
p := new(SMTPConfigProjection)
|
||||||
config.ProjectionName = SMTPConfigProjectionTable
|
config.ProjectionName = SMTPConfigProjectionTable
|
||||||
config.Reducers = p.reducers()
|
config.Reducers = p.reducers()
|
||||||
p.StatementHandler = crdb.NewStatementHandler(ctx, config)
|
p.StatementHandler = crdb.NewStatementHandler(ctx, config)
|
||||||
|
@@ -25,7 +25,7 @@ const (
|
|||||||
)
|
)
|
||||||
|
|
||||||
func NewUserProjection(ctx context.Context, config crdb.StatementHandlerConfig) *UserProjection {
|
func NewUserProjection(ctx context.Context, config crdb.StatementHandlerConfig) *UserProjection {
|
||||||
p := &UserProjection{}
|
p := new(UserProjection)
|
||||||
config.ProjectionName = UserTable
|
config.ProjectionName = UserTable
|
||||||
config.Reducers = p.reducers()
|
config.Reducers = p.reducers()
|
||||||
p.StatementHandler = crdb.NewStatementHandler(ctx, config)
|
p.StatementHandler = crdb.NewStatementHandler(ctx, config)
|
||||||
|
@@ -21,7 +21,7 @@ const (
|
|||||||
)
|
)
|
||||||
|
|
||||||
func NewUserAuthMethodProjection(ctx context.Context, config crdb.StatementHandlerConfig) *UserAuthMethodProjection {
|
func NewUserAuthMethodProjection(ctx context.Context, config crdb.StatementHandlerConfig) *UserAuthMethodProjection {
|
||||||
p := &UserAuthMethodProjection{}
|
p := new(UserAuthMethodProjection)
|
||||||
config.ProjectionName = UserAuthMethodTable
|
config.ProjectionName = UserAuthMethodTable
|
||||||
config.Reducers = p.reducers()
|
config.Reducers = p.reducers()
|
||||||
p.StatementHandler = crdb.NewStatementHandler(ctx, config)
|
p.StatementHandler = crdb.NewStatementHandler(ctx, config)
|
||||||
|
@@ -25,7 +25,7 @@ const (
|
|||||||
)
|
)
|
||||||
|
|
||||||
func NewUserGrantProjection(ctx context.Context, config crdb.StatementHandlerConfig) *UserGrantProjection {
|
func NewUserGrantProjection(ctx context.Context, config crdb.StatementHandlerConfig) *UserGrantProjection {
|
||||||
p := &UserGrantProjection{}
|
p := new(UserGrantProjection)
|
||||||
config.ProjectionName = UserGrantProjectionTable
|
config.ProjectionName = UserGrantProjectionTable
|
||||||
config.Reducers = p.reducers()
|
config.Reducers = p.reducers()
|
||||||
p.StatementHandler = crdb.NewStatementHandler(ctx, config)
|
p.StatementHandler = crdb.NewStatementHandler(ctx, config)
|
||||||
|
@@ -19,7 +19,7 @@ type UserMetadataProjection struct {
|
|||||||
const UserMetadataProjectionTable = "zitadel.projections.user_metadata"
|
const UserMetadataProjectionTable = "zitadel.projections.user_metadata"
|
||||||
|
|
||||||
func NewUserMetadataProjection(ctx context.Context, config crdb.StatementHandlerConfig) *UserMetadataProjection {
|
func NewUserMetadataProjection(ctx context.Context, config crdb.StatementHandlerConfig) *UserMetadataProjection {
|
||||||
p := &UserMetadataProjection{}
|
p := new(UserMetadataProjection)
|
||||||
config.ProjectionName = UserMetadataProjectionTable
|
config.ProjectionName = UserMetadataProjectionTable
|
||||||
config.Reducers = p.reducers()
|
config.Reducers = p.reducers()
|
||||||
p.StatementHandler = crdb.NewStatementHandler(ctx, config)
|
p.StatementHandler = crdb.NewStatementHandler(ctx, config)
|
||||||
|
@@ -22,7 +22,7 @@ const (
|
|||||||
)
|
)
|
||||||
|
|
||||||
func NewPersonalAccessTokenProjection(ctx context.Context, config crdb.StatementHandlerConfig) *PersonalAccessTokenProjection {
|
func NewPersonalAccessTokenProjection(ctx context.Context, config crdb.StatementHandlerConfig) *PersonalAccessTokenProjection {
|
||||||
p := &PersonalAccessTokenProjection{}
|
p := new(PersonalAccessTokenProjection)
|
||||||
config.ProjectionName = PersonalAccessTokenProjectionTable
|
config.ProjectionName = PersonalAccessTokenProjectionTable
|
||||||
config.Reducers = p.reducers()
|
config.Reducers = p.reducers()
|
||||||
p.StatementHandler = crdb.NewStatementHandler(ctx, config)
|
p.StatementHandler = crdb.NewStatementHandler(ctx, config)
|
||||||
|
@@ -23,6 +23,8 @@ func RegisterEventMappers(es *eventstore.Eventstore) {
|
|||||||
RegisterFilterEventMapper(SMSConfigActivatedEventType, SMSConfigActivatedEventMapper).
|
RegisterFilterEventMapper(SMSConfigActivatedEventType, SMSConfigActivatedEventMapper).
|
||||||
RegisterFilterEventMapper(SMSConfigDeactivatedEventType, SMSConfigDeactivatedEventMapper).
|
RegisterFilterEventMapper(SMSConfigDeactivatedEventType, SMSConfigDeactivatedEventMapper).
|
||||||
RegisterFilterEventMapper(SMSConfigRemovedEventType, SMSConfigRemovedEventMapper).
|
RegisterFilterEventMapper(SMSConfigRemovedEventType, SMSConfigRemovedEventMapper).
|
||||||
|
RegisterFilterEventMapper(OIDCSettingsAddedEventType, OIDCSettingsAddedEventMapper).
|
||||||
|
RegisterFilterEventMapper(OIDCSettingsChangedEventType, OIDCSettingsChangedEventMapper).
|
||||||
RegisterFilterEventMapper(LabelPolicyAddedEventType, LabelPolicyAddedEventMapper).
|
RegisterFilterEventMapper(LabelPolicyAddedEventType, LabelPolicyAddedEventMapper).
|
||||||
RegisterFilterEventMapper(LabelPolicyChangedEventType, LabelPolicyChangedEventMapper).
|
RegisterFilterEventMapper(LabelPolicyChangedEventType, LabelPolicyChangedEventMapper).
|
||||||
RegisterFilterEventMapper(LabelPolicyActivatedEventType, LabelPolicyActivatedEventMapper).
|
RegisterFilterEventMapper(LabelPolicyActivatedEventType, LabelPolicyActivatedEventMapper).
|
||||||
|
145
internal/repository/iam/oidc_settings.go
Normal file
145
internal/repository/iam/oidc_settings.go
Normal file
@@ -0,0 +1,145 @@
|
|||||||
|
package iam
|
||||||
|
|
||||||
|
import (
|
||||||
|
"context"
|
||||||
|
"encoding/json"
|
||||||
|
"time"
|
||||||
|
|
||||||
|
"github.com/caos/zitadel/internal/errors"
|
||||||
|
"github.com/caos/zitadel/internal/eventstore"
|
||||||
|
"github.com/caos/zitadel/internal/eventstore/repository"
|
||||||
|
)
|
||||||
|
|
||||||
|
const (
|
||||||
|
oidcSettingsPrefix = "oidc.settings."
|
||||||
|
OIDCSettingsAddedEventType = iamEventTypePrefix + oidcSettingsPrefix + "added"
|
||||||
|
OIDCSettingsChangedEventType = iamEventTypePrefix + oidcSettingsPrefix + "changed"
|
||||||
|
OIDCSettingsRemovedEventType = iamEventTypePrefix + oidcSettingsPrefix + "removed"
|
||||||
|
)
|
||||||
|
|
||||||
|
type OIDCSettingsAddedEvent struct {
|
||||||
|
eventstore.BaseEvent `json:"-"`
|
||||||
|
|
||||||
|
AccessTokenLifetime time.Duration `json:"accessTokenLifetime,omitempty"`
|
||||||
|
IdTokenLifetime time.Duration `json:"idTokenLifetime,omitempty"`
|
||||||
|
RefreshTokenIdleExpiration time.Duration `json:"refreshTokenIdleExpiration,omitempty"`
|
||||||
|
RefreshTokenExpiration time.Duration `json:"refreshTokenExpiration,omitempty"`
|
||||||
|
}
|
||||||
|
|
||||||
|
func NewOIDCSettingsAddedEvent(
|
||||||
|
ctx context.Context,
|
||||||
|
aggregate *eventstore.Aggregate,
|
||||||
|
accessTokenLifetime,
|
||||||
|
idTokenLifetime,
|
||||||
|
refreshTokenIdleExpiration,
|
||||||
|
refreshTokenExpiration time.Duration,
|
||||||
|
) *OIDCSettingsAddedEvent {
|
||||||
|
return &OIDCSettingsAddedEvent{
|
||||||
|
BaseEvent: *eventstore.NewBaseEventForPush(
|
||||||
|
ctx,
|
||||||
|
aggregate,
|
||||||
|
OIDCSettingsAddedEventType,
|
||||||
|
),
|
||||||
|
AccessTokenLifetime: accessTokenLifetime,
|
||||||
|
IdTokenLifetime: idTokenLifetime,
|
||||||
|
RefreshTokenIdleExpiration: refreshTokenIdleExpiration,
|
||||||
|
RefreshTokenExpiration: refreshTokenExpiration,
|
||||||
|
}
|
||||||
|
}
|
||||||
|
|
||||||
|
func (e *OIDCSettingsAddedEvent) Data() interface{} {
|
||||||
|
return e
|
||||||
|
}
|
||||||
|
|
||||||
|
func (e *OIDCSettingsAddedEvent) UniqueConstraints() []*eventstore.EventUniqueConstraint {
|
||||||
|
return nil
|
||||||
|
}
|
||||||
|
|
||||||
|
func OIDCSettingsAddedEventMapper(event *repository.Event) (eventstore.Event, error) {
|
||||||
|
oidcSettingsAdded := &OIDCSettingsAddedEvent{
|
||||||
|
BaseEvent: *eventstore.BaseEventFromRepo(event),
|
||||||
|
}
|
||||||
|
err := json.Unmarshal(event.Data, oidcSettingsAdded)
|
||||||
|
if err != nil {
|
||||||
|
return nil, errors.ThrowInternal(err, "IAM-soiwj", "unable to unmarshal oidc config added")
|
||||||
|
}
|
||||||
|
|
||||||
|
return oidcSettingsAdded, nil
|
||||||
|
}
|
||||||
|
|
||||||
|
type OIDCSettingsChangedEvent struct {
|
||||||
|
eventstore.BaseEvent `json:"-"`
|
||||||
|
|
||||||
|
AccessTokenLifetime *time.Duration `json:"accessTokenLifetime,omitempty"`
|
||||||
|
IdTokenLifetime *time.Duration `json:"idTokenLifetime,omitempty"`
|
||||||
|
RefreshTokenIdleExpiration *time.Duration `json:"refreshTokenIdleExpiration,omitempty"`
|
||||||
|
RefreshTokenExpiration *time.Duration `json:"refreshTokenExpiration,omitempty"`
|
||||||
|
}
|
||||||
|
|
||||||
|
func (e *OIDCSettingsChangedEvent) Data() interface{} {
|
||||||
|
return e
|
||||||
|
}
|
||||||
|
|
||||||
|
func (e *OIDCSettingsChangedEvent) UniqueConstraints() []*eventstore.EventUniqueConstraint {
|
||||||
|
return nil
|
||||||
|
}
|
||||||
|
|
||||||
|
func NewOIDCSettingsChangeEvent(
|
||||||
|
ctx context.Context,
|
||||||
|
aggregate *eventstore.Aggregate,
|
||||||
|
changes []OIDCSettingsChanges,
|
||||||
|
) (*OIDCSettingsChangedEvent, error) {
|
||||||
|
if len(changes) == 0 {
|
||||||
|
return nil, errors.ThrowPreconditionFailed(nil, "IAM-dnlwe", "Errors.NoChangesFound")
|
||||||
|
}
|
||||||
|
changeEvent := &OIDCSettingsChangedEvent{
|
||||||
|
BaseEvent: *eventstore.NewBaseEventForPush(
|
||||||
|
ctx,
|
||||||
|
aggregate,
|
||||||
|
OIDCSettingsChangedEventType,
|
||||||
|
),
|
||||||
|
}
|
||||||
|
for _, change := range changes {
|
||||||
|
change(changeEvent)
|
||||||
|
}
|
||||||
|
return changeEvent, nil
|
||||||
|
}
|
||||||
|
|
||||||
|
type OIDCSettingsChanges func(event *OIDCSettingsChangedEvent)
|
||||||
|
|
||||||
|
func ChangeOIDCSettingsAccessTokenLifetime(accessTokenLifetime time.Duration) func(event *OIDCSettingsChangedEvent) {
|
||||||
|
return func(e *OIDCSettingsChangedEvent) {
|
||||||
|
e.AccessTokenLifetime = &accessTokenLifetime
|
||||||
|
}
|
||||||
|
}
|
||||||
|
|
||||||
|
func ChangeOIDCSettingsIdTokenLifetime(idTokenLifetime time.Duration) func(event *OIDCSettingsChangedEvent) {
|
||||||
|
return func(e *OIDCSettingsChangedEvent) {
|
||||||
|
e.IdTokenLifetime = &idTokenLifetime
|
||||||
|
}
|
||||||
|
}
|
||||||
|
|
||||||
|
func ChangeOIDCSettingsRefreshTokenIdleExpiration(refreshTokenIdleExpiration time.Duration) func(event *OIDCSettingsChangedEvent) {
|
||||||
|
return func(e *OIDCSettingsChangedEvent) {
|
||||||
|
e.RefreshTokenIdleExpiration = &refreshTokenIdleExpiration
|
||||||
|
}
|
||||||
|
}
|
||||||
|
|
||||||
|
func ChangeOIDCSettingsRefreshTokenExpiration(refreshTokenExpiration time.Duration) func(event *OIDCSettingsChangedEvent) {
|
||||||
|
return func(e *OIDCSettingsChangedEvent) {
|
||||||
|
e.RefreshTokenExpiration = &refreshTokenExpiration
|
||||||
|
}
|
||||||
|
}
|
||||||
|
|
||||||
|
func OIDCSettingsChangedEventMapper(event *repository.Event) (eventstore.Event, error) {
|
||||||
|
e := &OIDCSettingsChangedEvent{
|
||||||
|
BaseEvent: *eventstore.BaseEventFromRepo(event),
|
||||||
|
}
|
||||||
|
|
||||||
|
err := json.Unmarshal(event.Data, e)
|
||||||
|
if err != nil {
|
||||||
|
return nil, errors.ThrowInternal(err, "IAM-f98uf", "unable to unmarshal oidc settings changed")
|
||||||
|
}
|
||||||
|
|
||||||
|
return e, nil
|
||||||
|
}
|
@@ -29,6 +29,20 @@ Errors:
|
|||||||
ExceedsDefault: Limit überschreitet default Limit
|
ExceedsDefault: Limit überschreitet default Limit
|
||||||
Language:
|
Language:
|
||||||
NotParsed: Sprache konnte nicht gemapped werde
|
NotParsed: Sprache konnte nicht gemapped werde
|
||||||
|
OIDCSettings:
|
||||||
|
NotFound: OIDC Konfiguration konnte nicht gefunden werden
|
||||||
|
AlreadyExists: OIDC Konfiguration existiert bereits
|
||||||
|
SecretGenerator:
|
||||||
|
AlreadyExists: Passwort Generator exisiter bereits
|
||||||
|
TypeMissing: Passwort Generator Typ fehlt
|
||||||
|
NotFound: Passwort Generator nicht gefunden
|
||||||
|
SMSConfig:
|
||||||
|
NotFound: SMS Konfiguration nicht gefunden
|
||||||
|
AlreadyActive: SMS Konfiguration ist bereits aktiviert
|
||||||
|
AlreadyDeactivated: SMS Konfiguration ist bereits deaktiviert
|
||||||
|
SMTPConfig:
|
||||||
|
NotFound: SMTP Konfiguration nicht gefunden
|
||||||
|
AlreadyExists: SMTP Konfiguration existiert bereits
|
||||||
User:
|
User:
|
||||||
NotFound: Benutzer konnte nicht gefunden werden
|
NotFound: Benutzer konnte nicht gefunden werden
|
||||||
AlreadyExists: Benutzer existierts bereits
|
AlreadyExists: Benutzer existierts bereits
|
||||||
@@ -816,6 +830,35 @@ EventTypes:
|
|||||||
removed: Schrift von Label Richtlinie entfernt
|
removed: Schrift von Label Richtlinie entfernt
|
||||||
assets:
|
assets:
|
||||||
removed: Bilder und Schrift von Label Richtlinie entfernt
|
removed: Bilder und Schrift von Label Richtlinie entfernt
|
||||||
|
default:
|
||||||
|
language:
|
||||||
|
set: Standard Sprache gesetzt
|
||||||
|
oidc:
|
||||||
|
settings:
|
||||||
|
added: OIDC Konfiguration hinzugefügt
|
||||||
|
changed: OIDC Konfiguration geändert
|
||||||
|
removed: OIDC Konfiguration gelöscht
|
||||||
|
secret:
|
||||||
|
generator:
|
||||||
|
added: Passwort Generator hinzugefügt
|
||||||
|
changed: Passwort Generator geändert
|
||||||
|
removed: Passwort Generator gelöscht
|
||||||
|
smtp:
|
||||||
|
config:
|
||||||
|
added: SMTP Konfiguration hinzugefügt
|
||||||
|
changed: SMTP Konfiguration geändert
|
||||||
|
password:
|
||||||
|
changed: SMTP Konfigurations Passwort geändert
|
||||||
|
sms:
|
||||||
|
config:
|
||||||
|
twilio:
|
||||||
|
added: Twilio SMS Provider hinzugefügt
|
||||||
|
changed: Twilio SMS Provider geändert
|
||||||
|
token:
|
||||||
|
changed: Twilio SMS Provider Token geändert
|
||||||
|
removed: Twilio SMS Provider entfernt
|
||||||
|
activated: Twilio SMS Provider aktiviert
|
||||||
|
deactivated: Twilio SMS Provider deaktiviert
|
||||||
key_pair:
|
key_pair:
|
||||||
added: Schlüsselpaar hinzugefügt
|
added: Schlüsselpaar hinzugefügt
|
||||||
action:
|
action:
|
||||||
|
@@ -29,6 +29,20 @@ Errors:
|
|||||||
ExceedsDefault: Limit exceeds default limit
|
ExceedsDefault: Limit exceeds default limit
|
||||||
Language:
|
Language:
|
||||||
NotParsed: Could not parse languge
|
NotParsed: Could not parse languge
|
||||||
|
OIDCSettings:
|
||||||
|
NotFound: OIDC Configuration not found
|
||||||
|
AlreadyExists: OIDC configuration already exists
|
||||||
|
SecretGenerator:
|
||||||
|
AlreadyExists: Secret generator already exists
|
||||||
|
TypeMissing: Secret generator type missing
|
||||||
|
NotFound: Secret generator not found
|
||||||
|
SMSConfig:
|
||||||
|
NotFound: SMS configuration not found
|
||||||
|
AlreadyActive: SMS configuration already active
|
||||||
|
AlreadyDeactivated: SMS configuration already deactived
|
||||||
|
SMTPConfig:
|
||||||
|
NotFound: SMTP configuration not found
|
||||||
|
AlreadyExists: SMTP configuration already exists
|
||||||
User:
|
User:
|
||||||
NotFound: User could not be found
|
NotFound: User could not be found
|
||||||
AlreadyExists: User already exists
|
AlreadyExists: User already exists
|
||||||
@@ -813,6 +827,35 @@ EventTypes:
|
|||||||
removed: Font removed from Label Policy
|
removed: Font removed from Label Policy
|
||||||
assets:
|
assets:
|
||||||
removed: Assets removed from Label Policy
|
removed: Assets removed from Label Policy
|
||||||
|
default:
|
||||||
|
language:
|
||||||
|
set: Default language set
|
||||||
|
oidc:
|
||||||
|
settings:
|
||||||
|
added: OIDC configuration added
|
||||||
|
changed: OIDC configuration changed
|
||||||
|
removed: OIDC configuration removed
|
||||||
|
secret:
|
||||||
|
generator:
|
||||||
|
added: Secret generator added
|
||||||
|
changed: Secret generator changed
|
||||||
|
removed: Secret generator removed
|
||||||
|
smtp:
|
||||||
|
config:
|
||||||
|
added: SMTP configuration added
|
||||||
|
changed: SMTP configuration changed
|
||||||
|
password:
|
||||||
|
changed: SMTP configuration secret changed
|
||||||
|
sms:
|
||||||
|
config:
|
||||||
|
twilio:
|
||||||
|
added: Twilio SMS provider added
|
||||||
|
changed: Twilio SMS provider changed
|
||||||
|
token:
|
||||||
|
changed: Twilio SMS provider token changed
|
||||||
|
removed: Twilio SMS provider removed
|
||||||
|
activated: Twilio SMS provider activated
|
||||||
|
deactivated: Twilio SMS provider deactivated
|
||||||
key_pair:
|
key_pair:
|
||||||
added: Key pair added
|
added: Key pair added
|
||||||
action:
|
action:
|
||||||
@@ -821,6 +864,7 @@ EventTypes:
|
|||||||
deactivated: Action deactivated
|
deactivated: Action deactivated
|
||||||
reactivated: Action reactivated
|
reactivated: Action reactivated
|
||||||
removed: Action removed
|
removed: Action removed
|
||||||
|
|
||||||
Application:
|
Application:
|
||||||
OIDC:
|
OIDC:
|
||||||
UnsupportedVersion: Your OIDC version is not supported
|
UnsupportedVersion: Your OIDC version is not supported
|
||||||
|
@@ -29,6 +29,20 @@ Errors:
|
|||||||
ExceedsDefault: Il limite supera quello predefinito
|
ExceedsDefault: Il limite supera quello predefinito
|
||||||
Language:
|
Language:
|
||||||
NotParsed: Impossibile analizzare la lingua
|
NotParsed: Impossibile analizzare la lingua
|
||||||
|
OIDCSettings:
|
||||||
|
NotFound: Impossibile trovare la configurazione OIDC
|
||||||
|
AlreadyExists: La configurazione OIDC esiste già
|
||||||
|
SecretGenerator:
|
||||||
|
AlreadyExists: Il generatore di segreti esiste già
|
||||||
|
TypeMissing: Manca il tipo di generatore segreto
|
||||||
|
NotFound: Generatore segreto non trovato
|
||||||
|
SMSConfig:
|
||||||
|
NotFound: Configurazione SMS non trovata
|
||||||
|
AlreadyActive: Configurazione SMS già attiva
|
||||||
|
AlreadyDeactivated: Configurazione SMS già disattivata
|
||||||
|
SMTPConfig:
|
||||||
|
NotFound: Configurazione SMTP non trovata
|
||||||
|
AlreadyExists: La configurazione SMTP esiste già
|
||||||
User:
|
User:
|
||||||
NotFound: L'utente non è stato trovato
|
NotFound: L'utente non è stato trovato
|
||||||
AlreadyExists: L'utente già esistente
|
AlreadyExists: L'utente già esistente
|
||||||
@@ -811,6 +825,35 @@ EventTypes:
|
|||||||
removed: Font rimosso
|
removed: Font rimosso
|
||||||
assets:
|
assets:
|
||||||
removed: Asset rimosse
|
removed: Asset rimosse
|
||||||
|
default:
|
||||||
|
language:
|
||||||
|
set: lingua predefinita impostata
|
||||||
|
oidc:
|
||||||
|
settings:
|
||||||
|
added: Configurazione OIDC aggiunta
|
||||||
|
changed: Configurazione OIDC cambiata
|
||||||
|
removed: Configurazione OIDC rimossa
|
||||||
|
secret:
|
||||||
|
generator:
|
||||||
|
added: Generatore di segreti aggiunto
|
||||||
|
changed: Generatore di segreti cambiato
|
||||||
|
removed: Generatore di segreti cambiato
|
||||||
|
smtp:
|
||||||
|
config:
|
||||||
|
added: SMTP configuration added
|
||||||
|
changed: SMTP configuration changed
|
||||||
|
password:
|
||||||
|
changed: SMTP configuration secret changed
|
||||||
|
sms:
|
||||||
|
config:
|
||||||
|
twilio:
|
||||||
|
added: Aggiunto il fornitore di SMS Twilio
|
||||||
|
changed: Twilio SMS Provider cambiato
|
||||||
|
token:
|
||||||
|
changed: Twilio SMS Provider token cambiato
|
||||||
|
removed: Provider SMS Twilio rimosso
|
||||||
|
activated: Provider SMS Twilio attivato
|
||||||
|
deactivated: Provider SMS Twilio disattivato
|
||||||
key_pair:
|
key_pair:
|
||||||
added: Keypair aggiunto
|
added: Keypair aggiunto
|
||||||
action:
|
action:
|
||||||
|
@@ -313,6 +313,28 @@ service AdminService {
|
|||||||
};
|
};
|
||||||
}
|
}
|
||||||
|
|
||||||
|
// Get OIDC settings (e.g token lifetimes, etc.)
|
||||||
|
rpc GetOIDCSettings(GetOIDCSettingsRequest) returns (GetOIDCSettingsResponse) {
|
||||||
|
option (google.api.http) = {
|
||||||
|
get: "/settings/oidc";
|
||||||
|
};
|
||||||
|
|
||||||
|
option (zitadel.v1.auth_option) = {
|
||||||
|
permission: "iam.read";
|
||||||
|
};
|
||||||
|
}
|
||||||
|
|
||||||
|
// Update oidc settings (e.g token lifetimes, etc)
|
||||||
|
rpc UpdateOIDCSettings(UpdateOIDCSettingsRequest) returns (UpdateOIDCSettingsResponse) {
|
||||||
|
option (google.api.http) = {
|
||||||
|
put: "/settings/oidc";
|
||||||
|
body: "*"
|
||||||
|
};
|
||||||
|
|
||||||
|
option (zitadel.v1.auth_option) = {
|
||||||
|
permission: "iam.write";
|
||||||
|
};
|
||||||
|
}
|
||||||
|
|
||||||
// Returns an organisation by id
|
// Returns an organisation by id
|
||||||
rpc GetOrgByID(GetOrgByIDRequest) returns (GetOrgByIDResponse) {
|
rpc GetOrgByID(GetOrgByIDRequest) returns (GetOrgByIDResponse) {
|
||||||
@@ -2539,6 +2561,24 @@ message UpdateSMSProviderTwilioTokenResponse {
|
|||||||
zitadel.v1.ObjectDetails details = 1;
|
zitadel.v1.ObjectDetails details = 1;
|
||||||
}
|
}
|
||||||
|
|
||||||
|
// This is an empty request
|
||||||
|
message GetOIDCSettingsRequest {}
|
||||||
|
|
||||||
|
message GetOIDCSettingsResponse {
|
||||||
|
zitadel.settings.v1.OIDCSettings settings = 1;
|
||||||
|
}
|
||||||
|
|
||||||
|
message UpdateOIDCSettingsRequest {
|
||||||
|
google.protobuf.Duration access_token_lifetime = 1;
|
||||||
|
google.protobuf.Duration id_token_lifetime = 2;
|
||||||
|
google.protobuf.Duration refresh_token_idle_expiration = 3;
|
||||||
|
google.protobuf.Duration refresh_token_expiration = 4;
|
||||||
|
}
|
||||||
|
|
||||||
|
message UpdateOIDCSettingsResponse {
|
||||||
|
zitadel.v1.ObjectDetails details = 1;
|
||||||
|
}
|
||||||
|
|
||||||
// if name or domain is already in use, org is not unique
|
// if name or domain is already in use, org is not unique
|
||||||
message IsOrgUniqueRequest {
|
message IsOrgUniqueRequest {
|
||||||
option (grpc.gateway.protoc_gen_openapiv2.options.openapiv2_schema) = {
|
option (grpc.gateway.protoc_gen_openapiv2.options.openapiv2_schema) = {
|
||||||
|
@@ -20,7 +20,6 @@ message SecretGenerator {
|
|||||||
bool include_symbols = 8;
|
bool include_symbols = 8;
|
||||||
}
|
}
|
||||||
|
|
||||||
|
|
||||||
message SecretGeneratorQuery {
|
message SecretGeneratorQuery {
|
||||||
oneof query {
|
oneof query {
|
||||||
option (validate.required) = true;
|
option (validate.required) = true;
|
||||||
@@ -67,9 +66,16 @@ message TwilioConfig {
|
|||||||
string sender_number = 2;
|
string sender_number = 2;
|
||||||
}
|
}
|
||||||
|
|
||||||
|
|
||||||
enum SMSProviderConfigState {
|
enum SMSProviderConfigState {
|
||||||
SMS_PROVIDER_CONFIG_STATE_UNSPECIFIED = 0;
|
SMS_PROVIDER_CONFIG_STATE_UNSPECIFIED = 0;
|
||||||
SMS_PROVIDER_CONFIG_ACTIVE = 1;
|
SMS_PROVIDER_CONFIG_ACTIVE = 1;
|
||||||
SMS_PROVIDER_CONFIG_INACTIVE = 2;
|
SMS_PROVIDER_CONFIG_INACTIVE = 2;
|
||||||
}
|
}
|
||||||
|
|
||||||
|
message OIDCSettings {
|
||||||
|
zitadel.v1.ObjectDetails details = 1;
|
||||||
|
google.protobuf.Duration access_token_lifetime = 2;
|
||||||
|
google.protobuf.Duration id_token_lifetime = 3;
|
||||||
|
google.protobuf.Duration refresh_token_idle_expiration = 4;
|
||||||
|
google.protobuf.Duration refresh_token_expiration = 5;
|
||||||
|
}
|
||||||
|
Reference in New Issue
Block a user