diff --git a/api/v1alpha1/oauth2client_types.go b/api/v1alpha1/oauth2client_types.go index ffd1829..c4eac2d 100644 --- a/api/v1alpha1/oauth2client_types.go +++ b/api/v1alpha1/oauth2client_types.go @@ -51,6 +51,69 @@ type HydraAdmin struct { ForwardedProto string `json:"forwardedProto,omitempty"` } +// TokenLifespans defines the desired token durations by grant type for OAuth2Client +type TokenLifespans struct { + // +kubebuilder:validation:Pattern=[0-9]+(ns|us|ms|s|m|h) + // + // AuthorizationCodeGrantAccessTokenLifespan is the access token lifespan + // issued on an authorization_code grant. + AuthorizationCodeGrantAccessTokenLifespan string `json:"authorization_code_grant_access_token_lifespan,omitempty"` + + // +kubebuilder:validation:Pattern=[0-9]+(ns|us|ms|s|m|h) + // + // AuthorizationCodeGrantIdTokenLifespan is the id token lifespan + // issued on an authorization_code grant. + AuthorizationCodeGrantIdTokenLifespan string `json:"authorization_code_grant_id_token_lifespan,omitempty"` + + // +kubebuilder:validation:Pattern=[0-9]+(ns|us|ms|s|m|h) + // + // AuthorizationCodeGrantRefreshTokenLifespan is the refresh token lifespan + // issued on an authorization_code grant. + AuthorizationCodeGrantRefreshTokenLifespan string `json:"authorization_code_grant_refresh_token_lifespan,omitempty"` + + // +kubebuilder:validation:Pattern=[0-9]+(ns|us|ms|s|m|h) + // + // AuthorizationCodeGrantRefreshTokenLifespan is the access token lifespan + // issued on a client_credentials grant. + ClientCredentialsGrantAccessTokenLifespan string `json:"client_credentials_grant_access_token_lifespan,omitempty"` + + // +kubebuilder:validation:Pattern=[0-9]+(ns|us|ms|s|m|h) + // + // ImplicitGrantAccessTokenLifespan is the access token lifespan + // issued on an implicit grant. + ImplicitGrantAccessTokenLifespan string `json:"implicit_grant_access_token_lifespan,omitempty"` + + // +kubebuilder:validation:Pattern=[0-9]+(ns|us|ms|s|m|h) + // + // ImplicitGrantIdTokenLifespan is the id token lifespan + // issued on an implicit grant. + ImplicitGrantIdTokenLifespan string `json:"implicit_grant_id_token_lifespan,omitempty"` + + // +kubebuilder:validation:Pattern=[0-9]+(ns|us|ms|s|m|h) + // + // JwtBearerGrantAccessTokenLifespan is the access token lifespan + // issued on a jwt_bearer grant. + JwtBearerGrantAccessTokenLifespan string `json:"jwt_bearer_grant_access_token_lifespan,omitempty"` + + // +kubebuilder:validation:Pattern=[0-9]+(ns|us|ms|s|m|h) + // + // RefreshTokenGrantAccessTokenLifespan is the access token lifespan + // issued on a refresh_token grant. + RefreshTokenGrantAccessTokenLifespan string `json:"refresh_token_grant_access_token_lifespan,omitempty"` + + // +kubebuilder:validation:Pattern=[0-9]+(ns|us|ms|s|m|h) + // + // RefreshTokenGrantIdTokenLifespan is the id token lifespan + // issued on a refresh_token grant. + RefreshTokenGrantIdTokenLifespan string `json:"refresh_token_grant_id_token_lifespan,omitempty"` + + // +kubebuilder:validation:Pattern=[0-9]+(ns|us|ms|s|m|h) + // + // RefreshTokenGrantRefreshTokenLifespan is the refresh token lifespan + // issued on a refresh_token grant. + RefreshTokenGrantRefreshTokenLifespan string `json:"refresh_token_grant_refresh_token_lifespan,omitempty"` +} + // OAuth2ClientSpec defines the desired state of OAuth2Client type OAuth2ClientSpec struct { @@ -110,6 +173,10 @@ type OAuth2ClientSpec struct { // Indication which authentication method shoud be used for the token endpoint TokenEndpointAuthMethod TokenEndpointAuthMethod `json:"tokenEndpointAuthMethod,omitempty"` + // TokenLifespans is the configuration to use for managing different token lifespans + // depending on the used grant type. + TokenLifespans TokenLifespans `json:"tokenLifespans,omitempty"` + // +kubebuilder:validation:Type=object // +nullable // +optional diff --git a/api/v1alpha1/oauth2client_types_test.go b/api/v1alpha1/oauth2client_types_test.go index 0c33d00..3d92f7f 100644 --- a/api/v1alpha1/oauth2client_types_test.go +++ b/api/v1alpha1/oauth2client_types_test.go @@ -89,17 +89,27 @@ func TestCreateAPI(t *testing.T) { t.Run("by failing if the requested object doesn't meet CRD requirements", func(t *testing.T) { for desc, modifyClient := range map[string]func(){ - "invalid grant type": func() { created.Spec.GrantTypes = []GrantType{"invalid"} }, - "invalid response type": func() { created.Spec.ResponseTypes = []ResponseType{"invalid", "code"} }, - "invalid composite response type": func() { created.Spec.ResponseTypes = []ResponseType{"invalid code", "code id_token"} }, - "invalid scope": func() { created.Spec.Scope = "" }, - "missing secret name": func() { created.Spec.SecretName = "" }, - "invalid redirect URI": func() { created.Spec.RedirectURIs = []RedirectURI{"invalid"} }, - "invalid logout redirect URI": func() { created.Spec.PostLogoutRedirectURIs = []RedirectURI{"invalid"} }, - "invalid hydra url": func() { created.Spec.HydraAdmin.URL = "invalid" }, - "invalid hydra port high": func() { created.Spec.HydraAdmin.Port = 65536 }, - "invalid hydra endpoint": func() { created.Spec.HydraAdmin.Endpoint = "invalid" }, - "invalid hydra forwarded proto": func() { created.Spec.HydraAdmin.Endpoint = "invalid" }, + "invalid grant type": func() { created.Spec.GrantTypes = []GrantType{"invalid"} }, + "invalid response type": func() { created.Spec.ResponseTypes = []ResponseType{"invalid", "code"} }, + "invalid composite response type": func() { created.Spec.ResponseTypes = []ResponseType{"invalid code", "code id_token"} }, + "invalid scope": func() { created.Spec.Scope = "" }, + "missing secret name": func() { created.Spec.SecretName = "" }, + "invalid redirect URI": func() { created.Spec.RedirectURIs = []RedirectURI{"invalid"} }, + "invalid logout redirect URI": func() { created.Spec.PostLogoutRedirectURIs = []RedirectURI{"invalid"} }, + "invalid hydra url": func() { created.Spec.HydraAdmin.URL = "invalid" }, + "invalid hydra port high": func() { created.Spec.HydraAdmin.Port = 65536 }, + "invalid hydra endpoint": func() { created.Spec.HydraAdmin.Endpoint = "invalid" }, + "invalid hydra forwarded proto": func() { created.Spec.HydraAdmin.ForwardedProto = "invalid" }, + "invalid lifespan authorization code access token": func() { created.Spec.TokenLifespans.AuthorizationCodeGrantAccessTokenLifespan = "invalid" }, + "invalid lifespan authorization code id token": func() { created.Spec.TokenLifespans.AuthorizationCodeGrantIdTokenLifespan = "invalid" }, + "invalid lifespan authorization code refresh token": func() { created.Spec.TokenLifespans.AuthorizationCodeGrantRefreshTokenLifespan = "invalid" }, + "invalid lifespan client credentials access token": func() { created.Spec.TokenLifespans.ClientCredentialsGrantAccessTokenLifespan = "invalid" }, + "invalid lifespan implicit access token": func() { created.Spec.TokenLifespans.ImplicitGrantAccessTokenLifespan = "invalid" }, + "invalid lifespan implicit id token": func() { created.Spec.TokenLifespans.ImplicitGrantIdTokenLifespan = "invalid" }, + "invalid lifespan jwt bearer access token": func() { created.Spec.TokenLifespans.JwtBearerGrantAccessTokenLifespan = "invalid" }, + "invalid lifespan refresh token access token": func() { created.Spec.TokenLifespans.RefreshTokenGrantAccessTokenLifespan = "invalid" }, + "invalid lifespan refresh token id token": func() { created.Spec.TokenLifespans.RefreshTokenGrantIdTokenLifespan = "invalid" }, + "invalid lifespan refresh token refresh token": func() { created.Spec.TokenLifespans.RefreshTokenGrantRefreshTokenLifespan = "invalid" }, } { t.Run(fmt.Sprintf("case=%s", desc), func(t *testing.T) { resetTestClient() @@ -158,10 +168,11 @@ func resetTestClient() { Namespace: "default", }, Spec: OAuth2ClientSpec{ - GrantTypes: []GrantType{"implicit", "client_credentials", "authorization_code", "refresh_token"}, - ResponseTypes: []ResponseType{"id_token", "code", "token"}, - Scope: "read,write", - SecretName: "secret-name", + GrantTypes: []GrantType{"implicit", "client_credentials", "authorization_code", "refresh_token"}, + ResponseTypes: []ResponseType{"id_token", "code", "token"}, + Scope: "read,write", + SecretName: "secret-name", + TokenLifespans: TokenLifespans{}, }, } } diff --git a/api/v1alpha1/zz_generated.deepcopy.go b/api/v1alpha1/zz_generated.deepcopy.go index 18f8abf..9548b97 100644 --- a/api/v1alpha1/zz_generated.deepcopy.go +++ b/api/v1alpha1/zz_generated.deepcopy.go @@ -1,5 +1,4 @@ //go:build !ignore_autogenerated -// +build !ignore_autogenerated /* Copyright © 2023 Ory Corp @@ -149,6 +148,7 @@ func (in *OAuth2ClientSpec) DeepCopyInto(out *OAuth2ClientSpec) { copy(*out, *in) } out.HydraAdmin = in.HydraAdmin + out.TokenLifespans = in.TokenLifespans in.Metadata.DeepCopyInto(&out.Metadata) } @@ -197,3 +197,18 @@ func (in *ReconciliationError) DeepCopy() *ReconciliationError { in.DeepCopyInto(out) return out } + +// DeepCopyInto is an autogenerated deepcopy function, copying the receiver, writing into out. in must be non-nil. +func (in *TokenLifespans) DeepCopyInto(out *TokenLifespans) { + *out = *in +} + +// DeepCopy is an autogenerated deepcopy function, copying the receiver, creating a new TokenLifespans. +func (in *TokenLifespans) DeepCopy() *TokenLifespans { + if in == nil { + return nil + } + out := new(TokenLifespans) + in.DeepCopyInto(out) + return out +} diff --git a/config/crd/bases/hydra.ory.sh_oauth2clients.yaml b/config/crd/bases/hydra.ory.sh_oauth2clients.yaml index a777f8c..c90c62f 100644 --- a/config/crd/bases/hydra.ory.sh_oauth2clients.yaml +++ b/config/crd/bases/hydra.ory.sh_oauth2clients.yaml @@ -14,279 +14,318 @@ spec: singular: oauth2client scope: Namespaced versions: - - name: v1alpha1 - schema: - openAPIV3Schema: - description: OAuth2Client is the Schema for the oauth2clients API - properties: - apiVersion: - description: - "APIVersion defines the versioned schema of this representation - of an object. Servers should convert recognized schemas to the - latest internal value, and may reject unrecognized values. More - info: - https://git.k8s.io/community/contributors/devel/sig-architecture/api-conventions.md#resources" - type: string - kind: - description: - "Kind is a string value representing the REST resource this - object represents. Servers may infer this from the endpoint the - client submits requests to. Cannot be updated. In CamelCase. - More info: - https://git.k8s.io/community/contributors/devel/sig-architecture/api-conventions.md#types-kinds" - type: string - metadata: - type: object - spec: - description: - OAuth2ClientSpec defines the desired state of OAuth2Client - properties: - allowedCorsOrigins: - description: - AllowedCorsOrigins is an array of allowed CORS origins - items: - description: - RedirectURI represents a redirect URI for the client - pattern: \w+:/?/?[^\s]+ - type: string - type: array - audience: - description: - Audience is a whitelist defining the audiences this client - is allowed to request tokens for - items: - type: string - type: array - backChannelLogoutSessionRequired: - default: false - description: - BackChannelLogoutSessionRequired Boolean value specifying - whether the RP requires that a sid (session ID) Claim be - included in the Logout Token to identify the RP session with - the OP when the backchannel_logout_uri is used. If omitted, - the default value is false. - type: boolean - backChannelLogoutURI: - description: - BackChannelLogoutURI RP URL that will cause the RP to log - itself out when sent a Logout Token by the OP - pattern: (^$|^https?://.*) + - name: v1alpha1 + schema: + openAPIV3Schema: + description: OAuth2Client is the Schema for the oauth2clients API + properties: + apiVersion: + description: |- + APIVersion defines the versioned schema of this representation of an object. + Servers should convert recognized schemas to the latest internal value, and + may reject unrecognized values. + More info: https://git.k8s.io/community/contributors/devel/sig-architecture/api-conventions.md#resources + type: string + kind: + description: |- + Kind is a string value representing the REST resource this object represents. + Servers may infer this from the endpoint the client submits requests to. + Cannot be updated. + In CamelCase. + More info: https://git.k8s.io/community/contributors/devel/sig-architecture/api-conventions.md#types-kinds + type: string + metadata: + type: object + spec: + description: OAuth2ClientSpec defines the desired state of OAuth2Client + properties: + allowedCorsOrigins: + description: AllowedCorsOrigins is an array of allowed CORS origins + items: + description: RedirectURI represents a redirect URI for the client + pattern: \w+:/?/?[^\s]+ type: string - clientName: - description: - ClientName is the human-readable string name of the client - to be presented to the end-user during authorization. + type: array + audience: + description: Audience is a whitelist defining the audiences this client + is allowed to request tokens for + items: type: string - frontChannelLogoutSessionRequired: - default: false - description: - FrontChannelLogoutSessionRequired Boolean value specifying - whether the RP requires that iss (issuer) and sid (session - ID) query parameters be included to identify the RP session - with the OP when the frontchannel_logout_uri is used - type: boolean - frontChannelLogoutURI: - description: - FrontChannelLogoutURI RP URL that will cause the RP to log - itself out when rendered in an iframe by the OP. An iss - (issuer) query parameter and a sid (session ID) query - parameter MAY be included by the OP to enable the RP to - validate the request and to determine which of the - potentially multiple sessions is to be logged out; if either - is included, both MUST be - pattern: (^$|^https?://.*) + type: array + backChannelLogoutSessionRequired: + default: false + description: BackChannelLogoutSessionRequired Boolean value specifying + whether the RP requires that a sid (session ID) Claim be included + in the Logout Token to identify the RP session with the OP when + the backchannel_logout_uri is used. If omitted, the default value + is false. + type: boolean + backChannelLogoutURI: + description: BackChannelLogoutURI RP URL that will cause the RP to + log itself out when sent a Logout Token by the OP + pattern: (^$|^https?://.*) + type: string + clientName: + description: ClientName is the human-readable string name of the client + to be presented to the end-user during authorization. + type: string + frontChannelLogoutSessionRequired: + default: false + description: FrontChannelLogoutSessionRequired Boolean value specifying + whether the RP requires that iss (issuer) and sid (session ID) query + parameters be included to identify the RP session with the OP when + the frontchannel_logout_uri is used + type: boolean + frontChannelLogoutURI: + description: FrontChannelLogoutURI RP URL that will cause the RP to + log itself out when rendered in an iframe by the OP. An iss (issuer) + query parameter and a sid (session ID) query parameter MAY be included + by the OP to enable the RP to validate the request and to determine + which of the potentially multiple sessions is to be logged out; + if either is included, both MUST be + pattern: (^$|^https?://.*) + type: string + grantTypes: + description: GrantTypes is an array of grant types the client is allowed + to use. + items: + description: GrantType represents an OAuth 2.0 grant type + enum: + - client_credentials + - authorization_code + - implicit + - refresh_token type: string - grantTypes: - description: - GrantTypes is an array of grant types the client is allowed - to use. - items: - description: GrantType represents an OAuth 2.0 grant type - enum: - - client_credentials - - authorization_code - - implicit - - refresh_token - type: string - maxItems: 4 - minItems: 1 - type: array - hydraAdmin: - description: - HydraAdmin is the optional configuration to use for managing - this client - properties: - endpoint: - description: - Endpoint is the endpoint for the hydra instance on which - to set up the client. This value will override the value - provided to `--endpoint` (defaults to `"/clients"` in - the application) - pattern: (^$|^/.*) - type: string - forwardedProto: - description: - ForwardedProto overrides the `--forwarded-proto` flag. - The value "off" will force this to be off even if - `--forwarded-proto` is specified - pattern: (^$|https?|off) - type: string - port: - description: - Port is the port for the hydra instance on which to set - up the client. This value will override the value - provided to `--hydra-port` - maximum: 65535 - type: integer - url: - description: - URL is the URL for the hydra instance on which to set up - the client. This value will override the value provided - to `--hydra-url` - maxLength: 64 - pattern: (^$|^https?://.*) - type: string - type: object - jwksUri: - description: - JwksUri Define the URL where the JSON Web Key Set should be - fetched from when performing the private_key_jwt client - authentication method. - pattern: (^$|^https?://.*) - type: string - metadata: - description: Metadata is arbitrary data - nullable: true - type: object - x-kubernetes-preserve-unknown-fields: true - postLogoutRedirectUris: - description: - PostLogoutRedirectURIs is an array of the post logout - redirect URIs allowed for the application - items: - description: - RedirectURI represents a redirect URI for the client - pattern: \w+:/?/?[^\s]+ + maxItems: 4 + minItems: 1 + type: array + hydraAdmin: + description: |- + HydraAdmin is the optional configuration to use for managing + this client + properties: + endpoint: + description: |- + Endpoint is the endpoint for the hydra instance on which + to set up the client. This value will override the value + provided to `--endpoint` (defaults to `"/clients"` in the + application) + pattern: (^$|^/.*) type: string - type: array - redirectUris: - description: - RedirectURIs is an array of the redirect URIs allowed for - the application - items: - description: - RedirectURI represents a redirect URI for the client - pattern: \w+:/?/?[^\s]+ + forwardedProto: + description: |- + ForwardedProto overrides the `--forwarded-proto` flag. The + value "off" will force this to be off even if + `--forwarded-proto` is specified + pattern: (^$|https?|off) type: string - type: array - responseTypes: - description: - ResponseTypes is an array of the OAuth 2.0 response type - strings that the client can use at the authorization - endpoint. - items: - description: - ResponseType represents an OAuth 2.0 response type strings - enum: - - id_token - - code - - token - - code token - - code id_token - - id_token token - - code id_token token + port: + description: |- + Port is the port for the hydra instance on + which to set up the client. This value will override the value + provided to `--hydra-port` + maximum: 65535 + type: integer + url: + description: |- + URL is the URL for the hydra instance on + which to set up the client. This value will override the value + provided to `--hydra-url` + maxLength: 64 + pattern: (^$|^https?://.*) type: string - maxItems: 3 - minItems: 1 - type: array - scope: - description: - Scope is a string containing a space-separated list of scope - values (as described in Section 3.3 of OAuth 2.0 [RFC6749]) - that the client can use when requesting access tokens. - pattern: ([a-zA-Z0-9\.\*]+\s?)+ + type: object + jwksUri: + description: JwksUri Define the URL where the JSON Web Key Set should + be fetched from when performing the private_key_jwt client authentication + method. + pattern: (^$|^https?://.*) + type: string + metadata: + description: Metadata is arbitrary data + nullable: true + type: object + x-kubernetes-preserve-unknown-fields: true + postLogoutRedirectUris: + description: PostLogoutRedirectURIs is an array of the post logout + redirect URIs allowed for the application + items: + description: RedirectURI represents a redirect URI for the client + pattern: \w+:/?/?[^\s]+ type: string - secretName: - description: - SecretName points to the K8s secret that contains this - client's ID and password - maxLength: 253 - minLength: 1 - pattern: '[a-z0-9]([-a-z0-9]*[a-z0-9])?(\.[a-z0-9]([-a-z0-9]*[a-z0-9])?)*' + type: array + redirectUris: + description: RedirectURIs is an array of the redirect URIs allowed + for the application + items: + description: RedirectURI represents a redirect URI for the client + pattern: \w+:/?/?[^\s]+ type: string - skipConsent: - default: false - description: - SkipConsent skips the consent screen for this client. - type: boolean - tokenEndpointAuthMethod: - allOf: - - enum: - - client_secret_basic - - client_secret_post - - private_key_jwt - - none - - enum: - - client_secret_basic - - client_secret_post - - private_key_jwt - - none - description: - Indication which authentication method shoud be used for the - token endpoint + type: array + responseTypes: + description: |- + ResponseTypes is an array of the OAuth 2.0 response type strings that the client can + use at the authorization endpoint. + items: + description: ResponseType represents an OAuth 2.0 response type + strings + enum: + - id_token + - code + - token + - code token + - code id_token + - id_token token + - code id_token token type: string - required: - - grantTypes - - scope - - secretName - type: object - status: - description: - OAuth2ClientStatus defines the observed state of OAuth2Client - properties: - conditions: - items: - description: - OAuth2ClientCondition contains condition information for - an OAuth2Client - properties: - status: - enum: - - "True" - - "False" - - Unknown - type: string - type: - type: string - required: - - status - - type - type: object - type: array - observedGeneration: - description: - ObservedGeneration represents the most recent generation - observed by the daemon set controller. - format: int64 - type: integer - reconciliationError: - description: - ReconciliationError represents an error that occurred during - the reconciliation process + maxItems: 3 + minItems: 1 + type: array + scope: + description: |- + Scope is a string containing a space-separated list of scope values (as + described in Section 3.3 of OAuth 2.0 [RFC6749]) that the client + can use when requesting access tokens. + pattern: ([a-zA-Z0-9\.\*]+\s?)+ + type: string + secretName: + description: SecretName points to the K8s secret that contains this + client's ID and password + maxLength: 253 + minLength: 1 + pattern: '[a-z0-9]([-a-z0-9]*[a-z0-9])?(\.[a-z0-9]([-a-z0-9]*[a-z0-9])?)*' + type: string + skipConsent: + default: false + description: SkipConsent skips the consent screen for this client. + type: boolean + tokenEndpointAuthMethod: + allOf: + - enum: + - client_secret_basic + - client_secret_post + - private_key_jwt + - none + - enum: + - client_secret_basic + - client_secret_post + - private_key_jwt + - none + description: Indication which authentication method shoud be used + for the token endpoint + type: string + tokenLifespans: + description: |- + TokenLifespans is the configuration to use for managing different token lifespans + depending on the used grant type. + properties: + authorization_code_grant_access_token_lifespan: + description: |- + AuthorizationCodeGrantAccessTokenLifespan is the access token lifespan + issued on an authorization_code grant. + pattern: '[0-9]+(ns|us|ms|s|m|h)' + type: string + authorization_code_grant_id_token_lifespan: + description: |- + AuthorizationCodeGrantIdTokenLifespan is the id token lifespan + issued on an authorization_code grant. + pattern: '[0-9]+(ns|us|ms|s|m|h)' + type: string + authorization_code_grant_refresh_token_lifespan: + description: |- + AuthorizationCodeGrantRefreshTokenLifespan is the refresh token lifespan + issued on an authorization_code grant. + pattern: '[0-9]+(ns|us|ms|s|m|h)' + type: string + client_credentials_grant_access_token_lifespan: + description: |- + AuthorizationCodeGrantRefreshTokenLifespan is the access token lifespan + issued on a client_credentials grant. + pattern: '[0-9]+(ns|us|ms|s|m|h)' + type: string + implicit_grant_access_token_lifespan: + description: |- + ImplicitGrantAccessTokenLifespan is the access token lifespan + issued on an implicit grant. + pattern: '[0-9]+(ns|us|ms|s|m|h)' + type: string + implicit_grant_id_token_lifespan: + description: |- + ImplicitGrantIdTokenLifespan is the id token lifespan + issued on an implicit grant. + pattern: '[0-9]+(ns|us|ms|s|m|h)' + type: string + jwt_bearer_grant_access_token_lifespan: + description: |- + JwtBearerGrantAccessTokenLifespan is the access token lifespan + issued on a jwt_bearer grant. + pattern: '[0-9]+(ns|us|ms|s|m|h)' + type: string + refresh_token_grant_access_token_lifespan: + description: |- + RefreshTokenGrantAccessTokenLifespan is the access token lifespan + issued on a refresh_token grant. + pattern: '[0-9]+(ns|us|ms|s|m|h)' + type: string + refresh_token_grant_id_token_lifespan: + description: |- + RefreshTokenGrantIdTokenLifespan is the id token lifespan + issued on a refresh_token grant. + pattern: '[0-9]+(ns|us|ms|s|m|h)' + type: string + refresh_token_grant_refresh_token_lifespan: + description: |- + RefreshTokenGrantRefreshTokenLifespan is the refresh token lifespan + issued on a refresh_token grant. + pattern: '[0-9]+(ns|us|ms|s|m|h)' + type: string + type: object + required: + - grantTypes + - scope + - secretName + type: object + status: + description: OAuth2ClientStatus defines the observed state of OAuth2Client + properties: + conditions: + items: + description: OAuth2ClientCondition contains condition information + for an OAuth2Client properties: - description: - description: - Description is the description of the reconciliation - error + status: + enum: + - "True" + - "False" + - Unknown type: string - statusCode: - description: - Code is the status code of the reconciliation error + type: type: string + required: + - status + - type type: object - type: object - type: object - served: true - storage: true - subresources: - status: {} + type: array + observedGeneration: + description: ObservedGeneration represents the most recent generation + observed by the daemon set controller. + format: int64 + type: integer + reconciliationError: + description: ReconciliationError represents an error that occurred + during the reconciliation process + properties: + description: + description: Description is the description of the reconciliation + error + type: string + statusCode: + description: Code is the status code of the reconciliation error + type: string + type: object + type: object + type: object + served: true + storage: true + subresources: + status: {} diff --git a/config/rbac/role.yaml b/config/rbac/role.yaml index 9d43f10..08b823d 100644 --- a/config/rbac/role.yaml +++ b/config/rbac/role.yaml @@ -2,38 +2,37 @@ apiVersion: rbac.authorization.k8s.io/v1 kind: ClusterRole metadata: - creationTimestamp: null name: manager-role rules: - - apiGroups: - - "" - resources: - - secrets - verbs: - - create - - delete - - get - - list - - patch - - update - - watch - - apiGroups: - - hydra.ory.sh - resources: - - oauth2clients - verbs: - - create - - delete - - get - - list - - patch - - update - - watch - - apiGroups: - - hydra.ory.sh - resources: - - oauth2clients/status - verbs: - - get - - patch - - update +- apiGroups: + - "" + resources: + - secrets + verbs: + - create + - delete + - get + - list + - patch + - update + - watch +- apiGroups: + - hydra.ory.sh + resources: + - oauth2clients + verbs: + - create + - delete + - get + - list + - patch + - update + - watch +- apiGroups: + - hydra.ory.sh + resources: + - oauth2clients/status + verbs: + - get + - patch + - update diff --git a/hydra/client_test.go b/hydra/client_test.go index 42415ee..887e17d 100644 --- a/hydra/client_test.go +++ b/hydra/client_test.go @@ -53,6 +53,7 @@ var testOAuthJSONPost = &hydra.OAuth2ClientJSON{ FrontChannelLogoutSessionRequired: false, BackChannelLogoutURI: "https://localhost/backchannel-logout", BackChannelLogoutSessionRequired: false, + AuthorizationCodeGrantAccessTokenLifespan: "6h", } var testOAuthJSONPut = &hydra.OAuth2ClientJSON{ diff --git a/hydra/types.go b/hydra/types.go index dddc3e2..af8ed0d 100644 --- a/hydra/types.go +++ b/hydra/types.go @@ -14,25 +14,35 @@ import ( // OAuth2ClientJSON represents an OAuth2 client digestible by ORY Hydra type OAuth2ClientJSON struct { - ClientName string `json:"client_name,omitempty"` - ClientID *string `json:"client_id,omitempty"` - Secret *string `json:"client_secret,omitempty"` - GrantTypes []string `json:"grant_types"` - RedirectURIs []string `json:"redirect_uris,omitempty"` - PostLogoutRedirectURIs []string `json:"post_logout_redirect_uris,omitempty"` - AllowedCorsOrigins []string `json:"allowed_cors_origins,omitempty"` - ResponseTypes []string `json:"response_types,omitempty"` - Audience []string `json:"audience,omitempty"` - Scope string `json:"scope"` - SkipConsent bool `json:"skip_consent,omitempty"` - Owner string `json:"owner"` - TokenEndpointAuthMethod string `json:"token_endpoint_auth_method,omitempty"` - Metadata json.RawMessage `json:"metadata,omitempty"` - JwksUri string `json:"jwks_uri,omitempty"` - FrontChannelLogoutSessionRequired bool `json:"frontchannel_logout_session_required"` - FrontChannelLogoutURI string `json:"frontchannel_logout_uri"` - BackChannelLogoutSessionRequired bool `json:"backchannel_logout_session_required"` - BackChannelLogoutURI string `json:"backchannel_logout_uri"` + ClientName string `json:"client_name,omitempty"` + ClientID *string `json:"client_id,omitempty"` + Secret *string `json:"client_secret,omitempty"` + GrantTypes []string `json:"grant_types"` + RedirectURIs []string `json:"redirect_uris,omitempty"` + PostLogoutRedirectURIs []string `json:"post_logout_redirect_uris,omitempty"` + AllowedCorsOrigins []string `json:"allowed_cors_origins,omitempty"` + ResponseTypes []string `json:"response_types,omitempty"` + Audience []string `json:"audience,omitempty"` + Scope string `json:"scope"` + SkipConsent bool `json:"skip_consent,omitempty"` + Owner string `json:"owner"` + TokenEndpointAuthMethod string `json:"token_endpoint_auth_method,omitempty"` + Metadata json.RawMessage `json:"metadata,omitempty"` + JwksUri string `json:"jwks_uri,omitempty"` + FrontChannelLogoutSessionRequired bool `json:"frontchannel_logout_session_required"` + FrontChannelLogoutURI string `json:"frontchannel_logout_uri"` + BackChannelLogoutSessionRequired bool `json:"backchannel_logout_session_required"` + BackChannelLogoutURI string `json:"backchannel_logout_uri"` + AuthorizationCodeGrantAccessTokenLifespan string `json:"authorization_code_grant_access_token_lifespan,omitempty"` + AuthorizationCodeGrantIdTokenLifespan string `json:"authorization_code_grant_id_token_lifespan,omitempty"` + AuthorizationCodeGrantRefreshTokenLifespan string `json:"authorization_code_grant_refresh_token_lifespan,omitempty"` + ClientCredentialsGrantAccessTokenLifespan string `json:"client_credentials_grant_access_token_lifespan,omitempty"` + ImplicitGrantAccessTokenLifespan string `json:"implicit_grant_access_token_lifespan,omitempty"` + ImplicitGrantIdTokenLifespan string `json:"implicit_grant_id_token_lifespan,omitempty"` + JwtBearerGrantAccessTokenLifespan string `json:"jwt_bearer_grant_access_token_lifespan,omitempty"` + RefreshTokenGrantAccessTokenLifespan string `json:"refresh_token_grant_access_token_lifespan,omitempty"` + RefreshTokenGrantIdTokenLifespan string `json:"refresh_token_grant_id_token_lifespan,omitempty"` + RefreshTokenGrantRefreshTokenLifespan string `json:"refresh_token_grant_refresh_token_lifespan,omitempty"` } // Oauth2ClientCredentials represents client ID and password fetched from a @@ -74,6 +84,16 @@ func FromOAuth2Client(c *hydrav1alpha1.OAuth2Client) (*OAuth2ClientJSON, error) FrontChannelLogoutSessionRequired: c.Spec.BackChannelLogoutSessionRequired, BackChannelLogoutSessionRequired: c.Spec.BackChannelLogoutSessionRequired, BackChannelLogoutURI: c.Spec.BackChannelLogoutURI, + AuthorizationCodeGrantAccessTokenLifespan: c.Spec.TokenLifespans.AuthorizationCodeGrantAccessTokenLifespan, + AuthorizationCodeGrantIdTokenLifespan: c.Spec.TokenLifespans.AuthorizationCodeGrantIdTokenLifespan, + AuthorizationCodeGrantRefreshTokenLifespan: c.Spec.TokenLifespans.AuthorizationCodeGrantRefreshTokenLifespan, + ClientCredentialsGrantAccessTokenLifespan: c.Spec.TokenLifespans.ClientCredentialsGrantAccessTokenLifespan, + ImplicitGrantAccessTokenLifespan: c.Spec.TokenLifespans.ImplicitGrantAccessTokenLifespan, + ImplicitGrantIdTokenLifespan: c.Spec.TokenLifespans.ImplicitGrantIdTokenLifespan, + JwtBearerGrantAccessTokenLifespan: c.Spec.TokenLifespans.JwtBearerGrantAccessTokenLifespan, + RefreshTokenGrantAccessTokenLifespan: c.Spec.TokenLifespans.RefreshTokenGrantAccessTokenLifespan, + RefreshTokenGrantIdTokenLifespan: c.Spec.TokenLifespans.RefreshTokenGrantIdTokenLifespan, + RefreshTokenGrantRefreshTokenLifespan: c.Spec.TokenLifespans.RefreshTokenGrantRefreshTokenLifespan, }, nil }