mirror of
https://github.com/zitadel/zitadel.git
synced 2025-08-11 15:49:35 +00:00
instance custom domain event tests done
This commit is contained in:
@@ -13,6 +13,13 @@ const (
|
||||
DomainValidationTypeHTTP DomainValidationType = "http"
|
||||
)
|
||||
|
||||
type DomainType string
|
||||
|
||||
const (
|
||||
DomainTypeCustom DomainType = "custom"
|
||||
DomainTypeTrusted DomainType = "trusted"
|
||||
)
|
||||
|
||||
type domainColumns interface {
|
||||
// InstanceIDColumn returns the column for the instance id field.
|
||||
// `qualified` indicates if the column should be qualified with the table name.
|
||||
@@ -20,15 +27,9 @@ type domainColumns interface {
|
||||
// DomainColumn returns the column for the domain field.
|
||||
// `qualified` indicates if the column should be qualified with the table name.
|
||||
DomainColumn(qualified bool) database.Column
|
||||
// IsVerifiedColumn returns the column for the is verified field.
|
||||
// `qualified` indicates if the column should be qualified with the table name.
|
||||
IsVerifiedColumn(qualified bool) database.Column
|
||||
// IsPrimaryColumn returns the column for the is primary field.
|
||||
// `qualified` indicates if the column should be qualified with the table name.
|
||||
IsPrimaryColumn(qualified bool) database.Column
|
||||
// ValidationTypeColumn returns the column for the verification type field.
|
||||
// `qualified` indicates if the column should be qualified with the table name.
|
||||
ValidationTypeColumn(qualified bool) database.Column
|
||||
// CreatedAtColumn returns the column for the created at field.
|
||||
// `qualified` indicates if the column should be qualified with the table name.
|
||||
CreatedAtColumn(qualified bool) database.Column
|
||||
@@ -44,13 +45,9 @@ type domainConditions interface {
|
||||
DomainCondition(op database.TextOperation, domain string) database.Condition
|
||||
// IsPrimaryCondition returns a filter on the is primary field.
|
||||
IsPrimaryCondition(isPrimary bool) database.Condition
|
||||
// IsVerifiedCondition returns a filter on the is verified field.
|
||||
IsVerifiedCondition(isVerified bool) database.Condition
|
||||
}
|
||||
|
||||
type domainChanges interface {
|
||||
// SetVerified sets the is verified column to true.
|
||||
SetVerified() database.Change
|
||||
// SetPrimary sets a domain as primary based on the condition.
|
||||
// All other domains will be set to non-primary.
|
||||
//
|
||||
@@ -62,9 +59,6 @@ type domainChanges interface {
|
||||
// - The domain is already primary.
|
||||
// - No domain matches the condition.
|
||||
SetPrimary() database.Change
|
||||
// SetValidationType sets the verification type column.
|
||||
// If the domain is already verified, this is a no-op.
|
||||
SetValidationType(verificationType DomainValidationType) database.Change
|
||||
// SetUpdatedAt sets the updated at column.
|
||||
// This is used for reducing events.
|
||||
SetUpdatedAt(t time.Time) database.Change
|
||||
|
@@ -8,30 +8,28 @@ import (
|
||||
)
|
||||
|
||||
type InstanceDomain struct {
|
||||
InstanceID string `json:"instanceId,omitempty" db:"instance_id"`
|
||||
Domain string `json:"domain,omitempty" db:"domain"`
|
||||
IsVerified bool `json:"isVerified,omitempty" db:"is_verified"`
|
||||
IsPrimary bool `json:"isPrimary,omitempty" db:"is_primary"`
|
||||
ValidationType *DomainValidationType `json:"validationType,omitempty" db:"validation_type"`
|
||||
InstanceID string `json:"instanceId,omitempty" db:"instance_id"`
|
||||
Domain string `json:"domain,omitempty" db:"domain"`
|
||||
IsPrimary bool `json:"isPrimary,omitempty" db:"is_primary"`
|
||||
Type DomainType `json:"type,omitempty" db:"type"`
|
||||
|
||||
CreatedAt time.Time `json:"createdAt,omitzero" db:"created_at"`
|
||||
UpdatedAt time.Time `json:"updatedAt,omitzero" db:"updated_at"`
|
||||
}
|
||||
|
||||
type AddInstanceDomain struct {
|
||||
InstanceID string `json:"instanceId,omitempty" db:"instance_id"`
|
||||
Domain string `json:"domain,omitempty" db:"domain"`
|
||||
IsVerified bool `json:"isVerified,omitempty" db:"is_verified"`
|
||||
IsPrimary bool `json:"isPrimary,omitempty" db:"is_primary"`
|
||||
IsGenerated bool `json:"isGenerated,omitempty" db:"is_generated"`
|
||||
ValidationType *DomainValidationType `json:"validationType,omitempty" db:"validation_type"`
|
||||
InstanceID string `json:"instanceId,omitempty" db:"instance_id"`
|
||||
Domain string `json:"domain,omitempty" db:"domain"`
|
||||
IsPrimary bool `json:"isPrimary,omitempty" db:"is_primary"`
|
||||
IsGenerated bool `json:"isGenerated,omitempty" db:"is_generated"`
|
||||
Type DomainType `json:"type,omitempty" db:"type"`
|
||||
|
||||
// CreatedAt is the time when the domain was added.
|
||||
// It is set by the repository and should not be set by the caller.
|
||||
CreatedAt time.Time `json:"createdAt,omitzero" db:"created_at"`
|
||||
CreatedAt *time.Time `json:"createdAt,omitzero" db:"created_at"`
|
||||
// UpdatedAt is the time when the domain was last updated.
|
||||
// It is set by the repository and should not be set by the caller.
|
||||
UpdatedAt time.Time `json:"updatedAt,omitzero" db:"updated_at"`
|
||||
UpdatedAt *time.Time `json:"updatedAt,omitzero" db:"updated_at"`
|
||||
}
|
||||
|
||||
type instanceDomainColumns interface {
|
||||
@@ -39,14 +37,21 @@ type instanceDomainColumns interface {
|
||||
// IsGeneratedColumn returns the column for the is generated field.
|
||||
// `qualified` indicates if the column should be qualified with the table name.
|
||||
IsGeneratedColumn(qualified bool) database.Column
|
||||
// TypeColumn returns the column for the type field.
|
||||
// `qualified` indicates if the column should be qualified with the table name.
|
||||
TypeColumn(qualified bool) database.Column
|
||||
}
|
||||
|
||||
type instanceDomainConditions interface {
|
||||
domainConditions
|
||||
// TypeCondition returns a filter for the type field.
|
||||
TypeCondition(typ DomainType) database.Condition
|
||||
}
|
||||
|
||||
type instanceDomainChanges interface {
|
||||
domainChanges
|
||||
// SetType sets the type column.
|
||||
SetType(typ DomainType) database.Change
|
||||
}
|
||||
|
||||
type InstanceDomainRepository interface {
|
||||
|
@@ -38,17 +38,31 @@ type AddOrganizationDomain struct {
|
||||
type organizationDomainColumns interface {
|
||||
domainColumns
|
||||
// OrgIDColumn returns the column for the org id field.
|
||||
// `qualified` indicates if the column should be qualified with the table name.
|
||||
OrgIDColumn(qualified bool) database.Column
|
||||
// IsVerifiedColumn returns the column for the is verified field.
|
||||
// `qualified` indicates if the column should be qualified with the table name.
|
||||
IsVerifiedColumn(qualified bool) database.Column
|
||||
// ValidationTypeColumn returns the column for the verification type field.
|
||||
// `qualified` indicates if the column should be qualified with the table name.
|
||||
ValidationTypeColumn(qualified bool) database.Column
|
||||
}
|
||||
|
||||
type organizationDomainConditions interface {
|
||||
domainConditions
|
||||
// OrgIDCondition returns a filter on the org id field.
|
||||
OrgIDCondition(orgID string) database.Condition
|
||||
// IsVerifiedCondition returns a filter on the is verified field.
|
||||
IsVerifiedCondition(isVerified bool) database.Condition
|
||||
}
|
||||
|
||||
type organizationDomainChanges interface {
|
||||
domainChanges
|
||||
// SetVerified sets the is verified column to true.
|
||||
SetVerified() database.Change
|
||||
// SetValidationType sets the verification type column.
|
||||
// If the domain is already verified, this is a no-op.
|
||||
SetValidationType(verificationType DomainValidationType) database.Change
|
||||
}
|
||||
|
||||
type OrganizationDomainRepository interface {
|
||||
|
@@ -3,20 +3,28 @@ CREATE TYPE zitadel.domain_validation_type AS ENUM (
|
||||
, 'dns'
|
||||
);
|
||||
|
||||
CREATE TYPE zitadel.domain_type AS ENUM (
|
||||
'custom'
|
||||
, 'trusted'
|
||||
);
|
||||
|
||||
CREATE TABLE zitadel.instance_domains(
|
||||
instance_id TEXT NOT NULL
|
||||
, domain TEXT NOT NULL CHECK (LENGTH(domain) BETWEEN 1 AND 255)
|
||||
, is_verified BOOLEAN NOT NULL DEFAULT FALSE
|
||||
, is_primary BOOLEAN NOT NULL DEFAULT FALSE
|
||||
, is_generated BOOLEAN NOT NULL DEFAULT FALSE
|
||||
, validation_type zitadel.domain_validation_type
|
||||
, is_primary BOOLEAN
|
||||
, is_generated BOOLEAN
|
||||
, type zitadel.domain_type NOT NULL
|
||||
|
||||
, created_at TIMESTAMP DEFAULT NOW()
|
||||
, updated_at TIMESTAMP DEFAULT NOW()
|
||||
, created_at TIMESTAMPTZ DEFAULT NOW()
|
||||
, updated_at TIMESTAMPTZ DEFAULT NOW()
|
||||
|
||||
, PRIMARY KEY (domain)
|
||||
|
||||
, FOREIGN KEY (instance_id) REFERENCES zitadel.instances(id) ON DELETE CASCADE
|
||||
|
||||
, CONSTRAINT primary_cannot_be_trusted CHECK (is_primary IS NULL OR type != 'trusted')
|
||||
, CONSTRAINT generated_cannot_be_trusted CHECK (is_generated IS NULL OR type != 'trusted')
|
||||
, CONSTRAINT custom_values_set CHECK (type = 'custom' AND is_primary IS NOT NULL AND is_generated IS NOT NULL)
|
||||
);
|
||||
|
||||
CREATE INDEX idx_instance_domain_instance ON zitadel.instance_domains(instance_id);
|
||||
@@ -29,8 +37,8 @@ CREATE TABLE zitadel.org_domains(
|
||||
, is_primary BOOLEAN NOT NULL DEFAULT FALSE
|
||||
, validation_type zitadel.domain_validation_type
|
||||
|
||||
, created_at TIMESTAMP DEFAULT NOW()
|
||||
, updated_at TIMESTAMP DEFAULT NOW()
|
||||
, created_at TIMESTAMPTZ DEFAULT NOW()
|
||||
, updated_at TIMESTAMPTZ DEFAULT NOW()
|
||||
|
||||
, PRIMARY KEY (instance_id, org_id, domain)
|
||||
|
||||
@@ -91,7 +99,8 @@ BEGIN
|
||||
SET is_primary = FALSE, updated_at = NOW()
|
||||
WHERE instance_id = NEW.instance_id
|
||||
AND domain != NEW.domain
|
||||
AND is_primary = TRUE;
|
||||
AND is_primary = TRUE
|
||||
AND type = 'custom';
|
||||
|
||||
RETURN NEW;
|
||||
END;
|
||||
|
@@ -4,6 +4,7 @@ package events_test
|
||||
|
||||
import (
|
||||
"context"
|
||||
"log"
|
||||
"os"
|
||||
"testing"
|
||||
"time"
|
||||
@@ -14,11 +15,12 @@ import (
|
||||
"github.com/zitadel/zitadel/backend/v3/storage/database"
|
||||
"github.com/zitadel/zitadel/backend/v3/storage/database/dialect/postgres"
|
||||
"github.com/zitadel/zitadel/internal/integration"
|
||||
v2beta "github.com/zitadel/zitadel/pkg/grpc/instance/v2beta"
|
||||
v2beta_org "github.com/zitadel/zitadel/pkg/grpc/org/v2beta"
|
||||
"github.com/zitadel/zitadel/pkg/grpc/system"
|
||||
)
|
||||
|
||||
const ConnString = "host=localhost port=5432 user=zitadel dbname=zitadel sslmode=disable"
|
||||
const ConnString = "host=localhost port=5432 user=zitadel password=zitadel dbname=zitadel sslmode=disable"
|
||||
|
||||
var (
|
||||
dbPool *pgxpool.Pool
|
||||
@@ -35,12 +37,21 @@ func TestMain(m *testing.M) {
|
||||
ctx, cancel := context.WithTimeout(context.Background(), 15*time.Minute)
|
||||
defer cancel()
|
||||
|
||||
Instance = integration.NewInstance(ctx)
|
||||
CTX = integration.WithSystemAuthorization(ctx)
|
||||
Instance = integration.NewInstance(CTX)
|
||||
|
||||
CTX = Instance.WithAuthorization(ctx, integration.UserTypeIAMOwner)
|
||||
SystemClient = integration.SystemClient()
|
||||
OrgClient = Instance.Client.OrgV2beta
|
||||
|
||||
defer func() {
|
||||
_, err := Instance.Client.InstanceV2Beta.DeleteInstance(CTX, &v2beta.DeleteInstanceRequest{
|
||||
InstanceId: Instance.Instance.Id,
|
||||
})
|
||||
if err != nil {
|
||||
log.Printf("Failed to delete instance on cleanup: %v\n", err)
|
||||
}
|
||||
}()
|
||||
|
||||
var err error
|
||||
dbConfig, err := pgxpool.ParseConfig(ConnString)
|
||||
if err != nil {
|
||||
|
@@ -0,0 +1,224 @@
|
||||
//go:build integration
|
||||
|
||||
package events_test
|
||||
|
||||
import (
|
||||
"log"
|
||||
"testing"
|
||||
"time"
|
||||
|
||||
"github.com/brianvoe/gofakeit/v6"
|
||||
"github.com/stretchr/testify/assert"
|
||||
"github.com/stretchr/testify/require"
|
||||
|
||||
"github.com/zitadel/zitadel/backend/v3/storage/database"
|
||||
"github.com/zitadel/zitadel/backend/v3/storage/database/repository"
|
||||
"github.com/zitadel/zitadel/internal/integration"
|
||||
v2beta "github.com/zitadel/zitadel/pkg/grpc/instance/v2beta"
|
||||
"github.com/zitadel/zitadel/pkg/grpc/system"
|
||||
)
|
||||
|
||||
func TestServer_TestInstanceDomainReduces(t *testing.T) {
|
||||
instance := integration.NewInstance(CTX)
|
||||
|
||||
instanceRepo := repository.InstanceRepository(pool)
|
||||
instanceDomainRepo := instanceRepo.Domains(true)
|
||||
|
||||
t.Cleanup(func() {
|
||||
_, err := instance.Client.InstanceV2Beta.DeleteInstance(CTX, &v2beta.DeleteInstanceRequest{
|
||||
InstanceId: instance.Instance.Id,
|
||||
})
|
||||
if err != nil {
|
||||
t.Logf("Failed to delete instance on cleanup: %v", err)
|
||||
}
|
||||
})
|
||||
|
||||
// Wait for instance to be created
|
||||
retryDuration, tick := integration.WaitForAndTickWithMaxDuration(CTX, time.Minute)
|
||||
assert.EventuallyWithT(t, func(ttt *assert.CollectT) {
|
||||
_, err := instanceRepo.Get(CTX,
|
||||
database.WithCondition(instanceRepo.IDCondition(instance.Instance.Id)),
|
||||
)
|
||||
assert.NoError(ttt, err)
|
||||
}, retryDuration, tick)
|
||||
|
||||
t.Run("test instance domain add reduces", func(t *testing.T) {
|
||||
// Add a domain to the instance
|
||||
domainName := gofakeit.DomainName()
|
||||
beforeAdd := time.Now()
|
||||
_, err := instance.Client.InstanceV2Beta.AddCustomDomain(CTX, &v2beta.AddCustomDomainRequest{
|
||||
InstanceId: instance.Instance.Id,
|
||||
Domain: domainName,
|
||||
})
|
||||
require.NoError(t, err)
|
||||
afterAdd := time.Now()
|
||||
|
||||
t.Cleanup(func() {
|
||||
_, err := instance.Client.InstanceV2Beta.RemoveCustomDomain(CTX, &v2beta.RemoveCustomDomainRequest{
|
||||
InstanceId: instance.Instance.Id,
|
||||
Domain: domainName,
|
||||
})
|
||||
if err != nil {
|
||||
t.Logf("Failed to delete instance domain on cleanup: %v", err)
|
||||
}
|
||||
})
|
||||
|
||||
// Test that domain add reduces
|
||||
retryDuration, tick = integration.WaitForAndTickWithMaxDuration(CTX, time.Minute)
|
||||
assert.EventuallyWithT(t, func(ttt *assert.CollectT) {
|
||||
domain, err := instanceDomainRepo.Get(CTX,
|
||||
database.WithCondition(
|
||||
database.And(
|
||||
instanceDomainRepo.InstanceIDCondition(instance.Instance.Id),
|
||||
instanceDomainRepo.DomainCondition(database.TextOperationEqual, domainName),
|
||||
),
|
||||
),
|
||||
)
|
||||
require.NoError(ttt, err)
|
||||
// event instance.domain.added
|
||||
assert.Equal(ttt, domainName, domain.Domain)
|
||||
assert.Equal(ttt, instance.Instance.Id, domain.InstanceID)
|
||||
assert.False(ttt, domain.IsPrimary)
|
||||
log.Printf("created at %v\n", domain.CreatedAt)
|
||||
log.Printf("after %v\n", afterAdd)
|
||||
log.Printf("before %v\n", beforeAdd)
|
||||
assert.WithinRange(ttt, domain.CreatedAt, beforeAdd, afterAdd)
|
||||
assert.WithinRange(ttt, domain.UpdatedAt, beforeAdd, afterAdd)
|
||||
}, retryDuration, tick)
|
||||
})
|
||||
t.Run("test instance domain set primary reduces", func(t *testing.T) {
|
||||
// Add a domain to the instance
|
||||
domainName := gofakeit.DomainName()
|
||||
_, err := instance.Client.InstanceV2Beta.AddCustomDomain(CTX, &v2beta.AddCustomDomainRequest{
|
||||
InstanceId: instance.Instance.Id,
|
||||
Domain: domainName,
|
||||
})
|
||||
require.NoError(t, err)
|
||||
|
||||
t.Cleanup(func() {
|
||||
// first we change the primary domain to something else
|
||||
domain, err := instanceDomainRepo.Get(CTX,
|
||||
database.WithCondition(
|
||||
database.And(
|
||||
instanceDomainRepo.InstanceIDCondition(instance.Instance.Id),
|
||||
instanceDomainRepo.IsPrimaryCondition(false),
|
||||
),
|
||||
),
|
||||
database.WithLimit(1),
|
||||
)
|
||||
require.NoError(t, err)
|
||||
_, err = SystemClient.SetPrimaryDomain(CTX, &system.SetPrimaryDomainRequest{
|
||||
InstanceId: instance.Instance.Id,
|
||||
Domain: domain.Domain,
|
||||
})
|
||||
require.NoError(t, err)
|
||||
|
||||
_, err = instance.Client.InstanceV2Beta.RemoveCustomDomain(CTX, &v2beta.RemoveCustomDomainRequest{
|
||||
InstanceId: instance.Instance.Id,
|
||||
Domain: domainName,
|
||||
})
|
||||
if err != nil {
|
||||
t.Logf("Failed to delete instance domain on cleanup: %v", err)
|
||||
}
|
||||
})
|
||||
|
||||
// Wait for domain to be created
|
||||
retryDuration, tick = integration.WaitForAndTickWithMaxDuration(CTX, time.Minute)
|
||||
assert.EventuallyWithT(t, func(ttt *assert.CollectT) {
|
||||
domain, err := instanceDomainRepo.Get(CTX,
|
||||
database.WithCondition(
|
||||
database.And(
|
||||
instanceDomainRepo.InstanceIDCondition(instance.Instance.Id),
|
||||
instanceDomainRepo.DomainCondition(database.TextOperationEqual, domainName)),
|
||||
),
|
||||
)
|
||||
require.NoError(ttt, err)
|
||||
require.False(ttt, domain.IsPrimary)
|
||||
assert.Equal(ttt, domainName, domain.Domain)
|
||||
}, retryDuration, tick)
|
||||
|
||||
// Set domain as primary
|
||||
beforeSetPrimary := time.Now()
|
||||
_, err = SystemClient.SetPrimaryDomain(CTX, &system.SetPrimaryDomainRequest{
|
||||
InstanceId: instance.Instance.Id,
|
||||
Domain: domainName,
|
||||
})
|
||||
require.NoError(t, err)
|
||||
afterSetPrimary := time.Now()
|
||||
|
||||
// Test that set primary reduces
|
||||
retryDuration, tick = integration.WaitForAndTickWithMaxDuration(CTX, time.Minute)
|
||||
assert.EventuallyWithT(t, func(ttt *assert.CollectT) {
|
||||
domain, err := instanceDomainRepo.Get(CTX,
|
||||
database.WithCondition(
|
||||
database.And(
|
||||
instanceDomainRepo.InstanceIDCondition(instance.Instance.Id),
|
||||
instanceDomainRepo.IsPrimaryCondition(true),
|
||||
),
|
||||
),
|
||||
)
|
||||
require.NoError(ttt, err)
|
||||
// event instance.domain.primary.set
|
||||
assert.Equal(ttt, domainName, domain.Domain)
|
||||
assert.True(ttt, domain.IsPrimary)
|
||||
assert.WithinRange(ttt, domain.UpdatedAt, beforeSetPrimary, afterSetPrimary)
|
||||
}, retryDuration, tick)
|
||||
})
|
||||
|
||||
t.Run("test instance domain remove reduces", func(t *testing.T) {
|
||||
// Add a domain to the instance
|
||||
domainName := gofakeit.DomainName()
|
||||
_, err := instance.Client.InstanceV2Beta.AddCustomDomain(CTX, &v2beta.AddCustomDomainRequest{
|
||||
InstanceId: instance.Instance.Id,
|
||||
Domain: domainName,
|
||||
})
|
||||
require.NoError(t, err)
|
||||
|
||||
t.Cleanup(func() {
|
||||
_, err := instance.Client.InstanceV2Beta.RemoveCustomDomain(CTX, &v2beta.RemoveCustomDomainRequest{
|
||||
InstanceId: instance.Instance.Id,
|
||||
Domain: domainName,
|
||||
})
|
||||
if err != nil {
|
||||
t.Logf("Failed to delete instance domain on cleanup: %v", err)
|
||||
}
|
||||
})
|
||||
|
||||
// Wait for domain to be created and verify it exists
|
||||
retryDuration, tick = integration.WaitForAndTickWithMaxDuration(CTX, time.Minute)
|
||||
assert.EventuallyWithT(t, func(ttt *assert.CollectT) {
|
||||
_, err := instanceDomainRepo.Get(CTX,
|
||||
database.WithCondition(
|
||||
database.And(
|
||||
instanceDomainRepo.InstanceIDCondition(instance.Instance.Id),
|
||||
instanceDomainRepo.DomainCondition(database.TextOperationEqual, domainName),
|
||||
),
|
||||
),
|
||||
)
|
||||
require.NoError(ttt, err)
|
||||
}, retryDuration, tick)
|
||||
|
||||
// Remove the domain
|
||||
_, err = SystemClient.RemoveDomain(CTX, &system.RemoveDomainRequest{
|
||||
InstanceId: instance.Instance.Id,
|
||||
Domain: domainName,
|
||||
})
|
||||
require.NoError(t, err)
|
||||
|
||||
// Test that domain remove reduces
|
||||
retryDuration, tick = integration.WaitForAndTickWithMaxDuration(CTX, time.Minute)
|
||||
assert.EventuallyWithT(t, func(ttt *assert.CollectT) {
|
||||
domain, err := instanceDomainRepo.Get(CTX,
|
||||
database.WithCondition(
|
||||
database.And(
|
||||
instanceDomainRepo.InstanceIDCondition(instance.Instance.Id),
|
||||
instanceDomainRepo.DomainCondition(database.TextOperationEqual, domainName),
|
||||
),
|
||||
),
|
||||
)
|
||||
// event instance.domain.removed
|
||||
assert.Nil(ttt, domain)
|
||||
require.ErrorIs(ttt, err, new(database.NoRowFoundError))
|
||||
}, retryDuration, tick)
|
||||
})
|
||||
}
|
@@ -17,6 +17,8 @@ import (
|
||||
)
|
||||
|
||||
func TestServer_TestInstanceReduces(t *testing.T) {
|
||||
instanceRepo := repository.InstanceRepository(pool)
|
||||
|
||||
t.Run("test instance add reduces", func(t *testing.T) {
|
||||
instanceName := gofakeit.Name()
|
||||
beforeCreate := time.Now()
|
||||
@@ -33,8 +35,15 @@ func TestServer_TestInstanceReduces(t *testing.T) {
|
||||
afterCreate := time.Now()
|
||||
|
||||
require.NoError(t, err)
|
||||
t.Cleanup(func() {
|
||||
_, err = SystemClient.RemoveInstance(CTX, &system.RemoveInstanceRequest{
|
||||
InstanceId: instance.GetInstanceId(),
|
||||
})
|
||||
if err != nil {
|
||||
t.Logf("Failed to delete instance on cleanup: %v", err)
|
||||
}
|
||||
})
|
||||
|
||||
instanceRepo := repository.InstanceRepository(pool)
|
||||
retryDuration, tick := integration.WaitForAndTickWithMaxDuration(CTX, time.Minute)
|
||||
assert.EventuallyWithT(t, func(ttt *assert.CollectT) {
|
||||
instance, err := instanceRepo.Get(CTX,
|
||||
@@ -71,6 +80,14 @@ func TestServer_TestInstanceReduces(t *testing.T) {
|
||||
},
|
||||
})
|
||||
require.NoError(t, err)
|
||||
t.Cleanup(func() {
|
||||
_, err = SystemClient.RemoveInstance(CTX, &system.RemoveInstanceRequest{
|
||||
InstanceId: res.GetInstanceId(),
|
||||
})
|
||||
if err != nil {
|
||||
t.Logf("Failed to delete instance on cleanup: %v", err)
|
||||
}
|
||||
})
|
||||
|
||||
instanceName += "new"
|
||||
beforeUpdate := time.Now()
|
||||
@@ -78,10 +95,9 @@ func TestServer_TestInstanceReduces(t *testing.T) {
|
||||
InstanceId: res.InstanceId,
|
||||
InstanceName: instanceName,
|
||||
})
|
||||
require.NoError(t, err)
|
||||
afterUpdate := time.Now()
|
||||
require.NoError(t, err)
|
||||
|
||||
instanceRepo := repository.InstanceRepository(pool)
|
||||
retryDuration, tick := integration.WaitForAndTickWithMaxDuration(CTX, time.Minute)
|
||||
assert.EventuallyWithT(t, func(ttt *assert.CollectT) {
|
||||
instance, err := instanceRepo.Get(CTX,
|
||||
@@ -108,8 +124,6 @@ func TestServer_TestInstanceReduces(t *testing.T) {
|
||||
})
|
||||
require.NoError(t, err)
|
||||
|
||||
instanceRepo := repository.InstanceRepository(pool)
|
||||
|
||||
// check instance exists
|
||||
retryDuration, tick := integration.WaitForAndTickWithMaxDuration(CTX, time.Minute)
|
||||
assert.EventuallyWithT(t, func(ttt *assert.CollectT) {
|
||||
|
@@ -19,25 +19,33 @@ import (
|
||||
|
||||
func TestServer_TestOrganizationReduces(t *testing.T) {
|
||||
instanceID := Instance.ID()
|
||||
orgRepo := repository.OrganizationRepository(pool)
|
||||
|
||||
t.Run("test org add reduces", func(t *testing.T) {
|
||||
beforeCreate := time.Now()
|
||||
orgName := gofakeit.Name()
|
||||
|
||||
_, err := OrgClient.CreateOrganization(CTX, &v2beta_org.CreateOrganizationRequest{
|
||||
org, err := OrgClient.CreateOrganization(CTX, &v2beta_org.CreateOrganizationRequest{
|
||||
Name: orgName,
|
||||
})
|
||||
require.NoError(t, err)
|
||||
afterCreate := time.Now()
|
||||
|
||||
orgRepo := repository.OrganizationRepository(pool)
|
||||
t.Cleanup(func() {
|
||||
_, err = OrgClient.DeleteOrganization(CTX, &v2beta_org.DeleteOrganizationRequest{
|
||||
Id: org.GetId(),
|
||||
})
|
||||
if err != nil {
|
||||
t.Logf("Failed to delete organization on cleanup: %v", err)
|
||||
}
|
||||
})
|
||||
|
||||
retryDuration, tick := integration.WaitForAndTickWithMaxDuration(CTX, time.Minute)
|
||||
assert.EventuallyWithT(t, func(tt *assert.CollectT) {
|
||||
organization, err := orgRepo.Get(CTX,
|
||||
database.WithCondition(
|
||||
database.And(
|
||||
orgRepo.NameCondition(orgName),
|
||||
orgRepo.IDCondition(org.GetId()),
|
||||
orgRepo.InstanceIDCondition(instanceID),
|
||||
),
|
||||
),
|
||||
@@ -63,6 +71,15 @@ func TestServer_TestOrganizationReduces(t *testing.T) {
|
||||
})
|
||||
require.NoError(t, err)
|
||||
|
||||
t.Cleanup(func() {
|
||||
_, err = OrgClient.DeleteOrganization(CTX, &v2beta_org.DeleteOrganizationRequest{
|
||||
Id: organization.Id,
|
||||
})
|
||||
if err != nil {
|
||||
t.Logf("Failed to delete organization on cleanup: %v", err)
|
||||
}
|
||||
})
|
||||
|
||||
// 2. update org name
|
||||
beforeUpdate := time.Now()
|
||||
orgName = orgName + "_new"
|
||||
@@ -73,14 +90,12 @@ func TestServer_TestOrganizationReduces(t *testing.T) {
|
||||
require.NoError(t, err)
|
||||
afterUpdate := time.Now()
|
||||
|
||||
orgRepo := repository.OrganizationRepository(pool)
|
||||
|
||||
retryDuration, tick := integration.WaitForAndTickWithMaxDuration(CTX, time.Minute)
|
||||
assert.EventuallyWithT(t, func(t *assert.CollectT) {
|
||||
organization, err := orgRepo.Get(CTX,
|
||||
database.WithCondition(
|
||||
database.And(
|
||||
orgRepo.NameCondition(orgName),
|
||||
orgRepo.IDCondition(organization.Id),
|
||||
orgRepo.InstanceIDCondition(instanceID),
|
||||
),
|
||||
),
|
||||
@@ -101,6 +116,15 @@ func TestServer_TestOrganizationReduces(t *testing.T) {
|
||||
Name: orgName,
|
||||
})
|
||||
require.NoError(t, err)
|
||||
t.Cleanup(func() {
|
||||
// Cleanup: delete the organization
|
||||
_, err = OrgClient.DeleteOrganization(CTX, &v2beta_org.DeleteOrganizationRequest{
|
||||
Id: organization.Id,
|
||||
})
|
||||
if err != nil {
|
||||
t.Logf("Failed to delete organization on cleanup: %v", err)
|
||||
}
|
||||
})
|
||||
|
||||
// 2. deactivate org name
|
||||
beforeDeactivate := time.Now()
|
||||
@@ -111,14 +135,12 @@ func TestServer_TestOrganizationReduces(t *testing.T) {
|
||||
require.NoError(t, err)
|
||||
afterDeactivate := time.Now()
|
||||
|
||||
orgRepo := repository.OrganizationRepository(pool)
|
||||
|
||||
retryDuration, tick := integration.WaitForAndTickWithMaxDuration(CTX, time.Minute)
|
||||
assert.EventuallyWithT(t, func(t *assert.CollectT) {
|
||||
organization, err := orgRepo.Get(CTX,
|
||||
database.WithCondition(
|
||||
database.And(
|
||||
orgRepo.NameCondition(orgName),
|
||||
orgRepo.IDCondition(organization.Id),
|
||||
orgRepo.InstanceIDCondition(instanceID),
|
||||
),
|
||||
),
|
||||
@@ -126,7 +148,6 @@ func TestServer_TestOrganizationReduces(t *testing.T) {
|
||||
require.NoError(t, err)
|
||||
|
||||
// event org.deactivate
|
||||
assert.Equal(t, orgName, organization.Name)
|
||||
assert.Equal(t, domain.OrgStateInactive, organization.State)
|
||||
assert.WithinRange(t, organization.UpdatedAt, beforeDeactivate, afterDeactivate)
|
||||
}, retryDuration, tick)
|
||||
@@ -140,6 +161,15 @@ func TestServer_TestOrganizationReduces(t *testing.T) {
|
||||
Name: orgName,
|
||||
})
|
||||
require.NoError(t, err)
|
||||
t.Cleanup(func() {
|
||||
// Cleanup: delete the organization
|
||||
_, err = OrgClient.DeleteOrganization(CTX, &v2beta_org.DeleteOrganizationRequest{
|
||||
Id: organization.Id,
|
||||
})
|
||||
if err != nil {
|
||||
t.Logf("Failed to delete organization on cleanup: %v", err)
|
||||
}
|
||||
})
|
||||
|
||||
// 2. deactivate org name
|
||||
_, err = OrgClient.DeactivateOrganization(CTX, &v2beta_org.DeactivateOrganizationRequest{
|
||||
@@ -154,14 +184,12 @@ func TestServer_TestOrganizationReduces(t *testing.T) {
|
||||
organization, err := orgRepo.Get(CTX,
|
||||
database.WithCondition(
|
||||
database.And(
|
||||
orgRepo.NameCondition(orgName),
|
||||
orgRepo.IDCondition(organization.Id),
|
||||
orgRepo.InstanceIDCondition(instanceID),
|
||||
),
|
||||
),
|
||||
)
|
||||
require.NoError(t, err)
|
||||
|
||||
assert.Equal(t, orgName, organization.Name)
|
||||
assert.Equal(t, domain.OrgStateInactive, organization.State)
|
||||
}, retryDuration, tick)
|
||||
|
||||
@@ -178,7 +206,7 @@ func TestServer_TestOrganizationReduces(t *testing.T) {
|
||||
organization, err := orgRepo.Get(CTX,
|
||||
database.WithCondition(
|
||||
database.And(
|
||||
orgRepo.NameCondition(orgName),
|
||||
orgRepo.IDCondition(organization.Id),
|
||||
orgRepo.InstanceIDCondition(instanceID),
|
||||
),
|
||||
),
|
||||
@@ -201,24 +229,19 @@ func TestServer_TestOrganizationReduces(t *testing.T) {
|
||||
})
|
||||
require.NoError(t, err)
|
||||
|
||||
// 2. check org retrivable
|
||||
// 2. check org retrievable
|
||||
orgRepo := repository.OrganizationRepository(pool)
|
||||
retryDuration, tick := integration.WaitForAndTickWithMaxDuration(CTX, time.Minute)
|
||||
assert.EventuallyWithT(t, func(t *assert.CollectT) {
|
||||
organization, err := orgRepo.Get(CTX,
|
||||
_, err := orgRepo.Get(CTX,
|
||||
database.WithCondition(
|
||||
database.And(
|
||||
orgRepo.NameCondition(orgName),
|
||||
orgRepo.IDCondition(organization.Id),
|
||||
orgRepo.InstanceIDCondition(instanceID),
|
||||
),
|
||||
),
|
||||
)
|
||||
require.NoError(t, err)
|
||||
|
||||
if organization == nil {
|
||||
assert.Fail(t, "this error is here because of a race condition")
|
||||
}
|
||||
assert.Equal(t, orgName, organization.Name)
|
||||
}, retryDuration, tick)
|
||||
|
||||
// 3. delete org
|
||||
@@ -232,7 +255,7 @@ func TestServer_TestOrganizationReduces(t *testing.T) {
|
||||
organization, err := orgRepo.Get(CTX,
|
||||
database.WithCondition(
|
||||
database.And(
|
||||
orgRepo.NameCondition(orgName),
|
||||
orgRepo.IDCondition(organization.Id),
|
||||
orgRepo.InstanceIDCondition(instanceID),
|
||||
),
|
||||
),
|
||||
|
@@ -30,7 +30,7 @@ func InstanceRepository(client database.QueryExecutor) domain.InstanceRepository
|
||||
|
||||
const (
|
||||
queryInstanceStmt = `SELECT instances.id, instances.name, instances.default_org_id, instances.iam_project_id, instances.console_client_id, instances.console_app_id, instances.default_language, instances.created_at, instances.updated_at` +
|
||||
` , CASE WHEN count(instance_domains.domain) > 0 THEN jsonb_agg(json_build_object('domain', instance_domains.domain, 'isVerified', instance_domains.is_verified, 'isPrimary', instance_domains.is_primary, 'isGenerated', instance_domains.is_generated, 'validationType', instance_domains.validation_type, 'createdAt', instance_domains.created_at, 'updatedAt', instance_domains.updated_at)) ELSE NULL::JSONB END domains` +
|
||||
` , CASE WHEN count(instance_domains.domain) > 0 THEN jsonb_agg(json_build_object('domain', instance_domains.domain, 'isPrimary', instance_domains.is_primary, 'isGenerated', instance_domains.is_generated, 'createdAt', instance_domains.created_at, 'updatedAt', instance_domains.updated_at)) ELSE NULL::JSONB END domains` +
|
||||
` FROM zitadel.instances`
|
||||
)
|
||||
|
||||
|
@@ -19,7 +19,7 @@ type instanceDomain struct {
|
||||
// repository
|
||||
// -------------------------------------------------------------
|
||||
|
||||
const queryInstanceDomainStmt = `SELECT instance_domains.instance_id, instance_domains.domain, instance_domains.is_verified, instance_domains.is_primary, instance_domains.validation_type, instance_domains.created_at, instance_domains.updated_at ` +
|
||||
const queryInstanceDomainStmt = `SELECT instance_domains.instance_id, instance_domains.domain, instance_domains.is_primary, instance_domains.created_at, instance_domains.updated_at ` +
|
||||
`FROM zitadel.instance_domains`
|
||||
|
||||
// Get implements [domain.InstanceDomainRepository].
|
||||
@@ -56,11 +56,11 @@ func (i *instanceDomain) List(ctx context.Context, opts ...database.QueryOption)
|
||||
func (i *instanceDomain) Add(ctx context.Context, domain *domain.AddInstanceDomain) error {
|
||||
var builder database.StatementBuilder
|
||||
|
||||
builder.WriteString(`INSERT INTO zitadel.instance_domains (instance_id, domain, is_verified, is_primary, validation_type) VALUES (`)
|
||||
builder.WriteArgs(domain.InstanceID, domain.Domain, domain.IsVerified, domain.IsPrimary, domain.ValidationType)
|
||||
builder.WriteString(`INSERT INTO zitadel.instance_domains (instance_id, domain, is_primary, is_generated, type, created_at, updated_at) VALUES (`)
|
||||
builder.WriteArgs(domain.InstanceID, domain.Domain, domain.IsPrimary, domain.IsGenerated, domain.Type, domain.CreatedAt, domain.UpdatedAt)
|
||||
builder.WriteString(`) RETURNING created_at, updated_at`)
|
||||
|
||||
return i.client.QueryRow(ctx, builder.String(), builder.Args()...).Scan(&domain.CreatedAt, &domain.UpdatedAt)
|
||||
return i.client.QueryRow(ctx, builder.String(), builder.Args()...).Scan(domain.CreatedAt, domain.UpdatedAt)
|
||||
}
|
||||
|
||||
// Remove implements [domain.InstanceDomainRepository].
|
||||
@@ -93,26 +93,21 @@ func (i *instanceDomain) Update(ctx context.Context, condition database.Conditio
|
||||
// changes
|
||||
// -------------------------------------------------------------
|
||||
|
||||
// SetValidationType implements [domain.InstanceDomainRepository].
|
||||
func (i instanceDomain) SetValidationType(verificationType domain.DomainValidationType) database.Change {
|
||||
return database.NewChange(i.ValidationTypeColumn(false), verificationType)
|
||||
}
|
||||
|
||||
// SetPrimary implements [domain.InstanceDomainRepository].
|
||||
func (i instanceDomain) SetPrimary() database.Change {
|
||||
return database.NewChange(i.IsPrimaryColumn(false), true)
|
||||
}
|
||||
|
||||
// SetVerified implements [domain.InstanceDomainRepository].
|
||||
func (i instanceDomain) SetVerified() database.Change {
|
||||
return database.NewChange(i.IsVerifiedColumn(false), true)
|
||||
}
|
||||
|
||||
// SetUpdatedAt implements [domain.OrganizationDomainRepository].
|
||||
func (i instanceDomain) SetUpdatedAt(updatedAt time.Time) database.Change {
|
||||
return database.NewChange(i.UpdatedAtColumn(false), updatedAt)
|
||||
}
|
||||
|
||||
// SetType implements [domain.InstanceDomainRepository].
|
||||
func (i instanceDomain) SetType(typ domain.DomainType) database.Change {
|
||||
return database.NewChange(i.TypeColumn(false), typ)
|
||||
}
|
||||
|
||||
// -------------------------------------------------------------
|
||||
// conditions
|
||||
// -------------------------------------------------------------
|
||||
@@ -132,9 +127,9 @@ func (i instanceDomain) IsPrimaryCondition(isPrimary bool) database.Condition {
|
||||
return database.NewBooleanCondition(i.IsPrimaryColumn(true), isPrimary)
|
||||
}
|
||||
|
||||
// IsVerifiedCondition implements [domain.InstanceDomainRepository].
|
||||
func (i instanceDomain) IsVerifiedCondition(isVerified bool) database.Condition {
|
||||
return database.NewBooleanCondition(i.IsVerifiedColumn(true), isVerified)
|
||||
// TypeCondition implements [domain.InstanceDomainRepository].
|
||||
func (i instanceDomain) TypeCondition(typ domain.DomainType) database.Condition {
|
||||
return database.NewTextCondition(i.TypeColumn(true), database.TextOperationEqual, typ)
|
||||
}
|
||||
|
||||
// -------------------------------------------------------------
|
||||
@@ -174,14 +169,6 @@ func (instanceDomain) IsPrimaryColumn(qualified bool) database.Column {
|
||||
return database.NewColumn("is_primary")
|
||||
}
|
||||
|
||||
// IsVerifiedColumn implements [domain.InstanceDomainRepository].
|
||||
func (instanceDomain) IsVerifiedColumn(qualified bool) database.Column {
|
||||
if qualified {
|
||||
return database.NewColumn("instance_domains.is_verified")
|
||||
}
|
||||
return database.NewColumn("is_verified")
|
||||
}
|
||||
|
||||
// UpdatedAtColumn implements [domain.InstanceDomainRepository].
|
||||
// Subtle: this method shadows the method ([domain.InstanceRepository]).UpdatedAtColumn of instanceDomain.instance.
|
||||
func (instanceDomain) UpdatedAtColumn(qualified bool) database.Column {
|
||||
@@ -191,14 +178,6 @@ func (instanceDomain) UpdatedAtColumn(qualified bool) database.Column {
|
||||
return database.NewColumn("updated_at")
|
||||
}
|
||||
|
||||
// ValidationTypeColumn implements [domain.InstanceDomainRepository].
|
||||
func (instanceDomain) ValidationTypeColumn(qualified bool) database.Column {
|
||||
if qualified {
|
||||
return database.NewColumn("instance_domains.validation_type")
|
||||
}
|
||||
return database.NewColumn("validation_type")
|
||||
}
|
||||
|
||||
// IsGeneratedColumn implements [domain.InstanceDomainRepository].
|
||||
func (instanceDomain) IsGeneratedColumn(qualified bool) database.Column {
|
||||
if qualified {
|
||||
@@ -207,6 +186,14 @@ func (instanceDomain) IsGeneratedColumn(qualified bool) database.Column {
|
||||
return database.NewColumn("is_generated")
|
||||
}
|
||||
|
||||
// TypeColumn implements [domain.InstanceDomainRepository].
|
||||
func (instanceDomain) TypeColumn(qualified bool) database.Column {
|
||||
if qualified {
|
||||
return database.NewColumn("instance_domains.type")
|
||||
}
|
||||
return database.NewColumn("type")
|
||||
}
|
||||
|
||||
// -------------------------------------------------------------
|
||||
// scanners
|
||||
// -------------------------------------------------------------
|
||||
|
@@ -5,7 +5,6 @@ import (
|
||||
"testing"
|
||||
|
||||
"github.com/brianvoe/gofakeit/v6"
|
||||
"github.com/muhlemmer/gu"
|
||||
"github.com/stretchr/testify/assert"
|
||||
"github.com/stretchr/testify/require"
|
||||
|
||||
@@ -39,41 +38,25 @@ func TestAddInstanceDomain(t *testing.T) {
|
||||
{
|
||||
name: "happy path",
|
||||
instanceDomain: domain.AddInstanceDomain{
|
||||
InstanceID: instanceID,
|
||||
Domain: gofakeit.DomainName(),
|
||||
IsVerified: false,
|
||||
IsPrimary: false,
|
||||
ValidationType: gu.Ptr(domain.DomainValidationTypeDNS),
|
||||
},
|
||||
},
|
||||
{
|
||||
name: "add verified domain",
|
||||
instanceDomain: domain.AddInstanceDomain{
|
||||
InstanceID: instanceID,
|
||||
Domain: gofakeit.DomainName(),
|
||||
IsVerified: true,
|
||||
IsPrimary: false,
|
||||
ValidationType: gu.Ptr(domain.DomainValidationTypeHTTP),
|
||||
InstanceID: instanceID,
|
||||
Domain: gofakeit.DomainName(),
|
||||
IsPrimary: false,
|
||||
},
|
||||
},
|
||||
{
|
||||
name: "add primary domain",
|
||||
instanceDomain: domain.AddInstanceDomain{
|
||||
InstanceID: instanceID,
|
||||
Domain: gofakeit.DomainName(),
|
||||
IsVerified: true,
|
||||
IsPrimary: true,
|
||||
ValidationType: gu.Ptr(domain.DomainValidationTypeDNS),
|
||||
InstanceID: instanceID,
|
||||
Domain: gofakeit.DomainName(),
|
||||
IsPrimary: true,
|
||||
},
|
||||
},
|
||||
{
|
||||
name: "add domain without domain name",
|
||||
instanceDomain: domain.AddInstanceDomain{
|
||||
InstanceID: instanceID,
|
||||
Domain: "",
|
||||
IsVerified: false,
|
||||
IsPrimary: false,
|
||||
ValidationType: gu.Ptr(domain.DomainValidationTypeDNS),
|
||||
InstanceID: instanceID,
|
||||
Domain: "",
|
||||
IsPrimary: false,
|
||||
},
|
||||
err: new(database.CheckError),
|
||||
},
|
||||
@@ -83,11 +66,9 @@ func TestAddInstanceDomain(t *testing.T) {
|
||||
domainName := gofakeit.DomainName()
|
||||
|
||||
instanceDomain := &domain.AddInstanceDomain{
|
||||
InstanceID: instanceID,
|
||||
Domain: domainName,
|
||||
IsVerified: false,
|
||||
IsPrimary: false,
|
||||
ValidationType: gu.Ptr(domain.DomainValidationTypeDNS),
|
||||
InstanceID: instanceID,
|
||||
Domain: domainName,
|
||||
IsPrimary: false,
|
||||
}
|
||||
|
||||
err := domainRepo.Add(ctx, instanceDomain)
|
||||
@@ -95,11 +76,9 @@ func TestAddInstanceDomain(t *testing.T) {
|
||||
|
||||
// return same domain again
|
||||
return &domain.AddInstanceDomain{
|
||||
InstanceID: instanceID,
|
||||
Domain: domainName,
|
||||
IsVerified: true,
|
||||
IsPrimary: true,
|
||||
ValidationType: gu.Ptr(domain.DomainValidationTypeHTTP),
|
||||
InstanceID: instanceID,
|
||||
Domain: domainName,
|
||||
IsPrimary: true,
|
||||
}
|
||||
},
|
||||
err: new(database.UniqueError),
|
||||
@@ -107,21 +86,17 @@ func TestAddInstanceDomain(t *testing.T) {
|
||||
{
|
||||
name: "add domain with non-existent instance",
|
||||
instanceDomain: domain.AddInstanceDomain{
|
||||
InstanceID: "non-existent-instance",
|
||||
Domain: gofakeit.DomainName(),
|
||||
IsVerified: false,
|
||||
IsPrimary: false,
|
||||
ValidationType: gu.Ptr(domain.DomainValidationTypeDNS),
|
||||
InstanceID: "non-existent-instance",
|
||||
Domain: gofakeit.DomainName(),
|
||||
IsPrimary: false,
|
||||
},
|
||||
err: new(database.ForeignKeyError),
|
||||
},
|
||||
{
|
||||
name: "add domain without instance id",
|
||||
instanceDomain: domain.AddInstanceDomain{
|
||||
Domain: gofakeit.DomainName(),
|
||||
IsVerified: false,
|
||||
IsPrimary: false,
|
||||
ValidationType: gu.Ptr(domain.DomainValidationTypeDNS),
|
||||
Domain: gofakeit.DomainName(),
|
||||
IsPrimary: false,
|
||||
},
|
||||
err: new(database.ForeignKeyError),
|
||||
},
|
||||
@@ -186,18 +161,14 @@ func TestGetInstanceDomain(t *testing.T) {
|
||||
domainName2 := gofakeit.DomainName()
|
||||
|
||||
domain1 := &domain.AddInstanceDomain{
|
||||
InstanceID: instanceID,
|
||||
Domain: domainName1,
|
||||
IsVerified: true,
|
||||
IsPrimary: true,
|
||||
ValidationType: gu.Ptr(domain.DomainValidationTypeDNS),
|
||||
InstanceID: instanceID,
|
||||
Domain: domainName1,
|
||||
IsPrimary: true,
|
||||
}
|
||||
domain2 := &domain.AddInstanceDomain{
|
||||
InstanceID: instanceID,
|
||||
Domain: domainName2,
|
||||
IsVerified: false,
|
||||
IsPrimary: false,
|
||||
ValidationType: gu.Ptr(domain.DomainValidationTypeHTTP),
|
||||
InstanceID: instanceID,
|
||||
Domain: domainName2,
|
||||
IsPrimary: false,
|
||||
}
|
||||
|
||||
err = domainRepo.Add(t.Context(), domain1)
|
||||
@@ -217,11 +188,9 @@ func TestGetInstanceDomain(t *testing.T) {
|
||||
database.WithCondition(domainRepo.IsPrimaryCondition(true)),
|
||||
},
|
||||
expected: &domain.InstanceDomain{
|
||||
InstanceID: instanceID,
|
||||
Domain: domainName1,
|
||||
IsVerified: true,
|
||||
IsPrimary: true,
|
||||
ValidationType: gu.Ptr(domain.DomainValidationTypeDNS),
|
||||
InstanceID: instanceID,
|
||||
Domain: domainName1,
|
||||
IsPrimary: true,
|
||||
},
|
||||
},
|
||||
{
|
||||
@@ -230,24 +199,9 @@ func TestGetInstanceDomain(t *testing.T) {
|
||||
database.WithCondition(domainRepo.DomainCondition(database.TextOperationEqual, domainName2)),
|
||||
},
|
||||
expected: &domain.InstanceDomain{
|
||||
InstanceID: instanceID,
|
||||
Domain: domainName2,
|
||||
IsVerified: false,
|
||||
IsPrimary: false,
|
||||
ValidationType: gu.Ptr(domain.DomainValidationTypeHTTP),
|
||||
},
|
||||
},
|
||||
{
|
||||
name: "get verified domain",
|
||||
opts: []database.QueryOption{
|
||||
database.WithCondition(domainRepo.IsVerifiedCondition(true)),
|
||||
},
|
||||
expected: &domain.InstanceDomain{
|
||||
InstanceID: instanceID,
|
||||
Domain: domainName1,
|
||||
IsVerified: true,
|
||||
IsPrimary: true,
|
||||
ValidationType: gu.Ptr(domain.DomainValidationTypeDNS),
|
||||
InstanceID: instanceID,
|
||||
Domain: domainName2,
|
||||
IsPrimary: false,
|
||||
},
|
||||
},
|
||||
{
|
||||
@@ -272,9 +226,7 @@ func TestGetInstanceDomain(t *testing.T) {
|
||||
require.NoError(t, err)
|
||||
assert.Equal(t, test.expected.InstanceID, result.InstanceID)
|
||||
assert.Equal(t, test.expected.Domain, result.Domain)
|
||||
assert.Equal(t, test.expected.IsVerified, result.IsVerified)
|
||||
assert.Equal(t, test.expected.IsPrimary, result.IsPrimary)
|
||||
assert.Equal(t, test.expected.ValidationType, result.ValidationType)
|
||||
assert.NotEmpty(t, result.CreatedAt)
|
||||
assert.NotEmpty(t, result.UpdatedAt)
|
||||
})
|
||||
@@ -307,25 +259,19 @@ func TestListInstanceDomains(t *testing.T) {
|
||||
domainRepo := instanceRepo.Domains(false)
|
||||
domains := []domain.AddInstanceDomain{
|
||||
{
|
||||
InstanceID: instanceID,
|
||||
Domain: gofakeit.DomainName(),
|
||||
IsVerified: true,
|
||||
IsPrimary: true,
|
||||
ValidationType: gu.Ptr(domain.DomainValidationTypeDNS),
|
||||
InstanceID: instanceID,
|
||||
Domain: gofakeit.DomainName(),
|
||||
IsPrimary: true,
|
||||
},
|
||||
{
|
||||
InstanceID: instanceID,
|
||||
Domain: gofakeit.DomainName(),
|
||||
IsVerified: false,
|
||||
IsPrimary: false,
|
||||
ValidationType: gu.Ptr(domain.DomainValidationTypeHTTP),
|
||||
InstanceID: instanceID,
|
||||
Domain: gofakeit.DomainName(),
|
||||
IsPrimary: false,
|
||||
},
|
||||
{
|
||||
InstanceID: instanceID,
|
||||
Domain: gofakeit.DomainName(),
|
||||
IsVerified: true,
|
||||
IsPrimary: false,
|
||||
ValidationType: gu.Ptr(domain.DomainValidationTypeDNS),
|
||||
InstanceID: instanceID,
|
||||
Domain: gofakeit.DomainName(),
|
||||
IsPrimary: false,
|
||||
},
|
||||
}
|
||||
|
||||
@@ -344,13 +290,6 @@ func TestListInstanceDomains(t *testing.T) {
|
||||
opts: []database.QueryOption{},
|
||||
expectedCount: 3,
|
||||
},
|
||||
{
|
||||
name: "list verified domains",
|
||||
opts: []database.QueryOption{
|
||||
database.WithCondition(domainRepo.IsVerifiedCondition(true)),
|
||||
},
|
||||
expectedCount: 2,
|
||||
},
|
||||
{
|
||||
name: "list primary domains",
|
||||
opts: []database.QueryOption{
|
||||
@@ -419,11 +358,9 @@ func TestUpdateInstanceDomain(t *testing.T) {
|
||||
domainRepo := instanceRepo.Domains(false)
|
||||
domainName := gofakeit.DomainName()
|
||||
instanceDomain := &domain.AddInstanceDomain{
|
||||
InstanceID: instanceID,
|
||||
Domain: domainName,
|
||||
IsVerified: false,
|
||||
IsPrimary: false,
|
||||
ValidationType: gu.Ptr(domain.DomainValidationTypeDNS),
|
||||
InstanceID: instanceID,
|
||||
Domain: domainName,
|
||||
IsPrimary: false,
|
||||
}
|
||||
|
||||
err = domainRepo.Add(t.Context(), instanceDomain)
|
||||
@@ -436,38 +373,16 @@ func TestUpdateInstanceDomain(t *testing.T) {
|
||||
expected int64
|
||||
err error
|
||||
}{
|
||||
{
|
||||
name: "set verified",
|
||||
condition: domainRepo.DomainCondition(database.TextOperationEqual, domainName),
|
||||
changes: []database.Change{domainRepo.SetVerified()},
|
||||
expected: 1,
|
||||
},
|
||||
{
|
||||
name: "set primary",
|
||||
condition: domainRepo.DomainCondition(database.TextOperationEqual, domainName),
|
||||
changes: []database.Change{domainRepo.SetPrimary()},
|
||||
expected: 1,
|
||||
},
|
||||
{
|
||||
name: "set validation type",
|
||||
condition: domainRepo.DomainCondition(database.TextOperationEqual, domainName),
|
||||
changes: []database.Change{domainRepo.SetValidationType(domain.DomainValidationTypeHTTP)},
|
||||
expected: 1,
|
||||
},
|
||||
{
|
||||
name: "multiple changes",
|
||||
condition: domainRepo.DomainCondition(database.TextOperationEqual, domainName),
|
||||
changes: []database.Change{
|
||||
domainRepo.SetVerified(),
|
||||
domainRepo.SetPrimary(),
|
||||
domainRepo.SetValidationType(domain.DomainValidationTypeDNS),
|
||||
},
|
||||
expected: 1,
|
||||
},
|
||||
{
|
||||
name: "update non-existent domain",
|
||||
condition: domainRepo.DomainCondition(database.TextOperationEqual, "non-existent.com"),
|
||||
changes: []database.Change{domainRepo.SetVerified()},
|
||||
changes: []database.Change{domainRepo.SetPrimary()},
|
||||
expected: 0,
|
||||
},
|
||||
{
|
||||
@@ -533,18 +448,14 @@ func TestRemoveInstanceDomain(t *testing.T) {
|
||||
domainName2 := gofakeit.DomainName()
|
||||
|
||||
domain1 := &domain.AddInstanceDomain{
|
||||
InstanceID: instanceID,
|
||||
Domain: domainName1,
|
||||
IsVerified: true,
|
||||
IsPrimary: true,
|
||||
ValidationType: gu.Ptr(domain.DomainValidationTypeDNS),
|
||||
InstanceID: instanceID,
|
||||
Domain: domainName1,
|
||||
IsPrimary: true,
|
||||
}
|
||||
domain2 := &domain.AddInstanceDomain{
|
||||
InstanceID: instanceID,
|
||||
Domain: domainName2,
|
||||
IsVerified: false,
|
||||
IsPrimary: false,
|
||||
ValidationType: gu.Ptr(domain.DomainValidationTypeHTTP),
|
||||
InstanceID: instanceID,
|
||||
Domain: domainName2,
|
||||
IsPrimary: false,
|
||||
}
|
||||
|
||||
err = domainRepo.Add(t.Context(), domain1)
|
||||
@@ -628,16 +539,6 @@ func TestInstanceDomainConditions(t *testing.T) {
|
||||
condition: domainRepo.IsPrimaryCondition(false),
|
||||
expected: "instance_domains.is_primary = $1",
|
||||
},
|
||||
{
|
||||
name: "is verified true",
|
||||
condition: domainRepo.IsVerifiedCondition(true),
|
||||
expected: "instance_domains.is_verified = $1",
|
||||
},
|
||||
{
|
||||
name: "is verified false",
|
||||
condition: domainRepo.IsVerifiedCondition(false),
|
||||
expected: "instance_domains.is_verified = $1",
|
||||
},
|
||||
}
|
||||
|
||||
for _, test := range tests {
|
||||
@@ -658,26 +559,11 @@ func TestInstanceDomainChanges(t *testing.T) {
|
||||
change database.Change
|
||||
expected string
|
||||
}{
|
||||
{
|
||||
name: "set verified",
|
||||
change: domainRepo.SetVerified(),
|
||||
expected: "is_verified = $1",
|
||||
},
|
||||
{
|
||||
name: "set primary",
|
||||
change: domainRepo.SetPrimary(),
|
||||
expected: "is_primary = $1",
|
||||
},
|
||||
{
|
||||
name: "set validation type DNS",
|
||||
change: domainRepo.SetValidationType(domain.DomainValidationTypeDNS),
|
||||
expected: "validation_type = $1",
|
||||
},
|
||||
{
|
||||
name: "set validation type HTTP",
|
||||
change: domainRepo.SetValidationType(domain.DomainValidationTypeHTTP),
|
||||
expected: "validation_type = $1",
|
||||
},
|
||||
}
|
||||
|
||||
for _, test := range tests {
|
||||
|
@@ -9,6 +9,7 @@ Database:
|
||||
SSL:
|
||||
Mode: disable
|
||||
Admin:
|
||||
Username: zitadel
|
||||
Username: adlerhurst
|
||||
Password: password
|
||||
SSL:
|
||||
Mode: disable
|
||||
|
@@ -4,6 +4,8 @@ import (
|
||||
"context"
|
||||
"database/sql"
|
||||
|
||||
"github.com/muhlemmer/gu"
|
||||
|
||||
"github.com/zitadel/zitadel/backend/v3/domain"
|
||||
"github.com/zitadel/zitadel/backend/v3/storage/database"
|
||||
v3_sql "github.com/zitadel/zitadel/backend/v3/storage/database/dialect/sql"
|
||||
@@ -31,7 +33,7 @@ func (p *instanceDomainRelationalProjection) Reducers() []handler.AggregateReduc
|
||||
EventReducers: []handler.EventReducer{
|
||||
{
|
||||
Event: instance.InstanceDomainAddedEventType,
|
||||
Reduce: p.reduceDomainAdded,
|
||||
Reduce: p.reduceCustomDomainAdded,
|
||||
},
|
||||
{
|
||||
Event: instance.InstanceDomainPrimarySetEventType,
|
||||
@@ -39,14 +41,22 @@ func (p *instanceDomainRelationalProjection) Reducers() []handler.AggregateReduc
|
||||
},
|
||||
{
|
||||
Event: instance.InstanceDomainRemovedEventType,
|
||||
Reduce: p.reduceDomainRemoved,
|
||||
Reduce: p.reduceCustomDomainRemoved,
|
||||
},
|
||||
{
|
||||
Event: instance.TrustedDomainAddedEventType,
|
||||
Reduce: p.reduceTrustedDomainAdded,
|
||||
},
|
||||
{
|
||||
Event: instance.TrustedDomainRemovedEventType,
|
||||
Reduce: p.reduceTrustedDomainRemoved,
|
||||
},
|
||||
},
|
||||
},
|
||||
}
|
||||
}
|
||||
|
||||
func (p *instanceDomainRelationalProjection) reduceDomainAdded(event eventstore.Event) (*handler.Statement, error) {
|
||||
func (p *instanceDomainRelationalProjection) reduceCustomDomainAdded(event eventstore.Event) (*handler.Statement, error) {
|
||||
e, ok := event.(*instance.DomainAddedEvent)
|
||||
if !ok {
|
||||
return nil, zerrors.ThrowInvalidArgumentf(nil, "HANDL-DU0xF", "reduce.wrong.event.type %s", instance.InstanceDomainAddedEventType)
|
||||
@@ -60,8 +70,9 @@ func (p *instanceDomainRelationalProjection) reduceDomainAdded(event eventstore.
|
||||
InstanceID: e.Aggregate().InstanceID,
|
||||
Domain: e.Domain,
|
||||
IsGenerated: e.Generated,
|
||||
CreatedAt: e.CreationDate(),
|
||||
UpdatedAt: e.CreationDate(),
|
||||
Type: domain.DomainTypeCustom,
|
||||
CreatedAt: gu.Ptr(e.CreationDate()),
|
||||
UpdatedAt: gu.Ptr(e.CreationDate()),
|
||||
})
|
||||
}), nil
|
||||
}
|
||||
@@ -81,6 +92,7 @@ func (p *instanceDomainRelationalProjection) reduceDomainPrimarySet(event events
|
||||
database.And(
|
||||
domainRepo.InstanceIDCondition(e.Aggregate().InstanceID),
|
||||
domainRepo.DomainCondition(database.TextOperationEqual, e.Domain),
|
||||
domainRepo.TypeCondition(domain.DomainTypeCustom),
|
||||
),
|
||||
domainRepo.SetPrimary(),
|
||||
domainRepo.SetUpdatedAt(e.CreationDate()),
|
||||
@@ -89,7 +101,7 @@ func (p *instanceDomainRelationalProjection) reduceDomainPrimarySet(event events
|
||||
}), nil
|
||||
}
|
||||
|
||||
func (p *instanceDomainRelationalProjection) reduceDomainRemoved(event eventstore.Event) (*handler.Statement, error) {
|
||||
func (p *instanceDomainRelationalProjection) reduceCustomDomainRemoved(event eventstore.Event) (*handler.Statement, error) {
|
||||
e, ok := event.(*instance.DomainRemovedEvent)
|
||||
if !ok {
|
||||
return nil, zerrors.ThrowInvalidArgumentf(nil, "HANDL-Hhcdl", "reduce.wrong.event.type %s", instance.InstanceDomainRemovedEventType)
|
||||
@@ -104,6 +116,49 @@ func (p *instanceDomainRelationalProjection) reduceDomainRemoved(event eventstor
|
||||
database.And(
|
||||
domainRepo.InstanceIDCondition(e.Aggregate().InstanceID),
|
||||
domainRepo.DomainCondition(database.TextOperationEqual, e.Domain),
|
||||
domainRepo.TypeCondition(domain.DomainTypeCustom),
|
||||
),
|
||||
)
|
||||
return err
|
||||
}), nil
|
||||
}
|
||||
|
||||
func (p *instanceDomainRelationalProjection) reduceTrustedDomainAdded(event eventstore.Event) (*handler.Statement, error) {
|
||||
e, ok := event.(*instance.TrustedDomainAddedEvent)
|
||||
if !ok {
|
||||
return nil, zerrors.ThrowInvalidArgumentf(nil, "HANDL-svHDh", "reduce.wrong.event.type %s", instance.TrustedDomainAddedEventType)
|
||||
}
|
||||
return handler.NewStatement(e, func(ctx context.Context, ex handler.Executer, projectionName string) error {
|
||||
tx, ok := ex.(*sql.Tx)
|
||||
if !ok {
|
||||
return zerrors.ThrowInvalidArgumentf(nil, "HANDL-gx7tQ", "reduce.wrong.db.pool %T", ex)
|
||||
}
|
||||
return repository.InstanceRepository(v3_sql.SQLTx(tx)).Domains(false).Add(ctx, &domain.AddInstanceDomain{
|
||||
InstanceID: e.Aggregate().InstanceID,
|
||||
Domain: e.Domain,
|
||||
Type: domain.DomainTypeCustom,
|
||||
CreatedAt: gu.Ptr(e.CreationDate()),
|
||||
UpdatedAt: gu.Ptr(e.CreationDate()),
|
||||
})
|
||||
}), nil
|
||||
}
|
||||
|
||||
func (p *instanceDomainRelationalProjection) reduceTrustedDomainRemoved(event eventstore.Event) (*handler.Statement, error) {
|
||||
e, ok := event.(*instance.TrustedDomainRemovedEvent)
|
||||
if !ok {
|
||||
return nil, zerrors.ThrowInvalidArgumentf(nil, "HANDL-4K74E", "reduce.wrong.event.type %s", instance.TrustedDomainRemovedEventType)
|
||||
}
|
||||
return handler.NewStatement(e, func(ctx context.Context, ex handler.Executer, projectionName string) error {
|
||||
tx, ok := ex.(*sql.Tx)
|
||||
if !ok {
|
||||
return zerrors.ThrowInvalidArgumentf(nil, "HANDL-D68ap", "reduce.wrong.db.pool %T", ex)
|
||||
}
|
||||
domainRepo := repository.InstanceRepository(v3_sql.SQLTx(tx)).Domains(false)
|
||||
_, err := domainRepo.Remove(ctx,
|
||||
database.And(
|
||||
domainRepo.InstanceIDCondition(e.Aggregate().InstanceID),
|
||||
domainRepo.DomainCondition(database.TextOperationEqual, e.Domain),
|
||||
domainRepo.TypeCondition(domain.DomainTypeTrusted),
|
||||
),
|
||||
)
|
||||
return err
|
||||
|
@@ -8,6 +8,7 @@ import (
|
||||
"github.com/zitadel/zitadel/backend/v3/storage/database"
|
||||
v3_sql "github.com/zitadel/zitadel/backend/v3/storage/database/dialect/sql"
|
||||
"github.com/zitadel/zitadel/backend/v3/storage/database/repository"
|
||||
old_domain "github.com/zitadel/zitadel/internal/domain"
|
||||
"github.com/zitadel/zitadel/internal/eventstore"
|
||||
"github.com/zitadel/zitadel/internal/eventstore/handler/v2"
|
||||
"github.com/zitadel/zitadel/internal/repository/org"
|
||||
@@ -31,22 +32,30 @@ func (p *orgDomainRelationalProjection) Reducers() []handler.AggregateReducer {
|
||||
EventReducers: []handler.EventReducer{
|
||||
{
|
||||
Event: org.OrgDomainAddedEventType,
|
||||
Reduce: p.reduceDomainAdded,
|
||||
Reduce: p.reduceAdded,
|
||||
},
|
||||
{
|
||||
Event: org.OrgDomainPrimarySetEventType,
|
||||
Reduce: p.reduceDomainPrimarySet,
|
||||
Reduce: p.reducePrimarySet,
|
||||
},
|
||||
{
|
||||
Event: org.OrgDomainRemovedEventType,
|
||||
Reduce: p.reduceDomainRemoved,
|
||||
Reduce: p.reduceRemoved,
|
||||
},
|
||||
{
|
||||
Event: org.OrgDomainVerificationAddedEventType,
|
||||
Reduce: p.reduceVerificationAdded,
|
||||
},
|
||||
{
|
||||
Event: org.OrgDomainVerifiedEventType,
|
||||
Reduce: p.reduceVerified,
|
||||
},
|
||||
},
|
||||
},
|
||||
}
|
||||
}
|
||||
|
||||
func (p *orgDomainRelationalProjection) reduceDomainAdded(event eventstore.Event) (*handler.Statement, error) {
|
||||
func (p *orgDomainRelationalProjection) reduceAdded(event eventstore.Event) (*handler.Statement, error) {
|
||||
e, ok := event.(*org.DomainAddedEvent)
|
||||
if !ok {
|
||||
return nil, zerrors.ThrowInvalidArgumentf(nil, "HANDL-ZX9Fw", "reduce.wrong.event.type %s", org.OrgDomainAddedEventType)
|
||||
@@ -66,7 +75,7 @@ func (p *orgDomainRelationalProjection) reduceDomainAdded(event eventstore.Event
|
||||
}), nil
|
||||
}
|
||||
|
||||
func (p *orgDomainRelationalProjection) reduceDomainPrimarySet(event eventstore.Event) (*handler.Statement, error) {
|
||||
func (p *orgDomainRelationalProjection) reducePrimarySet(event eventstore.Event) (*handler.Statement, error) {
|
||||
e, ok := event.(*org.DomainPrimarySetEvent)
|
||||
if !ok {
|
||||
return nil, zerrors.ThrowInvalidArgumentf(nil, "HANDL-dmFdb", "reduce.wrong.event.type %s", org.OrgDomainPrimarySetEventType)
|
||||
@@ -90,7 +99,7 @@ func (p *orgDomainRelationalProjection) reduceDomainPrimarySet(event eventstore.
|
||||
}), nil
|
||||
}
|
||||
|
||||
func (p *orgDomainRelationalProjection) reduceDomainRemoved(event eventstore.Event) (*handler.Statement, error) {
|
||||
func (p *orgDomainRelationalProjection) reduceRemoved(event eventstore.Event) (*handler.Statement, error) {
|
||||
e, ok := event.(*org.DomainRemovedEvent)
|
||||
if !ok {
|
||||
return nil, zerrors.ThrowInvalidArgumentf(nil, "HANDL-MzC0n", "reduce.wrong.event.type %s", org.OrgDomainRemovedEventType)
|
||||
@@ -111,3 +120,58 @@ func (p *orgDomainRelationalProjection) reduceDomainRemoved(event eventstore.Eve
|
||||
return err
|
||||
}), nil
|
||||
}
|
||||
|
||||
func (p *orgDomainRelationalProjection) reduceVerificationAdded(event eventstore.Event) (*handler.Statement, error) {
|
||||
e, ok := event.(*org.DomainVerificationAddedEvent)
|
||||
if !ok {
|
||||
return nil, zerrors.ThrowInvalidArgumentf(nil, "HANDL-oGzip", "reduce.wrong.event.type %s", org.OrgDomainVerificationAddedEventType)
|
||||
}
|
||||
var validationType domain.DomainValidationType
|
||||
switch e.ValidationType {
|
||||
case old_domain.OrgDomainValidationTypeDNS:
|
||||
validationType = domain.DomainValidationTypeDNS
|
||||
case old_domain.OrgDomainValidationTypeHTTP:
|
||||
validationType = domain.DomainValidationTypeHTTP
|
||||
case old_domain.OrgDomainValidationTypeUnspecified:
|
||||
return nil, zerrors.ThrowInvalidArgumentf(nil, "HANDL-FJfKB", "reduce.unsupported.validation.type %v", e.ValidationType)
|
||||
}
|
||||
return handler.NewStatement(e, func(ctx context.Context, ex handler.Executer, projectionName string) error {
|
||||
tx, ok := ex.(*sql.Tx)
|
||||
if !ok {
|
||||
return zerrors.ThrowInvalidArgumentf(nil, "HANDL-yF03i", "reduce.wrong.db.pool %T", ex)
|
||||
}
|
||||
domainRepo := repository.OrganizationRepository(v3_sql.SQLTx(tx)).Domains(false)
|
||||
_, err := domainRepo.Update(ctx,
|
||||
database.And(
|
||||
domainRepo.InstanceIDCondition(e.Aggregate().InstanceID),
|
||||
domainRepo.OrgIDCondition(e.Aggregate().ResourceOwner),
|
||||
domainRepo.DomainCondition(database.TextOperationEqual, e.Domain),
|
||||
),
|
||||
domainRepo.SetValidationType(validationType),
|
||||
)
|
||||
return err
|
||||
}), nil
|
||||
}
|
||||
|
||||
func (p *orgDomainRelationalProjection) reduceVerified(event eventstore.Event) (*handler.Statement, error) {
|
||||
e, ok := event.(*org.DomainVerifiedEvent)
|
||||
if !ok {
|
||||
return nil, zerrors.ThrowInvalidArgumentf(nil, "HANDL-7WrI2", "reduce.wrong.event.type %s", org.OrgDomainVerifiedEventType)
|
||||
}
|
||||
return handler.NewStatement(e, func(ctx context.Context, ex handler.Executer, projectionName string) error {
|
||||
tx, ok := ex.(*sql.Tx)
|
||||
if !ok {
|
||||
return zerrors.ThrowInvalidArgumentf(nil, "HANDL-0ZGqC", "reduce.wrong.db.pool %T", ex)
|
||||
}
|
||||
domainRepo := repository.OrganizationRepository(v3_sql.SQLTx(tx)).Domains(false)
|
||||
_, err := domainRepo.Update(ctx,
|
||||
database.And(
|
||||
domainRepo.InstanceIDCondition(e.Aggregate().InstanceID),
|
||||
domainRepo.OrgIDCondition(e.Aggregate().ResourceOwner),
|
||||
domainRepo.DomainCondition(database.TextOperationEqual, e.Domain),
|
||||
),
|
||||
domainRepo.SetVerified(),
|
||||
)
|
||||
return err
|
||||
}), nil
|
||||
}
|
||||
|
Reference in New Issue
Block a user