diff --git a/go.mod b/go.mod index 0131cb11494..79a167af78e 100644 --- a/go.mod +++ b/go.mod @@ -22,7 +22,7 @@ require ( github.com/gobuffalo/pop/v5 v5.3.1 github.com/gobuffalo/x v0.0.0-20181007152206-913e47c59ca7 github.com/gobwas/glob v0.2.3 - github.com/golang/mock v1.4.3 + github.com/golang/mock v1.4.4 github.com/google/uuid v1.1.1 github.com/gorilla/securecookie v1.1.1 github.com/gorilla/sessions v1.2.0 @@ -39,7 +39,7 @@ require ( github.com/olekukonko/tablewriter v0.0.1 github.com/ory/analytics-go/v4 v4.0.1 github.com/ory/cli v0.0.35 - github.com/ory/fosite v0.36.0 + github.com/ory/fosite v0.39.0 github.com/ory/go-acc v0.2.6 github.com/ory/graceful v0.1.1 github.com/ory/herodot v0.9.1 @@ -54,14 +54,13 @@ require ( github.com/sawadashota/encrypta v0.0.2 github.com/sirupsen/logrus v1.6.0 github.com/spf13/cobra v1.0.0 - github.com/sqs/goreturns v0.0.0-20181028201513-538ac6014518 // indirect github.com/stretchr/testify v1.6.1 github.com/tidwall/gjson v1.6.7 github.com/toqueteos/webbrowser v1.2.0 github.com/uber/jaeger-lib v2.4.0+incompatible // indirect github.com/urfave/negroni v1.0.0 go.uber.org/automaxprocs v1.3.0 - golang.org/x/crypto v0.0.0-20200709230013-948cd5f35899 + golang.org/x/crypto v0.0.0-20201203163018-be400aefbc4c golang.org/x/lint v0.0.0-20200302205851-738671d3881b // indirect golang.org/x/oauth2 v0.0.0-20200107190931-bf48bf16ab8d golang.org/x/tools v0.0.0-20201019175715-b894a3290fff diff --git a/go.sum b/go.sum index e07ff5d697a..b4d0f32ba4e 100644 --- a/go.sum +++ b/go.sum @@ -559,8 +559,8 @@ github.com/golang/groupcache v0.0.0-20190702054246-869f871628b6/go.mod h1:cIg4er github.com/golang/mock v1.1.1/go.mod h1:oTYuIxOrZwtPieC+H1uAHpcLFnEyAGVDL/k47Jfbm0A= github.com/golang/mock v1.2.0/go.mod h1:oTYuIxOrZwtPieC+H1uAHpcLFnEyAGVDL/k47Jfbm0A= github.com/golang/mock v1.3.1/go.mod h1:sBzyDLLjw3U8JLTeZvSv8jJB+tU5PVekmnlKIyFUx0Y= -github.com/golang/mock v1.4.3 h1:GV+pQPG/EUUbkh47niozDcADz6go/dUwhVzdUQHIVRw= -github.com/golang/mock v1.4.3/go.mod h1:UOMv5ysSaYNkG+OFQykRIcU/QvvxJf3p21QfJ2Bt3cw= +github.com/golang/mock v1.4.4 h1:l75CXGRSwbaYNpl/Z2X1XIIAMSCquvXgpVZDhwEIJsc= +github.com/golang/mock v1.4.4/go.mod h1:l3mdAwkq5BuhzHwde/uurv3sEJeZMXNpwsxVWU71h+4= github.com/golang/protobuf v1.1.0/go.mod h1:6lQm79b+lXiMfvg/cZm0SGofjICqVBUtrP5yJMmIC1U= github.com/golang/protobuf v1.2.0/go.mod h1:6lQm79b+lXiMfvg/cZm0SGofjICqVBUtrP5yJMmIC1U= github.com/golang/protobuf v1.3.1/go.mod h1:6lQm79b+lXiMfvg/cZm0SGofjICqVBUtrP5yJMmIC1U= @@ -957,8 +957,8 @@ github.com/ory/dockertest v3.3.5+incompatible/go.mod h1:1vX4m9wsvi00u5bseYwXaSnh github.com/ory/dockertest/v3 v3.5.4 h1:rYijlJuraj8D4OgC1DpYpCV8SGXrkviT3RVrjFy7OFc= github.com/ory/dockertest/v3 v3.5.4/go.mod h1:J8ZUbNB2FOhm1cFZW9xBpDsODqsSWcyYgtJYVPcnF70= github.com/ory/fosite v0.29.0/go.mod h1:0atSZmXO7CAcs6NPMI/Qtot8tmZYj04Nddoold4S2h0= -github.com/ory/fosite v0.36.0 h1:6XGd9sE0h/y6XJx3L3iRm/UFPHVEnARQch0YFxvxziQ= -github.com/ory/fosite v0.36.0/go.mod h1:NE15bS1ya8E4J8VmminFY+nsZdoBQu+5/vGF2ELvDsY= +github.com/ory/fosite v0.39.0 h1:u1Ct/ME7XYzREvufr7ehBIdq/KatjVLIYg/ABqWzprw= +github.com/ory/fosite v0.39.0/go.mod h1:37r59qkOSPueYKmaA7EHiXrDMF1B+XPN+MgkZgTRg3Y= github.com/ory/go-acc v0.0.0-20181118080137-ddc355013f90/go.mod h1:sxnvPCxChFuSmTJGj8FdMupeq1BezCiEpDjTUXQ4hf4= github.com/ory/go-acc v0.2.5/go.mod h1:4Kb/UnPcT8qRAk3IAxta+hvVapdxTLWtrr7bFLlEgpw= github.com/ory/go-acc v0.2.6 h1:YfI+L9dxI7QCtWn2RbawqO0vXhiThdXu/RgizJBbaq0= @@ -1312,8 +1312,8 @@ golang.org/x/crypto v0.0.0-20200323165209-0ec3e9974c59/go.mod h1:LzIPMQfyMNhhGPh golang.org/x/crypto v0.0.0-20200510223506-06a226fb4e37/go.mod h1:LzIPMQfyMNhhGPhUkYOs5KpL4U8rLKemX1yGLhDgUto= golang.org/x/crypto v0.0.0-20200604202706-70a84ac30bf9/go.mod h1:LzIPMQfyMNhhGPhUkYOs5KpL4U8rLKemX1yGLhDgUto= golang.org/x/crypto v0.0.0-20200622213623-75b288015ac9/go.mod h1:LzIPMQfyMNhhGPhUkYOs5KpL4U8rLKemX1yGLhDgUto= -golang.org/x/crypto v0.0.0-20200709230013-948cd5f35899 h1:DZhuSZLsGlFL4CmhA8BcRA0mnthyA/nZ00AqCUo7vHg= -golang.org/x/crypto v0.0.0-20200709230013-948cd5f35899/go.mod h1:LzIPMQfyMNhhGPhUkYOs5KpL4U8rLKemX1yGLhDgUto= +golang.org/x/crypto v0.0.0-20201203163018-be400aefbc4c h1:9HhBz5L/UjnK9XLtiZhYAdue5BVKep3PMmS2LuPDt8k= +golang.org/x/crypto v0.0.0-20201203163018-be400aefbc4c/go.mod h1:jdWPYTVW3xRLrWPugEBEK3UY2ZEsg3UU495nc5E+M+I= golang.org/x/exp v0.0.0-20180321215751-8460e604b9de/go.mod h1:CJ0aWSM057203Lf6IL+f9T1iT9GByDxfZKAQTCR3kQA= golang.org/x/exp v0.0.0-20180807140117-3d87b88a115f/go.mod h1:CJ0aWSM057203Lf6IL+f9T1iT9GByDxfZKAQTCR3kQA= golang.org/x/exp v0.0.0-20190121172915-509febef88a4/go.mod h1:CJ0aWSM057203Lf6IL+f9T1iT9GByDxfZKAQTCR3kQA= @@ -1460,7 +1460,8 @@ golang.org/x/sys v0.0.0-20200519105757-fe76b779f299/go.mod h1:h1NjWce9XRLGQEsW7w golang.org/x/sys v0.0.0-20200602225109-6fdc65e7d980/go.mod h1:h1NjWce9XRLGQEsW7wpKNCjG9DtNlClVuFLEZdDNbEs= golang.org/x/sys v0.0.0-20200720211630-cb9d2d5c5666 h1:gVCS+QOncANNPlmlO1AhlU3oxs4V9z+gTtPwIk3p2N8= golang.org/x/sys v0.0.0-20200720211630-cb9d2d5c5666/go.mod h1:h1NjWce9XRLGQEsW7wpKNCjG9DtNlClVuFLEZdDNbEs= -golang.org/x/text v0.0.0-20170915032832-14c0d48ead0c/go.mod h1:NqM8EUOU14njkJ3fqMW+pc6Ldnwhi/IjpwHt7yyuwOQ= +golang.org/x/term v0.0.0-20201117132131-f5c789dd3221 h1:/ZHdbVpdR/jk3g30/d4yUL0JU9kksj8+F/bnQUVLGDM= +golang.org/x/term v0.0.0-20201117132131-f5c789dd3221/go.mod h1:Nr5EML6q2oocZ2LXRh80K7BxOlk5/8JxuGnuhpl+muw= golang.org/x/text v0.3.0/go.mod h1:NqM8EUOU14njkJ3fqMW+pc6Ldnwhi/IjpwHt7yyuwOQ= golang.org/x/text v0.3.1-0.20180807135948-17ff2d5776d2/go.mod h1:NqM8EUOU14njkJ3fqMW+pc6Ldnwhi/IjpwHt7yyuwOQ= golang.org/x/text v0.3.2/go.mod h1:bEr9sfX3Q8Zfm5fL9x+3itogRgK3+ptLWKqgva+5dAk= @@ -1675,5 +1676,3 @@ mvdan.cc/lint v0.0.0-20170908181259-adc824a0674b/go.mod h1:2odslEg/xrtNQqCYg2/jC mvdan.cc/unparam v0.0.0-20190720180237-d51796306d8f/go.mod h1:4G1h5nDURzA3bwVMZIVpwbkw+04kSxk3rAtzlimaUJw= rsc.io/binaryregexp v0.2.0/go.mod h1:qTv7/COck+e2FymRvadv62gMdZztPaShugOCi3I+8D8= rsc.io/pdf v0.1.1/go.mod h1:n8OzWcQ6Sp37PL01nO98y4iUCRdTGarVfzxY20ICaU4= -rsc.io/quote/v3 v3.1.0/go.mod h1:yEA65RcK8LyAZtP9Kv3t0HmxON59tX3rD+tICJqUlj0= -rsc.io/sampler v1.3.0/go.mod h1:T1hPZKmBbMNahiBKFy5HrXp6adAjACjK9JXDnKaTXpA= diff --git a/oauth2/fosite_store_helpers.go b/oauth2/fosite_store_helpers.go index a6cee0e4789..e7a520d2ef6 100644 --- a/oauth2/fosite_store_helpers.go +++ b/oauth2/fosite_store_helpers.go @@ -284,11 +284,13 @@ func testHelperRevokeRefreshToken(x InternalRegistry) func(t *testing.T) { err = m.RevokeRefreshToken(ctx, reqIdTwo) require.NoError(t, err) - _, err = m.GetRefreshTokenSession(ctx, "1111", &Session{}) - assert.NotNil(t, err) + req, err := m.GetRefreshTokenSession(ctx, "1111", &Session{}) + assert.NotNil(t, req) + assert.EqualError(t, err, fosite.ErrInactiveToken.Error()) - _, err = m.GetRefreshTokenSession(ctx, "1122", &Session{}) - assert.NotNil(t, err) + req, err = m.GetRefreshTokenSession(ctx, "1122", &Session{}) + assert.NotNil(t, req) + assert.EqualError(t, err, fosite.ErrInactiveToken.Error()) } } diff --git a/oauth2/oauth2_auth_code_test.go b/oauth2/oauth2_auth_code_test.go index 0e6a098b0e6..cf1999a469b 100644 --- a/oauth2/oauth2_auth_code_test.go +++ b/oauth2/oauth2_auth_code_test.go @@ -899,16 +899,26 @@ func TestAuthCodeWithMockStrategy(t *testing.T) { assert.EqualValues(t, http.StatusUnauthorized, res.StatusCode) }) + t.Run("refreshing new refresh token should work", func(t *testing.T) { + res, err := testRefresh(t, &refreshedToken, ts.URL, false) + require.NoError(t, err) + assert.Equal(t, http.StatusOK, res.StatusCode) + + body, err := ioutil.ReadAll(res.Body) + require.NoError(t, err) + require.NoError(t, json.Unmarshal(body, &refreshedToken)) + }) + t.Run("refreshing old token should no longer work", func(t *testing.T) { res, err := testRefresh(t, token, ts.URL, false) require.NoError(t, err) - assert.Equal(t, http.StatusBadRequest, res.StatusCode) + assert.Equal(t, http.StatusUnauthorized, res.StatusCode) }) - t.Run("refreshing new refresh token should work", func(t *testing.T) { + t.Run("attempt to refresh old token should revoke new token", func(t *testing.T) { res, err := testRefresh(t, &refreshedToken, ts.URL, false) require.NoError(t, err) - assert.Equal(t, http.StatusOK, res.StatusCode) + assert.Equal(t, http.StatusUnauthorized, res.StatusCode) }) t.Run("duplicate code exchange fails", func(t *testing.T) { diff --git a/persistence/sql/persister_oauth2.go b/persistence/sql/persister_oauth2.go index 93a24ef67c4..74f84d58d88 100644 --- a/persistence/sql/persister_oauth2.go +++ b/persistence/sql/persister_oauth2.go @@ -231,15 +231,15 @@ func (p *Persister) findSessionBySignature(ctx context.Context, rawSignature str return errorsx.WithStack(fosite.ErrNotFound) } else if err != nil { return sqlcon.HandleError(err) - } else if !r.Active && table == sqlTableCode { + } else if !r.Active { fr, err = r.toRequest(ctx, session, p) if err != nil { return err - } else { + } else if table == sqlTableCode { return errorsx.WithStack(fosite.ErrInvalidatedAuthorizeCode) + } else if table == sqlTableRefresh { + return errorsx.WithStack(fosite.ErrInactiveToken) } - } else if !r.Active { - return errorsx.WithStack(fosite.ErrInactiveToken) } fr, err = r.toRequest(ctx, session, p) @@ -247,7 +247,7 @@ func (p *Persister) findSessionBySignature(ctx context.Context, rawSignature str }) } -func (p *Persister) deleteSession(ctx context.Context, signature string, table tableName) error { +func (p *Persister) deleteSessionBySignature(ctx context.Context, signature string, table tableName) error { signature = p.hashSignature(signature, table) /* #nosec G201 table is static */ @@ -257,7 +257,7 @@ func (p *Persister) deleteSession(ctx context.Context, signature string, table t Exec()) } -func (p *Persister) revokeSession(ctx context.Context, id string, table tableName) error { +func (p *Persister) deleteSessionByRequestID(ctx context.Context, id string, table tableName) error { /* #nosec G201 table is static */ if err := p.Connection(ctx).RawQuery( fmt.Sprintf("DELETE FROM %s WHERE request_id=?", OAuth2RequestSQL{Table: table}.TableName()), @@ -275,6 +275,18 @@ func (p *Persister) revokeSession(ctx context.Context, id string, table tableNam return nil } +func (p *Persister) deactivateSessionByRequestID(ctx context.Context, id string, table tableName) error { + /* #nosec G201 table is static */ + return sqlcon.HandleError( + p.Connection(ctx). + RawQuery( + fmt.Sprintf("UPDATE %s SET active=false WHERE request_id=?", OAuth2RequestSQL{Table: table}.TableName()), + id, + ). + Exec(), + ) +} + func (p *Persister) CreateAuthorizeCodeSession(ctx context.Context, signature string, requester fosite.Requester) (err error) { return p.createSession(ctx, signature, requester, sqlTableCode) } @@ -302,7 +314,7 @@ func (p *Persister) GetAccessTokenSession(ctx context.Context, signature string, } func (p *Persister) DeleteAccessTokenSession(ctx context.Context, signature string) (err error) { - return p.deleteSession(ctx, signature, sqlTableAccess) + return p.deleteSessionBySignature(ctx, signature, sqlTableAccess) } func (p *Persister) CreateRefreshTokenSession(ctx context.Context, signature string, requester fosite.Requester) (err error) { @@ -314,7 +326,7 @@ func (p *Persister) GetRefreshTokenSession(ctx context.Context, signature string } func (p *Persister) DeleteRefreshTokenSession(ctx context.Context, signature string) (err error) { - return p.deleteSession(ctx, signature, sqlTableRefresh) + return p.deleteSessionBySignature(ctx, signature, sqlTableRefresh) } func (p *Persister) CreateOpenIDConnectSession(ctx context.Context, signature string, requester fosite.Requester) error { @@ -326,7 +338,7 @@ func (p *Persister) GetOpenIDConnectSession(ctx context.Context, signature strin } func (p *Persister) DeleteOpenIDConnectSession(ctx context.Context, signature string) error { - return p.deleteSession(ctx, signature, sqlTableOpenID) + return p.deleteSessionBySignature(ctx, signature, sqlTableOpenID) } func (p *Persister) GetPKCERequestSession(ctx context.Context, signature string, session fosite.Session) (fosite.Requester, error) { @@ -338,15 +350,15 @@ func (p *Persister) CreatePKCERequestSession(ctx context.Context, signature stri } func (p *Persister) DeletePKCERequestSession(ctx context.Context, signature string) error { - return p.deleteSession(ctx, signature, sqlTablePKCE) + return p.deleteSessionBySignature(ctx, signature, sqlTablePKCE) } func (p *Persister) RevokeRefreshToken(ctx context.Context, id string) error { - return p.revokeSession(ctx, id, sqlTableRefresh) + return p.deactivateSessionByRequestID(ctx, id, sqlTableRefresh) } func (p *Persister) RevokeAccessToken(ctx context.Context, id string) error { - return p.revokeSession(ctx, id, sqlTableAccess) + return p.deleteSessionByRequestID(ctx, id, sqlTableAccess) } func (p *Persister) FlushInactiveAccessTokens(ctx context.Context, notAfter time.Time) error {