Skip to content

Commit

Permalink
all: write swagger docs
Browse files Browse the repository at this point in the history
  • Loading branch information
aeneasr authored and arekkas committed Oct 5, 2017
1 parent 5d29fda commit 635d0a1
Show file tree
Hide file tree
Showing 18 changed files with 554 additions and 52 deletions.
2 changes: 1 addition & 1 deletion client/handler.go
Original file line number Diff line number Diff line change
Expand Up @@ -282,7 +282,7 @@ func (h *Handler) List(w http.ResponseWriter, r *http.Request, ps httprouter.Par
//
// ```
// {
// "resources": ["rn:hydra:clients:<some-id> "],
// "resources": ["rn:hydra:clients:<some-id>"],
// "actions": ["get"],
// "effect": "allow",
// "conditions": { "owner": { "type": "EqualsSubjectCondition" } }
Expand Down
12 changes: 6 additions & 6 deletions client/manager_sql.go
Original file line number Diff line number Diff line change
Expand Up @@ -25,14 +25,14 @@ var migrations = &migrate.MemoryMigrationSource{
redirect_uris text NOT NULL,
grant_types text NOT NULL,
response_types text NOT NULL,
scope text NOT NULL,
owner text NOT NULL,
scope text NOT NULL,
owner text NOT NULL,
policy_uri text NOT NULL,
tos_uri text NOT NULL,
tos_uri text NOT NULL,
client_uri text NOT NULL,
logo_uri text NOT NULL,
contacts text NOT NULL,
public boolean NOT NULL
logo_uri text NOT NULL,
contacts text NOT NULL,
public boolean NOT NULL
)`},
Down: []string{
"DROP TABLE hydra_client",
Expand Down
9 changes: 5 additions & 4 deletions cmd/cli/handler_migrate.go
Original file line number Diff line number Diff line change
Expand Up @@ -138,10 +138,11 @@ func (h *MigrateHandler) runMigrateSQL(db *sqlx.DB) error {
}

for k, m := range map[string]schemaCreator{
"client": &client.SQLManager{DB: db},
"oauth2": &oauth2.FositeSQLStore{DB: db},
"jwk": &jwk.SQLManager{DB: db},
"group": &group.SQLManager{DB: db},
"client": &client.SQLManager{DB: db},
"oauth2": &oauth2.FositeSQLStore{DB: db},
"jwk": &jwk.SQLManager{DB: db},
"group": &group.SQLManager{DB: db},
"consent": oauth2.NewConsentRequestSQLManager(db),
} {
fmt.Printf("Applying `%s` SQL migrations...\n", k)
if num, err := m.CreateSchemas(); err != nil {
Expand Down
13 changes: 12 additions & 1 deletion doc.go
Original file line number Diff line number Diff line change
@@ -1,13 +1,23 @@
// Package main Hydra OAuth2 & OpenID Connect Server
// Package main Hydra OAuth2 & OpenID Connect Server (1.0.0-aplha1)
//
// Please refer to the user guide for in-depth documentation: https://ory.gitbooks.io/hydra/content/
//
//
// Hydra offers OAuth 2.0 and OpenID Connect Core 1.0 capabilities as a service. Hydra is different, because it works with any existing authentication infrastructure, not just LDAP or SAML. By implementing a consent app (works with any programming language) you build a bridge between Hydra and your authentication infrastructure.
// Hydra is able to securely manage JSON Web Keys, and has a sophisticated policy-based access control you can use if you want to.
// Hydra is suitable for green- (new) and brownfield (existing) projects. If you are not familiar with OAuth 2.0 and are working on a greenfield project, we recommend evaluating if OAuth 2.0 really serves your purpose. Knowledge of OAuth 2.0 is imperative in understanding what Hydra does and how it works.
//
//
// The official repository is located at https://github.com/ory/hydra
//
//
// ### ATTENTION - IMPORTANT NOTE
//
//
// The swagger generator used to create this documentation does currently not support example responses. To see
// request and response payloads click on **"Show JSON schema"**:
// ![Enable JSON Schema on Apiary](https://storage.googleapis.com/ory.am/hydra/json-schema.png)
//
// Schemes: http, https
// Host:
// BasePath: /
Expand Down Expand Up @@ -38,6 +48,7 @@
// hydra.keys.delete: "A scope required to delete JSON Web Keys"
// hydra.keys.update: "A scope required to get JSON Web Keys"
// hydra.health: "A scope required to get health information"
// hydra.consent: "A scope required to fetch and modify consent requests"
// offline: "A scope required when requesting refresh tokens"
// openid: "Request an OpenID Connect ID Token"
// basic:
Expand Down
6 changes: 2 additions & 4 deletions doc_swagger.go
Original file line number Diff line number Diff line change
Expand Up @@ -19,8 +19,6 @@ type genericError struct {
}
}

// The standard error format
// An empty response
// swagger:response emptyResponse
type emptyResponse struct {
Description string `json:"description,omitempty"`
}
type emptyResponse struct{}
94 changes: 87 additions & 7 deletions oauth2/consent_handler.go
Original file line number Diff line number Diff line change
Expand Up @@ -33,25 +33,35 @@ func (h *ConsentSessionHandler) SetRoutes(r *httprouter.Router) {
r.PATCH(ConsentSessionPath+"/:id/accept", h.AcceptConsentRequestHandler)
}

// swagger:route GET /.well-known/openid-configuration oauth2 openid-connect WellKnownHandler
// swagger:route GET /oauth2/consent/requests/{id} oauth2 consent getConsentRequest
//
// Server well known configuration
// Receive consent request information
//
// For more information, please refer to https://openid.net/specs/openid-connect-discovery-1_0.html
// Call this endpoint to receive information on consent requests.
//
// The subject making the request needs to be assigned to a policy containing:
//
// ```
// {
// "resources": ["rn:hydra:oauth2:consent:requests:<request-id>"],
// "actions": ["get"],
// "effect": "allow"
// }
// ```
//
// Consumes:
// - application/x-www-form-urlencoded
// - application/json
//
// Produces:
// - application/json
//
// Schemes: http, https
//
// Security:
// oauth2:
// oauth2: hydra.consent
//
// Responses:
// 200: WellKnown
// 200: oauthConsentRequest
// 401: genericError
// 500: genericError
func (h *ConsentSessionHandler) FetchConsentRequest(w http.ResponseWriter, r *http.Request, ps httprouter.Params) {
Expand All @@ -71,6 +81,38 @@ func (h *ConsentSessionHandler) FetchConsentRequest(w http.ResponseWriter, r *ht
}
}

// swagger:route PATCH /oauth2/consent/requests/{id}/reject oauth2 consent rejectConsentRequest
//
// Reject a consent request
//
// Call this endpoint to reject a consent request. This usually happens when a user denies access rights to an
// application.
//
// The subject making the request needs to be assigned to a policy containing:
//
// ```
// {
// "resources": ["rn:hydra:oauth2:consent:requests:<request-id>"],
// "actions": ["reject"],
// "effect": "allow"
// }
// ```
//
// Consumes:
// - application/json
//
// Produces:
// - application/json
//
// Schemes: http, https
//
// Security:
// oauth2: hydra.consent
//
// Responses:
// 204: emptyResponse
// 401: genericError
// 500: genericError
func (h *ConsentSessionHandler) RejectConsentRequestHandler(w http.ResponseWriter, r *http.Request, ps httprouter.Params) {
if _, err := h.W.TokenAllowed(r.Context(), h.W.TokenFromRequest(r), &firewall.TokenAccessRequest{
Resource: fmt.Sprintf(ConsentResource, ps.ByName("id")),
Expand All @@ -80,14 +122,52 @@ func (h *ConsentSessionHandler) RejectConsentRequestHandler(w http.ResponseWrite
return
}

if err := h.M.RejectConsentRequest(ps.ByName("id")); err != nil {
var payload RejectConsentRequestPayload
if err := json.NewDecoder(r.Body).Decode(&payload); err != nil {
h.H.WriteError(w, r, errors.WithStack(err))
return
}

if err := h.M.RejectConsentRequest(ps.ByName("id"), &payload); err != nil {
h.H.WriteError(w, r, err)
return
}

w.WriteHeader(http.StatusNoContent)
}

// swagger:route PATCH /oauth2/consent/requests/{id}/accept oauth2 consent acceptConsentRequest
//
// Accept a consent request
//
// Call this endpoint to accept a consent request. This usually happens when a user agrees to give access rights to
// an application.
//
// The subject making the request needs to be assigned to a policy containing:
//
// ```
// {
// "resources": ["rn:hydra:oauth2:consent:requests:<request-id>"],
// "actions": ["accept"],
// "effect": "allow"
// }
// ```
//
// Consumes:
// - application/json
//
// Produces:
// - application/json
//
// Schemes: http, https
//
// Security:
// oauth2: hydra.consent
//
// Responses:
// 204: emptyResponse
// 401: genericError
// 500: genericError
func (h *ConsentSessionHandler) AcceptConsentRequestHandler(w http.ResponseWriter, r *http.Request, ps httprouter.Params) {
if _, err := h.W.TokenAllowed(r.Context(), h.W.TokenFromRequest(r), &firewall.TokenAccessRequest{
Resource: fmt.Sprintf(ConsentResource, ps.ByName("id")),
Expand Down
56 changes: 46 additions & 10 deletions oauth2/consent_manager.go
Original file line number Diff line number Diff line change
Expand Up @@ -2,34 +2,70 @@ package oauth2

import "time"

// ConsentRequest represents a consent request.
//
// swagger:model consentRequest
type ConsentRequest struct {
ID string `json:"id"`
// ID is the id of this consent request.
ID string `json:"id"`

// RequestedScopes represents a list of scopes that have been requested by the OAuth2 request initiator.
RequestedScopes []string `json:"requestedScopes,omitempty"`

// Audience is the client id that initiated the OAuth2 request.
Audience string `json:"audience"`

// ExpiresAt is the time where the access request will expire.
ExpiresAt time.Time `json:"expiresAt"`

// Redirect URL is the URL where the user agent should be redirected to after the consent has been
// accepted or rejected.
RedirectURL string `json:"redirectUrl"`

CSRF string `json:"-"`
GrantedScopes []string `json:"-"`
RequestedScope []string `json:"requested_scope,omitempty"`
Audience string `json:"audience"`
Subject string `json:"-"`
ExpiresAt time.Time `json:"expires_at"`
RedirectURL string `json:"redirect_url"`
AccessTokenExtra map[string]interface{} `json:"-"`
IDTokenExtra map[string]interface{} `json:"-"`
Consent string `json:"-"`
DenyReason string `json:"-"`
}

func (c *ConsentRequest) IsConsentGranted() bool {
return c.Consent == ConsentRequestAccepted
}

// AcceptConsentRequestPayload represents data that will be used to accept a consent request.
//
// swagger:model acceptConsentRequestPayload
type AcceptConsentRequestPayload struct {
AccessTokenExtra map[string]interface{} `json:"access_token_extra"`
IDTokenExtra map[string]interface{} `json:"id_token_extra"`
Subject string `json:"subject"`
GrantScopes []string `json:"grant_scopes"`
// AccessTokenExtra represents arbitrary data that will be added to the access token and that will be returned
// on introspection and warden requests.
AccessTokenExtra map[string]interface{} `json:"accessTokenExtra"`

// IDTokenExtra represents arbitrary data that will be added to the ID token. The ID token will only be issued
// if the user agrees to it and if the client requested an ID token.
IDTokenExtra map[string]interface{} `json:"idTokenExtra"`

// Subject represents a unique identifier of the user (or service, or legal entity, ...) that accepted the
// OAuth2 request.
Subject string `json:"subject"`

// A list of scopes that the user agreed to grant. It should be a subset of requestedScopes from the consent request.
GrantScopes []string `json:"grantScopes"`
}

// RejectConsentRequestPayload represents data that will be used to reject a consent request.
//
// swagger:model rejectConsentRequestPayload
type RejectConsentRequestPayload struct {
// Reason represents the reason why the user rejected the consent request.
Reason string `json:"reason"`
}

type ConsentRequestClient interface {
AcceptConsentRequest(id string, payload *AcceptConsentRequestPayload) error
RejectConsentRequest(id string) error
RejectConsentRequest(id string, payload *RejectConsentRequestPayload) error
GetConsentRequest(id string) (*ConsentRequest, error)
}

Expand Down
4 changes: 2 additions & 2 deletions oauth2/consent_manager_http.go
Original file line number Diff line number Diff line change
Expand Up @@ -23,12 +23,12 @@ func (m *HTTPConsentManager) AcceptConsentRequest(id string, payload *AcceptCons
return r.Patch(payload)
}

func (m *HTTPConsentManager) RejectConsentRequest(id string) error {
func (m *HTTPConsentManager) RejectConsentRequest(id string, payload *RejectConsentRequestPayload) error {
var r = pkg.NewSuperAgent(pkg.JoinURL(m.Endpoint, id, "reject").String())
r.Client = m.Client
r.Dry = m.Dry
r.FakeTLSTermination = m.FakeTLSTermination
return r.Patch(struct{}{})
return r.Patch(payload)
}

func (m *HTTPConsentManager) GetConsentRequest(id string) (*ConsentRequest, error) {
Expand Down
3 changes: 2 additions & 1 deletion oauth2/consent_manager_memory.go
Original file line number Diff line number Diff line change
Expand Up @@ -33,13 +33,14 @@ func (m *ConsentRequestMemoryManager) AcceptConsentRequest(id string, payload *A
return m.PersistConsentRequest(session)
}

func (m *ConsentRequestMemoryManager) RejectConsentRequest(id string) error {
func (m *ConsentRequestMemoryManager) RejectConsentRequest(id string, payload *RejectConsentRequestPayload) error {
session, err := m.GetConsentRequest(id)
if err != nil {
return err
}

session.Consent = ConsentRequestRejected
session.DenyReason = payload.Reason
return m.PersistConsentRequest(session)
}

Expand Down
Loading

0 comments on commit 635d0a1

Please sign in to comment.