Skip to content

Commit

Permalink
e2e: Add e2e tests checking consistency (ory#1184)
Browse files Browse the repository at this point in the history
Signed-off-by: aeneasr <[email protected]>
  • Loading branch information
aeneasr authored Nov 21, 2018
1 parent 9f991f2 commit 328d617
Show file tree
Hide file tree
Showing 6 changed files with 142 additions and 41 deletions.
15 changes: 12 additions & 3 deletions consent/manager_memory.go
Original file line number Diff line number Diff line change
Expand Up @@ -91,14 +91,23 @@ func (m *MemoryManager) RevokeUserConsentSession(ctx context.Context, user strin
func (m *MemoryManager) RevokeUserClientConsentSession(ctx context.Context, user, client string) error {
m.m["handledConsentRequests"].Lock()
defer m.m["handledConsentRequests"].Unlock()
m.m["consentRequests"].Lock()
defer m.m["consentRequests"].Unlock()

var found bool
for k, c := range m.handledConsentRequests {
if c.ConsentRequest.Subject == user && (client == "" || (client != "" && c.ConsentRequest.Client.GetID() == client)) {
cr, err := m.GetConsentRequest(ctx, c.Challenge)
if err != nil {
return err
}

if cr.Subject == user &&
(client == "" ||
(client != "" && cr.Client.GetID() == client)) {
delete(m.handledConsentRequests, k)

m.m["consentRequests"].Lock()
delete(m.consentRequests, k)
m.m["consentRequests"].Unlock()

if err := m.store.RevokeAccessToken(nil, c.Challenge); errors.Cause(err) == fosite.ErrNotFound {
// do nothing
} else if err != nil {
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 @@ -393,10 +393,10 @@ func ManagerTests(m Manager, clientManager client.Manager, fositeManager pkg.Fos
_, err = m.HandleConsentRequest(context.TODO(), "challengerv2", hcr2)
require.NoError(t, err)

fositeManager.CreateAccessTokenSession(nil, "trva1", &fosite.Request{ID: "challengerv1", RequestedAt: time.Now()})
fositeManager.CreateRefreshTokenSession(nil, "rrva1", &fosite.Request{ID: "challengerv1", RequestedAt: time.Now()})
fositeManager.CreateAccessTokenSession(nil, "trva2", &fosite.Request{ID: "challengerv2", RequestedAt: time.Now()})
fositeManager.CreateRefreshTokenSession(nil, "rrva2", &fosite.Request{ID: "challengerv2", RequestedAt: time.Now()})
fositeManager.CreateAccessTokenSession(nil, "trva1", &fosite.Request{Client: cr1.Client, ID: "challengerv1", RequestedAt: time.Now()})
fositeManager.CreateRefreshTokenSession(nil, "rrva1", &fosite.Request{Client: cr1.Client, ID: "challengerv1", RequestedAt: time.Now()})
fositeManager.CreateAccessTokenSession(nil, "trva2", &fosite.Request{Client: cr2.Client, ID: "challengerv2", RequestedAt: time.Now()})
fositeManager.CreateRefreshTokenSession(nil, "rrva2", &fosite.Request{Client: cr2.Client, ID: "challengerv2", RequestedAt: time.Now()})

for i, tc := range []struct {
subject string
Expand Down Expand Up @@ -437,10 +437,10 @@ func ManagerTests(m Manager, clientManager client.Manager, fositeManager pkg.Fos
})
}

_, err = fositeManager.GetAccessTokenSession(context.TODO(), tc.at, nil)
assert.Error(t, err)
_, err = fositeManager.GetRefreshTokenSession(context.TODO(), tc.rt, nil)
assert.Error(t, err)
r, err := fositeManager.GetAccessTokenSession(context.TODO(), tc.at, nil)
assert.Error(t, err, "%+v", r)
r, err = fositeManager.GetRefreshTokenSession(context.TODO(), tc.rt, nil)
assert.Error(t, err, "%+v", r)
})
}
})
Expand Down
83 changes: 71 additions & 12 deletions oauth2/fosite_store_memory.go
Original file line number Diff line number Diff line change
Expand Up @@ -29,6 +29,7 @@ import (

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

func NewFositeMemoryStore(m client.Manager, ls time.Duration) *FositeMemoryStore {
Expand Down Expand Up @@ -68,14 +69,25 @@ func (s *FositeMemoryStore) CreateOpenIDConnectSession(_ context.Context, author
return nil
}

func (s *FositeMemoryStore) GetOpenIDConnectSession(_ context.Context, authorizeCode string, requester fosite.Requester) (fosite.Requester, error) {
func (s *FositeMemoryStore) GetOpenIDConnectSession(ctx context.Context, code string, requester fosite.Requester) (fosite.Requester, error) {
s.RLock()
defer s.RUnlock()
cl, ok := s.IDSessions[authorizeCode]
rel, ok := s.IDSessions[code]
s.RUnlock()

if !ok {
return nil, errors.Wrap(fosite.ErrNotFound, "")
}
return cl, nil

if _, err := s.GetClient(ctx, rel.GetClient().GetID()); errors.Cause(err) == sqlcon.ErrNoRows {
s.Lock()
delete(s.IDSessions, code)
s.Unlock()
return nil, err
} else if err != nil {
return nil, err
}

return rel, nil
}

func (s *FositeMemoryStore) DeleteOpenIDConnectSession(_ context.Context, authorizeCode string) error {
Expand All @@ -92,11 +104,11 @@ func (s *FositeMemoryStore) CreateAuthorizeCodeSession(_ context.Context, code s
return nil
}

func (s *FositeMemoryStore) GetAuthorizeCodeSession(_ context.Context, code string, _ fosite.Session) (fosite.Requester, error) {
func (s *FositeMemoryStore) GetAuthorizeCodeSession(ctx context.Context, code string, _ fosite.Session) (fosite.Requester, error) {
s.RLock()
defer s.RUnlock()

rel, ok := s.AuthorizeCodes[code]
s.RUnlock()

if !ok {
return nil, errors.Wrap(fosite.ErrNotFound, "")
}
Expand All @@ -105,6 +117,15 @@ func (s *FositeMemoryStore) GetAuthorizeCodeSession(_ context.Context, code stri
return rel.Requester, errors.WithStack(fosite.ErrInvalidatedAuthorizeCode)
}

if _, err := s.GetClient(ctx, rel.GetClient().GetID()); errors.Cause(err) == sqlcon.ErrNoRows {
s.Lock()
delete(s.AuthorizeCodes, code)
s.Unlock()
return nil, err
} else if err != nil {
return nil, err
}

return rel.Requester, nil
}

Expand All @@ -128,13 +149,24 @@ func (s *FositeMemoryStore) CreateAccessTokenSession(_ context.Context, signatur
return nil
}

func (s *FositeMemoryStore) GetAccessTokenSession(_ context.Context, signature string, _ fosite.Session) (fosite.Requester, error) {
func (s *FositeMemoryStore) GetAccessTokenSession(ctx context.Context, signature string, _ fosite.Session) (fosite.Requester, error) {
s.RLock()
defer s.RUnlock()
rel, ok := s.AccessTokens[signature]
s.RUnlock()

if !ok {
return nil, errors.Wrap(fosite.ErrNotFound, "")
}

if _, err := s.GetClient(ctx, rel.GetClient().GetID()); errors.Cause(err) == sqlcon.ErrNoRows {
s.Lock()
delete(s.AccessTokens, signature)
s.Unlock()
return nil, err
} else if err != nil {
return nil, err
}

return rel, nil
}

Expand All @@ -156,13 +188,24 @@ func (s *FositeMemoryStore) CreateRefreshTokenSession(_ context.Context, signatu
return nil
}

func (s *FositeMemoryStore) GetRefreshTokenSession(_ context.Context, signature string, _ fosite.Session) (fosite.Requester, error) {
func (s *FositeMemoryStore) GetRefreshTokenSession(ctx context.Context, signature string, _ fosite.Session) (fosite.Requester, error) {
s.RLock()
defer s.RUnlock()
rel, ok := s.RefreshTokens[signature]
s.RUnlock()

if !ok {
return nil, errors.Wrap(fosite.ErrNotFound, "")
}

if _, err := s.GetClient(ctx, rel.GetClient().GetID()); errors.Cause(err) == sqlcon.ErrNoRows {
s.Lock()
delete(s.RefreshTokens, signature)
s.Unlock()
return nil, err
} else if err != nil {
return nil, err
}

return rel, nil
}

Expand Down Expand Up @@ -238,19 +281,35 @@ func (s *FositeMemoryStore) FlushInactiveAccessTokens(ctx context.Context, notAf
}

func (s *FositeMemoryStore) CreatePKCERequestSession(_ context.Context, code string, req fosite.Requester) error {
s.Lock()
s.PKCES[code] = req
s.Unlock()
return nil
}

func (s *FositeMemoryStore) GetPKCERequestSession(_ context.Context, code string, _ fosite.Session) (fosite.Requester, error) {
func (s *FositeMemoryStore) GetPKCERequestSession(ctx context.Context, code string, _ fosite.Session) (fosite.Requester, error) {
s.RLock()
rel, ok := s.PKCES[code]
s.RUnlock()
if !ok {
return nil, fosite.ErrNotFound
}

if _, err := s.GetClient(ctx, rel.GetClient().GetID()); errors.Cause(err) == sqlcon.ErrNoRows {
s.Lock()
delete(s.RefreshTokens, code)
s.Unlock()
return nil, err
} else if err != nil {
return nil, err
}

return rel, nil
}

func (s *FositeMemoryStore) DeletePKCERequestSession(_ context.Context, code string) error {
s.Lock()
delete(s.PKCES, code)
s.Unlock()
return nil
}
4 changes: 3 additions & 1 deletion oauth2/handler_test.go
Original file line number Diff line number Diff line change
Expand Up @@ -84,7 +84,8 @@ var flushRequests = []*fosite.Request{
}

func TestHandlerFlushHandler(t *testing.T) {
store := oauth2.NewFositeMemoryStore(nil, lifespan)
cl := client.NewMemoryManager(&fosite.BCrypt{WorkFactor: 4})
store := oauth2.NewFositeMemoryStore(cl, lifespan)
h := &oauth2.Handler{
H: herodot.NewJSONWriter(nil),
ScopeStrategy: fosite.HierarchicScopeStrategy,
Expand All @@ -94,6 +95,7 @@ func TestHandlerFlushHandler(t *testing.T) {

for _, r := range flushRequests {
require.NoError(t, store.CreateAccessTokenSession(nil, r.ID, r))
_ = cl.CreateClient(nil, r.Client.(*client.Client))
}

r := httprouter.New()
Expand Down
45 changes: 31 additions & 14 deletions scripts/test-e2e.sh
Original file line number Diff line number Diff line change
Expand Up @@ -47,18 +47,16 @@ hydra clients create \
--scope openid,offline \
--callbacks http://127.0.0.1:5555/callback

token=$(hydra token client)
clientToken=$(hydra token client)

introspect=$(hydra token introspect "$token")

if [[ "$(echo $introspect)" =~ "false" ]]; then
if [[ $(hydra token introspect "$(echo $clientToken)") =~ "false" ]]; then
echo "Token introspection should return true"
exit 1
fi

## Authenticate but do not remember user
cookie=$(OAUTH2_EXTRA="&mockLogin=accept&mockConsent=accept" \
mock-client)
mock-client -print-cookie)
export AUTH_COOKIE=$cookie

## Must fail because prompt=none but no session was remembered
Expand All @@ -70,7 +68,7 @@ fi

# Authenticate and remember login (but not consent)
cookie=$(OAUTH2_EXTRA="&mockLogin=accept&mockConsent=accept&rememberLogin=yes" \
mock-client)
mock-client -print-cookie)
export AUTH_COOKIE=$cookie

## Must fail because prompt=none but consent was not yet stored
Expand All @@ -81,22 +79,41 @@ if OAUTH2_EXTRA="&mockLogin=accept&mockConsent=accept&prompt=none" \
fi

# Remember consent
cookie=$(OAUTH2_EXTRA="&mockLogin=accept&mockConsent=accept&rememberConsent=yes" \
$(OAUTH2_EXTRA="&mockLogin=accept&mockConsent=accept&rememberConsent=yes" \
mock-client)

## Prompt none should work now because cookie was set
OAUTH2_EXTRA="&mockLogin=accept&mockConsent=accept&prompt=none" \
mock-client
userToken=$(OAUTH2_EXTRA="&mockLogin=accept&mockConsent=accept&prompt=none" \
mock-client -print-token)

if [[ "$(hydra token introspect $userToken)" =~ "false" ]]; then
echo "Token introspection should return true for the user token"
exit 1
fi

if [[ "$(curl http://localhost:4445/oauth2/auth/sessions/consent/the-subject)" =~ "the-subject" ]]; then
echo "Consent session looks good"
else
echo "Checking consent session should show the-subject"
exit 1
fi

curl -X DELETE http://localhost:4445/oauth2/auth/sessions/consent/the-subject

if [[ "$(hydra token introspect $userToken)" =~ "true" ]]; then
echo "Token introspection should return false because the consent session was revoked"
exit 1
fi

if [[ "$(echo $introspect)" =~ "false" ]]; then
if [[ "$(hydra token introspect $clientToken)" =~ "false" ]]; then
echo "Token introspection should return true"
exit 1
fi

hydra clients delete $OAUTH2_CLIENT_ID

if [[ "$(hydra token introspect $token)" =~ "true" ]]; then
echo "Token introspection should return false"
if [[ "$(hydra token introspect $clientToken)" =~ "true" ]]; then
echo "Token introspection should return false because the client was deleted"
exit 1
fi

Expand All @@ -109,8 +126,8 @@ hydra clients create \
--scope openid,offline \
--callbacks http://127.0.0.1:5555/callback

if [[ "$(hydra token introspect $token)" =~ "true" ]]; then
echo "Token introspection should return false"
if [[ "$(hydra token introspect $clientToken)" =~ "true" ]]; then
echo "Token introspection should return false even after the client was re-created"
exit 1
fi

Expand Down
20 changes: 17 additions & 3 deletions test/mock-client/main.go
Original file line number Diff line number Diff line change
Expand Up @@ -23,6 +23,7 @@ package main
import (
"bytes"
"encoding/json"
"flag"
"fmt"
"io/ioutil"
"log"
Expand All @@ -33,7 +34,7 @@ import (
"strings"
"time"

jwt "github.com/dgrijalva/jwt-go"
"github.com/dgrijalva/jwt-go"
"golang.org/x/oauth2"

"github.com/ory/hydra/sdk/go/hydra/swagger"
Expand All @@ -50,7 +51,15 @@ type oauth2token struct {
Expiry time.Time `json:"expiry,omitempty"`
}

var printToken, printCookie bool

func init() {
flag.BoolVar(&printToken, "print-token", false, "")
flag.BoolVar(&printCookie, "print-cookie", false, "")
}

func main() {
flag.Parse()
conf := oauth2.Config{
ClientID: os.Getenv("OAUTH2_CLIENT_ID"),
ClientSecret: os.Getenv("OAUTH2_CLIENT_SECRET"),
Expand Down Expand Up @@ -93,7 +102,9 @@ func main() {

for _, c := range c.Cookies(u) {
if c.Name == "oauth2_authentication_session" {
fmt.Print(c.Value)
if printCookie {
fmt.Print(c.Value)
}
}
}

Expand All @@ -108,7 +119,10 @@ func main() {
checkTokenResponse(token)
}

refreshToken(token)
newToken := refreshToken(token)
if printToken {
fmt.Printf("%s", newToken.AccessToken)
}

// refreshing the same token twice does not work
resp, err = refreshTokenRequest(token)
Expand Down

0 comments on commit 328d617

Please sign in to comment.