Skip to content

Commit

Permalink
feat(consent)!: Track handled_at for consent requests (#1689)
Browse files Browse the repository at this point in the history
This patch adds a feature where handling (accepting or rejecting) a consent request causes a time stamp (`handled_at`) to be updated.

This patch includes schema changes that required `hydra migrate sql` to be applied.

Closes #1684

Co-authored-by: Marco Hutzsch <[email protected]>
  • Loading branch information
DennisPattmann5012 and marcohutzsch1234 authored Feb 3, 2020
1 parent f11d143 commit d9308fa
Show file tree
Hide file tree
Showing 10 changed files with 147 additions and 1 deletion.
2 changes: 2 additions & 0 deletions consent/handler.go
Original file line number Diff line number Diff line change
Expand Up @@ -553,6 +553,7 @@ func (h *Handler) AcceptConsentRequest(w http.ResponseWriter, r *http.Request, p

p.Challenge = challenge
p.RequestedAt = cr.RequestedAt
p.HandledAt = time.Now().UTC()

hr, err := h.r.ConsentManager().HandleConsentRequest(r.Context(), challenge, &p)
if err != nil {
Expand Down Expand Up @@ -633,6 +634,7 @@ func (h *Handler) RejectConsentRequest(w http.ResponseWriter, r *http.Request, p
Error: &p,
Challenge: challenge,
RequestedAt: hr.RequestedAt,
HandledAt: time.Now().UTC(),
})
if err != nil {
h.r.Writer().WriteError(w, r, errors.WithStack(err))
Expand Down
5 changes: 4 additions & 1 deletion consent/manager_test_helpers.go
Original file line number Diff line number Diff line change
Expand Up @@ -88,7 +88,8 @@ func MockConsentRequest(key string, remember bool, rememberFor int, hasError boo
GrantedScope: []string{"scopea" + key, "scopeb" + key},
GrantedAudience: []string{"auda" + key, "audb" + key},
Error: err,
// WasUsed: true,
HandledAt: time.Now().UTC(),
//WasUsed: true,
}

return c, h
Expand Down Expand Up @@ -187,6 +188,7 @@ func SaneMockHandleConsentRequest(t *testing.T, m Manager, c *ConsentRequest, au
GrantedAudience: []string{"auda", "audb"},
Error: rde,
WasUsed: false,
HandledAt: time.Now().UTC().Add(-time.Minute),
}

_, err := m.HandleConsentRequest(context.Background(), c.Challenge, h)
Expand Down Expand Up @@ -418,6 +420,7 @@ func ManagerTests(m Manager, clientManager client.Manager, fositeManager x.Fosit

got1, err = m.HandleConsentRequest(context.TODO(), "challenge"+tc.key, h)
require.NoError(t, err)
require.Equal(t, time.Now().UTC().Round(time.Minute), h.HandledAt.Round(time.Minute))
compareConsentRequest(t, c, got1)

_, err = m.HandleConsentRequest(context.TODO(), "challenge"+tc.key, h)
Expand Down
5 changes: 5 additions & 0 deletions consent/migrations/sql/cockroach/14.sql
Original file line number Diff line number Diff line change
@@ -0,0 +1,5 @@
-- +migrate Up
ALTER TABLE hydra_oauth2_consent_request_handled ADD handled_at timestamp NULL;

-- +migrate Down
ALTER TABLE hydra_oauth2_consent_request_handled DROP COLUMN handled_at;
5 changes: 5 additions & 0 deletions consent/migrations/sql/shared/14.sql
Original file line number Diff line number Diff line change
@@ -0,0 +1,5 @@
-- +migrate Up
ALTER TABLE hydra_oauth2_consent_request_handled ADD handled_at timestamp NULL;

-- +migrate Down
ALTER TABLE hydra_oauth2_consent_request_handled DROP COLUMN handled_at;
46 changes: 46 additions & 0 deletions consent/migrations/sql/tests/14_test.sql
Original file line number Diff line number Diff line change
@@ -0,0 +1,46 @@
-- +migrate Up
INSERT INTO hydra_client (id, allowed_cors_origins, client_name, client_secret, redirect_uris, grant_types, response_types, scope, owner, policy_uri, tos_uri, client_uri, logo_uri, contacts, client_secret_expires_at, sector_identifier_uri, jwks, jwks_uri, token_endpoint_auth_method, request_uris, request_object_signing_alg, userinfo_signed_response_alg, subject_type, audience, frontchannel_logout_uri, frontchannel_logout_session_required, post_logout_redirect_uris, backchannel_logout_uri, backchannel_logout_session_required, metadata)
VALUES
('14-client', 'http://localhost|http://google', 'some-client', 'abcdef', 'http://localhost|http://google', 'authorize_code|implicit', 'token|id_token', 'foo|bar', 'aeneas', 'http://policy', 'http://tos', 'http://client', 'http://logo', 'aeneas|foo', 0, 'http://sector', '{"keys": []}', 'http://jwks', 'none', 'http://uri1|http://uri2', 'rs256', 'rs526', 'public', 'https://www.ory.sh/api', 'http://fc-logout/', true, 'http://redir1/|http://redir2/', 'http://bc-logout/', true, '{"foo":"bar"}');

INSERT INTO
hydra_oauth2_authentication_session (id, authenticated_at, subject, remember)
VALUES
('14-login-session-id', NOW(), '14-sub', true);

INSERT INTO
hydra_oauth2_authentication_request (challenge, verifier, client_id, subject, request_url, skip, requested_scope, csrf, authenticated_at, requested_at, oidc_context, login_session_id, requested_at_audience)
VALUES
('14-challenge', '14-verifier', '14-client', '14-subject', '14-redirect', false, '14-scope', '14-csrf', NOW(), NOW(), '{}', '14-login-session-id', '14-aud');

INSERT INTO
hydra_oauth2_consent_request (challenge, verifier, client_id, subject, request_url, skip, requested_scope, csrf, authenticated_at, requested_at, oidc_context, forced_subject_identifier, login_session_id, login_challenge, requested_at_audience, acr, context)
VALUES
('14-challenge', '14-verifier', '14-client', '14-subject', '14-redirect', false, '14-scope', '14-csrf', NOW(), NOW(), '{}', '14-forced-sub', '14-login-session-id', '14-challenge', '14-aud', '14-acr', '{"foo":"bar"}');

INSERT INTO
hydra_oauth2_consent_request_handled (challenge, granted_scope, remember, remember_for, error, requested_at, session_access_token, session_id_token, authenticated_at, was_used, granted_at_audience, handled_at)
VALUES
('14-challenge', '14-scope', true, 3600, '{}', NOW(), '{}', '{}', NOW(), false, '14-aud', NOW());

INSERT INTO
hydra_oauth2_authentication_request_handled (challenge, subject, remember, remember_for, error, acr, requested_at, authenticated_at, was_used, forced_subject_identifier, context)
VALUES
('14-challenge', '14-sub', true, 3600, '{}', '1', NOW(), NOW(), false, '14-forced-sub', '{"foo":"bar"}');

INSERT INTO
hydra_oauth2_obfuscated_authentication_session (subject, client_id, subject_obfuscated)
VALUES
('14-sub', '14-client', '14-obfuscated');

INSERT INTO
hydra_oauth2_logout_request (challenge, verifier, subject, sid, client_id, request_url, redir_url, was_used, accepted, rejected, rp_initiated)
VALUES
('14-challenge', '14-verifier', '14-subject', '14-session-id', '14-client', 'https://request-url/', 'https://redirect-url', false, false, false, false);

INSERT INTO
hydra_oauth2_logout_request (challenge, verifier, subject, sid, client_id, request_url, redir_url, was_used, accepted, rejected, rp_initiated)
VALUES
('14-1-challenge', '14-1-verifier', '14-1-subject', '14-1-session-id', NULL, 'https://request-url/', 'https://redirect-url', false, false, false, false);

-- +migrate Down
4 changes: 4 additions & 0 deletions consent/sql_helper.go
Original file line number Diff line number Diff line change
Expand Up @@ -98,6 +98,7 @@ var sqlParamsConsentRequestHandled = []string{
"session_access_token",
"session_id_token",
"was_used",
"handled_at",
}
var sqlParamsConsentRequestHandledUpdate = func() []string {
p := make([]string, len(sqlParamsConsentRequestHandled))
Expand Down Expand Up @@ -369,6 +370,7 @@ type sqlHandledConsentRequest struct {
RequestedAt time.Time `db:"requested_at"`
WasUsed bool `db:"was_used"`
AuthenticatedAt *time.Time `db:"authenticated_at"`
HandledAt time.Time `db:"handled_at"`
}

func newSQLHandledConsentRequest(c *HandledConsentRequest) (*sqlHandledConsentRequest, error) {
Expand Down Expand Up @@ -414,6 +416,7 @@ func newSQLHandledConsentRequest(c *HandledConsentRequest) (*sqlHandledConsentRe
RequestedAt: c.RequestedAt,
WasUsed: c.WasUsed,
AuthenticatedAt: toMySQLDateHack(c.AuthenticatedAt),
HandledAt: c.HandledAt,
}, nil
}

Expand Down Expand Up @@ -451,6 +454,7 @@ func (s *sqlHandledConsentRequest) toHandledConsentRequest(r *ConsentRequest) (*
Error: e,
ConsentRequest: r,
AuthenticatedAt: fromMySQLDateHack(s.AuthenticatedAt),
HandledAt: s.HandledAt,
}, nil
}

Expand Down
Loading

0 comments on commit d9308fa

Please sign in to comment.