Skip to content
New issue

Have a question about this project? Sign up for a free GitHub account to open an issue and contact its maintainers and the community.

By clicking “Sign up for GitHub”, you agree to our terms of service and privacy statement. We’ll occasionally send you account related emails.

Already on GitHub? Sign in to your account

refactor(client): Reduce SQL boilerplate code #1758

Merged
merged 21 commits into from
Mar 14, 2020
Prev Previous commit
Next Next commit
u
  • Loading branch information
aeneasr committed Mar 14, 2020
commit e2af079a5c7f463a7f256aebb0562b5287114a6d
4 changes: 2 additions & 2 deletions consent/manager_memory.go
Original file line number Diff line number Diff line change
Expand Up @@ -472,7 +472,7 @@ func (m *MemoryManager) ListUserAuthenticatedClientsWithFrontChannelLogout(ctx c
for _, cr := range m.consentRequests {
if cr.Subject == subject &&
len(cr.Client.FrontChannelLogoutURI) > 0 &&
cr.LoginSessionID == sid &&
cr.LoginSessionID.String() == sid &&
!preventDupes[cr.Client.GetID()] {

rs = append(rs, *cr.Client)
Expand All @@ -491,7 +491,7 @@ func (m *MemoryManager) ListUserAuthenticatedClientsWithBackChannelLogout(ctx co
var rs []client.Client
for _, cr := range m.consentRequests {
if cr.Subject == subject &&
cr.LoginSessionID == sid &&
cr.LoginSessionID.String() == sid &&
len(cr.Client.BackChannelLogoutURI) > 0 &&
!(clientsMap[cr.Client.GetID()]) {
rs = append(rs, *cr.Client)
Expand Down
14 changes: 5 additions & 9 deletions consent/manager_sql.go
Original file line number Diff line number Diff line change
Expand Up @@ -220,25 +220,20 @@ func (m *SQLManager) GetForcedObfuscatedLoginSession(ctx context.Context, client
}

func (m *SQLManager) CreateConsentRequest(ctx context.Context, c *ConsentRequest) error {
d, err := newSQLConsentRequest(c)
if err != nil {
return err
}

/* #nosec G201 - sqlParamsConsentRequest is "constant" array */
if _, err := m.DB.NamedExecContext(ctx, fmt.Sprintf(
"INSERT INTO hydra_oauth2_consent_request (%s) VALUES (%s)",
strings.Join(sqlParamsConsentRequest, ", "),
":"+strings.Join(sqlParamsConsentRequest, ", :"),
), d); err != nil {
), c.prepareSQL()); err != nil {
return sqlcon.HandleError(err)
}

return nil
}

func (m *SQLManager) GetConsentRequest(ctx context.Context, challenge string) (*ConsentRequest, error) {
var d sqlConsentRequest
var d ConsentRequest
err := m.DB.GetContext(ctx, &d, m.DB.Rebind("SELECT r.*, COALESCE(hr.was_used, false) as was_handled FROM hydra_oauth2_consent_request r "+
"LEFT JOIN hydra_oauth2_consent_request_handled hr ON r.challenge = hr.challenge WHERE r.challenge=?"), challenge)
if err != nil {
Expand All @@ -248,12 +243,13 @@ func (m *SQLManager) GetConsentRequest(ctx context.Context, challenge string) (*
return nil, sqlcon.HandleError(err)
}

c, err := m.r.ClientManager().GetConcreteClient(ctx, d.Client)
c, err := m.r.ClientManager().GetConcreteClient(ctx, d.ClientID)
if err != nil {
return nil, err
}

return d.toConsentRequest(c)
d.Client = c
return &d,nil
}

func (m *SQLManager) CreateLoginRequest(ctx context.Context, c *LoginRequest) error {
Expand Down
16 changes: 8 additions & 8 deletions consent/manager_test_helpers.go
Original file line number Diff line number Diff line change
Expand Up @@ -52,16 +52,16 @@ func MockConsentRequest(key string, remember bool, rememberFor int, hasError boo
},
Client: &client.Client{ClientID: "fk-client-" + key},
RequestURL: "https://request-url/path" + key,
LoginChallenge: "fk-login-challenge-" + key,
LoginSessionID: "fk-login-session-" + key,
LoginChallenge: sqlxx.NullString("fk-login-challenge-" + key),
LoginSessionID: sqlxx.NullString("fk-login-session-" + key),
ForceSubjectIdentifier: "forced-subject",
SubjectIdentifier: "forced-subject",
Verifier: "verifier" + key,
CSRF: "csrf" + key,
ACR: "1",
AuthenticatedAt: time.Now().UTC().Add(-time.Hour),
AuthenticatedAt: sqlxx.NullTime(time.Now().UTC().Add(-time.Hour)),
RequestedAt: time.Now().UTC().Add(-time.Hour),
Context: map[string]interface{}{"foo": "bar" + key},
Context: x.JSONRawMessage(`{"foo": "bar` + key + `"}`),
}

var err *RequestDeniedError
Expand Down Expand Up @@ -212,14 +212,14 @@ func SaneMockConsentRequest(t *testing.T, m Manager, ar *LoginRequest, skip bool
},
Client: ar.Client,
RequestURL: "https://request-url/path",
LoginChallenge: ar.Challenge,
LoginSessionID: string(ar.SessionID),
LoginChallenge: sqlxx.NullString(ar.Challenge),
LoginSessionID: ar.SessionID,
ForceSubjectIdentifier: "forced-subject",
SubjectIdentifier: "forced-subject",
ACR: "1",
AuthenticatedAt: time.Now().UTC().Add(-time.Hour),
AuthenticatedAt: sqlxx.NullTime(time.Now().UTC().Add(-time.Hour)),
RequestedAt: time.Now().UTC().Add(-time.Hour),
Context: map[string]interface{}{"foo": "bar"},
Context: x.JSONRawMessage(`{"foo": "bar"}`),

Challenge: uuid.New().String(),
Verifier: uuid.New().String(),
Expand Down
117 changes: 1 addition & 116 deletions consent/sql_helper.go
Original file line number Diff line number Diff line change
Expand Up @@ -32,8 +32,6 @@ import (

"github.com/ory/x/dbal"
"github.com/ory/x/stringsx"

"github.com/ory/hydra/client"
)

var Migrations = map[string]*dbal.PackrMigrationSource{
Expand Down Expand Up @@ -130,31 +128,6 @@ var sqlParamsLogoutRequest = []string{
"rp_initiated",
}

type sqlAuthenticationRequest struct {
OpenIDConnectContext string `db:"oidc_context"`
Client string `db:"client_id"`
Subject string `db:"subject"`
RequestURL string `db:"request_url"`
Skip bool `db:"skip"`
Challenge string `db:"challenge"`
RequestedScope string `db:"requested_scope"`
RequestedAudience sql.NullString `db:"requested_at_audience"`
Verifier string `db:"verifier"`
CSRF string `db:"csrf"`
AuthenticatedAt sql.NullTime `db:"authenticated_at"`
RequestedAt time.Time `db:"requested_at"`
LoginSessionID sql.NullString `db:"login_session_id"`
Context string `db:"context"`
WasHandled bool `db:"was_handled"`
}

type sqlConsentRequest struct {
sqlAuthenticationRequest
LoginChallenge sql.NullString `db:"login_challenge"`
ACR string `db:"acr"`
ForcedSubjectIdentifier string `db:"forced_subject_identifier"`
}

func toMySQLDateHack(t time.Time) sql.NullTime {
if t.IsZero() {
return sql.NullTime{}
Expand All @@ -169,89 +142,6 @@ func fromMySQLDateHack(t sql.NullTime) time.Time {
return time.Time{}
}

func newSQLConsentRequest(c *ConsentRequest) (*sqlConsentRequest, error) {
oidc, err := json.Marshal(c.OpenIDConnectContext)
if err != nil {
return nil, errors.WithStack(err)
}

var sessionID sql.NullString
if len(c.LoginSessionID) > 0 {
sessionID = sql.NullString{
Valid: true,
String: c.LoginSessionID,
}
}

if c.Context == nil {
c.Context = map[string]interface{}{}
}

context, err := json.Marshal(c.Context)
if err != nil {
return nil, errors.WithStack(err)
}

return &sqlConsentRequest{
sqlAuthenticationRequest: sqlAuthenticationRequest{
OpenIDConnectContext: string(oidc),
Client: c.Client.GetID(),
Subject: c.Subject,
RequestURL: c.RequestURL,
Skip: c.Skip,
Challenge: c.Challenge,
RequestedScope: strings.Join(c.RequestedScope, "|"),
RequestedAudience: sql.NullString{Valid: true, String: strings.Join(c.RequestedAudience, "|")},
Verifier: c.Verifier,
CSRF: c.CSRF,
AuthenticatedAt: toMySQLDateHack(c.AuthenticatedAt),
RequestedAt: c.RequestedAt,
LoginSessionID: sessionID,
Context: string(context),
},
LoginChallenge: sql.NullString{Valid: true, String: c.LoginChallenge},
ForcedSubjectIdentifier: c.ForceSubjectIdentifier,
ACR: c.ACR,
}, nil
}

func (s *sqlConsentRequest) toConsentRequest(client *client.Client) (*ConsentRequest, error) {
var oidc OpenIDConnectContext
var context map[string]interface{}
if err := json.Unmarshal([]byte(s.OpenIDConnectContext), &oidc); err != nil {
return nil, errors.WithStack(err)
}

if s.Context == "" {
s.Context = "{}"
}

if err := json.Unmarshal([]byte(s.Context), &context); err != nil {
return nil, errors.WithStack(err)
}

return &ConsentRequest{
OpenIDConnectContext: &oidc,
Client: client,
Subject: s.Subject,
RequestURL: s.RequestURL,
Skip: s.Skip,
Challenge: s.Challenge,
RequestedScope: stringsx.Splitx(s.RequestedScope, "|"),
RequestedAudience: stringsx.Splitx(s.RequestedAudience.String, "|"),
Verifier: s.Verifier,
CSRF: s.CSRF,
AuthenticatedAt: fromMySQLDateHack(s.AuthenticatedAt),
ForceSubjectIdentifier: s.ForcedSubjectIdentifier,
RequestedAt: s.RequestedAt,
WasHandled: s.WasHandled,
LoginSessionID: s.LoginSessionID.String,
LoginChallenge: s.LoginChallenge.String,
Context: context,
ACR: s.ACR,
}, nil
}

type sqlHandledConsentRequest struct {
GrantedScope string `db:"granted_scope"`
GrantedAudience sql.NullString `db:"granted_at_audience"`
Expand Down Expand Up @@ -411,11 +301,6 @@ func (s *sqlHandledLoginRequest) toHandledLoginRequest(a *LoginRequest) (*Handle
}
}

var context map[string]interface{}
if err := json.Unmarshal([]byte(s.Context), &context); err != nil {
return nil, errors.WithStack(err)
}

return &HandledLoginRequest{
ForceSubjectIdentifier: s.ForceSubjectIdentifier,
RememberFor: s.RememberFor,
Expand All @@ -426,7 +311,7 @@ func (s *sqlHandledLoginRequest) toHandledLoginRequest(a *LoginRequest) (*Handle
ACR: s.ACR,
Error: e,
LoginRequest: a,
Context: context,
Context: json.RawMessage(s.Context),
Subject: s.Subject,
AuthenticatedAt: fromMySQLDateHack(s.AuthenticatedAt),
}, nil
Expand Down
15 changes: 5 additions & 10 deletions consent/sql_helper_test.go
Original file line number Diff line number Diff line change
Expand Up @@ -21,6 +21,7 @@
package consent

import (
"encoding/json"
"testing"
"time"

Expand All @@ -30,6 +31,7 @@ import (
"github.com/ory/x/sqlxx"

"github.com/ory/hydra/client"
"github.com/ory/hydra/x"
)

func TestMySQLHack(t *testing.T) {
Expand Down Expand Up @@ -79,7 +81,7 @@ func TestSQLAuthenticationConverter(t *testing.T) {
ForceSubjectIdentifier: "foo-id",
ACR: "acr",
WasUsed: true,
Context: map[string]interface{}{"foo": "bar"},
Context: json.RawMessage(`{"foo":"bar"}`),
}

b1, err := newSQLHandledLoginRequest(b)
Expand Down Expand Up @@ -112,10 +114,10 @@ func TestSQLConsentConverter(t *testing.T) {
RequestedAudience: []string{"auda", "audb"},
Verifier: "verifier",
CSRF: "csrf",
AuthenticatedAt: time.Now().UTC().Add(-time.Minute),
AuthenticatedAt: sqlxx.NullTime(time.Now().UTC().Add(-time.Minute)),
LoginChallenge: "login-challenge",
LoginSessionID: "login-session-id",
Context: map[string]interface{}{},
Context: x.JSONRawMessage(`{}`),
}

b := &HandledConsentRequest{
Expand All @@ -140,16 +142,9 @@ func TestSQLConsentConverter(t *testing.T) {
},
}

a1, err := newSQLConsentRequest(a)
require.NoError(t, err)

b1, err := newSQLHandledConsentRequest(b)
require.NoError(t, err)

a2, err := a1.toConsentRequest(a.Client)
require.NoError(t, err)
assert.EqualValues(t, a, a2)

b2, err := b1.toHandledConsentRequest(a)
require.NoError(t, err)
assert.EqualValues(t, b, b2)
Expand Down
12 changes: 6 additions & 6 deletions consent/strategy_default.go
Original file line number Diff line number Diff line change
Expand Up @@ -540,13 +540,13 @@ func (s *DefaultStrategy) forwardConsentRequest(w http.ResponseWriter, r *http.R
Subject: as.Subject,
Client: sanitizeClientFromRequest(ar),
RequestURL: as.LoginRequest.RequestURL,
AuthenticatedAt: as.AuthenticatedAt,
AuthenticatedAt: sqlxx.NullTime(as.AuthenticatedAt),
RequestedAt: as.RequestedAt,
ForceSubjectIdentifier: as.ForceSubjectIdentifier,
OpenIDConnectContext: as.LoginRequest.OpenIDConnectContext,
LoginSessionID: as.LoginRequest.SessionID.String(),
LoginChallenge: as.LoginRequest.Challenge,
Context: as.Context,
LoginSessionID: as.LoginRequest.SessionID,
LoginChallenge: sqlxx.NullString(as.LoginRequest.Challenge),
Context: x.JSONRawMessage(as.Context),
},
); err != nil {
return errors.WithStack(err)
Expand Down Expand Up @@ -582,7 +582,7 @@ func (s *DefaultStrategy) verifyConsent(w http.ResponseWriter, r *http.Request,
return nil, errors.WithStack(session.Error.toRFCError())
}

if session.ConsentRequest.AuthenticatedAt.IsZero() {
if time.Time(session.ConsentRequest.AuthenticatedAt).IsZero() {
return nil, errors.WithStack(fosite.ErrServerError.WithDebug("The authenticatedAt value was not set."))
}

Expand All @@ -608,7 +608,7 @@ func (s *DefaultStrategy) verifyConsent(w http.ResponseWriter, r *http.Request,
}

session.ConsentRequest.SubjectIdentifier = pw
session.AuthenticatedAt = session.ConsentRequest.AuthenticatedAt
session.AuthenticatedAt = time.Time(session.ConsentRequest.AuthenticatedAt)
return session, nil
}

Expand Down
3 changes: 2 additions & 1 deletion consent/strategy_default_test.go
Original file line number Diff line number Diff line change
Expand Up @@ -38,6 +38,7 @@ import (

jwtgo "github.com/dgrijalva/jwt-go"
"github.com/julienschmidt/httprouter"
"github.com/ory/x/sqlxx"
"github.com/pborman/uuid"
"github.com/pkg/errors"
"github.com/stretchr/testify/assert"
Expand Down Expand Up @@ -476,7 +477,7 @@ func TestStrategyLogout(t *testing.T) {
}))
servers[k] = httptest.NewServer(n)
c, hc := MockConsentRequest(uuid.New(), true, 100, false, false, true)
c.LoginSessionID = tc.sessionID
c.LoginSessionID = sqlxx.NullString(tc.sessionID)
c.Client.BackChannelLogoutURI = servers[k].URL
c.Subject = tc.subject
require.NoError(t, reg.ConsentManager().CreateConsentRequest(context.Background(), c))
Expand Down
Loading