2021-11-16 08:03:12 +00:00
package query
import (
"database/sql"
"database/sql/driver"
"errors"
"fmt"
"regexp"
"testing"
2022-04-26 23:01:45 +00:00
"github.com/zitadel/zitadel/internal/crypto"
2022-08-31 07:52:43 +00:00
"github.com/zitadel/zitadel/internal/database"
2022-04-26 23:01:45 +00:00
"github.com/zitadel/zitadel/internal/domain"
errs "github.com/zitadel/zitadel/internal/errors"
2021-11-16 08:03:12 +00:00
)
2022-10-27 06:08:36 +00:00
var (
2022-11-30 16:01:17 +00:00
idpQuery = ` SELECT projections.idps3.id, ` +
` projections.idps3.resource_owner, ` +
` projections.idps3.creation_date, ` +
` projections.idps3.change_date, ` +
` projections.idps3.sequence, ` +
` projections.idps3.state, ` +
` projections.idps3.name, ` +
` projections.idps3.styling_type, ` +
` projections.idps3.owner_type, ` +
` projections.idps3.auto_register, ` +
` projections.idps3_oidc_config.idp_id, ` +
` projections.idps3_oidc_config.client_id, ` +
` projections.idps3_oidc_config.client_secret, ` +
` projections.idps3_oidc_config.issuer, ` +
` projections.idps3_oidc_config.scopes, ` +
` projections.idps3_oidc_config.display_name_mapping, ` +
` projections.idps3_oidc_config.username_mapping, ` +
` projections.idps3_oidc_config.authorization_endpoint, ` +
` projections.idps3_oidc_config.token_endpoint, ` +
` projections.idps3_jwt_config.idp_id, ` +
` projections.idps3_jwt_config.issuer, ` +
` projections.idps3_jwt_config.keys_endpoint, ` +
` projections.idps3_jwt_config.header_name, ` +
` projections.idps3_jwt_config.endpoint ` +
` FROM projections.idps3 ` +
` LEFT JOIN projections.idps3_oidc_config ON projections.idps3.id = projections.idps3_oidc_config.idp_id AND projections.idps3.instance_id = projections.idps3_oidc_config.instance_id ` +
` LEFT JOIN projections.idps3_jwt_config ON projections.idps3.id = projections.idps3_jwt_config.idp_id AND projections.idps3.instance_id = projections.idps3_jwt_config.instance_id `
2022-10-27 06:08:36 +00:00
idpCols = [ ] string {
"id" ,
"resource_owner" ,
"creation_date" ,
"change_date" ,
"sequence" ,
"state" ,
"name" ,
"styling_type" ,
"owner_type" ,
"auto_register" ,
// oidc config
"idp_id" ,
"client_id" ,
"client_secret" ,
"issuer" ,
"scopes" ,
"display_name_mapping" ,
"username_mapping" ,
"authorization_endpoint" ,
"token_endpoint" ,
// jwt config
"idp_id" ,
"issuer" ,
"keys_endpoint" ,
"header_name" ,
"endpoint" ,
}
2022-11-30 16:01:17 +00:00
idpsQuery = ` SELECT projections.idps3.id, ` +
` projections.idps3.resource_owner, ` +
` projections.idps3.creation_date, ` +
` projections.idps3.change_date, ` +
` projections.idps3.sequence, ` +
` projections.idps3.state, ` +
` projections.idps3.name, ` +
` projections.idps3.styling_type, ` +
` projections.idps3.owner_type, ` +
` projections.idps3.auto_register, ` +
` projections.idps3_oidc_config.idp_id, ` +
` projections.idps3_oidc_config.client_id, ` +
` projections.idps3_oidc_config.client_secret, ` +
` projections.idps3_oidc_config.issuer, ` +
` projections.idps3_oidc_config.scopes, ` +
` projections.idps3_oidc_config.display_name_mapping, ` +
` projections.idps3_oidc_config.username_mapping, ` +
` projections.idps3_oidc_config.authorization_endpoint, ` +
` projections.idps3_oidc_config.token_endpoint, ` +
` projections.idps3_jwt_config.idp_id, ` +
` projections.idps3_jwt_config.issuer, ` +
` projections.idps3_jwt_config.keys_endpoint, ` +
` projections.idps3_jwt_config.header_name, ` +
` projections.idps3_jwt_config.endpoint, ` +
2022-10-27 06:08:36 +00:00
` COUNT(*) OVER () ` +
2022-11-30 16:01:17 +00:00
` FROM projections.idps3 ` +
` LEFT JOIN projections.idps3_oidc_config ON projections.idps3.id = projections.idps3_oidc_config.idp_id AND projections.idps3.instance_id = projections.idps3_oidc_config.instance_id ` +
` LEFT JOIN projections.idps3_jwt_config ON projections.idps3.id = projections.idps3_jwt_config.idp_id AND projections.idps3.instance_id = projections.idps3_jwt_config.instance_id `
2022-10-27 06:08:36 +00:00
idpsCols = [ ] string {
"id" ,
"resource_owner" ,
"creation_date" ,
"change_date" ,
"sequence" ,
"state" ,
"name" ,
"styling_type" ,
"owner_type" ,
"auto_register" ,
// oidc config
"idp_id" ,
"client_id" ,
"client_secret" ,
"issuer" ,
"scopes" ,
"display_name_mapping" ,
"username_mapping" ,
"authorization_endpoint" ,
"token_endpoint" ,
// jwt config
"idp_id" ,
"issuer" ,
"keys_endpoint" ,
"header_name" ,
"endpoint" ,
"count" ,
}
)
2021-11-16 08:03:12 +00:00
func Test_IDPPrepares ( t * testing . T ) {
type want struct {
sqlExpectations sqlExpectation
err checkErr
}
tests := [ ] struct {
name string
prepare interface { }
want want
object interface { }
} {
{
name : "prepareIDPByIDQuery no result" ,
prepare : prepareIDPByIDQuery ,
want : want {
sqlExpectations : mockQuery (
2022-10-27 06:08:36 +00:00
regexp . QuoteMeta ( idpQuery ) ,
2021-11-16 08:03:12 +00:00
nil ,
nil ,
) ,
err : func ( err error ) ( error , bool ) {
if ! errs . IsNotFound ( err ) {
return fmt . Errorf ( "err should be zitadel.NotFoundError got: %w" , err ) , false
}
return nil , true
} ,
} ,
object : ( * IDP ) ( nil ) ,
} ,
{
name : "prepareIDPByIDQuery oidc idp" ,
prepare : prepareIDPByIDQuery ,
want : want {
sqlExpectations : mockQuery (
2022-10-27 06:08:36 +00:00
regexp . QuoteMeta ( idpQuery ) ,
idpCols ,
2021-11-16 08:03:12 +00:00
[ ] driver . Value {
"idp-id" ,
"ro" ,
testNow ,
testNow ,
uint64 ( 20211109 ) ,
domain . IDPConfigStateActive ,
"idp-name" ,
domain . IDPConfigStylingTypeGoogle ,
domain . IdentityProviderTypeOrg ,
true ,
// oidc config
"idp-id" ,
"oidc-client-id" ,
nil ,
"oidc-issuer" ,
2022-08-31 07:52:43 +00:00
database . StringArray { "scope" } ,
2021-11-16 08:03:12 +00:00
domain . OIDCMappingFieldEmail ,
domain . OIDCMappingFieldPreferredLoginName ,
"auth.endpoint.ch" ,
"token.endpoint.ch" ,
// jwt config
nil ,
nil ,
nil ,
nil ,
nil ,
} ,
) ,
} ,
object : & IDP {
CreationDate : testNow ,
ChangeDate : testNow ,
Sequence : 20211109 ,
ResourceOwner : "ro" ,
ID : "idp-id" ,
State : domain . IDPConfigStateActive ,
Name : "idp-name" ,
StylingType : domain . IDPConfigStylingTypeGoogle ,
OwnerType : domain . IdentityProviderTypeOrg ,
AutoRegister : true ,
OIDCIDP : & OIDCIDP {
IDPID : "idp-id" ,
ClientID : "oidc-client-id" ,
ClientSecret : & crypto . CryptoValue { } ,
Issuer : "oidc-issuer" ,
2022-08-31 07:52:43 +00:00
Scopes : database . StringArray { "scope" } ,
2021-11-16 08:03:12 +00:00
DisplayNameMapping : domain . OIDCMappingFieldEmail ,
UsernameMapping : domain . OIDCMappingFieldPreferredLoginName ,
AuthorizationEndpoint : "auth.endpoint.ch" ,
TokenEndpoint : "token.endpoint.ch" ,
} ,
} ,
} ,
{
name : "prepareIDPByIDQuery jwt config" ,
prepare : prepareIDPByIDQuery ,
want : want {
sqlExpectations : mockQuery (
2022-10-27 06:08:36 +00:00
regexp . QuoteMeta ( idpQuery ) ,
idpCols ,
2021-11-16 08:03:12 +00:00
[ ] driver . Value {
"idp-id" ,
"ro" ,
testNow ,
testNow ,
uint64 ( 20211109 ) ,
domain . IDPConfigStateActive ,
"idp-name" ,
domain . IDPConfigStylingTypeGoogle ,
domain . IdentityProviderTypeOrg ,
true ,
// oidc config
nil ,
nil ,
nil ,
nil ,
nil ,
nil ,
nil ,
nil ,
nil ,
// jwt config
"idp-id" ,
"jwt-issuer" ,
"key.ch" ,
"x-header-name" ,
"jwt.endpoint.ch" ,
} ,
) ,
} ,
object : & IDP {
CreationDate : testNow ,
ChangeDate : testNow ,
Sequence : 20211109 ,
ResourceOwner : "ro" ,
ID : "idp-id" ,
State : domain . IDPConfigStateActive ,
Name : "idp-name" ,
StylingType : domain . IDPConfigStylingTypeGoogle ,
OwnerType : domain . IdentityProviderTypeOrg ,
AutoRegister : true ,
JWTIDP : & JWTIDP {
IDPID : "idp-id" ,
Issuer : "jwt-issuer" ,
KeysEndpoint : "key.ch" ,
HeaderName : "x-header-name" ,
Endpoint : "jwt.endpoint.ch" ,
} ,
} ,
} ,
{
name : "prepareIDPByIDQuery no config" ,
prepare : prepareIDPByIDQuery ,
want : want {
sqlExpectations : mockQuery (
2022-10-27 06:08:36 +00:00
regexp . QuoteMeta ( idpQuery ) ,
idpCols ,
2021-11-16 08:03:12 +00:00
[ ] driver . Value {
"idp-id" ,
"ro" ,
testNow ,
testNow ,
uint64 ( 20211109 ) ,
domain . IDPConfigStateActive ,
"idp-name" ,
domain . IDPConfigStylingTypeGoogle ,
domain . IdentityProviderTypeOrg ,
true ,
// oidc config
nil ,
nil ,
nil ,
nil ,
nil ,
nil ,
nil ,
nil ,
nil ,
// jwt config
nil ,
nil ,
nil ,
nil ,
nil ,
} ,
) ,
} ,
object : & IDP {
CreationDate : testNow ,
ChangeDate : testNow ,
Sequence : 20211109 ,
ResourceOwner : "ro" ,
ID : "idp-id" ,
State : domain . IDPConfigStateActive ,
Name : "idp-name" ,
StylingType : domain . IDPConfigStylingTypeGoogle ,
OwnerType : domain . IdentityProviderTypeOrg ,
AutoRegister : true ,
} ,
} ,
{
name : "prepareIDPByIDQuery sql err" ,
prepare : prepareIDPByIDQuery ,
want : want {
sqlExpectations : mockQueryErr (
2022-10-27 06:08:36 +00:00
regexp . QuoteMeta ( idpQuery ) ,
2021-11-16 08:03:12 +00:00
sql . ErrConnDone ,
) ,
err : func ( err error ) ( error , bool ) {
if ! errors . Is ( err , sql . ErrConnDone ) {
return fmt . Errorf ( "err should be sql.ErrConnDone got: %w" , err ) , false
}
return nil , true
} ,
} ,
object : nil ,
} ,
{
name : "prepareIDPsQuery no result" ,
prepare : prepareIDPsQuery ,
want : want {
sqlExpectations : mockQueries (
2022-10-27 06:08:36 +00:00
regexp . QuoteMeta ( idpsQuery ) ,
2021-11-16 08:03:12 +00:00
nil ,
nil ,
) ,
err : func ( err error ) ( error , bool ) {
if ! errs . IsNotFound ( err ) {
return fmt . Errorf ( "err should be zitadel.NotFoundError got: %w" , err ) , false
}
return nil , true
} ,
} ,
object : & IDPs { IDPs : [ ] * IDP { } } ,
} ,
{
name : "prepareIDPsQuery oidc idp" ,
prepare : prepareIDPsQuery ,
want : want {
sqlExpectations : mockQueries (
2022-10-27 06:08:36 +00:00
regexp . QuoteMeta ( idpsQuery ) ,
idpsCols ,
2021-11-16 08:03:12 +00:00
[ ] [ ] driver . Value {
{
"idp-id" ,
"ro" ,
testNow ,
testNow ,
uint64 ( 20211109 ) ,
domain . IDPConfigStateActive ,
"idp-name" ,
domain . IDPConfigStylingTypeGoogle ,
domain . IdentityProviderTypeOrg ,
true ,
// oidc config
"idp-id" ,
"oidc-client-id" ,
nil ,
"oidc-issuer" ,
2022-08-31 07:52:43 +00:00
database . StringArray { "scope" } ,
2021-11-16 08:03:12 +00:00
domain . OIDCMappingFieldEmail ,
domain . OIDCMappingFieldPreferredLoginName ,
"auth.endpoint.ch" ,
"token.endpoint.ch" ,
// jwt config
nil ,
nil ,
nil ,
nil ,
nil ,
} ,
} ,
) ,
} ,
object : & IDPs {
SearchResponse : SearchResponse {
Count : 1 ,
} ,
IDPs : [ ] * IDP {
{
CreationDate : testNow ,
ChangeDate : testNow ,
Sequence : 20211109 ,
ResourceOwner : "ro" ,
ID : "idp-id" ,
State : domain . IDPConfigStateActive ,
Name : "idp-name" ,
StylingType : domain . IDPConfigStylingTypeGoogle ,
OwnerType : domain . IdentityProviderTypeOrg ,
AutoRegister : true ,
OIDCIDP : & OIDCIDP {
IDPID : "idp-id" ,
ClientID : "oidc-client-id" ,
ClientSecret : & crypto . CryptoValue { } ,
Issuer : "oidc-issuer" ,
2022-08-31 07:52:43 +00:00
Scopes : database . StringArray { "scope" } ,
2021-11-16 08:03:12 +00:00
DisplayNameMapping : domain . OIDCMappingFieldEmail ,
UsernameMapping : domain . OIDCMappingFieldPreferredLoginName ,
AuthorizationEndpoint : "auth.endpoint.ch" ,
TokenEndpoint : "token.endpoint.ch" ,
} ,
} ,
} ,
} ,
} ,
{
name : "prepareIDPsQuery jwt config" ,
prepare : prepareIDPsQuery ,
want : want {
sqlExpectations : mockQueries (
2022-10-27 06:08:36 +00:00
regexp . QuoteMeta ( idpsQuery ) ,
idpsCols ,
2021-11-16 08:03:12 +00:00
[ ] [ ] driver . Value {
{
"idp-id" ,
"ro" ,
testNow ,
testNow ,
uint64 ( 20211109 ) ,
domain . IDPConfigStateActive ,
"idp-name" ,
domain . IDPConfigStylingTypeGoogle ,
domain . IdentityProviderTypeOrg ,
true ,
// oidc config
nil ,
nil ,
nil ,
nil ,
nil ,
nil ,
nil ,
nil ,
nil ,
// jwt config
"idp-id" ,
"jwt-issuer" ,
"key.ch" ,
"x-header-name" ,
"jwt.endpoint.ch" ,
} ,
} ,
) ,
} ,
object : & IDPs {
SearchResponse : SearchResponse {
Count : 1 ,
} ,
IDPs : [ ] * IDP {
{
CreationDate : testNow ,
ChangeDate : testNow ,
Sequence : 20211109 ,
ResourceOwner : "ro" ,
ID : "idp-id" ,
State : domain . IDPConfigStateActive ,
Name : "idp-name" ,
StylingType : domain . IDPConfigStylingTypeGoogle ,
OwnerType : domain . IdentityProviderTypeOrg ,
AutoRegister : true ,
JWTIDP : & JWTIDP {
IDPID : "idp-id" ,
Issuer : "jwt-issuer" ,
KeysEndpoint : "key.ch" ,
HeaderName : "x-header-name" ,
Endpoint : "jwt.endpoint.ch" ,
} ,
} ,
} ,
} ,
} ,
{
name : "prepareIDPsQuery no config" ,
prepare : prepareIDPsQuery ,
want : want {
sqlExpectations : mockQueries (
2022-10-27 06:08:36 +00:00
regexp . QuoteMeta ( idpsQuery ) ,
idpsCols ,
2021-11-16 08:03:12 +00:00
[ ] [ ] driver . Value {
{
"idp-id" ,
"ro" ,
testNow ,
testNow ,
uint64 ( 20211109 ) ,
domain . IDPConfigStateActive ,
"idp-name" ,
domain . IDPConfigStylingTypeGoogle ,
domain . IdentityProviderTypeOrg ,
true ,
// oidc config
nil ,
nil ,
nil ,
nil ,
nil ,
nil ,
nil ,
nil ,
nil ,
// jwt config
nil ,
nil ,
nil ,
nil ,
nil ,
} ,
} ,
) ,
} ,
object : & IDPs {
SearchResponse : SearchResponse {
Count : 1 ,
} ,
IDPs : [ ] * IDP {
{
CreationDate : testNow ,
ChangeDate : testNow ,
Sequence : 20211109 ,
ResourceOwner : "ro" ,
ID : "idp-id" ,
State : domain . IDPConfigStateActive ,
Name : "idp-name" ,
StylingType : domain . IDPConfigStylingTypeGoogle ,
OwnerType : domain . IdentityProviderTypeOrg ,
AutoRegister : true ,
} ,
} ,
} ,
} ,
{
name : "prepareIDPsQuery all config types" ,
prepare : prepareIDPsQuery ,
want : want {
sqlExpectations : mockQueries (
2022-10-27 06:08:36 +00:00
regexp . QuoteMeta ( idpsQuery ) ,
idpsCols ,
2021-11-16 08:03:12 +00:00
[ ] [ ] driver . Value {
{
"idp-id-1" ,
"ro" ,
testNow ,
testNow ,
uint64 ( 20211109 ) ,
domain . IDPConfigStateActive ,
"idp-name" ,
domain . IDPConfigStylingTypeGoogle ,
domain . IdentityProviderTypeOrg ,
true ,
// oidc config
nil ,
nil ,
nil ,
nil ,
nil ,
nil ,
nil ,
nil ,
nil ,
// jwt config
nil ,
nil ,
nil ,
nil ,
nil ,
} ,
{
"idp-id-2" ,
"ro" ,
testNow ,
testNow ,
uint64 ( 20211109 ) ,
domain . IDPConfigStateActive ,
"idp-name" ,
domain . IDPConfigStylingTypeGoogle ,
domain . IdentityProviderTypeOrg ,
true ,
// oidc config
"idp-id" ,
"oidc-client-id" ,
nil ,
"oidc-issuer" ,
2022-08-31 07:52:43 +00:00
database . StringArray { "scope" } ,
2021-11-16 08:03:12 +00:00
domain . OIDCMappingFieldEmail ,
domain . OIDCMappingFieldPreferredLoginName ,
"auth.endpoint.ch" ,
"token.endpoint.ch" ,
// jwt config
nil ,
nil ,
nil ,
nil ,
nil ,
} ,
{
"idp-id-3" ,
"ro" ,
testNow ,
testNow ,
uint64 ( 20211109 ) ,
domain . IDPConfigStateActive ,
"idp-name" ,
domain . IDPConfigStylingTypeGoogle ,
domain . IdentityProviderTypeOrg ,
true ,
// oidc config
nil ,
nil ,
nil ,
nil ,
nil ,
nil ,
nil ,
nil ,
nil ,
// jwt config
"idp-id" ,
"jwt-issuer" ,
"key.ch" ,
"x-header-name" ,
"jwt.endpoint.ch" ,
} ,
} ,
) ,
} ,
object : & IDPs {
SearchResponse : SearchResponse {
Count : 3 ,
} ,
IDPs : [ ] * IDP {
{
CreationDate : testNow ,
ChangeDate : testNow ,
Sequence : 20211109 ,
ResourceOwner : "ro" ,
ID : "idp-id-1" ,
State : domain . IDPConfigStateActive ,
Name : "idp-name" ,
StylingType : domain . IDPConfigStylingTypeGoogle ,
OwnerType : domain . IdentityProviderTypeOrg ,
AutoRegister : true ,
} ,
{
CreationDate : testNow ,
ChangeDate : testNow ,
Sequence : 20211109 ,
ResourceOwner : "ro" ,
ID : "idp-id-2" ,
State : domain . IDPConfigStateActive ,
Name : "idp-name" ,
StylingType : domain . IDPConfigStylingTypeGoogle ,
OwnerType : domain . IdentityProviderTypeOrg ,
AutoRegister : true ,
OIDCIDP : & OIDCIDP {
IDPID : "idp-id" ,
ClientID : "oidc-client-id" ,
ClientSecret : & crypto . CryptoValue { } ,
Issuer : "oidc-issuer" ,
2022-08-31 07:52:43 +00:00
Scopes : database . StringArray { "scope" } ,
2021-11-16 08:03:12 +00:00
DisplayNameMapping : domain . OIDCMappingFieldEmail ,
UsernameMapping : domain . OIDCMappingFieldPreferredLoginName ,
AuthorizationEndpoint : "auth.endpoint.ch" ,
TokenEndpoint : "token.endpoint.ch" ,
} ,
} ,
{
CreationDate : testNow ,
ChangeDate : testNow ,
Sequence : 20211109 ,
ResourceOwner : "ro" ,
ID : "idp-id-3" ,
State : domain . IDPConfigStateActive ,
Name : "idp-name" ,
StylingType : domain . IDPConfigStylingTypeGoogle ,
OwnerType : domain . IdentityProviderTypeOrg ,
AutoRegister : true ,
JWTIDP : & JWTIDP {
IDPID : "idp-id" ,
Issuer : "jwt-issuer" ,
KeysEndpoint : "key.ch" ,
HeaderName : "x-header-name" ,
Endpoint : "jwt.endpoint.ch" ,
} ,
} ,
} ,
} ,
} ,
{
name : "prepareIDPsQuery sql err" ,
prepare : prepareIDPsQuery ,
want : want {
sqlExpectations : mockQueryErr (
2022-10-27 06:08:36 +00:00
regexp . QuoteMeta ( idpsQuery ) ,
2021-11-16 08:03:12 +00:00
sql . ErrConnDone ,
) ,
err : func ( err error ) ( error , bool ) {
if ! errors . Is ( err , sql . ErrConnDone ) {
return fmt . Errorf ( "err should be sql.ErrConnDone got: %w" , err ) , false
}
return nil , true
} ,
} ,
object : nil ,
} ,
}
for _ , tt := range tests {
t . Run ( tt . name , func ( t * testing . T ) {
assertPrepare ( t , tt . prepare , tt . object , tt . want . sqlExpectations , tt . want . err )
} )
}
}