fix: claim verified domain from usernames (#603)

* fix: return orgDomain validationType

* added missing translations for orgDomain activity

* claim org domain

* show message if domain token was requested

* fix tests

* fix tests

Co-authored-by: Max Peintner <max@caos.ch>
This commit is contained in:
Livio Amstutz
2020-08-18 08:57:16 +02:00
committed by GitHub
parent 406924bed8
commit 1a00faf132
41 changed files with 15945 additions and 16717 deletions

View File

@@ -1,17 +1,19 @@
package model
import (
"github.com/caos/zitadel/internal/model"
"time"
"github.com/caos/zitadel/internal/model"
)
type OrgDomainView struct {
OrgID string
CreationDate time.Time
ChangeDate time.Time
Domain string
Primary bool
Verified bool
OrgID string
CreationDate time.Time
ChangeDate time.Time
Domain string
Primary bool
Verified bool
ValidationType OrgDomainValidationType
}
type OrgDomainSearchRequest struct {

View File

@@ -53,7 +53,7 @@ func StartOrg(conf OrgConfig, defaults systemdefaults.SystemDefaults) *OrgEvents
}
}
func (es *OrgEventstore) PrepareCreateOrg(ctx context.Context, orgModel *org_model.Org) (*model.Org, []*es_models.Aggregate, error) {
func (es *OrgEventstore) PrepareCreateOrg(ctx context.Context, orgModel *org_model.Org, users func(context.Context, string) ([]*es_models.Aggregate, error)) (*model.Org, []*es_models.Aggregate, error) {
if orgModel == nil || !orgModel.IsValid() {
return nil, nil, errors.ThrowInvalidArgument(nil, "EVENT-OeLSk", "Errors.Org.Invalid")
}
@@ -66,13 +66,13 @@ func (es *OrgEventstore) PrepareCreateOrg(ctx context.Context, orgModel *org_mod
orgModel.AggregateID = id
org := model.OrgFromModel(orgModel)
aggregates, err := orgCreatedAggregates(ctx, es.AggregateCreator(), org)
aggregates, err := orgCreatedAggregates(ctx, es.AggregateCreator(), org, users)
return org, aggregates, err
}
func (es *OrgEventstore) CreateOrg(ctx context.Context, orgModel *org_model.Org) (*org_model.Org, error) {
org, aggregates, err := es.PrepareCreateOrg(ctx, orgModel)
func (es *OrgEventstore) CreateOrg(ctx context.Context, orgModel *org_model.Org, users func(context.Context, string) ([]*es_models.Aggregate, error)) (*org_model.Org, error) {
org, aggregates, err := es.PrepareCreateOrg(ctx, orgModel, users)
err = es_sdk.PushAggregates(ctx, es.PushAggregates, org.AppendEvents, aggregates...)
if err != nil {
return nil, err
@@ -222,7 +222,7 @@ func (es *OrgEventstore) GenerateOrgDomainValidation(ctx context.Context, domain
return token, url, err
}
func (es *OrgEventstore) ValidateOrgDomain(ctx context.Context, domain *org_model.OrgDomain) error {
func (es *OrgEventstore) ValidateOrgDomain(ctx context.Context, domain *org_model.OrgDomain, users func(context.Context, string) ([]*es_models.Aggregate, error)) error {
if domain == nil || !domain.IsValid() {
return errors.ThrowPreconditionFailed(nil, "EVENT-R24hb", "Errors.Org.InvalidDomain")
}
@@ -249,7 +249,7 @@ func (es *OrgEventstore) ValidateOrgDomain(ctx context.Context, domain *org_mode
checkType, _ := d.ValidationType.CheckType()
err = es.verificationValidator(d.Domain, validationCode, validationCode, checkType)
if err == nil {
orgAggregates, err := OrgDomainVerifiedAggregate(ctx, es.Eventstore.AggregateCreator(), repoOrg, repoDomain)
orgAggregates, err := OrgDomainVerifiedAggregate(ctx, es.Eventstore.AggregateCreator(), repoOrg, repoDomain, users)
if err != nil {
return err
}

View File

@@ -578,6 +578,7 @@ func TestOrgEventstore_ValidateOrgDomain(t *testing.T) {
type args struct {
ctx context.Context
domain *org_model.OrgDomain
users func(ctx context.Context, domain string) ([]*es_models.Aggregate, error)
}
tests := []struct {
name string
@@ -682,6 +683,26 @@ func TestOrgEventstore_ValidateOrgDomain(t *testing.T) {
isErr: errors.IsInternal,
},
},
{
name: "(user) aggregate fails",
fields: fields{Eventstore: newTestEventstore(t).
expectFilterEvents([]*es_models.Event{orgCreatedEvent(), orgDomainAddedEvent(), orgDomainVerificationAddedEvent("token")}, nil).
expectDecrypt().
expectVerification(true).
expectAggregateCreator().
expectPushEvents(0, errors.ThrowInternal(nil, "EVENT-S8WzW", "test")),
},
args: args{
ctx: authz.NewMockContext("org", "user"),
domain: &org_model.OrgDomain{ObjectRoot: es_models.ObjectRoot{AggregateID: "hodor-org"}, Domain: "hodor.org", ValidationType: org_model.OrgDomainValidationTypeHTTP},
users: func(ctx context.Context, domain string) ([]*es_models.Aggregate, error) {
return nil, errors.ThrowInternal(nil, "id", "internal error")
},
},
res: res{
isErr: errors.IsPreconditionFailed,
},
},
{
name: "push failed",
fields: fields{Eventstore: newTestEventstore(t).
@@ -719,7 +740,7 @@ func TestOrgEventstore_ValidateOrgDomain(t *testing.T) {
}
for _, tt := range tests {
t.Run(tt.name, func(t *testing.T) {
err := tt.fields.Eventstore.ValidateOrgDomain(tt.args.ctx, tt.args.domain)
err := tt.fields.Eventstore.ValidateOrgDomain(tt.args.ctx, tt.args.domain, tt.args.users)
if tt.res.isErr == nil && err != nil {
t.Errorf("no error expected got:%T %v", err, err)
}

View File

@@ -2,6 +2,7 @@ package eventsourcing
import (
"context"
"github.com/caos/zitadel/internal/errors"
es_models "github.com/caos/zitadel/internal/eventstore/models"
org_model "github.com/caos/zitadel/internal/org/model"
@@ -42,7 +43,7 @@ func OrgAggregate(ctx context.Context, aggCreator *es_models.AggregateCreator, i
return aggCreator.NewAggregate(ctx, id, model.OrgAggregate, model.OrgVersion, sequence)
}
func orgCreatedAggregates(ctx context.Context, aggCreator *es_models.AggregateCreator, org *model.Org) (_ []*es_models.Aggregate, err error) {
func orgCreatedAggregates(ctx context.Context, aggCreator *es_models.AggregateCreator, org *model.Org, users func(context.Context, string) ([]*es_models.Aggregate, error)) (_ []*es_models.Aggregate, err error) {
if org == nil {
return nil, errors.ThrowPreconditionFailed(nil, "EVENT-kdie7", "Errors.Internal")
}
@@ -56,7 +57,7 @@ func orgCreatedAggregates(ctx context.Context, aggCreator *es_models.AggregateCr
return nil, err
}
aggregates := make([]*es_models.Aggregate, 0)
aggregates, err = addDomainAggregateAndEvents(ctx, aggCreator, agg, aggregates, org)
aggregates, err = addDomainAggregateAndEvents(ctx, aggCreator, agg, aggregates, org, users)
if err != nil {
return nil, err
}
@@ -68,22 +69,18 @@ func orgCreatedAggregates(ctx context.Context, aggCreator *es_models.AggregateCr
return append(aggregates, agg), nil
}
func addDomainAggregateAndEvents(ctx context.Context, aggCreator *es_models.AggregateCreator, orgAggregate *es_models.Aggregate, aggregates []*es_models.Aggregate, org *model.Org) ([]*es_models.Aggregate, error) {
func addDomainAggregateAndEvents(ctx context.Context, aggCreator *es_models.AggregateCreator, orgAggregate *es_models.Aggregate, aggregates []*es_models.Aggregate, org *model.Org, users func(context.Context, string) ([]*es_models.Aggregate, error)) ([]*es_models.Aggregate, error) {
for _, domain := range org.Domains {
orgAggregate, err := orgAggregate.AppendEvent(model.OrgDomainAdded, domain)
if err != nil {
return nil, err
}
if domain.Verified {
domainAggregate, err := reservedUniqueDomainAggregate(ctx, aggCreator, org.AggregateID, domain.Domain)
if err != nil {
return nil, err
}
aggregates = append(aggregates, domainAggregate)
orgAggregate, err = orgAggregate.AppendEvent(model.OrgDomainVerified, domain)
domainAggregates, err := OrgDomainVerifiedAggregate(ctx, aggCreator, org, domain, users)
if err != nil {
return nil, err
}
aggregates = append(aggregates, domainAggregates...)
}
if domain.Primary {
orgAggregate, err = orgAggregate.AppendEvent(model.OrgDomainPrimarySet, domain)
@@ -182,7 +179,6 @@ func reservedUniqueDomainAggregate(ctx context.Context, aggCreator *es_models.Ag
if err != nil {
return nil, err
}
return aggregate.SetPrecondition(OrgDomainUniqueQuery(domain), isEventValidation(aggregate, model.OrgDomainReserved)), nil
}
@@ -273,7 +269,7 @@ func OrgDomainValidationFailedAggregate(aggCreator *es_models.AggregateCreator,
}
}
func OrgDomainVerifiedAggregate(ctx context.Context, aggCreator *es_models.AggregateCreator, existing *model.Org, domain *model.OrgDomain) ([]*es_models.Aggregate, error) {
func OrgDomainVerifiedAggregate(ctx context.Context, aggCreator *es_models.AggregateCreator, existing *model.Org, domain *model.OrgDomain, users func(context.Context, string) ([]*es_models.Aggregate, error)) ([]*es_models.Aggregate, error) {
if domain == nil {
return nil, errors.ThrowPreconditionFailed(nil, "EVENT-DHs7s", "Errors.Internal")
}
@@ -291,6 +287,13 @@ func OrgDomainVerifiedAggregate(ctx context.Context, aggCreator *es_models.Aggre
return nil, err
}
aggregates = append(aggregates, domainAgregate)
if users != nil {
userAggregates, err := users(ctx, domain.Domain)
if err != nil {
return nil, errors.ThrowPreconditionFailed(err, "EVENT-HBwsw", "Errors.Internal")
}
aggregates = append(aggregates, userAggregates...)
}
return append(aggregates, agg), nil
}

View File

@@ -466,6 +466,7 @@ func TestOrgCreatedAggregates(t *testing.T) {
ctx context.Context
aggCreator *es_models.AggregateCreator
org *model.Org
users func(ctx context.Context, domain string) ([]*es_models.Aggregate, error)
}
tests := []struct {
name string
@@ -523,6 +524,30 @@ func TestOrgCreatedAggregates(t *testing.T) {
isErr: nil,
},
},
{
name: "org with domain users aggregate error",
args: args{
ctx: authz.NewMockContext("org", "user"),
aggCreator: es_models.NewAggregateCreator("test"),
org: &model.Org{
ObjectRoot: es_models.ObjectRoot{
AggregateID: "sdaf",
Sequence: 5,
},
Name: "caos",
Domains: []*model.OrgDomain{{
Domain: "caos.ch",
Verified: true,
}},
},
users: func(ctx context.Context, domain string) ([]*es_models.Aggregate, error) {
return nil, errors.ThrowInternal(nil, "id", "internal error")
},
},
res: res{
isErr: errors.IsPreconditionFailed,
},
},
{
name: "no name error",
args: args{
@@ -543,7 +568,7 @@ func TestOrgCreatedAggregates(t *testing.T) {
}
for _, tt := range tests {
t.Run(tt.name, func(t *testing.T) {
got, err := orgCreatedAggregates(tt.args.ctx, tt.args.aggCreator, tt.args.org)
got, err := orgCreatedAggregates(tt.args.ctx, tt.args.aggCreator, tt.args.org, tt.args.users)
if tt.res.isErr == nil && err != nil {
t.Errorf("no error expected got %T: %v", err, err)
}
@@ -676,7 +701,7 @@ func TestOrgDomainVerifiedAggregates(t *testing.T) {
}
for _, tt := range tests {
t.Run(tt.name, func(t *testing.T) {
got, err := OrgDomainVerifiedAggregate(tt.args.ctx, tt.args.aggCreator, tt.args.org, tt.args.domain)
got, err := OrgDomainVerifiedAggregate(tt.args.ctx, tt.args.aggCreator, tt.args.org, tt.args.domain, nil)
if tt.res.isErr == nil && err != nil {
t.Errorf("no error expected got %T: %v", err, err)
}

View File

@@ -2,12 +2,14 @@ package model
import (
"encoding/json"
"time"
"github.com/caos/logging"
caos_errs "github.com/caos/zitadel/internal/errors"
"github.com/caos/zitadel/internal/eventstore/models"
"github.com/caos/zitadel/internal/org/model"
es_model "github.com/caos/zitadel/internal/org/repository/eventsourcing/model"
"time"
)
const (
@@ -18,11 +20,12 @@ const (
)
type OrgDomainView struct {
Domain string `json:"domain" gorm:"column:domain;primary_key"`
OrgID string `json:"-" gorm:"column:org_id;primary_key"`
Verified bool `json:"-" gorm:"column:verified"`
Primary bool `json:"-" gorm:"column:primary_domain"`
Sequence uint64 `json:"-" gorm:"column:sequence"`
Domain string `json:"domain" gorm:"column:domain;primary_key"`
OrgID string `json:"-" gorm:"column:org_id;primary_key"`
Verified bool `json:"-" gorm:"column:verified"`
Primary bool `json:"-" gorm:"column:primary_domain"`
ValidationType int32 `json:"validationType" gorm:"column:validation_type"`
Sequence uint64 `json:"-" gorm:"column:sequence"`
CreationDate time.Time `json:"-" gorm:"column:creation_date"`
ChangeDate time.Time `json:"-" gorm:"column:change_date"`
@@ -30,23 +33,25 @@ type OrgDomainView struct {
func OrgDomainViewFromModel(domain *model.OrgDomainView) *OrgDomainView {
return &OrgDomainView{
OrgID: domain.OrgID,
Domain: domain.Domain,
Primary: domain.Primary,
Verified: domain.Verified,
CreationDate: domain.CreationDate,
ChangeDate: domain.ChangeDate,
OrgID: domain.OrgID,
Domain: domain.Domain,
Primary: domain.Primary,
Verified: domain.Verified,
ValidationType: int32(domain.ValidationType),
CreationDate: domain.CreationDate,
ChangeDate: domain.ChangeDate,
}
}
func OrgDomainToModel(domain *OrgDomainView) *model.OrgDomainView {
return &model.OrgDomainView{
OrgID: domain.OrgID,
Domain: domain.Domain,
Primary: domain.Primary,
Verified: domain.Verified,
CreationDate: domain.CreationDate,
ChangeDate: domain.ChangeDate,
OrgID: domain.OrgID,
Domain: domain.Domain,
Primary: domain.Primary,
Verified: domain.Verified,
ValidationType: model.OrgDomainValidationType(domain.ValidationType),
CreationDate: domain.CreationDate,
ChangeDate: domain.ChangeDate,
}
}
@@ -66,6 +71,8 @@ func (d *OrgDomainView) AppendEvent(event *models.Event) (err error) {
d.setRootData(event)
d.CreationDate = event.CreationDate
err = d.SetData(event)
case es_model.OrgDomainVerificationAdded:
err = d.SetData(event)
case es_model.OrgDomainVerified:
d.Verified = true
case es_model.OrgDomainPrimarySet: