From 006bf56671d8162cdb5bcce630c027b67935263d Mon Sep 17 00:00:00 2001 From: aeneasr <3372410+aeneasr@users.noreply.github.com> Date: Tue, 25 Aug 2020 10:24:50 +0200 Subject: [PATCH] refactor: add method and rename request to flow --- persistence/reference.go | 2 +- persistence/sql/persister_settings.go | 37 +++++++-- selfservice/flow/settings/persistence.go | 100 +++++++++++++++-------- 3 files changed, 98 insertions(+), 41 deletions(-) diff --git a/persistence/reference.go b/persistence/reference.go index 20057f13eff..b4319aa925f 100644 --- a/persistence/reference.go +++ b/persistence/reference.go @@ -28,7 +28,7 @@ type Persister interface { identity.PrivilegedPool registration.FlowPersister login.FlowPersister - settings.RequestPersister + settings.FlowPersister courier.Persister session.Persister errorx.Persister diff --git a/persistence/sql/persister_settings.go b/persistence/sql/persister_settings.go index e1e8e062a37..ad70d33b3d9 100644 --- a/persistence/sql/persister_settings.go +++ b/persistence/sql/persister_settings.go @@ -5,20 +5,21 @@ import ( "github.com/gobuffalo/pop/v5" "github.com/gofrs/uuid" + "github.com/ory/x/sqlxx" "github.com/ory/x/sqlcon" "github.com/ory/kratos/selfservice/flow/settings" ) -var _ settings.RequestPersister = new(Persister) +var _ settings.FlowPersister = new(Persister) -func (p *Persister) CreateSettingsRequest(ctx context.Context, r *settings.Request) error { +func (p *Persister) CreateSettingsFlow(ctx context.Context, r *settings.Flow) error { return sqlcon.HandleError(p.GetConnection(ctx).Eager("MethodsRaw").Create(r)) } -func (p *Persister) GetSettingsRequest(ctx context.Context, id uuid.UUID) (*settings.Request, error) { - var r settings.Request +func (p *Persister) GetSettingsFlow(ctx context.Context, id uuid.UUID) (*settings.Flow, error) { + var r settings.Flow if err := p.GetConnection(ctx).Eager().Find(&r, id); err != nil { return nil, sqlcon.HandleError(err) } @@ -30,10 +31,10 @@ func (p *Persister) GetSettingsRequest(ctx context.Context, id uuid.UUID) (*sett return &r, nil } -func (p *Persister) UpdateSettingsRequest(ctx context.Context, r *settings.Request) error { +func (p *Persister) UpdateSettingsFlow(ctx context.Context, r *settings.Flow) error { return p.Transaction(ctx, func(ctx context.Context, tx *pop.Connection) error { - rr, err := p.GetSettingsRequest(ctx, r.ID) + rr, err := p.GetSettingsFlow(ctx, r.ID) if err != nil { return err } @@ -61,3 +62,27 @@ func (p *Persister) UpdateSettingsRequest(ctx context.Context, r *settings.Reque return tx.Save(r) }) } + +func (p *Persister) UpdateSettingsFlowMethod(ctx context.Context, id uuid.UUID, method string, fm *settings.FlowMethod) error { + return p.Transaction(ctx, func(ctx context.Context, tx *pop.Connection) error { + rr, err := p.GetSettingsFlow(ctx, id) + if err != nil { + return err + } + + m, ok := rr.Methods[method] + if !ok { + fm.FlowID = rr.ID + fm.Method = method + return tx.Save(fm) + } + + m.Config = fm.Config + if err := tx.Save(m); err != nil { + return err + } + + rr.Active = sqlxx.NullString(method) + return tx.Save(rr) + }) +} diff --git a/selfservice/flow/settings/persistence.go b/selfservice/flow/settings/persistence.go index dca97ad2e0e..fff12961f9b 100644 --- a/selfservice/flow/settings/persistence.go +++ b/selfservice/flow/settings/persistence.go @@ -19,23 +19,24 @@ import ( ) type ( - RequestPersister interface { - CreateSettingsRequest(context.Context, *Request) error - GetSettingsRequest(ctx context.Context, id uuid.UUID) (*Request, error) - UpdateSettingsRequest(context.Context, *Request) error + FlowPersister interface { + CreateSettingsFlow(context.Context, *Flow) error + GetSettingsFlow(ctx context.Context, id uuid.UUID) (*Flow, error) + UpdateSettingsFlow(context.Context, *Flow) error + UpdateSettingsFlowMethod(context.Context, uuid.UUID, string, *FlowMethod) error } - RequestPersistenceProvider interface { - SettingsRequestPersister() RequestPersister + FlowPersistenceProvider interface { + SettingsFlowPersister() FlowPersister } ) func TestRequestPersister(p interface { - RequestPersister + FlowPersister identity.PrivilegedPool }) func(t *testing.T) { viper.Set(configuration.ViperKeyDefaultIdentitySchemaURL, "file://./stub/identity.schema.json") - var clearids = func(r *Request) { + var clearids = func(r *Flow) { r.ID = uuid.UUID{} r.Identity.ID = uuid.UUID{} r.IdentityID = uuid.UUID{} @@ -43,12 +44,12 @@ func TestRequestPersister(p interface { return func(t *testing.T) { t.Run("case=should error when the settings request does not exist", func(t *testing.T) { - _, err := p.GetSettingsRequest(context.Background(), x.NewUUID()) + _, err := p.GetSettingsFlow(context.Background(), x.NewUUID()) require.Error(t, err) }) - var newRequest = func(t *testing.T) *Request { - var r Request + var newFlow = func(t *testing.T) *Flow { + var r Flow require.NoError(t, faker.FakeData(&r)) clearids(&r) require.NoError(t, p.CreateIdentity(context.Background(), r.Identity)) @@ -56,30 +57,30 @@ func TestRequestPersister(p interface { } t.Run("case=should create a new settings request", func(t *testing.T) { - r := newRequest(t) - err := p.CreateSettingsRequest(context.Background(), r) + r := newFlow(t) + err := p.CreateSettingsFlow(context.Background(), r) require.NoError(t, err, "%#v", err) }) t.Run("case=should create with set ids", func(t *testing.T) { - var r Request + var r Flow require.NoError(t, faker.FakeData(&r)) require.NoError(t, p.CreateIdentity(context.Background(), r.Identity)) - require.NoError(t, p.CreateSettingsRequest(context.Background(), &r)) + require.NoError(t, p.CreateSettingsFlow(context.Background(), &r)) }) t.Run("case=should create and fetch a settings request", func(t *testing.T) { - expected := newRequest(t) - err := p.CreateSettingsRequest(context.Background(), expected) + expected := newFlow(t) + err := p.CreateSettingsFlow(context.Background(), expected) require.NoError(t, err) - actual, err := p.GetSettingsRequest(context.Background(), expected.ID) + actual, err := p.GetSettingsFlow(context.Background(), expected.ID) require.NoError(t, err) factual, _ := json.Marshal(actual.Methods[StrategyProfile].Config) fexpected, _ := json.Marshal(expected.Methods[StrategyProfile].Config) - require.NotEmpty(t, actual.Methods[StrategyProfile].Config.RequestMethodConfigurator.(*form.HTMLForm).Action) + require.NotEmpty(t, actual.Methods[StrategyProfile].Config.FlowMethodConfigurator.(*form.HTMLForm).Action) assert.EqualValues(t, expected.ID, actual.ID) assert.JSONEq(t, string(fexpected), string(factual)) x.AssertEqualTime(t, expected.IssuedAt, actual.IssuedAt) @@ -92,41 +93,72 @@ func TestRequestPersister(p interface { }) t.Run("case=should fail to create if identity does not exist", func(t *testing.T) { - var expected Request + var expected Flow require.NoError(t, faker.FakeData(&expected)) clearids(&expected) expected.Identity = nil expected.IdentityID = uuid.Nil - err := p.CreateSettingsRequest(context.Background(), &expected) + err := p.CreateSettingsFlow(context.Background(), &expected) require.Error(t, err, "%+s", expected) }) t.Run("case=should create and update a settings request", func(t *testing.T) { - expected := newRequest(t) - expected.Methods["oidc"] = &RequestMethod{ - Method: "oidc", Config: &RequestMethodConfig{RequestMethodConfigurator: &form.HTMLForm{Fields: []form.Field{{ + expected := newFlow(t) + expected.Methods["oidc"] = &FlowMethod{ + Method: "oidc", Config: &FlowMethodConfig{FlowMethodConfigurator: &form.HTMLForm{Fields: []form.Field{{ Name: "zab", Type: "bar", Pattern: "baz"}}}}} - expected.Methods["password"] = &RequestMethod{ - Method: "password", Config: &RequestMethodConfig{RequestMethodConfigurator: &form.HTMLForm{Fields: []form.Field{{ + expected.Methods["password"] = &FlowMethod{ + Method: "password", Config: &FlowMethodConfig{FlowMethodConfigurator: &form.HTMLForm{Fields: []form.Field{{ Name: "foo", Type: "bar", Pattern: "baz"}}}}} - err := p.CreateSettingsRequest(context.Background(), expected) + err := p.CreateSettingsFlow(context.Background(), expected) require.NoError(t, err) - expected.Methods[StrategyProfile].Config.RequestMethodConfigurator.(*form.HTMLForm).Action = "/new-action" - expected.Methods["password"].Config.RequestMethodConfigurator.(*form.HTMLForm).Fields = []form.Field{{ + expected.Methods[StrategyProfile].Config.FlowMethodConfigurator.(*form.HTMLForm).Action = "/new-action" + expected.Methods["password"].Config.FlowMethodConfigurator.(*form.HTMLForm).Fields = []form.Field{{ Name: "zab", Type: "zab", Pattern: "zab"}} expected.RequestURL = "/new-request-url" - require.NoError(t, p.UpdateSettingsRequest(context.Background(), expected)) + require.NoError(t, p.UpdateSettingsFlow(context.Background(), expected)) - actual, err := p.GetSettingsRequest(context.Background(), expected.ID) + actual, err := p.GetSettingsFlow(context.Background(), expected.ID) require.NoError(t, err) - assert.Equal(t, "/new-action", actual.Methods[StrategyProfile].Config.RequestMethodConfigurator.(*form.HTMLForm).Action) + assert.Equal(t, "/new-action", actual.Methods[StrategyProfile].Config.FlowMethodConfigurator.(*form.HTMLForm).Action) assert.Equal(t, "/new-request-url", actual.RequestURL) assert.EqualValues(t, []form.Field{{Name: "zab", Type: "zab", Pattern: "zab"}}, actual. - Methods["password"].Config.RequestMethodConfigurator.(*form.HTMLForm).Fields) + Methods["password"].Config.FlowMethodConfigurator.(*form.HTMLForm).Fields) assert.EqualValues(t, []form.Field{{Name: "zab", Type: "bar", Pattern: "baz"}}, actual. - Methods["oidc"].Config.RequestMethodConfigurator.(*form.HTMLForm).Fields) + Methods["oidc"].Config.FlowMethodConfigurator.(*form.HTMLForm).Fields) + }) + + t.Run("case=should update a settings flow method", func(t *testing.T) { + expected := newFlow(t) + delete(expected.Methods, identity.CredentialsTypeOIDC.String()) + delete(expected.Methods, StrategyProfile) + + err := p.CreateSettingsFlow(context.Background(), expected) + require.NoError(t, err) + + actual, err := p.GetSettingsFlow(context.Background(), expected.ID) + require.NoError(t, err) + assert.Len(t, actual.Methods, 1) + + require.NoError(t, p.UpdateSettingsFlowMethod(context.Background(), expected.ID, identity.CredentialsTypeOIDC.String(), &FlowMethod{ + Method: identity.CredentialsTypeOIDC.String(), + Config: &FlowMethodConfig{FlowMethodConfigurator: form.NewHTMLForm(string(identity.CredentialsTypeOIDC))}, + })) + + require.NoError(t, p.UpdateSettingsFlowMethod(context.Background(), expected.ID, identity.CredentialsTypePassword.String(), &FlowMethod{ + Method: identity.CredentialsTypePassword.String(), + Config: &FlowMethodConfig{FlowMethodConfigurator: form.NewHTMLForm(string(identity.CredentialsTypePassword))}, + })) + + actual, err = p.GetSettingsFlow(context.Background(), expected.ID) + require.NoError(t, err) + require.Len(t, actual.Methods, 2) + assert.EqualValues(t, identity.CredentialsTypePassword, actual.Active) + + assert.Equal(t, string(identity.CredentialsTypePassword), actual.Methods[identity.CredentialsTypePassword.String()].Config.FlowMethodConfigurator.(*form.HTMLForm).Action) + assert.Equal(t, string(identity.CredentialsTypeOIDC), actual.Methods[identity.CredentialsTypeOIDC.String()].Config.FlowMethodConfigurator.(*form.HTMLForm).Action) }) } }