Skip to content

Commit 5ef20a2

Browse files
authored
fix: do not iteratively delete records (#3766)
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.
1 parent 7563907 commit 5ef20a2

17 files changed

+397
-74
lines changed

.github/workflows/ci.yaml

+2-2
Original file line numberDiff line numberDiff line change
@@ -69,7 +69,7 @@ jobs:
6969
steps:
7070
- run: |
7171
docker create --name cockroach -p 26257:26257 \
72-
cockroachdb/cockroach:v22.1.10 start-single-node --insecure
72+
cockroachdb/cockroach:v24.1.0 start-single-node --insecure
7373
docker start cockroach
7474
name: Start CockroachDB
7575
- uses: ory/ci/checkout@master
@@ -170,7 +170,7 @@ jobs:
170170
steps:
171171
- run: |
172172
docker create --name cockroach -p 26257:26257 \
173-
cockroachdb/cockroach:v22.1.10 start-single-node --insecure
173+
cockroachdb/cockroach:v24.1.0 start-single-node --insecure
174174
docker start cockroach
175175
name: Start CockroachDB
176176
- uses: ory/ci/checkout@master

consent/test/manager_test_helpers.go

+2-2
Original file line numberDiff line numberDiff line change
@@ -744,8 +744,8 @@ func ManagerTests(deps Deps, m consent.Manager, clientManager client.Manager, fo
744744
})
745745
}
746746

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

751751
t.Run("case=list-used-consent-requests", func(t *testing.T) {

internal/driver.go

+5-8
Original file line numberDiff line numberDiff line change
@@ -9,19 +9,16 @@ import (
99
"testing"
1010

1111
"github.com/go-jose/go-jose/v3"
12-
13-
"github.com/ory/x/configx"
14-
1512
"github.com/stretchr/testify/require"
1613

17-
"github.com/ory/hydra/v2/x"
18-
"github.com/ory/x/contextx"
19-
"github.com/ory/x/sqlcon/dockertest"
20-
2114
"github.com/ory/hydra/v2/driver"
2215
"github.com/ory/hydra/v2/driver/config"
2316
"github.com/ory/hydra/v2/jwk"
17+
"github.com/ory/hydra/v2/x"
18+
"github.com/ory/x/configx"
19+
"github.com/ory/x/contextx"
2420
"github.com/ory/x/logrusx"
21+
"github.com/ory/x/sqlcon/dockertest"
2522
)
2623

2724
func resetConfig(p *config.DefaultProvider) {
@@ -87,7 +84,7 @@ func ConnectToPG(t testing.TB) string {
8784
}
8885

8986
func ConnectToCRDB(t testing.TB) string {
90-
return dockertest.RunTestCockroachDBWithVersion(t, "v22.1.2")
87+
return dockertest.RunTestCockroachDBWithVersion(t, "v24.1.0")
9188
}
9289

9390
func ConnectDatabases(t *testing.T, migrate bool, ctxer contextx.Contextualizer) (pg, mysql, crdb driver.Registry, clean func(*testing.T)) {

internal/httpclient/go.sum

+347
Large diffs are not rendered by default.
Original file line numberDiff line numberDiff line change
@@ -1 +1 @@
1-
ALTER TABLE hydra_client ALTER PRIMARY KEY USING COLUMNS (id, nid) USING HASH;
1+
ALTER TABLE hydra_client ALTER PRIMARY KEY USING COLUMNS (id, nid);

persistence/sql/persister_consent.go

+39-38
Original file line numberDiff line numberDiff line change
@@ -12,21 +12,18 @@ import (
1212

1313
"github.com/gobuffalo/pop/v6"
1414
"github.com/gofrs/uuid"
15-
16-
"github.com/ory/hydra/v2/oauth2/flowctx"
17-
"github.com/ory/x/otelx"
18-
"github.com/ory/x/sqlxx"
19-
20-
"github.com/ory/x/errorsx"
21-
2215
"github.com/pkg/errors"
2316

2417
"github.com/ory/fosite"
2518
"github.com/ory/hydra/v2/client"
2619
"github.com/ory/hydra/v2/consent"
2720
"github.com/ory/hydra/v2/flow"
21+
"github.com/ory/hydra/v2/oauth2/flowctx"
2822
"github.com/ory/hydra/v2/x"
23+
"github.com/ory/x/errorsx"
24+
"github.com/ory/x/otelx"
2925
"github.com/ory/x/sqlcon"
26+
"github.com/ory/x/sqlxx"
3027
)
3128

3229
var _ consent.Manager = &Persister{}
@@ -51,43 +48,47 @@ func (p *Persister) revokeConsentSession(whereStmt string, whereArgs ...interfac
5148
if err := p.QueryWithNetwork(ctx).
5249
Where(whereStmt, whereArgs...).
5350
Select("consent_challenge_id").
54-
All(&fs); err != nil {
55-
if errors.Is(err, sql.ErrNoRows) {
56-
return errorsx.WithStack(x.ErrNotFound)
57-
}
58-
51+
All(&fs); errors.Is(err, sql.ErrNoRows) {
52+
return errorsx.WithStack(x.ErrNotFound)
53+
} else if err != nil {
5954
return sqlcon.HandleError(err)
6055
}
6156

62-
var count int
57+
ids := make([]interface{}, 0, len(fs))
58+
nid := p.NetworkID(ctx)
6359
for _, f := range fs {
64-
if err := p.RevokeAccessToken(ctx, f.ConsentChallengeID.String()); errors.Is(err, fosite.ErrNotFound) {
65-
// do nothing
66-
} else if err != nil {
67-
return err
68-
}
69-
70-
if err := p.RevokeRefreshToken(ctx, f.ConsentChallengeID.String()); errors.Is(err, fosite.ErrNotFound) {
71-
// do nothing
72-
} else if err != nil {
73-
return err
74-
}
75-
76-
localCount, err := c.RawQuery("DELETE FROM hydra_oauth2_flow WHERE consent_challenge_id = ? AND nid = ?", f.ConsentChallengeID, p.NetworkID(ctx)).ExecWithCount()
77-
if err != nil {
78-
if errors.Is(err, sql.ErrNoRows) {
79-
return errorsx.WithStack(x.ErrNotFound)
80-
}
81-
return sqlcon.HandleError(err)
82-
}
83-
84-
// If there are no sessions to revoke we should return an error to indicate to the caller
85-
// that the request failed.
86-
count += localCount
60+
ids = append(ids, f.ConsentChallengeID.String())
61+
}
62+
63+
if len(ids) == 0 {
64+
return nil
65+
}
66+
67+
if err := p.QueryWithNetwork(ctx).
68+
Where("nid = ?", nid).
69+
Where("request_id IN (?)", ids...).
70+
Delete(&OAuth2RequestSQL{Table: sqlTableAccess}); errors.Is(err, fosite.ErrNotFound) {
71+
// do nothing
72+
} else if err != nil {
73+
return err
8774
}
8875

89-
if count == 0 {
76+
if err := p.QueryWithNetwork(ctx).
77+
Where("nid = ?", nid).
78+
Where("request_id IN (?)", ids...).
79+
Delete(&OAuth2RequestSQL{Table: sqlTableRefresh}); errors.Is(err, fosite.ErrNotFound) {
80+
// do nothing
81+
} else if err != nil {
82+
return err
83+
}
84+
85+
if err := p.QueryWithNetwork(ctx).
86+
Where("nid = ?", nid).
87+
Where("consent_challenge_id IN (?)", ids...).
88+
Delete(new(flow.Flow)); errors.Is(err, sql.ErrNoRows) {
9089
return errorsx.WithStack(x.ErrNotFound)
90+
} else if err != nil {
91+
return sqlcon.HandleError(err)
9192
}
9293

9394
return nil
@@ -642,7 +643,7 @@ SELECT DISTINCT c.* FROM hydra_client as c
642643
JOIN hydra_oauth2_flow as f ON (c.id = f.client_id AND c.nid = f.nid)
643644
WHERE
644645
f.subject=? AND
645-
c.%schannel_logout_uri!='' AND
646+
c.%schannel_logout_uri != '' AND
646647
c.%schannel_logout_uri IS NOT NULL AND
647648
f.login_session_id = ? AND
648649
f.nid = ? AND

persistence/sql/persister_nid_test.go

+1-1
Original file line numberDiff line numberDiff line change
@@ -1834,7 +1834,7 @@ func (s *PersisterTestSuite) TestRevokeSubjectClientConsentSession() {
18341834

18351835
actual := flow.Flow{}
18361836

1837-
require.Error(t, r.Persister().RevokeSubjectClientConsentSession(s.t2, "sub", client.ID))
1837+
require.NoError(t, r.Persister().RevokeSubjectClientConsentSession(s.t2, "sub", client.ID), "should not error if nothing was found")
18381838
require.NoError(t, r.Persister().Connection(context.Background()).Find(&actual, f.ID))
18391839
require.NoError(t, r.Persister().RevokeSubjectClientConsentSession(s.t1, "sub", client.ID))
18401840
require.Error(t, r.Persister().Connection(context.Background()).Find(&actual, f.ID))

quickstart-cockroach.yml

-1
Original file line numberDiff line numberDiff line change
@@ -9,7 +9,6 @@
99
# endpoint can only be used if you follow the steps in the tutorial. #
1010
# #
1111
###########################################################################
12-
version: "3.7"
1312
services:
1413
hydra-migrate:
1514
environment:

quickstart-cors.yml

-3
Original file line numberDiff line numberDiff line change
@@ -9,9 +9,6 @@
99
# endpoint can only be used if you follow the steps in the tutorial. #
1010
# #
1111
###########################################################################
12-
13-
version: "3.7"
14-
1512
services:
1613
hydra:
1714
environment:

quickstart-debug.yml

-3
Original file line numberDiff line numberDiff line change
@@ -9,9 +9,6 @@
99
# endpoint can only be used if you follow the steps in the tutorial. #
1010
# #
1111
###########################################################################
12-
13-
version: "3.7"
14-
1512
services:
1613
hydra:
1714
environment:

quickstart-hsm.yml

-3
Original file line numberDiff line numberDiff line change
@@ -9,9 +9,6 @@
99
# endpoint can only be used if you follow the steps in the tutorial. #
1010
# #
1111
###########################################################################
12-
13-
version: "3.7"
14-
1512
services:
1613
hydra:
1714
build:

quickstart-jwt.yml

-3
Original file line numberDiff line numberDiff line change
@@ -9,9 +9,6 @@
99
# endpoint can only be used if you follow the steps in the tutorial. #
1010
# #
1111
###########################################################################
12-
13-
version: "3.7"
14-
1512
services:
1613
hydra:
1714
environment:

quickstart-mysql.yml

-1
Original file line numberDiff line numberDiff line change
@@ -9,7 +9,6 @@
99
# endpoint can only be used if you follow the steps in the tutorial. #
1010
# #
1111
###########################################################################
12-
version: "3.7"
1312
services:
1413
hydra-migrate:
1514
environment:

quickstart-postgres.yml

-1
Original file line numberDiff line numberDiff line change
@@ -9,7 +9,6 @@
99
# endpoint can only be used if you follow the steps in the tutorial. #
1010
# #
1111
###########################################################################
12-
version: "3.7"
1312
services:
1413
hydra-migrate:
1514
environment:

quickstart-prometheus.yml

-3
Original file line numberDiff line numberDiff line change
@@ -9,9 +9,6 @@
99
# endpoint can only be used if you follow the steps in the tutorial. #
1010
# #
1111
###########################################################################
12-
13-
version: "3.7"
14-
1512
services:
1613
prometheus:
1714
image: prom/prometheus:v2.12.0

quickstart-tracing.yml

-3
Original file line numberDiff line numberDiff line change
@@ -9,9 +9,6 @@
99
# endpoint can only be used if you follow the steps in the tutorial. #
1010
# #
1111
###########################################################################
12-
13-
version: "3.7"
14-
1512
services:
1613
hydra:
1714
depends_on:

quickstart.yml

-1
Original file line numberDiff line numberDiff line change
@@ -9,7 +9,6 @@
99
# endpoint can only be used if you follow the steps in the tutorial. #
1010
# #
1111
###########################################################################
12-
version: "3.7"
1312
services:
1413
hydra:
1514
image: oryd/hydra:v2.2.0

0 commit comments

Comments
 (0)