feat: allow skip of success page for native apps (#5627)

add possibility to return to callback directly after login without rendering the successful login page
This commit is contained in:
Livio Spring
2023-04-11 17:07:32 +02:00
committed by GitHub
parent b3d8787921
commit 8bf36301ed
32 changed files with 641 additions and 390 deletions

View File

@@ -40,23 +40,24 @@ type App struct {
}
type OIDCApp struct {
RedirectURIs database.StringArray
ResponseTypes database.EnumArray[domain.OIDCResponseType]
GrantTypes database.EnumArray[domain.OIDCGrantType]
AppType domain.OIDCApplicationType
ClientID string
AuthMethodType domain.OIDCAuthMethodType
PostLogoutRedirectURIs database.StringArray
Version domain.OIDCVersion
ComplianceProblems database.StringArray
IsDevMode bool
AccessTokenType domain.OIDCTokenType
AssertAccessTokenRole bool
AssertIDTokenRole bool
AssertIDTokenUserinfo bool
ClockSkew time.Duration
AdditionalOrigins database.StringArray
AllowedOrigins database.StringArray
RedirectURIs database.StringArray
ResponseTypes database.EnumArray[domain.OIDCResponseType]
GrantTypes database.EnumArray[domain.OIDCGrantType]
AppType domain.OIDCApplicationType
ClientID string
AuthMethodType domain.OIDCAuthMethodType
PostLogoutRedirectURIs database.StringArray
Version domain.OIDCVersion
ComplianceProblems database.StringArray
IsDevMode bool
AccessTokenType domain.OIDCTokenType
AssertAccessTokenRole bool
AssertIDTokenRole bool
AssertIDTokenUserinfo bool
ClockSkew time.Duration
AdditionalOrigins database.StringArray
AllowedOrigins database.StringArray
SkipNativeAppSuccessPage bool
}
type SAMLApp struct {
@@ -241,6 +242,10 @@ var (
name: projection.AppOIDCConfigColumnAdditionalOrigins,
table: appOIDCConfigsTable,
}
AppOIDCConfigColumnSkipNativeAppSuccessPage = Column{
name: projection.AppOIDCConfigColumnSkipNativeAppSuccessPage,
table: appOIDCConfigsTable,
}
)
func (q *Queries) AppByProjectAndAppID(ctx context.Context, shouldTriggerBulk bool, projectID, appID string, withOwnerRemoved bool) (_ *App, err error) {
@@ -535,6 +540,7 @@ func prepareAppQuery(ctx context.Context, db prepareDatabase) (sq.SelectBuilder,
AppOIDCConfigColumnIDTokenUserinfoAssertion.identifier(),
AppOIDCConfigColumnClockSkew.identifier(),
AppOIDCConfigColumnAdditionalOrigins.identifier(),
AppOIDCConfigColumnSkipNativeAppSuccessPage.identifier(),
AppSAMLConfigColumnAppID.identifier(),
AppSAMLConfigColumnEntityID.identifier(),
@@ -583,6 +589,7 @@ func prepareAppQuery(ctx context.Context, db prepareDatabase) (sq.SelectBuilder,
&oidcConfig.iDTokenUserinfoAssertion,
&oidcConfig.clockSkew,
&oidcConfig.additionalOrigins,
&oidcConfig.skipNativeAppSuccessPage,
&samlConfig.appID,
&samlConfig.entityID,
@@ -703,6 +710,7 @@ func prepareAppsQuery(ctx context.Context, db prepareDatabase) (sq.SelectBuilder
AppOIDCConfigColumnIDTokenUserinfoAssertion.identifier(),
AppOIDCConfigColumnClockSkew.identifier(),
AppOIDCConfigColumnAdditionalOrigins.identifier(),
AppOIDCConfigColumnSkipNativeAppSuccessPage.identifier(),
AppSAMLConfigColumnAppID.identifier(),
AppSAMLConfigColumnEntityID.identifier(),
@@ -754,6 +762,7 @@ func prepareAppsQuery(ctx context.Context, db prepareDatabase) (sq.SelectBuilder
&oidcConfig.iDTokenUserinfoAssertion,
&oidcConfig.clockSkew,
&oidcConfig.additionalOrigins,
&oidcConfig.skipNativeAppSuccessPage,
&samlConfig.appID,
&samlConfig.entityID,
@@ -825,6 +834,7 @@ type sqlOIDCConfig struct {
additionalOrigins database.StringArray
responseTypes database.EnumArray[domain.OIDCResponseType]
grantTypes database.EnumArray[domain.OIDCGrantType]
skipNativeAppSuccessPage sql.NullBool
}
func (c sqlOIDCConfig) set(app *App) {
@@ -832,21 +842,22 @@ func (c sqlOIDCConfig) set(app *App) {
return
}
app.OIDCConfig = &OIDCApp{
Version: domain.OIDCVersion(c.version.Int32),
ClientID: c.clientID.String,
RedirectURIs: c.redirectUris,
AppType: domain.OIDCApplicationType(c.applicationType.Int16),
AuthMethodType: domain.OIDCAuthMethodType(c.authMethodType.Int16),
PostLogoutRedirectURIs: c.postLogoutRedirectUris,
IsDevMode: c.devMode.Bool,
AccessTokenType: domain.OIDCTokenType(c.accessTokenType.Int16),
AssertAccessTokenRole: c.accessTokenRoleAssertion.Bool,
AssertIDTokenRole: c.iDTokenRoleAssertion.Bool,
AssertIDTokenUserinfo: c.iDTokenUserinfoAssertion.Bool,
ClockSkew: time.Duration(c.clockSkew.Int64),
AdditionalOrigins: c.additionalOrigins,
ResponseTypes: c.responseTypes,
GrantTypes: c.grantTypes,
Version: domain.OIDCVersion(c.version.Int32),
ClientID: c.clientID.String,
RedirectURIs: c.redirectUris,
AppType: domain.OIDCApplicationType(c.applicationType.Int16),
AuthMethodType: domain.OIDCAuthMethodType(c.authMethodType.Int16),
PostLogoutRedirectURIs: c.postLogoutRedirectUris,
IsDevMode: c.devMode.Bool,
AccessTokenType: domain.OIDCTokenType(c.accessTokenType.Int16),
AssertAccessTokenRole: c.accessTokenRoleAssertion.Bool,
AssertIDTokenRole: c.iDTokenRoleAssertion.Bool,
AssertIDTokenUserinfo: c.iDTokenUserinfoAssertion.Bool,
ClockSkew: time.Duration(c.clockSkew.Int64),
AdditionalOrigins: c.additionalOrigins,
ResponseTypes: c.responseTypes,
GrantTypes: c.grantTypes,
SkipNativeAppSuccessPage: c.skipNativeAppSuccessPage.Bool,
}
compliance := domain.GetOIDCCompliance(app.OIDCConfig.Version, app.OIDCConfig.AppType, app.OIDCConfig.GrantTypes, app.OIDCConfig.ResponseTypes, app.OIDCConfig.AuthMethodType, app.OIDCConfig.RedirectURIs)
app.OIDCConfig.ComplianceProblems = compliance.Problems

View File

@@ -15,96 +15,98 @@ import (
)
var (
expectedAppQuery = regexp.QuoteMeta(`SELECT projections.apps4.id,` +
` projections.apps4.name,` +
` projections.apps4.project_id,` +
` projections.apps4.creation_date,` +
` projections.apps4.change_date,` +
` projections.apps4.resource_owner,` +
` projections.apps4.state,` +
` projections.apps4.sequence,` +
expectedAppQuery = regexp.QuoteMeta(`SELECT projections.apps5.id,` +
` projections.apps5.name,` +
` projections.apps5.project_id,` +
` projections.apps5.creation_date,` +
` projections.apps5.change_date,` +
` projections.apps5.resource_owner,` +
` projections.apps5.state,` +
` projections.apps5.sequence,` +
// api config
` projections.apps4_api_configs.app_id,` +
` projections.apps4_api_configs.client_id,` +
` projections.apps4_api_configs.auth_method,` +
` projections.apps5_api_configs.app_id,` +
` projections.apps5_api_configs.client_id,` +
` projections.apps5_api_configs.auth_method,` +
// oidc config
` projections.apps4_oidc_configs.app_id,` +
` projections.apps4_oidc_configs.version,` +
` projections.apps4_oidc_configs.client_id,` +
` projections.apps4_oidc_configs.redirect_uris,` +
` projections.apps4_oidc_configs.response_types,` +
` projections.apps4_oidc_configs.grant_types,` +
` projections.apps4_oidc_configs.application_type,` +
` projections.apps4_oidc_configs.auth_method_type,` +
` projections.apps4_oidc_configs.post_logout_redirect_uris,` +
` projections.apps4_oidc_configs.is_dev_mode,` +
` projections.apps4_oidc_configs.access_token_type,` +
` projections.apps4_oidc_configs.access_token_role_assertion,` +
` projections.apps4_oidc_configs.id_token_role_assertion,` +
` projections.apps4_oidc_configs.id_token_userinfo_assertion,` +
` projections.apps4_oidc_configs.clock_skew,` +
` projections.apps4_oidc_configs.additional_origins,` +
` projections.apps5_oidc_configs.app_id,` +
` projections.apps5_oidc_configs.version,` +
` projections.apps5_oidc_configs.client_id,` +
` projections.apps5_oidc_configs.redirect_uris,` +
` projections.apps5_oidc_configs.response_types,` +
` projections.apps5_oidc_configs.grant_types,` +
` projections.apps5_oidc_configs.application_type,` +
` projections.apps5_oidc_configs.auth_method_type,` +
` projections.apps5_oidc_configs.post_logout_redirect_uris,` +
` projections.apps5_oidc_configs.is_dev_mode,` +
` projections.apps5_oidc_configs.access_token_type,` +
` projections.apps5_oidc_configs.access_token_role_assertion,` +
` projections.apps5_oidc_configs.id_token_role_assertion,` +
` projections.apps5_oidc_configs.id_token_userinfo_assertion,` +
` projections.apps5_oidc_configs.clock_skew,` +
` projections.apps5_oidc_configs.additional_origins,` +
` projections.apps5_oidc_configs.skip_native_app_success_page,` +
//saml config
` projections.apps4_saml_configs.app_id,` +
` projections.apps4_saml_configs.entity_id,` +
` projections.apps4_saml_configs.metadata,` +
` projections.apps4_saml_configs.metadata_url` +
` FROM projections.apps4` +
` LEFT JOIN projections.apps4_api_configs ON projections.apps4.id = projections.apps4_api_configs.app_id AND projections.apps4.instance_id = projections.apps4_api_configs.instance_id` +
` LEFT JOIN projections.apps4_oidc_configs ON projections.apps4.id = projections.apps4_oidc_configs.app_id AND projections.apps4.instance_id = projections.apps4_oidc_configs.instance_id` +
` LEFT JOIN projections.apps4_saml_configs ON projections.apps4.id = projections.apps4_saml_configs.app_id AND projections.apps4.instance_id = projections.apps4_saml_configs.instance_id` +
` projections.apps5_saml_configs.app_id,` +
` projections.apps5_saml_configs.entity_id,` +
` projections.apps5_saml_configs.metadata,` +
` projections.apps5_saml_configs.metadata_url` +
` FROM projections.apps5` +
` LEFT JOIN projections.apps5_api_configs ON projections.apps5.id = projections.apps5_api_configs.app_id AND projections.apps5.instance_id = projections.apps5_api_configs.instance_id` +
` LEFT JOIN projections.apps5_oidc_configs ON projections.apps5.id = projections.apps5_oidc_configs.app_id AND projections.apps5.instance_id = projections.apps5_oidc_configs.instance_id` +
` LEFT JOIN projections.apps5_saml_configs ON projections.apps5.id = projections.apps5_saml_configs.app_id AND projections.apps5.instance_id = projections.apps5_saml_configs.instance_id` +
` AS OF SYSTEM TIME '-1 ms'`)
expectedAppsQuery = regexp.QuoteMeta(`SELECT projections.apps4.id,` +
` projections.apps4.name,` +
` projections.apps4.project_id,` +
` projections.apps4.creation_date,` +
` projections.apps4.change_date,` +
` projections.apps4.resource_owner,` +
` projections.apps4.state,` +
` projections.apps4.sequence,` +
expectedAppsQuery = regexp.QuoteMeta(`SELECT projections.apps5.id,` +
` projections.apps5.name,` +
` projections.apps5.project_id,` +
` projections.apps5.creation_date,` +
` projections.apps5.change_date,` +
` projections.apps5.resource_owner,` +
` projections.apps5.state,` +
` projections.apps5.sequence,` +
// api config
` projections.apps4_api_configs.app_id,` +
` projections.apps4_api_configs.client_id,` +
` projections.apps4_api_configs.auth_method,` +
` projections.apps5_api_configs.app_id,` +
` projections.apps5_api_configs.client_id,` +
` projections.apps5_api_configs.auth_method,` +
// oidc config
` projections.apps4_oidc_configs.app_id,` +
` projections.apps4_oidc_configs.version,` +
` projections.apps4_oidc_configs.client_id,` +
` projections.apps4_oidc_configs.redirect_uris,` +
` projections.apps4_oidc_configs.response_types,` +
` projections.apps4_oidc_configs.grant_types,` +
` projections.apps4_oidc_configs.application_type,` +
` projections.apps4_oidc_configs.auth_method_type,` +
` projections.apps4_oidc_configs.post_logout_redirect_uris,` +
` projections.apps4_oidc_configs.is_dev_mode,` +
` projections.apps4_oidc_configs.access_token_type,` +
` projections.apps4_oidc_configs.access_token_role_assertion,` +
` projections.apps4_oidc_configs.id_token_role_assertion,` +
` projections.apps4_oidc_configs.id_token_userinfo_assertion,` +
` projections.apps4_oidc_configs.clock_skew,` +
` projections.apps4_oidc_configs.additional_origins,` +
` projections.apps5_oidc_configs.app_id,` +
` projections.apps5_oidc_configs.version,` +
` projections.apps5_oidc_configs.client_id,` +
` projections.apps5_oidc_configs.redirect_uris,` +
` projections.apps5_oidc_configs.response_types,` +
` projections.apps5_oidc_configs.grant_types,` +
` projections.apps5_oidc_configs.application_type,` +
` projections.apps5_oidc_configs.auth_method_type,` +
` projections.apps5_oidc_configs.post_logout_redirect_uris,` +
` projections.apps5_oidc_configs.is_dev_mode,` +
` projections.apps5_oidc_configs.access_token_type,` +
` projections.apps5_oidc_configs.access_token_role_assertion,` +
` projections.apps5_oidc_configs.id_token_role_assertion,` +
` projections.apps5_oidc_configs.id_token_userinfo_assertion,` +
` projections.apps5_oidc_configs.clock_skew,` +
` projections.apps5_oidc_configs.additional_origins,` +
` projections.apps5_oidc_configs.skip_native_app_success_page,` +
//saml config
` projections.apps4_saml_configs.app_id,` +
` projections.apps4_saml_configs.entity_id,` +
` projections.apps4_saml_configs.metadata,` +
` projections.apps4_saml_configs.metadata_url,` +
` projections.apps5_saml_configs.app_id,` +
` projections.apps5_saml_configs.entity_id,` +
` projections.apps5_saml_configs.metadata,` +
` projections.apps5_saml_configs.metadata_url,` +
` COUNT(*) OVER ()` +
` FROM projections.apps4` +
` LEFT JOIN projections.apps4_api_configs ON projections.apps4.id = projections.apps4_api_configs.app_id AND projections.apps4.instance_id = projections.apps4_api_configs.instance_id` +
` LEFT JOIN projections.apps4_oidc_configs ON projections.apps4.id = projections.apps4_oidc_configs.app_id AND projections.apps4.instance_id = projections.apps4_oidc_configs.instance_id` +
` LEFT JOIN projections.apps4_saml_configs ON projections.apps4.id = projections.apps4_saml_configs.app_id AND projections.apps4.instance_id = projections.apps4_saml_configs.instance_id` +
` FROM projections.apps5` +
` LEFT JOIN projections.apps5_api_configs ON projections.apps5.id = projections.apps5_api_configs.app_id AND projections.apps5.instance_id = projections.apps5_api_configs.instance_id` +
` LEFT JOIN projections.apps5_oidc_configs ON projections.apps5.id = projections.apps5_oidc_configs.app_id AND projections.apps5.instance_id = projections.apps5_oidc_configs.instance_id` +
` LEFT JOIN projections.apps5_saml_configs ON projections.apps5.id = projections.apps5_saml_configs.app_id AND projections.apps5.instance_id = projections.apps5_saml_configs.instance_id` +
` AS OF SYSTEM TIME '-1 ms'`)
expectedAppIDsQuery = regexp.QuoteMeta(`SELECT projections.apps4_api_configs.client_id,` +
` projections.apps4_oidc_configs.client_id` +
` FROM projections.apps4` +
` LEFT JOIN projections.apps4_api_configs ON projections.apps4.id = projections.apps4_api_configs.app_id AND projections.apps4.instance_id = projections.apps4_api_configs.instance_id` +
` LEFT JOIN projections.apps4_oidc_configs ON projections.apps4.id = projections.apps4_oidc_configs.app_id AND projections.apps4.instance_id = projections.apps4_oidc_configs.instance_id` +
expectedAppIDsQuery = regexp.QuoteMeta(`SELECT projections.apps5_api_configs.client_id,` +
` projections.apps5_oidc_configs.client_id` +
` FROM projections.apps5` +
` LEFT JOIN projections.apps5_api_configs ON projections.apps5.id = projections.apps5_api_configs.app_id AND projections.apps5.instance_id = projections.apps5_api_configs.instance_id` +
` LEFT JOIN projections.apps5_oidc_configs ON projections.apps5.id = projections.apps5_oidc_configs.app_id AND projections.apps5.instance_id = projections.apps5_oidc_configs.instance_id` +
` AS OF SYSTEM TIME '-1 ms'`)
expectedProjectIDByAppQuery = regexp.QuoteMeta(`SELECT projections.apps4.project_id` +
` FROM projections.apps4` +
` LEFT JOIN projections.apps4_api_configs ON projections.apps4.id = projections.apps4_api_configs.app_id AND projections.apps4.instance_id = projections.apps4_api_configs.instance_id` +
` LEFT JOIN projections.apps4_oidc_configs ON projections.apps4.id = projections.apps4_oidc_configs.app_id AND projections.apps4.instance_id = projections.apps4_oidc_configs.instance_id` +
` LEFT JOIN projections.apps4_saml_configs ON projections.apps4.id = projections.apps4_saml_configs.app_id AND projections.apps4.instance_id = projections.apps4_saml_configs.instance_id` +
expectedProjectIDByAppQuery = regexp.QuoteMeta(`SELECT projections.apps5.project_id` +
` FROM projections.apps5` +
` LEFT JOIN projections.apps5_api_configs ON projections.apps5.id = projections.apps5_api_configs.app_id AND projections.apps5.instance_id = projections.apps5_api_configs.instance_id` +
` LEFT JOIN projections.apps5_oidc_configs ON projections.apps5.id = projections.apps5_oidc_configs.app_id AND projections.apps5.instance_id = projections.apps5_oidc_configs.instance_id` +
` LEFT JOIN projections.apps5_saml_configs ON projections.apps5.id = projections.apps5_saml_configs.app_id AND projections.apps5.instance_id = projections.apps5_saml_configs.instance_id` +
` AS OF SYSTEM TIME '-1 ms'`)
expectedProjectByAppQuery = regexp.QuoteMeta(`SELECT projections.projects3.id,` +
` projections.projects3.creation_date,` +
@@ -118,10 +120,10 @@ var (
` projections.projects3.has_project_check,` +
` projections.projects3.private_labeling_setting` +
` FROM projections.projects3` +
` JOIN projections.apps4 ON projections.projects3.id = projections.apps4.project_id AND projections.projects3.instance_id = projections.apps4.instance_id` +
` LEFT JOIN projections.apps4_api_configs ON projections.apps4.id = projections.apps4_api_configs.app_id AND projections.apps4.instance_id = projections.apps4_api_configs.instance_id` +
` LEFT JOIN projections.apps4_oidc_configs ON projections.apps4.id = projections.apps4_oidc_configs.app_id AND projections.apps4.instance_id = projections.apps4_oidc_configs.instance_id` +
` LEFT JOIN projections.apps4_saml_configs ON projections.apps4.id = projections.apps4_saml_configs.app_id AND projections.apps4.instance_id = projections.apps4_saml_configs.instance_id` +
` JOIN projections.apps5 ON projections.projects3.id = projections.apps5.project_id AND projections.projects3.instance_id = projections.apps5.instance_id` +
` LEFT JOIN projections.apps5_api_configs ON projections.apps5.id = projections.apps5_api_configs.app_id AND projections.apps5.instance_id = projections.apps5_api_configs.instance_id` +
` LEFT JOIN projections.apps5_oidc_configs ON projections.apps5.id = projections.apps5_oidc_configs.app_id AND projections.apps5.instance_id = projections.apps5_oidc_configs.instance_id` +
` LEFT JOIN projections.apps5_saml_configs ON projections.apps5.id = projections.apps5_saml_configs.app_id AND projections.apps5.instance_id = projections.apps5_saml_configs.instance_id` +
` AS OF SYSTEM TIME '-1 ms'`)
appCols = database.StringArray{
@@ -154,6 +156,7 @@ var (
"id_token_userinfo_assertion",
"clock_skew",
"additional_origins",
"skip_native_app_success_page",
//saml config
"app_id",
"entity_id",
@@ -224,6 +227,7 @@ func Test_AppsPrepare(t *testing.T) {
nil,
nil,
nil,
nil,
// saml config
nil,
nil,
@@ -289,6 +293,7 @@ func Test_AppsPrepare(t *testing.T) {
nil,
nil,
nil,
nil,
// saml config
nil,
nil,
@@ -357,6 +362,7 @@ func Test_AppsPrepare(t *testing.T) {
nil,
nil,
nil,
nil,
// saml config
"app-id",
"https://test.com/saml/metadata",
@@ -427,6 +433,7 @@ func Test_AppsPrepare(t *testing.T) {
true,
1 * time.Second,
database.StringArray{"additional.origin"},
false,
// saml config
nil,
nil,
@@ -451,23 +458,24 @@ func Test_AppsPrepare(t *testing.T) {
Name: "app-name",
ProjectID: "project-id",
OIDCConfig: &OIDCApp{
Version: domain.OIDCVersionV1,
ClientID: "oidc-client-id",
RedirectURIs: database.StringArray{"https://redirect.to/me"},
ResponseTypes: database.EnumArray[domain.OIDCResponseType]{domain.OIDCResponseTypeIDTokenToken},
GrantTypes: database.EnumArray[domain.OIDCGrantType]{domain.OIDCGrantTypeImplicit},
AppType: domain.OIDCApplicationTypeUserAgent,
AuthMethodType: domain.OIDCAuthMethodTypeNone,
PostLogoutRedirectURIs: database.StringArray{"post.logout.ch"},
IsDevMode: true,
AccessTokenType: domain.OIDCTokenTypeJWT,
AssertAccessTokenRole: true,
AssertIDTokenRole: true,
AssertIDTokenUserinfo: true,
ClockSkew: 1 * time.Second,
AdditionalOrigins: database.StringArray{"additional.origin"},
ComplianceProblems: nil,
AllowedOrigins: database.StringArray{"https://redirect.to", "additional.origin"},
Version: domain.OIDCVersionV1,
ClientID: "oidc-client-id",
RedirectURIs: database.StringArray{"https://redirect.to/me"},
ResponseTypes: database.EnumArray[domain.OIDCResponseType]{domain.OIDCResponseTypeIDTokenToken},
GrantTypes: database.EnumArray[domain.OIDCGrantType]{domain.OIDCGrantTypeImplicit},
AppType: domain.OIDCApplicationTypeUserAgent,
AuthMethodType: domain.OIDCAuthMethodTypeNone,
PostLogoutRedirectURIs: database.StringArray{"post.logout.ch"},
IsDevMode: true,
AccessTokenType: domain.OIDCTokenTypeJWT,
AssertAccessTokenRole: true,
AssertIDTokenRole: true,
AssertIDTokenUserinfo: true,
ClockSkew: 1 * time.Second,
AdditionalOrigins: database.StringArray{"additional.origin"},
ComplianceProblems: nil,
AllowedOrigins: database.StringArray{"https://redirect.to", "additional.origin"},
SkipNativeAppSuccessPage: false,
},
},
},
@@ -511,6 +519,7 @@ func Test_AppsPrepare(t *testing.T) {
true,
1 * time.Second,
database.StringArray{"additional.origin"},
false,
// saml config
nil,
nil,
@@ -535,23 +544,24 @@ func Test_AppsPrepare(t *testing.T) {
Name: "app-name",
ProjectID: "project-id",
OIDCConfig: &OIDCApp{
Version: domain.OIDCVersionV1,
ClientID: "oidc-client-id",
RedirectURIs: database.StringArray{"https://redirect.to/me"},
ResponseTypes: database.EnumArray[domain.OIDCResponseType]{domain.OIDCResponseTypeIDTokenToken},
GrantTypes: database.EnumArray[domain.OIDCGrantType]{domain.OIDCGrantTypeImplicit},
AppType: domain.OIDCApplicationTypeUserAgent,
AuthMethodType: domain.OIDCAuthMethodTypeNone,
PostLogoutRedirectURIs: database.StringArray{"post.logout.ch"},
IsDevMode: false,
AccessTokenType: domain.OIDCTokenTypeJWT,
AssertAccessTokenRole: false,
AssertIDTokenRole: false,
AssertIDTokenUserinfo: true,
ClockSkew: 1 * time.Second,
AdditionalOrigins: database.StringArray{"additional.origin"},
ComplianceProblems: nil,
AllowedOrigins: database.StringArray{"https://redirect.to", "additional.origin"},
Version: domain.OIDCVersionV1,
ClientID: "oidc-client-id",
RedirectURIs: database.StringArray{"https://redirect.to/me"},
ResponseTypes: database.EnumArray[domain.OIDCResponseType]{domain.OIDCResponseTypeIDTokenToken},
GrantTypes: database.EnumArray[domain.OIDCGrantType]{domain.OIDCGrantTypeImplicit},
AppType: domain.OIDCApplicationTypeUserAgent,
AuthMethodType: domain.OIDCAuthMethodTypeNone,
PostLogoutRedirectURIs: database.StringArray{"post.logout.ch"},
IsDevMode: false,
AccessTokenType: domain.OIDCTokenTypeJWT,
AssertAccessTokenRole: false,
AssertIDTokenRole: false,
AssertIDTokenUserinfo: true,
ClockSkew: 1 * time.Second,
AdditionalOrigins: database.StringArray{"additional.origin"},
ComplianceProblems: nil,
AllowedOrigins: database.StringArray{"https://redirect.to", "additional.origin"},
SkipNativeAppSuccessPage: false,
},
},
},
@@ -595,6 +605,7 @@ func Test_AppsPrepare(t *testing.T) {
true,
1 * time.Second,
database.StringArray{"additional.origin"},
false,
// saml config
nil,
nil,
@@ -619,23 +630,24 @@ func Test_AppsPrepare(t *testing.T) {
Name: "app-name",
ProjectID: "project-id",
OIDCConfig: &OIDCApp{
Version: domain.OIDCVersionV1,
ClientID: "oidc-client-id",
RedirectURIs: database.StringArray{"https://redirect.to/me"},
ResponseTypes: database.EnumArray[domain.OIDCResponseType]{domain.OIDCResponseTypeIDTokenToken},
GrantTypes: database.EnumArray[domain.OIDCGrantType]{domain.OIDCGrantTypeImplicit},
AppType: domain.OIDCApplicationTypeUserAgent,
AuthMethodType: domain.OIDCAuthMethodTypeNone,
PostLogoutRedirectURIs: database.StringArray{"post.logout.ch"},
IsDevMode: true,
AccessTokenType: domain.OIDCTokenTypeJWT,
AssertAccessTokenRole: true,
AssertIDTokenRole: false,
AssertIDTokenUserinfo: true,
ClockSkew: 1 * time.Second,
AdditionalOrigins: database.StringArray{"additional.origin"},
ComplianceProblems: nil,
AllowedOrigins: database.StringArray{"https://redirect.to", "additional.origin"},
Version: domain.OIDCVersionV1,
ClientID: "oidc-client-id",
RedirectURIs: database.StringArray{"https://redirect.to/me"},
ResponseTypes: database.EnumArray[domain.OIDCResponseType]{domain.OIDCResponseTypeIDTokenToken},
GrantTypes: database.EnumArray[domain.OIDCGrantType]{domain.OIDCGrantTypeImplicit},
AppType: domain.OIDCApplicationTypeUserAgent,
AuthMethodType: domain.OIDCAuthMethodTypeNone,
PostLogoutRedirectURIs: database.StringArray{"post.logout.ch"},
IsDevMode: true,
AccessTokenType: domain.OIDCTokenTypeJWT,
AssertAccessTokenRole: true,
AssertIDTokenRole: false,
AssertIDTokenUserinfo: true,
ClockSkew: 1 * time.Second,
AdditionalOrigins: database.StringArray{"additional.origin"},
ComplianceProblems: nil,
AllowedOrigins: database.StringArray{"https://redirect.to", "additional.origin"},
SkipNativeAppSuccessPage: false,
},
},
},
@@ -679,6 +691,7 @@ func Test_AppsPrepare(t *testing.T) {
true,
1 * time.Second,
database.StringArray{"additional.origin"},
false,
// saml config
nil,
nil,
@@ -703,23 +716,24 @@ func Test_AppsPrepare(t *testing.T) {
Name: "app-name",
ProjectID: "project-id",
OIDCConfig: &OIDCApp{
Version: domain.OIDCVersionV1,
ClientID: "oidc-client-id",
RedirectURIs: database.StringArray{"https://redirect.to/me"},
ResponseTypes: database.EnumArray[domain.OIDCResponseType]{domain.OIDCResponseTypeIDTokenToken},
GrantTypes: database.EnumArray[domain.OIDCGrantType]{domain.OIDCGrantTypeImplicit},
AppType: domain.OIDCApplicationTypeUserAgent,
AuthMethodType: domain.OIDCAuthMethodTypeNone,
PostLogoutRedirectURIs: database.StringArray{"post.logout.ch"},
IsDevMode: false,
AccessTokenType: domain.OIDCTokenTypeJWT,
AssertAccessTokenRole: false,
AssertIDTokenRole: true,
AssertIDTokenUserinfo: true,
ClockSkew: 1 * time.Second,
AdditionalOrigins: database.StringArray{"additional.origin"},
ComplianceProblems: nil,
AllowedOrigins: database.StringArray{"https://redirect.to", "additional.origin"},
Version: domain.OIDCVersionV1,
ClientID: "oidc-client-id",
RedirectURIs: database.StringArray{"https://redirect.to/me"},
ResponseTypes: database.EnumArray[domain.OIDCResponseType]{domain.OIDCResponseTypeIDTokenToken},
GrantTypes: database.EnumArray[domain.OIDCGrantType]{domain.OIDCGrantTypeImplicit},
AppType: domain.OIDCApplicationTypeUserAgent,
AuthMethodType: domain.OIDCAuthMethodTypeNone,
PostLogoutRedirectURIs: database.StringArray{"post.logout.ch"},
IsDevMode: false,
AccessTokenType: domain.OIDCTokenTypeJWT,
AssertAccessTokenRole: false,
AssertIDTokenRole: true,
AssertIDTokenUserinfo: true,
ClockSkew: 1 * time.Second,
AdditionalOrigins: database.StringArray{"additional.origin"},
ComplianceProblems: nil,
AllowedOrigins: database.StringArray{"https://redirect.to", "additional.origin"},
SkipNativeAppSuccessPage: false,
},
},
},
@@ -763,6 +777,7 @@ func Test_AppsPrepare(t *testing.T) {
true,
1 * time.Second,
database.StringArray{"additional.origin"},
false,
// saml config
nil,
nil,
@@ -787,23 +802,110 @@ func Test_AppsPrepare(t *testing.T) {
Name: "app-name",
ProjectID: "project-id",
OIDCConfig: &OIDCApp{
Version: domain.OIDCVersionV1,
ClientID: "oidc-client-id",
RedirectURIs: database.StringArray{"https://redirect.to/me"},
ResponseTypes: database.EnumArray[domain.OIDCResponseType]{domain.OIDCResponseTypeIDTokenToken},
GrantTypes: database.EnumArray[domain.OIDCGrantType]{domain.OIDCGrantTypeImplicit},
AppType: domain.OIDCApplicationTypeUserAgent,
AuthMethodType: domain.OIDCAuthMethodTypeNone,
PostLogoutRedirectURIs: database.StringArray{"post.logout.ch"},
IsDevMode: false,
AccessTokenType: domain.OIDCTokenTypeJWT,
AssertAccessTokenRole: true,
AssertIDTokenRole: true,
AssertIDTokenUserinfo: true,
ClockSkew: 1 * time.Second,
AdditionalOrigins: database.StringArray{"additional.origin"},
ComplianceProblems: nil,
AllowedOrigins: database.StringArray{"https://redirect.to", "additional.origin"},
Version: domain.OIDCVersionV1,
ClientID: "oidc-client-id",
RedirectURIs: database.StringArray{"https://redirect.to/me"},
ResponseTypes: database.EnumArray[domain.OIDCResponseType]{domain.OIDCResponseTypeIDTokenToken},
GrantTypes: database.EnumArray[domain.OIDCGrantType]{domain.OIDCGrantTypeImplicit},
AppType: domain.OIDCApplicationTypeUserAgent,
AuthMethodType: domain.OIDCAuthMethodTypeNone,
PostLogoutRedirectURIs: database.StringArray{"post.logout.ch"},
IsDevMode: false,
AccessTokenType: domain.OIDCTokenTypeJWT,
AssertAccessTokenRole: true,
AssertIDTokenRole: true,
AssertIDTokenUserinfo: true,
ClockSkew: 1 * time.Second,
AdditionalOrigins: database.StringArray{"additional.origin"},
ComplianceProblems: nil,
AllowedOrigins: database.StringArray{"https://redirect.to", "additional.origin"},
SkipNativeAppSuccessPage: false,
},
},
},
},
},
{
name: "prepareAppsQuery oidc app native success page skip",
prepare: prepareAppsQuery,
want: want{
sqlExpectations: mockQueries(
expectedAppsQuery,
appsCols,
[][]driver.Value{
{
"app-id",
"app-name",
"project-id",
testNow,
testNow,
"ro",
domain.AppStateActive,
uint64(20211109),
// api config
nil,
nil,
nil,
// oidc config
"app-id",
domain.OIDCVersionV1,
"oidc-client-id",
database.StringArray{"https://redirect.to/me"},
database.EnumArray[domain.OIDCResponseType]{domain.OIDCResponseTypeIDTokenToken},
database.EnumArray[domain.OIDCGrantType]{domain.OIDCGrantTypeImplicit},
domain.OIDCApplicationTypeNative,
domain.OIDCAuthMethodTypeNone,
database.StringArray{"post.logout.ch"},
false,
domain.OIDCTokenTypeJWT,
false,
false,
true,
1 * time.Second,
database.StringArray{"additional.origin"},
true,
// saml config
nil,
nil,
nil,
nil,
},
},
),
},
object: &Apps{
SearchResponse: SearchResponse{
Count: 1,
},
Apps: []*App{
{
ID: "app-id",
CreationDate: testNow,
ChangeDate: testNow,
ResourceOwner: "ro",
State: domain.AppStateActive,
Sequence: 20211109,
Name: "app-name",
ProjectID: "project-id",
OIDCConfig: &OIDCApp{
Version: domain.OIDCVersionV1,
ClientID: "oidc-client-id",
RedirectURIs: database.StringArray{"https://redirect.to/me"},
ResponseTypes: database.EnumArray[domain.OIDCResponseType]{domain.OIDCResponseTypeIDTokenToken},
GrantTypes: database.EnumArray[domain.OIDCGrantType]{domain.OIDCGrantTypeImplicit},
AppType: domain.OIDCApplicationTypeNative,
AuthMethodType: domain.OIDCAuthMethodTypeNone,
PostLogoutRedirectURIs: database.StringArray{"post.logout.ch"},
IsDevMode: false,
AccessTokenType: domain.OIDCTokenTypeJWT,
AssertAccessTokenRole: false,
AssertIDTokenRole: false,
AssertIDTokenUserinfo: true,
ClockSkew: 1 * time.Second,
AdditionalOrigins: database.StringArray{"additional.origin"},
ComplianceProblems: nil,
AllowedOrigins: database.StringArray{"https://redirect.to", "additional.origin"},
SkipNativeAppSuccessPage: true,
},
},
},
@@ -847,6 +949,7 @@ func Test_AppsPrepare(t *testing.T) {
true,
1 * time.Second,
database.StringArray{"additional.origin"},
false,
// saml config
nil,
nil,
@@ -883,6 +986,7 @@ func Test_AppsPrepare(t *testing.T) {
nil,
nil,
nil,
nil,
// saml config
nil,
nil,
@@ -919,6 +1023,7 @@ func Test_AppsPrepare(t *testing.T) {
nil,
nil,
nil,
nil,
// saml config
"saml-app-id",
"https://test.com/saml/metadata",
@@ -943,23 +1048,24 @@ func Test_AppsPrepare(t *testing.T) {
Name: "app-name",
ProjectID: "project-id",
OIDCConfig: &OIDCApp{
Version: domain.OIDCVersionV1,
ClientID: "oidc-client-id",
RedirectURIs: database.StringArray{"https://redirect.to/me"},
ResponseTypes: database.EnumArray[domain.OIDCResponseType]{domain.OIDCResponseTypeIDTokenToken},
GrantTypes: database.EnumArray[domain.OIDCGrantType]{domain.OIDCGrantTypeImplicit},
AppType: domain.OIDCApplicationTypeUserAgent,
AuthMethodType: domain.OIDCAuthMethodTypeNone,
PostLogoutRedirectURIs: database.StringArray{"post.logout.ch"},
IsDevMode: true,
AccessTokenType: domain.OIDCTokenTypeJWT,
AssertAccessTokenRole: true,
AssertIDTokenRole: true,
AssertIDTokenUserinfo: true,
ClockSkew: 1 * time.Second,
AdditionalOrigins: database.StringArray{"additional.origin"},
ComplianceProblems: nil,
AllowedOrigins: database.StringArray{"https://redirect.to", "additional.origin"},
Version: domain.OIDCVersionV1,
ClientID: "oidc-client-id",
RedirectURIs: database.StringArray{"https://redirect.to/me"},
ResponseTypes: database.EnumArray[domain.OIDCResponseType]{domain.OIDCResponseTypeIDTokenToken},
GrantTypes: database.EnumArray[domain.OIDCGrantType]{domain.OIDCGrantTypeImplicit},
AppType: domain.OIDCApplicationTypeUserAgent,
AuthMethodType: domain.OIDCAuthMethodTypeNone,
PostLogoutRedirectURIs: database.StringArray{"post.logout.ch"},
IsDevMode: true,
AccessTokenType: domain.OIDCTokenTypeJWT,
AssertAccessTokenRole: true,
AssertIDTokenRole: true,
AssertIDTokenUserinfo: true,
ClockSkew: 1 * time.Second,
AdditionalOrigins: database.StringArray{"additional.origin"},
ComplianceProblems: nil,
AllowedOrigins: database.StringArray{"https://redirect.to", "additional.origin"},
SkipNativeAppSuccessPage: false,
},
},
{
@@ -1085,6 +1191,7 @@ func Test_AppPrepare(t *testing.T) {
nil,
nil,
nil,
nil,
// saml config
nil,
nil,
@@ -1142,6 +1249,7 @@ func Test_AppPrepare(t *testing.T) {
nil,
nil,
nil,
nil,
// saml config
nil,
nil,
@@ -1204,6 +1312,7 @@ func Test_AppPrepare(t *testing.T) {
true,
1 * time.Second,
database.StringArray{"additional.origin"},
false,
// saml config
nil,
nil,
@@ -1223,23 +1332,24 @@ func Test_AppPrepare(t *testing.T) {
Name: "app-name",
ProjectID: "project-id",
OIDCConfig: &OIDCApp{
Version: domain.OIDCVersionV1,
ClientID: "oidc-client-id",
RedirectURIs: database.StringArray{"https://redirect.to/me"},
ResponseTypes: database.EnumArray[domain.OIDCResponseType]{domain.OIDCResponseTypeIDTokenToken},
GrantTypes: database.EnumArray[domain.OIDCGrantType]{domain.OIDCGrantTypeImplicit},
AppType: domain.OIDCApplicationTypeUserAgent,
AuthMethodType: domain.OIDCAuthMethodTypeNone,
PostLogoutRedirectURIs: database.StringArray{"post.logout.ch"},
IsDevMode: true,
AccessTokenType: domain.OIDCTokenTypeJWT,
AssertAccessTokenRole: true,
AssertIDTokenRole: true,
AssertIDTokenUserinfo: true,
ClockSkew: 1 * time.Second,
AdditionalOrigins: database.StringArray{"additional.origin"},
ComplianceProblems: nil,
AllowedOrigins: database.StringArray{"https://redirect.to", "additional.origin"},
Version: domain.OIDCVersionV1,
ClientID: "oidc-client-id",
RedirectURIs: database.StringArray{"https://redirect.to/me"},
ResponseTypes: database.EnumArray[domain.OIDCResponseType]{domain.OIDCResponseTypeIDTokenToken},
GrantTypes: database.EnumArray[domain.OIDCGrantType]{domain.OIDCGrantTypeImplicit},
AppType: domain.OIDCApplicationTypeUserAgent,
AuthMethodType: domain.OIDCAuthMethodTypeNone,
PostLogoutRedirectURIs: database.StringArray{"post.logout.ch"},
IsDevMode: true,
AccessTokenType: domain.OIDCTokenTypeJWT,
AssertAccessTokenRole: true,
AssertIDTokenRole: true,
AssertIDTokenUserinfo: true,
ClockSkew: 1 * time.Second,
AdditionalOrigins: database.StringArray{"additional.origin"},
ComplianceProblems: nil,
AllowedOrigins: database.StringArray{"https://redirect.to", "additional.origin"},
SkipNativeAppSuccessPage: false,
},
},
}, {
@@ -1280,6 +1390,7 @@ func Test_AppPrepare(t *testing.T) {
nil,
nil,
nil,
nil,
// saml config
"app-id",
"https://test.com/saml/metadata",
@@ -1343,6 +1454,7 @@ func Test_AppPrepare(t *testing.T) {
true,
1 * time.Second,
database.StringArray{"additional.origin"},
false,
// saml config
nil,
nil,
@@ -1362,23 +1474,24 @@ func Test_AppPrepare(t *testing.T) {
Name: "app-name",
ProjectID: "project-id",
OIDCConfig: &OIDCApp{
Version: domain.OIDCVersionV1,
ClientID: "oidc-client-id",
RedirectURIs: database.StringArray{"https://redirect.to/me"},
ResponseTypes: database.EnumArray[domain.OIDCResponseType]{domain.OIDCResponseTypeIDTokenToken},
GrantTypes: database.EnumArray[domain.OIDCGrantType]{domain.OIDCGrantTypeImplicit},
AppType: domain.OIDCApplicationTypeUserAgent,
AuthMethodType: domain.OIDCAuthMethodTypeNone,
PostLogoutRedirectURIs: database.StringArray{"post.logout.ch"},
IsDevMode: false,
AccessTokenType: domain.OIDCTokenTypeJWT,
AssertAccessTokenRole: true,
AssertIDTokenRole: true,
AssertIDTokenUserinfo: true,
ClockSkew: 1 * time.Second,
AdditionalOrigins: database.StringArray{"additional.origin"},
ComplianceProblems: nil,
AllowedOrigins: database.StringArray{"https://redirect.to", "additional.origin"},
Version: domain.OIDCVersionV1,
ClientID: "oidc-client-id",
RedirectURIs: database.StringArray{"https://redirect.to/me"},
ResponseTypes: database.EnumArray[domain.OIDCResponseType]{domain.OIDCResponseTypeIDTokenToken},
GrantTypes: database.EnumArray[domain.OIDCGrantType]{domain.OIDCGrantTypeImplicit},
AppType: domain.OIDCApplicationTypeUserAgent,
AuthMethodType: domain.OIDCAuthMethodTypeNone,
PostLogoutRedirectURIs: database.StringArray{"post.logout.ch"},
IsDevMode: false,
AccessTokenType: domain.OIDCTokenTypeJWT,
AssertAccessTokenRole: true,
AssertIDTokenRole: true,
AssertIDTokenUserinfo: true,
ClockSkew: 1 * time.Second,
AdditionalOrigins: database.StringArray{"additional.origin"},
ComplianceProblems: nil,
AllowedOrigins: database.StringArray{"https://redirect.to", "additional.origin"},
SkipNativeAppSuccessPage: false,
},
},
},
@@ -1420,6 +1533,7 @@ func Test_AppPrepare(t *testing.T) {
true,
1 * time.Second,
database.StringArray{"additional.origin"},
false,
// saml config
nil,
nil,
@@ -1439,23 +1553,24 @@ func Test_AppPrepare(t *testing.T) {
Name: "app-name",
ProjectID: "project-id",
OIDCConfig: &OIDCApp{
Version: domain.OIDCVersionV1,
ClientID: "oidc-client-id",
RedirectURIs: database.StringArray{"https://redirect.to/me"},
ResponseTypes: database.EnumArray[domain.OIDCResponseType]{domain.OIDCResponseTypeIDTokenToken},
GrantTypes: database.EnumArray[domain.OIDCGrantType]{domain.OIDCGrantTypeImplicit},
AppType: domain.OIDCApplicationTypeUserAgent,
AuthMethodType: domain.OIDCAuthMethodTypeNone,
PostLogoutRedirectURIs: database.StringArray{"post.logout.ch"},
IsDevMode: true,
AccessTokenType: domain.OIDCTokenTypeJWT,
AssertAccessTokenRole: false,
AssertIDTokenRole: true,
AssertIDTokenUserinfo: true,
ClockSkew: 1 * time.Second,
AdditionalOrigins: database.StringArray{"additional.origin"},
ComplianceProblems: nil,
AllowedOrigins: database.StringArray{"https://redirect.to", "additional.origin"},
Version: domain.OIDCVersionV1,
ClientID: "oidc-client-id",
RedirectURIs: database.StringArray{"https://redirect.to/me"},
ResponseTypes: database.EnumArray[domain.OIDCResponseType]{domain.OIDCResponseTypeIDTokenToken},
GrantTypes: database.EnumArray[domain.OIDCGrantType]{domain.OIDCGrantTypeImplicit},
AppType: domain.OIDCApplicationTypeUserAgent,
AuthMethodType: domain.OIDCAuthMethodTypeNone,
PostLogoutRedirectURIs: database.StringArray{"post.logout.ch"},
IsDevMode: true,
AccessTokenType: domain.OIDCTokenTypeJWT,
AssertAccessTokenRole: false,
AssertIDTokenRole: true,
AssertIDTokenUserinfo: true,
ClockSkew: 1 * time.Second,
AdditionalOrigins: database.StringArray{"additional.origin"},
ComplianceProblems: nil,
AllowedOrigins: database.StringArray{"https://redirect.to", "additional.origin"},
SkipNativeAppSuccessPage: false,
},
},
},
@@ -1497,6 +1612,7 @@ func Test_AppPrepare(t *testing.T) {
true,
1 * time.Second,
database.StringArray{"additional.origin"},
false,
// saml config
nil,
nil,
@@ -1516,23 +1632,24 @@ func Test_AppPrepare(t *testing.T) {
Name: "app-name",
ProjectID: "project-id",
OIDCConfig: &OIDCApp{
Version: domain.OIDCVersionV1,
ClientID: "oidc-client-id",
RedirectURIs: database.StringArray{"https://redirect.to/me"},
ResponseTypes: database.EnumArray[domain.OIDCResponseType]{domain.OIDCResponseTypeIDTokenToken},
GrantTypes: database.EnumArray[domain.OIDCGrantType]{domain.OIDCGrantTypeImplicit},
AppType: domain.OIDCApplicationTypeUserAgent,
AuthMethodType: domain.OIDCAuthMethodTypeNone,
PostLogoutRedirectURIs: database.StringArray{"post.logout.ch"},
IsDevMode: true,
AccessTokenType: domain.OIDCTokenTypeJWT,
AssertAccessTokenRole: true,
AssertIDTokenRole: false,
AssertIDTokenUserinfo: true,
ClockSkew: 1 * time.Second,
AdditionalOrigins: database.StringArray{"additional.origin"},
ComplianceProblems: nil,
AllowedOrigins: database.StringArray{"https://redirect.to", "additional.origin"},
Version: domain.OIDCVersionV1,
ClientID: "oidc-client-id",
RedirectURIs: database.StringArray{"https://redirect.to/me"},
ResponseTypes: database.EnumArray[domain.OIDCResponseType]{domain.OIDCResponseTypeIDTokenToken},
GrantTypes: database.EnumArray[domain.OIDCGrantType]{domain.OIDCGrantTypeImplicit},
AppType: domain.OIDCApplicationTypeUserAgent,
AuthMethodType: domain.OIDCAuthMethodTypeNone,
PostLogoutRedirectURIs: database.StringArray{"post.logout.ch"},
IsDevMode: true,
AccessTokenType: domain.OIDCTokenTypeJWT,
AssertAccessTokenRole: true,
AssertIDTokenRole: false,
AssertIDTokenUserinfo: true,
ClockSkew: 1 * time.Second,
AdditionalOrigins: database.StringArray{"additional.origin"},
ComplianceProblems: nil,
AllowedOrigins: database.StringArray{"https://redirect.to", "additional.origin"},
SkipNativeAppSuccessPage: false,
},
},
},
@@ -1574,6 +1691,7 @@ func Test_AppPrepare(t *testing.T) {
false,
1 * time.Second,
database.StringArray{"additional.origin"},
false,
// saml config
nil,
nil,
@@ -1593,23 +1711,24 @@ func Test_AppPrepare(t *testing.T) {
Name: "app-name",
ProjectID: "project-id",
OIDCConfig: &OIDCApp{
Version: domain.OIDCVersionV1,
ClientID: "oidc-client-id",
RedirectURIs: database.StringArray{"https://redirect.to/me"},
ResponseTypes: database.EnumArray[domain.OIDCResponseType]{domain.OIDCResponseTypeIDTokenToken},
GrantTypes: database.EnumArray[domain.OIDCGrantType]{domain.OIDCGrantTypeImplicit},
AppType: domain.OIDCApplicationTypeUserAgent,
AuthMethodType: domain.OIDCAuthMethodTypeNone,
PostLogoutRedirectURIs: database.StringArray{"post.logout.ch"},
IsDevMode: true,
AccessTokenType: domain.OIDCTokenTypeJWT,
AssertAccessTokenRole: true,
AssertIDTokenRole: true,
AssertIDTokenUserinfo: false,
ClockSkew: 1 * time.Second,
AdditionalOrigins: database.StringArray{"additional.origin"},
ComplianceProblems: nil,
AllowedOrigins: database.StringArray{"https://redirect.to", "additional.origin"},
Version: domain.OIDCVersionV1,
ClientID: "oidc-client-id",
RedirectURIs: database.StringArray{"https://redirect.to/me"},
ResponseTypes: database.EnumArray[domain.OIDCResponseType]{domain.OIDCResponseTypeIDTokenToken},
GrantTypes: database.EnumArray[domain.OIDCGrantType]{domain.OIDCGrantTypeImplicit},
AppType: domain.OIDCApplicationTypeUserAgent,
AuthMethodType: domain.OIDCAuthMethodTypeNone,
PostLogoutRedirectURIs: database.StringArray{"post.logout.ch"},
IsDevMode: true,
AccessTokenType: domain.OIDCTokenTypeJWT,
AssertAccessTokenRole: true,
AssertIDTokenRole: true,
AssertIDTokenUserinfo: false,
ClockSkew: 1 * time.Second,
AdditionalOrigins: database.StringArray{"additional.origin"},
ComplianceProblems: nil,
AllowedOrigins: database.StringArray{"https://redirect.to", "additional.origin"},
SkipNativeAppSuccessPage: false,
},
},
},

View File

@@ -15,7 +15,7 @@ import (
)
const (
AppProjectionTable = "projections.apps4"
AppProjectionTable = "projections.apps5"
AppAPITable = AppProjectionTable + "_" + appAPITableSuffix
AppOIDCTable = AppProjectionTable + "_" + appOIDCTableSuffix
AppSAMLTable = AppProjectionTable + "_" + appSAMLTableSuffix
@@ -57,6 +57,7 @@ const (
AppOIDCConfigColumnIDTokenUserinfoAssertion = "id_token_userinfo_assertion"
AppOIDCConfigColumnClockSkew = "clock_skew"
AppOIDCConfigColumnAdditionalOrigins = "additional_origins"
AppOIDCConfigColumnSkipNativeAppSuccessPage = "skip_native_app_success_page"
appSAMLTableSuffix = "saml_configs"
AppSAMLConfigColumnAppID = "app_id"
@@ -122,6 +123,7 @@ func newAppProjection(ctx context.Context, config crdb.StatementHandlerConfig) *
crdb.NewColumn(AppOIDCConfigColumnIDTokenUserinfoAssertion, crdb.ColumnTypeBool, crdb.Default(false)),
crdb.NewColumn(AppOIDCConfigColumnClockSkew, crdb.ColumnTypeInt64, crdb.Default(0)),
crdb.NewColumn(AppOIDCConfigColumnAdditionalOrigins, crdb.ColumnTypeTextArray, crdb.Nullable()),
crdb.NewColumn(AppOIDCConfigColumnSkipNativeAppSuccessPage, crdb.ColumnTypeBool, crdb.Default(false)),
},
crdb.NewPrimaryKey(AppOIDCConfigColumnInstanceID, AppOIDCConfigColumnAppID),
appOIDCTableSuffix,
@@ -463,6 +465,7 @@ func (p *appProjection) reduceOIDCConfigAdded(event eventstore.Event) (*handler.
handler.NewCol(AppOIDCConfigColumnIDTokenUserinfoAssertion, e.IDTokenUserinfoAssertion),
handler.NewCol(AppOIDCConfigColumnClockSkew, e.ClockSkew),
handler.NewCol(AppOIDCConfigColumnAdditionalOrigins, database.StringArray(e.AdditionalOrigins)),
handler.NewCol(AppOIDCConfigColumnSkipNativeAppSuccessPage, e.SkipNativeAppSuccessPage),
},
crdb.WithTableSuffix(appOIDCTableSuffix),
),
@@ -528,6 +531,9 @@ func (p *appProjection) reduceOIDCConfigChanged(event eventstore.Event) (*handle
if e.AdditionalOrigins != nil {
cols = append(cols, handler.NewCol(AppOIDCConfigColumnAdditionalOrigins, database.StringArray(*e.AdditionalOrigins)))
}
if e.SkipNativeAppSuccessPage != nil {
cols = append(cols, handler.NewCol(AppOIDCConfigColumnSkipNativeAppSuccessPage, *e.SkipNativeAppSuccessPage))
}
if len(cols) == 0 {
return crdb.NewNoOpStatement(e), nil

View File

@@ -45,7 +45,7 @@ func TestAppProjection_reduces(t *testing.T) {
executer: &testExecuter{
executions: []execution{
{
expectedStmt: "INSERT INTO projections.apps4 (id, name, project_id, creation_date, change_date, resource_owner, instance_id, state, sequence) VALUES ($1, $2, $3, $4, $5, $6, $7, $8, $9)",
expectedStmt: "INSERT INTO projections.apps5 (id, name, project_id, creation_date, change_date, resource_owner, instance_id, state, sequence) VALUES ($1, $2, $3, $4, $5, $6, $7, $8, $9)",
expectedArgs: []interface{}{
"app-id",
"my-app",
@@ -82,7 +82,7 @@ func TestAppProjection_reduces(t *testing.T) {
executer: &testExecuter{
executions: []execution{
{
expectedStmt: "UPDATE projections.apps4 SET (name, change_date, sequence) = ($1, $2, $3) WHERE (id = $4) AND (instance_id = $5)",
expectedStmt: "UPDATE projections.apps5 SET (name, change_date, sequence) = ($1, $2, $3) WHERE (id = $4) AND (instance_id = $5)",
expectedArgs: []interface{}{
"my-app",
anyArg{},
@@ -95,6 +95,27 @@ func TestAppProjection_reduces(t *testing.T) {
},
},
},
{
name: "project reduceAppChanged no change",
args: args{
event: getEvent(testEvent(
repository.EventType(project.ApplicationChangedType),
project.AggregateType,
[]byte(`{
"appId": "app-id"
}`),
), project.ApplicationChangedEventMapper),
},
reduce: (&appProjection{}).reduceAppChanged,
want: wantReduce{
aggregateType: eventstore.AggregateType("project"),
sequence: 15,
previousSequence: 10,
executer: &testExecuter{
executions: []execution{},
},
},
},
{
name: "project reduceAppDeactivated",
args: args{
@@ -114,7 +135,7 @@ func TestAppProjection_reduces(t *testing.T) {
executer: &testExecuter{
executions: []execution{
{
expectedStmt: "UPDATE projections.apps4 SET (state, change_date, sequence) = ($1, $2, $3) WHERE (id = $4) AND (instance_id = $5)",
expectedStmt: "UPDATE projections.apps5 SET (state, change_date, sequence) = ($1, $2, $3) WHERE (id = $4) AND (instance_id = $5)",
expectedArgs: []interface{}{
domain.AppStateInactive,
anyArg{},
@@ -146,7 +167,7 @@ func TestAppProjection_reduces(t *testing.T) {
executer: &testExecuter{
executions: []execution{
{
expectedStmt: "UPDATE projections.apps4 SET (state, change_date, sequence) = ($1, $2, $3) WHERE (id = $4) AND (instance_id = $5)",
expectedStmt: "UPDATE projections.apps5 SET (state, change_date, sequence) = ($1, $2, $3) WHERE (id = $4) AND (instance_id = $5)",
expectedArgs: []interface{}{
domain.AppStateActive,
anyArg{},
@@ -178,7 +199,7 @@ func TestAppProjection_reduces(t *testing.T) {
executer: &testExecuter{
executions: []execution{
{
expectedStmt: "DELETE FROM projections.apps4 WHERE (id = $1) AND (instance_id = $2)",
expectedStmt: "DELETE FROM projections.apps5 WHERE (id = $1) AND (instance_id = $2)",
expectedArgs: []interface{}{
"app-id",
"instance-id",
@@ -205,7 +226,7 @@ func TestAppProjection_reduces(t *testing.T) {
executer: &testExecuter{
executions: []execution{
{
expectedStmt: "DELETE FROM projections.apps4 WHERE (project_id = $1) AND (instance_id = $2)",
expectedStmt: "DELETE FROM projections.apps5 WHERE (project_id = $1) AND (instance_id = $2)",
expectedArgs: []interface{}{
"agg-id",
"instance-id",
@@ -232,7 +253,7 @@ func TestAppProjection_reduces(t *testing.T) {
executer: &testExecuter{
executions: []execution{
{
expectedStmt: "DELETE FROM projections.apps4 WHERE (instance_id = $1)",
expectedStmt: "DELETE FROM projections.apps5 WHERE (instance_id = $1)",
expectedArgs: []interface{}{
"agg-id",
},
@@ -263,7 +284,7 @@ func TestAppProjection_reduces(t *testing.T) {
executer: &testExecuter{
executions: []execution{
{
expectedStmt: "INSERT INTO projections.apps4_api_configs (app_id, instance_id, client_id, client_secret, auth_method) VALUES ($1, $2, $3, $4, $5)",
expectedStmt: "INSERT INTO projections.apps5_api_configs (app_id, instance_id, client_id, client_secret, auth_method) VALUES ($1, $2, $3, $4, $5)",
expectedArgs: []interface{}{
"app-id",
"instance-id",
@@ -273,7 +294,7 @@ func TestAppProjection_reduces(t *testing.T) {
},
},
{
expectedStmt: "UPDATE projections.apps4 SET (change_date, sequence) = ($1, $2) WHERE (id = $3) AND (instance_id = $4)",
expectedStmt: "UPDATE projections.apps5 SET (change_date, sequence) = ($1, $2) WHERE (id = $3) AND (instance_id = $4)",
expectedArgs: []interface{}{
anyArg{},
uint64(15),
@@ -307,7 +328,7 @@ func TestAppProjection_reduces(t *testing.T) {
executer: &testExecuter{
executions: []execution{
{
expectedStmt: "UPDATE projections.apps4_api_configs SET (client_secret, auth_method) = ($1, $2) WHERE (app_id = $3) AND (instance_id = $4)",
expectedStmt: "UPDATE projections.apps5_api_configs SET (client_secret, auth_method) = ($1, $2) WHERE (app_id = $3) AND (instance_id = $4)",
expectedArgs: []interface{}{
anyArg{},
domain.APIAuthMethodTypePrivateKeyJWT,
@@ -316,7 +337,7 @@ func TestAppProjection_reduces(t *testing.T) {
},
},
{
expectedStmt: "UPDATE projections.apps4 SET (change_date, sequence) = ($1, $2) WHERE (id = $3) AND (instance_id = $4)",
expectedStmt: "UPDATE projections.apps5 SET (change_date, sequence) = ($1, $2) WHERE (id = $3) AND (instance_id = $4)",
expectedArgs: []interface{}{
anyArg{},
uint64(15),
@@ -369,7 +390,7 @@ func TestAppProjection_reduces(t *testing.T) {
executer: &testExecuter{
executions: []execution{
{
expectedStmt: "UPDATE projections.apps4_api_configs SET client_secret = $1 WHERE (app_id = $2) AND (instance_id = $3)",
expectedStmt: "UPDATE projections.apps5_api_configs SET client_secret = $1 WHERE (app_id = $2) AND (instance_id = $3)",
expectedArgs: []interface{}{
anyArg{},
"app-id",
@@ -377,7 +398,7 @@ func TestAppProjection_reduces(t *testing.T) {
},
},
{
expectedStmt: "UPDATE projections.apps4 SET (change_date, sequence) = ($1, $2) WHERE (id = $3) AND (instance_id = $4)",
expectedStmt: "UPDATE projections.apps5 SET (change_date, sequence) = ($1, $2) WHERE (id = $3) AND (instance_id = $4)",
expectedArgs: []interface{}{
anyArg{},
uint64(15),
@@ -412,7 +433,8 @@ func TestAppProjection_reduces(t *testing.T) {
"idTokenRoleAssertion": true,
"idTokenUserinfoAssertion": true,
"clockSkew": 1000,
"additionalOrigins": ["origin.one.ch", "origin.two.ch"]
"additionalOrigins": ["origin.one.ch", "origin.two.ch"],
"skipNativeAppSuccessPage": true
}`),
), project.OIDCConfigAddedEventMapper),
},
@@ -424,7 +446,7 @@ func TestAppProjection_reduces(t *testing.T) {
executer: &testExecuter{
executions: []execution{
{
expectedStmt: "INSERT INTO projections.apps4_oidc_configs (app_id, instance_id, version, client_id, client_secret, redirect_uris, response_types, grant_types, application_type, auth_method_type, post_logout_redirect_uris, is_dev_mode, access_token_type, access_token_role_assertion, id_token_role_assertion, id_token_userinfo_assertion, clock_skew, additional_origins) VALUES ($1, $2, $3, $4, $5, $6, $7, $8, $9, $10, $11, $12, $13, $14, $15, $16, $17, $18)",
expectedStmt: "INSERT INTO projections.apps5_oidc_configs (app_id, instance_id, version, client_id, client_secret, redirect_uris, response_types, grant_types, application_type, auth_method_type, post_logout_redirect_uris, is_dev_mode, access_token_type, access_token_role_assertion, id_token_role_assertion, id_token_userinfo_assertion, clock_skew, additional_origins, skip_native_app_success_page) VALUES ($1, $2, $3, $4, $5, $6, $7, $8, $9, $10, $11, $12, $13, $14, $15, $16, $17, $18, $19)",
expectedArgs: []interface{}{
"app-id",
"instance-id",
@@ -444,10 +466,11 @@ func TestAppProjection_reduces(t *testing.T) {
true,
1 * time.Microsecond,
database.StringArray{"origin.one.ch", "origin.two.ch"},
true,
},
},
{
expectedStmt: "UPDATE projections.apps4 SET (change_date, sequence) = ($1, $2) WHERE (id = $3) AND (instance_id = $4)",
expectedStmt: "UPDATE projections.apps5 SET (change_date, sequence) = ($1, $2) WHERE (id = $3) AND (instance_id = $4)",
expectedArgs: []interface{}{
anyArg{},
uint64(15),
@@ -480,7 +503,9 @@ func TestAppProjection_reduces(t *testing.T) {
"idTokenRoleAssertion": true,
"idTokenUserinfoAssertion": true,
"clockSkew": 1000,
"additionalOrigins": ["origin.one.ch", "origin.two.ch"]
"additionalOrigins": ["origin.one.ch", "origin.two.ch"],
"skipNativeAppSuccessPage": true
}`),
), project.OIDCConfigChangedEventMapper),
},
@@ -492,7 +517,7 @@ func TestAppProjection_reduces(t *testing.T) {
executer: &testExecuter{
executions: []execution{
{
expectedStmt: "UPDATE projections.apps4_oidc_configs SET (version, redirect_uris, response_types, grant_types, application_type, auth_method_type, post_logout_redirect_uris, is_dev_mode, access_token_type, access_token_role_assertion, id_token_role_assertion, id_token_userinfo_assertion, clock_skew, additional_origins) = ($1, $2, $3, $4, $5, $6, $7, $8, $9, $10, $11, $12, $13, $14) WHERE (app_id = $15) AND (instance_id = $16)",
expectedStmt: "UPDATE projections.apps5_oidc_configs SET (version, redirect_uris, response_types, grant_types, application_type, auth_method_type, post_logout_redirect_uris, is_dev_mode, access_token_type, access_token_role_assertion, id_token_role_assertion, id_token_userinfo_assertion, clock_skew, additional_origins, skip_native_app_success_page) = ($1, $2, $3, $4, $5, $6, $7, $8, $9, $10, $11, $12, $13, $14, $15) WHERE (app_id = $16) AND (instance_id = $17)",
expectedArgs: []interface{}{
domain.OIDCVersionV1,
database.StringArray{"redirect.one.ch", "redirect.two.ch"},
@@ -508,12 +533,13 @@ func TestAppProjection_reduces(t *testing.T) {
true,
1 * time.Microsecond,
database.StringArray{"origin.one.ch", "origin.two.ch"},
true,
"app-id",
"instance-id",
},
},
{
expectedStmt: "UPDATE projections.apps4 SET (change_date, sequence) = ($1, $2) WHERE (id = $3) AND (instance_id = $4)",
expectedStmt: "UPDATE projections.apps5 SET (change_date, sequence) = ($1, $2) WHERE (id = $3) AND (instance_id = $4)",
expectedArgs: []interface{}{
anyArg{},
uint64(15),
@@ -566,7 +592,7 @@ func TestAppProjection_reduces(t *testing.T) {
executer: &testExecuter{
executions: []execution{
{
expectedStmt: "UPDATE projections.apps4_oidc_configs SET client_secret = $1 WHERE (app_id = $2) AND (instance_id = $3)",
expectedStmt: "UPDATE projections.apps5_oidc_configs SET client_secret = $1 WHERE (app_id = $2) AND (instance_id = $3)",
expectedArgs: []interface{}{
anyArg{},
"app-id",
@@ -574,7 +600,7 @@ func TestAppProjection_reduces(t *testing.T) {
},
},
{
expectedStmt: "UPDATE projections.apps4 SET (change_date, sequence) = ($1, $2) WHERE (id = $3) AND (instance_id = $4)",
expectedStmt: "UPDATE projections.apps5 SET (change_date, sequence) = ($1, $2) WHERE (id = $3) AND (instance_id = $4)",
expectedArgs: []interface{}{
anyArg{},
uint64(15),
@@ -603,7 +629,7 @@ func TestAppProjection_reduces(t *testing.T) {
executer: &testExecuter{
executions: []execution{
{
expectedStmt: "UPDATE projections.apps4 SET (change_date, sequence, owner_removed) = ($1, $2, $3) WHERE (instance_id = $4) AND (resource_owner = $5)",
expectedStmt: "UPDATE projections.apps5 SET (change_date, sequence, owner_removed) = ($1, $2, $3) WHERE (instance_id = $4) AND (resource_owner = $5)",
expectedArgs: []interface{}{
anyArg{},
uint64(15),