Skip to content

Commit

Permalink
fix: use correct post-verification identity state in post-hooks (#3863)
Browse files Browse the repository at this point in the history
  • Loading branch information
aeneasr committed Apr 5, 2024
1 parent f696fcf commit 6e63d06
Show file tree
Hide file tree
Showing 6 changed files with 73 additions and 18 deletions.
1 change: 1 addition & 0 deletions internal/client-go/go.sum
Original file line number Diff line number Diff line change
Expand Up @@ -4,6 +4,7 @@ github.com/golang/protobuf v1.2.0/go.mod h1:6lQm79b+lXiMfvg/cZm0SGofjICqVBUtrP5y
golang.org/x/net v0.0.0-20180724234803-3673e40ba225/go.mod h1:mL1N/T3taQHkDXs73rZJwtUhF3w3ftmwwsq0BUmARs4=
golang.org/x/net v0.0.0-20190108225652-1e06a53dbb7e h1:bRhVy7zSSasaqNksaRZiA5EEI+Ei4I1nO5Jh72wfHlg=
golang.org/x/net v0.0.0-20190108225652-1e06a53dbb7e/go.mod h1:mL1N/T3taQHkDXs73rZJwtUhF3w3ftmwwsq0BUmARs4=
golang.org/x/oauth2 v0.0.0-20190604053449-0f29369cfe45/go.mod h1:gOpvHmFTYa4IltrdGE7lF6nIHvwfUNPOp7c8zoXwtLw=
golang.org/x/sync v0.0.0-20181221193216-37e7f081c4d4 h1:YUO/7uOKsKeq9UokNS62b8FYywz3ker1l1vDZRCRefw=
golang.org/x/sync v0.0.0-20181221193216-37e7f081c4d4/go.mod h1:RxMgew5VJxzue5/jJTE5uejpjVlOe/izrB70Jof72aM=
golang.org/x/text v0.3.0/go.mod h1:NqM8EUOU14njkJ3fqMW+pc6Ldnwhi/IjpwHt7yyuwOQ=
Expand Down
27 changes: 27 additions & 0 deletions internal/testhelpers/selfservice_verification.go
Original file line number Diff line number Diff line change
Expand Up @@ -7,6 +7,7 @@ import (
"bytes"
"context"
"encoding/json"
"io"
"net/http"
"net/http/httptest"
"net/url"
Expand All @@ -29,6 +30,32 @@ import (
"github.com/ory/kratos/x"
)

func NewVerifyAfterHookWebHookTarget(ctx context.Context, t *testing.T, conf *config.Config, assert func(t *testing.T, body []byte)) {
ts := httptest.NewServer(http.HandlerFunc(func(w http.ResponseWriter, r *http.Request) {
msg, err := io.ReadAll(r.Body)
require.NoError(t, err)

assert(t, msg)
}))

// A hook to ensure that the verification hook is called with the correct data
conf.MustSet(ctx, config.ViperKeySelfServiceVerificationAfter+".hooks", []map[string]interface{}{
{
"hook": "web_hook",
"config": map[string]interface{}{
"url": ts.URL,
"method": "POST",
"body": "base64://ZnVuY3Rpb24oY3R4KSB7CiAgICBpZGVudGl0eTogY3R4LmlkZW50aXR5Cn0=",
},
},
})

t.Cleanup(ts.Close)
t.Cleanup(func() {
conf.MustSet(ctx, config.ViperKeySelfServiceVerificationAfter+".hooks", []map[string]interface{}{})
})
}

func NewRecoveryUIFlowEchoServer(t *testing.T, reg driver.Registry) *httptest.Server {
ctx := context.Background()
ts := httptest.NewServer(http.HandlerFunc(func(w http.ResponseWriter, r *http.Request) {
Expand Down
18 changes: 9 additions & 9 deletions selfservice/strategy/code/strategy_verification.go
Original file line number Diff line number Diff line change
Expand Up @@ -254,15 +254,6 @@ func (s *Strategy) verificationUseCode(w http.ResponseWriter, r *http.Request, c
return s.retryVerificationFlowWithError(w, r, f.Type, err)
}

i, err := s.deps.IdentityPool().GetIdentity(r.Context(), code.VerifiableAddress.IdentityID, identity.ExpandDefault)
if err != nil {
return s.retryVerificationFlowWithError(w, r, f.Type, err)
}

if err := s.deps.VerificationExecutor().PostVerificationHook(w, r, f, i); err != nil {
return s.retryVerificationFlowWithError(w, r, f.Type, err)
}

address := code.VerifiableAddress
address.Verified = true
verifiedAt := sqlxx.NullTime(time.Now().UTC())
Expand All @@ -272,6 +263,11 @@ func (s *Strategy) verificationUseCode(w http.ResponseWriter, r *http.Request, c
return s.retryVerificationFlowWithError(w, r, f.Type, err)
}

i, err := s.deps.IdentityPool().GetIdentity(r.Context(), code.VerifiableAddress.IdentityID, identity.ExpandDefault)
if err != nil {
return s.retryVerificationFlowWithError(w, r, f.Type, err)
}

returnTo := f.ContinueURL(r.Context(), s.deps.Config())

f.UI = &container.Container{
Expand All @@ -292,6 +288,10 @@ func (s *Strategy) verificationUseCode(w http.ResponseWriter, r *http.Request, c
return s.retryVerificationFlowWithError(w, r, flow.TypeBrowser, err)
}

if err := s.deps.VerificationExecutor().PostVerificationHook(w, r, f, i); err != nil {
return s.retryVerificationFlowWithError(w, r, f.Type, err)
}

return nil
}

Expand Down
14 changes: 14 additions & 0 deletions selfservice/strategy/code/strategy_verification_test.go
Original file line number Diff line number Diff line change
Expand Up @@ -13,6 +13,7 @@ import (
"net/http/httptest"
"net/url"
"strings"
"sync"
"testing"
"time"

Expand Down Expand Up @@ -297,6 +298,13 @@ func TestVerification(t *testing.T) {
})

t.Run("description=should verify an email address", func(t *testing.T) {
var wg sync.WaitGroup
testhelpers.NewVerifyAfterHookWebHookTarget(ctx, t, conf, func(t *testing.T, msg []byte) {
defer wg.Done()
assert.EqualValues(t, true, gjson.GetBytes(msg, "identity.verifiable_addresses.0.verified").Bool(), string(msg))
assert.EqualValues(t, "completed", gjson.GetBytes(msg, "identity.verifiable_addresses.0.status").String(), string(msg))
})

check := func(t *testing.T, actual string) {
assert.EqualValues(t, string(node.CodeGroup), gjson.Get(actual, "active").String(), "%s", actual)
assert.EqualValues(t, verificationEmail, gjson.Get(actual, "ui.nodes.#(attributes.name==email).attributes.value").String(), "%s", actual)
Expand Down Expand Up @@ -342,15 +350,21 @@ func TestVerification(t *testing.T) {
}

t.Run("type=browser", func(t *testing.T) {
wg.Add(1)
check(t, expectSuccess(t, nil, false, false, values))
wg.Wait()
})

t.Run("type=spa", func(t *testing.T) {
wg.Add(1)
check(t, expectSuccess(t, nil, false, true, values))
wg.Wait()
})

t.Run("type=api", func(t *testing.T) {
wg.Add(1)
check(t, expectSuccess(t, nil, true, false, values))
wg.Wait()
})
})

Expand Down
18 changes: 9 additions & 9 deletions selfservice/strategy/link/strategy_verification.go
Original file line number Diff line number Diff line change
Expand Up @@ -216,15 +216,6 @@ func (s *Strategy) verificationUseToken(w http.ResponseWriter, r *http.Request,
return s.retryVerificationFlowWithError(w, r, flow.TypeBrowser, err)
}

i, err := s.d.IdentityPool().GetIdentity(r.Context(), token.VerifiableAddress.IdentityID, identity.ExpandDefault)
if err != nil {
return s.retryVerificationFlowWithError(w, r, flow.TypeBrowser, err)
}

if err := s.d.VerificationExecutor().PostVerificationHook(w, r, f, i); err != nil {
return s.retryVerificationFlowWithError(w, r, flow.TypeBrowser, err)
}

address := token.VerifiableAddress
address.Verified = true
verifiedAt := sqlxx.NullTime(time.Now().UTC())
Expand All @@ -234,6 +225,11 @@ func (s *Strategy) verificationUseToken(w http.ResponseWriter, r *http.Request,
return s.retryVerificationFlowWithError(w, r, flow.TypeBrowser, err)
}

i, err := s.d.IdentityPool().GetIdentity(r.Context(), token.VerifiableAddress.IdentityID, identity.ExpandDefault)
if err != nil {
return s.retryVerificationFlowWithError(w, r, flow.TypeBrowser, err)
}

returnTo := f.ContinueURL(r.Context(), s.d.Config())

f.UI.
Expand All @@ -259,6 +255,10 @@ func (s *Strategy) verificationUseToken(w http.ResponseWriter, r *http.Request,
return s.retryVerificationFlowWithError(w, r, flow.TypeBrowser, err)
}

if err := s.d.VerificationExecutor().PostVerificationHook(w, r, f, i); err != nil {
return s.retryVerificationFlowWithError(w, r, flow.TypeBrowser, err)
}

return nil
}

Expand Down
13 changes: 13 additions & 0 deletions selfservice/strategy/link/strategy_verification_test.go
Original file line number Diff line number Diff line change
Expand Up @@ -11,6 +11,7 @@ import (
"net/http"
"net/http/httptest"
"net/url"
"sync"
"testing"
"time"

Expand Down Expand Up @@ -270,6 +271,12 @@ func TestVerification(t *testing.T) {
})

t.Run("description=should verify an email address", func(t *testing.T) {
var wg sync.WaitGroup
testhelpers.NewVerifyAfterHookWebHookTarget(ctx, t, conf, func(t *testing.T, msg []byte) {
defer wg.Done()
assert.EqualValues(t, true, gjson.GetBytes(msg, "identity.verifiable_addresses.0.verified").Bool(), string(msg))
assert.EqualValues(t, "completed", gjson.GetBytes(msg, "identity.verifiable_addresses.0.status").String(), string(msg))
})
check := func(t *testing.T, actual string) {
assert.EqualValues(t, string(node.LinkGroup), gjson.Get(actual, "active").String(), "%s", actual)
assert.EqualValues(t, verificationEmail, gjson.Get(actual, "ui.nodes.#(attributes.name==email).attributes.value").String(), "%s", actual)
Expand Down Expand Up @@ -310,15 +317,21 @@ func TestVerification(t *testing.T) {
}

t.Run("type=browser", func(t *testing.T) {
wg.Add(1)
check(t, expectSuccess(t, nil, false, false, values))
wg.Wait()
})

t.Run("type=spa", func(t *testing.T) {
wg.Add(1)
check(t, expectSuccess(t, nil, false, true, values))
wg.Wait()
})

t.Run("type=api", func(t *testing.T) {
wg.Add(1)
check(t, expectSuccess(t, nil, true, false, values))
wg.Wait()
})
})

Expand Down

0 comments on commit 6e63d06

Please sign in to comment.