mirror of
https://github.com/zitadel/zitadel.git
synced 2025-01-13 03:43:39 +00:00
fix(queries): idp projection (#2411)
* job queue * wg improvements * start handler * statement * statements * imporve handler * improve statement * statement in seperate file * move handlers * move query/old to query * handler * read models * bulk works * cleanup * contrib * rename readmodel to projection * rename read_models schema to projections * rename read_models schema to projections * search query as func, bulk iterates as long as new events * add event sequence less query * update checks for events between current sequence and sequence of first statement if it has previous sequence 0 * cleanup crdb projection * refactor projection handler * start with testing * tests for handler * remove todo * refactor statement: remove table name, add tests * improve projection handler shutdown, no savepoint if noop stmt, tests for stmt handler * tests * start failed events * seperate branch for contrib * move statement constructors to crdb pkg * correct import * Subscribe for eventtypes (#1800) * fix: is default (#1737) * fix: use email as username on global org (#1738) * fix: use email as username on global org * Update user_human.go * Update register_handler.go * chore(deps): update docusaurus (#1739) * chore: remove PAT and use GH Token (#1716) * chore: remove PAT and use GH Token * fix env * fix env * fix env * md lint * trigger ci * change user * fix GH bug * replace login part * chore: add GH Token to sem rel (#1746) * chore: add GH Token to sem rel * try branch * add GH Token * remove test branch again * docs: changes acme to acme-caos (#1744) * changes acme to acme-caos * Apply suggestions from code review Co-authored-by: Florian Forster <florian@caos.ch> Co-authored-by: Maximilian Panne <maximilian.panne@gmail.com> Co-authored-by: Florian Forster <florian@caos.ch> * feat: add additional origins on applications (#1691) * feat: add additional origins on applications * app additional redirects * chore(deps-dev): bump @angular/cli from 11.2.8 to 11.2.11 in /console (#1706) * fix: show org with regex (#1688) * fix: flag mapping (#1699) * chore(deps-dev): bump @angular/cli from 11.2.8 to 11.2.11 in /console Bumps [@angular/cli](https://github.com/angular/angular-cli) from 11.2.8 to 11.2.11. - [Release notes](https://github.com/angular/angular-cli/releases) - [Commits](https://github.com/angular/angular-cli/compare/v11.2.8...v11.2.11) Signed-off-by: dependabot[bot] <support@github.com> Co-authored-by: Max Peintner <max@caos.ch> Co-authored-by: Silvan <silvan.reusser@gmail.com> Co-authored-by: dependabot[bot] <49699333+dependabot[bot]@users.noreply.github.com> * chore(deps-dev): bump stylelint from 13.10.0 to 13.13.1 in /console (#1703) * fix: show org with regex (#1688) * fix: flag mapping (#1699) * chore(deps-dev): bump stylelint from 13.10.0 to 13.13.1 in /console Bumps [stylelint](https://github.com/stylelint/stylelint) from 13.10.0 to 13.13.1. - [Release notes](https://github.com/stylelint/stylelint/releases) - [Changelog](https://github.com/stylelint/stylelint/blob/master/CHANGELOG.md) - [Commits](https://github.com/stylelint/stylelint/compare/13.10.0...13.13.1) Signed-off-by: dependabot[bot] <support@github.com> Co-authored-by: Max Peintner <max@caos.ch> Co-authored-by: Silvan <silvan.reusser@gmail.com> Co-authored-by: dependabot[bot] <49699333+dependabot[bot]@users.noreply.github.com> * chore(deps-dev): bump @types/node from 14.14.37 to 15.0.1 in /console (#1702) * fix: show org with regex (#1688) * fix: flag mapping (#1699) * chore(deps-dev): bump @types/node from 14.14.37 to 15.0.1 in /console Bumps [@types/node](https://github.com/DefinitelyTyped/DefinitelyTyped/tree/HEAD/types/node) from 14.14.37 to 15.0.1. - [Release notes](https://github.com/DefinitelyTyped/DefinitelyTyped/releases) - [Commits](https://github.com/DefinitelyTyped/DefinitelyTyped/commits/HEAD/types/node) Signed-off-by: dependabot[bot] <support@github.com> Co-authored-by: Max Peintner <max@caos.ch> Co-authored-by: Silvan <silvan.reusser@gmail.com> Co-authored-by: dependabot[bot] <49699333+dependabot[bot]@users.noreply.github.com> * chore(deps): bump ts-protoc-gen from 0.14.0 to 0.15.0 in /console (#1701) * fix: show org with regex (#1688) * fix: flag mapping (#1699) * chore(deps): bump ts-protoc-gen from 0.14.0 to 0.15.0 in /console Bumps [ts-protoc-gen](https://github.com/improbable-eng/ts-protoc-gen) from 0.14.0 to 0.15.0. - [Release notes](https://github.com/improbable-eng/ts-protoc-gen/releases) - [Changelog](https://github.com/improbable-eng/ts-protoc-gen/blob/master/CHANGELOG.md) - [Commits](https://github.com/improbable-eng/ts-protoc-gen/compare/0.14.0...0.15.0) Signed-off-by: dependabot[bot] <support@github.com> Co-authored-by: Max Peintner <max@caos.ch> Co-authored-by: Silvan <silvan.reusser@gmail.com> Co-authored-by: dependabot[bot] <49699333+dependabot[bot]@users.noreply.github.com> * chore(deps-dev): bump @types/jasmine from 3.6.9 to 3.6.10 in /console (#1682) Bumps [@types/jasmine](https://github.com/DefinitelyTyped/DefinitelyTyped/tree/HEAD/types/jasmine) from 3.6.9 to 3.6.10. - [Release notes](https://github.com/DefinitelyTyped/DefinitelyTyped/releases) - [Commits](https://github.com/DefinitelyTyped/DefinitelyTyped/commits/HEAD/types/jasmine) Signed-off-by: dependabot[bot] <support@github.com> Co-authored-by: dependabot[bot] <49699333+dependabot[bot]@users.noreply.github.com> * chore(deps): bump @types/google-protobuf in /console (#1681) Bumps [@types/google-protobuf](https://github.com/DefinitelyTyped/DefinitelyTyped/tree/HEAD/types/google-protobuf) from 3.7.4 to 3.15.2. - [Release notes](https://github.com/DefinitelyTyped/DefinitelyTyped/releases) - [Commits](https://github.com/DefinitelyTyped/DefinitelyTyped/commits/HEAD/types/google-protobuf) Signed-off-by: dependabot[bot] <support@github.com> Co-authored-by: dependabot[bot] <49699333+dependabot[bot]@users.noreply.github.com> * chore(deps): bump grpc from 1.24.5 to 1.24.7 in /console (#1666) Bumps [grpc](https://github.com/grpc/grpc-node) from 1.24.5 to 1.24.7. - [Release notes](https://github.com/grpc/grpc-node/releases) - [Commits](https://github.com/grpc/grpc-node/compare/grpc@1.24.5...grpc@1.24.7) Signed-off-by: dependabot[bot] <support@github.com> Co-authored-by: dependabot[bot] <49699333+dependabot[bot]@users.noreply.github.com> * lock * chore(deps-dev): bump @angular/language-service from 11.2.9 to 11.2.12 in /console (#1704) * fix: show org with regex (#1688) * fix: flag mapping (#1699) * chore(deps-dev): bump @angular/language-service in /console Bumps [@angular/language-service](https://github.com/angular/angular/tree/HEAD/packages/language-service) from 11.2.9 to 11.2.12. - [Release notes](https://github.com/angular/angular/releases) - [Changelog](https://github.com/angular/angular/blob/master/CHANGELOG.md) - [Commits](https://github.com/angular/angular/commits/11.2.12/packages/language-service) Signed-off-by: dependabot[bot] <support@github.com> Co-authored-by: Max Peintner <max@caos.ch> Co-authored-by: Silvan <silvan.reusser@gmail.com> Co-authored-by: dependabot[bot] <49699333+dependabot[bot]@users.noreply.github.com> * package lock * downgrade grpc * downgrade protobuf types * revert npm packs 🥸 Co-authored-by: Max Peintner <max@caos.ch> Co-authored-by: dependabot[bot] <49699333+dependabot[bot]@users.noreply.github.com> Co-authored-by: Silvan <silvan.reusser@gmail.com> * docs: update run and start section texts (#1745) * update run and start section texts * adds showcase Co-authored-by: Maximilian Panne <maximilian.panne@gmail.com> * fix: additional origin list (#1753) * fix: handle api configs in authz handler (#1755) * fix(console): add model for api keys, fix toast, binding (#1757) * fix: add model for api keys, fix toast, binding * show api clientid * fix: missing patchvalue (#1758) * feat: refresh token (#1728) * begin refresh tokens * refresh tokens * list and revoke refresh tokens * handle remove * tests for refresh tokens * uniqueness and default expiration * rename oidc token methods * cleanup * migration version * Update internal/static/i18n/en.yaml Co-authored-by: Fabi <38692350+fgerschwiler@users.noreply.github.com> * fixes * feat: update oidc pkg for refresh tokens Co-authored-by: Fabi <38692350+fgerschwiler@users.noreply.github.com> * fix: correct json name of clientId in key.json (#1760) * fix: migration version (#1767) * start subscription * eventtypes * fix(login): links (#1778) * fix(login): href for help * fix(login): correct link to tos * fix: access tokens for service users and refresh token infos (#1779) * fix: access token for service user * handle info from refresh request * uniqueness * postpone access token uniqueness change * chore(coc): recommend code of conduct (#1782) * subscribe for events * feat(console): refresh toggle out of granttype context (#1785) * refresh toggle * disable if not code flow, lint * lint * fix: change oidc config order * accept refresh option within flow Co-authored-by: Livio Amstutz <livio.a@gmail.com> * fix: refresh token activation (#1795) * fix: oidc grant type check * docs: add offline_access scope * docs: update refresh token status in supported grant types * fix: update oidc pkg * fix: check refresh token grant type (#1796) * configuration structs * org admins * failed events * fixes Co-authored-by: Max Peintner <max@caos.ch> Co-authored-by: Livio Amstutz <livio.a@gmail.com> Co-authored-by: Florian Forster <florian@caos.ch> Co-authored-by: mffap <mpa@caos.ch> Co-authored-by: Maximilian Panne <maximilian.panne@gmail.com> Co-authored-by: dependabot[bot] <49699333+dependabot[bot]@users.noreply.github.com> Co-authored-by: Fabi <38692350+fgerschwiler@users.noreply.github.com> * remove comment * aggregate reducer * remove eventtypes * add protoc-get-validate to mod * fix transaltion * upsert * add gender on org admins, allow to retry failed stmts after configurable time * remove if * sub queries * fix: tests * add builder to tests * new search query * rename searchquerybuilder to builder * remove comment from code * test with multiple queries * add filters test * current sequences * make org and org_admins work again * add aggregate type to current sequence * fix(contibute): listing * add validate module * fix: search queries * feat(eventstore): previous aggregate root sequence (#1810) * feat(eventstore): previous aggregate root sequence * fix tests * fix: eventstore v1 test * add col to all mocked rows * next try * fix mig * rename aggregate root to aggregate type * update comment Co-authored-by: Livio Amstutz <livio.a@gmail.com> Co-authored-by: Livio Amstutz <livio.a@gmail.com> * small refactorings * allow update multiple current sequences * unique log id * fix migrations * rename org admin to org owner * improve error handling and logging * fix(migration): optimize prev agg root seq * fix: projection handler test * fix: sub queries * small fixes * additional event types * correct org owner projection * fix primary key * feat(eventstore): jobs for projections (#2026) * fix: template names in login (#1974) * fix: template names in login * fix: error.html * fix: check for features on mgmt only (#1976) * fix: add sentry in ui, http and projection handlers (#1977) * fix: add sentry in ui, http and projection handlers * fix test * fix(eventstore): sub queries (#1805) * sub queries * fix: tests * add builder to tests * new search query * rename searchquerybuilder to builder * remove comment from code * test with multiple queries * add filters test * fix(contibute): listing * add validate module * fix: search queries * remove unused event type in query * ignore query if error in marshal * go mod tidy * update privacy policy query * update queries Co-authored-by: Livio Amstutz <livio.a@gmail.com> * feat: Extend oidc idp with oauth endpoints (#1980) * feat: add oauth attributes to oidc idp configuration * feat: return idpconfig id on create idp * feat: tests * feat: descriptions * feat: docs * feat: tests * docs: update to beta 3 (#1984) * fix: role assertion (#1986) * fix: enum to display access token role assertion * improve assertion descriptions * fix nil pointer * docs: eventstore (#1982) * docs: eventstore * Apply suggestions from code review Co-authored-by: Florian Forster <florian@caos.ch> Co-authored-by: Florian Forster <florian@caos.ch> * fix(sentry): trigger sentry release (#1989) * feat(send sentry release): send sentry release * fix(moved step and added releasetag): moved step and added releasetag * fix: set version for sentry release (#1990) * feat(send sentry release): send sentry release * fix(moved step and added releasetag): moved step and added releasetag * fix(corrected var name): corrected var name Co-authored-by: Livio Amstutz <livio.a@gmail.com> * fix: log error reason on terminate session (#1973) * fix: return default language file, if requested lang does not exist for default login texts (#1988) * fix: return default language file, if requested lang doesnt exists * feat: read default translation file * feat: docs * fix: race condition in auth request unmarshalling (#1993) * feat: handle ui_locales in login (#1994) * fix: handle ui_locales in login * move supportedlanguage func into i18n package * update oidc pkg * fix: handle closed channels on unsubscribe (#1995) * fix: give restore more time (#1997) * fix: translation file read (#2009) * feat: translation file read * feat: readme * fix: enable idp add button for iam users (#2010) * fix: filter event_data (#2011) * feat: Custom message files (#1992) * feat: add get custom message text to admin api * feat: read custom message texts from files * feat: get languages in apis * feat: get languages in apis * feat: get languages in apis * feat: pr feedback * feat: docs * feat: merge main * fix: sms notification (#2013) * fix: phone verifications * feat: fix password reset as sms * fix: phone verification * fix: grpc status in sentry and validation interceptors (#2012) * fix: remove oauth endpoints from oidc config proto (#2014) * try with view * fix(console): disable sw (#2021) * fix: disable sw * angular.json disable sw * project projections * fix typos * customize projections * customizable projections, add change date to projects Co-authored-by: Livio Amstutz <livio.a@gmail.com> Co-authored-by: Max Peintner <max@caos.ch> Co-authored-by: Fabi <38692350+fgerschwiler@users.noreply.github.com> Co-authored-by: Florian Forster <florian@caos.ch> Co-authored-by: mffap <mpa@caos.ch> Co-authored-by: Christian Jakob <47860090+thesephirot@users.noreply.github.com> Co-authored-by: Elio Bischof <eliobischof@gmail.com> * env file * typo * correct users * correct migration * fix: merge fail * fix test * fix(tests): unordered matcher * improve currentSequenceMatcher * correct certs * correct certs * add zitadel database on database list * refctor switch in match * enable all handlers * Delete io.env * cleanup * add handlers * rename view to projection * rename view to projection * fix type typo * remove unnecessary logs * refactor stmts * simplify interval calculation * fix tests * fix unlock test * fix migration * migs * fix(operator): update cockroach and flyway versions (#2138) * chore(deps): bump k8s.io/apiextensions-apiserver from 0.19.2 to 0.21.3 Bumps [k8s.io/apiextensions-apiserver](https://github.com/kubernetes/apiextensions-apiserver) from 0.19.2 to 0.21.3. - [Release notes](https://github.com/kubernetes/apiextensions-apiserver/releases) - [Commits](https://github.com/kubernetes/apiextensions-apiserver/compare/v0.19.2...v0.21.3) --- updated-dependencies: - dependency-name: k8s.io/apiextensions-apiserver dependency-type: direct:production update-type: version-update:semver-minor ... Signed-off-by: dependabot[bot] <support@github.com> * chore(deps): bump google.golang.org/api from 0.34.0 to 0.52.0 Bumps [google.golang.org/api](https://github.com/googleapis/google-api-go-client) from 0.34.0 to 0.52.0. - [Release notes](https://github.com/googleapis/google-api-go-client/releases) - [Changelog](https://github.com/googleapis/google-api-go-client/blob/master/CHANGES.md) - [Commits](https://github.com/googleapis/google-api-go-client/compare/v0.34.0...v0.52.0) --- updated-dependencies: - dependency-name: google.golang.org/api dependency-type: direct:production update-type: version-update:semver-minor ... Signed-off-by: dependabot[bot] <support@github.com> * start update dependencies * update mods and otlp * fix(build): update to go 1.16 * old version for k8s mods * update k8s versions * update orbos * fix(operator): update cockroach and flyway version * Update images.go Co-authored-by: dependabot[bot] <49699333+dependabot[bot]@users.noreply.github.com> Co-authored-by: Stefan Benz <stefan@caos.ch> * fix import * fix typo * fix(migration): add org projection * fix(projection): correct table for org events in org owners * better insert stmt * fix typo * fix typo * set max connection lifetime * set max conns and conn lifetime in eventstore v1 * configure sql connection settings * add mig for agg type index * fix replace tab in yaml * handler interfaces * subscription * first try * handler * move sql client initialization * first part implemented * removed all occurencies of org by id and search orgs * fix merge issues * cleanup code * fix: queries implements orgviewprovider * cleanup * refactor text comparison * remove unused file * remove unused code * log * remove unused code * remove unused field * remove unused file * refactor * tests for search query * remove try * simplify state change mappers * projection tests * query functions * move reusable objects to separate files * rename domain column to primar_domain * fix tests * add current sequence * remove log prints * fix tests * fix: verifier * fix test * rename domain col migrations * simplify search response * move org domain to query * cleanup code * add org id as condition to projection * begin projection * add custom column constructors * start query * import * initial implementation of login policy * remove unused field * tests * factors * simplify reducers * idp projection * fix: org projection table const * start query * apis changed * fix: full column name * feat: text query extension * fix: tests for query * number query * add deprection message * column in a single place (#2416) * column in a single place * use projection for columns * query column with aliases * rename methods * remove unused code * column * column * column * column for current sequences * latest sequence * global counter column * fix is org unique * count * remove col * fix naming * correct errors * error messages * deprecate duplicated is_default in api's, error messages, migrations * migration version * add bool query * Update internal/query/policy_login.go Co-authored-by: Fabi <38692350+fgerschwiler@users.noreply.github.com> * Update login_policy.go * fix tests * add creation-, change-date and sequence to idp, update meta data of idp on config changes, fix wrong mapping * tests * remove unused file * add resource owner * move vars to top Co-authored-by: Max Peintner <max@caos.ch> Co-authored-by: Livio Amstutz <livio.a@gmail.com> Co-authored-by: Florian Forster <florian@caos.ch> Co-authored-by: mffap <mpa@caos.ch> Co-authored-by: Maximilian Panne <maximilian.panne@gmail.com> Co-authored-by: dependabot[bot] <49699333+dependabot[bot]@users.noreply.github.com> Co-authored-by: Fabi <38692350+fgerschwiler@users.noreply.github.com> Co-authored-by: Christian Jakob <47860090+thesephirot@users.noreply.github.com> Co-authored-by: Elio Bischof <eliobischof@gmail.com> Co-authored-by: Stefan Benz <stefan@caos.ch> Co-authored-by: fabi <fabienne.gerschwiler@gmail.com>
This commit is contained in:
parent
48135daa84
commit
1aa26e727e
@ -3,13 +3,14 @@ package admin
|
||||
import (
|
||||
"context"
|
||||
|
||||
"github.com/caos/zitadel/internal/api/authz"
|
||||
idp_grpc "github.com/caos/zitadel/internal/api/grpc/idp"
|
||||
object_pb "github.com/caos/zitadel/internal/api/grpc/object"
|
||||
admin_pb "github.com/caos/zitadel/pkg/grpc/admin"
|
||||
)
|
||||
|
||||
func (s *Server) GetIDPByID(ctx context.Context, req *admin_pb.GetIDPByIDRequest) (*admin_pb.GetIDPByIDResponse, error) {
|
||||
idp, err := s.query.DefaultIDPConfigByID(ctx, req.Id)
|
||||
idp, err := s.query.IDPByIDAndResourceOwner(ctx, req.Id, authz.GetCtxData(ctx).OrgID)
|
||||
if err != nil {
|
||||
return nil, err
|
||||
}
|
||||
@ -17,13 +18,17 @@ func (s *Server) GetIDPByID(ctx context.Context, req *admin_pb.GetIDPByIDRequest
|
||||
}
|
||||
|
||||
func (s *Server) ListIDPs(ctx context.Context, req *admin_pb.ListIDPsRequest) (*admin_pb.ListIDPsResponse, error) {
|
||||
resp, err := s.iam.SearchIDPConfigs(ctx, listIDPsToModel(req))
|
||||
queries, err := listIDPsToModel(req)
|
||||
if err != nil {
|
||||
return nil, err
|
||||
}
|
||||
resp, err := s.query.SearchIDPs(ctx, authz.GetCtxData(ctx).OrgID, queries)
|
||||
if err != nil {
|
||||
return nil, err
|
||||
}
|
||||
return &admin_pb.ListIDPsResponse{
|
||||
Result: idp_grpc.IDPViewsToPb(resp.Result),
|
||||
Details: object_pb.ToListDetails(resp.TotalResult, resp.Sequence, resp.Timestamp),
|
||||
Result: idp_grpc.IDPViewsToPb(resp.IDPs),
|
||||
Details: object_pb.ToListDetails(resp.Count, resp.Sequence, resp.Timestamp),
|
||||
}, nil
|
||||
}
|
||||
|
||||
|
@ -4,8 +4,10 @@ import (
|
||||
idp_grpc "github.com/caos/zitadel/internal/api/grpc/idp"
|
||||
"github.com/caos/zitadel/internal/api/grpc/object"
|
||||
"github.com/caos/zitadel/internal/domain"
|
||||
"github.com/caos/zitadel/internal/errors"
|
||||
"github.com/caos/zitadel/internal/eventstore/v1/models"
|
||||
iam_model "github.com/caos/zitadel/internal/iam/model"
|
||||
"github.com/caos/zitadel/internal/query"
|
||||
user_model "github.com/caos/zitadel/internal/user/model"
|
||||
admin_pb "github.com/caos/zitadel/pkg/grpc/admin"
|
||||
)
|
||||
@ -81,34 +83,43 @@ func updateJWTConfigToDomain(req *admin_pb.UpdateIDPJWTConfigRequest) *domain.JW
|
||||
}
|
||||
}
|
||||
|
||||
func listIDPsToModel(req *admin_pb.ListIDPsRequest) *iam_model.IDPConfigSearchRequest {
|
||||
func listIDPsToModel(req *admin_pb.ListIDPsRequest) (*query.IDPSearchQueries, error) {
|
||||
offset, limit, asc := object.ListQueryToModel(req.Query)
|
||||
return &iam_model.IDPConfigSearchRequest{
|
||||
Offset: offset,
|
||||
Limit: limit,
|
||||
Asc: asc,
|
||||
SortingColumn: idp_grpc.FieldNameToModel(req.SortingColumn),
|
||||
Queries: idpQueriesToModel(req.Queries),
|
||||
queries, err := idpQueriesToModel(req.Queries)
|
||||
if err != nil {
|
||||
return nil, err
|
||||
}
|
||||
return &query.IDPSearchQueries{
|
||||
SearchRequest: query.SearchRequest{
|
||||
Offset: offset,
|
||||
Limit: limit,
|
||||
Asc: asc,
|
||||
SortingColumn: idp_grpc.FieldNameToModel(req.SortingColumn),
|
||||
},
|
||||
Queries: queries,
|
||||
}, nil
|
||||
}
|
||||
|
||||
func idpQueriesToModel(queries []*admin_pb.IDPQuery) []*iam_model.IDPConfigSearchQuery {
|
||||
q := make([]*iam_model.IDPConfigSearchQuery, len(queries))
|
||||
func idpQueriesToModel(queries []*admin_pb.IDPQuery) (q []query.SearchQuery, err error) {
|
||||
q = make([]query.SearchQuery, len(queries))
|
||||
for i, query := range queries {
|
||||
q[i] = idpQueryToModel(query)
|
||||
q[i], err = idpQueryToModel(query)
|
||||
if err != nil {
|
||||
return nil, err
|
||||
}
|
||||
}
|
||||
|
||||
return q
|
||||
return q, nil
|
||||
}
|
||||
|
||||
func idpQueryToModel(query *admin_pb.IDPQuery) *iam_model.IDPConfigSearchQuery {
|
||||
switch q := query.Query.(type) {
|
||||
func idpQueryToModel(idpQuery *admin_pb.IDPQuery) (query.SearchQuery, error) {
|
||||
switch q := idpQuery.Query.(type) {
|
||||
case *admin_pb.IDPQuery_IdpNameQuery:
|
||||
return idp_grpc.IDPNameQueryToModel(q.IdpNameQuery)
|
||||
return query.NewIDPNameSearchQuery(object.TextMethodToQuery(q.IdpNameQuery.Method), q.IdpNameQuery.Name)
|
||||
case *admin_pb.IDPQuery_IdpIdQuery:
|
||||
return idp_grpc.IDPIDQueryToModel(q.IdpIdQuery)
|
||||
return query.NewIDPIDSearchQuery(q.IdpIdQuery.Id)
|
||||
default:
|
||||
return nil
|
||||
return nil, errors.ThrowInvalidArgument(nil, "ADMIN-VmqQu", "List.Query.Invalid")
|
||||
}
|
||||
}
|
||||
|
||||
|
@ -4,11 +4,12 @@ import (
|
||||
obj_grpc "github.com/caos/zitadel/internal/api/grpc/object"
|
||||
"github.com/caos/zitadel/internal/domain"
|
||||
iam_model "github.com/caos/zitadel/internal/iam/model"
|
||||
"github.com/caos/zitadel/internal/query"
|
||||
user_model "github.com/caos/zitadel/internal/user/model"
|
||||
idp_pb "github.com/caos/zitadel/pkg/grpc/idp"
|
||||
)
|
||||
|
||||
func IDPViewsToPb(idps []*iam_model.IDPConfigView) []*idp_pb.IDP {
|
||||
func IDPViewsToPb(idps []*query.IDP) []*idp_pb.IDP {
|
||||
resp := make([]*idp_pb.IDP, len(idps))
|
||||
for i, idp := range idps {
|
||||
resp[i] = ModelIDPViewToPb(idp)
|
||||
@ -16,33 +17,34 @@ func IDPViewsToPb(idps []*iam_model.IDPConfigView) []*idp_pb.IDP {
|
||||
return resp
|
||||
}
|
||||
|
||||
func ModelIDPViewToPb(idp *iam_model.IDPConfigView) *idp_pb.IDP {
|
||||
func ModelIDPViewToPb(idp *query.IDP) *idp_pb.IDP {
|
||||
return &idp_pb.IDP{
|
||||
Id: idp.IDPConfigID,
|
||||
Id: idp.ID,
|
||||
State: ModelIDPStateToPb(idp.State),
|
||||
Name: idp.Name,
|
||||
StylingType: ModelIDPStylingTypeToPb(idp.StylingType),
|
||||
AutoRegister: idp.AutoRegister,
|
||||
Owner: ModelIDPProviderTypeToPb(idp.IDPProviderType),
|
||||
Owner: ModelIDPProviderTypeToPb(idp.OwnerType),
|
||||
Config: ModelIDPViewToConfigPb(idp),
|
||||
Details: obj_grpc.ToViewDetailsPb(
|
||||
idp.Sequence,
|
||||
idp.CreationDate,
|
||||
idp.ChangeDate,
|
||||
idp.AggregateID,
|
||||
idp.ID,
|
||||
),
|
||||
}
|
||||
}
|
||||
|
||||
func IDPViewToPb(idp *domain.IDPConfigView) *idp_pb.IDP {
|
||||
func IDPViewToPb(idp *query.IDP) *idp_pb.IDP {
|
||||
mapped := &idp_pb.IDP{
|
||||
Id: idp.IDPConfigID,
|
||||
Owner: ownerTypeToPB(idp.OwnerType),
|
||||
Id: idp.ID,
|
||||
State: IDPStateToPb(idp.State),
|
||||
Name: idp.Name,
|
||||
StylingType: IDPStylingTypeToPb(idp.StylingType),
|
||||
AutoRegister: idp.AutoRegister,
|
||||
Config: IDPViewToConfigPb(idp),
|
||||
Details: obj_grpc.ToViewDetailsPb(idp.Sequence, idp.CreationDate, idp.ChangeDate, idp.AggregateID),
|
||||
Details: obj_grpc.ToViewDetailsPb(idp.Sequence, idp.CreationDate, idp.ChangeDate, idp.ID),
|
||||
}
|
||||
return mapped
|
||||
}
|
||||
@ -107,11 +109,11 @@ func IDPStateToPb(state domain.IDPConfigState) idp_pb.IDPState {
|
||||
}
|
||||
}
|
||||
|
||||
func ModelIDPStateToPb(state iam_model.IDPConfigState) idp_pb.IDPState {
|
||||
func ModelIDPStateToPb(state domain.IDPConfigState) idp_pb.IDPState {
|
||||
switch state {
|
||||
case iam_model.IDPConfigStateActive:
|
||||
case domain.IDPConfigStateActive:
|
||||
return idp_pb.IDPState_IDP_STATE_ACTIVE
|
||||
case iam_model.IDPConfigStateInactive:
|
||||
case domain.IDPConfigStateInactive:
|
||||
return idp_pb.IDPState_IDP_STATE_INACTIVE
|
||||
default:
|
||||
return idp_pb.IDPState_IDP_STATE_UNSPECIFIED
|
||||
@ -127,9 +129,9 @@ func IDPStylingTypeToDomain(stylingType idp_pb.IDPStylingType) domain.IDPConfigS
|
||||
}
|
||||
}
|
||||
|
||||
func ModelIDPStylingTypeToPb(stylingType iam_model.IDPStylingType) idp_pb.IDPStylingType {
|
||||
func ModelIDPStylingTypeToPb(stylingType domain.IDPConfigStylingType) idp_pb.IDPStylingType {
|
||||
switch stylingType {
|
||||
case iam_model.IDPStylingTypeGoogle:
|
||||
case domain.IDPConfigStylingTypeGoogle:
|
||||
return idp_pb.IDPStylingType_STYLING_TYPE_GOOGLE
|
||||
default:
|
||||
return idp_pb.IDPStylingType_STYLING_TYPE_UNSPECIFIED
|
||||
@ -145,65 +147,65 @@ func IDPStylingTypeToPb(stylingType domain.IDPConfigStylingType) idp_pb.IDPStyli
|
||||
}
|
||||
}
|
||||
|
||||
func ModelIDPViewToConfigPb(config *iam_model.IDPConfigView) idp_pb.IDPConfig {
|
||||
if config.IsOIDC {
|
||||
func ModelIDPViewToConfigPb(config *query.IDP) idp_pb.IDPConfig {
|
||||
if config.OIDCIDP != nil {
|
||||
return &idp_pb.IDP_OidcConfig{
|
||||
OidcConfig: &idp_pb.OIDCConfig{
|
||||
ClientId: config.OIDCClientID,
|
||||
Issuer: config.OIDCIssuer,
|
||||
Scopes: config.OIDCScopes,
|
||||
DisplayNameMapping: ModelMappingFieldToPb(config.OIDCIDPDisplayNameMapping),
|
||||
UsernameMapping: ModelMappingFieldToPb(config.OIDCUsernameMapping),
|
||||
ClientId: config.ClientID,
|
||||
Issuer: config.OIDCIDP.Issuer,
|
||||
Scopes: config.Scopes,
|
||||
DisplayNameMapping: ModelMappingFieldToPb(config.DisplayNameMapping),
|
||||
UsernameMapping: ModelMappingFieldToPb(config.UsernameMapping),
|
||||
},
|
||||
}
|
||||
}
|
||||
return &idp_pb.IDP_JwtConfig{
|
||||
JwtConfig: &idp_pb.JWTConfig{
|
||||
JwtEndpoint: config.JWTEndpoint,
|
||||
Issuer: config.JWTIssuer,
|
||||
KeysEndpoint: config.JWTKeysEndpoint,
|
||||
HeaderName: config.JWTHeaderName,
|
||||
JwtEndpoint: config.Endpoint,
|
||||
Issuer: config.JWTIDP.Issuer,
|
||||
KeysEndpoint: config.KeysEndpoint,
|
||||
HeaderName: config.HeaderName,
|
||||
},
|
||||
}
|
||||
}
|
||||
|
||||
func IDPViewToConfigPb(config *domain.IDPConfigView) idp_pb.IDPConfig {
|
||||
if config.IsOIDC {
|
||||
func IDPViewToConfigPb(config *query.IDP) idp_pb.IDPConfig {
|
||||
if config.OIDCIDP != nil {
|
||||
return &idp_pb.IDP_OidcConfig{
|
||||
OidcConfig: &idp_pb.OIDCConfig{
|
||||
ClientId: config.OIDCClientID,
|
||||
Issuer: config.OIDCIssuer,
|
||||
Scopes: config.OIDCScopes,
|
||||
DisplayNameMapping: MappingFieldToPb(config.OIDCIDPDisplayNameMapping),
|
||||
UsernameMapping: MappingFieldToPb(config.OIDCUsernameMapping),
|
||||
ClientId: config.ClientID,
|
||||
Issuer: config.OIDCIDP.Issuer,
|
||||
Scopes: config.Scopes,
|
||||
DisplayNameMapping: MappingFieldToPb(config.DisplayNameMapping),
|
||||
UsernameMapping: MappingFieldToPb(config.UsernameMapping),
|
||||
},
|
||||
}
|
||||
}
|
||||
return &idp_pb.IDP_JwtConfig{
|
||||
JwtConfig: &idp_pb.JWTConfig{
|
||||
JwtEndpoint: config.JWTEndpoint,
|
||||
Issuer: config.JWTIssuer,
|
||||
KeysEndpoint: config.JWTKeysEndpoint,
|
||||
JwtEndpoint: config.JWTIDP.Endpoint,
|
||||
Issuer: config.JWTIDP.Issuer,
|
||||
KeysEndpoint: config.JWTIDP.KeysEndpoint,
|
||||
},
|
||||
}
|
||||
}
|
||||
|
||||
func FieldNameToModel(fieldName idp_pb.IDPFieldName) iam_model.IDPConfigSearchKey {
|
||||
func FieldNameToModel(fieldName idp_pb.IDPFieldName) query.Column {
|
||||
switch fieldName {
|
||||
// case admin.IdpSearchKey_IDPSEARCHKEY_IDP_CONFIG_ID: //TODO: not implemented in proto
|
||||
// return iam_model.IDPConfigSearchKeyIdpConfigID
|
||||
case idp_pb.IDPFieldName_IDP_FIELD_NAME_NAME:
|
||||
return iam_model.IDPConfigSearchKeyName
|
||||
return query.IDPNameCol
|
||||
default:
|
||||
return iam_model.IDPConfigSearchKeyUnspecified
|
||||
return query.Column{}
|
||||
}
|
||||
}
|
||||
|
||||
func ModelMappingFieldToPb(mappingField iam_model.OIDCMappingField) idp_pb.OIDCMappingField {
|
||||
func ModelMappingFieldToPb(mappingField domain.OIDCMappingField) idp_pb.OIDCMappingField {
|
||||
switch mappingField {
|
||||
case iam_model.OIDCMappingFieldEmail:
|
||||
case domain.OIDCMappingFieldEmail:
|
||||
return idp_pb.OIDCMappingField_OIDC_MAPPING_FIELD_EMAIL
|
||||
case iam_model.OIDCMappingFieldPreferredLoginName:
|
||||
case domain.OIDCMappingFieldPreferredLoginName:
|
||||
return idp_pb.OIDCMappingField_OIDC_MAPPING_FIELD_PREFERRED_USERNAME
|
||||
default:
|
||||
return idp_pb.OIDCMappingField_OIDC_MAPPING_FIELD_UNSPECIFIED
|
||||
@ -232,11 +234,11 @@ func MappingFieldToDomain(mappingField idp_pb.OIDCMappingField) domain.OIDCMappi
|
||||
}
|
||||
}
|
||||
|
||||
func ModelIDPProviderTypeToPb(typ iam_model.IDPProviderType) idp_pb.IDPOwnerType {
|
||||
func ModelIDPProviderTypeToPb(typ domain.IdentityProviderType) idp_pb.IDPOwnerType {
|
||||
switch typ {
|
||||
case iam_model.IDPProviderTypeOrg:
|
||||
case domain.IdentityProviderTypeOrg:
|
||||
return idp_pb.IDPOwnerType_IDP_OWNER_TYPE_ORG
|
||||
case iam_model.IDPProviderTypeSystem:
|
||||
case domain.IdentityProviderTypeSystem:
|
||||
return idp_pb.IDPOwnerType_IDP_OWNER_TYPE_SYSTEM
|
||||
default:
|
||||
return idp_pb.IDPOwnerType_IDP_OWNER_TYPE_UNSPECIFIED
|
||||
@ -288,3 +290,13 @@ func IDPOwnerTypeQueryToModel(query *idp_pb.IDPOwnerTypeQuery) *iam_model.IDPCon
|
||||
Value: IDPProviderTypeModelFromPb(query.OwnerType),
|
||||
}
|
||||
}
|
||||
func ownerTypeToPB(typ domain.IdentityProviderType) idp_pb.IDPOwnerType {
|
||||
switch typ {
|
||||
case domain.IdentityProviderTypeOrg:
|
||||
return idp_pb.IDPOwnerType_IDP_OWNER_TYPE_ORG
|
||||
case domain.IdentityProviderTypeSystem:
|
||||
return idp_pb.IDPOwnerType_IDP_OWNER_TYPE_SYSTEM
|
||||
default:
|
||||
return idp_pb.IDPOwnerType_IDP_OWNER_TYPE_UNSPECIFIED
|
||||
}
|
||||
}
|
||||
|
@ -10,20 +10,25 @@ import (
|
||||
)
|
||||
|
||||
func (s *Server) GetOrgIDPByID(ctx context.Context, req *mgmt_pb.GetOrgIDPByIDRequest) (*mgmt_pb.GetOrgIDPByIDResponse, error) {
|
||||
idp, err := s.org.IDPConfigByID(ctx, req.Id)
|
||||
idp, err := s.query.IDPByIDAndResourceOwner(ctx, req.Id, authz.GetCtxData(ctx).OrgID)
|
||||
if err != nil {
|
||||
return nil, err
|
||||
}
|
||||
return &mgmt_pb.GetOrgIDPByIDResponse{Idp: idp_grpc.ModelIDPViewToPb(idp)}, nil
|
||||
}
|
||||
|
||||
func (s *Server) ListOrgIDPs(ctx context.Context, req *mgmt_pb.ListOrgIDPsRequest) (*mgmt_pb.ListOrgIDPsResponse, error) {
|
||||
resp, err := s.org.SearchIDPConfigs(ctx, listIDPsToModel(req))
|
||||
queries, err := listIDPsToModel(req)
|
||||
if err != nil {
|
||||
return nil, err
|
||||
}
|
||||
resp, err := s.query.SearchIDPs(ctx, authz.GetCtxData(ctx).OrgID, queries)
|
||||
if err != nil {
|
||||
return nil, err
|
||||
}
|
||||
return &mgmt_pb.ListOrgIDPsResponse{
|
||||
Result: idp_grpc.IDPViewsToPb(resp.Result),
|
||||
Details: object_pb.ToListDetails(resp.TotalResult, resp.Sequence, resp.Timestamp),
|
||||
Result: idp_grpc.IDPViewsToPb(resp.IDPs),
|
||||
Details: object_pb.ToListDetails(resp.Count, resp.Sequence, resp.Timestamp),
|
||||
}, nil
|
||||
}
|
||||
func (s *Server) AddOrgOIDCIDP(ctx context.Context, req *mgmt_pb.AddOrgOIDCIDPRequest) (*mgmt_pb.AddOrgOIDCIDPResponse, error) {
|
||||
|
@ -4,8 +4,10 @@ import (
|
||||
idp_grpc "github.com/caos/zitadel/internal/api/grpc/idp"
|
||||
"github.com/caos/zitadel/internal/api/grpc/object"
|
||||
"github.com/caos/zitadel/internal/domain"
|
||||
"github.com/caos/zitadel/internal/errors"
|
||||
"github.com/caos/zitadel/internal/eventstore/v1/models"
|
||||
iam_model "github.com/caos/zitadel/internal/iam/model"
|
||||
"github.com/caos/zitadel/internal/query"
|
||||
user_model "github.com/caos/zitadel/internal/user/model"
|
||||
mgmt_pb "github.com/caos/zitadel/pkg/grpc/management"
|
||||
)
|
||||
@ -81,36 +83,45 @@ func updateJWTConfigToDomain(req *mgmt_pb.UpdateOrgIDPJWTConfigRequest) *domain.
|
||||
}
|
||||
}
|
||||
|
||||
func listIDPsToModel(req *mgmt_pb.ListOrgIDPsRequest) *iam_model.IDPConfigSearchRequest {
|
||||
func listIDPsToModel(req *mgmt_pb.ListOrgIDPsRequest) (queries *query.IDPSearchQueries, err error) {
|
||||
offset, limit, asc := object.ListQueryToModel(req.Query)
|
||||
return &iam_model.IDPConfigSearchRequest{
|
||||
Offset: offset,
|
||||
Limit: limit,
|
||||
Asc: asc,
|
||||
SortingColumn: idp_grpc.FieldNameToModel(req.SortingColumn),
|
||||
Queries: idpQueriesToModel(req.Queries),
|
||||
q, err := idpQueriesToModel(req.Queries)
|
||||
if err != nil {
|
||||
return nil, err
|
||||
}
|
||||
return &query.IDPSearchQueries{
|
||||
SearchRequest: query.SearchRequest{
|
||||
Offset: offset,
|
||||
Limit: limit,
|
||||
Asc: asc,
|
||||
SortingColumn: idp_grpc.FieldNameToModel(req.SortingColumn),
|
||||
},
|
||||
Queries: q,
|
||||
}, nil
|
||||
}
|
||||
|
||||
func idpQueriesToModel(queries []*mgmt_pb.IDPQuery) []*iam_model.IDPConfigSearchQuery {
|
||||
q := make([]*iam_model.IDPConfigSearchQuery, len(queries))
|
||||
func idpQueriesToModel(queries []*mgmt_pb.IDPQuery) (q []query.SearchQuery, err error) {
|
||||
q = make([]query.SearchQuery, len(queries))
|
||||
for i, query := range queries {
|
||||
q[i] = idpQueryToModel(query)
|
||||
q[i], err = idpQueryToModel(query)
|
||||
if err != nil {
|
||||
return nil, err
|
||||
}
|
||||
}
|
||||
|
||||
return q
|
||||
return q, nil
|
||||
}
|
||||
|
||||
func idpQueryToModel(query *mgmt_pb.IDPQuery) *iam_model.IDPConfigSearchQuery {
|
||||
switch q := query.Query.(type) {
|
||||
func idpQueryToModel(idpQuery *mgmt_pb.IDPQuery) (query.SearchQuery, error) {
|
||||
switch q := idpQuery.Query.(type) {
|
||||
case *mgmt_pb.IDPQuery_IdpNameQuery:
|
||||
return idp_grpc.IDPNameQueryToModel(q.IdpNameQuery)
|
||||
return query.NewIDPNameSearchQuery(object.TextMethodToQuery(q.IdpNameQuery.Method), q.IdpNameQuery.Name)
|
||||
case *mgmt_pb.IDPQuery_IdpIdQuery:
|
||||
return idp_grpc.IDPIDQueryToModel(q.IdpIdQuery)
|
||||
return query.NewIDPIDSearchQuery(q.IdpIdQuery.Id)
|
||||
case *mgmt_pb.IDPQuery_OwnerTypeQuery:
|
||||
return idp_grpc.IDPOwnerTypeQueryToModel(q.OwnerTypeQuery)
|
||||
return query.NewIDPOwnerTypeSearchQuery(idp_grpc.IDPProviderTypeFromPb(q.OwnerTypeQuery.OwnerType))
|
||||
default:
|
||||
return nil
|
||||
return nil, errors.ThrowInvalidArgument(nil, "MANAG-WtLPV", "List.Query.Invalid")
|
||||
}
|
||||
}
|
||||
|
||||
|
@ -1,16 +0,0 @@
|
||||
package query
|
||||
|
||||
import (
|
||||
"context"
|
||||
"github.com/caos/zitadel/internal/domain"
|
||||
)
|
||||
|
||||
func (r *Queries) DefaultIDPConfigByID(ctx context.Context, idpConfigID string) (*domain.IDPConfigView, error) {
|
||||
idpConfig := NewIAMIDPConfigReadModel(r.iamID, idpConfigID)
|
||||
err := r.eventstore.FilterToQueryReducer(ctx, idpConfig)
|
||||
if err != nil {
|
||||
return nil, err
|
||||
}
|
||||
|
||||
return readModelToIDPConfigView(idpConfig), nil
|
||||
}
|
489
internal/query/idp.go
Normal file
489
internal/query/idp.go
Normal file
@ -0,0 +1,489 @@
|
||||
package query
|
||||
|
||||
import (
|
||||
"context"
|
||||
"database/sql"
|
||||
errs "errors"
|
||||
"log"
|
||||
"time"
|
||||
|
||||
sq "github.com/Masterminds/squirrel"
|
||||
"github.com/caos/zitadel/internal/crypto"
|
||||
"github.com/caos/zitadel/internal/domain"
|
||||
"github.com/caos/zitadel/internal/errors"
|
||||
"github.com/caos/zitadel/internal/query/projection"
|
||||
"github.com/lib/pq"
|
||||
)
|
||||
|
||||
type IDP struct {
|
||||
CreationDate time.Time
|
||||
ChangeDate time.Time
|
||||
Sequence uint64
|
||||
ResourceOwner string
|
||||
ID string
|
||||
State domain.IDPConfigState
|
||||
Name string
|
||||
StylingType domain.IDPConfigStylingType
|
||||
OwnerType domain.IdentityProviderType
|
||||
AutoRegister bool
|
||||
*OIDCIDP
|
||||
*JWTIDP
|
||||
}
|
||||
|
||||
type IDPs struct {
|
||||
SearchResponse
|
||||
IDPs []*IDP
|
||||
}
|
||||
|
||||
type OIDCIDP struct {
|
||||
IDPID string
|
||||
ClientID string
|
||||
ClientSecret *crypto.CryptoValue
|
||||
Issuer string
|
||||
Scopes []string
|
||||
DisplayNameMapping domain.OIDCMappingField
|
||||
UsernameMapping domain.OIDCMappingField
|
||||
AuthorizationEndpoint string
|
||||
TokenEndpoint string
|
||||
}
|
||||
|
||||
type JWTIDP struct {
|
||||
IDPID string
|
||||
Issuer string
|
||||
KeysEndpoint string
|
||||
HeaderName string
|
||||
Endpoint string
|
||||
}
|
||||
|
||||
var (
|
||||
idpTable = table{
|
||||
name: projection.IDPTable,
|
||||
}
|
||||
IDPIDCol = Column{
|
||||
name: projection.IDPIDCol,
|
||||
table: idpTable,
|
||||
}
|
||||
IDPCreationDateCol = Column{
|
||||
name: projection.IDPCreationDateCol,
|
||||
table: idpTable,
|
||||
}
|
||||
IDPChangeDateCol = Column{
|
||||
name: projection.IDPChangeDateCol,
|
||||
table: idpTable,
|
||||
}
|
||||
IDPSequenceCol = Column{
|
||||
name: projection.IDPSequenceCol,
|
||||
table: idpTable,
|
||||
}
|
||||
IDPResourceOwnerCol = Column{
|
||||
name: projection.IDPResourceOwnerCol,
|
||||
table: idpTable,
|
||||
}
|
||||
IDPStateCol = Column{
|
||||
name: projection.IDPStateCol,
|
||||
table: idpTable,
|
||||
}
|
||||
IDPNameCol = Column{
|
||||
name: projection.IDPNameCol,
|
||||
table: idpTable,
|
||||
}
|
||||
IDPStylingTypeCol = Column{
|
||||
name: projection.IDPStylingTypeCol,
|
||||
table: idpTable,
|
||||
}
|
||||
IDPOwnerCol = Column{
|
||||
name: projection.IDPOwnerTypeCol,
|
||||
table: idpTable,
|
||||
}
|
||||
IDPAutoRegisterCol = Column{
|
||||
name: projection.IDPAutoRegisterCol,
|
||||
table: idpTable,
|
||||
}
|
||||
)
|
||||
|
||||
var (
|
||||
oidcIDPTable = table{
|
||||
name: projection.IDPOIDCTable,
|
||||
}
|
||||
OIDCIDPColIDPID = Column{
|
||||
name: projection.OIDCConfigIDPIDCol,
|
||||
table: oidcIDPTable,
|
||||
}
|
||||
OIDCIDPColClientID = Column{
|
||||
name: projection.OIDCConfigClientIDCol,
|
||||
table: oidcIDPTable,
|
||||
}
|
||||
OIDCIDPColClientSecret = Column{
|
||||
name: projection.OIDCConfigClientSecretCol,
|
||||
table: oidcIDPTable,
|
||||
}
|
||||
OIDCIDPColIssuer = Column{
|
||||
name: projection.OIDCConfigIssuerCol,
|
||||
table: oidcIDPTable,
|
||||
}
|
||||
OIDCIDPColScopes = Column{
|
||||
name: projection.OIDCConfigScopesCol,
|
||||
table: oidcIDPTable,
|
||||
}
|
||||
OIDCIDPColDisplayNameMapping = Column{
|
||||
name: projection.OIDCConfigDisplayNameMappingCol,
|
||||
table: oidcIDPTable,
|
||||
}
|
||||
OIDCIDPColUsernameMapping = Column{
|
||||
name: projection.OIDCConfigUsernameMappingCol,
|
||||
table: oidcIDPTable,
|
||||
}
|
||||
OIDCIDPColAuthorizationEndpoint = Column{
|
||||
name: projection.OIDCConfigAuthorizationEndpointCol,
|
||||
table: oidcIDPTable,
|
||||
}
|
||||
OIDCIDPColTokenEndpoint = Column{
|
||||
name: projection.OIDCConfigTokenEndpointCol,
|
||||
table: oidcIDPTable,
|
||||
}
|
||||
)
|
||||
|
||||
var (
|
||||
jwtIDPTable = table{
|
||||
name: projection.IDPJWTTable,
|
||||
}
|
||||
JWTIDPColIDPID = Column{
|
||||
name: projection.JWTConfigIDPIDCol,
|
||||
table: jwtIDPTable,
|
||||
}
|
||||
JWTIDPColIssuer = Column{
|
||||
name: projection.JWTConfigIssuerCol,
|
||||
table: jwtIDPTable,
|
||||
}
|
||||
JWTIDPColKeysEndpoint = Column{
|
||||
name: projection.JWTConfigKeysEndpointCol,
|
||||
table: jwtIDPTable,
|
||||
}
|
||||
JWTIDPColHeaderName = Column{
|
||||
name: projection.JWTConfigHeaderNameCol,
|
||||
table: jwtIDPTable,
|
||||
}
|
||||
JWTIDPColEndpoint = Column{
|
||||
name: projection.JWTConfigEndpointCol,
|
||||
table: jwtIDPTable,
|
||||
}
|
||||
)
|
||||
|
||||
//IDPByIDAndResourceOwner searches for the requested id in the context of the resource owner and IAM
|
||||
func (q *Queries) IDPByIDAndResourceOwner(ctx context.Context, id, resourceOwner string) (*IDP, error) {
|
||||
stmt, scan := prepareIDPByIDQuery()
|
||||
query, args, err := stmt.Where(
|
||||
sq.And{
|
||||
sq.Eq{
|
||||
IDPIDCol.identifier(): id,
|
||||
},
|
||||
sq.Or{
|
||||
sq.Eq{
|
||||
IDPResourceOwnerCol.identifier(): resourceOwner,
|
||||
},
|
||||
sq.Eq{
|
||||
IDPResourceOwnerCol.identifier(): q.iamID,
|
||||
},
|
||||
},
|
||||
},
|
||||
).ToSql()
|
||||
if err != nil {
|
||||
return nil, errors.ThrowInternal(err, "QUERY-0gocI", "Errors.Query.SQLStatement")
|
||||
}
|
||||
|
||||
row := q.client.QueryRowContext(ctx, query, args...)
|
||||
return scan(row)
|
||||
}
|
||||
|
||||
//SearchIDPs searches executes the query in the context of the resource owner and IAM
|
||||
func (q *Queries) SearchIDPs(ctx context.Context, resourceOwner string, queries *IDPSearchQueries) (idps *IDPs, err error) {
|
||||
query, scan := prepareIDPsQuery()
|
||||
query = queries.toQuery(query)
|
||||
query = query.Where(
|
||||
sq.Or{
|
||||
sq.Eq{
|
||||
IDPResourceOwnerCol.identifier(): resourceOwner,
|
||||
IDPResourceOwnerCol.identifier(): q.iamID,
|
||||
},
|
||||
},
|
||||
)
|
||||
stmt, args, err := queries.toQuery(query).ToSql()
|
||||
if err != nil {
|
||||
return nil, errors.ThrowInvalidArgument(err, "QUERY-zC6gk", "Errors.Query.InvalidRequest")
|
||||
}
|
||||
|
||||
rows, err := q.client.QueryContext(ctx, stmt, args...)
|
||||
if err != nil {
|
||||
log.Println(err)
|
||||
return nil, errors.ThrowInternal(err, "QUERY-YTug9", "Errors.Internal")
|
||||
}
|
||||
idps, err = scan(rows)
|
||||
if err != nil {
|
||||
return nil, err
|
||||
}
|
||||
idps.LatestSequence, err = q.latestSequence(ctx, idpTable)
|
||||
return idps, err
|
||||
}
|
||||
|
||||
type IDPSearchQueries struct {
|
||||
SearchRequest
|
||||
Queries []SearchQuery
|
||||
}
|
||||
|
||||
func NewIDPIDSearchQuery(id string) (SearchQuery, error) {
|
||||
return NewTextQuery(IDPIDCol, id, TextEquals)
|
||||
}
|
||||
|
||||
func NewIDPOwnerTypeSearchQuery(ownerType domain.IdentityProviderType) (SearchQuery, error) {
|
||||
switch ownerType {
|
||||
case domain.IdentityProviderTypeOrg:
|
||||
return NewBoolQuery(LoginPolicyColumnIsDefault, false)
|
||||
case domain.IdentityProviderTypeSystem:
|
||||
return NewBoolQuery(LoginPolicyColumnIsDefault, true)
|
||||
default:
|
||||
return nil, errors.ThrowUnimplemented(nil, "QUERY-8yZAI", "Errors.Query.InvalidRequest")
|
||||
}
|
||||
}
|
||||
|
||||
func NewIDPNameSearchQuery(method TextComparison, value string) (SearchQuery, error) {
|
||||
return NewTextQuery(IDPNameCol, value, method)
|
||||
}
|
||||
|
||||
func (q *IDPSearchQueries) toQuery(query sq.SelectBuilder) sq.SelectBuilder {
|
||||
query = q.SearchRequest.toQuery(query)
|
||||
for _, q := range q.Queries {
|
||||
query = q.ToQuery(query)
|
||||
}
|
||||
return query
|
||||
}
|
||||
|
||||
func prepareIDPByIDQuery() (sq.SelectBuilder, func(*sql.Row) (*IDP, error)) {
|
||||
return sq.Select(
|
||||
IDPIDCol.identifier(),
|
||||
IDPResourceOwnerCol.identifier(),
|
||||
IDPCreationDateCol.identifier(),
|
||||
IDPChangeDateCol.identifier(),
|
||||
IDPSequenceCol.identifier(),
|
||||
IDPStateCol.identifier(),
|
||||
IDPNameCol.identifier(),
|
||||
IDPStylingTypeCol.identifier(),
|
||||
IDPOwnerCol.identifier(),
|
||||
IDPAutoRegisterCol.identifier(),
|
||||
OIDCIDPColIDPID.identifier(),
|
||||
OIDCIDPColClientID.identifier(),
|
||||
OIDCIDPColClientSecret.identifier(),
|
||||
OIDCIDPColIssuer.identifier(),
|
||||
OIDCIDPColScopes.identifier(),
|
||||
OIDCIDPColDisplayNameMapping.identifier(),
|
||||
OIDCIDPColUsernameMapping.identifier(),
|
||||
OIDCIDPColAuthorizationEndpoint.identifier(),
|
||||
OIDCIDPColTokenEndpoint.identifier(),
|
||||
JWTIDPColIDPID.identifier(),
|
||||
JWTIDPColIssuer.identifier(),
|
||||
JWTIDPColKeysEndpoint.identifier(),
|
||||
JWTIDPColHeaderName.identifier(),
|
||||
JWTIDPColEndpoint.identifier(),
|
||||
).From(idpTable.identifier()).
|
||||
LeftJoin(join(OIDCIDPColIDPID, IDPIDCol)).
|
||||
LeftJoin(join(JWTIDPColIDPID, IDPIDCol)).
|
||||
PlaceholderFormat(sq.Dollar),
|
||||
func(row *sql.Row) (*IDP, error) {
|
||||
idp := new(IDP)
|
||||
|
||||
oidcIDPID := sql.NullString{}
|
||||
oidcClientID := sql.NullString{}
|
||||
oidcClientSecret := new(crypto.CryptoValue)
|
||||
oidcIssuer := sql.NullString{}
|
||||
oidcScopes := pq.StringArray{}
|
||||
oidcDisplayNameMapping := sql.NullInt32{}
|
||||
oidcUsernameMapping := sql.NullInt32{}
|
||||
oidcAuthorizationEndpoint := sql.NullString{}
|
||||
oidcTokenEndpoint := sql.NullString{}
|
||||
|
||||
jwtIDPID := sql.NullString{}
|
||||
jwtIssuer := sql.NullString{}
|
||||
jwtKeysEndpoint := sql.NullString{}
|
||||
jwtHeaderName := sql.NullString{}
|
||||
jwtEndpoint := sql.NullString{}
|
||||
|
||||
err := row.Scan(
|
||||
&idp.ID,
|
||||
&idp.ResourceOwner,
|
||||
&idp.CreationDate,
|
||||
&idp.ChangeDate,
|
||||
&idp.Sequence,
|
||||
&idp.State,
|
||||
&idp.Name,
|
||||
&idp.StylingType,
|
||||
&idp.OwnerType,
|
||||
&idp.AutoRegister,
|
||||
&oidcIDPID,
|
||||
&oidcClientID,
|
||||
oidcClientSecret,
|
||||
&oidcIssuer,
|
||||
&oidcScopes,
|
||||
&oidcDisplayNameMapping,
|
||||
&oidcUsernameMapping,
|
||||
&oidcAuthorizationEndpoint,
|
||||
&oidcTokenEndpoint,
|
||||
&jwtIDPID,
|
||||
&jwtIssuer,
|
||||
&jwtKeysEndpoint,
|
||||
&jwtHeaderName,
|
||||
&jwtEndpoint,
|
||||
)
|
||||
if err != nil {
|
||||
if errs.Is(err, sql.ErrNoRows) {
|
||||
return nil, errors.ThrowNotFound(err, "QUERY-rhR2o", "Errors.IDPConfig.NotExisting")
|
||||
}
|
||||
return nil, errors.ThrowInternal(err, "QUERY-zE3Ro", "Errors.Internal")
|
||||
}
|
||||
|
||||
if oidcIDPID.Valid {
|
||||
idp.OIDCIDP = &OIDCIDP{
|
||||
IDPID: oidcIDPID.String,
|
||||
ClientID: oidcClientID.String,
|
||||
ClientSecret: oidcClientSecret,
|
||||
Issuer: oidcIssuer.String,
|
||||
Scopes: oidcScopes,
|
||||
DisplayNameMapping: domain.OIDCMappingField(oidcDisplayNameMapping.Int32),
|
||||
UsernameMapping: domain.OIDCMappingField(oidcUsernameMapping.Int32),
|
||||
AuthorizationEndpoint: oidcAuthorizationEndpoint.String,
|
||||
TokenEndpoint: oidcTokenEndpoint.String,
|
||||
}
|
||||
} else if jwtIDPID.Valid {
|
||||
idp.JWTIDP = &JWTIDP{
|
||||
IDPID: jwtIDPID.String,
|
||||
Issuer: jwtIssuer.String,
|
||||
KeysEndpoint: jwtKeysEndpoint.String,
|
||||
HeaderName: jwtHeaderName.String,
|
||||
Endpoint: jwtEndpoint.String,
|
||||
}
|
||||
}
|
||||
|
||||
return idp, nil
|
||||
}
|
||||
}
|
||||
|
||||
func prepareIDPsQuery() (sq.SelectBuilder, func(*sql.Rows) (*IDPs, error)) {
|
||||
return sq.Select(
|
||||
IDPIDCol.identifier(),
|
||||
IDPResourceOwnerCol.identifier(),
|
||||
IDPCreationDateCol.identifier(),
|
||||
IDPChangeDateCol.identifier(),
|
||||
IDPSequenceCol.identifier(),
|
||||
IDPStateCol.identifier(),
|
||||
IDPNameCol.identifier(),
|
||||
IDPStylingTypeCol.identifier(),
|
||||
IDPOwnerCol.identifier(),
|
||||
IDPAutoRegisterCol.identifier(),
|
||||
OIDCIDPColIDPID.identifier(),
|
||||
OIDCIDPColClientID.identifier(),
|
||||
OIDCIDPColClientSecret.identifier(),
|
||||
OIDCIDPColIssuer.identifier(),
|
||||
OIDCIDPColScopes.identifier(),
|
||||
OIDCIDPColDisplayNameMapping.identifier(),
|
||||
OIDCIDPColUsernameMapping.identifier(),
|
||||
OIDCIDPColAuthorizationEndpoint.identifier(),
|
||||
OIDCIDPColTokenEndpoint.identifier(),
|
||||
JWTIDPColIDPID.identifier(),
|
||||
JWTIDPColIssuer.identifier(),
|
||||
JWTIDPColKeysEndpoint.identifier(),
|
||||
JWTIDPColHeaderName.identifier(),
|
||||
JWTIDPColEndpoint.identifier(),
|
||||
countColumn.identifier(),
|
||||
).From(idpTable.identifier()).
|
||||
LeftJoin(join(OIDCIDPColIDPID, IDPIDCol)).
|
||||
LeftJoin(join(JWTIDPColIDPID, IDPIDCol)).
|
||||
PlaceholderFormat(sq.Dollar),
|
||||
func(rows *sql.Rows) (*IDPs, error) {
|
||||
idps := make([]*IDP, 0)
|
||||
var count uint64
|
||||
for rows.Next() {
|
||||
idp := new(IDP)
|
||||
|
||||
oidcIDPID := sql.NullString{}
|
||||
oidcClientID := sql.NullString{}
|
||||
oidcClientSecret := new(crypto.CryptoValue)
|
||||
oidcIssuer := sql.NullString{}
|
||||
oidcScopes := pq.StringArray{}
|
||||
oidcDisplayNameMapping := sql.NullInt32{}
|
||||
oidcUsernameMapping := sql.NullInt32{}
|
||||
oidcAuthorizationEndpoint := sql.NullString{}
|
||||
oidcTokenEndpoint := sql.NullString{}
|
||||
|
||||
jwtIDPID := sql.NullString{}
|
||||
jwtIssuer := sql.NullString{}
|
||||
jwtKeysEndpoint := sql.NullString{}
|
||||
jwtHeaderName := sql.NullString{}
|
||||
jwtEndpoint := sql.NullString{}
|
||||
|
||||
err := rows.Scan(
|
||||
&idp.ID,
|
||||
&idp.ResourceOwner,
|
||||
&idp.CreationDate,
|
||||
&idp.ChangeDate,
|
||||
&idp.Sequence,
|
||||
&idp.State,
|
||||
&idp.Name,
|
||||
&idp.StylingType,
|
||||
&idp.OwnerType,
|
||||
&idp.AutoRegister,
|
||||
&oidcIDPID,
|
||||
&oidcClientID,
|
||||
oidcClientSecret,
|
||||
&oidcIssuer,
|
||||
&oidcScopes,
|
||||
&oidcDisplayNameMapping,
|
||||
&oidcUsernameMapping,
|
||||
&oidcAuthorizationEndpoint,
|
||||
&oidcTokenEndpoint,
|
||||
&jwtIDPID,
|
||||
&jwtIssuer,
|
||||
&jwtKeysEndpoint,
|
||||
&jwtHeaderName,
|
||||
&jwtEndpoint,
|
||||
&count,
|
||||
)
|
||||
|
||||
if err != nil {
|
||||
return nil, err
|
||||
}
|
||||
|
||||
if oidcIDPID.Valid {
|
||||
idp.OIDCIDP = &OIDCIDP{
|
||||
IDPID: oidcIDPID.String,
|
||||
ClientID: oidcClientID.String,
|
||||
ClientSecret: oidcClientSecret,
|
||||
Issuer: oidcIssuer.String,
|
||||
Scopes: oidcScopes,
|
||||
DisplayNameMapping: domain.OIDCMappingField(oidcDisplayNameMapping.Int32),
|
||||
UsernameMapping: domain.OIDCMappingField(oidcUsernameMapping.Int32),
|
||||
AuthorizationEndpoint: oidcAuthorizationEndpoint.String,
|
||||
TokenEndpoint: oidcTokenEndpoint.String,
|
||||
}
|
||||
} else if jwtIDPID.Valid {
|
||||
idp.JWTIDP = &JWTIDP{
|
||||
IDPID: jwtIDPID.String,
|
||||
Issuer: jwtIssuer.String,
|
||||
KeysEndpoint: jwtKeysEndpoint.String,
|
||||
HeaderName: jwtHeaderName.String,
|
||||
Endpoint: jwtEndpoint.String,
|
||||
}
|
||||
}
|
||||
|
||||
idps = append(idps, idp)
|
||||
}
|
||||
|
||||
if err := rows.Close(); err != nil {
|
||||
return nil, errors.ThrowInternal(err, "QUERY-iiBgK", "Errors.Query.CloseRows")
|
||||
}
|
||||
|
||||
return &IDPs{
|
||||
IDPs: idps,
|
||||
SearchResponse: SearchResponse{
|
||||
Count: count,
|
||||
},
|
||||
}, nil
|
||||
}
|
||||
}
|
484
internal/query/projection/idp.go
Normal file
484
internal/query/projection/idp.go
Normal file
@ -0,0 +1,484 @@
|
||||
package projection
|
||||
|
||||
import (
|
||||
"context"
|
||||
|
||||
"github.com/caos/logging"
|
||||
"github.com/caos/zitadel/internal/domain"
|
||||
"github.com/caos/zitadel/internal/errors"
|
||||
"github.com/caos/zitadel/internal/eventstore"
|
||||
"github.com/caos/zitadel/internal/eventstore/handler"
|
||||
"github.com/caos/zitadel/internal/eventstore/handler/crdb"
|
||||
"github.com/caos/zitadel/internal/repository/iam"
|
||||
"github.com/caos/zitadel/internal/repository/idpconfig"
|
||||
"github.com/caos/zitadel/internal/repository/org"
|
||||
"github.com/lib/pq"
|
||||
)
|
||||
|
||||
type IDPProjection struct {
|
||||
crdb.StatementHandler
|
||||
}
|
||||
|
||||
const (
|
||||
IDPTable = "zitadel.projections.idps"
|
||||
IDPOIDCTable = IDPTable + "_" + IDPOIDCSuffix
|
||||
IDPJWTTable = IDPTable + "_" + IDPJWTSuffix
|
||||
)
|
||||
|
||||
func NewIDPProjection(ctx context.Context, config crdb.StatementHandlerConfig) *IDPProjection {
|
||||
p := &IDPProjection{}
|
||||
config.ProjectionName = IDPTable
|
||||
config.Reducers = p.reducers()
|
||||
p.StatementHandler = crdb.NewStatementHandler(ctx, config)
|
||||
return p
|
||||
}
|
||||
|
||||
func (p *IDPProjection) reducers() []handler.AggregateReducer {
|
||||
return []handler.AggregateReducer{
|
||||
{
|
||||
Aggregate: iam.AggregateType,
|
||||
EventRedusers: []handler.EventReducer{
|
||||
{
|
||||
Event: iam.IDPConfigAddedEventType,
|
||||
Reduce: p.reduceIDPAdded,
|
||||
},
|
||||
{
|
||||
Event: iam.IDPConfigChangedEventType,
|
||||
Reduce: p.reduceIDPChanged,
|
||||
},
|
||||
{
|
||||
Event: iam.IDPConfigDeactivatedEventType,
|
||||
Reduce: p.reduceIDPDeactivated,
|
||||
},
|
||||
{
|
||||
Event: iam.IDPConfigReactivatedEventType,
|
||||
Reduce: p.reduceIDPReactivated,
|
||||
},
|
||||
{
|
||||
Event: iam.IDPConfigRemovedEventType,
|
||||
Reduce: p.reduceIDPRemoved,
|
||||
},
|
||||
{
|
||||
Event: iam.IDPOIDCConfigAddedEventType,
|
||||
Reduce: p.reduceOIDCConfigAdded,
|
||||
},
|
||||
{
|
||||
Event: iam.IDPOIDCConfigChangedEventType,
|
||||
Reduce: p.reduceOIDCConfigChanged,
|
||||
},
|
||||
{
|
||||
Event: iam.IDPJWTConfigAddedEventType,
|
||||
Reduce: p.reduceJWTConfigAdded,
|
||||
},
|
||||
{
|
||||
Event: iam.IDPJWTConfigChangedEventType,
|
||||
Reduce: p.reduceJWTConfigChanged,
|
||||
},
|
||||
},
|
||||
},
|
||||
{
|
||||
Aggregate: org.AggregateType,
|
||||
EventRedusers: []handler.EventReducer{
|
||||
{
|
||||
Event: org.IDPConfigAddedEventType,
|
||||
Reduce: p.reduceIDPAdded,
|
||||
},
|
||||
{
|
||||
Event: org.IDPConfigChangedEventType,
|
||||
Reduce: p.reduceIDPChanged,
|
||||
},
|
||||
{
|
||||
Event: org.IDPConfigDeactivatedEventType,
|
||||
Reduce: p.reduceIDPDeactivated,
|
||||
},
|
||||
{
|
||||
Event: org.IDPConfigReactivatedEventType,
|
||||
Reduce: p.reduceIDPReactivated,
|
||||
},
|
||||
{
|
||||
Event: org.IDPConfigRemovedEventType,
|
||||
Reduce: p.reduceIDPRemoved,
|
||||
},
|
||||
{
|
||||
Event: org.IDPOIDCConfigAddedEventType,
|
||||
Reduce: p.reduceOIDCConfigAdded,
|
||||
},
|
||||
{
|
||||
Event: org.IDPOIDCConfigChangedEventType,
|
||||
Reduce: p.reduceOIDCConfigChanged,
|
||||
},
|
||||
{
|
||||
Event: org.IDPJWTConfigAddedEventType,
|
||||
Reduce: p.reduceJWTConfigAdded,
|
||||
},
|
||||
{
|
||||
Event: org.IDPJWTConfigChangedEventType,
|
||||
Reduce: p.reduceJWTConfigChanged,
|
||||
},
|
||||
},
|
||||
},
|
||||
}
|
||||
}
|
||||
|
||||
const (
|
||||
IDPOIDCSuffix = "oidc_config"
|
||||
IDPJWTSuffix = "jwt_config"
|
||||
|
||||
IDPIDCol = "id"
|
||||
IDPCreationDateCol = "creation_date"
|
||||
IDPChangeDateCol = "change_date"
|
||||
IDPSequenceCol = "sequence"
|
||||
IDPResourceOwnerCol = "resource_owner"
|
||||
IDPStateCol = "state"
|
||||
IDPNameCol = "name"
|
||||
IDPStylingTypeCol = "styling_type"
|
||||
IDPOwnerTypeCol = "owner_type"
|
||||
IDPAutoRegisterCol = "auto_register"
|
||||
|
||||
OIDCConfigIDPIDCol = "idp_id"
|
||||
OIDCConfigClientIDCol = "client_id"
|
||||
OIDCConfigClientSecretCol = "client_secret"
|
||||
OIDCConfigIssuerCol = "issuer"
|
||||
OIDCConfigScopesCol = "scopes"
|
||||
OIDCConfigDisplayNameMappingCol = "display_name_mapping"
|
||||
OIDCConfigUsernameMappingCol = "username_mapping"
|
||||
OIDCConfigAuthorizationEndpointCol = "authorization_endpoint"
|
||||
OIDCConfigTokenEndpointCol = "token_endpoint"
|
||||
|
||||
JWTConfigIDPIDCol = "idp_id"
|
||||
JWTConfigIssuerCol = "issuer"
|
||||
JWTConfigKeysEndpointCol = "keys_endpoint"
|
||||
JWTConfigHeaderNameCol = "header_name"
|
||||
JWTConfigEndpointCol = "endpoint"
|
||||
)
|
||||
|
||||
func (p *IDPProjection) reduceIDPAdded(event eventstore.EventReader) (*handler.Statement, error) {
|
||||
var idpEvent idpconfig.IDPConfigAddedEvent
|
||||
var idpOwnerType domain.IdentityProviderType
|
||||
switch e := event.(type) {
|
||||
case *org.IDPConfigAddedEvent:
|
||||
idpEvent = e.IDPConfigAddedEvent
|
||||
idpOwnerType = domain.IdentityProviderTypeOrg
|
||||
case *iam.IDPConfigAddedEvent:
|
||||
idpEvent = e.IDPConfigAddedEvent
|
||||
idpOwnerType = domain.IdentityProviderTypeSystem
|
||||
default:
|
||||
logging.LogWithFields("HANDL-hBriG", "seq", e.Sequence(), "expectedTypes", []eventstore.EventType{org.IDPConfigAddedEventType, iam.IDPConfigAddedEventType}).Error("wrong event type")
|
||||
return nil, errors.ThrowInvalidArgument(nil, "HANDL-fcUdQ", "reduce.wrong.event.type")
|
||||
}
|
||||
|
||||
return crdb.NewCreateStatement(
|
||||
&idpEvent,
|
||||
[]handler.Column{
|
||||
handler.NewCol(IDPIDCol, idpEvent.ConfigID),
|
||||
handler.NewCol(IDPCreationDateCol, idpEvent.CreationDate()),
|
||||
handler.NewCol(IDPChangeDateCol, idpEvent.CreationDate()),
|
||||
handler.NewCol(IDPSequenceCol, idpEvent.Sequence()),
|
||||
handler.NewCol(IDPResourceOwnerCol, idpEvent.Aggregate().ResourceOwner),
|
||||
handler.NewCol(IDPStateCol, domain.IDPConfigStateActive),
|
||||
handler.NewCol(IDPNameCol, idpEvent.Name),
|
||||
handler.NewCol(IDPStylingTypeCol, idpEvent.StylingType),
|
||||
handler.NewCol(IDPAutoRegisterCol, idpEvent.AutoRegister),
|
||||
handler.NewCol(IDPOwnerTypeCol, idpOwnerType),
|
||||
},
|
||||
), nil
|
||||
}
|
||||
|
||||
func (p *IDPProjection) reduceIDPChanged(event eventstore.EventReader) (*handler.Statement, error) {
|
||||
var idpEvent idpconfig.IDPConfigChangedEvent
|
||||
switch e := event.(type) {
|
||||
case *org.IDPConfigChangedEvent:
|
||||
idpEvent = e.IDPConfigChangedEvent
|
||||
case *iam.IDPConfigChangedEvent:
|
||||
idpEvent = e.IDPConfigChangedEvent
|
||||
default:
|
||||
logging.LogWithFields("HANDL-FFrph", "seq", e.Sequence(), "expectedTypes", []eventstore.EventType{org.IDPConfigChangedEventType, iam.IDPConfigChangedEventType}).Error("wrong event type")
|
||||
return nil, errors.ThrowInvalidArgument(nil, "HANDL-NVvJD", "reduce.wrong.event.type")
|
||||
}
|
||||
|
||||
cols := make([]handler.Column, 0, 5)
|
||||
if idpEvent.Name != nil {
|
||||
cols = append(cols, handler.NewCol(IDPNameCol, *idpEvent.Name))
|
||||
}
|
||||
if idpEvent.StylingType != nil {
|
||||
cols = append(cols, handler.NewCol(IDPStylingTypeCol, *idpEvent.StylingType))
|
||||
}
|
||||
if idpEvent.AutoRegister != nil {
|
||||
cols = append(cols, handler.NewCol(IDPAutoRegisterCol, *idpEvent.AutoRegister))
|
||||
}
|
||||
if len(cols) == 0 {
|
||||
return crdb.NewNoOpStatement(&idpEvent), nil
|
||||
}
|
||||
|
||||
cols = append(cols,
|
||||
handler.NewCol(IDPChangeDateCol, idpEvent.CreationDate()),
|
||||
handler.NewCol(IDPSequenceCol, idpEvent.Sequence()),
|
||||
)
|
||||
|
||||
return crdb.NewUpdateStatement(
|
||||
&idpEvent,
|
||||
cols,
|
||||
[]handler.Condition{
|
||||
handler.NewCond(IDPIDCol, idpEvent.ConfigID),
|
||||
},
|
||||
), nil
|
||||
}
|
||||
|
||||
func (p *IDPProjection) reduceIDPDeactivated(event eventstore.EventReader) (*handler.Statement, error) {
|
||||
var idpEvent idpconfig.IDPConfigDeactivatedEvent
|
||||
switch e := event.(type) {
|
||||
case *org.IDPConfigDeactivatedEvent:
|
||||
idpEvent = e.IDPConfigDeactivatedEvent
|
||||
case *iam.IDPConfigDeactivatedEvent:
|
||||
idpEvent = e.IDPConfigDeactivatedEvent
|
||||
default:
|
||||
logging.LogWithFields("HANDL-1s33a", "seq", e.Sequence(), "expectedTypes", []eventstore.EventType{org.IDPConfigDeactivatedEventType, iam.IDPConfigDeactivatedEventType}).Error("wrong event type")
|
||||
return nil, errors.ThrowInvalidArgument(nil, "HANDL-94O5l", "reduce.wrong.event.type")
|
||||
}
|
||||
|
||||
return crdb.NewUpdateStatement(
|
||||
&idpEvent,
|
||||
[]handler.Column{
|
||||
handler.NewCol(IDPStateCol, domain.IDPConfigStateInactive),
|
||||
handler.NewCol(IDPChangeDateCol, idpEvent.CreationDate()),
|
||||
handler.NewCol(IDPSequenceCol, idpEvent.Sequence()),
|
||||
},
|
||||
[]handler.Condition{
|
||||
handler.NewCond(IDPIDCol, idpEvent.ConfigID),
|
||||
},
|
||||
), nil
|
||||
}
|
||||
|
||||
func (p *IDPProjection) reduceIDPReactivated(event eventstore.EventReader) (*handler.Statement, error) {
|
||||
var idpEvent idpconfig.IDPConfigReactivatedEvent
|
||||
switch e := event.(type) {
|
||||
case *org.IDPConfigReactivatedEvent:
|
||||
idpEvent = e.IDPConfigReactivatedEvent
|
||||
case *iam.IDPConfigReactivatedEvent:
|
||||
idpEvent = e.IDPConfigReactivatedEvent
|
||||
default:
|
||||
logging.LogWithFields("HANDL-Zgzpt", "seq", e.Sequence(), "expectedTypes", []eventstore.EventType{org.IDPConfigReactivatedEventType, iam.IDPConfigReactivatedEventType}).Error("wrong event type")
|
||||
return nil, errors.ThrowInvalidArgument(nil, "HANDL-I8QyS", "reduce.wrong.event.type")
|
||||
}
|
||||
|
||||
return crdb.NewUpdateStatement(
|
||||
&idpEvent,
|
||||
[]handler.Column{
|
||||
handler.NewCol(IDPStateCol, domain.IDPConfigStateActive),
|
||||
handler.NewCol(IDPChangeDateCol, idpEvent.CreationDate()),
|
||||
handler.NewCol(IDPSequenceCol, idpEvent.Sequence()),
|
||||
},
|
||||
[]handler.Condition{
|
||||
handler.NewCond(IDPIDCol, idpEvent.ConfigID),
|
||||
},
|
||||
), nil
|
||||
}
|
||||
|
||||
func (p *IDPProjection) reduceIDPRemoved(event eventstore.EventReader) (*handler.Statement, error) {
|
||||
var idpEvent idpconfig.IDPConfigRemovedEvent
|
||||
switch e := event.(type) {
|
||||
case *org.IDPConfigRemovedEvent:
|
||||
idpEvent = e.IDPConfigRemovedEvent
|
||||
case *iam.IDPConfigRemovedEvent:
|
||||
idpEvent = e.IDPConfigRemovedEvent
|
||||
default:
|
||||
logging.LogWithFields("HANDL-JJasT", "seq", e.Sequence(), "expectedTypes", []eventstore.EventType{org.IDPConfigRemovedEventType, iam.IDPConfigRemovedEventType}).Error("wrong event type")
|
||||
return nil, errors.ThrowInvalidArgument(nil, "HANDL-B4zy8", "reduce.wrong.event.type")
|
||||
}
|
||||
|
||||
return crdb.NewDeleteStatement(
|
||||
&idpEvent,
|
||||
[]handler.Condition{
|
||||
handler.NewCond(IDPIDCol, idpEvent.ConfigID),
|
||||
},
|
||||
), nil
|
||||
}
|
||||
|
||||
func (p *IDPProjection) reduceOIDCConfigAdded(event eventstore.EventReader) (*handler.Statement, error) {
|
||||
var idpEvent idpconfig.OIDCConfigAddedEvent
|
||||
switch e := event.(type) {
|
||||
case *org.IDPOIDCConfigAddedEvent:
|
||||
idpEvent = e.OIDCConfigAddedEvent
|
||||
case *iam.IDPOIDCConfigAddedEvent:
|
||||
idpEvent = e.OIDCConfigAddedEvent
|
||||
default:
|
||||
logging.LogWithFields("HANDL-DCmeB", "seq", e.Sequence(), "expectedTypes", []eventstore.EventType{org.IDPOIDCConfigAddedEventType, iam.IDPOIDCConfigAddedEventType}).Error("wrong event type")
|
||||
return nil, errors.ThrowInvalidArgument(nil, "HANDL-2FuAA", "reduce.wrong.event.type")
|
||||
}
|
||||
|
||||
return crdb.NewMultiStatement(&idpEvent,
|
||||
crdb.AddUpdateStatement(
|
||||
[]handler.Column{
|
||||
handler.NewCol(IDPChangeDateCol, idpEvent.CreationDate()),
|
||||
handler.NewCol(IDPSequenceCol, idpEvent.Sequence()),
|
||||
},
|
||||
[]handler.Condition{
|
||||
handler.NewCond(IDPIDCol, idpEvent.IDPConfigID),
|
||||
},
|
||||
),
|
||||
crdb.AddCreateStatement(
|
||||
[]handler.Column{
|
||||
handler.NewCol(OIDCConfigIDPIDCol, idpEvent.IDPConfigID),
|
||||
handler.NewCol(OIDCConfigClientIDCol, idpEvent.ClientID),
|
||||
handler.NewCol(OIDCConfigClientSecretCol, idpEvent.ClientSecret),
|
||||
handler.NewCol(OIDCConfigIssuerCol, idpEvent.Issuer),
|
||||
handler.NewCol(OIDCConfigScopesCol, pq.StringArray(idpEvent.Scopes)),
|
||||
handler.NewCol(OIDCConfigDisplayNameMappingCol, idpEvent.IDPDisplayNameMapping),
|
||||
handler.NewCol(OIDCConfigUsernameMappingCol, idpEvent.UserNameMapping),
|
||||
handler.NewCol(OIDCConfigAuthorizationEndpointCol, idpEvent.AuthorizationEndpoint),
|
||||
handler.NewCol(OIDCConfigTokenEndpointCol, idpEvent.TokenEndpoint),
|
||||
},
|
||||
crdb.WithTableSuffix(IDPOIDCSuffix),
|
||||
),
|
||||
), nil
|
||||
}
|
||||
|
||||
func (p *IDPProjection) reduceOIDCConfigChanged(event eventstore.EventReader) (*handler.Statement, error) {
|
||||
var idpEvent idpconfig.OIDCConfigChangedEvent
|
||||
switch e := event.(type) {
|
||||
case *org.IDPOIDCConfigChangedEvent:
|
||||
idpEvent = e.OIDCConfigChangedEvent
|
||||
case *iam.IDPOIDCConfigChangedEvent:
|
||||
idpEvent = e.OIDCConfigChangedEvent
|
||||
default:
|
||||
logging.LogWithFields("HANDL-VyBm2", "seq", e.Sequence(), "expectedTypes", []eventstore.EventType{org.IDPOIDCConfigChangedEventType, iam.IDPOIDCConfigChangedEventType}).Error("wrong event type")
|
||||
return nil, errors.ThrowInvalidArgument(nil, "HANDL-x2IVI", "reduce.wrong.event.type")
|
||||
}
|
||||
|
||||
cols := make([]handler.Column, 0, 8)
|
||||
|
||||
if idpEvent.ClientID != nil {
|
||||
cols = append(cols, handler.NewCol(OIDCConfigClientIDCol, *idpEvent.ClientID))
|
||||
}
|
||||
if idpEvent.ClientSecret != nil {
|
||||
cols = append(cols, handler.NewCol(OIDCConfigClientSecretCol, *idpEvent.ClientSecret))
|
||||
}
|
||||
if idpEvent.Issuer != nil {
|
||||
cols = append(cols, handler.NewCol(OIDCConfigIssuerCol, *idpEvent.Issuer))
|
||||
}
|
||||
if idpEvent.AuthorizationEndpoint != nil {
|
||||
cols = append(cols, handler.NewCol(OIDCConfigAuthorizationEndpointCol, *idpEvent.AuthorizationEndpoint))
|
||||
}
|
||||
if idpEvent.TokenEndpoint != nil {
|
||||
cols = append(cols, handler.NewCol(OIDCConfigTokenEndpointCol, *idpEvent.TokenEndpoint))
|
||||
}
|
||||
if idpEvent.Scopes != nil {
|
||||
cols = append(cols, handler.NewCol(OIDCConfigScopesCol, pq.StringArray(idpEvent.Scopes)))
|
||||
}
|
||||
if idpEvent.IDPDisplayNameMapping != nil {
|
||||
cols = append(cols, handler.NewCol(OIDCConfigDisplayNameMappingCol, *idpEvent.IDPDisplayNameMapping))
|
||||
}
|
||||
if idpEvent.UserNameMapping != nil {
|
||||
cols = append(cols, handler.NewCol(OIDCConfigUsernameMappingCol, *idpEvent.UserNameMapping))
|
||||
}
|
||||
|
||||
if len(cols) == 0 {
|
||||
return crdb.NewNoOpStatement(&idpEvent), nil
|
||||
}
|
||||
|
||||
return crdb.NewMultiStatement(&idpEvent,
|
||||
crdb.AddUpdateStatement(
|
||||
[]handler.Column{
|
||||
handler.NewCol(IDPChangeDateCol, idpEvent.CreationDate()),
|
||||
handler.NewCol(IDPSequenceCol, idpEvent.Sequence()),
|
||||
},
|
||||
[]handler.Condition{
|
||||
handler.NewCond(IDPIDCol, idpEvent.IDPConfigID),
|
||||
},
|
||||
),
|
||||
crdb.AddUpdateStatement(
|
||||
cols,
|
||||
[]handler.Condition{
|
||||
handler.NewCond(OIDCConfigIDPIDCol, idpEvent.IDPConfigID),
|
||||
},
|
||||
crdb.WithTableSuffix(IDPOIDCSuffix),
|
||||
),
|
||||
), nil
|
||||
}
|
||||
|
||||
func (p *IDPProjection) reduceJWTConfigAdded(event eventstore.EventReader) (*handler.Statement, error) {
|
||||
var idpEvent idpconfig.JWTConfigAddedEvent
|
||||
switch e := event.(type) {
|
||||
case *org.IDPJWTConfigAddedEvent:
|
||||
idpEvent = e.JWTConfigAddedEvent
|
||||
case *iam.IDPJWTConfigAddedEvent:
|
||||
idpEvent = e.JWTConfigAddedEvent
|
||||
default:
|
||||
logging.LogWithFields("HANDL-228q7", "seq", e.Sequence(), "expectedTypes", []eventstore.EventType{org.IDPJWTConfigAddedEventType, iam.IDPJWTConfigAddedEventType}).Error("wrong event type")
|
||||
return nil, errors.ThrowInvalidArgument(nil, "HANDL-qvPdb", "reduce.wrong.event.type")
|
||||
}
|
||||
|
||||
return crdb.NewMultiStatement(&idpEvent,
|
||||
crdb.AddUpdateStatement(
|
||||
[]handler.Column{
|
||||
handler.NewCol(IDPChangeDateCol, idpEvent.CreationDate()),
|
||||
handler.NewCol(IDPSequenceCol, idpEvent.Sequence()),
|
||||
},
|
||||
[]handler.Condition{
|
||||
handler.NewCond(IDPIDCol, idpEvent.IDPConfigID),
|
||||
},
|
||||
),
|
||||
|
||||
crdb.AddCreateStatement(
|
||||
[]handler.Column{
|
||||
handler.NewCol(OIDCConfigIDPIDCol, idpEvent.IDPConfigID),
|
||||
handler.NewCol(JWTConfigEndpointCol, idpEvent.JWTEndpoint),
|
||||
handler.NewCol(JWTConfigIssuerCol, idpEvent.Issuer),
|
||||
handler.NewCol(JWTConfigKeysEndpointCol, idpEvent.KeysEndpoint),
|
||||
handler.NewCol(JWTConfigHeaderNameCol, idpEvent.HeaderName),
|
||||
},
|
||||
crdb.WithTableSuffix(IDPJWTSuffix),
|
||||
),
|
||||
), nil
|
||||
}
|
||||
|
||||
func (p *IDPProjection) reduceJWTConfigChanged(event eventstore.EventReader) (*handler.Statement, error) {
|
||||
var idpEvent idpconfig.JWTConfigChangedEvent
|
||||
switch e := event.(type) {
|
||||
case *org.IDPJWTConfigChangedEvent:
|
||||
idpEvent = e.JWTConfigChangedEvent
|
||||
case *iam.IDPJWTConfigChangedEvent:
|
||||
idpEvent = e.JWTConfigChangedEvent
|
||||
default:
|
||||
logging.LogWithFields("HANDL-VyBm2", "seq", e.Sequence(), "expectedTypes", []eventstore.EventType{org.IDPJWTConfigChangedEventType, iam.IDPJWTConfigChangedEventType}).Error("wrong event type")
|
||||
return nil, errors.ThrowInvalidArgument(nil, "HANDL-x2IVI", "reduce.wrong.event.type")
|
||||
}
|
||||
|
||||
cols := make([]handler.Column, 0, 4)
|
||||
|
||||
if idpEvent.JWTEndpoint != nil {
|
||||
cols = append(cols, handler.NewCol(JWTConfigEndpointCol, *idpEvent.JWTEndpoint))
|
||||
}
|
||||
if idpEvent.Issuer != nil {
|
||||
cols = append(cols, handler.NewCol(JWTConfigIssuerCol, *idpEvent.Issuer))
|
||||
}
|
||||
if idpEvent.KeysEndpoint != nil {
|
||||
cols = append(cols, handler.NewCol(JWTConfigKeysEndpointCol, *idpEvent.KeysEndpoint))
|
||||
}
|
||||
if idpEvent.HeaderName != nil {
|
||||
cols = append(cols, handler.NewCol(JWTConfigHeaderNameCol, *idpEvent.HeaderName))
|
||||
}
|
||||
|
||||
if len(cols) == 0 {
|
||||
return crdb.NewNoOpStatement(&idpEvent), nil
|
||||
}
|
||||
|
||||
return crdb.NewMultiStatement(&idpEvent,
|
||||
crdb.AddUpdateStatement(
|
||||
[]handler.Column{
|
||||
handler.NewCol(IDPChangeDateCol, idpEvent.CreationDate()),
|
||||
handler.NewCol(IDPSequenceCol, idpEvent.Sequence()),
|
||||
},
|
||||
[]handler.Condition{
|
||||
handler.NewCond(IDPIDCol, idpEvent.IDPConfigID),
|
||||
},
|
||||
),
|
||||
crdb.AddUpdateStatement(
|
||||
cols,
|
||||
[]handler.Condition{
|
||||
handler.NewCond(OIDCConfigIDPIDCol, idpEvent.IDPConfigID),
|
||||
},
|
||||
crdb.WithTableSuffix(IDPJWTSuffix),
|
||||
),
|
||||
), nil
|
||||
}
|
872
internal/query/projection/idp_test.go
Normal file
872
internal/query/projection/idp_test.go
Normal file
@ -0,0 +1,872 @@
|
||||
package projection
|
||||
|
||||
import (
|
||||
"testing"
|
||||
|
||||
"github.com/caos/zitadel/internal/domain"
|
||||
"github.com/caos/zitadel/internal/errors"
|
||||
"github.com/caos/zitadel/internal/eventstore"
|
||||
"github.com/caos/zitadel/internal/eventstore/handler"
|
||||
"github.com/caos/zitadel/internal/eventstore/repository"
|
||||
"github.com/caos/zitadel/internal/repository/iam"
|
||||
"github.com/caos/zitadel/internal/repository/org"
|
||||
"github.com/lib/pq"
|
||||
)
|
||||
|
||||
func TestIDPProjection_reduces(t *testing.T) {
|
||||
type args struct {
|
||||
event func(t *testing.T) eventstore.EventReader
|
||||
}
|
||||
tests := []struct {
|
||||
name string
|
||||
args args
|
||||
reduce func(event eventstore.EventReader) (*handler.Statement, error)
|
||||
want wantReduce
|
||||
}{
|
||||
{
|
||||
name: "iam.reduceIDPAdded",
|
||||
args: args{
|
||||
event: getEvent(testEvent(
|
||||
repository.EventType(iam.IDPConfigAddedEventType),
|
||||
iam.AggregateType,
|
||||
[]byte(`{
|
||||
"idpConfigId": "idp-config-id",
|
||||
"name": "custom-zitadel-instance",
|
||||
"idpType": 0,
|
||||
"stylingType": 0,
|
||||
"autoRegister": true
|
||||
}`),
|
||||
), iam.IDPConfigAddedEventMapper),
|
||||
},
|
||||
reduce: (&IDPProjection{}).reduceIDPAdded,
|
||||
want: wantReduce{
|
||||
aggregateType: eventstore.AggregateType("iam"),
|
||||
sequence: 15,
|
||||
previousSequence: 10,
|
||||
projection: IDPTable,
|
||||
executer: &testExecuter{
|
||||
executions: []execution{
|
||||
{
|
||||
expectedStmt: "INSERT INTO zitadel.projections.idps (id, creation_date, change_date, sequence, resource_owner, state, name, styling_type, auto_register, owner_type) VALUES ($1, $2, $3, $4, $5, $6, $7, $8, $9, $10)",
|
||||
expectedArgs: []interface{}{
|
||||
"idp-config-id",
|
||||
anyArg{},
|
||||
anyArg{},
|
||||
uint64(15),
|
||||
"ro-id",
|
||||
domain.IDPConfigStateActive,
|
||||
"custom-zitadel-instance",
|
||||
domain.IDPConfigStylingTypeUnspecified,
|
||||
true,
|
||||
domain.IdentityProviderTypeSystem,
|
||||
},
|
||||
},
|
||||
},
|
||||
},
|
||||
},
|
||||
},
|
||||
{
|
||||
name: "iam.reduceIDPChanged",
|
||||
args: args{
|
||||
event: getEvent(testEvent(
|
||||
repository.EventType(iam.IDPConfigChangedEventType),
|
||||
iam.AggregateType,
|
||||
[]byte(`{
|
||||
"idpConfigId": "idp-config-id",
|
||||
"name": "custom-zitadel-instance",
|
||||
"stylingType": 1,
|
||||
"autoRegister": true
|
||||
}`),
|
||||
), iam.IDPConfigChangedEventMapper),
|
||||
},
|
||||
reduce: (&IDPProjection{}).reduceIDPChanged,
|
||||
want: wantReduce{
|
||||
aggregateType: eventstore.AggregateType("iam"),
|
||||
sequence: 15,
|
||||
previousSequence: 10,
|
||||
projection: IDPTable,
|
||||
executer: &testExecuter{
|
||||
executions: []execution{
|
||||
{
|
||||
expectedStmt: "UPDATE zitadel.projections.idps SET (name, styling_type, auto_register, change_date, sequence) = ($1, $2, $3, $4, $5) WHERE (id = $6)",
|
||||
expectedArgs: []interface{}{
|
||||
"custom-zitadel-instance",
|
||||
domain.IDPConfigStylingTypeGoogle,
|
||||
true,
|
||||
anyArg{},
|
||||
uint64(15),
|
||||
"idp-config-id",
|
||||
},
|
||||
},
|
||||
},
|
||||
},
|
||||
},
|
||||
},
|
||||
{
|
||||
name: "iam.reduceIDPDeactivated",
|
||||
args: args{
|
||||
event: getEvent(testEvent(
|
||||
repository.EventType(iam.IDPConfigDeactivatedEventType),
|
||||
iam.AggregateType,
|
||||
[]byte(`{
|
||||
"idpConfigId": "idp-config-id"
|
||||
}`),
|
||||
), iam.IDPConfigDeactivatedEventMapper),
|
||||
},
|
||||
reduce: (&IDPProjection{}).reduceIDPDeactivated,
|
||||
want: wantReduce{
|
||||
aggregateType: eventstore.AggregateType("iam"),
|
||||
sequence: 15,
|
||||
previousSequence: 10,
|
||||
projection: IDPTable,
|
||||
executer: &testExecuter{
|
||||
executions: []execution{
|
||||
{
|
||||
expectedStmt: "UPDATE zitadel.projections.idps SET (state, change_date, sequence) = ($1, $2, $3) WHERE (id = $4)",
|
||||
expectedArgs: []interface{}{
|
||||
domain.IDPConfigStateInactive,
|
||||
anyArg{},
|
||||
uint64(15),
|
||||
"idp-config-id",
|
||||
},
|
||||
},
|
||||
},
|
||||
},
|
||||
},
|
||||
},
|
||||
{
|
||||
name: "iam.reduceIDPReactivated",
|
||||
args: args{
|
||||
event: getEvent(testEvent(
|
||||
repository.EventType(iam.IDPConfigReactivatedEventType),
|
||||
iam.AggregateType,
|
||||
[]byte(`{
|
||||
"idpConfigId": "idp-config-id"
|
||||
}`),
|
||||
), iam.IDPConfigReactivatedEventMapper),
|
||||
},
|
||||
reduce: (&IDPProjection{}).reduceIDPReactivated,
|
||||
want: wantReduce{
|
||||
aggregateType: eventstore.AggregateType("iam"),
|
||||
sequence: 15,
|
||||
previousSequence: 10,
|
||||
projection: IDPTable,
|
||||
executer: &testExecuter{
|
||||
executions: []execution{
|
||||
{
|
||||
expectedStmt: "UPDATE zitadel.projections.idps SET (state, change_date, sequence) = ($1, $2, $3) WHERE (id = $4)",
|
||||
expectedArgs: []interface{}{
|
||||
domain.IDPConfigStateActive,
|
||||
anyArg{},
|
||||
uint64(15),
|
||||
"idp-config-id",
|
||||
},
|
||||
},
|
||||
},
|
||||
},
|
||||
},
|
||||
},
|
||||
{
|
||||
name: "iam.reduceIDPRemoved",
|
||||
args: args{
|
||||
event: getEvent(testEvent(
|
||||
repository.EventType(iam.IDPConfigRemovedEventType),
|
||||
iam.AggregateType,
|
||||
[]byte(`{
|
||||
"idpConfigId": "idp-config-id"
|
||||
}`),
|
||||
), iam.IDPConfigRemovedEventMapper),
|
||||
},
|
||||
reduce: (&IDPProjection{}).reduceIDPRemoved,
|
||||
want: wantReduce{
|
||||
aggregateType: eventstore.AggregateType("iam"),
|
||||
sequence: 15,
|
||||
previousSequence: 10,
|
||||
projection: IDPTable,
|
||||
executer: &testExecuter{
|
||||
executions: []execution{
|
||||
{
|
||||
expectedStmt: "DELETE FROM zitadel.projections.idps WHERE (id = $1)",
|
||||
expectedArgs: []interface{}{
|
||||
"idp-config-id",
|
||||
},
|
||||
},
|
||||
},
|
||||
},
|
||||
},
|
||||
},
|
||||
{
|
||||
name: "iam.reduceOIDCConfigAdded",
|
||||
args: args{
|
||||
event: getEvent(testEvent(
|
||||
repository.EventType(iam.IDPOIDCConfigAddedEventType),
|
||||
iam.AggregateType,
|
||||
[]byte(`{
|
||||
"idpConfigId": "idp-config-id",
|
||||
"clientId": "client-id",
|
||||
"clientSecret": {
|
||||
"cryptoType": 0,
|
||||
"algorithm": "RSA-265",
|
||||
"keyId": "key-id"
|
||||
},
|
||||
"issuer": "issuer",
|
||||
"authorizationEndpoint": "https://api.zitadel.ch/authorize",
|
||||
"tokenEndpoint": "https://api.zitadel.ch/token",
|
||||
"scopes": ["profile"],
|
||||
"idpDisplayNameMapping": 0,
|
||||
"usernameMapping": 1
|
||||
}`),
|
||||
), iam.IDPOIDCConfigAddedEventMapper),
|
||||
},
|
||||
reduce: (&IDPProjection{}).reduceOIDCConfigAdded,
|
||||
want: wantReduce{
|
||||
aggregateType: eventstore.AggregateType("iam"),
|
||||
sequence: 15,
|
||||
previousSequence: 10,
|
||||
projection: IDPTable,
|
||||
executer: &testExecuter{
|
||||
executions: []execution{
|
||||
{
|
||||
expectedStmt: "UPDATE zitadel.projections.idps SET (change_date, sequence) = ($1, $2) WHERE (id = $3)",
|
||||
expectedArgs: []interface{}{
|
||||
anyArg{},
|
||||
uint64(15),
|
||||
"idp-config-id",
|
||||
},
|
||||
},
|
||||
{
|
||||
expectedStmt: "INSERT INTO zitadel.projections.idps_oidc_config (idp_id, client_id, client_secret, issuer, scopes, display_name_mapping, username_mapping, authorization_endpoint, token_endpoint) VALUES ($1, $2, $3, $4, $5, $6, $7, $8, $9)",
|
||||
expectedArgs: []interface{}{
|
||||
"idp-config-id",
|
||||
"client-id",
|
||||
anyArg{},
|
||||
"issuer",
|
||||
pq.StringArray{"profile"},
|
||||
domain.OIDCMappingFieldUnspecified,
|
||||
domain.OIDCMappingFieldPreferredLoginName,
|
||||
"https://api.zitadel.ch/authorize",
|
||||
"https://api.zitadel.ch/token",
|
||||
},
|
||||
},
|
||||
},
|
||||
},
|
||||
},
|
||||
},
|
||||
{
|
||||
name: "iam.reduceOIDCConfigChanged",
|
||||
args: args{
|
||||
event: getEvent(testEvent(
|
||||
repository.EventType(iam.IDPOIDCConfigChangedEventType),
|
||||
iam.AggregateType,
|
||||
[]byte(`{
|
||||
"idpConfigId": "idp-config-id",
|
||||
"clientId": "client-id",
|
||||
"clientSecret": {
|
||||
"cryptoType": 0,
|
||||
"algorithm": "RSA-265",
|
||||
"keyId": "key-id"
|
||||
},
|
||||
"issuer": "issuer",
|
||||
"authorizationEndpoint": "https://api.zitadel.ch/authorize",
|
||||
"tokenEndpoint": "https://api.zitadel.ch/token",
|
||||
"scopes": ["profile"],
|
||||
"idpDisplayNameMapping": 0,
|
||||
"usernameMapping": 1
|
||||
}`),
|
||||
), iam.IDPOIDCConfigChangedEventMapper),
|
||||
},
|
||||
reduce: (&IDPProjection{}).reduceOIDCConfigChanged,
|
||||
want: wantReduce{
|
||||
aggregateType: eventstore.AggregateType("iam"),
|
||||
sequence: 15,
|
||||
previousSequence: 10,
|
||||
projection: IDPTable,
|
||||
executer: &testExecuter{
|
||||
executions: []execution{
|
||||
{
|
||||
expectedStmt: "UPDATE zitadel.projections.idps SET (change_date, sequence) = ($1, $2) WHERE (id = $3)",
|
||||
expectedArgs: []interface{}{
|
||||
anyArg{},
|
||||
uint64(15),
|
||||
"idp-config-id",
|
||||
},
|
||||
},
|
||||
{
|
||||
expectedStmt: "UPDATE zitadel.projections.idps_oidc_config SET (client_id, client_secret, issuer, authorization_endpoint, token_endpoint, scopes, display_name_mapping, username_mapping) = ($1, $2, $3, $4, $5, $6, $7, $8) WHERE (idp_id = $9)",
|
||||
expectedArgs: []interface{}{
|
||||
"client-id",
|
||||
anyArg{},
|
||||
"issuer",
|
||||
"https://api.zitadel.ch/authorize",
|
||||
"https://api.zitadel.ch/token",
|
||||
pq.StringArray{"profile"},
|
||||
domain.OIDCMappingFieldUnspecified,
|
||||
domain.OIDCMappingFieldPreferredLoginName,
|
||||
"idp-config-id",
|
||||
},
|
||||
},
|
||||
},
|
||||
},
|
||||
},
|
||||
},
|
||||
{
|
||||
name: "iam.reduceOIDCConfigChanged: no op",
|
||||
args: args{
|
||||
event: getEvent(testEvent(
|
||||
repository.EventType(iam.IDPOIDCConfigChangedEventType),
|
||||
iam.AggregateType,
|
||||
[]byte("{}"),
|
||||
), iam.IDPOIDCConfigChangedEventMapper),
|
||||
},
|
||||
reduce: (&IDPProjection{}).reduceOIDCConfigChanged,
|
||||
want: wantReduce{
|
||||
aggregateType: eventstore.AggregateType("iam"),
|
||||
sequence: 15,
|
||||
previousSequence: 10,
|
||||
projection: IDPTable,
|
||||
executer: &testExecuter{
|
||||
executions: []execution{},
|
||||
},
|
||||
},
|
||||
},
|
||||
{
|
||||
name: "iam.reduceJWTConfigAdded",
|
||||
args: args{
|
||||
event: getEvent(testEvent(
|
||||
repository.EventType(iam.IDPJWTConfigAddedEventType),
|
||||
iam.AggregateType,
|
||||
[]byte(`{
|
||||
"idpConfigId": "idp-config-id",
|
||||
"jwtEndpoint": "https://api.zitadel.ch/jwt",
|
||||
"issuer": "issuer",
|
||||
"keysEndpoint": "https://api.zitadel.ch/keys",
|
||||
"headerName": "hodor"
|
||||
}`),
|
||||
), iam.IDPJWTConfigAddedEventMapper),
|
||||
},
|
||||
reduce: (&IDPProjection{}).reduceJWTConfigAdded,
|
||||
want: wantReduce{
|
||||
aggregateType: eventstore.AggregateType("iam"),
|
||||
sequence: 15,
|
||||
previousSequence: 10,
|
||||
projection: IDPTable,
|
||||
executer: &testExecuter{
|
||||
executions: []execution{
|
||||
{
|
||||
expectedStmt: "UPDATE zitadel.projections.idps SET (change_date, sequence) = ($1, $2) WHERE (id = $3)",
|
||||
expectedArgs: []interface{}{
|
||||
anyArg{},
|
||||
uint64(15),
|
||||
"idp-config-id",
|
||||
},
|
||||
},
|
||||
{
|
||||
expectedStmt: "INSERT INTO zitadel.projections.idps_jwt_config (idp_id, endpoint, issuer, keys_endpoint, header_name) VALUES ($1, $2, $3, $4, $5)",
|
||||
expectedArgs: []interface{}{
|
||||
"idp-config-id",
|
||||
"https://api.zitadel.ch/jwt",
|
||||
"issuer",
|
||||
"https://api.zitadel.ch/keys",
|
||||
"hodor",
|
||||
},
|
||||
},
|
||||
},
|
||||
},
|
||||
},
|
||||
},
|
||||
{
|
||||
name: "iam.reduceJWTConfigChanged",
|
||||
args: args{
|
||||
event: getEvent(testEvent(
|
||||
repository.EventType(iam.IDPJWTConfigChangedEventType),
|
||||
iam.AggregateType,
|
||||
[]byte(`{
|
||||
"idpConfigId": "idp-config-id",
|
||||
"jwtEndpoint": "https://api.zitadel.ch/jwt",
|
||||
"issuer": "issuer",
|
||||
"keysEndpoint": "https://api.zitadel.ch/keys",
|
||||
"headerName": "hodor"
|
||||
}`),
|
||||
), iam.IDPJWTConfigChangedEventMapper),
|
||||
},
|
||||
reduce: (&IDPProjection{}).reduceJWTConfigChanged,
|
||||
want: wantReduce{
|
||||
aggregateType: eventstore.AggregateType("iam"),
|
||||
sequence: 15,
|
||||
previousSequence: 10,
|
||||
projection: IDPTable,
|
||||
executer: &testExecuter{
|
||||
executions: []execution{
|
||||
{
|
||||
expectedStmt: "UPDATE zitadel.projections.idps SET (change_date, sequence) = ($1, $2) WHERE (id = $3)",
|
||||
expectedArgs: []interface{}{
|
||||
anyArg{},
|
||||
uint64(15),
|
||||
"idp-config-id",
|
||||
},
|
||||
},
|
||||
{
|
||||
expectedStmt: "UPDATE zitadel.projections.idps_jwt_config SET (endpoint, issuer, keys_endpoint, header_name) = ($1, $2, $3, $4) WHERE (idp_id = $5)",
|
||||
expectedArgs: []interface{}{
|
||||
"https://api.zitadel.ch/jwt",
|
||||
"issuer",
|
||||
"https://api.zitadel.ch/keys",
|
||||
"hodor",
|
||||
"idp-config-id",
|
||||
},
|
||||
},
|
||||
},
|
||||
},
|
||||
},
|
||||
},
|
||||
{
|
||||
name: "iam.reduceJWTConfigChanged: no op",
|
||||
args: args{
|
||||
event: getEvent(testEvent(
|
||||
repository.EventType(iam.IDPJWTConfigChangedEventType),
|
||||
iam.AggregateType,
|
||||
[]byte(`{}`),
|
||||
), iam.IDPJWTConfigChangedEventMapper),
|
||||
},
|
||||
reduce: (&IDPProjection{}).reduceJWTConfigChanged,
|
||||
want: wantReduce{
|
||||
aggregateType: eventstore.AggregateType("iam"),
|
||||
sequence: 15,
|
||||
previousSequence: 10,
|
||||
projection: IDPTable,
|
||||
executer: &testExecuter{
|
||||
executions: []execution{},
|
||||
},
|
||||
},
|
||||
},
|
||||
{
|
||||
name: "org.reduceIDPAdded",
|
||||
args: args{
|
||||
event: getEvent(testEvent(
|
||||
repository.EventType(org.IDPConfigAddedEventType),
|
||||
org.AggregateType,
|
||||
[]byte(`{
|
||||
"idpConfigId": "idp-config-id",
|
||||
"name": "custom-zitadel-instance",
|
||||
"idpType": 0,
|
||||
"stylingType": 0,
|
||||
"autoRegister": true
|
||||
}`),
|
||||
), org.IDPConfigAddedEventMapper),
|
||||
},
|
||||
reduce: (&IDPProjection{}).reduceIDPAdded,
|
||||
want: wantReduce{
|
||||
aggregateType: eventstore.AggregateType("org"),
|
||||
sequence: 15,
|
||||
previousSequence: 10,
|
||||
projection: IDPTable,
|
||||
executer: &testExecuter{
|
||||
executions: []execution{
|
||||
{
|
||||
expectedStmt: "INSERT INTO zitadel.projections.idps (id, creation_date, change_date, sequence, resource_owner, state, name, styling_type, auto_register, owner_type) VALUES ($1, $2, $3, $4, $5, $6, $7, $8, $9, $10)",
|
||||
expectedArgs: []interface{}{
|
||||
"idp-config-id",
|
||||
anyArg{},
|
||||
anyArg{},
|
||||
uint64(15),
|
||||
"ro-id",
|
||||
domain.IDPConfigStateActive,
|
||||
"custom-zitadel-instance",
|
||||
domain.IDPConfigStylingTypeUnspecified,
|
||||
true,
|
||||
domain.IdentityProviderTypeOrg,
|
||||
},
|
||||
},
|
||||
},
|
||||
},
|
||||
},
|
||||
},
|
||||
{
|
||||
name: "org.reduceIDPChanged",
|
||||
args: args{
|
||||
event: getEvent(testEvent(
|
||||
repository.EventType(org.IDPConfigChangedEventType),
|
||||
org.AggregateType,
|
||||
[]byte(`{
|
||||
"idpConfigId": "idp-config-id",
|
||||
"name": "custom-zitadel-instance",
|
||||
"stylingType": 1,
|
||||
"autoRegister": true
|
||||
}`),
|
||||
), org.IDPConfigChangedEventMapper),
|
||||
},
|
||||
reduce: (&IDPProjection{}).reduceIDPChanged,
|
||||
want: wantReduce{
|
||||
aggregateType: eventstore.AggregateType("org"),
|
||||
sequence: 15,
|
||||
previousSequence: 10,
|
||||
projection: IDPTable,
|
||||
executer: &testExecuter{
|
||||
executions: []execution{
|
||||
{
|
||||
expectedStmt: "UPDATE zitadel.projections.idps SET (name, styling_type, auto_register, change_date, sequence) = ($1, $2, $3, $4, $5) WHERE (id = $6)",
|
||||
expectedArgs: []interface{}{
|
||||
"custom-zitadel-instance",
|
||||
domain.IDPConfigStylingTypeGoogle,
|
||||
true,
|
||||
anyArg{},
|
||||
uint64(15),
|
||||
"idp-config-id",
|
||||
},
|
||||
},
|
||||
},
|
||||
},
|
||||
},
|
||||
},
|
||||
{
|
||||
name: "org.reduceIDPDeactivated",
|
||||
args: args{
|
||||
event: getEvent(testEvent(
|
||||
repository.EventType(org.IDPConfigDeactivatedEventType),
|
||||
org.AggregateType,
|
||||
[]byte(`{
|
||||
"idpConfigId": "idp-config-id"
|
||||
}`),
|
||||
), org.IDPConfigDeactivatedEventMapper),
|
||||
},
|
||||
reduce: (&IDPProjection{}).reduceIDPDeactivated,
|
||||
want: wantReduce{
|
||||
aggregateType: eventstore.AggregateType("org"),
|
||||
sequence: 15,
|
||||
previousSequence: 10,
|
||||
projection: IDPTable,
|
||||
executer: &testExecuter{
|
||||
executions: []execution{
|
||||
{
|
||||
expectedStmt: "UPDATE zitadel.projections.idps SET (state, change_date, sequence) = ($1, $2, $3) WHERE (id = $4)",
|
||||
expectedArgs: []interface{}{
|
||||
domain.IDPConfigStateInactive,
|
||||
anyArg{},
|
||||
uint64(15),
|
||||
"idp-config-id",
|
||||
},
|
||||
},
|
||||
},
|
||||
},
|
||||
},
|
||||
},
|
||||
{
|
||||
name: "org.reduceIDPReactivated",
|
||||
args: args{
|
||||
event: getEvent(testEvent(
|
||||
repository.EventType(org.IDPConfigReactivatedEventType),
|
||||
org.AggregateType,
|
||||
[]byte(`{
|
||||
"idpConfigId": "idp-config-id"
|
||||
}`),
|
||||
), org.IDPConfigReactivatedEventMapper),
|
||||
},
|
||||
reduce: (&IDPProjection{}).reduceIDPReactivated,
|
||||
want: wantReduce{
|
||||
aggregateType: eventstore.AggregateType("org"),
|
||||
sequence: 15,
|
||||
previousSequence: 10,
|
||||
projection: IDPTable,
|
||||
executer: &testExecuter{
|
||||
executions: []execution{
|
||||
{
|
||||
expectedStmt: "UPDATE zitadel.projections.idps SET (state, change_date, sequence) = ($1, $2, $3) WHERE (id = $4)",
|
||||
expectedArgs: []interface{}{
|
||||
domain.IDPConfigStateActive,
|
||||
anyArg{},
|
||||
uint64(15),
|
||||
"idp-config-id",
|
||||
},
|
||||
},
|
||||
},
|
||||
},
|
||||
},
|
||||
},
|
||||
{
|
||||
name: "org.reduceIDPRemoved",
|
||||
args: args{
|
||||
event: getEvent(testEvent(
|
||||
repository.EventType(org.IDPConfigRemovedEventType),
|
||||
org.AggregateType,
|
||||
[]byte(`{
|
||||
"idpConfigId": "idp-config-id"
|
||||
}`),
|
||||
), org.IDPConfigRemovedEventMapper),
|
||||
},
|
||||
reduce: (&IDPProjection{}).reduceIDPRemoved,
|
||||
want: wantReduce{
|
||||
aggregateType: eventstore.AggregateType("org"),
|
||||
sequence: 15,
|
||||
previousSequence: 10,
|
||||
projection: IDPTable,
|
||||
executer: &testExecuter{
|
||||
executions: []execution{
|
||||
{
|
||||
expectedStmt: "DELETE FROM zitadel.projections.idps WHERE (id = $1)",
|
||||
expectedArgs: []interface{}{
|
||||
"idp-config-id",
|
||||
},
|
||||
},
|
||||
},
|
||||
},
|
||||
},
|
||||
},
|
||||
{
|
||||
name: "org.reduceOIDCConfigAdded",
|
||||
args: args{
|
||||
event: getEvent(testEvent(
|
||||
repository.EventType(org.IDPOIDCConfigAddedEventType),
|
||||
org.AggregateType,
|
||||
[]byte(`{
|
||||
"idpConfigId": "idp-config-id",
|
||||
"clientId": "client-id",
|
||||
"clientSecret": {
|
||||
"cryptoType": 0,
|
||||
"algorithm": "RSA-265",
|
||||
"keyId": "key-id"
|
||||
},
|
||||
"issuer": "issuer",
|
||||
"authorizationEndpoint": "https://api.zitadel.ch/authorize",
|
||||
"tokenEndpoint": "https://api.zitadel.ch/token",
|
||||
"scopes": ["profile"],
|
||||
"idpDisplayNameMapping": 0,
|
||||
"usernameMapping": 1
|
||||
}`),
|
||||
), org.IDPOIDCConfigAddedEventMapper),
|
||||
},
|
||||
reduce: (&IDPProjection{}).reduceOIDCConfigAdded,
|
||||
want: wantReduce{
|
||||
aggregateType: eventstore.AggregateType("org"),
|
||||
sequence: 15,
|
||||
previousSequence: 10,
|
||||
projection: IDPTable,
|
||||
executer: &testExecuter{
|
||||
executions: []execution{
|
||||
{
|
||||
expectedStmt: "UPDATE zitadel.projections.idps SET (change_date, sequence) = ($1, $2) WHERE (id = $3)",
|
||||
expectedArgs: []interface{}{
|
||||
anyArg{},
|
||||
uint64(15),
|
||||
"idp-config-id",
|
||||
},
|
||||
},
|
||||
{
|
||||
expectedStmt: "INSERT INTO zitadel.projections.idps_oidc_config (idp_id, client_id, client_secret, issuer, scopes, display_name_mapping, username_mapping, authorization_endpoint, token_endpoint) VALUES ($1, $2, $3, $4, $5, $6, $7, $8, $9)",
|
||||
expectedArgs: []interface{}{
|
||||
"idp-config-id",
|
||||
"client-id",
|
||||
anyArg{},
|
||||
"issuer",
|
||||
pq.StringArray{"profile"},
|
||||
domain.OIDCMappingFieldUnspecified,
|
||||
domain.OIDCMappingFieldPreferredLoginName,
|
||||
"https://api.zitadel.ch/authorize",
|
||||
"https://api.zitadel.ch/token",
|
||||
},
|
||||
},
|
||||
},
|
||||
},
|
||||
},
|
||||
},
|
||||
{
|
||||
name: "org.reduceOIDCConfigChanged",
|
||||
args: args{
|
||||
event: getEvent(testEvent(
|
||||
repository.EventType(org.IDPOIDCConfigChangedEventType),
|
||||
org.AggregateType,
|
||||
[]byte(`{
|
||||
"idpConfigId": "idp-config-id",
|
||||
"clientId": "client-id",
|
||||
"clientSecret": {
|
||||
"cryptoType": 0,
|
||||
"algorithm": "RSA-265",
|
||||
"keyId": "key-id"
|
||||
},
|
||||
"issuer": "issuer",
|
||||
"authorizationEndpoint": "https://api.zitadel.ch/authorize",
|
||||
"tokenEndpoint": "https://api.zitadel.ch/token",
|
||||
"scopes": ["profile"],
|
||||
"idpDisplayNameMapping": 0,
|
||||
"usernameMapping": 1
|
||||
}`),
|
||||
), org.IDPOIDCConfigChangedEventMapper),
|
||||
},
|
||||
reduce: (&IDPProjection{}).reduceOIDCConfigChanged,
|
||||
want: wantReduce{
|
||||
aggregateType: eventstore.AggregateType("org"),
|
||||
sequence: 15,
|
||||
previousSequence: 10,
|
||||
projection: IDPTable,
|
||||
executer: &testExecuter{
|
||||
executions: []execution{
|
||||
{
|
||||
expectedStmt: "UPDATE zitadel.projections.idps SET (change_date, sequence) = ($1, $2) WHERE (id = $3)",
|
||||
expectedArgs: []interface{}{
|
||||
anyArg{},
|
||||
uint64(15),
|
||||
"idp-config-id",
|
||||
},
|
||||
},
|
||||
{
|
||||
expectedStmt: "UPDATE zitadel.projections.idps_oidc_config SET (client_id, client_secret, issuer, authorization_endpoint, token_endpoint, scopes, display_name_mapping, username_mapping) = ($1, $2, $3, $4, $5, $6, $7, $8) WHERE (idp_id = $9)",
|
||||
expectedArgs: []interface{}{
|
||||
"client-id",
|
||||
anyArg{},
|
||||
"issuer",
|
||||
"https://api.zitadel.ch/authorize",
|
||||
"https://api.zitadel.ch/token",
|
||||
pq.StringArray{"profile"},
|
||||
domain.OIDCMappingFieldUnspecified,
|
||||
domain.OIDCMappingFieldPreferredLoginName,
|
||||
"idp-config-id",
|
||||
},
|
||||
},
|
||||
},
|
||||
},
|
||||
},
|
||||
},
|
||||
{
|
||||
name: "org.reduceOIDCConfigChanged: no op",
|
||||
args: args{
|
||||
event: getEvent(testEvent(
|
||||
repository.EventType(org.IDPOIDCConfigChangedEventType),
|
||||
org.AggregateType,
|
||||
[]byte("{}"),
|
||||
), org.IDPOIDCConfigChangedEventMapper),
|
||||
},
|
||||
reduce: (&IDPProjection{}).reduceOIDCConfigChanged,
|
||||
want: wantReduce{
|
||||
aggregateType: eventstore.AggregateType("org"),
|
||||
sequence: 15,
|
||||
previousSequence: 10,
|
||||
projection: IDPTable,
|
||||
executer: &testExecuter{
|
||||
executions: []execution{},
|
||||
},
|
||||
},
|
||||
},
|
||||
{
|
||||
name: "org.reduceJWTConfigAdded",
|
||||
args: args{
|
||||
event: getEvent(testEvent(
|
||||
repository.EventType(org.IDPJWTConfigAddedEventType),
|
||||
org.AggregateType,
|
||||
[]byte(`{
|
||||
"idpConfigId": "idp-config-id",
|
||||
"jwtEndpoint": "https://api.zitadel.ch/jwt",
|
||||
"issuer": "issuer",
|
||||
"keysEndpoint": "https://api.zitadel.ch/keys",
|
||||
"headerName": "hodor"
|
||||
}`),
|
||||
), org.IDPJWTConfigAddedEventMapper),
|
||||
},
|
||||
reduce: (&IDPProjection{}).reduceJWTConfigAdded,
|
||||
want: wantReduce{
|
||||
aggregateType: eventstore.AggregateType("org"),
|
||||
sequence: 15,
|
||||
previousSequence: 10,
|
||||
projection: IDPTable,
|
||||
executer: &testExecuter{
|
||||
executions: []execution{
|
||||
{
|
||||
expectedStmt: "UPDATE zitadel.projections.idps SET (change_date, sequence) = ($1, $2) WHERE (id = $3)",
|
||||
expectedArgs: []interface{}{
|
||||
anyArg{},
|
||||
uint64(15),
|
||||
"idp-config-id",
|
||||
},
|
||||
},
|
||||
{
|
||||
expectedStmt: "INSERT INTO zitadel.projections.idps_jwt_config (idp_id, endpoint, issuer, keys_endpoint, header_name) VALUES ($1, $2, $3, $4, $5)",
|
||||
expectedArgs: []interface{}{
|
||||
"idp-config-id",
|
||||
"https://api.zitadel.ch/jwt",
|
||||
"issuer",
|
||||
"https://api.zitadel.ch/keys",
|
||||
"hodor",
|
||||
},
|
||||
},
|
||||
},
|
||||
},
|
||||
},
|
||||
},
|
||||
{
|
||||
name: "org.reduceJWTConfigChanged",
|
||||
args: args{
|
||||
event: getEvent(testEvent(
|
||||
repository.EventType(org.IDPJWTConfigChangedEventType),
|
||||
org.AggregateType,
|
||||
[]byte(`{
|
||||
"idpConfigId": "idp-config-id",
|
||||
"jwtEndpoint": "https://api.zitadel.ch/jwt",
|
||||
"issuer": "issuer",
|
||||
"keysEndpoint": "https://api.zitadel.ch/keys",
|
||||
"headerName": "hodor"
|
||||
}`),
|
||||
), org.IDPJWTConfigChangedEventMapper),
|
||||
},
|
||||
reduce: (&IDPProjection{}).reduceJWTConfigChanged,
|
||||
want: wantReduce{
|
||||
aggregateType: eventstore.AggregateType("org"),
|
||||
sequence: 15,
|
||||
previousSequence: 10,
|
||||
projection: IDPTable,
|
||||
executer: &testExecuter{
|
||||
executions: []execution{
|
||||
{
|
||||
expectedStmt: "UPDATE zitadel.projections.idps SET (change_date, sequence) = ($1, $2) WHERE (id = $3)",
|
||||
expectedArgs: []interface{}{
|
||||
anyArg{},
|
||||
uint64(15),
|
||||
"idp-config-id",
|
||||
},
|
||||
},
|
||||
{
|
||||
expectedStmt: "UPDATE zitadel.projections.idps_jwt_config SET (endpoint, issuer, keys_endpoint, header_name) = ($1, $2, $3, $4) WHERE (idp_id = $5)",
|
||||
expectedArgs: []interface{}{
|
||||
"https://api.zitadel.ch/jwt",
|
||||
"issuer",
|
||||
"https://api.zitadel.ch/keys",
|
||||
"hodor",
|
||||
"idp-config-id",
|
||||
},
|
||||
},
|
||||
},
|
||||
},
|
||||
},
|
||||
},
|
||||
{
|
||||
name: "org.reduceJWTConfigChanged: no op",
|
||||
args: args{
|
||||
event: getEvent(testEvent(
|
||||
repository.EventType(org.IDPJWTConfigChangedEventType),
|
||||
org.AggregateType,
|
||||
[]byte(`{}`),
|
||||
), org.IDPJWTConfigChangedEventMapper),
|
||||
},
|
||||
reduce: (&IDPProjection{}).reduceJWTConfigChanged,
|
||||
want: wantReduce{
|
||||
aggregateType: eventstore.AggregateType("org"),
|
||||
sequence: 15,
|
||||
previousSequence: 10,
|
||||
projection: IDPTable,
|
||||
executer: &testExecuter{
|
||||
executions: []execution{},
|
||||
},
|
||||
},
|
||||
},
|
||||
}
|
||||
for _, tt := range tests {
|
||||
t.Run(tt.name, func(t *testing.T) {
|
||||
event := baseEvent(t)
|
||||
got, err := tt.reduce(event)
|
||||
if _, ok := err.(errors.InvalidArgument); !ok {
|
||||
t.Errorf("no wrong event mapping: %v, got: %v", err, got)
|
||||
}
|
||||
|
||||
event = tt.args.event(t)
|
||||
got, err = tt.reduce(event)
|
||||
assertReduce(t, got, err, tt.want)
|
||||
})
|
||||
}
|
||||
}
|
@ -42,6 +42,7 @@ func Start(ctx context.Context, sqlClient *sql.DB, es *eventstore.Eventstore, co
|
||||
// owner.NewOrgOwnerProjection(ctx, applyCustomConfig(projectionConfig, config.Customizations["org_owners"]))
|
||||
NewOrgDomainProjection(ctx, applyCustomConfig(projectionConfig, config.Customizations["org_domains"]))
|
||||
NewLoginPolicyProjection(ctx, applyCustomConfig(projectionConfig, config.Customizations["login_policies"]))
|
||||
NewIDPProjection(ctx, applyCustomConfig(projectionConfig, config.Customizations["idps"]))
|
||||
|
||||
return nil
|
||||
}
|
||||
|
@ -270,6 +270,27 @@ func ListComparisonFromMethod(m domain.SearchMethod) ListComparison {
|
||||
}
|
||||
}
|
||||
|
||||
type BoolQuery struct {
|
||||
Column Column
|
||||
Value bool
|
||||
}
|
||||
|
||||
func NewBoolQuery(c Column, value bool) (*BoolQuery, error) {
|
||||
return &BoolQuery{
|
||||
Column: c,
|
||||
Value: value,
|
||||
}, nil
|
||||
}
|
||||
|
||||
func (q *BoolQuery) ToQuery(query sq.SelectBuilder) sq.SelectBuilder {
|
||||
where, args := q.comp()
|
||||
return query.Where(where, args...)
|
||||
}
|
||||
|
||||
func (s *BoolQuery) comp() (comparison interface{}, args []interface{}) {
|
||||
return sq.Eq{s.Column.identifier(): s.Value}, nil
|
||||
}
|
||||
|
||||
var (
|
||||
//countColumn represents the default counter for search responses
|
||||
countColumn = Column{
|
||||
|
41
migrations/cockroach/V1.79__idp_projections.sql
Normal file
41
migrations/cockroach/V1.79__idp_projections.sql
Normal file
@ -0,0 +1,41 @@
|
||||
CREATE TABLE zitadel.projections.idps (
|
||||
id TEXT,
|
||||
creation_date TIMESTAMPTZ,
|
||||
change_date TIMESTAMPTZ,
|
||||
sequence BIGINT,
|
||||
resource_owner TEXT,
|
||||
|
||||
state SMALLINT,
|
||||
name TEXT,
|
||||
styling_type SMALLINT,
|
||||
owner_type SMALLINT,
|
||||
auto_register BOOLEAN,
|
||||
|
||||
PRIMARY KEY (id)
|
||||
);
|
||||
|
||||
CREATE TABLE zitadel.projections.idps_oidc_config (
|
||||
idp_id TEXT REFERENCES zitadel.projections.idps (id) ON DELETE CASCADE,
|
||||
|
||||
client_id TEXT,
|
||||
client_secret JSONB,
|
||||
issuer TEXT,
|
||||
scopes STRING[],
|
||||
display_name_mapping SMALLINT,
|
||||
username_mapping SMALLINT,
|
||||
authorization_endpoint TEXT,
|
||||
token_endpoint TEXT,
|
||||
|
||||
PRIMARY KEY (idp_id)
|
||||
);
|
||||
|
||||
CREATE TABLE zitadel.projections.idps_jwt_config (
|
||||
idp_id TEXT REFERENCES zitadel.projections.idps (id) ON DELETE CASCADE,
|
||||
|
||||
issuer TEXT,
|
||||
keys_endpoint TEXT,
|
||||
header_name TEXT,
|
||||
endpoint TEXT,
|
||||
|
||||
PRIMARY KEY (idp_id)
|
||||
);
|
Loading…
x
Reference in New Issue
Block a user