diff --git a/api/v1alpha1/oauth2client_types.go b/api/v1alpha1/oauth2client_types.go index 3f03950..b4324d3 100644 --- a/api/v1alpha1/oauth2client_types.go +++ b/api/v1alpha1/oauth2client_types.go @@ -20,6 +20,8 @@ import ( "fmt" "github.com/ory/hydra-maester/hydra" + "github.com/pkg/errors" + apiextensionsv1 "k8s.io/apiextensions-apiserver/pkg/apis/apiextensions/v1" metav1 "k8s.io/apimachinery/pkg/apis/meta/v1" ) @@ -120,8 +122,12 @@ type OAuth2ClientSpec struct { // Indication which authentication method shoud be used for the token endpoint TokenEndpointAuthMethod TokenEndpointAuthMethod `json:"tokenEndpointAuthMethod,omitempty"` + // +kubebuilder:validation:Type=object + // +nullable + // +optional + // // Metadata is abritrary data - Metadata json.RawMessage `json:"metadata,omitempty"` + Metadata apiextensionsv1.JSON `json:"metadata,omitempty"` } // +kubebuilder:validation:Enum=client_credentials;authorization_code;implicit;refresh_token @@ -181,7 +187,12 @@ func init() { } // ToOAuth2ClientJSON converts an OAuth2Client into a OAuth2ClientJSON object that represents an OAuth2 client digestible by ORY Hydra -func (c *OAuth2Client) ToOAuth2ClientJSON() *hydra.OAuth2ClientJSON { +func (c *OAuth2Client) ToOAuth2ClientJSON() (*hydra.OAuth2ClientJSON, error) { + meta, err := json.Marshal(c.Spec.Metadata) + if err != nil { + return nil, errors.WithMessage(err, "unable to encode `metadata` property value to json") + } + return &hydra.OAuth2ClientJSON{ ClientName: c.Spec.ClientName, GrantTypes: grantToStringSlice(c.Spec.GrantTypes), @@ -193,8 +204,8 @@ func (c *OAuth2Client) ToOAuth2ClientJSON() *hydra.OAuth2ClientJSON { Scope: c.Spec.Scope, Owner: fmt.Sprintf("%s/%s", c.Name, c.Namespace), TokenEndpointAuthMethod: string(c.Spec.TokenEndpointAuthMethod), - Metadata: c.Spec.Metadata, - } + Metadata: meta, + }, nil } func responseToStringSlice(rt []ResponseType) []string { diff --git a/api/v1alpha1/zz_generated.deepcopy.go b/api/v1alpha1/zz_generated.deepcopy.go index 1050062..fa8143c 100644 --- a/api/v1alpha1/zz_generated.deepcopy.go +++ b/api/v1alpha1/zz_generated.deepcopy.go @@ -20,7 +20,6 @@ limitations under the License. package v1alpha1 import ( - "encoding/json" runtime "k8s.io/apimachinery/pkg/runtime" ) @@ -132,11 +131,7 @@ func (in *OAuth2ClientSpec) DeepCopyInto(out *OAuth2ClientSpec) { copy(*out, *in) } out.HydraAdmin = in.HydraAdmin - if in.Metadata != nil { - in, out := &in.Metadata, &out.Metadata - *out = make(json.RawMessage, len(*in)) - copy(*out, *in) - } + in.Metadata.DeepCopyInto(&out.Metadata) } // DeepCopy is an autogenerated deepcopy function, copying the receiver, creating a new OAuth2ClientSpec. diff --git a/config/crd/bases/hydra.ory.sh_oauth2clients.yaml b/config/crd/bases/hydra.ory.sh_oauth2clients.yaml index 665e907..316fd28 100644 --- a/config/crd/bases/hydra.ory.sh_oauth2clients.yaml +++ b/config/crd/bases/hydra.ory.sh_oauth2clients.yaml @@ -99,8 +99,9 @@ spec: type: object metadata: description: Metadata is abritrary data - format: byte - type: string + 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 diff --git a/controllers/oauth2client_controller.go b/controllers/oauth2client_controller.go index 7863f8a..623f420 100644 --- a/controllers/oauth2client_controller.go +++ b/controllers/oauth2client_controller.go @@ -205,8 +205,16 @@ func (r *OAuth2ClientReconciler) registerOAuth2Client(ctx context.Context, c *hy return err } + oauth2client, err := c.ToOAuth2ClientJSON() + if err != nil { + if updateErr := r.updateReconciliationStatusError(ctx, c, hydrav1alpha1.StatusRegistrationFailed, err); updateErr != nil { + return updateErr + } + return errors.WithStack(err) + } + if credentials != nil { - if _, err := hydra.PostOAuth2Client(c.ToOAuth2ClientJSON().WithCredentials(credentials)); err != nil { + if _, err := hydra.PostOAuth2Client(oauth2client.WithCredentials(credentials)); err != nil { if updateErr := r.updateReconciliationStatusError(ctx, c, hydrav1alpha1.StatusRegistrationFailed, err); updateErr != nil { return updateErr } @@ -214,7 +222,7 @@ func (r *OAuth2ClientReconciler) registerOAuth2Client(ctx context.Context, c *hy return r.ensureEmptyStatusError(ctx, c) } - created, err := hydra.PostOAuth2Client(c.ToOAuth2ClientJSON()) + created, err := hydra.PostOAuth2Client(oauth2client) if err != nil { if updateErr := r.updateReconciliationStatusError(ctx, c, hydrav1alpha1.StatusRegistrationFailed, err); updateErr != nil { return updateErr @@ -257,7 +265,15 @@ func (r *OAuth2ClientReconciler) updateRegisteredOAuth2Client(ctx context.Contex return err } - if _, err := hydra.PutOAuth2Client(c.ToOAuth2ClientJSON().WithCredentials(credentials)); err != nil { + oauth2client, err := c.ToOAuth2ClientJSON() + if err != nil { + if updateErr := r.updateReconciliationStatusError(ctx, c, hydrav1alpha1.StatusUpdateFailed, err); updateErr != nil { + return updateErr + } + return errors.WithStack(err) + } + + if _, err := hydra.PutOAuth2Client(oauth2client.WithCredentials(credentials)); err != nil { if updateErr := r.updateReconciliationStatusError(ctx, c, hydrav1alpha1.StatusUpdateFailed, err); updateErr != nil { return updateErr } diff --git a/go.mod b/go.mod index 4616dfa..55f5730 100644 --- a/go.mod +++ b/go.mod @@ -11,6 +11,7 @@ require ( github.com/stretchr/testify v1.6.1 golang.org/x/net v0.0.0-20201110031124-69a78807bb2b k8s.io/api v0.20.2 + k8s.io/apiextensions-apiserver v0.20.1 k8s.io/apimachinery v0.20.2 k8s.io/client-go v0.20.2 k8s.io/utils v0.0.0-20210305010621-2afb4311ab10