feat: handle instance from context (#3382)

* commander

* commander

* selber!

* move to packages

* fix(errors): implement Is interface

* test: command

* test: commands

* add init steps

* setup tenant

* add default step yaml

* possibility to set password

* merge v2 into v2-commander

* fix: rename iam command side to instance

* fix: rename iam command side to instance

* fix: rename iam command side to instance

* fix: rename iam command side to instance

* fix: search query builder can filter events in memory

* fix: filters for add member

* fix(setup): add `ExternalSecure` to config

* chore: name iam to instance

* fix: matching

* remove unsued func

* base url

* base url

* test(command): filter funcs

* test: commands

* fix: rename orgiampolicy to domain policy

* start from init

* commands

* config

* fix indexes and add constraints

* fixes

* fix: merge conflicts

* fix: protos

* fix: md files

* setup

* add deprecated org iam policy again

* typo

* fix search query

* fix filter

* Apply suggestions from code review

* remove custom org from org setup

* add todos for verification

* change apps creation

* simplify package structure

* fix error

* move preparation helper for tests

* fix unique constraints

* fix config mapping in setup

* fix error handling in encryption_keys.go

* fix projection config

* fix query from old views to projection

* fix setup of mgmt api

* set iam project and fix instance projection

* fix tokens view

* fix steps.yaml and defaults.yaml

* fix projections

* change instance context to interface

* instance interceptors and additional events in setup

* cleanup

* tests for interceptors

* fix label policy

* add todo

* single api endpoint in environment.json

Co-authored-by: adlerhurst <silvan.reusser@gmail.com>
Co-authored-by: fabi <fabienne.gerschwiler@gmail.com>
This commit is contained in:
Livio Amstutz 2022-03-29 11:53:19 +02:00 committed by GitHub
parent c5b99274d7
commit 958362e6c9
No known key found for this signature in database
GPG Key ID: 4AEE18F83AFDEB23
101 changed files with 1520 additions and 274 deletions

View File

@ -1,7 +0,0 @@
{
"authServiceUrl": "http://localhost:50000",
"mgmtServiceUrl": "http://localhost:50000",
"adminServiceUrl": "http://localhost:50000",
"issuer": "http://localhost:50002/oauth/v2",
"clientid": "@zitadel"
}

View File

@ -127,6 +127,7 @@ CREATE TABLE auth.tokens (
audience STRING[] NULL,
preferred_language STRING NULL,
refresh_token_id STRING NULL,
is_pat BOOL NOT NULL DEFAULT false,
instance_id STRING NULL,
PRIMARY KEY (id),

View File

@ -22,7 +22,7 @@ S2DefaultInstance:
PasswordAgePolicy:
ExpireWarnDays: 0
MaxAgeDays: 0
OrgIAMPolicy:
DomainPolicy:
UserLoginMustBeDomain: true
LoginPolicy:
AllowUsernamePassword: true

View File

@ -2,6 +2,8 @@ package start
import (
"github.com/caos/logging"
"github.com/spf13/viper"
admin_es "github.com/caos/zitadel/internal/admin/repository/eventsourcing"
internal_authz "github.com/caos/zitadel/internal/api/authz"
"github.com/caos/zitadel/internal/api/http/middleware"
@ -16,7 +18,6 @@ import (
"github.com/caos/zitadel/internal/notification"
"github.com/caos/zitadel/internal/query/projection"
static_config "github.com/caos/zitadel/internal/static/config"
"github.com/spf13/viper"
)
type Config struct {
@ -25,6 +26,8 @@ type Config struct {
ExternalPort uint16
ExternalDomain string
ExternalSecure bool
HTTP2HostHeader string
HTTP1HostHeader string
Database database.Config
Projections projection.Config
AuthZ authz.Config

View File

@ -4,7 +4,6 @@ import (
"context"
"database/sql"
_ "embed"
"errors"
"fmt"
"net"
"net/http"
@ -139,7 +138,7 @@ func startAPIs(ctx context.Context, router *mux.Router, commands *command.Comman
}
verifier := internal_authz.Start(repo)
apis := api.New(config.Port, router, &repo, config.InternalAuthZ, config.ExternalSecure)
apis := api.New(config.Port, router, &repo, config.InternalAuthZ, config.ExternalSecure, config.HTTP2HostHeader)
authRepo, err := auth_es.Start(config.Auth, config.SystemDefaults, commands, queries, dbClient, assets.HandlerPrefix, keys.OIDC, keys.User)
if err != nil {
return fmt.Errorf("error starting auth repo: %w", err)
@ -164,9 +163,10 @@ func startAPIs(ctx context.Context, router *mux.Router, commands *command.Comman
if err != nil {
return err
}
instanceInterceptor := middleware.InstanceInterceptor(queries, config.HTTP1HostHeader)
issuer := oidc.Issuer(config.ExternalDomain, config.ExternalPort, config.ExternalSecure)
oidcProvider, err := oidc.NewProvider(ctx, config.OIDC, issuer, login.DefaultLoggedOutPath, commands, queries, authRepo, config.SystemDefaults.KeyConfig, keys.OIDC, keys.OIDCKey, eventstore, dbClient, keyChan, userAgentInterceptor)
oidcProvider, err := oidc.NewProvider(ctx, config.OIDC, issuer, login.DefaultLoggedOutPath, commands, queries, authRepo, config.SystemDefaults.KeyConfig, keys.OIDC, keys.OIDCKey, eventstore, dbClient, keyChan, userAgentInterceptor, instanceInterceptor.Handler)
if err != nil {
return fmt.Errorf("unable to start oidc provider: %w", err)
}
@ -178,18 +178,14 @@ func startAPIs(ctx context.Context, router *mux.Router, commands *command.Comman
}
apis.RegisterHandler(openapi.HandlerPrefix, openAPIHandler)
consoleID, err := consoleClientID(ctx, queries)
if err != nil {
return fmt.Errorf("unable to get client_id for console: %w", err)
}
baseURL := http_util.BuildHTTP(config.ExternalDomain, config.ExternalPort, config.ExternalSecure)
c, err := console.Start(config.Console, config.ExternalDomain, baseURL, issuer, consoleID)
c, err := console.Start(config.Console, config.ExternalDomain, baseURL, issuer, instanceInterceptor.Handler)
if err != nil {
return fmt.Errorf("unable to start console: %w", err)
}
apis.RegisterHandler(console.HandlerPrefix, c)
l, err := login.CreateLogin(config.Login, commands, queries, authRepo, store, config.SystemDefaults, console.HandlerPrefix, config.ExternalDomain, baseURL, oidc.AuthCallback, config.ExternalSecure, userAgentInterceptor, keys.User, keys.IDPConfig, keys.CSRFCookieKey)
l, err := login.CreateLogin(config.Login, commands, queries, authRepo, store, config.SystemDefaults, console.HandlerPrefix, config.ExternalDomain, baseURL, oidc.AuthCallback, config.ExternalSecure, userAgentInterceptor, instanceInterceptor.Handler, keys.User, keys.IDPConfig, keys.CSRFCookieKey)
if err != nil {
return fmt.Errorf("unable to start login: %w", err)
}
@ -236,29 +232,3 @@ func shutdownServer(ctx context.Context, server *http.Server) error {
logging.New().Info("server shutdown gracefully")
return nil
}
//TODO:!!??!!
func consoleClientID(ctx context.Context, queries *query.Queries) (string, error) {
iam, err := queries.Instance(ctx)
if err != nil {
return "", err
}
projectID, err := query.NewAppProjectIDSearchQuery(iam.IAMProjectID)
if err != nil {
return "", err
}
name, err := query.NewAppNameSearchQuery(query.TextContainsIgnoreCase, "console") //TODO:!!??!!
if err != nil {
return "", err
}
apps, err := queries.SearchApps(ctx, &query.AppSearchQueries{
Queries: []query.SearchQuery{projectID, name},
})
if err != nil {
return "", err
}
if len(apps.Apps) != 1 || apps.Apps[0].OIDCConfig == nil {
return "", errors.New("invalid app")
}
return apps.Apps[0].OIDCConfig.ClientID, nil
}

View File

@ -7,6 +7,8 @@ Port: 8080
ExternalPort: 8080
ExternalDomain: localhost
ExternalSecure: true
HTTP2HostHeader: ":authority"
HTTP1HostHeader: "host"
Database:
Host: localhost
@ -181,3 +183,399 @@ SystemDefaults:
PublicKeyLifetime: 30h
SigningKeyRotationCheck: 10s
SigningKeyGracefulPeriod: 10m
InternalAuthZ:
RolePermissionMappings:
- Role: 'IAM_OWNER'
Permissions:
- "iam.read"
- "iam.write"
- "iam.features.read"
- "iam.features.write"
- "iam.policy.read"
- "iam.policy.write"
- "iam.policy.delete"
- "iam.member.read"
- "iam.member.write"
- "iam.member.delete"
- "iam.idp.read"
- "iam.idp.write"
- "iam.idp.delete"
- "iam.action.read"
- "iam.action.write"
- "iam.action.delete"
- "iam.flow.read"
- "iam.flow.write"
- "iam.flow.delete"
- "org.read"
- "org.global.read"
- "org.create"
- "org.write"
- "org.member.read"
- "org.member.write"
- "org.member.delete"
- "org.idp.read"
- "org.idp.write"
- "org.idp.delete"
- "org.action.read"
- "org.action.write"
- "org.action.delete"
- "org.flow.read"
- "org.flow.write"
- "org.flow.delete"
- "user.read"
- "user.global.read"
- "user.write"
- "user.delete"
- "user.grant.read"
- "user.grant.write"
- "user.grant.delete"
- "user.membership.read"
- "user.credential.write"
- "features.read"
- "policy.read"
- "policy.write"
- "policy.delete"
- "project.read"
- "project.create"
- "project.write"
- "project.delete"
- "project.member.read"
- "project.member.write"
- "project.member.delete"
- "project.role.read"
- "project.role.write"
- "project.role.delete"
- "project.app.read"
- "project.app.write"
- "project.app.delete"
- "project.grant.read"
- "project.grant.write"
- "project.grant.delete"
- "project.grant.member.read"
- "project.grant.member.write"
- "project.grant.member.delete"
- Role: 'IAM_OWNER_VIEWER'
Permissions:
- "iam.read"
- "iam.features.read"
- "iam.policy.read"
- "iam.member.read"
- "iam.idp.read"
- "iam.action.read"
- "iam.flow.read"
- "org.read"
- "org.member.read"
- "org.idp.read"
- "org.action.read"
- "org.flow.read"
- "user.read"
- "user.global.read"
- "user.grant.read"
- "user.membership.read"
- "features.read"
- "policy.read"
- "project.read"
- "project.member.read"
- "project.role.read"
- "project.app.read"
- "project.grant.read"
- "project.grant.member.read"
- Role: 'IAM_ORG_MANAGER'
Permissions:
- "org.read"
- "org.global.read"
- "org.create"
- "org.write"
- "org.member.read"
- "org.member.write"
- "org.member.delete"
- "org.idp.read"
- "org.idp.write"
- "org.idp.delete"
- "org.action.read"
- "org.action.write"
- "org.action.delete"
- "org.flow.read"
- "org.flow.write"
- "org.flow.delete"
- "user.read"
- "user.global.read"
- "user.write"
- "user.delete"
- "user.grant.read"
- "user.grant.write"
- "user.grant.delete"
- "user.membership.read"
- "user.credential.write"
- "features.read"
- "policy.read"
- "policy.write"
- "policy.delete"
- "project.read"
- "project.create"
- "project.write"
- "project.delete"
- "project.member.read"
- "project.member.write"
- "project.member.delete"
- "project.role.read"
- "project.role.write"
- "project.role.delete"
- "project.app.read"
- "project.app.write"
- "project.app.delete"
- "project.grant.read"
- "project.grant.write"
- "project.grant.delete"
- "project.grant.member.read"
- "project.grant.member.write"
- "project.grant.member.delete"
- Role: 'IAM_USER_MANAGER'
Permissions:
- "org.read"
- "org.global.read"
- "org.member.read"
- "org.member.delete"
- "user.read"
- "user.global.read"
- "user.write"
- "user.delete"
- "user.grant.read"
- "user.grant.write"
- "user.grant.delete"
- "user.membership.read"
- "features.read"
- "project.read"
- "project.member.read"
- "project.role.read"
- "project.app.read"
- "project.grant.read"
- "project.grant.write"
- "project.grant.delete"
- "project.grant.member.read"
- Role: 'ORG_OWNER'
Permissions:
- "org.read"
- "org.global.read"
- "org.create"
- "org.write"
- "org.member.read"
- "org.member.write"
- "org.member.delete"
- "org.idp.read"
- "org.idp.write"
- "org.idp.delete"
- "org.action.read"
- "org.action.write"
- "org.action.delete"
- "org.flow.read"
- "org.flow.write"
- "org.flow.delete"
- "user.read"
- "user.global.read"
- "user.write"
- "user.delete"
- "user.grant.read"
- "user.grant.write"
- "user.grant.delete"
- "user.membership.read"
- "user.credential.write"
- "features.read"
- "policy.read"
- "policy.write"
- "policy.delete"
- "project.read"
- "project.create"
- "project.write"
- "project.delete"
- "project.member.read"
- "project.member.write"
- "project.member.delete"
- "project.role.read"
- "project.role.write"
- "project.role.delete"
- "project.app.read"
- "project.app.write"
- "project.grant.read"
- "project.grant.write"
- "project.grant.delete"
- "project.grant.member.read"
- "project.grant.member.write"
- "project.grant.member.delete"
- Role: 'ORG_USER_MANAGER'
Permissions:
- "user.read"
- "user.global.read"
- "user.write"
- "user.delete"
- "user.grant.read"
- "user.grant.write"
- "user.grant.delete"
- "user.membership.read"
- "project.read"
- "project.role.read"
- Role: 'ORG_OWNER_VIEWER'
Permissions:
- "org.read"
- "org.member.read"
- "org.idp.read"
- "org.action.read"
- "org.flow.read"
- "user.read"
- "user.global.read"
- "user.grant.read"
- "user.membership.read"
- "features.read"
- "policy.read"
- "project.read"
- "project.member.read"
- "project.role.read"
- "project.app.read"
- "project.grant.read"
- "project.grant.member.read"
- "project.grant.user.grant.read"
- Role: 'ORG_USER_PERMISSION_EDITOR'
Permissions:
- "org.read"
- "org.member.read"
- "user.read"
- "user.global.read"
- "user.grant.read"
- "user.grant.write"
- "user.grant.delete"
- "policy.read"
- "project.read"
- "project.member.read"
- "project.role.read"
- "project.app.read"
- "project.grant.read"
- "project.grant.member.read"
- Role: 'ORG_PROJECT_PERMISSION_EDITOR'
Permissions:
- "org.read"
- "org.member.read"
- "user.read"
- "user.global.read"
- "user.grant.read"
- "user.grant.write"
- "user.grant.delete"
- "policy.read"
- "project.read"
- "project.member.read"
- "project.role.read"
- "project.app.read"
- "project.grant.read"
- "project.grant.write"
- "project.grant.delete"
- "project.grant.member.read"
- Role: 'ORG_PROJECT_CREATOR'
Permissions:
- "user.global.read"
- "policy.read"
- "project.read:self"
- "project.create"
- Role: 'PROJECT_OWNER'
Permissions:
- "org.global.read"
- "policy.read"
- "project.read"
- "project.write"
- "project.delete"
- "project.member.read"
- "project.member.write"
- "project.member.delete"
- "project.role.read"
- "project.role.write"
- "project.role.delete"
- "project.app.read"
- "project.app.write"
- "project.app.delete"
- "project.grant.read"
- "project.grant.write"
- "project.grant.delete"
- "project.grant.member.read"
- "project.grant.member.write"
- "project.grant.member.delete"
- "user.read"
- "user.global.read"
- "user.grant.read"
- "user.grant.write"
- "user.grant.delete"
- "user.membership.read"
- Role: 'PROJECT_OWNER_VIEWER'
Permissions:
- "policy.read"
- "project.read"
- "project.member.read"
- "project.role.read"
- "project.app.read"
- "project.grant.read"
- "project.grant.member.read"
- "user.read"
- "user.global.read"
- "user.grant.read"
- "user.membership.read"
- Role: 'SELF_MANAGEMENT_GLOBAL'
Permissions:
- "org.create"
- "policy.read"
- "user.self.delete"
- Role: 'PROJECT_OWNER_GLOBAL'
Permissions:
- "org.global.read"
- "policy.read"
- "project.read"
- "project.write"
- "project.delete"
- "project.member.read"
- "project.member.write"
- "project.member.delete"
- "project.role.read"
- "project.role.write"
- "project.role.delete"
- "project.app.read"
- "project.app.write"
- "project.app.delete"
- "user.global.read"
- "user.grant.read"
- "user.grant.write"
- "user.grant.delete"
- "user.membership.read"
- Role: 'PROJECT_OWNER_VIEWER_GLOBAL'
Permissions:
- "policy.read"
- "project.read"
- "project.member.read"
- "project.role.read"
- "project.app.read"
- "project.grant.read"
- "project.grant.member.read"
- "user.global.read"
- "user.grant.read"
- "user.membership.read"
- Role: 'PROJECT_GRANT_OWNER'
Permissions:
- "policy.read"
- "org.global.read"
- "project.read"
- "project.grant.read"
- "project.grant.member.read"
- "project.grant.member.write"
- "project.grant.member.delete"
- "user.read"
- "user.global.read"
- "user.grant.read"
- "user.grant.write"
- "user.grant.delete"
- "user.membership.read"
- Role: 'PROJECT_GRANT_OWNER_VIEWER'
Permissions:
- "policy.read"
- "project.read"
- "project.grant.read"
- "project.grant.member.read"
- "user.read"
- "user.global.read"
- "user.grant.read"
- "user.membership.read"

View File

@ -29,9 +29,7 @@ export class InfoRowComponent implements OnInit {
.toPromise().then((env: any) => {
this.environmentMap = {
issuer: env.issuer,
adminServiceUrl: env.adminServiceUrl,
mgmtServiceUrl: env.mgmtServiceUrl,
authServiceUrl: env.adminServiceUrl,
api: env.api,
};
});
}

View File

@ -84,9 +84,8 @@ export class AssetService {
.get('./assets/environment.json')
.toPromise()
.then((data: any) => {
if (data && data.assetServiceUrl) {
console.log(data.assetServiceUrl);
return data.assetServiceUrl;
if (data && data.api) {
return data.api;
}
})
.catch((error) => {

View File

@ -34,7 +34,7 @@ export class GrpcService {
.get('./assets/environment.json')
.toPromise()
.then((data: any) => {
if (data && data.authServiceUrl && data.mgmtServiceUrl && data.issuer) {
if (data && data.api && data.issuer) {
const interceptors = {
unaryInterceptors: [
new OrgInterceptor(this.storageService),
@ -44,20 +44,19 @@ export class GrpcService {
};
this.auth = new AuthServiceClient(
data.authServiceUrl,
data.api,
null,
// @ts-ignore
interceptors,
);
this.mgmt = new ManagementServiceClient(
data.mgmtServiceUrl,
data.api,
null,
// @ts-ignore
interceptors,
);
this.admin = new AdminServiceClient(
// TODO: replace with service url
data.mgmtServiceUrl,
data.api,
null,
// @ts-ignore
interceptors,

View File

@ -26,7 +26,7 @@ export class SubscriptionService {
return this.http.get('./assets/environment.json')
.toPromise().then((data: any) => {
if (data && data.subscriptionServiceUrl) {
const serviceUrl = data.subscriptionServiceUrl;
const serviceUrl = data.api;
const accessToken = this.storageService.getItem(accessTokenStorageKey);
return this.http.get(`${serviceUrl}/redirect`, {
headers: {
@ -48,7 +48,7 @@ export class SubscriptionService {
return this.http.get('./assets/environment.json')
.toPromise().then((data: any) => {
if (data && data.subscriptionServiceUrl) {
const serviceUrl = data.subscriptionServiceUrl;
const serviceUrl = data.api;
const accessToken = this.storageService.getItem(accessTokenStorageKey);
return this.http.get(`${serviceUrl}/customer`, {
headers: {
@ -68,7 +68,7 @@ export class SubscriptionService {
return this.http.get('./assets/environment.json')
.toPromise().then((data: any) => {
if (data && data.subscriptionServiceUrl) {
const serviceUrl = data.subscriptionServiceUrl;
const serviceUrl = data.api;
const accessToken = this.storageService.getItem(accessTokenStorageKey);
return this.http.post(`${serviceUrl}/customer`, body, {
headers: {

View File

@ -1,9 +1,5 @@
{
"authServiceUrl": "https://api.zitadel.dev",
"mgmtServiceUrl": "https://api.zitadel.dev",
"adminServiceUrl": "https://api.zitadel.dev",
"subscriptionServiceUrl": "https://sub.zitadel.dev",
"assetServiceUrl": "https://api.zitadel.dev",
"api": "https://api.zitadel.dev",
"issuer": "https://issuer.zitadel.dev",
"clientid": "70669160379706195@zitadel"
}

View File

@ -44,6 +44,7 @@ func New(
},
authZ internal_authz.Config,
externalSecure bool,
http2HostName string,
) *API {
verifier := internal_authz.Start(repo)
api := &API{
@ -53,7 +54,7 @@ func New(
router: router,
externalSecure: externalSecure,
}
api.grpcServer = server.CreateServer(api.verifier, authZ, repo.Queries)
api.grpcServer = server.CreateServer(api.verifier, authZ, repo.Queries, http2HostName)
api.routeGRPC()
api.RegisterHandler("/debug", api.healthHandler())

View File

@ -31,10 +31,6 @@ func (ctxData CtxData) IsZero() bool {
return ctxData.UserID == "" || ctxData.OrgID == ""
}
type Instance struct {
ID string
}
type Grants []*Grant
type Grant struct {
@ -116,15 +112,6 @@ func GetCtxData(ctx context.Context) CtxData {
return ctxData
}
func GetInstance(ctx context.Context) Instance {
instance, _ := ctx.Value(instanceKey).(Instance)
return instance
}
func WithInstance(ctx context.Context, instance Instance) context.Context {
return context.WithValue(ctx, instanceKey, instance)
}
func GetRequestPermissionsFromCtx(ctx context.Context) []string {
ctxPermission, _ := ctx.Value(requestPermissionsKey).([]string)
return ctxPermission

View File

@ -0,0 +1,51 @@
package authz
import (
"context"
)
var (
emptyInstance = &instance{}
)
type Instance interface {
InstanceID() string
ProjectID() string
ConsoleClientID() string
}
type InstanceVerifier interface {
InstanceByHost(context.Context, string) (Instance, error)
}
type instance struct {
ID string
}
func (i *instance) InstanceID() string {
return i.ID
}
func (i *instance) ProjectID() string {
return ""
}
func (i *instance) ConsoleClientID() string {
return ""
}
func GetInstance(ctx context.Context) Instance {
instance, ok := ctx.Value(instanceKey).(Instance)
if !ok {
return emptyInstance
}
return instance
}
func WithInstance(ctx context.Context, instance Instance) context.Context {
return context.WithValue(ctx, instanceKey, instance)
}
func WithInstanceID(ctx context.Context, id string) context.Context {
return context.WithValue(ctx, instanceKey, &instance{ID: id})
}

View File

@ -0,0 +1,80 @@
package authz
import (
"context"
"testing"
"github.com/stretchr/testify/assert"
)
func Test_Instance(t *testing.T) {
type args struct {
ctx context.Context
}
type res struct {
instanceID string
projectID string
consoleID string
}
tests := []struct {
name string
args args
res res
}{
{
"empty context",
args{
context.Background(),
},
res{
instanceID: "",
projectID: "",
consoleID: "",
},
},
{
"WithInstanceID",
args{
WithInstanceID(context.Background(), "id"),
},
res{
instanceID: "id",
projectID: "",
consoleID: "",
},
},
{
"WithInstance",
args{
WithInstance(context.Background(), &mockInstance{}),
},
res{
instanceID: "instanceID",
projectID: "projectID",
consoleID: "consoleID",
},
},
}
for _, tt := range tests {
t.Run(tt.name, func(t *testing.T) {
got := GetInstance(tt.args.ctx)
assert.Equal(t, tt.res.instanceID, got.InstanceID())
assert.Equal(t, tt.res.projectID, got.ProjectID())
assert.Equal(t, tt.res.consoleID, got.ConsoleClientID())
})
}
}
type mockInstance struct{}
func (m *mockInstance) InstanceID() string {
return "instanceID"
}
func (m *mockInstance) ProjectID() string {
return "projectID"
}
func (m *mockInstance) ConsoleClientID() string {
return "consoleID"
}

View File

@ -152,14 +152,10 @@ func (s *Server) ListMyProjectOrgs(ctx context.Context, req *auth_pb.ListMyProje
return nil, err
}
iam, err := s.query.Instance(ctx)
if err != nil {
return nil, err
}
ctxData := authz.GetCtxData(ctx)
//client of user is not in project of ZITADEL
if ctxData.ProjectID != iam.IAMProjectID {
if ctxData.ProjectID != authz.GetInstance(ctx).ProjectID() {
userGrantProjectID, err := query.NewUserGrantProjectIDSearchQuery(ctxData.ProjectID)
if err != nil {
return nil, err

View File

@ -0,0 +1,50 @@
package middleware
import (
"context"
"fmt"
"google.golang.org/grpc"
"google.golang.org/grpc/codes"
"google.golang.org/grpc/metadata"
"google.golang.org/grpc/status"
"github.com/caos/zitadel/internal/api/authz"
)
type InstanceVerifier interface {
GetInstance(ctx context.Context)
}
func InstanceInterceptor(verifier authz.InstanceVerifier, headerName string) grpc.UnaryServerInterceptor {
return func(ctx context.Context, req interface{}, info *grpc.UnaryServerInfo, handler grpc.UnaryHandler) (interface{}, error) {
return setInstance(ctx, req, info, handler, verifier, headerName)
}
}
func setInstance(ctx context.Context, req interface{}, info *grpc.UnaryServerInfo, handler grpc.UnaryHandler, verifier authz.InstanceVerifier, headerName string) (_ interface{}, err error) {
host, err := hostNameFromContext(ctx, headerName)
if err != nil {
return nil, status.Error(codes.PermissionDenied, err.Error())
}
instance, err := verifier.InstanceByHost(ctx, host)
if err != nil {
return nil, status.Error(codes.PermissionDenied, err.Error())
}
return handler(authz.WithInstance(ctx, instance), req)
}
func hostNameFromContext(ctx context.Context, headerName string) (string, error) {
md, ok := metadata.FromIncomingContext(ctx)
if !ok {
return "", fmt.Errorf("cannot read metadata")
}
host, ok := md[headerName]
if !ok {
return "", fmt.Errorf("cannot find header: %v", headerName)
}
if len(host) != 1 {
return "", fmt.Errorf("invalid host header: %v", host)
}
return host[0], nil
}

View File

@ -0,0 +1,174 @@
package middleware
import (
"context"
"fmt"
"reflect"
"testing"
"google.golang.org/grpc"
"google.golang.org/grpc/metadata"
"github.com/caos/zitadel/internal/api/authz"
)
func Test_hostNameFromContext(t *testing.T) {
type args struct {
ctx context.Context
headerName string
}
type res struct {
want string
err bool
}
tests := []struct {
name string
args args
res res
}{
{
"empty context, error",
args{
ctx: context.Background(),
headerName: "header",
},
res{
want: "",
err: true,
},
},
{
"header not found",
args{
ctx: metadata.NewIncomingContext(context.Background(), nil),
headerName: "header",
},
res{
want: "",
err: true,
},
},
{
"header not found",
args{
ctx: metadata.NewIncomingContext(context.Background(), metadata.Pairs("header", "value")),
headerName: "header",
},
res{
want: "value",
err: false,
},
},
}
for _, tt := range tests {
t.Run(tt.name, func(t *testing.T) {
got, err := hostNameFromContext(tt.args.ctx, tt.args.headerName)
if (err != nil) != tt.res.err {
t.Errorf("hostNameFromContext() error = %v, wantErr %v", err, tt.res.err)
return
}
if got != tt.res.want {
t.Errorf("hostNameFromContext() got = %v, want %v", got, tt.res.want)
}
})
}
}
func Test_setInstance(t *testing.T) {
type args struct {
ctx context.Context
req interface{}
info *grpc.UnaryServerInfo
handler grpc.UnaryHandler
verifier authz.InstanceVerifier
headerName string
}
type res struct {
want interface{}
err bool
}
tests := []struct {
name string
args args
res res
}{
{
"hostname not found, error",
args{
ctx: context.Background(),
},
res{
want: nil,
err: true,
},
},
{
"invalid host, error",
args{
ctx: metadata.NewIncomingContext(context.Background(), metadata.Pairs("header", "host2")),
req: &mockRequest{},
verifier: &mockInstanceVerifier{"host"},
headerName: "header",
},
res{
want: nil,
err: true,
},
},
{
"valid host",
args{
ctx: metadata.NewIncomingContext(context.Background(), metadata.Pairs("header", "host")),
req: &mockRequest{},
verifier: &mockInstanceVerifier{"host"},
headerName: "header",
handler: func(ctx context.Context, req interface{}) (interface{}, error) {
return req, nil
},
},
res{
want: &mockRequest{},
err: false,
},
},
}
for _, tt := range tests {
t.Run(tt.name, func(t *testing.T) {
got, err := setInstance(tt.args.ctx, tt.args.req, tt.args.info, tt.args.handler, tt.args.verifier, tt.args.headerName)
if (err != nil) != tt.res.err {
t.Errorf("setInstance() error = %v, wantErr %v", err, tt.res.err)
return
}
if !reflect.DeepEqual(got, tt.res.want) {
t.Errorf("setInstance() got = %v, want %v", got, tt.res.want)
}
})
}
}
type mockRequest struct{}
type mockInstanceVerifier struct {
host string
}
func (m *mockInstanceVerifier) InstanceByHost(ctx context.Context, host string) (authz.Instance, error) {
if host != m.host {
return nil, fmt.Errorf("invalid host")
}
return &mockInstance{}, nil
}
type mockInstance struct{}
func (m *mockInstance) InstanceID() string {
return "instanceID"
}
func (m *mockInstance) ProjectID() string {
return "projectID"
}
func (m *mockInstance) ConsoleClientID() string {
return "consoleClientID"
}

View File

@ -20,7 +20,7 @@ type Server interface {
AuthMethods() authz.MethodMapping
}
func CreateServer(verifier *authz.TokenVerifier, authConfig authz.Config, queries *query.Queries) *grpc.Server {
func CreateServer(verifier *authz.TokenVerifier, authConfig authz.Config, queries *query.Queries, hostHeaderName string) *grpc.Server {
metricTypes := []metrics.MetricType{metrics.MetricTypeTotalCount, metrics.MetricTypeRequestCount, metrics.MetricTypeStatusCode}
return grpc.NewServer(
grpc.UnaryInterceptor(
@ -30,6 +30,7 @@ func CreateServer(verifier *authz.TokenVerifier, authConfig authz.Config, querie
middleware.SentryHandler(),
middleware.NoCacheInterceptor(),
middleware.ErrorHandler(),
middleware.InstanceInterceptor(queries, hostHeaderName),
middleware.AuthorizationInterceptor(verifier, authConfig),
middleware.TranslationHandler(queries),
middleware.ValidationHandler(),

View File

@ -0,0 +1,65 @@
package middleware
import (
"context"
"fmt"
"net/http"
"github.com/caos/zitadel/internal/api/authz"
"github.com/caos/zitadel/internal/telemetry/tracing"
)
type instanceInterceptor struct {
verifier authz.InstanceVerifier
headerName string
}
func InstanceInterceptor(verifier authz.InstanceVerifier, headerName string) *instanceInterceptor {
return &instanceInterceptor{
verifier: verifier,
headerName: headerName,
}
}
func (a *instanceInterceptor) Handler(next http.Handler) http.Handler {
return http.HandlerFunc(func(w http.ResponseWriter, r *http.Request) {
ctx, err := setInstance(r, a.verifier, a.headerName)
if err != nil {
http.Error(w, err.Error(), http.StatusUnauthorized)
return
}
r = r.WithContext(ctx)
next.ServeHTTP(w, r)
})
}
func (a *instanceInterceptor) HandlerFunc(next http.HandlerFunc) http.HandlerFunc {
return func(w http.ResponseWriter, r *http.Request) {
ctx, err := setInstance(r, a.verifier, a.headerName)
if err != nil {
http.Error(w, err.Error(), http.StatusForbidden)
return
}
r = r.WithContext(ctx)
next.ServeHTTP(w, r)
}
}
func setInstance(r *http.Request, verifier authz.InstanceVerifier, headerName string) (_ context.Context, err error) {
ctx := r.Context()
authCtx, span := tracing.NewServerInterceptorSpan(ctx)
defer func() { span.EndWithError(err) }()
host := r.Header.Get(headerName)
if host == "" {
return nil, fmt.Errorf("host header %s not found", headerName)
}
instance, err := verifier.InstanceByHost(authCtx, host)
if err != nil {
return nil, err
}
span.End()
return authz.WithInstance(ctx, instance), nil
}

View File

@ -0,0 +1,258 @@
package middleware
import (
"context"
"fmt"
"net/http"
"net/http/httptest"
"reflect"
"testing"
"github.com/stretchr/testify/assert"
"github.com/caos/zitadel/internal/api/authz"
)
func Test_instanceInterceptor_Handler(t *testing.T) {
type fields struct {
verifier authz.InstanceVerifier
headerName string
}
type args struct {
request *http.Request
}
type res struct {
statusCode int
context context.Context
}
tests := []struct {
name string
fields fields
args args
res res
}{
{
"setInstance error",
fields{
verifier: &mockInstanceVerifier{},
headerName: "header",
},
args{
request: httptest.NewRequest("", "/url", nil),
},
res{
statusCode: 403,
context: nil,
},
},
{
"setInstance ok",
fields{
verifier: &mockInstanceVerifier{"host"},
headerName: "header",
},
args{
request: func() *http.Request {
r := httptest.NewRequest("", "/url", nil)
r.Header.Set("header", "host")
return r
}(),
},
res{
statusCode: 200,
context: authz.WithInstance(context.Background(), &mockInstance{}),
},
},
}
for _, tt := range tests {
t.Run(tt.name, func(t *testing.T) {
a := &instanceInterceptor{
verifier: tt.fields.verifier,
headerName: tt.fields.headerName,
}
next := &testHandler{}
got := a.HandlerFunc(next.ServeHTTP)
rr := httptest.NewRecorder()
got.ServeHTTP(rr, tt.args.request)
assert.Equal(t, tt.res.statusCode, rr.Code)
assert.Equal(t, tt.res.context, next.context)
})
}
}
func Test_instanceInterceptor_HandlerFunc(t *testing.T) {
type fields struct {
verifier authz.InstanceVerifier
headerName string
}
type args struct {
request *http.Request
}
type res struct {
statusCode int
context context.Context
}
tests := []struct {
name string
fields fields
args args
res res
}{
{
"setInstance error",
fields{
verifier: &mockInstanceVerifier{},
headerName: "header",
},
args{
request: httptest.NewRequest("", "/url", nil),
},
res{
statusCode: 403,
context: nil,
},
},
{
"setInstance ok",
fields{
verifier: &mockInstanceVerifier{"host"},
headerName: "header",
},
args{
request: func() *http.Request {
r := httptest.NewRequest("", "/url", nil)
r.Header.Set("header", "host")
return r
}(),
},
res{
statusCode: 200,
context: authz.WithInstance(context.Background(), &mockInstance{}),
},
},
}
for _, tt := range tests {
t.Run(tt.name, func(t *testing.T) {
a := &instanceInterceptor{
verifier: tt.fields.verifier,
headerName: tt.fields.headerName,
}
next := &testHandler{}
got := a.HandlerFunc(next.ServeHTTP)
rr := httptest.NewRecorder()
got.ServeHTTP(rr, tt.args.request)
assert.Equal(t, tt.res.statusCode, rr.Code)
assert.Equal(t, tt.res.context, next.context)
})
}
}
func Test_setInstance(t *testing.T) {
type args struct {
r *http.Request
verifier authz.InstanceVerifier
headerName string
}
type res struct {
want context.Context
err bool
}
tests := []struct {
name string
args args
res res
}{
{
"hostname not found, error",
args{
r: func() *http.Request {
r := httptest.NewRequest("", "/url", nil)
return r
}(),
verifier: &mockInstanceVerifier{},
headerName: "",
},
res{
want: nil,
err: true,
},
},
{
"invalid host, error",
args{
r: func() *http.Request {
r := httptest.NewRequest("", "/url", nil)
r.Header.Set("header", "host2")
return r
}(),
verifier: &mockInstanceVerifier{"host"},
headerName: "header",
},
res{
want: nil,
err: true,
},
},
{
"valid host",
args{
r: func() *http.Request {
r := httptest.NewRequest("", "/url", nil)
r.Header.Set("header", "host")
return r
}(),
verifier: &mockInstanceVerifier{"host"},
headerName: "header",
},
res{
want: authz.WithInstance(context.Background(), &mockInstance{}),
err: false,
},
},
}
for _, tt := range tests {
t.Run(tt.name, func(t *testing.T) {
got, err := setInstance(tt.args.r, tt.args.verifier, tt.args.headerName)
if (err != nil) != tt.res.err {
t.Errorf("setInstance() error = %v, wantErr %v", err, tt.res.err)
return
}
if !reflect.DeepEqual(got, tt.res.want) {
t.Errorf("setInstance() got = %v, want %v", got, tt.res.want)
}
})
}
}
type testHandler struct {
context context.Context
}
func (t *testHandler) ServeHTTP(w http.ResponseWriter, r *http.Request) {
t.context = r.Context()
}
type mockInstanceVerifier struct {
host string
}
func (m *mockInstanceVerifier) InstanceByHost(ctx context.Context, host string) (authz.Instance, error) {
if host != m.host {
return nil, fmt.Errorf("invalid host")
}
return &mockInstance{}, nil
}
type mockInstance struct{}
func (m *mockInstance) InstanceID() string {
return "instanceID"
}
func (m *mockInstance) ProjectID() string {
return "projectID"
}
func (m *mockInstance) ConsoleClientID() string {
return "consoleClientID"
}

View File

@ -46,7 +46,7 @@ func (o *OPStorage) AuthRequestByID(ctx context.Context, id string) (_ op.AuthRe
if !ok {
return nil, errors.ThrowPreconditionFailed(nil, "OIDC-D3g21", "no user agent id")
}
instanceID := authz.GetInstance(ctx).ID
instanceID := authz.GetInstance(ctx).InstanceID()
resp, err := o.repo.AuthRequestByIDCheckLoggedIn(ctx, id, userAgentID, instanceID)
if err != nil {
return nil, err
@ -58,7 +58,7 @@ func (o *OPStorage) AuthRequestByCode(ctx context.Context, code string) (_ op.Au
ctx, span := tracing.NewSpan(ctx)
defer func() { span.EndWithError(err) }()
instanceID := authz.GetInstance(ctx).ID
instanceID := authz.GetInstance(ctx).InstanceID()
resp, err := o.repo.AuthRequestByCode(ctx, code, instanceID)
if err != nil {
return nil, err
@ -73,7 +73,7 @@ func (o *OPStorage) SaveAuthCode(ctx context.Context, id, code string) (err erro
if !ok {
return errors.ThrowPreconditionFailed(nil, "OIDC-Dgus2", "no user agent id")
}
instanceID := authz.GetInstance(ctx).ID
instanceID := authz.GetInstance(ctx).InstanceID()
return o.repo.SaveAuthCode(ctx, id, code, userAgentID, instanceID)
}
@ -81,7 +81,7 @@ func (o *OPStorage) DeleteAuthRequest(ctx context.Context, id string) (err error
ctx, span := tracing.NewSpan(ctx)
defer func() { span.EndWithError(err) }()
instanceID := authz.GetInstance(ctx).ID
instanceID := authz.GetInstance(ctx).InstanceID()
return o.repo.DeleteAuthRequest(ctx, id, instanceID)
}

View File

@ -133,7 +133,7 @@ func CreateAuthRequestToBusiness(ctx context.Context, authReq *oidc.AuthRequest,
SelectedIDPConfigID: GetSelectedIDPIDFromScopes(authReq.Scopes),
MaxAuthAge: MaxAgeToBusiness(authReq.MaxAge),
UserID: userID,
InstanceID: authz.GetInstance(ctx).ID,
InstanceID: authz.GetInstance(ctx).InstanceID(),
Request: &domain.AuthRequestOIDC{
Scopes: authReq.Scopes,
ResponseType: ResponseTypeToBusiness(authReq.ResponseType),

View File

@ -83,13 +83,13 @@ type OPStorage struct {
assetAPIPrefix string
}
func NewProvider(ctx context.Context, config Config, issuer, defaultLogoutRedirectURI string, command *command.Commands, query *query.Queries, repo repository.Repository, keyConfig systemdefaults.KeyConfig, encryptionAlg crypto.EncryptionAlgorithm, cryptoKey []byte, es *eventstore.Eventstore, projections *sql.DB, keyChan <-chan interface{}, userAgentCookie func(http.Handler) http.Handler) (op.OpenIDProvider, error) {
func NewProvider(ctx context.Context, config Config, issuer, defaultLogoutRedirectURI string, command *command.Commands, query *query.Queries, repo repository.Repository, keyConfig systemdefaults.KeyConfig, encryptionAlg crypto.EncryptionAlgorithm, cryptoKey []byte, es *eventstore.Eventstore, projections *sql.DB, keyChan <-chan interface{}, userAgentCookie, instanceHandler func(http.Handler) http.Handler) (op.OpenIDProvider, error) {
opConfig, err := createOPConfig(config, issuer, defaultLogoutRedirectURI, cryptoKey)
if err != nil {
return nil, caos_errs.ThrowInternal(err, "OIDC-EGrqd", "cannot create op config: %w")
}
storage := newStorage(config, command, query, repo, keyConfig, encryptionAlg, es, projections, keyChan)
options, err := createOptions(config, userAgentCookie)
options, err := createOptions(config, userAgentCookie, instanceHandler)
if err != nil {
return nil, caos_errs.ThrowInternal(err, "OIDC-D3gq1", "cannot create options: %w")
}
@ -131,12 +131,13 @@ func createOPConfig(config Config, issuer, defaultLogoutRedirectURI string, cryp
return opConfig, nil
}
func createOptions(config Config, userAgentCookie func(http.Handler) http.Handler) ([]op.Option, error) {
func createOptions(config Config, userAgentCookie, instanceHandler func(http.Handler) http.Handler) ([]op.Option, error) {
metricTypes := []metrics.MetricType{metrics.MetricTypeRequestCount, metrics.MetricTypeStatusCode, metrics.MetricTypeTotalCount}
interceptor := op.WithHttpInterceptors(
middleware.MetricsHandler(metricTypes),
middleware.TelemetryHandler(),
middleware.NoCacheInterceptor,
instanceHandler,
userAgentCookie,
http_utils.CopyHeadersToContext,
)

View File

@ -11,6 +11,8 @@ import (
"github.com/caos/logging"
"github.com/caos/zitadel/internal/api/authz"
"github.com/caos/zitadel/internal/api/http/middleware"
)
@ -51,12 +53,7 @@ func (i *spaHandler) Open(name string) (http.File, error) {
return i.fileSystem.Open("/index.html")
}
func Start(config Config, domain, url, issuer, clientID string) (http.Handler, error) {
environmentJSON, err := createEnvironmentJSON(url, issuer, clientID)
if err != nil {
return nil, fmt.Errorf("unable to marshal env for console: %w", err)
}
func Start(config Config, domain, url, issuer string, instanceHandler func(http.Handler) http.Handler) (http.Handler, error) {
consoleDir := consoleDefaultDir
if config.ConsoleOverwriteDir != "" {
consoleDir = config.ConsoleOverwriteDir
@ -73,10 +70,20 @@ func Start(config Config, domain, url, issuer, clientID string) (http.Handler, e
handler := &http.ServeMux{}
handler.Handle("/", cache(security(http.FileServer(&spaHandler{consoleHTTPDir}))))
handler.Handle(envRequestPath, cache(security(http.HandlerFunc(func(w http.ResponseWriter, r *http.Request) {
_, err := w.Write(environmentJSON)
handler.Handle(envRequestPath, instanceHandler(cache(security(http.HandlerFunc(func(w http.ResponseWriter, r *http.Request) {
instance := authz.GetInstance(r.Context())
if instance.InstanceID() == "" {
http.Error(w, "empty instanceID", http.StatusInternalServerError)
return
}
environmentJSON, err := createEnvironmentJSON(url, issuer, instance.ConsoleClientID())
if err != nil {
http.Error(w, fmt.Sprintf("unable to marshal env for console: %v", err), http.StatusInternalServerError)
return
}
_, err = w.Write(environmentJSON)
logging.OnError(err).Error("error serving environment.json")
}))))
})))))
return handler, nil
}
@ -92,23 +99,15 @@ func csp(zitadelDomain string) *middleware.CSP {
return &csp
}
func createEnvironmentJSON(url, issuer, clientID string) ([]byte, error) {
func createEnvironmentJSON(api, issuer, clientID string) ([]byte, error) {
environment := struct {
AuthServiceUrl string `json:"authServiceUrl,omitempty"`
MgmtServiceUrl string `json:"mgmtServiceUrl,omitempty"`
AdminServiceUrl string `json:"adminServiceUrl,omitempty"`
SubscriptionServiceUrl string `json:"subscriptionServiceUrl,omitempty"`
AssetServiceUrl string `json:"assetServiceUrl,omitempty"`
Issuer string `json:"issuer,omitempty"`
ClientID string `json:"clientid,omitempty"`
API string `json:"api,omitempty"`
Issuer string `json:"issuer,omitempty"`
ClientID string `json:"clientid,omitempty"`
}{
AuthServiceUrl: url,
MgmtServiceUrl: url,
AdminServiceUrl: url,
SubscriptionServiceUrl: url,
AssetServiceUrl: url,
Issuer: issuer,
ClientID: clientID,
API: api,
Issuer: issuer,
ClientID: clientID,
}
return json.Marshal(environment)
}

View File

@ -20,7 +20,7 @@ func (l *Login) getAuthRequest(r *http.Request) (*domain.AuthRequest, error) {
return nil, nil
}
userAgentID, _ := http_mw.UserAgentIDFromCtx(r.Context())
instanceID := authz.GetInstance(r.Context()).ID
instanceID := authz.GetInstance(r.Context()).InstanceID()
return l.authRepo.AuthRequestByID(r.Context(), authRequestID, userAgentID, instanceID)
}

View File

@ -89,7 +89,7 @@ func (l *Login) handleIDP(w http.ResponseWriter, r *http.Request, authReq *domai
return
}
userAgentID, _ := http_mw.UserAgentIDFromCtx(r.Context())
instanceID := authz.GetInstance(r.Context()).ID
instanceID := authz.GetInstance(r.Context()).InstanceID()
err = l.authRepo.SelectExternalIDP(r.Context(), authReq.ID, idpConfig.IDPConfigID, userAgentID, instanceID)
if err != nil {
l.renderLogin(w, r, authReq, err)
@ -142,7 +142,7 @@ func (l *Login) handleExternalLoginCallback(w http.ResponseWriter, r *http.Reque
return
}
userAgentID, _ := http_mw.UserAgentIDFromCtx(r.Context())
instanceID := authz.GetInstance(r.Context()).ID
instanceID := authz.GetInstance(r.Context()).InstanceID()
authReq, err := l.authRepo.AuthRequestByID(r.Context(), data.State, userAgentID, instanceID)
if err != nil {
l.renderError(w, r, authReq, err)
@ -202,7 +202,7 @@ func (l *Login) handleExternalUserAuthenticated(w http.ResponseWriter, r *http.R
return
}
instanceID := authz.GetInstance(r.Context()).ID
instanceID := authz.GetInstance(r.Context()).InstanceID()
err = l.authRepo.CheckExternalUserLogin(setContext(r.Context(), ""), authReq.ID, userAgentID, instanceID, externalUser, domain.BrowserInfoFromRequest(r))
if err != nil {
if errors.IsNotFound(err) {
@ -329,7 +329,7 @@ func (l *Login) handleExternalNotFoundOptionCheck(w http.ResponseWriter, r *http
return
} else if data.ResetLinking {
userAgentID, _ := http_mw.UserAgentIDFromCtx(r.Context())
instanceID := authz.GetInstance(r.Context()).ID
instanceID := authz.GetInstance(r.Context()).InstanceID()
err = l.authRepo.ResetLinkingUsers(r.Context(), authReq.ID, userAgentID, instanceID)
if err != nil {
l.renderExternalNotFoundOption(w, r, authReq, nil, nil, nil, nil, err)
@ -368,7 +368,7 @@ func (l *Login) handleAutoRegister(w http.ResponseWriter, r *http.Request, authR
}
userAgentID, _ := http_mw.UserAgentIDFromCtx(r.Context())
instanceID := authz.GetInstance(r.Context()).ID
instanceID := authz.GetInstance(r.Context()).InstanceID()
if len(authReq.LinkingUsers) == 0 {
l.renderError(w, r, authReq, caos_errors.ThrowPreconditionFailed(nil, "LOGIN-asfg3", "Errors.ExternalIDP.NoExternalUserData"))
return

View File

@ -68,7 +68,7 @@ func (l *Login) handleExternalRegister(w http.ResponseWriter, r *http.Request) {
return
}
userAgentID, _ := http_mw.UserAgentIDFromCtx(r.Context())
instanceID := authz.GetInstance(r.Context()).ID
instanceID := authz.GetInstance(r.Context()).InstanceID()
err = l.authRepo.SelectExternalIDP(r.Context(), authReq.ID, idpConfig.IDPConfigID, userAgentID, instanceID)
if err != nil {
l.renderLogin(w, r, authReq, err)
@ -89,7 +89,7 @@ func (l *Login) handleExternalRegisterCallback(w http.ResponseWriter, r *http.Re
return
}
userAgentID, _ := http_mw.UserAgentIDFromCtx(r.Context())
instanceID := authz.GetInstance(r.Context()).ID
instanceID := authz.GetInstance(r.Context()).InstanceID()
authReq, err := l.authRepo.AuthRequestByID(r.Context(), data.State, userAgentID, instanceID)
if err != nil {
l.renderError(w, r, authReq, err)

View File

@ -45,7 +45,7 @@ func (l *Login) handleJWTRequest(w http.ResponseWriter, r *http.Request) {
l.renderError(w, r, nil, err)
return
}
instanceID := authz.GetInstance(r.Context()).ID
instanceID := authz.GetInstance(r.Context()).InstanceID()
authReq, err := l.authRepo.AuthRequestByID(r.Context(), data.AuthRequestID, userAgentID, instanceID)
if err != nil {
l.renderError(w, r, authReq, err)
@ -209,7 +209,7 @@ func (l *Login) handleJWTCallback(w http.ResponseWriter, r *http.Request) {
l.renderError(w, r, nil, err)
return
}
instanceID := authz.GetInstance(r.Context()).ID
instanceID := authz.GetInstance(r.Context()).InstanceID()
authReq, err := l.authRepo.AuthRequestByID(r.Context(), data.AuthRequestID, userAgentID, instanceID)
if err != nil {
l.renderError(w, r, authReq, err)

View File

@ -14,7 +14,7 @@ const (
func (l *Login) linkUsers(w http.ResponseWriter, r *http.Request, authReq *domain.AuthRequest, err error) {
userAgentID, _ := http_mw.UserAgentIDFromCtx(r.Context())
instanceID := authz.GetInstance(r.Context()).ID
instanceID := authz.GetInstance(r.Context()).InstanceID()
err = l.authRepo.LinkExternalUsers(setContext(r.Context(), authReq.UserOrgID), authReq.ID, userAgentID, instanceID, domain.BrowserInfoFromRequest(r))
l.renderLinkUsersDone(w, r, authReq, err)
}

View File

@ -66,7 +66,8 @@ func CreateLogin(config Config,
baseURL,
oidcAuthCallbackURL string,
externalSecure bool,
userAgentCookie mux.MiddlewareFunc,
userAgentCookie,
instanceHandler mux.MiddlewareFunc,
userCodeAlg crypto.EncryptionAlgorithm,
idpConfigAlg crypto.EncryptionAlgorithm,
csrfCookieKey []byte,
@ -104,7 +105,7 @@ func CreateLogin(config Config,
return nil, fmt.Errorf("unable to create cacheInterceptor: %w", err)
}
security := middleware.SecurityHeaders(csp(), login.cspErrorHandler)
login.router = CreateRouter(login, statikFS, csrfInterceptor, cacheInterceptor, security, userAgentCookie, middleware.TelemetryHandler(EndpointResources))
login.router = CreateRouter(login, statikFS, instanceHandler, csrfInterceptor, cacheInterceptor, security, userAgentCookie, middleware.TelemetryHandler(EndpointResources))
login.renderer = CreateRenderer(HandlerPrefix, statikFS, staticStorage, config.LanguageCookieName, systemDefaults.DefaultLanguage)
login.parser = form.NewParser()
return login, nil

View File

@ -60,7 +60,7 @@ func (l *Login) handleLoginNameCheck(w http.ResponseWriter, r *http.Request) {
return
}
userAgentID, _ := http_mw.UserAgentIDFromCtx(r.Context())
instanceID := authz.GetInstance(r.Context()).ID
instanceID := authz.GetInstance(r.Context()).InstanceID()
loginName := data.LoginName
err = l.authRepo.CheckLoginName(r.Context(), authReq.ID, loginName, userAgentID, instanceID)
if err != nil {

View File

@ -36,7 +36,7 @@ func (l *Login) handleMFAVerify(w http.ResponseWriter, r *http.Request) {
}
if data.MFAType == domain.MFATypeOTP {
userAgentID, _ := http_mw.UserAgentIDFromCtx(r.Context())
instanceID := authz.GetInstance(r.Context()).ID
instanceID := authz.GetInstance(r.Context()).InstanceID()
err = l.authRepo.VerifyMFAOTP(setContext(r.Context(), authReq.UserOrgID), authReq.ID, authReq.UserID, authReq.UserOrgID, data.Code, userAgentID, instanceID, domain.BrowserInfoFromRequest(r))
if err != nil {
l.renderMFAVerifySelected(w, r, authReq, step, domain.MFATypeOTP, err)

View File

@ -30,7 +30,7 @@ func (l *Login) renderU2FVerification(w http.ResponseWriter, r *http.Request, au
var webAuthNLogin *domain.WebAuthNLogin
if err == nil {
userAgentID, _ := http_mw.UserAgentIDFromCtx(r.Context())
instanceID := authz.GetInstance(r.Context()).ID
instanceID := authz.GetInstance(r.Context()).InstanceID()
webAuthNLogin, err = l.authRepo.BeginMFAU2FLogin(setContext(r.Context(), authReq.UserOrgID), authReq.UserID, authReq.UserOrgID, authReq.ID, userAgentID, instanceID)
}
if err != nil {
@ -72,7 +72,7 @@ func (l *Login) handleU2FVerification(w http.ResponseWriter, r *http.Request) {
return
}
userAgentID, _ := http_mw.UserAgentIDFromCtx(r.Context())
instanceID := authz.GetInstance(r.Context()).ID
instanceID := authz.GetInstance(r.Context()).InstanceID()
err = l.authRepo.VerifyMFAU2F(setContext(r.Context(), authReq.UserOrgID), authReq.UserID, authReq.UserOrgID, authReq.ID, userAgentID, instanceID, credData, domain.BrowserInfoFromRequest(r))
if err != nil {
l.renderU2FVerification(w, r, authReq, step.MFAProviders, err)

View File

@ -95,7 +95,7 @@ func (l *Login) handleRegisterCheck(w http.ResponseWriter, r *http.Request) {
return
}
userAgentID, _ := http_mw.UserAgentIDFromCtx(r.Context())
instanceID := authz.GetInstance(r.Context()).ID
instanceID := authz.GetInstance(r.Context()).InstanceID()
err = l.authRepo.SelectUser(r.Context(), authRequest.ID, user.AggregateID, userAgentID, instanceID)
if err != nil {
l.renderRegister(w, r, authRequest, data, err)

View File

@ -39,7 +39,7 @@ func (l *Login) handleSelectUser(w http.ResponseWriter, r *http.Request) {
return
}
userAgentID, _ := http_mw.UserAgentIDFromCtx(r.Context())
instanceID := authz.GetInstance(r.Context()).ID
instanceID := authz.GetInstance(r.Context()).InstanceID()
err = l.authRepo.SelectUser(r.Context(), authSession.ID, data.UserID, userAgentID, instanceID)
if err != nil {
l.renderError(w, r, authSession, err)

View File

@ -1145,7 +1145,7 @@ func activeUserByID(ctx context.Context, userViewProvider userViewProvider, user
if !(user.State == user_model.UserStateActive || user.State == user_model.UserStateInitial) {
return nil, errors.ThrowPreconditionFailed(nil, "EVENT-FJ262", "Errors.User.NotActive")
}
org, err := queries.OrgByID(context.TODO(), user.ResourceOwner)
org, err := queries.OrgByID(ctx, user.ResourceOwner)
if err != nil {
return nil, err
}

View File

@ -73,5 +73,5 @@ func (h *handler) QueryLimit() uint64 {
}
func withInstanceID(ctx context.Context, instanceID string) context.Context {
return authz.WithInstance(ctx, authz.Instance{ID: instanceID})
return authz.WithInstanceID(ctx, instanceID)
}

View File

@ -35,18 +35,18 @@ func (c *AuthRequestCache) GetAuthRequestByCode(_ context.Context, code, instanc
}
func (c *AuthRequestCache) SaveAuthRequest(_ context.Context, request *domain.AuthRequest) error {
return c.saveAuthRequest(request, "INSERT INTO auth.auth_requests (id, request, instance_id, creation_date, change_date, request_type) VALUES($1, $2, $3, $3, $4, $5)", request.CreationDate, request.InstanceID, request.Request.Type())
return c.saveAuthRequest(request, "INSERT INTO auth.auth_requests (id, request, instance_id, creation_date, change_date, request_type) VALUES($1, $2, $3, $4, $4, $5)", request.CreationDate, request.Request.Type())
}
func (c *AuthRequestCache) UpdateAuthRequest(_ context.Context, request *domain.AuthRequest) error {
if request.ChangeDate.IsZero() {
request.ChangeDate = time.Now()
}
return c.saveAuthRequest(request, "UPDATE auth.auth_requests SET request = $2, instance_id = $3 change_date = $4, code = $5 WHERE id = $1", request.ChangeDate, request.InstanceID, request.Code)
return c.saveAuthRequest(request, "UPDATE auth.auth_requests SET request = $2, instance_id = $3, change_date = $4, code = $5 WHERE id = $1", request.ChangeDate, request.Code)
}
func (c *AuthRequestCache) DeleteAuthRequest(_ context.Context, id, instanceID string) error {
_, err := c.client.Exec("DELETE FROM auth.auth_requests WHERE instance = $1 and id = $2", instanceID, id)
_, err := c.client.Exec("DELETE FROM auth.auth_requests WHERE instance_id = $1 and id = $2", instanceID, id)
if err != nil {
return caos_errs.ThrowInternal(err, "CACHE-dsHw3", "unable to delete auth request")
}
@ -56,7 +56,7 @@ func (c *AuthRequestCache) DeleteAuthRequest(_ context.Context, id, instanceID s
func (c *AuthRequestCache) getAuthRequest(key, value, instanceID string) (*domain.AuthRequest, error) {
var b []byte
var requestType domain.AuthRequestType
query := fmt.Sprintf("SELECT request, request_type FROM auth.auth_requests WHERE instance = $1 and %s = $2", key)
query := fmt.Sprintf("SELECT request, request_type FROM auth.auth_requests WHERE instance_id = $1 and %s = $2", key)
err := c.client.QueryRow(query, instanceID, value).Scan(&b, &requestType)
if err != nil {
if errors.Is(err, sql.ErrNoRows) {
@ -74,18 +74,14 @@ func (c *AuthRequestCache) getAuthRequest(key, value, instanceID string) (*domai
return request, nil
}
func (c *AuthRequestCache) saveAuthRequest(request *domain.AuthRequest, query string, date time.Time, instanceID string, param interface{}) error {
func (c *AuthRequestCache) saveAuthRequest(request *domain.AuthRequest, query string, date time.Time, param interface{}) error {
b, err := json.Marshal(request)
if err != nil {
return caos_errs.ThrowInternal(err, "CACHE-os0GH", "Errors.Internal")
}
stmt, err := c.client.Prepare(query)
_, err = c.client.Exec(query, request.ID, b, request.InstanceID, date, param)
if err != nil {
return caos_errs.ThrowInternal(err, "CACHE-su3GK", "Errors.Internal")
}
_, err = stmt.Exec(request.ID, b, date, instanceID, param)
if err != nil {
return caos_errs.ThrowInternal(err, "CACHE-sj8iS", "Errors.Internal")
}
return nil
}

View File

@ -98,7 +98,7 @@ func (repo *TokenVerifierRepo) VerifyAccessToken(ctx context.Context, tokenStrin
}
func (repo *TokenVerifierRepo) ProjectIDAndOriginsByClientID(ctx context.Context, clientID string) (projectID string, origins []string, err error) {
app, err := repo.View.ApplicationByOIDCClientID(clientID)
app, err := repo.View.ApplicationByOIDCClientID(ctx, clientID)
if err != nil {
return "", nil, err
}

View File

@ -44,7 +44,7 @@ func (repo *UserMembershipRepo) searchUserMemberships(ctx context.Context) ([]*u
{
Key: user_model.UserMembershipSearchKeyInstanceID,
Method: domain.SearchMethodEquals,
Value: instance.ID,
Value: instance.InstanceID(),
},
},
})
@ -66,7 +66,7 @@ func (repo *UserMembershipRepo) searchUserMemberships(ctx context.Context) ([]*u
{
Key: user_model.UserMembershipSearchKeyInstanceID,
Method: domain.SearchMethodEquals,
Value: instance.ID,
Value: instance.InstanceID(),
},
},
})

View File

@ -8,8 +8,8 @@ import (
"github.com/caos/zitadel/internal/telemetry/tracing"
)
func (v *View) ApplicationByOIDCClientID(clientID string) (*query.App, error) {
return v.Query.AppByOIDCClientID(context.TODO(), clientID)
func (v *View) ApplicationByOIDCClientID(ctx context.Context, clientID string) (*query.App, error) {
return v.Query.AppByOIDCClientID(ctx, clientID)
}
func (v *View) ApplicationByProjecIDAndAppName(ctx context.Context, projectID, appName string) (_ *query.App, err error) {

View File

@ -61,6 +61,19 @@ type InstanceSetup struct {
PrivacyLink string
HelpLink string
}
LabelPolicy struct {
PrimaryColor string
BackgroundColor string
WarnColor string
FontColor string
PrimaryColorDark string
BackgroundColorDark string
WarnColorDark string
FontColorDark string
HideLoginNameSuffix bool
ErrorMsgPopup bool
DisableWatermark bool
}
LockoutPolicy struct {
MaxAttempts uint64
ShouldShowLockoutFailure bool
@ -134,7 +147,7 @@ func (command *Command) SetUpInstance(ctx context.Context, setup *InstanceSetup)
// if err != nil {
// return nil, err
// }
ctx = authz.SetCtxData(authz.WithInstance(ctx, authz.Instance{ID: "system"}), authz.CtxData{OrgID: domain.IAMID, ResourceOwner: domain.IAMID})
ctx = authz.SetCtxData(authz.WithInstanceID(ctx, "system"), authz.CtxData{OrgID: domain.IAMID, ResourceOwner: domain.IAMID})
orgID, err := id.SonyFlakeGenerator.Next()
if err != nil {
@ -196,6 +209,22 @@ func (command *Command) SetUpInstance(ctx context.Context, setup *InstanceSetup)
AddPrivacyPolicy(instanceAgg, setup.PrivacyPolicy.TOSLink, setup.PrivacyPolicy.PrivacyLink, setup.PrivacyPolicy.HelpLink),
AddDefaultLockoutPolicy(instanceAgg, setup.LockoutPolicy.MaxAttempts, setup.LockoutPolicy.ShouldShowLockoutFailure),
AddDefaultLabelPolicy(
instanceAgg,
setup.LabelPolicy.PrimaryColor,
setup.LabelPolicy.BackgroundColor,
setup.LabelPolicy.WarnColor,
setup.LabelPolicy.FontColor,
setup.LabelPolicy.PrimaryColorDark,
setup.LabelPolicy.BackgroundColorDark,
setup.LabelPolicy.WarnColorDark,
setup.LabelPolicy.FontColorDark,
setup.LabelPolicy.HideLoginNameSuffix,
setup.LabelPolicy.ErrorMsgPopup,
setup.LabelPolicy.DisableWatermark,
),
ActivateDefaultLabelPolicy(instanceAgg),
AddEmailTemplate(instanceAgg, setup.EmailTemplate),
}
@ -207,9 +236,9 @@ func (command *Command) SetUpInstance(ctx context.Context, setup *InstanceSetup)
AddOrg(orgAgg, setup.Org.Name, command.iamDomain),
AddHumanCommand(userAgg, &setup.Org.Human, command.userPasswordAlg),
AddOrgMember(orgAgg, userID, domain.RoleOrgOwner),
AddInstanceMember(instanceAgg, userID, domain.RoleIAMOwner),
AddProject(projectAgg, zitadelProjectName, userID, false, false, false, domain.PrivateLabelingSettingUnspecified),
SetIAMProject(instanceAgg, projectAgg.ID),
AddAPIApp(
@ -260,6 +289,7 @@ func (command *Command) SetUpInstance(ctx context.Context, setup *InstanceSetup)
0,
nil,
),
SetIAMConsoleID(instanceAgg, setup.Zitadel.consoleClientID),
)
cmds, err := preparation.PrepareCommands(ctx, command.es.Filter, validations...)
@ -278,7 +308,7 @@ func (command *Command) SetUpInstance(ctx context.Context, setup *InstanceSetup)
}, nil
}
//SetIAMProject defines the commands to set the id of the IAM project onto the instance
//SetIAMProject defines the command to set the id of the IAM project onto the instance
func SetIAMProject(a *instance.Aggregate, projectID string) preparation.Validation {
return func() (preparation.CreateCommands, error) {
return func(ctx context.Context, filter preparation.FilterToQueryReducer) ([]eventstore.Command, error) {
@ -288,3 +318,14 @@ func SetIAMProject(a *instance.Aggregate, projectID string) preparation.Validati
}, nil
}
}
//SetIAMConsoleID defines the command to set the clientID of the Console App onto the instance
func SetIAMConsoleID(a *instance.Aggregate, clientID string) preparation.Validation {
return func() (preparation.CreateCommands, error) {
return func(ctx context.Context, filter preparation.FilterToQueryReducer) ([]eventstore.Command, error) {
return []eventstore.Command{
instance.NewIAMConsoleSetEvent(ctx, &a.Aggregate, clientID),
}, nil
}, nil
}
}

View File

@ -43,3 +43,16 @@ func AddDefaultLabelPolicy(
}, nil
}
}
func ActivateDefaultLabelPolicy(
a *instance.Aggregate,
) preparation.Validation {
return func() (preparation.CreateCommands, error) {
return func(ctx context.Context, filter preparation.FilterToQueryReducer) ([]eventstore.Command, error) {
//TODO: check if already exists
return []eventstore.Command{
instance.NewLabelPolicyActivatedEvent(ctx, &a.Aggregate),
}, nil
}, nil
}
}

View File

@ -0,0 +1,64 @@
package command
import (
"context"
"github.com/caos/zitadel/internal/command/v2/preparation"
"github.com/caos/zitadel/internal/errors"
"github.com/caos/zitadel/internal/eventstore"
"github.com/caos/zitadel/internal/repository/instance"
)
func AddInstanceMember(a *instance.Aggregate, userID string, roles ...string) preparation.Validation {
return func() (preparation.CreateCommands, error) {
if userID == "" {
return nil, errors.ThrowInvalidArgument(nil, "INSTA-SDSfs", "Errors.Invalid.Argument")
}
// TODO: check roles
return func(ctx context.Context, filter preparation.FilterToQueryReducer) ([]eventstore.Command, error) {
if exists, err := ExistsUser(ctx, filter, userID, ""); err != nil || !exists {
return nil, errors.ThrowNotFound(err, "INSTA-GSXOn", "Errors.User.NotFound")
}
if isMember, err := IsInstanceMember(ctx, filter, a.ID, userID); err != nil || isMember {
return nil, errors.ThrowAlreadyExists(err, "INSTA-pFDwe", "Errors.Instance.Member.AlreadyExists")
}
return []eventstore.Command{instance.NewMemberAddedEvent(ctx, &a.Aggregate, userID, roles...)}, nil
},
nil
}
}
func IsInstanceMember(ctx context.Context, filter preparation.FilterToQueryReducer, instanceID, userID string) (isMember bool, err error) {
events, err := filter(ctx, eventstore.NewSearchQueryBuilder(eventstore.ColumnsEvent).
OrderAsc().
AddQuery().
AggregateIDs(instanceID).
AggregateTypes(instance.AggregateType).
EventTypes(
instance.MemberAddedEventType,
instance.MemberRemovedEventType,
instance.MemberCascadeRemovedEventType,
).Builder())
if err != nil {
return false, err
}
for _, event := range events {
switch e := event.(type) {
case *instance.MemberAddedEvent:
if e.UserID == userID {
isMember = true
}
case *instance.MemberRemovedEvent:
if e.UserID == userID {
isMember = false
}
case *instance.MemberCascadeRemovedEvent:
if e.UserID == userID {
isMember = false
}
}
}
return isMember, nil
}

View File

@ -21,7 +21,7 @@ func NewAggregate(
ID: id,
Type: typ,
ResourceOwner: authz.GetCtxData(ctx).OrgID,
InstanceID: authz.GetInstance(ctx).ID,
InstanceID: authz.GetInstance(ctx).InstanceID(),
Version: version,
}

View File

@ -41,7 +41,7 @@ func (es *Eventstore) Health(ctx context.Context) error {
//Push pushes the events in a single transaction
// an event needs at least an aggregate
func (es *Eventstore) Push(ctx context.Context, cmds ...Command) ([]Event, error) {
events, constraints, err := commandsToRepository(authz.GetInstance(ctx).ID, cmds)
events, constraints, err := commandsToRepository(authz.GetInstance(ctx).InstanceID(), cmds)
if err != nil {
return nil, err
}
@ -114,7 +114,7 @@ func uniqueConstraintsToRepository(instanceID string, constraints []*EventUnique
//Filter filters the stored events based on the searchQuery
// and maps the events to the defined event structs
func (es *Eventstore) Filter(ctx context.Context, queryFactory *SearchQueryBuilder) ([]Event, error) {
query, err := queryFactory.build(authz.GetInstance(ctx).ID)
query, err := queryFactory.build(authz.GetInstance(ctx).InstanceID())
if err != nil {
return nil, err
}
@ -171,7 +171,7 @@ func (es *Eventstore) FilterToReducer(ctx context.Context, searchQuery *SearchQu
//LatestSequence filters the latest sequence for the given search query
func (es *Eventstore) LatestSequence(ctx context.Context, queryFactory *SearchQueryBuilder) (uint64, error) {
query, err := queryFactory.build(authz.GetInstance(ctx).ID)
query, err := queryFactory.build(authz.GetInstance(ctx).InstanceID())
if err != nil {
return 0, err
}

View File

@ -21,7 +21,7 @@ func (c *AggregateCreator) NewAggregate(ctx context.Context, id string, typ Aggr
instance := authz.GetInstance(ctx)
editorUser := ctxData.UserID
resourceOwner := ctxData.OrgID
instanceID := instance.ID
instanceID := instance.InstanceID()
aggregate := &Aggregate{
ID: id,

View File

@ -251,7 +251,7 @@ func (u *NotifyUser) loginNameInformation(ctx context.Context, orgID string) (us
return false, "", nil, err
}
if org.DomainPolicy == nil {
policy, err := u.queries.DefaultDomainPolicy(authz.WithInstance(ctx, authz.Instance{ID: org.InstanceID}))
policy, err := u.queries.DefaultDomainPolicy(authz.WithInstanceID(ctx, org.InstanceID))
if err != nil {
return false, "", nil, err
}

View File

@ -101,7 +101,7 @@ func (q *Queries) SearchActions(ctx context.Context, queries *ActionSearchQuerie
query, scan := prepareActionsQuery()
stmt, args, err := queries.toQuery(query).
Where(sq.Eq{
ActionColumnInstanceID.identifier(): authz.GetInstance(ctx).ID,
ActionColumnInstanceID.identifier(): authz.GetInstance(ctx).InstanceID(),
}).
ToSql()
if err != nil {
@ -126,7 +126,7 @@ func (q *Queries) GetActionByID(ctx context.Context, id string, orgID string) (*
sq.Eq{
ActionColumnID.identifier(): id,
ActionColumnResourceOwner.identifier(): orgID,
ActionColumnInstanceID.identifier(): authz.GetInstance(ctx).ID,
ActionColumnInstanceID.identifier(): authz.GetInstance(ctx).InstanceID(),
}).ToSql()
if err != nil {
return nil, errors.ThrowInternal(err, "QUERY-Dgff3", "Errors.Query.SQLStatement")

View File

@ -68,7 +68,7 @@ func (q *Queries) GetFlow(ctx context.Context, flowType domain.FlowType, orgID s
sq.Eq{
FlowsTriggersColumnFlowType.identifier(): flowType,
FlowsTriggersColumnResourceOwner.identifier(): orgID,
FlowsTriggersColumnInstanceID.identifier(): authz.GetInstance(ctx).ID,
FlowsTriggersColumnInstanceID.identifier(): authz.GetInstance(ctx).InstanceID(),
}).ToSql()
if err != nil {
return nil, errors.ThrowInvalidArgument(err, "QUERY-HBRh3", "Errors.Query.InvalidRequest")
@ -88,7 +88,7 @@ func (q *Queries) GetActiveActionsByFlowAndTriggerType(ctx context.Context, flow
FlowsTriggersColumnFlowType.identifier(): flowType,
FlowsTriggersColumnTriggerType.identifier(): triggerType,
FlowsTriggersColumnResourceOwner.identifier(): orgID,
FlowsTriggersColumnInstanceID.identifier(): authz.GetInstance(ctx).ID,
FlowsTriggersColumnInstanceID.identifier(): authz.GetInstance(ctx).InstanceID(),
ActionColumnState.identifier(): domain.ActionStateActive,
},
).ToSql()
@ -108,7 +108,7 @@ func (q *Queries) GetFlowTypesOfActionID(ctx context.Context, actionID string) (
query, args, err := stmt.Where(
sq.Eq{
FlowsTriggersColumnActionID.identifier(): actionID,
FlowsTriggersColumnInstanceID.identifier(): authz.GetInstance(ctx).ID,
FlowsTriggersColumnInstanceID.identifier(): authz.GetInstance(ctx).InstanceID(),
},
).ToSql()
if err != nil {

View File

@ -212,7 +212,7 @@ func (q *Queries) AppByProjectAndAppID(ctx context.Context, projectID, appID str
sq.Eq{
AppColumnID.identifier(): appID,
AppColumnProjectID.identifier(): projectID,
AppColumnInstanceID.identifier(): authz.GetInstance(ctx).ID,
AppColumnInstanceID.identifier(): authz.GetInstance(ctx).InstanceID(),
},
).ToSql()
if err != nil {
@ -228,7 +228,7 @@ func (q *Queries) AppByID(ctx context.Context, appID string) (*App, error) {
query, args, err := stmt.Where(
sq.Eq{
AppColumnID.identifier(): appID,
AppColumnInstanceID.identifier(): authz.GetInstance(ctx).ID,
AppColumnInstanceID.identifier(): authz.GetInstance(ctx).InstanceID(),
},
).ToSql()
if err != nil {
@ -244,7 +244,7 @@ func (q *Queries) ProjectIDFromOIDCClientID(ctx context.Context, appID string) (
query, args, err := stmt.Where(
sq.Eq{
AppOIDCConfigColumnClientID.identifier(): appID,
AppColumnInstanceID.identifier(): authz.GetInstance(ctx).ID,
AppColumnInstanceID.identifier(): authz.GetInstance(ctx).InstanceID(),
},
).ToSql()
if err != nil {
@ -259,7 +259,7 @@ func (q *Queries) ProjectIDFromClientID(ctx context.Context, appID string) (stri
stmt, scan := prepareProjectIDByAppQuery()
query, args, err := stmt.Where(
sq.And{
sq.Eq{AppColumnInstanceID.identifier(): authz.GetInstance(ctx).ID},
sq.Eq{AppColumnInstanceID.identifier(): authz.GetInstance(ctx).InstanceID()},
sq.Or{
sq.Eq{AppOIDCConfigColumnClientID.identifier(): appID},
sq.Eq{AppAPIConfigColumnClientID.identifier(): appID},
@ -279,7 +279,7 @@ func (q *Queries) ProjectByOIDCClientID(ctx context.Context, id string) (*Projec
query, args, err := stmt.Where(
sq.Eq{
AppOIDCConfigColumnClientID.identifier(): id,
AppColumnInstanceID.identifier(): authz.GetInstance(ctx).ID,
AppColumnInstanceID.identifier(): authz.GetInstance(ctx).InstanceID(),
},
).ToSql()
if err != nil {
@ -295,7 +295,7 @@ func (q *Queries) AppByOIDCClientID(ctx context.Context, clientID string) (*App,
query, args, err := stmt.Where(
sq.Eq{
AppOIDCConfigColumnClientID.identifier(): clientID,
AppColumnInstanceID.identifier(): authz.GetInstance(ctx).ID,
AppColumnInstanceID.identifier(): authz.GetInstance(ctx).InstanceID(),
},
).ToSql()
if err != nil {
@ -310,7 +310,7 @@ func (q *Queries) AppByClientID(ctx context.Context, clientID string) (*App, err
stmt, scan := prepareAppQuery()
query, args, err := stmt.Where(
sq.And{
sq.Eq{AppColumnInstanceID.identifier(): authz.GetInstance(ctx).ID},
sq.Eq{AppColumnInstanceID.identifier(): authz.GetInstance(ctx).InstanceID()},
sq.Or{
sq.Eq{AppOIDCConfigColumnClientID.identifier(): clientID},
sq.Eq{AppAPIConfigColumnClientID.identifier(): clientID},
@ -329,7 +329,7 @@ func (q *Queries) SearchApps(ctx context.Context, queries *AppSearchQueries) (*A
query, scan := prepareAppsQuery()
stmt, args, err := queries.toQuery(query).
Where(
sq.Eq{AppColumnInstanceID.identifier(): authz.GetInstance(ctx).ID},
sq.Eq{AppColumnInstanceID.identifier(): authz.GetInstance(ctx).InstanceID()},
).ToSql()
if err != nil {
return nil, errors.ThrowInvalidArgument(err, "QUERY-fajp8", "Errors.Query.InvalidRequest")
@ -351,7 +351,7 @@ func (q *Queries) SearchClientIDs(ctx context.Context, queries *AppSearchQueries
query, scan := prepareClientIDsQuery()
stmt, args, err := queries.toQuery(query).
Where(
sq.Eq{AppColumnInstanceID.identifier(): authz.GetInstance(ctx).ID},
sq.Eq{AppColumnInstanceID.identifier(): authz.GetInstance(ctx).InstanceID()},
).ToSql()
if err != nil {
return nil, errors.ThrowInvalidArgument(err, "QUERY-fajp8", "Errors.Query.InvalidRequest")

View File

@ -103,7 +103,7 @@ func (q *Queries) SearchAuthNKeys(ctx context.Context, queries *AuthNKeySearchQu
stmt, args, err := query.Where(
sq.Eq{
AuthNKeyColumnEnabled.identifier(): true,
AuthNKeyColumnInstanceID.identifier(): authz.GetInstance(ctx).ID,
AuthNKeyColumnInstanceID.identifier(): authz.GetInstance(ctx).InstanceID(),
},
).ToSql()
if err != nil {
@ -131,7 +131,7 @@ func (q *Queries) GetAuthNKeyByID(ctx context.Context, id string, queries ...Sea
sq.Eq{
AuthNKeyColumnID.identifier(): id,
AuthNKeyColumnEnabled.identifier(): true,
AuthNKeyColumnInstanceID.identifier(): authz.GetInstance(ctx).ID,
AuthNKeyColumnInstanceID.identifier(): authz.GetInstance(ctx).InstanceID(),
}).ToSql()
if err != nil {
return nil, errors.ThrowInternal(err, "QUERY-AGhg4", "Errors.Query.SQLStatement")
@ -149,7 +149,7 @@ func (q *Queries) GetAuthNKeyPublicKeyByIDAndIdentifier(ctx context.Context, id
AuthNKeyColumnID.identifier(): id,
AuthNKeyColumnIdentifier.identifier(): identifier,
AuthNKeyColumnEnabled.identifier(): true,
AuthNKeyColumnInstanceID.identifier(): authz.GetInstance(ctx).ID,
AuthNKeyColumnInstanceID.identifier(): authz.GetInstance(ctx).InstanceID(),
},
sq.Gt{
AuthNKeyColumnExpiration.identifier(): time.Now(),

View File

@ -86,7 +86,7 @@ func (q *Queries) CustomTextList(ctx context.Context, aggregateID, template, lan
CustomTextColAggregateID.identifier(): aggregateID,
CustomTextColTemplate.identifier(): template,
CustomTextColLanguage.identifier(): language,
CustomTextColInstanceID.identifier(): authz.GetInstance(ctx).ID,
CustomTextColInstanceID.identifier(): authz.GetInstance(ctx).InstanceID(),
},
).ToSql()
if err != nil {
@ -111,7 +111,7 @@ func (q *Queries) CustomTextListByTemplate(ctx context.Context, aggregateID, tem
sq.Eq{
CustomTextColAggregateID.identifier(): aggregateID,
CustomTextColTemplate.identifier(): template,
CustomTextColInstanceID.identifier(): authz.GetInstance(ctx).ID,
CustomTextColInstanceID.identifier(): authz.GetInstance(ctx).InstanceID(),
},
).ToSql()
if err != nil {

View File

@ -163,7 +163,7 @@ func (q *Queries) FeaturesByOrgID(ctx context.Context, orgID string) (*Features,
stmt, args, err := query.Where(
sq.And{
sq.Eq{
FeatureColumnInstanceID.identifier(): authz.GetInstance(ctx).ID,
FeatureColumnInstanceID.identifier(): authz.GetInstance(ctx).InstanceID(),
},
sq.Or{
sq.Eq{
@ -188,7 +188,7 @@ func (q *Queries) DefaultFeatures(ctx context.Context) (*Features, error) {
query, scan := prepareFeaturesQuery()
stmt, args, err := query.Where(sq.Eq{
FeatureColumnAggregateID.identifier(): domain.IAMID,
FeatureColumnInstanceID.identifier(): authz.GetInstance(ctx).ID,
FeatureColumnInstanceID.identifier(): authz.GetInstance(ctx).InstanceID(),
}).ToSql()
if err != nil {
return nil, errors.ThrowInternal(err, "QUERY-1Ndlg", "Errors.Query.SQLStatement")

View File

@ -65,7 +65,7 @@ func (q *Queries) IAMMembers(ctx context.Context, queries *IAMMembersQuery) (*Me
query, scan := prepareInstanceMembersQuery()
stmt, args, err := queries.toQuery(query).
Where(sq.Eq{
InstanceMemberInstanceID.identifier(): authz.GetInstance(ctx).ID,
InstanceMemberInstanceID.identifier(): authz.GetInstance(ctx).InstanceID(),
}).ToSql()
if err != nil {
return nil, errors.ThrowInvalidArgument(err, "QUERY-USNwM", "Errors.Query.InvalidRequest")

View File

@ -186,7 +186,7 @@ func (q *Queries) IDPByIDAndResourceOwner(ctx context.Context, id, resourceOwner
sq.And{
sq.Eq{
IDPIDCol.identifier(): id,
IDPInstanceIDCol.identifier(): authz.GetInstance(ctx).ID,
IDPInstanceIDCol.identifier(): authz.GetInstance(ctx).InstanceID(),
},
sq.Or{
sq.Eq{
@ -211,7 +211,7 @@ func (q *Queries) IDPs(ctx context.Context, queries *IDPSearchQueries) (idps *ID
query, scan := prepareIDPsQuery()
stmt, args, err := queries.toQuery(query).
Where(sq.Eq{
IDPInstanceIDCol.identifier(): authz.GetInstance(ctx).ID,
IDPInstanceIDCol.identifier(): authz.GetInstance(ctx).InstanceID(),
}).ToSql()
if err != nil {
return nil, errors.ThrowInvalidArgument(err, "QUERY-X6X7y", "Errors.Query.InvalidRequest")

View File

@ -75,7 +75,7 @@ func (q *Queries) IDPLoginPolicyLinks(ctx context.Context, resourceOwner string,
stmt, args, err := queries.toQuery(query).Where(
sq.Eq{
IDPLoginPolicyLinkResourceOwnerCol.identifier(): resourceOwner,
IDPLoginPolicyLinkInstanceIDCol.identifier(): authz.GetInstance(ctx).ID,
IDPLoginPolicyLinkInstanceIDCol.identifier(): authz.GetInstance(ctx).InstanceID(),
},
).ToSql()
if err != nil {

View File

@ -86,7 +86,7 @@ func (q *Queries) IDPUserLinks(ctx context.Context, queries *IDPUserLinksSearchQ
query, scan := prepareIDPUserLinksQuery()
stmt, args, err := queries.toQuery(query).
Where(sq.Eq{
IDPUserLinkInstanceIDCol.identifier(): authz.GetInstance(ctx).ID,
IDPUserLinkInstanceIDCol.identifier(): authz.GetInstance(ctx).InstanceID(),
}).ToSql()
if err != nil {
return nil, errors.ThrowInvalidArgument(err, "QUERY-4zzFK", "Errors.Query.InvalidRequest")

View File

@ -39,6 +39,10 @@ var (
name: projection.InstanceColumnProjectID,
table: instanceTable,
}
InstanceColumnConsoleID = Column{
name: projection.InstanceColumnConsoleID,
table: instanceTable,
}
InstanceColumnSetupStarted = Column{
name: projection.InstanceColumnSetUpStarted,
table: instanceTable,
@ -60,11 +64,24 @@ type Instance struct {
GlobalOrgID string
IAMProjectID string
ConsoleID string
DefaultLanguage language.Tag
SetupStarted domain.Step
SetupDone domain.Step
}
func (i *Instance) InstanceID() string {
return i.ID
}
func (i *Instance) ProjectID() string {
return i.IAMProjectID
}
func (i *Instance) ConsoleClientID() string {
return i.ConsoleID
}
type InstanceSearchQueries struct {
SearchRequest
Queries []SearchQuery
@ -81,7 +98,7 @@ func (q *InstanceSearchQueries) toQuery(query sq.SelectBuilder) sq.SelectBuilder
func (q *Queries) Instance(ctx context.Context) (*Instance, error) {
stmt, scan := prepareIAMQuery()
query, args, err := stmt.Where(sq.Eq{
InstanceColumnID.identifier(): authz.GetInstance(ctx).ID,
InstanceColumnID.identifier(): authz.GetInstance(ctx).InstanceID(),
}).ToSql()
if err != nil {
return nil, errors.ThrowInternal(err, "QUERY-d9ngs", "Errors.Query.SQLStatement")
@ -91,6 +108,19 @@ func (q *Queries) Instance(ctx context.Context) (*Instance, error) {
return scan(row)
}
func (q *Queries) InstanceByHost(ctx context.Context, host string) (authz.Instance, error) {
stmt, scan := prepareIAMQuery()
query, args, err := stmt.Where(sq.Eq{
InstanceColumnID.identifier(): "system", //TODO: change column to domain when available
}).ToSql()
if err != nil {
return nil, errors.ThrowInternal(err, "QUERY-SAfg2", "Errors.Query.SQLStatement")
}
row := q.client.QueryRowContext(ctx, query, args...)
return scan(row)
}
func (q *Queries) GetDefaultLanguage(ctx context.Context) language.Tag {
iam, err := q.Instance(ctx)
if err != nil {
@ -106,6 +136,7 @@ func prepareIAMQuery() (sq.SelectBuilder, func(*sql.Row) (*Instance, error)) {
InstanceColumnSequence.identifier(),
InstanceColumnGlobalOrgID.identifier(),
InstanceColumnProjectID.identifier(),
InstanceColumnConsoleID.identifier(),
InstanceColumnSetupStarted.identifier(),
InstanceColumnSetupDone.identifier(),
InstanceColumnDefaultLanguage.identifier(),
@ -120,6 +151,7 @@ func prepareIAMQuery() (sq.SelectBuilder, func(*sql.Row) (*Instance, error)) {
&iam.Sequence,
&iam.GlobalOrgID,
&iam.IAMProjectID,
&iam.ConsoleID,
&iam.SetupStarted,
&iam.SetupDone,
&lang,

View File

@ -35,6 +35,7 @@ func Test_InstancePrepares(t *testing.T) {
` projections.instances.sequence,`+
` projections.instances.global_org_id,`+
` projections.instances.iam_project_id,`+
` projections.instances.console_client_id,`+
` projections.instances.setup_started,`+
` projections.instances.setup_done,`+
` projections.instances.default_language`+
@ -61,6 +62,7 @@ func Test_InstancePrepares(t *testing.T) {
` projections.instances.sequence,`+
` projections.instances.global_org_id,`+
` projections.instances.iam_project_id,`+
` projections.instances.console_client_id,`+
` projections.instances.setup_started,`+
` projections.instances.setup_done,`+
` projections.instances.default_language`+
@ -71,6 +73,7 @@ func Test_InstancePrepares(t *testing.T) {
"sequence",
"global_org_id",
"iam_project_id",
"console_client_id",
"setup_started",
"setup_done",
"default_language",
@ -81,6 +84,7 @@ func Test_InstancePrepares(t *testing.T) {
uint64(20211108),
"global-org-id",
"project-id",
"client-id",
domain.Step2,
domain.Step1,
"en",
@ -93,6 +97,7 @@ func Test_InstancePrepares(t *testing.T) {
Sequence: 20211108,
GlobalOrgID: "global-org-id",
IAMProjectID: "project-id",
ConsoleID: "client-id",
SetupStarted: domain.Step2,
SetupDone: domain.Step1,
DefaultLanguage: language.English,
@ -108,6 +113,7 @@ func Test_InstancePrepares(t *testing.T) {
` projections.instances.sequence,`+
` projections.instances.global_org_id,`+
` projections.instances.iam_project_id,`+
` projections.instances.console_client_id,`+
` projections.instances.setup_started,`+
` projections.instances.setup_done,`+
` projections.instances.default_language`+

View File

@ -181,7 +181,7 @@ func (q *Queries) ActivePublicKeys(ctx context.Context, t time.Time) (*PublicKey
stmt, args, err := query.Where(
sq.And{
sq.Eq{
KeyColInstanceID.identifier(): authz.GetInstance(ctx).ID,
KeyColInstanceID.identifier(): authz.GetInstance(ctx).InstanceID(),
},
sq.Gt{
KeyPublicColExpiry.identifier(): t,
@ -212,7 +212,7 @@ func (q *Queries) ActivePrivateSigningKey(ctx context.Context, t time.Time) (*Pr
sq.And{
sq.Eq{
KeyColUse.identifier(): domain.KeyUsageSigning,
KeyColInstanceID.identifier(): authz.GetInstance(ctx).ID,
KeyColInstanceID.identifier(): authz.GetInstance(ctx).InstanceID(),
},
sq.Gt{
KeyPrivateColExpiry.identifier(): t,

View File

@ -54,7 +54,7 @@ func (q *Queries) ActiveLabelPolicyByOrg(ctx context.Context, orgID string) (*La
},
sq.Eq{
LabelPolicyColState.identifier(): domain.LabelPolicyStateActive,
LabelPolicyColInstanceID.identifier(): authz.GetInstance(ctx).ID,
LabelPolicyColInstanceID.identifier(): authz.GetInstance(ctx).InstanceID(),
},
}).
OrderBy(LabelPolicyColIsDefault.identifier()).
@ -81,7 +81,7 @@ func (q *Queries) PreviewLabelPolicyByOrg(ctx context.Context, orgID string) (*L
},
sq.Eq{
LabelPolicyColState.identifier(): domain.LabelPolicyStatePreview,
LabelPolicyColInstanceID.identifier(): authz.GetInstance(ctx).ID,
LabelPolicyColInstanceID.identifier(): authz.GetInstance(ctx).InstanceID(),
},
}).
OrderBy(LabelPolicyColIsDefault.identifier()).
@ -99,7 +99,7 @@ func (q *Queries) DefaultActiveLabelPolicy(ctx context.Context) (*LabelPolicy, e
query, args, err := stmt.Where(sq.Eq{
LabelPolicyColID.identifier(): domain.IAMID,
LabelPolicyColState.identifier(): domain.LabelPolicyStateActive,
LabelPolicyColInstanceID.identifier(): authz.GetInstance(ctx).ID,
LabelPolicyColInstanceID.identifier(): authz.GetInstance(ctx).InstanceID(),
}).
OrderBy(LabelPolicyColIsDefault.identifier()).
Limit(1).ToSql()
@ -116,7 +116,7 @@ func (q *Queries) DefaultPreviewLabelPolicy(ctx context.Context) (*LabelPolicy,
query, args, err := stmt.Where(sq.Eq{
LabelPolicyColID.identifier(): domain.IAMID,
LabelPolicyColState.identifier(): domain.LabelPolicyStatePreview,
LabelPolicyColInstanceID.identifier(): authz.GetInstance(ctx).ID,
LabelPolicyColInstanceID.identifier(): authz.GetInstance(ctx).InstanceID(),
}).
OrderBy(LabelPolicyColIsDefault.identifier()).
Limit(1).ToSql()

View File

@ -80,7 +80,7 @@ func (q *Queries) LockoutPolicyByOrg(ctx context.Context, orgID string) (*Lockou
query, args, err := stmt.Where(
sq.And{
sq.Eq{
LockoutColInstanceID.identifier(): authz.GetInstance(ctx).ID,
LockoutColInstanceID.identifier(): authz.GetInstance(ctx).InstanceID(),
},
sq.Or{
sq.Eq{
@ -105,7 +105,7 @@ func (q *Queries) DefaultLockoutPolicy(ctx context.Context) (*LockoutPolicy, err
stmt, scan := prepareLockoutPolicyQuery()
query, args, err := stmt.Where(sq.Eq{
LockoutColID.identifier(): domain.IAMID,
LockoutColInstanceID.identifier(): authz.GetInstance(ctx).ID,
LockoutColInstanceID.identifier(): authz.GetInstance(ctx).InstanceID(),
}).
OrderBy(LockoutColIsDefault.identifier()).
Limit(1).ToSql()

View File

@ -134,7 +134,7 @@ func (q *Queries) LoginPolicyByID(ctx context.Context, orgID string) (*LoginPoli
stmt, args, err := query.Where(
sq.And{
sq.Eq{
LoginPolicyColumnInstanceID.identifier(): authz.GetInstance(ctx).ID,
LoginPolicyColumnInstanceID.identifier(): authz.GetInstance(ctx).InstanceID(),
},
sq.Or{
sq.Eq{
@ -159,7 +159,7 @@ func (q *Queries) DefaultLoginPolicy(ctx context.Context) (*LoginPolicy, error)
query, scan := prepareLoginPolicyQuery()
stmt, args, err := query.Where(sq.Eq{
LoginPolicyColumnOrgID.identifier(): domain.IAMID,
LoginPolicyColumnInstanceID.identifier(): authz.GetInstance(ctx).ID,
LoginPolicyColumnInstanceID.identifier(): authz.GetInstance(ctx).InstanceID(),
}).OrderBy(LoginPolicyColumnIsDefault.identifier()).ToSql()
if err != nil {
return nil, errors.ThrowInternal(err, "QUERY-t4TBK", "Errors.Query.SQLStatement")
@ -174,7 +174,7 @@ func (q *Queries) SecondFactorsByOrg(ctx context.Context, orgID string) (*Second
stmt, args, err := query.Where(
sq.And{
sq.Eq{
LoginPolicyColumnInstanceID.identifier(): authz.GetInstance(ctx).ID,
LoginPolicyColumnInstanceID.identifier(): authz.GetInstance(ctx).InstanceID(),
},
sq.Or{
sq.Eq{
@ -204,7 +204,7 @@ func (q *Queries) DefaultSecondFactors(ctx context.Context) (*SecondFactors, err
query, scan := prepareLoginPolicy2FAsQuery()
stmt, args, err := query.Where(sq.Eq{
LoginPolicyColumnOrgID.identifier(): domain.IAMID,
LoginPolicyColumnInstanceID.identifier(): authz.GetInstance(ctx).ID,
LoginPolicyColumnInstanceID.identifier(): authz.GetInstance(ctx).InstanceID(),
}).OrderBy(LoginPolicyColumnIsDefault.identifier()).ToSql()
if err != nil {
return nil, errors.ThrowInternal(err, "QUERY-CZ2Nv", "Errors.Query.SQLStatement")
@ -224,7 +224,7 @@ func (q *Queries) MultiFactorsByOrg(ctx context.Context, orgID string) (*MultiFa
stmt, args, err := query.Where(
sq.And{
sq.Eq{
LoginPolicyColumnInstanceID.identifier(): authz.GetInstance(ctx).ID,
LoginPolicyColumnInstanceID.identifier(): authz.GetInstance(ctx).InstanceID(),
},
sq.Or{
sq.Eq{
@ -254,7 +254,7 @@ func (q *Queries) DefaultMultiFactors(ctx context.Context) (*MultiFactors, error
query, scan := prepareLoginPolicyMFAsQuery()
stmt, args, err := query.Where(sq.Eq{
LoginPolicyColumnOrgID.identifier(): domain.IAMID,
LoginPolicyColumnInstanceID.identifier(): authz.GetInstance(ctx).ID,
LoginPolicyColumnInstanceID.identifier(): authz.GetInstance(ctx).InstanceID(),
}).OrderBy(LoginPolicyColumnIsDefault.identifier()).ToSql()
if err != nil {
return nil, errors.ThrowInternal(err, "QUERY-WxYjr", "Errors.Query.SQLStatement")

View File

@ -68,7 +68,7 @@ func (q *Queries) MailTemplateByOrg(ctx context.Context, orgID string) (*MailTem
query, args, err := stmt.Where(
sq.And{
sq.Eq{
MailTemplateColInstanceID.identifier(): authz.GetInstance(ctx).ID,
MailTemplateColInstanceID.identifier(): authz.GetInstance(ctx).InstanceID(),
},
sq.Or{
sq.Eq{
@ -93,7 +93,7 @@ func (q *Queries) DefaultMailTemplate(ctx context.Context) (*MailTemplate, error
stmt, scan := prepareMailTemplateQuery()
query, args, err := stmt.Where(sq.Eq{
MailTemplateColAggregateID.identifier(): domain.IAMID,
MailTemplateColInstanceID.identifier(): authz.GetInstance(ctx).ID,
MailTemplateColInstanceID.identifier(): authz.GetInstance(ctx).InstanceID(),
}).
OrderBy(MailTemplateColIsDefault.identifier()).
Limit(1).ToSql()

View File

@ -122,7 +122,7 @@ func (q *Queries) MessageTextByOrg(ctx context.Context, orgID string) (*MessageT
query, args, err := stmt.Where(
sq.And{
sq.Eq{
MessageTextColInstanceID.identifier(): authz.GetInstance(ctx).ID,
MessageTextColInstanceID.identifier(): authz.GetInstance(ctx).InstanceID(),
},
sq.Or{
sq.Eq{
@ -147,7 +147,7 @@ func (q *Queries) DefaultMessageText(ctx context.Context) (*MessageText, error)
stmt, scan := prepareMessageTextQuery()
query, args, err := stmt.Where(sq.Eq{
MessageTextColAggregateID.identifier(): domain.IAMID,
MessageTextColInstanceID.identifier(): authz.GetInstance(ctx).ID,
MessageTextColInstanceID.identifier(): authz.GetInstance(ctx).InstanceID(),
}).
Limit(1).ToSql()
if err != nil {
@ -177,7 +177,7 @@ func (q *Queries) CustomMessageTextByTypeAndLanguage(ctx context.Context, aggreg
MessageTextColLanguage.identifier(): language,
MessageTextColType.identifier(): messageType,
MessageTextColAggregateID.identifier(): aggregateID,
MessageTextColInstanceID.identifier(): authz.GetInstance(ctx).ID,
MessageTextColInstanceID.identifier(): authz.GetInstance(ctx).InstanceID(),
},
).
OrderBy(MessageTextColAggregateID.identifier()).

View File

@ -73,7 +73,7 @@ func (q *Queries) NotificationProviderByIDAndType(ctx context.Context, aggID str
stmt, args, err := query.Where(
sq.And{
sq.Eq{
NotificationProviderColumnInstanceID.identifier(): authz.GetInstance(ctx).ID,
NotificationProviderColumnInstanceID.identifier(): authz.GetInstance(ctx).InstanceID(),
},
sq.Or{
sq.Eq{

View File

@ -76,7 +76,7 @@ func (q *Queries) OIDCSettingsByAggID(ctx context.Context, aggregateID string) (
stmt, scan := prepareOIDCSettingsQuery()
query, args, err := stmt.Where(sq.Eq{
OIDCSettingsColumnAggregateID.identifier(): aggregateID,
OIDCSettingsColumnInstanceID.identifier(): authz.GetInstance(ctx).ID,
OIDCSettingsColumnInstanceID.identifier(): authz.GetInstance(ctx).InstanceID(),
}).ToSql()
if err != nil {
return nil, errors.ThrowInternal(err, "QUERY-s9nle", "Errors.Query.SQLStatment")

View File

@ -90,7 +90,7 @@ func (q *Queries) OrgByID(ctx context.Context, id string) (*Org, error) {
stmt, scan := prepareOrgQuery()
query, args, err := stmt.Where(sq.Eq{
OrgColumnID.identifier(): id,
OrgColumnInstanceID.identifier(): authz.GetInstance(ctx).ID,
OrgColumnInstanceID.identifier(): authz.GetInstance(ctx).InstanceID(),
}).ToSql()
if err != nil {
return nil, errors.ThrowInternal(err, "QUERY-AWx52", "Errors.Query.SQLStatement")
@ -104,7 +104,7 @@ func (q *Queries) OrgByDomainGlobal(ctx context.Context, domain string) (*Org, e
stmt, scan := prepareOrgQuery()
query, args, err := stmt.Where(sq.Eq{
OrgColumnDomain.identifier(): domain,
OrgColumnInstanceID.identifier(): authz.GetInstance(ctx).ID,
OrgColumnInstanceID.identifier(): authz.GetInstance(ctx).InstanceID(),
}).ToSql()
if err != nil {
return nil, errors.ThrowInternal(err, "QUERY-TYUCE", "Errors.Query.SQLStatement")
@ -119,7 +119,7 @@ func (q *Queries) IsOrgUnique(ctx context.Context, name, domain string) (isUniqu
stmt, args, err := query.Where(
sq.And{
sq.Eq{
OrgColumnInstanceID.identifier(): authz.GetInstance(ctx).ID,
OrgColumnInstanceID.identifier(): authz.GetInstance(ctx).InstanceID(),
},
sq.Or{
sq.Eq{
@ -147,7 +147,7 @@ func (q *Queries) SearchOrgs(ctx context.Context, queries *OrgSearchQueries) (or
query, scan := prepareOrgsQuery()
stmt, args, err := queries.toQuery(query).
Where(sq.Eq{
OrgColumnInstanceID.identifier(): authz.GetInstance(ctx).ID,
OrgColumnInstanceID.identifier(): authz.GetInstance(ctx).InstanceID(),
}).ToSql()
if err != nil {
return nil, errors.ThrowInvalidArgument(err, "QUERY-wQ3by", "Errors.Query.InvalidRequest")

View File

@ -58,7 +58,7 @@ func (q *Queries) SearchOrgDomains(ctx context.Context, queries *OrgDomainSearch
query, scan := prepareDomainsQuery()
stmt, args, err := queries.toQuery(query).
Where(sq.Eq{
OrgDomainInstanceIDCol.identifier(): authz.GetInstance(ctx).ID,
OrgDomainInstanceIDCol.identifier(): authz.GetInstance(ctx).InstanceID(),
}).ToSql()
if err != nil {
return nil, errors.ThrowInvalidArgument(err, "QUERY-ZRfj1", "Errors.Query.SQLStatement")

View File

@ -75,7 +75,7 @@ func (q *Queries) DomainPolicyByOrg(ctx context.Context, orgID string) (*DomainP
query, args, err := stmt.Where(
sq.And{
sq.Eq{
DomainPolicyColInstanceID.identifier(): authz.GetInstance(ctx).ID,
DomainPolicyColInstanceID.identifier(): authz.GetInstance(ctx).InstanceID(),
},
sq.Or{
sq.Eq{
@ -100,7 +100,7 @@ func (q *Queries) DefaultDomainPolicy(ctx context.Context) (*DomainPolicy, error
stmt, scan := prepareDomainPolicyQuery()
query, args, err := stmt.Where(sq.Eq{
DomainPolicyColID.identifier(): domain.IAMID,
DomainPolicyColInstanceID.identifier(): authz.GetInstance(ctx).ID,
DomainPolicyColInstanceID.identifier(): authz.GetInstance(ctx).InstanceID(),
}).
OrderBy(DomainPolicyColIsDefault.identifier()).
Limit(1).ToSql()

View File

@ -66,7 +66,7 @@ func (q *Queries) OrgMembers(ctx context.Context, queries *OrgMembersQuery) (*Me
query, scan := prepareOrgMembersQuery()
stmt, args, err := queries.toQuery(query).
Where(sq.Eq{
OrgMemberInstanceID.identifier(): authz.GetInstance(ctx).ID,
OrgMemberInstanceID.identifier(): authz.GetInstance(ctx).InstanceID(),
}).ToSql()
if err != nil {
return nil, errors.ThrowInvalidArgument(err, "QUERY-PDAVB", "Errors.Query.InvalidRequest")

View File

@ -79,7 +79,7 @@ func (q *Queries) PasswordAgePolicyByOrg(ctx context.Context, orgID string) (*Pa
query, args, err := stmt.Where(
sq.And{
sq.Eq{
PasswordAgeColInstanceID.identifier(): authz.GetInstance(ctx).ID,
PasswordAgeColInstanceID.identifier(): authz.GetInstance(ctx).InstanceID(),
},
sq.Or{
sq.Eq{

View File

@ -36,7 +36,7 @@ func (q *Queries) PasswordComplexityPolicyByOrg(ctx context.Context, orgID strin
query, args, err := stmt.Where(
sq.And{
sq.Eq{
PasswordComplexityColInstanceID.identifier(): authz.GetInstance(ctx).ID,
PasswordComplexityColInstanceID.identifier(): authz.GetInstance(ctx).InstanceID(),
},
sq.Or{
sq.Eq{
@ -61,7 +61,7 @@ func (q *Queries) DefaultPasswordComplexityPolicy(ctx context.Context) (*Passwor
stmt, scan := preparePasswordComplexityPolicyQuery()
query, args, err := stmt.Where(sq.Eq{
PasswordComplexityColID.identifier(): domain.IAMID,
PasswordComplexityColInstanceID.identifier(): authz.GetInstance(ctx).ID,
PasswordComplexityColInstanceID.identifier(): authz.GetInstance(ctx).InstanceID(),
}).
OrderBy(PasswordComplexityColIsDefault.identifier()).
Limit(1).ToSql()

View File

@ -84,7 +84,7 @@ func (q *Queries) PrivacyPolicyByOrg(ctx context.Context, orgID string) (*Privac
query, args, err := stmt.Where(
sq.And{
sq.Eq{
PrivacyColInstanceID.identifier(): authz.GetInstance(ctx).ID,
PrivacyColInstanceID.identifier(): authz.GetInstance(ctx).InstanceID(),
},
sq.Or{
sq.Eq{
@ -109,7 +109,7 @@ func (q *Queries) DefaultPrivacyPolicy(ctx context.Context) (*PrivacyPolicy, err
stmt, scan := preparePrivacyPolicyQuery()
query, args, err := stmt.Where(sq.Eq{
PrivacyColID.identifier(): domain.IAMID,
PrivacyColInstanceID.identifier(): authz.GetInstance(ctx).ID,
PrivacyColInstanceID.identifier(): authz.GetInstance(ctx).InstanceID(),
}).
OrderBy(PrivacyColIsDefault.identifier()).
Limit(1).ToSql()

View File

@ -102,7 +102,7 @@ func (q *Queries) ProjectByID(ctx context.Context, id string) (*Project, error)
stmt, scan := prepareProjectQuery()
query, args, err := stmt.Where(sq.Eq{
ProjectColumnID.identifier(): id,
ProjectColumnInstanceID.identifier(): authz.GetInstance(ctx).ID,
ProjectColumnInstanceID.identifier(): authz.GetInstance(ctx).InstanceID(),
}).ToSql()
if err != nil {
return nil, errors.ThrowInternal(err, "QUERY-2m00Q", "Errors.Query.SQLStatment")
@ -121,7 +121,7 @@ func (q *Queries) SearchProjects(ctx context.Context, queries *ProjectSearchQuer
query, scan := prepareProjectsQuery()
stmt, args, err := queries.toQuery(query).
Where(sq.Eq{
ProjectColumnInstanceID.identifier(): authz.GetInstance(ctx).ID,
ProjectColumnInstanceID.identifier(): authz.GetInstance(ctx).InstanceID(),
}).ToSql()
if err != nil {
return nil, errors.ThrowInvalidArgument(err, "QUERY-fn9ew", "Errors.Query.InvalidRequest")

View File

@ -109,7 +109,7 @@ func (q *Queries) ProjectGrantByID(ctx context.Context, id string) (*ProjectGran
stmt, scan := prepareProjectGrantQuery()
query, args, err := stmt.Where(sq.Eq{
ProjectGrantColumnGrantID.identifier(): id,
ProjectGrantColumnInstanceID.identifier(): authz.GetInstance(ctx).ID,
ProjectGrantColumnInstanceID.identifier(): authz.GetInstance(ctx).InstanceID(),
}).ToSql()
if err != nil {
return nil, errors.ThrowInternal(err, "QUERY-Nf93d", "Errors.Query.SQLStatment")
@ -124,7 +124,7 @@ func (q *Queries) ProjectGrantByIDAndGrantedOrg(ctx context.Context, id, granted
query, args, err := stmt.Where(sq.Eq{
ProjectGrantColumnGrantID.identifier(): id,
ProjectGrantColumnGrantedOrgID.identifier(): grantedOrg,
ProjectGrantColumnInstanceID.identifier(): authz.GetInstance(ctx).ID,
ProjectGrantColumnInstanceID.identifier(): authz.GetInstance(ctx).InstanceID(),
}).ToSql()
if err != nil {
return nil, errors.ThrowInternal(err, "QUERY-MO9fs", "Errors.Query.SQLStatment")
@ -143,7 +143,7 @@ func (q *Queries) SearchProjectGrants(ctx context.Context, queries *ProjectGrant
query, scan := prepareProjectGrantsQuery()
stmt, args, err := queries.toQuery(query).
Where(sq.Eq{
ProjectGrantColumnInstanceID.identifier(): authz.GetInstance(ctx).ID,
ProjectGrantColumnInstanceID.identifier(): authz.GetInstance(ctx).InstanceID(),
}).ToSql()
if err != nil {
return nil, errors.ThrowInvalidArgument(err, "QUERY-N9fsg", "Errors.Query.InvalidRequest")

View File

@ -80,7 +80,7 @@ func (q *Queries) ProjectGrantMembers(ctx context.Context, queries *ProjectGrant
query, scan := prepareProjectGrantMembersQuery()
stmt, args, err := queries.toQuery(query).
Where(sq.Eq{
ProjectGrantMemberInstanceID.identifier(): authz.GetInstance(ctx).ID,
ProjectGrantMemberInstanceID.identifier(): authz.GetInstance(ctx).InstanceID(),
}).ToSql()
if err != nil {
return nil, errors.ThrowInvalidArgument(err, "QUERY-USNwM", "Errors.Query.InvalidRequest")

View File

@ -67,7 +67,7 @@ func (q *Queries) ProjectMembers(ctx context.Context, queries *ProjectMembersQue
query, scan := prepareProjectMembersQuery()
stmt, args, err := queries.toQuery(query).
Where(sq.Eq{
ProjectMemberInstanceID.identifier(): authz.GetInstance(ctx).ID,
ProjectMemberInstanceID.identifier(): authz.GetInstance(ctx).InstanceID(),
}).ToSql()
if err != nil {
return nil, errors.ThrowInvalidArgument(err, "QUERY-T8CuT", "Errors.Query.InvalidRequest")

View File

@ -87,7 +87,7 @@ func (q *Queries) ProjectRoleByID(ctx context.Context, projectID, key string) (*
Where(sq.Eq{
ProjectRoleColumnProjectID.identifier(): projectID,
ProjectRoleColumnKey.identifier(): key,
ProjectRoleColumnInstanceID.identifier(): authz.GetInstance(ctx).ID,
ProjectRoleColumnInstanceID.identifier(): authz.GetInstance(ctx).InstanceID(),
}).ToSql()
if err != nil {
return nil, errors.ThrowInternal(err, "QUERY-2N0fs", "Errors.Query.SQLStatment")
@ -106,7 +106,7 @@ func (q *Queries) SearchProjectRoles(ctx context.Context, queries *ProjectRoleSe
query, scan := prepareProjectRolesQuery()
stmt, args, err := queries.toQuery(query).
Where(sq.Eq{
ProjectRoleColumnInstanceID.identifier(): authz.GetInstance(ctx).ID,
ProjectRoleColumnInstanceID.identifier(): authz.GetInstance(ctx).InstanceID(),
}).ToSql()
if err != nil {
return nil, errors.ThrowInvalidArgument(err, "QUERY-3N9ff", "Errors.Query.InvalidRequest")
@ -136,7 +136,7 @@ func (q *Queries) SearchGrantedProjectRoles(ctx context.Context, grantID, grante
query, scan := prepareProjectRolesQuery()
stmt, args, err := queries.toQuery(query).
Where(sq.Eq{
ProjectRoleColumnInstanceID.identifier(): authz.GetInstance(ctx).ID,
ProjectRoleColumnInstanceID.identifier(): authz.GetInstance(ctx).InstanceID(),
}).ToSql()
if err != nil {
return nil, errors.ThrowInvalidArgument(err, "QUERY-3N9ff", "Errors.Query.InvalidRequest")

View File

@ -17,6 +17,7 @@ const (
InstanceColumnChangeDate = "change_date"
InstanceColumnGlobalOrgID = "global_org_id"
InstanceColumnProjectID = "iam_project_id"
InstanceColumnConsoleID = "console_client_id"
InstanceColumnSequence = "sequence"
InstanceColumnSetUpStarted = "setup_started"
InstanceColumnSetUpDone = "setup_done"
@ -37,6 +38,7 @@ func NewInstanceProjection(ctx context.Context, config crdb.StatementHandlerConf
crdb.NewColumn(InstanceColumnChangeDate, crdb.ColumnTypeTimestamp),
crdb.NewColumn(InstanceColumnGlobalOrgID, crdb.ColumnTypeText, crdb.Default("")),
crdb.NewColumn(InstanceColumnProjectID, crdb.ColumnTypeText, crdb.Default("")),
crdb.NewColumn(InstanceColumnConsoleID, crdb.ColumnTypeText, crdb.Default("")),
crdb.NewColumn(InstanceColumnSequence, crdb.ColumnTypeInt64),
crdb.NewColumn(InstanceColumnSetUpStarted, crdb.ColumnTypeInt64, crdb.Default(0)),
crdb.NewColumn(InstanceColumnSetUpDone, crdb.ColumnTypeInt64, crdb.Default(0)),
@ -62,6 +64,10 @@ func (p *InstanceProjection) reducers() []handler.AggregateReducer {
Event: instance.ProjectSetEventType,
Reduce: p.reduceIAMProjectSet,
},
{
Event: instance.ConsoleSetEventType,
Reduce: p.reduceConsoleSet,
},
{
Event: instance.DefaultLanguageSetEventType,
Reduce: p.reduceDefaultLanguageSet,
@ -111,6 +117,22 @@ func (p *InstanceProjection) reduceIAMProjectSet(event eventstore.Event) (*handl
), nil
}
func (p *InstanceProjection) reduceConsoleSet(event eventstore.Event) (*handler.Statement, error) {
e, ok := event.(*instance.ConsoleSetEvent)
if !ok {
return nil, errors.ThrowInvalidArgumentf(nil, "HANDL-Dgf11", "reduce.wrong.event.type %s", instance.ConsoleSetEventType)
}
return crdb.NewUpsertStatement(
e,
[]handler.Column{
handler.NewCol(InstanceColumnID, e.Aggregate().InstanceID),
handler.NewCol(InstanceColumnChangeDate, e.CreationDate()),
handler.NewCol(InstanceColumnSequence, e.Sequence()),
handler.NewCol(InstanceColumnConsoleID, e.ClientID),
},
), nil
}
func (p *InstanceProjection) reduceDefaultLanguageSet(event eventstore.Event) (*handler.Statement, error) {
e, ok := event.(*instance.DefaultLanguageSetEvent)
if !ok {

View File

@ -14,7 +14,7 @@ import (
const (
InstanceMemberProjectionTable = "projections.instance_members"
InstanceMemberIAMIDCol = "instance_id"
InstanceMemberIAMIDCol = "id"
)
type InstanceMemberProjection struct {

View File

@ -44,7 +44,7 @@ func TestInstanceMemberProjection_reduces(t *testing.T) {
executer: &testExecuter{
executions: []execution{
{
expectedStmt: "INSERT INTO projections.instance_members (user_id, roles, creation_date, change_date, sequence, resource_owner, instance_id, instance_id) VALUES ($1, $2, $3, $4, $5, $6, $7, $8)",
expectedStmt: "INSERT INTO projections.instance_members (user_id, roles, creation_date, change_date, sequence, resource_owner, instance_id, id) VALUES ($1, $2, $3, $4, $5, $6, $7, $8)",
expectedArgs: []interface{}{
"user-id",
pq.StringArray{"role"},

View File

@ -107,7 +107,7 @@ func NewLoginNameProjection(ctx context.Context, config crdb.StatementHandlerCon
),
crdb.NewSuffixedTable([]*crdb.Column{
crdb.NewColumn(LoginNameDomainNameCol, crdb.ColumnTypeText),
crdb.NewColumn(LoginNameDomainIsPrimaryCol, crdb.ColumnTypeBool),
crdb.NewColumn(LoginNameDomainIsPrimaryCol, crdb.ColumnTypeBool, crdb.Default(false)),
crdb.NewColumn(LoginNameDomainResourceOwnerCol, crdb.ColumnTypeText),
crdb.NewColumn(LoginNameDomainInstanceIDCol, crdb.ColumnTypeText),
},

View File

@ -56,8 +56,8 @@ func NewLoginPolicyProjection(ctx context.Context, config crdb.StatementHandlerC
crdb.NewColumn(LoginPolicyAllowUsernamePasswordCol, crdb.ColumnTypeBool),
crdb.NewColumn(LoginPolicyAllowExternalIDPsCol, crdb.ColumnTypeBool),
crdb.NewColumn(LoginPolicyForceMFACol, crdb.ColumnTypeBool),
crdb.NewColumn(LoginPolicy2FAsCol, crdb.ColumnTypeEnumArray),
crdb.NewColumn(LoginPolicyMFAsCol, crdb.ColumnTypeEnumArray),
crdb.NewColumn(LoginPolicy2FAsCol, crdb.ColumnTypeEnumArray, crdb.Nullable()),
crdb.NewColumn(LoginPolicyMFAsCol, crdb.ColumnTypeEnumArray, crdb.Nullable()),
crdb.NewColumn(LoginPolicyPasswordlessTypeCol, crdb.ColumnTypeEnum),
crdb.NewColumn(LoginPolicyHidePWResetCol, crdb.ColumnTypeBool),
crdb.NewColumn(PasswordCheckLifetimeCol, crdb.ColumnTypeInt64),

View File

@ -51,13 +51,13 @@ func NewMessageTextProjection(ctx context.Context, config crdb.StatementHandlerC
crdb.NewColumn(MessageTextStateCol, crdb.ColumnTypeEnum),
crdb.NewColumn(MessageTextTypeCol, crdb.ColumnTypeText),
crdb.NewColumn(MessageTextLanguageCol, crdb.ColumnTypeText),
crdb.NewColumn(MessageTextTitleCol, crdb.ColumnTypeBool),
crdb.NewColumn(MessageTextPreHeaderCol, crdb.ColumnTypeBool),
crdb.NewColumn(MessageTextSubjectCol, crdb.ColumnTypeBool),
crdb.NewColumn(MessageTextGreetingCol, crdb.ColumnTypeBool),
crdb.NewColumn(MessageTextTextCol, crdb.ColumnTypeBool),
crdb.NewColumn(MessageTextButtonTextCol, crdb.ColumnTypeBool),
crdb.NewColumn(MessageTextFooterCol, crdb.ColumnTypeBool),
crdb.NewColumn(MessageTextTitleCol, crdb.ColumnTypeText, crdb.Nullable()),
crdb.NewColumn(MessageTextPreHeaderCol, crdb.ColumnTypeText, crdb.Nullable()),
crdb.NewColumn(MessageTextSubjectCol, crdb.ColumnTypeText, crdb.Nullable()),
crdb.NewColumn(MessageTextGreetingCol, crdb.ColumnTypeText, crdb.Nullable()),
crdb.NewColumn(MessageTextTextCol, crdb.ColumnTypeText, crdb.Nullable()),
crdb.NewColumn(MessageTextButtonTextCol, crdb.ColumnTypeText, crdb.Nullable()),
crdb.NewColumn(MessageTextFooterCol, crdb.ColumnTypeText, crdb.Nullable()),
},
crdb.NewPrimaryKey(MessageTextInstanceIDCol, MessageTextAggregateIDCol, MessageTextTypeCol, MessageTextLanguageCol),
),

View File

@ -43,7 +43,7 @@ func NewOrgProjection(ctx context.Context, config crdb.StatementHandlerConfig) *
crdb.NewColumn(OrgColumnState, crdb.ColumnTypeEnum),
crdb.NewColumn(OrgColumnSequence, crdb.ColumnTypeInt64),
crdb.NewColumn(OrgColumnName, crdb.ColumnTypeText),
crdb.NewColumn(OrgColumnDomain, crdb.ColumnTypeText),
crdb.NewColumn(OrgColumnDomain, crdb.ColumnTypeText, crdb.Default("")),
},
crdb.NewPrimaryKey(OrgColumnInstanceID, OrgColumnID),
crdb.WithIndex(crdb.NewIndex("domain_idx", []string{OrgColumnDomain})),

View File

@ -86,7 +86,7 @@ func NewUserProjection(ctx context.Context, config crdb.StatementHandlerConfig)
crdb.NewColumn(HumanNickNameCol, crdb.ColumnTypeText, crdb.Nullable()),
crdb.NewColumn(HumanDisplayNameCol, crdb.ColumnTypeText, crdb.Nullable()),
crdb.NewColumn(HumanPreferredLanguageCol, crdb.ColumnTypeText, crdb.Nullable()),
crdb.NewColumn(HumanGenderCol, crdb.ColumnTypeEnum),
crdb.NewColumn(HumanGenderCol, crdb.ColumnTypeEnum, crdb.Nullable()),
crdb.NewColumn(HumanAvatarURLCol, crdb.ColumnTypeText, crdb.Nullable()),
crdb.NewColumn(HumanEmailCol, crdb.ColumnTypeText),
crdb.NewColumn(HumanIsEmailVerifiedCol, crdb.ColumnTypeBool, crdb.Default(false)),

View File

@ -137,7 +137,7 @@ func (q *Queries) SecretGeneratorByType(ctx context.Context, generatorType domai
stmt, scan := prepareSecretGeneratorQuery()
query, args, err := stmt.Where(sq.Eq{
SecretGeneratorColumnGeneratorType.identifier(): generatorType,
SecretGeneratorColumnInstanceID.identifier(): authz.GetInstance(ctx).ID,
SecretGeneratorColumnInstanceID.identifier(): authz.GetInstance(ctx).InstanceID(),
}).ToSql()
if err != nil {
return nil, errors.ThrowInternal(err, "QUERY-3k99f", "Errors.Query.SQLStatment")
@ -151,7 +151,7 @@ func (q *Queries) SearchSecretGenerators(ctx context.Context, queries *SecretGen
query, scan := prepareSecretGeneratorsQuery()
stmt, args, err := queries.toQuery(query).
Where(sq.Eq{
SecretGeneratorColumnInstanceID.identifier(): authz.GetInstance(ctx).ID,
SecretGeneratorColumnInstanceID.identifier(): authz.GetInstance(ctx).InstanceID(),
}).ToSql()
if err != nil {
return nil, errors.ThrowInvalidArgument(err, "QUERY-sn9lw", "Errors.Query.InvalidRequest")

View File

@ -116,7 +116,7 @@ func (q *Queries) SMSProviderConfigByID(ctx context.Context, id string) (*SMSCon
query, args, err := stmt.Where(
sq.Eq{
SMSConfigColumnID.identifier(): id,
SMSConfigColumnInstanceID.identifier(): authz.GetInstance(ctx).ID,
SMSConfigColumnInstanceID.identifier(): authz.GetInstance(ctx).InstanceID(),
},
).ToSql()
if err != nil {
@ -131,7 +131,7 @@ func (q *Queries) SearchSMSConfigs(ctx context.Context, queries *SMSConfigsSearc
query, scan := prepareSMSConfigsQuery()
stmt, args, err := queries.toQuery(query).
Where(sq.Eq{
SMSConfigColumnInstanceID.identifier(): authz.GetInstance(ctx).ID,
SMSConfigColumnInstanceID.identifier(): authz.GetInstance(ctx).InstanceID(),
}).ToSql()
if err != nil {
return nil, errors.ThrowInvalidArgument(err, "QUERY-sn9Jf", "Errors.Query.InvalidRequest")

View File

@ -94,7 +94,7 @@ func (q *Queries) SMTPConfigByAggregateID(ctx context.Context, aggregateID strin
stmt, scan := prepareSMTPConfigQuery()
query, args, err := stmt.Where(sq.Eq{
SMTPConfigColumnAggregateID.identifier(): aggregateID,
SMTPConfigColumnInstanceID.identifier(): authz.GetInstance(ctx).ID,
SMTPConfigColumnInstanceID.identifier(): authz.GetInstance(ctx).InstanceID(),
}).ToSql()
if err != nil {
return nil, errors.ThrowInternal(err, "QUERY-3m9sl", "Errors.Query.SQLStatment")

View File

@ -231,7 +231,7 @@ var (
)
func (q *Queries) GetUserByID(ctx context.Context, userID string, queries ...SearchQuery) (*User, error) {
instanceID := authz.GetInstance(ctx).ID
instanceID := authz.GetInstance(ctx).InstanceID()
query, scan := prepareUserQuery(instanceID)
for _, q := range queries {
query = q.toQuery(query)
@ -249,7 +249,7 @@ func (q *Queries) GetUserByID(ctx context.Context, userID string, queries ...Sea
}
func (q *Queries) GetUser(ctx context.Context, queries ...SearchQuery) (*User, error) {
instanceID := authz.GetInstance(ctx).ID
instanceID := authz.GetInstance(ctx).InstanceID()
query, scan := prepareUserQuery(instanceID)
for _, q := range queries {
query = q.toQuery(query)
@ -272,7 +272,7 @@ func (q *Queries) GetHumanProfile(ctx context.Context, userID string, queries ..
}
stmt, args, err := query.Where(sq.Eq{
UserIDCol.identifier(): userID,
UserInstanceIDCol.identifier(): authz.GetInstance(ctx).ID,
UserInstanceIDCol.identifier(): authz.GetInstance(ctx).InstanceID(),
}).ToSql()
if err != nil {
return nil, errors.ThrowInternal(err, "QUERY-Dgbg2", "Errors.Query.SQLStatment")
@ -289,7 +289,7 @@ func (q *Queries) GetHumanEmail(ctx context.Context, userID string, queries ...S
}
stmt, args, err := query.Where(sq.Eq{
UserIDCol.identifier(): userID,
UserInstanceIDCol.identifier(): authz.GetInstance(ctx).ID,
UserInstanceIDCol.identifier(): authz.GetInstance(ctx).InstanceID(),
}).ToSql()
if err != nil {
return nil, errors.ThrowInternal(err, "QUERY-BHhj3", "Errors.Query.SQLStatment")
@ -306,7 +306,7 @@ func (q *Queries) GetHumanPhone(ctx context.Context, userID string, queries ...S
}
stmt, args, err := query.Where(sq.Eq{
UserIDCol.identifier(): userID,
UserInstanceIDCol.identifier(): authz.GetInstance(ctx).ID,
UserInstanceIDCol.identifier(): authz.GetInstance(ctx).InstanceID(),
}).ToSql()
if err != nil {
return nil, errors.ThrowInternal(err, "QUERY-Dg43g", "Errors.Query.SQLStatment")
@ -320,7 +320,7 @@ func (q *Queries) SearchUsers(ctx context.Context, queries *UserSearchQueries) (
query, scan := prepareUsersQuery()
stmt, args, err := queries.toQuery(query).
Where(sq.Eq{
UserInstanceIDCol.identifier(): authz.GetInstance(ctx).ID,
UserInstanceIDCol.identifier(): authz.GetInstance(ctx).InstanceID(),
}).ToSql()
if err != nil {
return nil, errors.ThrowInternal(err, "QUERY-Dgbg2", "Errors.Query.SQLStatment")
@ -366,7 +366,7 @@ func (q *Queries) IsUserUnique(ctx context.Context, username, email, resourceOwn
query = q.toQuery(query)
}
stmt, args, err := query.Where(sq.Eq{
UserInstanceIDCol.identifier(): authz.GetInstance(ctx).ID,
UserInstanceIDCol.identifier(): authz.GetInstance(ctx).InstanceID(),
}).ToSql()
if err != nil {
return false, errors.ThrowInternal(err, "QUERY-Dg43g", "Errors.Query.SQLStatment")
@ -437,7 +437,7 @@ func NewUserLoginNamesSearchQuery(value string) (SearchQuery, error) {
}
func prepareUserQuery(instanceID string) (sq.SelectBuilder, func(*sql.Row) (*User, error)) {
loginNamesQuery, _, err := sq.Select(
loginNamesQuery, loginNamesArgs, err := sq.Select(
userLoginNamesUserIDCol.identifier(),
"ARRAY_AGG("+userLoginNamesNameCol.identifier()+") as "+userLoginNamesListCol.name).
From(userLoginNamesTable.identifier()).
@ -489,7 +489,7 @@ func prepareUserQuery(instanceID string) (sq.SelectBuilder, func(*sql.Row) (*Use
From(userTable.identifier()).
LeftJoin(join(HumanUserIDCol, UserIDCol)).
LeftJoin(join(MachineUserIDCol, UserIDCol)).
LeftJoin("("+loginNamesQuery+") as "+userLoginNamesTable.alias+" on "+userLoginNamesUserIDCol.identifier()+" = "+UserIDCol.identifier()).
LeftJoin("("+loginNamesQuery+") as "+userLoginNamesTable.alias+" on "+userLoginNamesUserIDCol.identifier()+" = "+UserIDCol.identifier(), loginNamesArgs...).
LeftJoin("("+preferredLoginNameQuery+") as "+userPreferredLoginNameTable.alias+" on "+userPreferredLoginNameUserIDCol.identifier()+" = "+UserIDCol.identifier(), preferredLoginNameArgs...).
PlaceholderFormat(sq.Dollar),
func(row *sql.Row) (*User, error) {

View File

@ -91,7 +91,7 @@ func (q *Queries) UserAuthMethodByIDs(ctx context.Context, userID, tokenID, reso
UserAuthMethodColumnTokenID.identifier(): tokenID,
UserAuthMethodColumnResourceOwner.identifier(): resourceOwner,
UserAuthMethodColumnMethodType.identifier(): methodType,
UserAuthMethodColumnInstanceID.identifier(): authz.GetInstance(ctx).ID,
UserAuthMethodColumnInstanceID.identifier(): authz.GetInstance(ctx).InstanceID(),
}).ToSql()
if err != nil {
return nil, errors.ThrowInternal(err, "QUERY-2m00Q", "Errors.Query.SQLStatment")
@ -105,7 +105,7 @@ func (q *Queries) SearchUserAuthMethods(ctx context.Context, queries *UserAuthMe
query, scan := prepareUserAuthMethodsQuery()
stmt, args, err := queries.toQuery(query).
Where(sq.Eq{
UserAuthMethodColumnInstanceID.identifier(): authz.GetInstance(ctx).ID,
UserAuthMethodColumnInstanceID.identifier(): authz.GetInstance(ctx).InstanceID(),
}).ToSql()
if err != nil {
return nil, errors.ThrowInvalidArgument(err, "QUERY-j9NJd", "Errors.Query.InvalidRequest")

View File

@ -199,7 +199,7 @@ func (q *Queries) UserGrant(ctx context.Context, queries ...SearchQuery) (*UserG
}
stmt, args, err := query.
Where(sq.Eq{
UserGrantInstanceID.identifier(): authz.GetInstance(ctx).ID,
UserGrantInstanceID.identifier(): authz.GetInstance(ctx).InstanceID(),
}).ToSql()
if err != nil {
return nil, errors.ThrowInternal(err, "QUERY-Fa1KW", "Errors.Query.SQLStatement")
@ -213,7 +213,7 @@ func (q *Queries) UserGrants(ctx context.Context, queries *UserGrantsQueries) (*
query, scan := prepareUserGrantsQuery()
stmt, args, err := queries.toQuery(query).
Where(sq.Eq{
UserGrantInstanceID.identifier(): authz.GetInstance(ctx).ID,
UserGrantInstanceID.identifier(): authz.GetInstance(ctx).InstanceID(),
}).ToSql()
if err != nil {
return nil, errors.ThrowInternal(err, "QUERY-wXnQR", "Errors.Query.SQLStatement")

View File

@ -102,7 +102,7 @@ func (q *Queries) Memberships(ctx context.Context, queries *MembershipSearchQuer
query, scan := prepareMembershipsQuery()
stmt, args, err := queries.toQuery(query).
Where(sq.Eq{
membershipInstanceID.identifier(): authz.GetInstance(ctx).ID,
membershipInstanceID.identifier(): authz.GetInstance(ctx).InstanceID(),
}).ToSql()
if err != nil {
return nil, errors.ThrowInvalidArgument(err, "QUERY-T84X9", "Errors.Query.InvalidRequest")
@ -289,6 +289,7 @@ func prepareOrgMember() string {
OrgMemberChangeDate.identifier(),
OrgMemberSequence.identifier(),
OrgMemberResourceOwner.identifier(),
OrgMemberInstanceID.identifier(),
OrgMemberOrgID.identifier(),
"NULL::STRING AS "+membershipIAMID.name,
"NULL::STRING AS "+membershipProjectID.name,
@ -305,6 +306,7 @@ func prepareIAMMember() string {
InstanceMemberChangeDate.identifier(),
InstanceMemberSequence.identifier(),
InstanceMemberResourceOwner.identifier(),
InstanceMemberInstanceID.identifier(),
"NULL::STRING AS "+membershipOrgID.name,
InstanceMemberIAMID.identifier(),
"NULL::STRING AS "+membershipProjectID.name,
@ -321,6 +323,7 @@ func prepareProjectMember() string {
ProjectMemberChangeDate.identifier(),
ProjectMemberSequence.identifier(),
ProjectMemberResourceOwner.identifier(),
ProjectMemberInstanceID.identifier(),
"NULL::STRING AS "+membershipOrgID.name,
"NULL::STRING AS "+membershipIAMID.name,
ProjectMemberProjectID.identifier(),
@ -338,6 +341,7 @@ func prepareProjectGrantMember() string {
ProjectGrantMemberChangeDate.identifier(),
ProjectGrantMemberSequence.identifier(),
ProjectGrantMemberResourceOwner.identifier(),
ProjectGrantMemberInstanceID.identifier(),
"NULL::STRING AS "+membershipOrgID.name,
"NULL::STRING AS "+membershipIAMID.name,
ProjectGrantMemberProjectID.identifier(),

View File

@ -20,7 +20,7 @@ var (
", memberships.sequence" +
", memberships.resource_owner" +
", memberships.org_id" +
", memberships.instance_id" +
", memberships.id" +
", memberships.project_id" +
", memberships.grant_id" +
", projections.projects.name" +
@ -33,8 +33,9 @@ var (
", members.change_date" +
", members.sequence" +
", members.resource_owner" +
", members.instance_id" +
", members.org_id" +
", NULL::STRING AS instance_id" +
", NULL::STRING AS id" +
", NULL::STRING AS project_id" +
", NULL::STRING AS grant_id" +
" FROM projections.org_members as members" +
@ -45,8 +46,9 @@ var (
", members.change_date" +
", members.sequence" +
", members.resource_owner" +
", NULL::STRING AS org_id" +
", members.instance_id" +
", NULL::STRING AS org_id" +
", members.id" +
", NULL::STRING AS project_id" +
", NULL::STRING AS grant_id" +
" FROM projections.instance_members as members" +
@ -57,8 +59,9 @@ var (
", members.change_date" +
", members.sequence" +
", members.resource_owner" +
", members.instance_id" +
", NULL::STRING AS org_id" +
", NULL::STRING AS instance_id" +
", NULL::STRING AS id" +
", members.project_id" +
", NULL::STRING AS grant_id" +
" FROM projections.project_members as members" +
@ -69,8 +72,9 @@ var (
", members.change_date" +
", members.sequence" +
", members.resource_owner" +
", members.instance_id" +
", NULL::STRING AS org_id" +
", NULL::STRING AS instance_id" +
", NULL::STRING AS id" +
", members.project_id" +
", members.grant_id" +
" FROM projections.project_grant_members as members" +

View File

@ -80,7 +80,7 @@ func (q *Queries) GetUserMetadataByKey(ctx context.Context, userID, key string,
sq.Eq{
UserMetadataUserIDCol.identifier(): userID,
UserMetadataKeyCol.identifier(): key,
UserMetadataInstanceIDCol.identifier(): authz.GetInstance(ctx).ID,
UserMetadataInstanceIDCol.identifier(): authz.GetInstance(ctx).InstanceID(),
}).ToSql()
if err != nil {
return nil, errors.ThrowInternal(err, "QUERY-aDGG2", "Errors.Query.SQLStatment")
@ -95,7 +95,7 @@ func (q *Queries) SearchUserMetadata(ctx context.Context, userID string, queries
stmt, args, err := queries.toQuery(query).Where(
sq.Eq{
UserMetadataUserIDCol.identifier(): userID,
UserMetadataInstanceIDCol.identifier(): authz.GetInstance(ctx).ID,
UserMetadataInstanceIDCol.identifier(): authz.GetInstance(ctx).InstanceID(),
}).
ToSql()
if err != nil {

View File

@ -87,7 +87,7 @@ func (q *Queries) PersonalAccessTokenByID(ctx context.Context, id string, querie
}
stmt, args, err := query.Where(sq.Eq{
PersonalAccessTokenColumnID.identifier(): id,
PersonalAccessTokenColumnInstanceID.identifier(): authz.GetInstance(ctx).ID,
PersonalAccessTokenColumnInstanceID.identifier(): authz.GetInstance(ctx).InstanceID(),
}).ToSql()
if err != nil {
return nil, errors.ThrowInternal(err, "QUERY-Dgfb4", "Errors.Query.SQLStatment")
@ -101,7 +101,7 @@ func (q *Queries) SearchPersonalAccessTokens(ctx context.Context, queries *Perso
query, scan := preparePersonalAccessTokensQuery()
stmt, args, err := queries.toQuery(query).
Where(sq.Eq{
PersonalAccessTokenColumnInstanceID.identifier(): authz.GetInstance(ctx).ID,
PersonalAccessTokenColumnInstanceID.identifier(): authz.GetInstance(ctx).InstanceID(),
}).ToSql()
if err != nil {
return nil, errors.ThrowInvalidArgument(err, "QUERY-Hjw2w", "Errors.Query.InvalidRequest")

View File

@ -11,7 +11,8 @@ import (
)
const (
ProjectSetEventType eventstore.EventType = "iam.project.iam.set"
ProjectSetEventType eventstore.EventType = "instance.iam.project.set"
ConsoleSetEventType eventstore.EventType = "instance.iam.console.set"
)
type ProjectSetEvent struct {
@ -54,3 +55,44 @@ func ProjectSetMapper(event *repository.Event) (eventstore.Event, error) {
return e, nil
}
type ConsoleSetEvent struct {
eventstore.BaseEvent `json:"-"`
ClientID string `json:"clientId"`
}
func (e *ConsoleSetEvent) Data() interface{} {
return e
}
func (e *ConsoleSetEvent) UniqueConstraints() []*eventstore.EventUniqueConstraint {
return nil
}
func NewIAMConsoleSetEvent(
ctx context.Context,
aggregate *eventstore.Aggregate,
clientID string,
) *ConsoleSetEvent {
return &ConsoleSetEvent{
BaseEvent: *eventstore.NewBaseEventForPush(
ctx,
aggregate,
ConsoleSetEventType,
),
ClientID: clientID,
}
}
func ConsoleSetMapper(event *repository.Event) (eventstore.Event, error) {
e := &ConsoleSetEvent{
BaseEvent: *eventstore.BaseEventFromRepo(event),
}
err := json.Unmarshal(event.Data, e)
if err != nil {
return nil, errors.ThrowInternal(err, "IAM-cdFZH", "unable to unmarshal console set")
}
return e, nil
}

Some files were not shown because too many files have changed in this diff Show More