mirror of https://github.com/ory/hydra
288 lines
8.1 KiB
Go
288 lines
8.1 KiB
Go
// Copyright © 2022 Ory Corp
|
|
// SPDX-License-Identifier: Apache-2.0
|
|
|
|
package trust
|
|
|
|
import (
|
|
"encoding/json"
|
|
"net/http"
|
|
"time"
|
|
|
|
"github.com/gofrs/uuid"
|
|
"github.com/julienschmidt/httprouter"
|
|
"github.com/pkg/errors"
|
|
|
|
"github.com/ory/fosite"
|
|
"github.com/ory/hydra/v2/x"
|
|
"github.com/ory/x/httprouterx"
|
|
"github.com/ory/x/pagination/tokenpagination"
|
|
)
|
|
|
|
const (
|
|
grantJWTBearerPath = "/trust/grants/jwt-bearer/issuers" // #nosec G101
|
|
)
|
|
|
|
type Handler struct {
|
|
registry InternalRegistry
|
|
}
|
|
|
|
func NewHandler(r InternalRegistry) *Handler {
|
|
return &Handler{registry: r}
|
|
}
|
|
|
|
func (h *Handler) SetRoutes(admin *httprouterx.RouterAdmin) {
|
|
admin.GET(grantJWTBearerPath+"/:id", h.getTrustedOAuth2JwtGrantIssuer)
|
|
admin.GET(grantJWTBearerPath, h.adminListTrustedOAuth2JwtGrantIssuers)
|
|
admin.POST(grantJWTBearerPath, h.trustOAuth2JwtGrantIssuer)
|
|
admin.DELETE(grantJWTBearerPath+"/:id", h.deleteTrustedOAuth2JwtGrantIssuer)
|
|
}
|
|
|
|
// Trust OAuth2 JWT Bearer Grant Type Issuer Request Body
|
|
//
|
|
// swagger:model trustOAuth2JwtGrantIssuer
|
|
//
|
|
//lint:ignore U1000 Used to generate Swagger and OpenAPI definitions
|
|
type trustOAuth2JwtGrantIssuerBody struct {
|
|
// The "issuer" identifies the principal that issued the JWT assertion (same as "iss" claim in JWT).
|
|
//
|
|
// required: true
|
|
// example: https://jwt-idp.example.com
|
|
Issuer string `json:"issuer"`
|
|
|
|
// The "subject" identifies the principal that is the subject of the JWT.
|
|
//
|
|
// example: mike@example.com
|
|
Subject string `json:"subject"`
|
|
|
|
// The "allow_any_subject" indicates that the issuer is allowed to have any principal as the subject of the JWT.
|
|
AllowAnySubject bool `json:"allow_any_subject"`
|
|
|
|
// The "scope" contains list of scope values (as described in Section 3.3 of OAuth 2.0 [RFC6749])
|
|
//
|
|
// required:true
|
|
// example: ["openid", "offline"]
|
|
Scope []string `json:"scope"`
|
|
|
|
// The "jwk" contains public key in JWK format issued by "issuer", that will be used to check JWT assertion signature.
|
|
//
|
|
// required:true
|
|
JWK x.JSONWebKey `json:"jwk"`
|
|
|
|
// The "expires_at" indicates, when grant will expire, so we will reject assertion from "issuer" targeting "subject".
|
|
//
|
|
// required:true
|
|
ExpiresAt time.Time `json:"expires_at"`
|
|
}
|
|
|
|
// Trust OAuth2 JWT Bearer Grant Type Issuer Request
|
|
//
|
|
// swagger:parameters trustOAuth2JwtGrantIssuer
|
|
//
|
|
//lint:ignore U1000 Used to generate Swagger and OpenAPI definitions
|
|
type trustOAuth2JwtGrantIssuer struct {
|
|
// in: body
|
|
Body trustOAuth2JwtGrantIssuerBody
|
|
}
|
|
|
|
// swagger:route POST /admin/trust/grants/jwt-bearer/issuers oAuth2 trustOAuth2JwtGrantIssuer
|
|
//
|
|
// # Trust OAuth2 JWT Bearer Grant Type Issuer
|
|
//
|
|
// Use this endpoint to establish a trust relationship for a JWT issuer
|
|
// to perform JSON Web Token (JWT) Profile for OAuth 2.0 Client Authentication
|
|
// and Authorization Grants [RFC7523](https://datatracker.ietf.org/doc/html/rfc7523).
|
|
//
|
|
// Consumes:
|
|
// - application/json
|
|
//
|
|
// Produces:
|
|
// - application/json
|
|
//
|
|
// Schemes: http, https
|
|
//
|
|
// Responses:
|
|
// 201: trustedOAuth2JwtGrantIssuer
|
|
// default: genericError
|
|
func (h *Handler) trustOAuth2JwtGrantIssuer(w http.ResponseWriter, r *http.Request, _ httprouter.Params) {
|
|
var grantRequest createGrantRequest
|
|
|
|
if err := json.NewDecoder(r.Body).Decode(&grantRequest); err != nil {
|
|
h.registry.Writer().WriteError(w, r,
|
|
errors.WithStack(&fosite.RFC6749Error{
|
|
ErrorField: "error",
|
|
DescriptionField: err.Error(),
|
|
CodeField: http.StatusBadRequest,
|
|
}))
|
|
return
|
|
}
|
|
|
|
if err := h.registry.GrantValidator().Validate(grantRequest); err != nil {
|
|
h.registry.Writer().WriteError(w, r, err)
|
|
return
|
|
}
|
|
|
|
grant := Grant{
|
|
ID: uuid.Must(uuid.NewV4()).String(),
|
|
Issuer: grantRequest.Issuer,
|
|
Subject: grantRequest.Subject,
|
|
AllowAnySubject: grantRequest.AllowAnySubject,
|
|
Scope: grantRequest.Scope,
|
|
PublicKey: PublicKey{
|
|
Set: grantRequest.Issuer, // group all keys by issuer, so set=issuer
|
|
KeyID: grantRequest.PublicKeyJWK.KeyID,
|
|
},
|
|
CreatedAt: time.Now().UTC().Round(time.Second),
|
|
ExpiresAt: grantRequest.ExpiresAt.UTC().Round(time.Second),
|
|
}
|
|
|
|
if err := h.registry.GrantManager().CreateGrant(r.Context(), grant, grantRequest.PublicKeyJWK); err != nil {
|
|
h.registry.Writer().WriteError(w, r, err)
|
|
return
|
|
}
|
|
|
|
h.registry.Writer().WriteCreated(w, r, grantJWTBearerPath+"/"+grant.ID, &grant)
|
|
}
|
|
|
|
// Get Trusted OAuth2 JWT Bearer Grant Type Issuer Request
|
|
//
|
|
// swagger:parameters getTrustedOAuth2JwtGrantIssuer
|
|
//
|
|
//lint:ignore U1000 Used to generate Swagger and OpenAPI definitions
|
|
type getTrustedOAuth2JwtGrantIssuer struct {
|
|
// The id of the desired grant
|
|
//
|
|
// in: path
|
|
// required: true
|
|
ID string `json:"id"`
|
|
}
|
|
|
|
// swagger:route GET /admin/trust/grants/jwt-bearer/issuers/{id} oAuth2 getTrustedOAuth2JwtGrantIssuer
|
|
//
|
|
// # Get Trusted OAuth2 JWT Bearer Grant Type Issuer
|
|
//
|
|
// Use this endpoint to get a trusted JWT Bearer Grant Type Issuer. The ID is the one returned when you
|
|
// created the trust relationship.
|
|
//
|
|
// Consumes:
|
|
// - application/json
|
|
//
|
|
// Produces:
|
|
// - application/json
|
|
//
|
|
// Schemes: http, https
|
|
//
|
|
// Responses:
|
|
// 200: trustedOAuth2JwtGrantIssuer
|
|
// default: genericError
|
|
func (h *Handler) getTrustedOAuth2JwtGrantIssuer(w http.ResponseWriter, r *http.Request, ps httprouter.Params) {
|
|
var id = ps.ByName("id")
|
|
|
|
grant, err := h.registry.GrantManager().GetConcreteGrant(r.Context(), id)
|
|
if err != nil {
|
|
h.registry.Writer().WriteError(w, r, err)
|
|
return
|
|
}
|
|
|
|
h.registry.Writer().Write(w, r, grant)
|
|
}
|
|
|
|
// Delete Trusted OAuth2 JWT Bearer Grant Type Issuer Request
|
|
//
|
|
// swagger:parameters deleteTrustedOAuth2JwtGrantIssuer
|
|
//
|
|
//lint:ignore U1000 Used to generate Swagger and OpenAPI definitions
|
|
type deleteTrustedOAuth2JwtGrantIssuer struct {
|
|
// The id of the desired grant
|
|
// in: path
|
|
// required: true
|
|
ID string `json:"id"`
|
|
}
|
|
|
|
// swagger:route DELETE /admin/trust/grants/jwt-bearer/issuers/{id} oAuth2 deleteTrustedOAuth2JwtGrantIssuer
|
|
//
|
|
// # Delete Trusted OAuth2 JWT Bearer Grant Type Issuer
|
|
//
|
|
// Use this endpoint to delete trusted JWT Bearer Grant Type Issuer. The ID is the one returned when you
|
|
// created the trust relationship.
|
|
//
|
|
// Once deleted, the associated issuer will no longer be able to perform the JSON Web Token (JWT) Profile
|
|
// for OAuth 2.0 Client Authentication and Authorization Grant.
|
|
//
|
|
// Consumes:
|
|
// - application/json
|
|
//
|
|
// Produces:
|
|
// - application/json
|
|
//
|
|
// Schemes: http, https
|
|
//
|
|
// Responses:
|
|
// 204: emptyResponse
|
|
// default: genericError
|
|
func (h *Handler) deleteTrustedOAuth2JwtGrantIssuer(w http.ResponseWriter, r *http.Request, ps httprouter.Params) {
|
|
var id = ps.ByName("id")
|
|
|
|
if err := h.registry.GrantManager().DeleteGrant(r.Context(), id); err != nil {
|
|
h.registry.Writer().WriteError(w, r, err)
|
|
return
|
|
}
|
|
|
|
w.WriteHeader(http.StatusNoContent)
|
|
}
|
|
|
|
// List Trusted OAuth2 JWT Bearer Grant Type Issuers Request
|
|
//
|
|
// swagger:parameters listTrustedOAuth2JwtGrantIssuers
|
|
//
|
|
//lint:ignore U1000 Used to generate Swagger and OpenAPI definitions
|
|
type listTrustedOAuth2JwtGrantIssuers struct {
|
|
// If optional "issuer" is supplied, only jwt-bearer grants with this issuer will be returned.
|
|
//
|
|
// in: query
|
|
// required: false
|
|
Issuer string `json:"issuer"`
|
|
|
|
tokenpagination.TokenPaginator
|
|
}
|
|
|
|
// swagger:route GET /admin/trust/grants/jwt-bearer/issuers oAuth2 listTrustedOAuth2JwtGrantIssuers
|
|
//
|
|
// # List Trusted OAuth2 JWT Bearer Grant Type Issuers
|
|
//
|
|
// Use this endpoint to list all trusted JWT Bearer Grant Type Issuers.
|
|
//
|
|
// Consumes:
|
|
// - application/json
|
|
//
|
|
// Produces:
|
|
// - application/json
|
|
//
|
|
// Schemes: http, https
|
|
//
|
|
// Responses:
|
|
// 200: trustedOAuth2JwtGrantIssuers
|
|
// default: genericError
|
|
func (h *Handler) adminListTrustedOAuth2JwtGrantIssuers(w http.ResponseWriter, r *http.Request, ps httprouter.Params) {
|
|
page, itemsPerPage := x.ParsePagination(r)
|
|
optionalIssuer := r.URL.Query().Get("issuer")
|
|
|
|
grants, err := h.registry.GrantManager().GetGrants(r.Context(), itemsPerPage, page*itemsPerPage, optionalIssuer)
|
|
if err != nil {
|
|
h.registry.Writer().WriteError(w, r, err)
|
|
return
|
|
}
|
|
|
|
n, err := h.registry.GrantManager().CountGrants(r.Context())
|
|
if err != nil {
|
|
h.registry.Writer().WriteError(w, r, err)
|
|
return
|
|
}
|
|
|
|
x.PaginationHeader(w, r.URL, int64(n), page, itemsPerPage)
|
|
if grants == nil {
|
|
grants = []Grant{}
|
|
}
|
|
|
|
h.registry.Writer().Write(w, r, grants)
|
|
}
|