Skip to content

Commit

Permalink
oidc: preview
Browse files Browse the repository at this point in the history
  • Loading branch information
aeneasr committed Mar 21, 2016
1 parent eb9153c commit ba84987
Show file tree
Hide file tree
Showing 89 changed files with 1,462 additions and 631 deletions.
31 changes: 20 additions & 11 deletions README.md
Original file line number Diff line number Diff line change
Expand Up @@ -159,7 +159,9 @@ import(
"github.com/go-errors/errors"

. "github.com/ory-am/fosite"
"github.com/ory-am/fosite/enigma"

// Import hmac strategy for enigma
enigma "github.com/ory-am/fosite/enigma/hmac"
"github.com/ory-am/fosite/handler/core/explicit"
"github.com/ory-am/fosite/handler/core/implicit"
"github.com/ory-am/fosite/handler/core/owner"
Expand All @@ -172,7 +174,7 @@ import(
)

var hmacStrategy = &strategy.HMACSHAStrategy{
Enigma: &enigma.HMACSHAEnigma{
Enigma: &enigma.Enigma{
GlobalSecret: []byte("some-super-cool-secret-that-nobody-knows"),
},
}
Expand Down Expand Up @@ -204,32 +206,32 @@ func fositeFactory() OAuth2Provider {
AuthCodeLifespan: time.Minute * 10,
AccessTokenLifespan: accessTokenLifespan,
}
f.AuthorizeEndpointHandlers.Add("code", explicitHandler)
f.TokenEndpointHandlers.Add("code", explicitHandler)
f.AuthorizeEndpointHandlers.Append(explicitHandler)
f.TokenEndpointHandlers.Append(explicitHandler)

// Implicit grant type
implicitHandler := &implicit.AuthorizeImplicitGrantTypeHandler{
AccessTokenStrategy: hmacStrategy,
Store: store,
AccessTokenLifespan: accessTokenLifespan,
}
f.AuthorizeEndpointHandlers.Add("implicit", implicitHandler)
f.AuthorizeEndpointHandlers.Append(implicitHandler)

// Client credentials grant type
clientHandler := &coreclient.ClientCredentialsGrantHandler{
AccessTokenStrategy: hmacStrategy,
Store: store,
AccessTokenLifespan: accessTokenLifespan,
}
f.TokenEndpointHandlers.Add("client", clientHandler)
f.TokenEndpointHandlers.Append(clientHandler)

// Resource owner password credentials grant type
ownerHandler := &owner.ResourceOwnerPasswordCredentialsGrantHandler{
AccessTokenStrategy: hmacStrategy,
Store: store,
AccessTokenLifespan: accessTokenLifespan,
}
f.TokenEndpointHandlers.Add("owner", ownerHandler)
f.TokenEndpointHandlers.Append(ownerHandler)

// Refresh grant type
refreshHandler := &refresh.RefreshTokenGrantHandler{
Expand All @@ -238,7 +240,7 @@ func fositeFactory() OAuth2Provider {
Store: store,
AccessTokenLifespan: accessTokenLifespan,
}
f.TokenEndpointHandlers.Add("refresh", refreshHandler)
f.TokenEndpointHandlers.Append(refreshHandler)

return f
}
Expand Down Expand Up @@ -475,7 +477,7 @@ If you want to enable the handler able to handle this workflow, you can do this:

```go
var hmacStrategy = &strategy.HMACSHAStrategy{
Enigma: &enigma.HMACSHAEnigma{
Enigma: &enigma.Enigma{
GlobalSecret: []byte("some-super-cool-secret-that-nobody-knows"),
},
}
Expand All @@ -494,8 +496,10 @@ explicitHandler := &explicit.AuthorizeExplicitGrantTypeHandler{
AuthCodeLifespan: time.Minute * 10,
AccessTokenLifespan: accessTokenLifespan,
}
f.AuthorizeEndpointHandlers.Add("code", explicitHandler)
f.TokenEndpointHandlers.Add("code", explicitHandler)

// Please note that order matters!
f.AuthorizeEndpointHandlers.Append(explicitHandler)
f.TokenEndpointHandlers.Append(explicitHandler)
```

As you probably noticed, there are two types of handlers, one for the [authorization */auth* endpoint](https://tools.ietf.org/html/rfc6749#section-3.1) and one for the [token
Expand Down Expand Up @@ -534,18 +538,23 @@ rather sooner than later.
**Create storage mocks**
```sh
mockgen -destination internal/storage.go github.com/ory-am/fosite Storage
mockgen -destination internal/authorize_code_storage.go github.com/ory-am/fosite/handler/core AuthorizeCodeStorage
mockgen -destination internal/access_token_storage.go github.com/ory-am/fosite/handler/core AccessTokenStorage
mockgen -destination internal/refresh_token_strategy.go github.com/ory-am/fosite/handler/core RefreshTokenStorage
mockgen -destination internal/core_client_storage.go github.com/ory-am/fosite/handler/core/client ClientCredentialsGrantStorage
mockgen -destination internal/core_explicit_storage.go github.com/ory-am/fosite/handler/core/explicit AuthorizeCodeGrantStorage
mockgen -destination internal/core_implicit_storage.go github.com/ory-am/fosite/handler/core/implicit ImplicitGrantStorage
mockgen -destination internal/core_owner_storage.go github.com/ory-am/fosite/handler/core/owner ResourceOwnerPasswordCredentialsGrantStorage
mockgen -destination internal/core_refresh_storage.go github.com/ory-am/fosite/handler/core/refresh RefreshTokenGrantStorage
mockgen -destination internal/oidc_id_token_storage.go github.com/ory-am/fosite/handler/oidc OpenIDConnectRequestStorage
```

**Create strategy mocks**
```sh
mockgen -destination internal/access_token_strategy.go github.com/ory-am/fosite/handler/core AccessTokenStrategy
mockgen -destination internal/refresh_token_strategy.go github.com/ory-am/fosite/handler/core RefreshTokenStrategy
mockgen -destination internal/authorize_code_strategy.go github.com/ory-am/fosite/handler/core AuthorizeCodeStrategy
mockgen -destination internal/id_token_strategy.go github.com/ory-am/fosite/handler/oidc OpenIDConnectTokenStrategy
```

**Create handler mocks**
Expand Down
31 changes: 22 additions & 9 deletions access_request.go
Original file line number Diff line number Diff line change
@@ -1,25 +1,38 @@
package fosite

import (
"time"
)
import "time"

type AccessRequest struct {
GrantType string
HandledGrantType []string
GrantTypes Arguments
HandledGrantType Arguments
RequestedAt time.Time

Request
}

func (a *AccessRequest) DidHandleGrantType() bool {
return StringInSlice(a.GrantType, a.HandledGrantType)
func NewAccessRequest(session interface{}) *AccessRequest {
return &AccessRequest{
Request: Request{
Scopes: Arguments{},
Session: session,
RequestedAt: time.Now(),
},
}
}

func (a *AccessRequest) DidHandleGrantTypes() bool {
for _, grantType := range a.GrantTypes {
if !StringInSlice(grantType, a.HandledGrantType) {
return false
}
}
return true
}

func (a *AccessRequest) SetGrantTypeHandled(name string) {
a.HandledGrantType = append(a.HandledGrantType, name)
}

func (a *AccessRequest) GetGrantType() string {
return a.GrantType
func (a *AccessRequest) GetGrantTypes() Arguments {
return a.GrantTypes
}
20 changes: 7 additions & 13 deletions access_request_handler.go
Original file line number Diff line number Diff line change
@@ -1,11 +1,11 @@
package fosite

import (
"github.com/go-errors/errors"
"golang.org/x/net/context"
"net/http"
"strings"
"time"

"github.com/go-errors/errors"
"golang.org/x/net/context"
)

// Implements
Expand Down Expand Up @@ -34,13 +34,7 @@ import (
// client MUST authenticate with the authorization server as described
// in Section 3.2.1.
func (f *Fosite) NewAccessRequest(ctx context.Context, r *http.Request, session interface{}) (AccessRequester, error) {
accessRequest := &AccessRequest{
Request: Request{
Scopes: Arguments{},
Session: session,
RequestedAt: time.Now(),
},
}
accessRequest := NewAccessRequest(session)

if r.Method != "POST" {
return accessRequest, errors.New(ErrInvalidRequest)
Expand All @@ -61,8 +55,8 @@ func (f *Fosite) NewAccessRequest(ctx context.Context, r *http.Request, session
}

accessRequest.Scopes = removeEmpty(strings.Split(r.Form.Get("scope"), " "))
accessRequest.GrantType = r.Form.Get("grant_type")
if accessRequest.GrantType == "" {
accessRequest.GrantTypes = removeEmpty(strings.Split(r.Form.Get("grant_type"), " "))
if len(accessRequest.GrantTypes) < 1 {
return accessRequest, errors.New(ErrInvalidRequest)
}

Expand All @@ -88,7 +82,7 @@ func (f *Fosite) NewAccessRequest(ctx context.Context, r *http.Request, session
}
}

if !accessRequest.DidHandleGrantType() {
if !accessRequest.DidHandleGrantTypes() {
return accessRequest, errors.New(ErrUnsupportedGrantType)
}

Expand Down
19 changes: 10 additions & 9 deletions access_request_handler_test.go
Original file line number Diff line number Diff line change
Expand Up @@ -3,16 +3,17 @@ package fosite_test
import (
"encoding/base64"
"fmt"
"net/http"
"net/url"
"testing"

"github.com/go-errors/errors"
"github.com/golang/mock/gomock"
"github.com/ory-am/common/pkg"
. "github.com/ory-am/fosite"
"github.com/ory-am/fosite/internal"
"github.com/stretchr/testify/assert"
"golang.org/x/net/context"
"net/http"
"net/url"
"testing"
)

func TestNewAccessRequest(t *testing.T) {
Expand Down Expand Up @@ -125,7 +126,7 @@ func TestNewAccessRequest(t *testing.T) {
hasher.EXPECT().Compare(gomock.Eq([]byte("foo")), gomock.Eq([]byte("bar"))).Return(nil)
handler.EXPECT().ValidateTokenEndpointRequest(gomock.Any(), gomock.Any(), gomock.Any()).Return(ErrServerError)
},
handlers: TokenEndpointHandlers{"a": handler},
handlers: TokenEndpointHandlers{handler},
},
{
header: http.Header{
Expand All @@ -142,7 +143,7 @@ func TestNewAccessRequest(t *testing.T) {
hasher.EXPECT().Compare(gomock.Eq([]byte("foo")), gomock.Eq([]byte("bar"))).Return(nil)
handler.EXPECT().ValidateTokenEndpointRequest(gomock.Any(), gomock.Any(), gomock.Any()).Return(nil)
},
handlers: TokenEndpointHandlers{"a": handler},
handlers: TokenEndpointHandlers{handler},
},
{
header: http.Header{
Expand All @@ -161,7 +162,7 @@ func TestNewAccessRequest(t *testing.T) {
a.SetGrantTypeHandled("bar")
}).Return(nil)
},
handlers: TokenEndpointHandlers{"a": handler},
handlers: TokenEndpointHandlers{handler},
},
{
header: http.Header{
Expand All @@ -180,7 +181,7 @@ func TestNewAccessRequest(t *testing.T) {
a.SetScopes([]string{"asdfasdf"})
}).Return(nil)
},
handlers: TokenEndpointHandlers{"a": handler},
handlers: TokenEndpointHandlers{handler},
expectErr: ErrInvalidScope,
},
{
Expand All @@ -200,9 +201,9 @@ func TestNewAccessRequest(t *testing.T) {
a.SetScopes([]string{DefaultRequiredScopeName})
}).Return(nil)
},
handlers: TokenEndpointHandlers{"a": handler},
handlers: TokenEndpointHandlers{handler},
expect: &AccessRequest{
GrantType: "foo",
GrantTypes: Arguments{"foo"},
HandledGrantType: []string{"foo"},
Request: Request{
Client: client,
Expand Down
7 changes: 4 additions & 3 deletions access_request_test.go
Original file line number Diff line number Diff line change
@@ -1,18 +1,19 @@
package fosite

import (
"testing"

"github.com/ory-am/fosite/client"
"github.com/stretchr/testify/assert"
"testing"
)

func TestAccessRequest(t *testing.T) {
ar := &AccessRequest{}
ar.GrantType = "foobar"
ar.GrantTypes = Arguments{"foobar"}
ar.Client = &client.SecureClient{}
ar.GrantScope("foo")
assert.True(t, ar.GetGrantedScopes().Has("foo"))
assert.NotNil(t, ar.GetRequestedAt())
assert.Equal(t, ar.GrantType, ar.GetGrantType())
assert.Equal(t, ar.GrantTypes, ar.GetGrantTypes())
assert.Equal(t, ar.Client, ar.GetClient())
}
14 changes: 14 additions & 0 deletions access_response.go
Original file line number Diff line number Diff line change
@@ -1,5 +1,11 @@
package fosite

import (
"strconv"
"strings"
"time"
)

func NewAccessResponse() AccessResponder {
return &AccessResponse{
Extra: map[string]interface{}{},
Expand All @@ -12,6 +18,14 @@ type AccessResponse struct {
TokenType string
}

func (a *AccessResponse) SetScopes(scopes Arguments) {
a.SetExtra("scope", strings.Join(scopes, " "))
}

func (a *AccessResponse) SetExpiresIn(expiresIn time.Duration) {
a.SetExtra("expires_in", strconv.Itoa(int(expiresIn)))
}

func (a *AccessResponse) SetExtra(key string, value interface{}) {
a.Extra[key] = value
}
Expand Down
3 changes: 2 additions & 1 deletion access_response_handler.go
Original file line number Diff line number Diff line change
@@ -1,9 +1,10 @@
package fosite

import (
"net/http"

"github.com/go-errors/errors"
"golang.org/x/net/context"
"net/http"
)

func (f *Fosite) NewAccessResponse(ctx context.Context, req *http.Request, requester AccessRequester) (AccessResponder, error) {
Expand Down
13 changes: 7 additions & 6 deletions access_response_handler_test.go
Original file line number Diff line number Diff line change
@@ -1,14 +1,15 @@
package fosite_test

import (
"net/http"
"testing"

"github.com/go-errors/errors"
"github.com/golang/mock/gomock"
. "github.com/ory-am/fosite"
"github.com/ory-am/fosite/internal"
"github.com/stretchr/testify/assert"
"golang.org/x/net/context"
"net/http"
"testing"
)

func TestNewAccessResponse(t *testing.T) {
Expand All @@ -32,14 +33,14 @@ func TestNewAccessResponse(t *testing.T) {
mock: func() {
handler.EXPECT().HandleTokenEndpointRequest(gomock.Any(), gomock.Any(), gomock.Any(), gomock.Any()).Return(ErrServerError)
},
handlers: TokenEndpointHandlers{"a": handler},
handlers: TokenEndpointHandlers{handler},
expectErr: ErrServerError,
},
{
mock: func() {
handler.EXPECT().HandleTokenEndpointRequest(gomock.Any(), gomock.Any(), gomock.Any(), gomock.Any()).Return(nil)
},
handlers: TokenEndpointHandlers{"a": handler},
handlers: TokenEndpointHandlers{handler},
expectErr: ErrUnsupportedGrantType,
},
{
Expand All @@ -48,7 +49,7 @@ func TestNewAccessResponse(t *testing.T) {
resp.SetAccessToken("foo")
}).Return(nil)
},
handlers: TokenEndpointHandlers{"a": handler},
handlers: TokenEndpointHandlers{handler},
expectErr: ErrUnsupportedGrantType,
},
{
Expand All @@ -58,7 +59,7 @@ func TestNewAccessResponse(t *testing.T) {
resp.SetTokenType("bar")
}).Return(nil)
},
handlers: TokenEndpointHandlers{"a": handler},
handlers: TokenEndpointHandlers{handler},
expect: &AccessResponse{
Extra: map[string]interface{}{},
AccessToken: "foo",
Expand Down
Loading

0 comments on commit ba84987

Please sign in to comment.