mirror of
https://github.com/zitadel/zitadel.git
synced 2024-12-13 19:44:21 +00:00
d01bd1c51a
# Which Problems Are Solved In Zitadel, even after an organization is deactivated, associated projects, respectively their applications remain active. Users across other organizations can still log in and access through these applications, leading to unauthorized access. Additionally, if a project was deactivated access to applications was also still possible. # How the Problems Are Solved - Correctly check the status of the organization and related project. (Corresponding functions have been renamed to `Active...`)
2220 lines
68 KiB
Go
2220 lines
68 KiB
Go
package query
|
|
|
|
import (
|
|
"context"
|
|
"database/sql"
|
|
"database/sql/driver"
|
|
"errors"
|
|
"fmt"
|
|
"regexp"
|
|
"testing"
|
|
"time"
|
|
|
|
sq "github.com/Masterminds/squirrel"
|
|
|
|
"github.com/zitadel/zitadel/internal/database"
|
|
"github.com/zitadel/zitadel/internal/domain"
|
|
"github.com/zitadel/zitadel/internal/zerrors"
|
|
)
|
|
|
|
var (
|
|
expectedAppQueryBase = `SELECT projections.apps7.id,` +
|
|
` projections.apps7.name,` +
|
|
` projections.apps7.project_id,` +
|
|
` projections.apps7.creation_date,` +
|
|
` projections.apps7.change_date,` +
|
|
` projections.apps7.resource_owner,` +
|
|
` projections.apps7.state,` +
|
|
` projections.apps7.sequence,` +
|
|
// api config
|
|
` projections.apps7_api_configs.app_id,` +
|
|
` projections.apps7_api_configs.client_id,` +
|
|
` projections.apps7_api_configs.auth_method,` +
|
|
// oidc config
|
|
` projections.apps7_oidc_configs.app_id,` +
|
|
` projections.apps7_oidc_configs.version,` +
|
|
` projections.apps7_oidc_configs.client_id,` +
|
|
` projections.apps7_oidc_configs.redirect_uris,` +
|
|
` projections.apps7_oidc_configs.response_types,` +
|
|
` projections.apps7_oidc_configs.grant_types,` +
|
|
` projections.apps7_oidc_configs.application_type,` +
|
|
` projections.apps7_oidc_configs.auth_method_type,` +
|
|
` projections.apps7_oidc_configs.post_logout_redirect_uris,` +
|
|
` projections.apps7_oidc_configs.is_dev_mode,` +
|
|
` projections.apps7_oidc_configs.access_token_type,` +
|
|
` projections.apps7_oidc_configs.access_token_role_assertion,` +
|
|
` projections.apps7_oidc_configs.id_token_role_assertion,` +
|
|
` projections.apps7_oidc_configs.id_token_userinfo_assertion,` +
|
|
` projections.apps7_oidc_configs.clock_skew,` +
|
|
` projections.apps7_oidc_configs.additional_origins,` +
|
|
` projections.apps7_oidc_configs.skip_native_app_success_page,` +
|
|
//saml config
|
|
` projections.apps7_saml_configs.app_id,` +
|
|
` projections.apps7_saml_configs.entity_id,` +
|
|
` projections.apps7_saml_configs.metadata,` +
|
|
` projections.apps7_saml_configs.metadata_url` +
|
|
` FROM projections.apps7` +
|
|
` LEFT JOIN projections.apps7_api_configs ON projections.apps7.id = projections.apps7_api_configs.app_id AND projections.apps7.instance_id = projections.apps7_api_configs.instance_id` +
|
|
` LEFT JOIN projections.apps7_oidc_configs ON projections.apps7.id = projections.apps7_oidc_configs.app_id AND projections.apps7.instance_id = projections.apps7_oidc_configs.instance_id` +
|
|
` LEFT JOIN projections.apps7_saml_configs ON projections.apps7.id = projections.apps7_saml_configs.app_id AND projections.apps7.instance_id = projections.apps7_saml_configs.instance_id`
|
|
expectedAppQuery = regexp.QuoteMeta(expectedAppQueryBase)
|
|
expectedActiveAppQuery = regexp.QuoteMeta(expectedAppQueryBase +
|
|
` LEFT JOIN projections.projects4 ON projections.apps7.project_id = projections.projects4.id AND projections.apps7.instance_id = projections.projects4.instance_id` +
|
|
` LEFT JOIN projections.orgs1 ON projections.apps7.resource_owner = projections.orgs1.id AND projections.apps7.instance_id = projections.orgs1.instance_id`)
|
|
expectedAppsQuery = regexp.QuoteMeta(`SELECT projections.apps7.id,` +
|
|
` projections.apps7.name,` +
|
|
` projections.apps7.project_id,` +
|
|
` projections.apps7.creation_date,` +
|
|
` projections.apps7.change_date,` +
|
|
` projections.apps7.resource_owner,` +
|
|
` projections.apps7.state,` +
|
|
` projections.apps7.sequence,` +
|
|
// api config
|
|
` projections.apps7_api_configs.app_id,` +
|
|
` projections.apps7_api_configs.client_id,` +
|
|
` projections.apps7_api_configs.auth_method,` +
|
|
// oidc config
|
|
` projections.apps7_oidc_configs.app_id,` +
|
|
` projections.apps7_oidc_configs.version,` +
|
|
` projections.apps7_oidc_configs.client_id,` +
|
|
` projections.apps7_oidc_configs.redirect_uris,` +
|
|
` projections.apps7_oidc_configs.response_types,` +
|
|
` projections.apps7_oidc_configs.grant_types,` +
|
|
` projections.apps7_oidc_configs.application_type,` +
|
|
` projections.apps7_oidc_configs.auth_method_type,` +
|
|
` projections.apps7_oidc_configs.post_logout_redirect_uris,` +
|
|
` projections.apps7_oidc_configs.is_dev_mode,` +
|
|
` projections.apps7_oidc_configs.access_token_type,` +
|
|
` projections.apps7_oidc_configs.access_token_role_assertion,` +
|
|
` projections.apps7_oidc_configs.id_token_role_assertion,` +
|
|
` projections.apps7_oidc_configs.id_token_userinfo_assertion,` +
|
|
` projections.apps7_oidc_configs.clock_skew,` +
|
|
` projections.apps7_oidc_configs.additional_origins,` +
|
|
` projections.apps7_oidc_configs.skip_native_app_success_page,` +
|
|
//saml config
|
|
` projections.apps7_saml_configs.app_id,` +
|
|
` projections.apps7_saml_configs.entity_id,` +
|
|
` projections.apps7_saml_configs.metadata,` +
|
|
` projections.apps7_saml_configs.metadata_url,` +
|
|
` COUNT(*) OVER ()` +
|
|
` FROM projections.apps7` +
|
|
` LEFT JOIN projections.apps7_api_configs ON projections.apps7.id = projections.apps7_api_configs.app_id AND projections.apps7.instance_id = projections.apps7_api_configs.instance_id` +
|
|
` LEFT JOIN projections.apps7_oidc_configs ON projections.apps7.id = projections.apps7_oidc_configs.app_id AND projections.apps7.instance_id = projections.apps7_oidc_configs.instance_id` +
|
|
` LEFT JOIN projections.apps7_saml_configs ON projections.apps7.id = projections.apps7_saml_configs.app_id AND projections.apps7.instance_id = projections.apps7_saml_configs.instance_id` +
|
|
` AS OF SYSTEM TIME '-1 ms'`)
|
|
expectedAppIDsQuery = regexp.QuoteMeta(`SELECT projections.apps7_api_configs.client_id,` +
|
|
` projections.apps7_oidc_configs.client_id` +
|
|
` FROM projections.apps7` +
|
|
` LEFT JOIN projections.apps7_api_configs ON projections.apps7.id = projections.apps7_api_configs.app_id AND projections.apps7.instance_id = projections.apps7_api_configs.instance_id` +
|
|
` LEFT JOIN projections.apps7_oidc_configs ON projections.apps7.id = projections.apps7_oidc_configs.app_id AND projections.apps7.instance_id = projections.apps7_oidc_configs.instance_id` +
|
|
` AS OF SYSTEM TIME '-1 ms'`)
|
|
expectedProjectIDByAppQuery = regexp.QuoteMeta(`SELECT projections.apps7.project_id` +
|
|
` FROM projections.apps7` +
|
|
` LEFT JOIN projections.apps7_api_configs ON projections.apps7.id = projections.apps7_api_configs.app_id AND projections.apps7.instance_id = projections.apps7_api_configs.instance_id` +
|
|
` LEFT JOIN projections.apps7_oidc_configs ON projections.apps7.id = projections.apps7_oidc_configs.app_id AND projections.apps7.instance_id = projections.apps7_oidc_configs.instance_id` +
|
|
` LEFT JOIN projections.apps7_saml_configs ON projections.apps7.id = projections.apps7_saml_configs.app_id AND projections.apps7.instance_id = projections.apps7_saml_configs.instance_id` +
|
|
` AS OF SYSTEM TIME '-1 ms'`)
|
|
expectedProjectByAppQuery = regexp.QuoteMeta(`SELECT projections.projects4.id,` +
|
|
` projections.projects4.creation_date,` +
|
|
` projections.projects4.change_date,` +
|
|
` projections.projects4.resource_owner,` +
|
|
` projections.projects4.state,` +
|
|
` projections.projects4.sequence,` +
|
|
` projections.projects4.name,` +
|
|
` projections.projects4.project_role_assertion,` +
|
|
` projections.projects4.project_role_check,` +
|
|
` projections.projects4.has_project_check,` +
|
|
` projections.projects4.private_labeling_setting` +
|
|
` FROM projections.projects4` +
|
|
` JOIN projections.apps7 ON projections.projects4.id = projections.apps7.project_id AND projections.projects4.instance_id = projections.apps7.instance_id` +
|
|
` LEFT JOIN projections.apps7_api_configs ON projections.apps7.id = projections.apps7_api_configs.app_id AND projections.apps7.instance_id = projections.apps7_api_configs.instance_id` +
|
|
` LEFT JOIN projections.apps7_oidc_configs ON projections.apps7.id = projections.apps7_oidc_configs.app_id AND projections.apps7.instance_id = projections.apps7_oidc_configs.instance_id` +
|
|
` LEFT JOIN projections.apps7_saml_configs ON projections.apps7.id = projections.apps7_saml_configs.app_id AND projections.apps7.instance_id = projections.apps7_saml_configs.instance_id` +
|
|
` AS OF SYSTEM TIME '-1 ms'`)
|
|
|
|
appCols = database.TextArray[string]{
|
|
"id",
|
|
"name",
|
|
"project_id",
|
|
"creation_date",
|
|
"change_date",
|
|
"resource_owner",
|
|
"state",
|
|
"sequence",
|
|
// api config
|
|
"app_id",
|
|
"client_id",
|
|
"auth_method",
|
|
// oidc config
|
|
"app_id",
|
|
"version",
|
|
"client_id",
|
|
"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",
|
|
//saml config
|
|
"app_id",
|
|
"entity_id",
|
|
"metadata",
|
|
"metadata_url",
|
|
}
|
|
appsCols = append(appCols, "count")
|
|
)
|
|
|
|
func Test_AppsPrepare(t *testing.T) {
|
|
type want struct {
|
|
sqlExpectations sqlExpectation
|
|
err checkErr
|
|
}
|
|
tests := []struct {
|
|
name string
|
|
prepare interface{}
|
|
want want
|
|
object interface{}
|
|
}{
|
|
{
|
|
name: "prepareAppsQuery no result",
|
|
prepare: prepareAppsQuery,
|
|
want: want{
|
|
sqlExpectations: mockQueries(
|
|
expectedAppsQuery,
|
|
nil,
|
|
nil,
|
|
),
|
|
},
|
|
object: &Apps{Apps: []*App{}},
|
|
},
|
|
{
|
|
name: "prepareAppsQuery only app",
|
|
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
|
|
nil,
|
|
nil,
|
|
nil,
|
|
nil,
|
|
nil,
|
|
nil,
|
|
nil,
|
|
nil,
|
|
nil,
|
|
nil,
|
|
nil,
|
|
nil,
|
|
nil,
|
|
nil,
|
|
nil,
|
|
nil,
|
|
nil,
|
|
// 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",
|
|
},
|
|
},
|
|
},
|
|
},
|
|
{
|
|
name: "prepareAppsQuery api app",
|
|
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
|
|
"app-id",
|
|
"api-client-id",
|
|
domain.APIAuthMethodTypePrivateKeyJWT,
|
|
// oidc config
|
|
nil,
|
|
nil,
|
|
nil,
|
|
nil,
|
|
nil,
|
|
nil,
|
|
nil,
|
|
nil,
|
|
nil,
|
|
nil,
|
|
nil,
|
|
nil,
|
|
nil,
|
|
nil,
|
|
nil,
|
|
nil,
|
|
nil,
|
|
// 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",
|
|
APIConfig: &APIApp{
|
|
ClientID: "api-client-id",
|
|
AuthMethodType: domain.APIAuthMethodTypePrivateKeyJWT,
|
|
},
|
|
},
|
|
},
|
|
},
|
|
}, {
|
|
name: "prepareAppsQuery saml app",
|
|
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
|
|
nil,
|
|
nil,
|
|
nil,
|
|
nil,
|
|
nil,
|
|
nil,
|
|
nil,
|
|
nil,
|
|
nil,
|
|
nil,
|
|
nil,
|
|
nil,
|
|
nil,
|
|
nil,
|
|
nil,
|
|
nil,
|
|
nil,
|
|
// saml config
|
|
"app-id",
|
|
"https://test.com/saml/metadata",
|
|
[]byte("<?xml version=\"1.0\"?>\n<md:EntityDescriptor xmlns:md=\"urn:oasis:names:tc:SAML:2.0:metadata\"\n validUntil=\"2022-08-26T14:08:16Z\"\n cacheDuration=\"PT604800S\"\n entityID=\"https://test.com/saml/metadata\">\n <md:SPSSODescriptor AuthnRequestsSigned=\"false\" WantAssertionsSigned=\"false\" protocolSupportEnumeration=\"urn:oasis:names:tc:SAML:2.0:protocol\">\n <md:NameIDFormat>urn:oasis:names:tc:SAML:1.1:nameid-format:unspecified</md:NameIDFormat>\n <md:AssertionConsumerService Binding=\"urn:oasis:names:tc:SAML:2.0:bindings:HTTP-POST\"\n Location=\"https://test.com/saml/acs\"\n index=\"1\" />\n \n </md:SPSSODescriptor>\n</md:EntityDescriptor>"),
|
|
"https://test.com/saml/metadata",
|
|
},
|
|
},
|
|
),
|
|
},
|
|
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",
|
|
SAMLConfig: &SAMLApp{
|
|
Metadata: []byte("<?xml version=\"1.0\"?>\n<md:EntityDescriptor xmlns:md=\"urn:oasis:names:tc:SAML:2.0:metadata\"\n validUntil=\"2022-08-26T14:08:16Z\"\n cacheDuration=\"PT604800S\"\n entityID=\"https://test.com/saml/metadata\">\n <md:SPSSODescriptor AuthnRequestsSigned=\"false\" WantAssertionsSigned=\"false\" protocolSupportEnumeration=\"urn:oasis:names:tc:SAML:2.0:protocol\">\n <md:NameIDFormat>urn:oasis:names:tc:SAML:1.1:nameid-format:unspecified</md:NameIDFormat>\n <md:AssertionConsumerService Binding=\"urn:oasis:names:tc:SAML:2.0:bindings:HTTP-POST\"\n Location=\"https://test.com/saml/acs\"\n index=\"1\" />\n \n </md:SPSSODescriptor>\n</md:EntityDescriptor>"),
|
|
MetadataURL: "https://test.com/saml/metadata",
|
|
EntityID: "https://test.com/saml/metadata",
|
|
},
|
|
},
|
|
},
|
|
},
|
|
},
|
|
{
|
|
name: "prepareAppsQuery oidc app",
|
|
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.TextArray[string]{"https://redirect.to/me"},
|
|
database.NumberArray[domain.OIDCResponseType]{domain.OIDCResponseTypeIDTokenToken},
|
|
database.NumberArray[domain.OIDCGrantType]{domain.OIDCGrantTypeImplicit},
|
|
domain.OIDCApplicationTypeUserAgent,
|
|
domain.OIDCAuthMethodTypeNone,
|
|
database.TextArray[string]{"post.logout.ch"},
|
|
true,
|
|
domain.OIDCTokenTypeJWT,
|
|
true,
|
|
true,
|
|
true,
|
|
1 * time.Second,
|
|
database.TextArray[string]{"additional.origin"},
|
|
false,
|
|
// 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.TextArray[string]{"https://redirect.to/me"},
|
|
ResponseTypes: database.NumberArray[domain.OIDCResponseType]{domain.OIDCResponseTypeIDTokenToken},
|
|
GrantTypes: database.NumberArray[domain.OIDCGrantType]{domain.OIDCGrantTypeImplicit},
|
|
AppType: domain.OIDCApplicationTypeUserAgent,
|
|
AuthMethodType: domain.OIDCAuthMethodTypeNone,
|
|
PostLogoutRedirectURIs: database.TextArray[string]{"post.logout.ch"},
|
|
IsDevMode: true,
|
|
AccessTokenType: domain.OIDCTokenTypeJWT,
|
|
AssertAccessTokenRole: true,
|
|
AssertIDTokenRole: true,
|
|
AssertIDTokenUserinfo: true,
|
|
ClockSkew: 1 * time.Second,
|
|
AdditionalOrigins: database.TextArray[string]{"additional.origin"},
|
|
ComplianceProblems: nil,
|
|
AllowedOrigins: database.TextArray[string]{"https://redirect.to", "additional.origin"},
|
|
SkipNativeAppSuccessPage: false,
|
|
},
|
|
},
|
|
},
|
|
},
|
|
},
|
|
{
|
|
name: "prepareAppsQuery oidc app AssertIDTokenUserinfo active",
|
|
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.TextArray[string]{"https://redirect.to/me"},
|
|
database.NumberArray[domain.OIDCResponseType]{domain.OIDCResponseTypeIDTokenToken},
|
|
database.NumberArray[domain.OIDCGrantType]{domain.OIDCGrantTypeImplicit},
|
|
domain.OIDCApplicationTypeUserAgent,
|
|
domain.OIDCAuthMethodTypeNone,
|
|
database.TextArray[string]{"post.logout.ch"},
|
|
false,
|
|
domain.OIDCTokenTypeJWT,
|
|
false,
|
|
false,
|
|
true,
|
|
1 * time.Second,
|
|
database.TextArray[string]{"additional.origin"},
|
|
false,
|
|
// 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.TextArray[string]{"https://redirect.to/me"},
|
|
ResponseTypes: database.NumberArray[domain.OIDCResponseType]{domain.OIDCResponseTypeIDTokenToken},
|
|
GrantTypes: database.NumberArray[domain.OIDCGrantType]{domain.OIDCGrantTypeImplicit},
|
|
AppType: domain.OIDCApplicationTypeUserAgent,
|
|
AuthMethodType: domain.OIDCAuthMethodTypeNone,
|
|
PostLogoutRedirectURIs: database.TextArray[string]{"post.logout.ch"},
|
|
IsDevMode: false,
|
|
AccessTokenType: domain.OIDCTokenTypeJWT,
|
|
AssertAccessTokenRole: false,
|
|
AssertIDTokenRole: false,
|
|
AssertIDTokenUserinfo: true,
|
|
ClockSkew: 1 * time.Second,
|
|
AdditionalOrigins: database.TextArray[string]{"additional.origin"},
|
|
ComplianceProblems: nil,
|
|
AllowedOrigins: database.TextArray[string]{"https://redirect.to", "additional.origin"},
|
|
SkipNativeAppSuccessPage: false,
|
|
},
|
|
},
|
|
},
|
|
},
|
|
},
|
|
{
|
|
name: "prepareAppsQuery oidc app AssertIDTokenRole active",
|
|
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.TextArray[string]{"https://redirect.to/me"},
|
|
database.NumberArray[domain.OIDCResponseType]{domain.OIDCResponseTypeIDTokenToken},
|
|
database.NumberArray[domain.OIDCGrantType]{domain.OIDCGrantTypeImplicit},
|
|
domain.OIDCApplicationTypeUserAgent,
|
|
domain.OIDCAuthMethodTypeNone,
|
|
database.TextArray[string]{"post.logout.ch"},
|
|
true,
|
|
domain.OIDCTokenTypeJWT,
|
|
true,
|
|
false,
|
|
true,
|
|
1 * time.Second,
|
|
database.TextArray[string]{"additional.origin"},
|
|
false,
|
|
// 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.TextArray[string]{"https://redirect.to/me"},
|
|
ResponseTypes: database.NumberArray[domain.OIDCResponseType]{domain.OIDCResponseTypeIDTokenToken},
|
|
GrantTypes: database.NumberArray[domain.OIDCGrantType]{domain.OIDCGrantTypeImplicit},
|
|
AppType: domain.OIDCApplicationTypeUserAgent,
|
|
AuthMethodType: domain.OIDCAuthMethodTypeNone,
|
|
PostLogoutRedirectURIs: database.TextArray[string]{"post.logout.ch"},
|
|
IsDevMode: true,
|
|
AccessTokenType: domain.OIDCTokenTypeJWT,
|
|
AssertAccessTokenRole: true,
|
|
AssertIDTokenRole: false,
|
|
AssertIDTokenUserinfo: true,
|
|
ClockSkew: 1 * time.Second,
|
|
AdditionalOrigins: database.TextArray[string]{"additional.origin"},
|
|
ComplianceProblems: nil,
|
|
AllowedOrigins: database.TextArray[string]{"https://redirect.to", "additional.origin"},
|
|
SkipNativeAppSuccessPage: false,
|
|
},
|
|
},
|
|
},
|
|
},
|
|
},
|
|
{
|
|
name: "prepareAppsQuery oidc app AssertAccessTokenRole active",
|
|
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.TextArray[string]{"https://redirect.to/me"},
|
|
database.NumberArray[domain.OIDCResponseType]{domain.OIDCResponseTypeIDTokenToken},
|
|
database.NumberArray[domain.OIDCGrantType]{domain.OIDCGrantTypeImplicit},
|
|
domain.OIDCApplicationTypeUserAgent,
|
|
domain.OIDCAuthMethodTypeNone,
|
|
database.TextArray[string]{"post.logout.ch"},
|
|
false,
|
|
domain.OIDCTokenTypeJWT,
|
|
false,
|
|
true,
|
|
true,
|
|
1 * time.Second,
|
|
database.TextArray[string]{"additional.origin"},
|
|
false,
|
|
// 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.TextArray[string]{"https://redirect.to/me"},
|
|
ResponseTypes: database.NumberArray[domain.OIDCResponseType]{domain.OIDCResponseTypeIDTokenToken},
|
|
GrantTypes: database.NumberArray[domain.OIDCGrantType]{domain.OIDCGrantTypeImplicit},
|
|
AppType: domain.OIDCApplicationTypeUserAgent,
|
|
AuthMethodType: domain.OIDCAuthMethodTypeNone,
|
|
PostLogoutRedirectURIs: database.TextArray[string]{"post.logout.ch"},
|
|
IsDevMode: false,
|
|
AccessTokenType: domain.OIDCTokenTypeJWT,
|
|
AssertAccessTokenRole: false,
|
|
AssertIDTokenRole: true,
|
|
AssertIDTokenUserinfo: true,
|
|
ClockSkew: 1 * time.Second,
|
|
AdditionalOrigins: database.TextArray[string]{"additional.origin"},
|
|
ComplianceProblems: nil,
|
|
AllowedOrigins: database.TextArray[string]{"https://redirect.to", "additional.origin"},
|
|
SkipNativeAppSuccessPage: false,
|
|
},
|
|
},
|
|
},
|
|
},
|
|
},
|
|
{
|
|
name: "prepareAppsQuery oidc app IsDevMode active",
|
|
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.TextArray[string]{"https://redirect.to/me"},
|
|
database.NumberArray[domain.OIDCResponseType]{domain.OIDCResponseTypeIDTokenToken},
|
|
database.NumberArray[domain.OIDCGrantType]{domain.OIDCGrantTypeImplicit},
|
|
domain.OIDCApplicationTypeUserAgent,
|
|
domain.OIDCAuthMethodTypeNone,
|
|
database.TextArray[string]{"post.logout.ch"},
|
|
false,
|
|
domain.OIDCTokenTypeJWT,
|
|
true,
|
|
true,
|
|
true,
|
|
1 * time.Second,
|
|
database.TextArray[string]{"additional.origin"},
|
|
false,
|
|
// 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.TextArray[string]{"https://redirect.to/me"},
|
|
ResponseTypes: database.NumberArray[domain.OIDCResponseType]{domain.OIDCResponseTypeIDTokenToken},
|
|
GrantTypes: database.NumberArray[domain.OIDCGrantType]{domain.OIDCGrantTypeImplicit},
|
|
AppType: domain.OIDCApplicationTypeUserAgent,
|
|
AuthMethodType: domain.OIDCAuthMethodTypeNone,
|
|
PostLogoutRedirectURIs: database.TextArray[string]{"post.logout.ch"},
|
|
IsDevMode: false,
|
|
AccessTokenType: domain.OIDCTokenTypeJWT,
|
|
AssertAccessTokenRole: true,
|
|
AssertIDTokenRole: true,
|
|
AssertIDTokenUserinfo: true,
|
|
ClockSkew: 1 * time.Second,
|
|
AdditionalOrigins: database.TextArray[string]{"additional.origin"},
|
|
ComplianceProblems: nil,
|
|
AllowedOrigins: database.TextArray[string]{"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.TextArray[string]{"https://redirect.to/me"},
|
|
database.NumberArray[domain.OIDCResponseType]{domain.OIDCResponseTypeIDTokenToken},
|
|
database.NumberArray[domain.OIDCGrantType]{domain.OIDCGrantTypeImplicit},
|
|
domain.OIDCApplicationTypeNative,
|
|
domain.OIDCAuthMethodTypeNone,
|
|
database.TextArray[string]{"post.logout.ch"},
|
|
false,
|
|
domain.OIDCTokenTypeJWT,
|
|
false,
|
|
false,
|
|
true,
|
|
1 * time.Second,
|
|
database.TextArray[string]{"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.TextArray[string]{"https://redirect.to/me"},
|
|
ResponseTypes: database.NumberArray[domain.OIDCResponseType]{domain.OIDCResponseTypeIDTokenToken},
|
|
GrantTypes: database.NumberArray[domain.OIDCGrantType]{domain.OIDCGrantTypeImplicit},
|
|
AppType: domain.OIDCApplicationTypeNative,
|
|
AuthMethodType: domain.OIDCAuthMethodTypeNone,
|
|
PostLogoutRedirectURIs: database.TextArray[string]{"post.logout.ch"},
|
|
IsDevMode: false,
|
|
AccessTokenType: domain.OIDCTokenTypeJWT,
|
|
AssertAccessTokenRole: false,
|
|
AssertIDTokenRole: false,
|
|
AssertIDTokenUserinfo: true,
|
|
ClockSkew: 1 * time.Second,
|
|
AdditionalOrigins: database.TextArray[string]{"additional.origin"},
|
|
ComplianceProblems: nil,
|
|
AllowedOrigins: database.TextArray[string]{"https://redirect.to", "additional.origin"},
|
|
SkipNativeAppSuccessPage: true,
|
|
},
|
|
},
|
|
},
|
|
},
|
|
},
|
|
{
|
|
name: "prepareAppsQuery multiple result",
|
|
prepare: prepareAppsQuery,
|
|
want: want{
|
|
sqlExpectations: mockQueries(
|
|
expectedAppsQuery,
|
|
appsCols,
|
|
[][]driver.Value{
|
|
{
|
|
"oidc-app-id",
|
|
"app-name",
|
|
"project-id",
|
|
testNow,
|
|
testNow,
|
|
"ro",
|
|
domain.AppStateActive,
|
|
uint64(20211109),
|
|
// api config
|
|
nil,
|
|
nil,
|
|
nil,
|
|
// oidc config
|
|
"oidc-app-id",
|
|
domain.OIDCVersionV1,
|
|
"oidc-client-id",
|
|
database.TextArray[string]{"https://redirect.to/me"},
|
|
database.NumberArray[domain.OIDCResponseType]{domain.OIDCResponseTypeIDTokenToken},
|
|
database.NumberArray[domain.OIDCGrantType]{domain.OIDCGrantTypeImplicit},
|
|
domain.OIDCApplicationTypeUserAgent,
|
|
domain.OIDCAuthMethodTypeNone,
|
|
database.TextArray[string]{"post.logout.ch"},
|
|
true,
|
|
domain.OIDCTokenTypeJWT,
|
|
true,
|
|
true,
|
|
true,
|
|
1 * time.Second,
|
|
database.TextArray[string]{"additional.origin"},
|
|
false,
|
|
// saml config
|
|
nil,
|
|
nil,
|
|
nil,
|
|
nil,
|
|
},
|
|
{
|
|
"api-app-id",
|
|
"app-name",
|
|
"project-id",
|
|
testNow,
|
|
testNow,
|
|
"ro",
|
|
domain.AppStateActive,
|
|
uint64(20211109),
|
|
// api config
|
|
"api-app-id",
|
|
"api-client-id",
|
|
domain.APIAuthMethodTypePrivateKeyJWT,
|
|
// oidc config
|
|
nil,
|
|
nil,
|
|
nil,
|
|
nil,
|
|
nil,
|
|
nil,
|
|
nil,
|
|
nil,
|
|
nil,
|
|
nil,
|
|
nil,
|
|
nil,
|
|
nil,
|
|
nil,
|
|
nil,
|
|
nil,
|
|
nil,
|
|
// saml config
|
|
nil,
|
|
nil,
|
|
nil,
|
|
nil,
|
|
},
|
|
{
|
|
"saml-app-id",
|
|
"app-name",
|
|
"project-id",
|
|
testNow,
|
|
testNow,
|
|
"ro",
|
|
domain.AppStateActive,
|
|
uint64(20211109),
|
|
// api config
|
|
nil,
|
|
nil,
|
|
nil,
|
|
// oidc config
|
|
nil,
|
|
nil,
|
|
nil,
|
|
nil,
|
|
nil,
|
|
nil,
|
|
nil,
|
|
nil,
|
|
nil,
|
|
nil,
|
|
nil,
|
|
nil,
|
|
nil,
|
|
nil,
|
|
nil,
|
|
nil,
|
|
nil,
|
|
// saml config
|
|
"saml-app-id",
|
|
"https://test.com/saml/metadata",
|
|
[]byte("<?xml version=\"1.0\"?>\n<md:EntityDescriptor xmlns:md=\"urn:oasis:names:tc:SAML:2.0:metadata\"\n validUntil=\"2022-08-26T14:08:16Z\"\n cacheDuration=\"PT604800S\"\n entityID=\"https://test.com/saml/metadata\">\n <md:SPSSODescriptor AuthnRequestsSigned=\"false\" WantAssertionsSigned=\"false\" protocolSupportEnumeration=\"urn:oasis:names:tc:SAML:2.0:protocol\">\n <md:NameIDFormat>urn:oasis:names:tc:SAML:1.1:nameid-format:unspecified</md:NameIDFormat>\n <md:AssertionConsumerService Binding=\"urn:oasis:names:tc:SAML:2.0:bindings:HTTP-POST\"\n Location=\"https://test.com/saml/acs\"\n index=\"1\" />\n \n </md:SPSSODescriptor>\n</md:EntityDescriptor>"),
|
|
"https://test.com/saml/metadata",
|
|
},
|
|
},
|
|
),
|
|
},
|
|
object: &Apps{
|
|
SearchResponse: SearchResponse{
|
|
Count: 3,
|
|
},
|
|
Apps: []*App{
|
|
{
|
|
ID: "oidc-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.TextArray[string]{"https://redirect.to/me"},
|
|
ResponseTypes: database.NumberArray[domain.OIDCResponseType]{domain.OIDCResponseTypeIDTokenToken},
|
|
GrantTypes: database.NumberArray[domain.OIDCGrantType]{domain.OIDCGrantTypeImplicit},
|
|
AppType: domain.OIDCApplicationTypeUserAgent,
|
|
AuthMethodType: domain.OIDCAuthMethodTypeNone,
|
|
PostLogoutRedirectURIs: database.TextArray[string]{"post.logout.ch"},
|
|
IsDevMode: true,
|
|
AccessTokenType: domain.OIDCTokenTypeJWT,
|
|
AssertAccessTokenRole: true,
|
|
AssertIDTokenRole: true,
|
|
AssertIDTokenUserinfo: true,
|
|
ClockSkew: 1 * time.Second,
|
|
AdditionalOrigins: database.TextArray[string]{"additional.origin"},
|
|
ComplianceProblems: nil,
|
|
AllowedOrigins: database.TextArray[string]{"https://redirect.to", "additional.origin"},
|
|
SkipNativeAppSuccessPage: false,
|
|
},
|
|
},
|
|
{
|
|
ID: "api-app-id",
|
|
CreationDate: testNow,
|
|
ChangeDate: testNow,
|
|
ResourceOwner: "ro",
|
|
State: domain.AppStateActive,
|
|
Sequence: 20211109,
|
|
Name: "app-name",
|
|
ProjectID: "project-id",
|
|
APIConfig: &APIApp{
|
|
ClientID: "api-client-id",
|
|
AuthMethodType: domain.APIAuthMethodTypePrivateKeyJWT,
|
|
},
|
|
},
|
|
{
|
|
ID: "saml-app-id",
|
|
CreationDate: testNow,
|
|
ChangeDate: testNow,
|
|
ResourceOwner: "ro",
|
|
State: domain.AppStateActive,
|
|
Sequence: 20211109,
|
|
Name: "app-name",
|
|
ProjectID: "project-id",
|
|
SAMLConfig: &SAMLApp{
|
|
Metadata: []byte("<?xml version=\"1.0\"?>\n<md:EntityDescriptor xmlns:md=\"urn:oasis:names:tc:SAML:2.0:metadata\"\n validUntil=\"2022-08-26T14:08:16Z\"\n cacheDuration=\"PT604800S\"\n entityID=\"https://test.com/saml/metadata\">\n <md:SPSSODescriptor AuthnRequestsSigned=\"false\" WantAssertionsSigned=\"false\" protocolSupportEnumeration=\"urn:oasis:names:tc:SAML:2.0:protocol\">\n <md:NameIDFormat>urn:oasis:names:tc:SAML:1.1:nameid-format:unspecified</md:NameIDFormat>\n <md:AssertionConsumerService Binding=\"urn:oasis:names:tc:SAML:2.0:bindings:HTTP-POST\"\n Location=\"https://test.com/saml/acs\"\n index=\"1\" />\n \n </md:SPSSODescriptor>\n</md:EntityDescriptor>"),
|
|
MetadataURL: "https://test.com/saml/metadata",
|
|
EntityID: "https://test.com/saml/metadata",
|
|
},
|
|
},
|
|
},
|
|
},
|
|
},
|
|
{
|
|
name: "prepareAppsQuery sql err",
|
|
prepare: prepareAppsQuery,
|
|
want: want{
|
|
sqlExpectations: mockQueryErr(
|
|
expectedAppsQuery,
|
|
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: (*App)(nil),
|
|
},
|
|
}
|
|
for _, tt := range tests {
|
|
t.Run(tt.name, func(t *testing.T) {
|
|
if tt.name == "prepareAppsQuery oidc app" {
|
|
_ = tt.name
|
|
}
|
|
assertPrepare(t, tt.prepare, tt.object, tt.want.sqlExpectations, tt.want.err, defaultPrepareArgs...)
|
|
})
|
|
}
|
|
}
|
|
|
|
func Test_AppPrepare(t *testing.T) {
|
|
type want struct {
|
|
sqlExpectations sqlExpectation
|
|
err checkErr
|
|
}
|
|
tests := []struct {
|
|
name string
|
|
prepare interface{}
|
|
want want
|
|
object interface{}
|
|
}{
|
|
{
|
|
name: "prepareAppQuery no result",
|
|
prepare: func(ctx context.Context, db prepareDatabase) (sq.SelectBuilder, func(*sql.Row) (*App, error)) {
|
|
return prepareAppQuery(ctx, db, false)
|
|
},
|
|
want: want{
|
|
sqlExpectations: mockQueriesScanErr(
|
|
expectedAppQuery,
|
|
nil,
|
|
nil,
|
|
),
|
|
err: func(err error) (error, bool) {
|
|
if !zerrors.IsNotFound(err) {
|
|
return fmt.Errorf("err should be zitadel.NotFoundError got: %w", err), false
|
|
}
|
|
return nil, true
|
|
},
|
|
},
|
|
object: (*App)(nil),
|
|
},
|
|
{
|
|
name: "prepareAppQuery found",
|
|
prepare: func(ctx context.Context, db prepareDatabase) (sq.SelectBuilder, func(*sql.Row) (*App, error)) {
|
|
return prepareAppQuery(ctx, db, false)
|
|
},
|
|
want: want{
|
|
sqlExpectations: mockQuery(
|
|
expectedAppQuery,
|
|
appCols,
|
|
[]driver.Value{
|
|
"app-id",
|
|
"app-name",
|
|
"project-id",
|
|
testNow,
|
|
testNow,
|
|
"ro",
|
|
domain.AppStateActive,
|
|
uint64(20211109),
|
|
// api config
|
|
nil,
|
|
nil,
|
|
nil,
|
|
// oidc config
|
|
nil,
|
|
nil,
|
|
nil,
|
|
nil,
|
|
nil,
|
|
nil,
|
|
nil,
|
|
nil,
|
|
nil,
|
|
nil,
|
|
nil,
|
|
nil,
|
|
nil,
|
|
nil,
|
|
nil,
|
|
nil,
|
|
nil,
|
|
// saml config
|
|
nil,
|
|
nil,
|
|
nil,
|
|
nil,
|
|
},
|
|
),
|
|
},
|
|
object: &App{
|
|
ID: "app-id",
|
|
CreationDate: testNow,
|
|
ChangeDate: testNow,
|
|
ResourceOwner: "ro",
|
|
State: domain.AppStateActive,
|
|
Sequence: 20211109,
|
|
Name: "app-name",
|
|
ProjectID: "project-id",
|
|
},
|
|
},
|
|
{
|
|
name: "prepareAppQuery api app",
|
|
prepare: func(ctx context.Context, db prepareDatabase) (sq.SelectBuilder, func(*sql.Row) (*App, error)) {
|
|
return prepareAppQuery(ctx, db, false)
|
|
},
|
|
want: want{
|
|
sqlExpectations: mockQueries(
|
|
expectedAppQuery,
|
|
appCols,
|
|
[][]driver.Value{
|
|
{
|
|
"app-id",
|
|
"app-name",
|
|
"project-id",
|
|
testNow,
|
|
testNow,
|
|
"ro",
|
|
domain.AppStateActive,
|
|
uint64(20211109),
|
|
// api config
|
|
"app-id",
|
|
"api-client-id",
|
|
domain.APIAuthMethodTypePrivateKeyJWT,
|
|
// oidc config
|
|
nil,
|
|
nil,
|
|
nil,
|
|
nil,
|
|
nil,
|
|
nil,
|
|
nil,
|
|
nil,
|
|
nil,
|
|
nil,
|
|
nil,
|
|
nil,
|
|
nil,
|
|
nil,
|
|
nil,
|
|
nil,
|
|
nil,
|
|
// saml config
|
|
nil,
|
|
nil,
|
|
nil,
|
|
nil,
|
|
},
|
|
},
|
|
),
|
|
},
|
|
object: &App{
|
|
ID: "app-id",
|
|
CreationDate: testNow,
|
|
ChangeDate: testNow,
|
|
ResourceOwner: "ro",
|
|
State: domain.AppStateActive,
|
|
Sequence: 20211109,
|
|
Name: "app-name",
|
|
ProjectID: "project-id",
|
|
APIConfig: &APIApp{
|
|
ClientID: "api-client-id",
|
|
AuthMethodType: domain.APIAuthMethodTypePrivateKeyJWT,
|
|
},
|
|
},
|
|
},
|
|
{
|
|
name: "prepareAppQuery oidc app",
|
|
prepare: func(ctx context.Context, db prepareDatabase) (sq.SelectBuilder, func(*sql.Row) (*App, error)) {
|
|
return prepareAppQuery(ctx, db, false)
|
|
},
|
|
want: want{
|
|
sqlExpectations: mockQueries(
|
|
expectedAppQuery,
|
|
appCols,
|
|
[][]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.TextArray[string]{"https://redirect.to/me"},
|
|
database.NumberArray[domain.OIDCResponseType]{domain.OIDCResponseTypeIDTokenToken},
|
|
database.NumberArray[domain.OIDCGrantType]{domain.OIDCGrantTypeImplicit},
|
|
domain.OIDCApplicationTypeUserAgent,
|
|
domain.OIDCAuthMethodTypeNone,
|
|
database.TextArray[string]{"post.logout.ch"},
|
|
true,
|
|
domain.OIDCTokenTypeJWT,
|
|
true,
|
|
true,
|
|
true,
|
|
1 * time.Second,
|
|
database.TextArray[string]{"additional.origin"},
|
|
false,
|
|
// saml config
|
|
nil,
|
|
nil,
|
|
nil,
|
|
nil,
|
|
},
|
|
},
|
|
),
|
|
},
|
|
object: &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.TextArray[string]{"https://redirect.to/me"},
|
|
ResponseTypes: database.NumberArray[domain.OIDCResponseType]{domain.OIDCResponseTypeIDTokenToken},
|
|
GrantTypes: database.NumberArray[domain.OIDCGrantType]{domain.OIDCGrantTypeImplicit},
|
|
AppType: domain.OIDCApplicationTypeUserAgent,
|
|
AuthMethodType: domain.OIDCAuthMethodTypeNone,
|
|
PostLogoutRedirectURIs: database.TextArray[string]{"post.logout.ch"},
|
|
IsDevMode: true,
|
|
AccessTokenType: domain.OIDCTokenTypeJWT,
|
|
AssertAccessTokenRole: true,
|
|
AssertIDTokenRole: true,
|
|
AssertIDTokenUserinfo: true,
|
|
ClockSkew: 1 * time.Second,
|
|
AdditionalOrigins: database.TextArray[string]{"additional.origin"},
|
|
ComplianceProblems: nil,
|
|
AllowedOrigins: database.TextArray[string]{"https://redirect.to", "additional.origin"},
|
|
SkipNativeAppSuccessPage: false,
|
|
},
|
|
},
|
|
},
|
|
{
|
|
name: "prepareAppQuery oidc app active only",
|
|
prepare: func(ctx context.Context, db prepareDatabase) (sq.SelectBuilder, func(*sql.Row) (*App, error)) {
|
|
return prepareAppQuery(ctx, db, true)
|
|
},
|
|
want: want{
|
|
sqlExpectations: mockQueries(
|
|
expectedActiveAppQuery,
|
|
appCols,
|
|
[][]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.TextArray[string]{"https://redirect.to/me"},
|
|
database.NumberArray[domain.OIDCResponseType]{domain.OIDCResponseTypeIDTokenToken},
|
|
database.NumberArray[domain.OIDCGrantType]{domain.OIDCGrantTypeImplicit},
|
|
domain.OIDCApplicationTypeUserAgent,
|
|
domain.OIDCAuthMethodTypeNone,
|
|
database.TextArray[string]{"post.logout.ch"},
|
|
true,
|
|
domain.OIDCTokenTypeJWT,
|
|
true,
|
|
true,
|
|
true,
|
|
1 * time.Second,
|
|
database.TextArray[string]{"additional.origin"},
|
|
false,
|
|
// saml config
|
|
nil,
|
|
nil,
|
|
nil,
|
|
nil,
|
|
},
|
|
},
|
|
),
|
|
},
|
|
object: &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.TextArray[string]{"https://redirect.to/me"},
|
|
ResponseTypes: database.NumberArray[domain.OIDCResponseType]{domain.OIDCResponseTypeIDTokenToken},
|
|
GrantTypes: database.NumberArray[domain.OIDCGrantType]{domain.OIDCGrantTypeImplicit},
|
|
AppType: domain.OIDCApplicationTypeUserAgent,
|
|
AuthMethodType: domain.OIDCAuthMethodTypeNone,
|
|
PostLogoutRedirectURIs: database.TextArray[string]{"post.logout.ch"},
|
|
IsDevMode: true,
|
|
AccessTokenType: domain.OIDCTokenTypeJWT,
|
|
AssertAccessTokenRole: true,
|
|
AssertIDTokenRole: true,
|
|
AssertIDTokenUserinfo: true,
|
|
ClockSkew: 1 * time.Second,
|
|
AdditionalOrigins: database.TextArray[string]{"additional.origin"},
|
|
ComplianceProblems: nil,
|
|
AllowedOrigins: database.TextArray[string]{"https://redirect.to", "additional.origin"},
|
|
SkipNativeAppSuccessPage: false,
|
|
},
|
|
},
|
|
},
|
|
{
|
|
name: "prepareAppQuery saml app",
|
|
prepare: func(ctx context.Context, db prepareDatabase) (sq.SelectBuilder, func(*sql.Row) (*App, error)) {
|
|
return prepareAppQuery(ctx, db, false)
|
|
},
|
|
want: want{
|
|
sqlExpectations: mockQueries(
|
|
expectedAppQuery,
|
|
appCols,
|
|
[][]driver.Value{
|
|
{
|
|
"app-id",
|
|
"app-name",
|
|
"project-id",
|
|
testNow,
|
|
testNow,
|
|
"ro",
|
|
domain.AppStateActive,
|
|
uint64(20211109),
|
|
// api config
|
|
nil,
|
|
nil,
|
|
nil,
|
|
// oidc config
|
|
nil,
|
|
nil,
|
|
nil,
|
|
nil,
|
|
nil,
|
|
nil,
|
|
nil,
|
|
nil,
|
|
nil,
|
|
nil,
|
|
nil,
|
|
nil,
|
|
nil,
|
|
nil,
|
|
nil,
|
|
nil,
|
|
nil,
|
|
// saml config
|
|
"app-id",
|
|
"https://test.com/saml/metadata",
|
|
[]byte("<?xml version=\"1.0\"?>\n<md:EntityDescriptor xmlns:md=\"urn:oasis:names:tc:SAML:2.0:metadata\"\n validUntil=\"2022-08-26T14:08:16Z\"\n cacheDuration=\"PT604800S\"\n entityID=\"https://test.com/saml/metadata\">\n <md:SPSSODescriptor AuthnRequestsSigned=\"false\" WantAssertionsSigned=\"false\" protocolSupportEnumeration=\"urn:oasis:names:tc:SAML:2.0:protocol\">\n <md:NameIDFormat>urn:oasis:names:tc:SAML:1.1:nameid-format:unspecified</md:NameIDFormat>\n <md:AssertionConsumerService Binding=\"urn:oasis:names:tc:SAML:2.0:bindings:HTTP-POST\"\n Location=\"https://test.com/saml/acs\"\n index=\"1\" />\n \n </md:SPSSODescriptor>\n</md:EntityDescriptor>"),
|
|
"https://test.com/saml/metadata",
|
|
},
|
|
},
|
|
),
|
|
},
|
|
object: &App{
|
|
ID: "app-id",
|
|
CreationDate: testNow,
|
|
ChangeDate: testNow,
|
|
ResourceOwner: "ro",
|
|
State: domain.AppStateActive,
|
|
Sequence: 20211109,
|
|
Name: "app-name",
|
|
ProjectID: "project-id",
|
|
SAMLConfig: &SAMLApp{
|
|
Metadata: []byte("<?xml version=\"1.0\"?>\n<md:EntityDescriptor xmlns:md=\"urn:oasis:names:tc:SAML:2.0:metadata\"\n validUntil=\"2022-08-26T14:08:16Z\"\n cacheDuration=\"PT604800S\"\n entityID=\"https://test.com/saml/metadata\">\n <md:SPSSODescriptor AuthnRequestsSigned=\"false\" WantAssertionsSigned=\"false\" protocolSupportEnumeration=\"urn:oasis:names:tc:SAML:2.0:protocol\">\n <md:NameIDFormat>urn:oasis:names:tc:SAML:1.1:nameid-format:unspecified</md:NameIDFormat>\n <md:AssertionConsumerService Binding=\"urn:oasis:names:tc:SAML:2.0:bindings:HTTP-POST\"\n Location=\"https://test.com/saml/acs\"\n index=\"1\" />\n \n </md:SPSSODescriptor>\n</md:EntityDescriptor>"),
|
|
MetadataURL: "https://test.com/saml/metadata",
|
|
EntityID: "https://test.com/saml/metadata",
|
|
},
|
|
},
|
|
},
|
|
{
|
|
name: "prepareAppQuery oidc app IsDevMode inactive",
|
|
prepare: func(ctx context.Context, db prepareDatabase) (sq.SelectBuilder, func(*sql.Row) (*App, error)) {
|
|
return prepareAppQuery(ctx, db, false)
|
|
},
|
|
want: want{
|
|
sqlExpectations: mockQueries(
|
|
expectedAppQuery,
|
|
appCols,
|
|
[][]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.TextArray[string]{"https://redirect.to/me"},
|
|
database.NumberArray[domain.OIDCResponseType]{domain.OIDCResponseTypeIDTokenToken},
|
|
database.NumberArray[domain.OIDCGrantType]{domain.OIDCGrantTypeImplicit},
|
|
domain.OIDCApplicationTypeUserAgent,
|
|
domain.OIDCAuthMethodTypeNone,
|
|
database.TextArray[string]{"post.logout.ch"},
|
|
false,
|
|
domain.OIDCTokenTypeJWT,
|
|
true,
|
|
true,
|
|
true,
|
|
1 * time.Second,
|
|
database.TextArray[string]{"additional.origin"},
|
|
false,
|
|
// saml config
|
|
nil,
|
|
nil,
|
|
nil,
|
|
nil,
|
|
},
|
|
},
|
|
),
|
|
},
|
|
object: &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.TextArray[string]{"https://redirect.to/me"},
|
|
ResponseTypes: database.NumberArray[domain.OIDCResponseType]{domain.OIDCResponseTypeIDTokenToken},
|
|
GrantTypes: database.NumberArray[domain.OIDCGrantType]{domain.OIDCGrantTypeImplicit},
|
|
AppType: domain.OIDCApplicationTypeUserAgent,
|
|
AuthMethodType: domain.OIDCAuthMethodTypeNone,
|
|
PostLogoutRedirectURIs: database.TextArray[string]{"post.logout.ch"},
|
|
IsDevMode: false,
|
|
AccessTokenType: domain.OIDCTokenTypeJWT,
|
|
AssertAccessTokenRole: true,
|
|
AssertIDTokenRole: true,
|
|
AssertIDTokenUserinfo: true,
|
|
ClockSkew: 1 * time.Second,
|
|
AdditionalOrigins: database.TextArray[string]{"additional.origin"},
|
|
ComplianceProblems: nil,
|
|
AllowedOrigins: database.TextArray[string]{"https://redirect.to", "additional.origin"},
|
|
SkipNativeAppSuccessPage: false,
|
|
},
|
|
},
|
|
},
|
|
{
|
|
name: "prepareAppQuery oidc app AssertAccessTokenRole inactive",
|
|
prepare: func(ctx context.Context, db prepareDatabase) (sq.SelectBuilder, func(*sql.Row) (*App, error)) {
|
|
return prepareAppQuery(ctx, db, false)
|
|
},
|
|
want: want{
|
|
sqlExpectations: mockQueries(
|
|
expectedAppQuery,
|
|
appCols,
|
|
[][]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.TextArray[string]{"https://redirect.to/me"},
|
|
database.NumberArray[domain.OIDCResponseType]{domain.OIDCResponseTypeIDTokenToken},
|
|
database.NumberArray[domain.OIDCGrantType]{domain.OIDCGrantTypeImplicit},
|
|
domain.OIDCApplicationTypeUserAgent,
|
|
domain.OIDCAuthMethodTypeNone,
|
|
database.TextArray[string]{"post.logout.ch"},
|
|
true,
|
|
domain.OIDCTokenTypeJWT,
|
|
false,
|
|
true,
|
|
true,
|
|
1 * time.Second,
|
|
database.TextArray[string]{"additional.origin"},
|
|
false,
|
|
// saml config
|
|
nil,
|
|
nil,
|
|
nil,
|
|
nil,
|
|
},
|
|
},
|
|
),
|
|
},
|
|
object: &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.TextArray[string]{"https://redirect.to/me"},
|
|
ResponseTypes: database.NumberArray[domain.OIDCResponseType]{domain.OIDCResponseTypeIDTokenToken},
|
|
GrantTypes: database.NumberArray[domain.OIDCGrantType]{domain.OIDCGrantTypeImplicit},
|
|
AppType: domain.OIDCApplicationTypeUserAgent,
|
|
AuthMethodType: domain.OIDCAuthMethodTypeNone,
|
|
PostLogoutRedirectURIs: database.TextArray[string]{"post.logout.ch"},
|
|
IsDevMode: true,
|
|
AccessTokenType: domain.OIDCTokenTypeJWT,
|
|
AssertAccessTokenRole: false,
|
|
AssertIDTokenRole: true,
|
|
AssertIDTokenUserinfo: true,
|
|
ClockSkew: 1 * time.Second,
|
|
AdditionalOrigins: database.TextArray[string]{"additional.origin"},
|
|
ComplianceProblems: nil,
|
|
AllowedOrigins: database.TextArray[string]{"https://redirect.to", "additional.origin"},
|
|
SkipNativeAppSuccessPage: false,
|
|
},
|
|
},
|
|
},
|
|
{
|
|
name: "prepareAppQuery oidc app AssertIDTokenRole inactive",
|
|
prepare: func(ctx context.Context, db prepareDatabase) (sq.SelectBuilder, func(*sql.Row) (*App, error)) {
|
|
return prepareAppQuery(ctx, db, false)
|
|
},
|
|
want: want{
|
|
sqlExpectations: mockQueries(
|
|
expectedAppQuery,
|
|
appCols,
|
|
[][]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.TextArray[string]{"https://redirect.to/me"},
|
|
database.NumberArray[domain.OIDCResponseType]{domain.OIDCResponseTypeIDTokenToken},
|
|
database.NumberArray[domain.OIDCGrantType]{domain.OIDCGrantTypeImplicit},
|
|
domain.OIDCApplicationTypeUserAgent,
|
|
domain.OIDCAuthMethodTypeNone,
|
|
database.TextArray[string]{"post.logout.ch"},
|
|
true,
|
|
domain.OIDCTokenTypeJWT,
|
|
true,
|
|
false,
|
|
true,
|
|
1 * time.Second,
|
|
database.TextArray[string]{"additional.origin"},
|
|
false,
|
|
// saml config
|
|
nil,
|
|
nil,
|
|
nil,
|
|
nil,
|
|
},
|
|
},
|
|
),
|
|
},
|
|
object: &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.TextArray[string]{"https://redirect.to/me"},
|
|
ResponseTypes: database.NumberArray[domain.OIDCResponseType]{domain.OIDCResponseTypeIDTokenToken},
|
|
GrantTypes: database.NumberArray[domain.OIDCGrantType]{domain.OIDCGrantTypeImplicit},
|
|
AppType: domain.OIDCApplicationTypeUserAgent,
|
|
AuthMethodType: domain.OIDCAuthMethodTypeNone,
|
|
PostLogoutRedirectURIs: database.TextArray[string]{"post.logout.ch"},
|
|
IsDevMode: true,
|
|
AccessTokenType: domain.OIDCTokenTypeJWT,
|
|
AssertAccessTokenRole: true,
|
|
AssertIDTokenRole: false,
|
|
AssertIDTokenUserinfo: true,
|
|
ClockSkew: 1 * time.Second,
|
|
AdditionalOrigins: database.TextArray[string]{"additional.origin"},
|
|
ComplianceProblems: nil,
|
|
AllowedOrigins: database.TextArray[string]{"https://redirect.to", "additional.origin"},
|
|
SkipNativeAppSuccessPage: false,
|
|
},
|
|
},
|
|
},
|
|
{
|
|
name: "prepareAppQuery oidc app AssertIDTokenUserinfo inactive",
|
|
prepare: func(ctx context.Context, db prepareDatabase) (sq.SelectBuilder, func(*sql.Row) (*App, error)) {
|
|
return prepareAppQuery(ctx, db, false)
|
|
},
|
|
want: want{
|
|
sqlExpectations: mockQueries(
|
|
expectedAppQuery,
|
|
appCols,
|
|
[][]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.TextArray[string]{"https://redirect.to/me"},
|
|
database.NumberArray[domain.OIDCResponseType]{domain.OIDCResponseTypeIDTokenToken},
|
|
database.NumberArray[domain.OIDCGrantType]{domain.OIDCGrantTypeImplicit},
|
|
domain.OIDCApplicationTypeUserAgent,
|
|
domain.OIDCAuthMethodTypeNone,
|
|
database.TextArray[string]{"post.logout.ch"},
|
|
true,
|
|
domain.OIDCTokenTypeJWT,
|
|
true,
|
|
true,
|
|
false,
|
|
1 * time.Second,
|
|
database.TextArray[string]{"additional.origin"},
|
|
false,
|
|
// saml config
|
|
nil,
|
|
nil,
|
|
nil,
|
|
nil,
|
|
},
|
|
},
|
|
),
|
|
},
|
|
object: &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.TextArray[string]{"https://redirect.to/me"},
|
|
ResponseTypes: database.NumberArray[domain.OIDCResponseType]{domain.OIDCResponseTypeIDTokenToken},
|
|
GrantTypes: database.NumberArray[domain.OIDCGrantType]{domain.OIDCGrantTypeImplicit},
|
|
AppType: domain.OIDCApplicationTypeUserAgent,
|
|
AuthMethodType: domain.OIDCAuthMethodTypeNone,
|
|
PostLogoutRedirectURIs: database.TextArray[string]{"post.logout.ch"},
|
|
IsDevMode: true,
|
|
AccessTokenType: domain.OIDCTokenTypeJWT,
|
|
AssertAccessTokenRole: true,
|
|
AssertIDTokenRole: true,
|
|
AssertIDTokenUserinfo: false,
|
|
ClockSkew: 1 * time.Second,
|
|
AdditionalOrigins: database.TextArray[string]{"additional.origin"},
|
|
ComplianceProblems: nil,
|
|
AllowedOrigins: database.TextArray[string]{"https://redirect.to", "additional.origin"},
|
|
SkipNativeAppSuccessPage: false,
|
|
},
|
|
},
|
|
},
|
|
{
|
|
name: "prepareAppQuery sql err",
|
|
prepare: func(ctx context.Context, db prepareDatabase) (sq.SelectBuilder, func(*sql.Row) (*App, error)) {
|
|
return prepareAppQuery(ctx, db, false)
|
|
},
|
|
want: want{
|
|
sqlExpectations: mockQueryErr(
|
|
expectedAppQuery,
|
|
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: (*App)(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, defaultPrepareArgs...)
|
|
})
|
|
}
|
|
}
|
|
|
|
func Test_AppIDsPrepare(t *testing.T) {
|
|
type want struct {
|
|
sqlExpectations sqlExpectation
|
|
err checkErr
|
|
}
|
|
tests := []struct {
|
|
name string
|
|
prepare interface{}
|
|
want want
|
|
object interface{}
|
|
}{
|
|
{
|
|
name: "prepareClientIDsQuery no result",
|
|
prepare: prepareClientIDsQuery,
|
|
want: want{
|
|
sqlExpectations: mockQueries(
|
|
expectedAppIDsQuery,
|
|
nil,
|
|
nil,
|
|
),
|
|
},
|
|
object: []string{},
|
|
},
|
|
{
|
|
name: "prepareClientIDsQuery one result",
|
|
prepare: prepareClientIDsQuery,
|
|
want: want{
|
|
sqlExpectations: mockQueries(
|
|
expectedAppIDsQuery,
|
|
database.TextArray[string]{"client_id", "client_id"},
|
|
[][]driver.Value{
|
|
{
|
|
"app-id",
|
|
nil,
|
|
},
|
|
},
|
|
),
|
|
},
|
|
object: []string{"app-id"},
|
|
},
|
|
{
|
|
name: "prepareClientIDsQuery multiple result",
|
|
prepare: prepareClientIDsQuery,
|
|
want: want{
|
|
sqlExpectations: mockQueries(
|
|
expectedAppIDsQuery,
|
|
database.TextArray[string]{"client_id", "client_id"},
|
|
[][]driver.Value{
|
|
{
|
|
nil,
|
|
"oidc-app-id",
|
|
},
|
|
{
|
|
"api-app-id",
|
|
nil,
|
|
},
|
|
},
|
|
),
|
|
},
|
|
object: []string{"oidc-app-id", "api-app-id"},
|
|
},
|
|
{
|
|
name: "prepareClientIDsQuery sql err",
|
|
prepare: prepareClientIDsQuery,
|
|
want: want{
|
|
sqlExpectations: mockQueryErr(
|
|
expectedAppIDsQuery,
|
|
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: (*App)(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, defaultPrepareArgs...)
|
|
})
|
|
}
|
|
}
|
|
|
|
func Test_ProjectIDByAppPrepare(t *testing.T) {
|
|
type want struct {
|
|
sqlExpectations sqlExpectation
|
|
err checkErr
|
|
}
|
|
tests := []struct {
|
|
name string
|
|
prepare interface{}
|
|
want want
|
|
object interface{}
|
|
}{
|
|
{
|
|
name: "prepareProjectIDByAppQuery no result",
|
|
prepare: prepareProjectIDByAppQuery,
|
|
want: want{
|
|
sqlExpectations: mockQueriesScanErr(
|
|
expectedProjectIDByAppQuery,
|
|
nil,
|
|
nil,
|
|
),
|
|
err: func(err error) (error, bool) {
|
|
if !zerrors.IsNotFound(err) {
|
|
return fmt.Errorf("err should be zitadel.NotFoundError got: %w", err), false
|
|
}
|
|
return nil, true
|
|
},
|
|
},
|
|
object: "",
|
|
},
|
|
{
|
|
name: "prepareProjectIDByAppQuery one result",
|
|
prepare: prepareProjectIDByAppQuery,
|
|
want: want{
|
|
sqlExpectations: mockQuery(
|
|
expectedProjectIDByAppQuery,
|
|
database.TextArray[string]{"project_id"},
|
|
[]driver.Value{"project-id"},
|
|
),
|
|
},
|
|
object: "project-id",
|
|
},
|
|
{
|
|
name: "prepareProjectIDByAppQuery sql err",
|
|
prepare: prepareProjectIDByAppQuery,
|
|
want: want{
|
|
sqlExpectations: mockQueryErr(
|
|
expectedProjectIDByAppQuery,
|
|
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: "",
|
|
},
|
|
}
|
|
for _, tt := range tests {
|
|
t.Run(tt.name, func(t *testing.T) {
|
|
assertPrepare(t, tt.prepare, tt.object, tt.want.sqlExpectations, tt.want.err, defaultPrepareArgs...)
|
|
})
|
|
}
|
|
}
|
|
|
|
func Test_ProjectByAppPrepare(t *testing.T) {
|
|
type want struct {
|
|
sqlExpectations sqlExpectation
|
|
err checkErr
|
|
}
|
|
tests := []struct {
|
|
name string
|
|
prepare interface{}
|
|
want want
|
|
object interface{}
|
|
}{
|
|
{
|
|
name: "prepareProjectByAppQuery no result",
|
|
prepare: prepareProjectByAppQuery,
|
|
want: want{
|
|
sqlExpectations: mockQueriesScanErr(
|
|
expectedProjectByAppQuery,
|
|
nil,
|
|
nil,
|
|
),
|
|
err: func(err error) (error, bool) {
|
|
if !zerrors.IsNotFound(err) {
|
|
return fmt.Errorf("err should be zitadel.NotFoundError got: %w", err), false
|
|
}
|
|
return nil, true
|
|
},
|
|
},
|
|
object: (*Project)(nil),
|
|
},
|
|
{
|
|
name: "prepareProjectByAppQuery found",
|
|
prepare: prepareProjectByAppQuery,
|
|
want: want{
|
|
sqlExpectations: mockQuery(
|
|
expectedProjectByAppQuery,
|
|
projectCols,
|
|
[]driver.Value{
|
|
"project-id",
|
|
testNow,
|
|
testNow,
|
|
"ro",
|
|
domain.ProjectStateInactive,
|
|
uint64(20211109),
|
|
"project-name",
|
|
true,
|
|
true,
|
|
true,
|
|
domain.PrivateLabelingSettingAllowLoginUserResourceOwnerPolicy,
|
|
},
|
|
),
|
|
},
|
|
object: &Project{
|
|
ID: "project-id",
|
|
CreationDate: testNow,
|
|
ChangeDate: testNow,
|
|
ResourceOwner: "ro",
|
|
Sequence: 20211109,
|
|
Name: "project-name",
|
|
State: domain.ProjectStateInactive,
|
|
ProjectRoleAssertion: true,
|
|
ProjectRoleCheck: true,
|
|
HasProjectCheck: true,
|
|
PrivateLabelingSetting: domain.PrivateLabelingSettingAllowLoginUserResourceOwnerPolicy,
|
|
},
|
|
},
|
|
{
|
|
name: "prepareProjectByAppQuery found",
|
|
prepare: prepareProjectByAppQuery,
|
|
want: want{
|
|
sqlExpectations: mockQuery(
|
|
expectedProjectByAppQuery,
|
|
projectCols,
|
|
[]driver.Value{
|
|
"project-id",
|
|
testNow,
|
|
testNow,
|
|
"ro",
|
|
domain.ProjectStateInactive,
|
|
uint64(20211109),
|
|
"project-name",
|
|
false,
|
|
true,
|
|
true,
|
|
domain.PrivateLabelingSettingAllowLoginUserResourceOwnerPolicy,
|
|
},
|
|
),
|
|
},
|
|
object: &Project{
|
|
ID: "project-id",
|
|
CreationDate: testNow,
|
|
ChangeDate: testNow,
|
|
ResourceOwner: "ro",
|
|
Sequence: 20211109,
|
|
Name: "project-name",
|
|
State: domain.ProjectStateInactive,
|
|
ProjectRoleAssertion: false,
|
|
ProjectRoleCheck: true,
|
|
HasProjectCheck: true,
|
|
PrivateLabelingSetting: domain.PrivateLabelingSettingAllowLoginUserResourceOwnerPolicy,
|
|
},
|
|
},
|
|
{
|
|
name: "prepareProjectByAppQuery found",
|
|
prepare: prepareProjectByAppQuery,
|
|
want: want{
|
|
sqlExpectations: mockQuery(
|
|
expectedProjectByAppQuery,
|
|
projectCols,
|
|
[]driver.Value{
|
|
"project-id",
|
|
testNow,
|
|
testNow,
|
|
"ro",
|
|
domain.ProjectStateInactive,
|
|
uint64(20211109),
|
|
"project-name",
|
|
true,
|
|
false,
|
|
true,
|
|
domain.PrivateLabelingSettingAllowLoginUserResourceOwnerPolicy,
|
|
},
|
|
),
|
|
},
|
|
object: &Project{
|
|
ID: "project-id",
|
|
CreationDate: testNow,
|
|
ChangeDate: testNow,
|
|
ResourceOwner: "ro",
|
|
Sequence: 20211109,
|
|
Name: "project-name",
|
|
State: domain.ProjectStateInactive,
|
|
ProjectRoleAssertion: true,
|
|
ProjectRoleCheck: false,
|
|
HasProjectCheck: true,
|
|
PrivateLabelingSetting: domain.PrivateLabelingSettingAllowLoginUserResourceOwnerPolicy,
|
|
},
|
|
},
|
|
{
|
|
name: "prepareProjectByAppQuery found",
|
|
prepare: prepareProjectByAppQuery,
|
|
want: want{
|
|
sqlExpectations: mockQuery(
|
|
expectedProjectByAppQuery,
|
|
projectCols,
|
|
[]driver.Value{
|
|
"project-id",
|
|
testNow,
|
|
testNow,
|
|
"ro",
|
|
domain.ProjectStateInactive,
|
|
uint64(20211109),
|
|
"project-name",
|
|
true,
|
|
true,
|
|
false,
|
|
domain.PrivateLabelingSettingAllowLoginUserResourceOwnerPolicy,
|
|
},
|
|
),
|
|
},
|
|
object: &Project{
|
|
ID: "project-id",
|
|
CreationDate: testNow,
|
|
ChangeDate: testNow,
|
|
ResourceOwner: "ro",
|
|
Sequence: 20211109,
|
|
Name: "project-name",
|
|
State: domain.ProjectStateInactive,
|
|
ProjectRoleAssertion: true,
|
|
ProjectRoleCheck: true,
|
|
HasProjectCheck: false,
|
|
PrivateLabelingSetting: domain.PrivateLabelingSettingAllowLoginUserResourceOwnerPolicy,
|
|
},
|
|
},
|
|
{
|
|
name: "prepareProjectByAppQuery sql err",
|
|
prepare: prepareProjectByAppQuery,
|
|
want: want{
|
|
sqlExpectations: mockQueryErr(
|
|
expectedProjectByAppQuery,
|
|
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: (*Project)(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, defaultPrepareArgs...)
|
|
})
|
|
}
|
|
}
|