-
Notifications
You must be signed in to change notification settings - Fork 368
Commit
This commit does not belong to any branch on this repository, and may belong to a fork outside of the repository.
- Loading branch information
Aeneas Rekkas
committed
Jan 10, 2016
1 parent
5da857b
commit 9f482ef
Showing
16 changed files
with
500 additions
and
96 deletions.
There are no files selected for viewing
This file contains bidirectional Unicode text that may be interpreted or compiled differently than what appears below. To review, open the file in an editor that reveals hidden Unicode characters.
Learn more about bidirectional Unicode characters
This file contains bidirectional Unicode text that may be interpreted or compiled differently than what appears below. To review, open the file in an editor that reveals hidden Unicode characters.
Learn more about bidirectional Unicode characters
Original file line number | Diff line number | Diff line change |
---|---|---|
@@ -0,0 +1,25 @@ | ||
package fosite | ||
|
||
import ( | ||
"encoding/json" | ||
"fmt" | ||
"net/http" | ||
) | ||
|
||
func (c *Fosite) WriteAccessError(rw http.ResponseWriter, requester AccessRequester, err error) { | ||
rw.Header().Set("Content-Type", "application/json;charset=UTF-8") | ||
|
||
rfcerr := ErrorToRFC6749Error(err) | ||
js, err := json.Marshal(rfcerr) | ||
if err != nil { | ||
http.Error(rw, fmt.Sprintf(`{"error": "%s"}`, err.Error()), http.StatusInternalServerError) | ||
return | ||
} | ||
|
||
rw.WriteHeader(http.StatusBadRequest) | ||
if rfcerr.Name == errServerErrorName { | ||
rw.WriteHeader(http.StatusInternalServerError) | ||
} | ||
|
||
rw.Write(js) | ||
} |
This file contains bidirectional Unicode text that may be interpreted or compiled differently than what appears below. To review, open the file in an editor that reveals hidden Unicode characters.
Learn more about bidirectional Unicode characters
Original file line number | Diff line number | Diff line change |
---|---|---|
@@ -1,112 +1,57 @@ | ||
package fosite | ||
|
||
import ( | ||
"github.com/go-errors/errors" | ||
"github.com/ory-am/fosite/client" | ||
"golang.org/x/net/context" | ||
"net/http" | ||
"time" | ||
) | ||
|
||
type AccessRequester interface { | ||
// GetGrantType returns the requests grant type. | ||
GetGrantType() string | ||
|
||
// GetClient returns the requests client. | ||
GetClient() client.Client | ||
|
||
// GetRequestedAt returns the time the request was created. | ||
GetRequestedAt() time.Time | ||
} | ||
|
||
type AccessRequest struct { | ||
GrantType string | ||
RequestedAt time.Time | ||
Client client.Client | ||
} | ||
// SetGrantTypeHandled marks a grant type as handled indicating that the response type is supported. | ||
SetGrantTypeHandled(string) | ||
|
||
func (a *AccessRequest) GetGrantType() string { | ||
return a.GrantType | ||
// DidHandleGrantType returns if the requested grant type has been handled correctly. | ||
DidHandleGrantType() bool | ||
} | ||
|
||
func (a *AccessRequest) GetRequestedAt() time.Time { | ||
return a.RequestedAt | ||
} | ||
|
||
func (a *AccessRequest) GetClient() client.Client { | ||
return a.Client | ||
type AccessRequest struct { | ||
GrantType string | ||
HandledGrantType []string | ||
RequestedAt time.Time | ||
Client client.Client | ||
} | ||
|
||
func NewAccessRequest() *AccessRequest { | ||
return &AccessRequest{ | ||
RequestedAt: time.Now(), | ||
RequestedAt: time.Now(), | ||
HandledGrantType: []string{}, | ||
} | ||
} | ||
|
||
// | ||
// Implements | ||
// * https://tools.ietf.org/html/rfc6749#section-2.3.1 | ||
// Clients in possession of a client password MAY use the HTTP Basic | ||
// authentication scheme as defined in [RFC2617] to authenticate with | ||
// the authorization server. The client identifier is encoded using the | ||
// "application/x-www-form-urlencoded" encoding algorithm per | ||
// Appendix B, and the encoded value is used as the username; the client | ||
// password is encoded using the same algorithm and used as the | ||
// password. The authorization server MUST support the HTTP Basic | ||
// authentication scheme for authenticating clients that were issued a | ||
// client password. | ||
// Including the client credentials in the request-body using the two | ||
// parameters is NOT RECOMMENDED and SHOULD be limited to clients unable | ||
// to directly utilize the HTTP Basic authentication scheme (or other | ||
// password-based HTTP authentication schemes). The parameters can only | ||
// be transmitted in the request-body and MUST NOT be included in the | ||
// request URI. | ||
// * https://tools.ietf.org/html/rfc6749#section-3.2.1 | ||
// - Confidential clients or other clients issued client credentials MUST | ||
// authenticate with the authorization server as described in | ||
// Section 2.3 when making requests to the token endpoint. | ||
// - If the client type is confidential or the client was issued client | ||
// credentials (or assigned other authentication requirements), the | ||
// client MUST authenticate with the authorization server as described | ||
// in Section 3.2.1. | ||
func (c *Fosite) NewAccessRequest(ctx context.Context, r *http.Request, session interface{}) (AccessRequester, error) { | ||
ar := NewAccessRequest() | ||
if c.RequiredScope == "" { | ||
c.RequiredScope = DefaultRequiredScopeName | ||
} | ||
|
||
if err := r.ParseForm(); err != nil { | ||
return ar, errors.New(ErrInvalidRequest) | ||
} | ||
|
||
if session == nil { | ||
return ar, errors.New("Session must not be nil") | ||
} | ||
|
||
ar.GrantType = r.Form.Get("grant_type") | ||
if ar.GrantType == "" { | ||
return ar, errors.New(ErrInvalidRequest) | ||
} | ||
|
||
clientID, clientSecret, ok := r.BasicAuth() | ||
if !ok { | ||
clientID = r.Form.Get("client_id") | ||
} | ||
if clientID == "" { | ||
return ar, errors.New(ErrInvalidRequest) | ||
} | ||
func (a *AccessRequest) DidHandleGrantType() bool { | ||
return StringInSlice(a.GrantType, a.HandledGrantType) | ||
} | ||
|
||
client, err := c.Store.GetClient(clientID) | ||
if err != nil { | ||
return ar, errors.New(ErrInvalidClient) | ||
} | ||
func (a *AccessRequest) SetGrantTypeHandled(name string) { | ||
a.HandledGrantType = append(a.HandledGrantType, name) | ||
} | ||
|
||
// Enforce client authentication | ||
if !client.CompareSecretWith([]byte(clientSecret)) { | ||
return ar, errors.New(ErrInvalidClient) | ||
} | ||
ar.Client = client | ||
func (a *AccessRequest) GetGrantType() string { | ||
return a.GrantType | ||
} | ||
|
||
for _, loader := range c.TokenEndpointHandlers { | ||
if err := loader.HandleTokenEndpointRequest(ctx, ar, r, session); err != nil { | ||
return ar, err | ||
} | ||
} | ||
func (a *AccessRequest) GetRequestedAt() time.Time { | ||
return a.RequestedAt | ||
} | ||
|
||
return ar, nil | ||
func (a *AccessRequest) GetClient() client.Client { | ||
return a.Client | ||
} |
This file contains bidirectional Unicode text that may be interpreted or compiled differently than what appears below. To review, open the file in an editor that reveals hidden Unicode characters.
Learn more about bidirectional Unicode characters
Original file line number | Diff line number | Diff line change |
---|---|---|
@@ -0,0 +1,84 @@ | ||
package fosite | ||
|
||
import ( | ||
"github.com/go-errors/errors" | ||
"golang.org/x/net/context" | ||
"net/http" | ||
) | ||
|
||
// Implements | ||
// * https://tools.ietf.org/html/rfc6749#section-2.3.1 | ||
// Clients in possession of a client password MAY use the HTTP Basic | ||
// authentication scheme as defined in [RFC2617] to authenticate with | ||
// the authorization server. The client identifier is encoded using the | ||
// "application/x-www-form-urlencoded" encoding algorithm per | ||
// Appendix B, and the encoded value is used as the username; the client | ||
// password is encoded using the same algorithm and used as the | ||
// password. The authorization server MUST support the HTTP Basic | ||
// authentication scheme for authenticating clients that were issued a | ||
// client password. | ||
// Including the client credentials in the request-body using the two | ||
// parameters is NOT RECOMMENDED and SHOULD be limited to clients unable | ||
// to directly utilize the HTTP Basic authentication scheme (or other | ||
// password-based HTTP authentication schemes). The parameters can only | ||
// be transmitted in the request-body and MUST NOT be included in the | ||
// request URI. | ||
// * https://tools.ietf.org/html/rfc6749#section-3.2.1 | ||
// - Confidential clients or other clients issued client credentials MUST | ||
// authenticate with the authorization server as described in | ||
// Section 2.3 when making requests to the token endpoint. | ||
// - If the client type is confidential or the client was issued client | ||
// credentials (or assigned other authentication requirements), the | ||
// client MUST authenticate with the authorization server as described | ||
// in Section 3.2.1. | ||
func (c *Fosite) NewAccessRequest(ctx context.Context, r *http.Request, session interface{}) (AccessRequester, error) { | ||
ar := NewAccessRequest() | ||
if r.Method != "POST" { | ||
return ar, errors.New(ErrInvalidRequest) | ||
} | ||
|
||
if c.RequiredScope == "" { | ||
c.RequiredScope = DefaultRequiredScopeName | ||
} | ||
|
||
if err := r.ParseForm(); err != nil { | ||
return ar, errors.New(ErrInvalidRequest) | ||
} | ||
|
||
if session == nil { | ||
return ar, errors.New("Session must not be nil") | ||
} | ||
|
||
ar.GrantType = r.Form.Get("grant_type") | ||
if ar.GrantType == "" { | ||
return ar, errors.New(ErrInvalidRequest) | ||
} | ||
|
||
clientID, clientSecret, ok := r.BasicAuth() | ||
if !ok { | ||
return ar, errors.New(ErrInvalidRequest) | ||
} | ||
|
||
client, err := c.Store.GetClient(clientID) | ||
if err != nil { | ||
return ar, errors.New(ErrInvalidClient) | ||
} | ||
|
||
// Enforce client authentication | ||
if !client.CompareSecretWith([]byte(clientSecret)) { | ||
return ar, errors.New(ErrInvalidClient) | ||
} | ||
ar.Client = client | ||
|
||
for _, loader := range c.TokenEndpointHandlers { | ||
if err := loader.HandleTokenEndpointRequest(ctx, ar, r, session); err != nil { | ||
return ar, err | ||
} | ||
} | ||
|
||
if !ar.DidHandleGrantType() { | ||
return ar, errors.New(ErrUnsupportedGrantType) | ||
} | ||
|
||
return ar, nil | ||
} |
Oops, something went wrong.