Skip to content

Commit

Permalink
fix: do not iteratively delete records (#3766)
Browse files Browse the repository at this point in the history
Resolves performance issues on some databases when deleting consent.

BREAKING CHANGES: Deleting consents no longer returns 404 in certain edge cases but instead always 204.
  • Loading branch information
aeneasr committed Jun 7, 2024
1 parent 7563907 commit 5ef20a2
Show file tree
Hide file tree
Showing 17 changed files with 397 additions and 74 deletions.
4 changes: 2 additions & 2 deletions .github/workflows/ci.yaml
Original file line number Diff line number Diff line change
Expand Up @@ -69,7 +69,7 @@ jobs:
steps:
- run: |
docker create --name cockroach -p 26257:26257 \
cockroachdb/cockroach:v22.1.10 start-single-node --insecure
cockroachdb/cockroach:v24.1.0 start-single-node --insecure
docker start cockroach
name: Start CockroachDB
- uses: ory/ci/checkout@master
Expand Down Expand Up @@ -170,7 +170,7 @@ jobs:
steps:
- run: |
docker create --name cockroach -p 26257:26257 \
cockroachdb/cockroach:v22.1.10 start-single-node --insecure
cockroachdb/cockroach:v24.1.0 start-single-node --insecure
docker start cockroach
name: Start CockroachDB
- uses: ory/ci/checkout@master
Expand Down
4 changes: 2 additions & 2 deletions consent/test/manager_test_helpers.go
Original file line number Diff line number Diff line change
Expand Up @@ -744,8 +744,8 @@ func ManagerTests(deps Deps, m consent.Manager, clientManager client.Manager, fo
})
}

require.EqualError(t, m.RevokeSubjectConsentSession(ctx, "i-do-not-exist"), x.ErrNotFound.Error())
require.EqualError(t, m.RevokeSubjectClientConsentSession(ctx, "i-do-not-exist", "i-do-not-exist"), x.ErrNotFound.Error())
require.NoError(t, m.RevokeSubjectConsentSession(ctx, "i-do-not-exist"))
require.NoError(t, m.RevokeSubjectClientConsentSession(ctx, "i-do-not-exist", "i-do-not-exist"))
})

t.Run("case=list-used-consent-requests", func(t *testing.T) {
Expand Down
13 changes: 5 additions & 8 deletions internal/driver.go
Original file line number Diff line number Diff line change
Expand Up @@ -9,19 +9,16 @@ import (
"testing"

"github.com/go-jose/go-jose/v3"

"github.com/ory/x/configx"

"github.com/stretchr/testify/require"

"github.com/ory/hydra/v2/x"
"github.com/ory/x/contextx"
"github.com/ory/x/sqlcon/dockertest"

"github.com/ory/hydra/v2/driver"
"github.com/ory/hydra/v2/driver/config"
"github.com/ory/hydra/v2/jwk"
"github.com/ory/hydra/v2/x"
"github.com/ory/x/configx"
"github.com/ory/x/contextx"
"github.com/ory/x/logrusx"
"github.com/ory/x/sqlcon/dockertest"
)

func resetConfig(p *config.DefaultProvider) {
Expand Down Expand Up @@ -87,7 +84,7 @@ func ConnectToPG(t testing.TB) string {
}

func ConnectToCRDB(t testing.TB) string {
return dockertest.RunTestCockroachDBWithVersion(t, "v22.1.2")
return dockertest.RunTestCockroachDBWithVersion(t, "v24.1.0")
}

func ConnectDatabases(t *testing.T, migrate bool, ctxer contextx.Contextualizer) (pg, mysql, crdb driver.Registry, clean func(*testing.T)) {
Expand Down
347 changes: 347 additions & 0 deletions internal/httpclient/go.sum

Large diffs are not rendered by default.

Original file line number Diff line number Diff line change
@@ -1 +1 @@
ALTER TABLE hydra_client ALTER PRIMARY KEY USING COLUMNS (id, nid) USING HASH;
ALTER TABLE hydra_client ALTER PRIMARY KEY USING COLUMNS (id, nid);
77 changes: 39 additions & 38 deletions persistence/sql/persister_consent.go
Original file line number Diff line number Diff line change
Expand Up @@ -12,21 +12,18 @@ import (

"github.com/gobuffalo/pop/v6"
"github.com/gofrs/uuid"

"github.com/ory/hydra/v2/oauth2/flowctx"
"github.com/ory/x/otelx"
"github.com/ory/x/sqlxx"

"github.com/ory/x/errorsx"

"github.com/pkg/errors"

"github.com/ory/fosite"
"github.com/ory/hydra/v2/client"
"github.com/ory/hydra/v2/consent"
"github.com/ory/hydra/v2/flow"
"github.com/ory/hydra/v2/oauth2/flowctx"
"github.com/ory/hydra/v2/x"
"github.com/ory/x/errorsx"
"github.com/ory/x/otelx"
"github.com/ory/x/sqlcon"
"github.com/ory/x/sqlxx"
)

var _ consent.Manager = &Persister{}
Expand All @@ -51,43 +48,47 @@ func (p *Persister) revokeConsentSession(whereStmt string, whereArgs ...interfac
if err := p.QueryWithNetwork(ctx).
Where(whereStmt, whereArgs...).
Select("consent_challenge_id").
All(&fs); err != nil {
if errors.Is(err, sql.ErrNoRows) {
return errorsx.WithStack(x.ErrNotFound)
}

All(&fs); errors.Is(err, sql.ErrNoRows) {
return errorsx.WithStack(x.ErrNotFound)
} else if err != nil {
return sqlcon.HandleError(err)
}

var count int
ids := make([]interface{}, 0, len(fs))
nid := p.NetworkID(ctx)
for _, f := range fs {
if err := p.RevokeAccessToken(ctx, f.ConsentChallengeID.String()); errors.Is(err, fosite.ErrNotFound) {
// do nothing
} else if err != nil {
return err
}

if err := p.RevokeRefreshToken(ctx, f.ConsentChallengeID.String()); errors.Is(err, fosite.ErrNotFound) {
// do nothing
} else if err != nil {
return err
}

localCount, err := c.RawQuery("DELETE FROM hydra_oauth2_flow WHERE consent_challenge_id = ? AND nid = ?", f.ConsentChallengeID, p.NetworkID(ctx)).ExecWithCount()
if err != nil {
if errors.Is(err, sql.ErrNoRows) {
return errorsx.WithStack(x.ErrNotFound)
}
return sqlcon.HandleError(err)
}

// If there are no sessions to revoke we should return an error to indicate to the caller
// that the request failed.
count += localCount
ids = append(ids, f.ConsentChallengeID.String())
}

if len(ids) == 0 {
return nil
}

if err := p.QueryWithNetwork(ctx).
Where("nid = ?", nid).
Where("request_id IN (?)", ids...).
Delete(&OAuth2RequestSQL{Table: sqlTableAccess}); errors.Is(err, fosite.ErrNotFound) {
// do nothing
} else if err != nil {
return err
}

if count == 0 {
if err := p.QueryWithNetwork(ctx).
Where("nid = ?", nid).
Where("request_id IN (?)", ids...).
Delete(&OAuth2RequestSQL{Table: sqlTableRefresh}); errors.Is(err, fosite.ErrNotFound) {
// do nothing
} else if err != nil {
return err
}

if err := p.QueryWithNetwork(ctx).
Where("nid = ?", nid).
Where("consent_challenge_id IN (?)", ids...).
Delete(new(flow.Flow)); errors.Is(err, sql.ErrNoRows) {
return errorsx.WithStack(x.ErrNotFound)
} else if err != nil {
return sqlcon.HandleError(err)
}

return nil
Expand Down Expand Up @@ -642,7 +643,7 @@ SELECT DISTINCT c.* FROM hydra_client as c
JOIN hydra_oauth2_flow as f ON (c.id = f.client_id AND c.nid = f.nid)
WHERE
f.subject=? AND
c.%schannel_logout_uri!='' AND
c.%schannel_logout_uri != '' AND
c.%schannel_logout_uri IS NOT NULL AND
f.login_session_id = ? AND
f.nid = ? AND
Expand Down
2 changes: 1 addition & 1 deletion persistence/sql/persister_nid_test.go
Original file line number Diff line number Diff line change
Expand Up @@ -1834,7 +1834,7 @@ func (s *PersisterTestSuite) TestRevokeSubjectClientConsentSession() {

actual := flow.Flow{}

require.Error(t, r.Persister().RevokeSubjectClientConsentSession(s.t2, "sub", client.ID))
require.NoError(t, r.Persister().RevokeSubjectClientConsentSession(s.t2, "sub", client.ID), "should not error if nothing was found")
require.NoError(t, r.Persister().Connection(context.Background()).Find(&actual, f.ID))
require.NoError(t, r.Persister().RevokeSubjectClientConsentSession(s.t1, "sub", client.ID))
require.Error(t, r.Persister().Connection(context.Background()).Find(&actual, f.ID))
Expand Down
1 change: 0 additions & 1 deletion quickstart-cockroach.yml
Original file line number Diff line number Diff line change
Expand Up @@ -9,7 +9,6 @@
# endpoint can only be used if you follow the steps in the tutorial. #
# #
###########################################################################
version: "3.7"
services:
hydra-migrate:
environment:
Expand Down
3 changes: 0 additions & 3 deletions quickstart-cors.yml
Original file line number Diff line number Diff line change
Expand Up @@ -9,9 +9,6 @@
# endpoint can only be used if you follow the steps in the tutorial. #
# #
###########################################################################

version: "3.7"

services:
hydra:
environment:
Expand Down
3 changes: 0 additions & 3 deletions quickstart-debug.yml
Original file line number Diff line number Diff line change
Expand Up @@ -9,9 +9,6 @@
# endpoint can only be used if you follow the steps in the tutorial. #
# #
###########################################################################

version: "3.7"

services:
hydra:
environment:
Expand Down
3 changes: 0 additions & 3 deletions quickstart-hsm.yml
Original file line number Diff line number Diff line change
Expand Up @@ -9,9 +9,6 @@
# endpoint can only be used if you follow the steps in the tutorial. #
# #
###########################################################################

version: "3.7"

services:
hydra:
build:
Expand Down
3 changes: 0 additions & 3 deletions quickstart-jwt.yml
Original file line number Diff line number Diff line change
Expand Up @@ -9,9 +9,6 @@
# endpoint can only be used if you follow the steps in the tutorial. #
# #
###########################################################################

version: "3.7"

services:
hydra:
environment:
Expand Down
1 change: 0 additions & 1 deletion quickstart-mysql.yml
Original file line number Diff line number Diff line change
Expand Up @@ -9,7 +9,6 @@
# endpoint can only be used if you follow the steps in the tutorial. #
# #
###########################################################################
version: "3.7"
services:
hydra-migrate:
environment:
Expand Down
1 change: 0 additions & 1 deletion quickstart-postgres.yml
Original file line number Diff line number Diff line change
Expand Up @@ -9,7 +9,6 @@
# endpoint can only be used if you follow the steps in the tutorial. #
# #
###########################################################################
version: "3.7"
services:
hydra-migrate:
environment:
Expand Down
3 changes: 0 additions & 3 deletions quickstart-prometheus.yml
Original file line number Diff line number Diff line change
Expand Up @@ -9,9 +9,6 @@
# endpoint can only be used if you follow the steps in the tutorial. #
# #
###########################################################################

version: "3.7"

services:
prometheus:
image: prom/prometheus:v2.12.0
Expand Down
3 changes: 0 additions & 3 deletions quickstart-tracing.yml
Original file line number Diff line number Diff line change
Expand Up @@ -9,9 +9,6 @@
# endpoint can only be used if you follow the steps in the tutorial. #
# #
###########################################################################

version: "3.7"

services:
hydra:
depends_on:
Expand Down
1 change: 0 additions & 1 deletion quickstart.yml
Original file line number Diff line number Diff line change
Expand Up @@ -9,7 +9,6 @@
# endpoint can only be used if you follow the steps in the tutorial. #
# #
###########################################################################
version: "3.7"
services:
hydra:
image: oryd/hydra:v2.2.0
Expand Down

0 comments on commit 5ef20a2

Please sign in to comment.