fix(controller): Ensure that OAuth2Client reconciliation creates hydra client for specs (#83)
This commit is contained in:
@ -8,15 +8,51 @@ import (
|
||||
"net/http"
|
||||
"net/url"
|
||||
"path"
|
||||
|
||||
hydrav1alpha1 "github.com/ory/hydra-maester/api/v1alpha1"
|
||||
"github.com/ory/hydra-maester/helpers"
|
||||
)
|
||||
|
||||
type Client struct {
|
||||
type Client interface {
|
||||
GetOAuth2Client(id string) (*OAuth2ClientJSON, bool, error)
|
||||
ListOAuth2Client() ([]*OAuth2ClientJSON, error)
|
||||
PostOAuth2Client(o *OAuth2ClientJSON) (*OAuth2ClientJSON, error)
|
||||
PutOAuth2Client(o *OAuth2ClientJSON) (*OAuth2ClientJSON, error)
|
||||
DeleteOAuth2Client(id string) error
|
||||
}
|
||||
|
||||
type InternalClient struct {
|
||||
HydraURL url.URL
|
||||
HTTPClient *http.Client
|
||||
ForwardedProto string
|
||||
}
|
||||
|
||||
func (c *Client) GetOAuth2Client(id string) (*OAuth2ClientJSON, bool, error) {
|
||||
// New returns a new hydra InternalClient instance.
|
||||
func New(spec hydrav1alpha1.OAuth2ClientSpec, tlsTrustStore string, insecureSkipVerify bool) (Client, error) {
|
||||
address := fmt.Sprintf("%s:%d", spec.HydraAdmin.URL, spec.HydraAdmin.Port)
|
||||
u, err := url.Parse(address)
|
||||
if err != nil {
|
||||
return nil, err
|
||||
}
|
||||
|
||||
c, err := helpers.CreateHttpClient(insecureSkipVerify, tlsTrustStore)
|
||||
if err != nil {
|
||||
return nil, err
|
||||
}
|
||||
|
||||
client := &InternalClient{
|
||||
HydraURL: *u.ResolveReference(&url.URL{Path: spec.HydraAdmin.Endpoint}),
|
||||
HTTPClient: c,
|
||||
}
|
||||
|
||||
if spec.HydraAdmin.ForwardedProto != "" && spec.HydraAdmin.ForwardedProto != "off" {
|
||||
client.ForwardedProto = spec.HydraAdmin.ForwardedProto
|
||||
}
|
||||
|
||||
return client, nil
|
||||
}
|
||||
|
||||
func (c *InternalClient) GetOAuth2Client(id string) (*OAuth2ClientJSON, bool, error) {
|
||||
|
||||
var jsonClient *OAuth2ClientJSON
|
||||
|
||||
@ -40,7 +76,7 @@ func (c *Client) GetOAuth2Client(id string) (*OAuth2ClientJSON, bool, error) {
|
||||
}
|
||||
}
|
||||
|
||||
func (c *Client) ListOAuth2Client() ([]*OAuth2ClientJSON, error) {
|
||||
func (c *InternalClient) ListOAuth2Client() ([]*OAuth2ClientJSON, error) {
|
||||
|
||||
var jsonClientList []*OAuth2ClientJSON
|
||||
|
||||
@ -62,7 +98,7 @@ func (c *Client) ListOAuth2Client() ([]*OAuth2ClientJSON, error) {
|
||||
}
|
||||
}
|
||||
|
||||
func (c *Client) PostOAuth2Client(o *OAuth2ClientJSON) (*OAuth2ClientJSON, error) {
|
||||
func (c *InternalClient) PostOAuth2Client(o *OAuth2ClientJSON) (*OAuth2ClientJSON, error) {
|
||||
|
||||
var jsonClient *OAuth2ClientJSON
|
||||
|
||||
@ -86,7 +122,7 @@ func (c *Client) PostOAuth2Client(o *OAuth2ClientJSON) (*OAuth2ClientJSON, error
|
||||
}
|
||||
}
|
||||
|
||||
func (c *Client) PutOAuth2Client(o *OAuth2ClientJSON) (*OAuth2ClientJSON, error) {
|
||||
func (c *InternalClient) PutOAuth2Client(o *OAuth2ClientJSON) (*OAuth2ClientJSON, error) {
|
||||
|
||||
var jsonClient *OAuth2ClientJSON
|
||||
|
||||
@ -107,7 +143,7 @@ func (c *Client) PutOAuth2Client(o *OAuth2ClientJSON) (*OAuth2ClientJSON, error)
|
||||
return jsonClient, nil
|
||||
}
|
||||
|
||||
func (c *Client) DeleteOAuth2Client(id string) error {
|
||||
func (c *InternalClient) DeleteOAuth2Client(id string) error {
|
||||
|
||||
req, err := c.newRequest(http.MethodDelete, id, nil)
|
||||
if err != nil {
|
||||
@ -123,14 +159,14 @@ func (c *Client) DeleteOAuth2Client(id string) error {
|
||||
case http.StatusNoContent:
|
||||
return nil
|
||||
case http.StatusNotFound:
|
||||
fmt.Printf("client with id %s does not exist", id)
|
||||
fmt.Printf("InternalClient with id %s does not exist", id)
|
||||
return nil
|
||||
default:
|
||||
return fmt.Errorf("%s %s http request returned unexpected status code %s", req.Method, req.URL.String(), resp.Status)
|
||||
}
|
||||
}
|
||||
|
||||
func (c *Client) newRequest(method, relativePath string, body interface{}) (*http.Request, error) {
|
||||
func (c *InternalClient) newRequest(method, relativePath string, body interface{}) (*http.Request, error) {
|
||||
|
||||
var buf io.ReadWriter
|
||||
if body != nil {
|
||||
@ -162,7 +198,7 @@ func (c *Client) newRequest(method, relativePath string, body interface{}) (*htt
|
||||
|
||||
}
|
||||
|
||||
func (c *Client) do(req *http.Request, v interface{}) (*http.Response, error) {
|
||||
func (c *InternalClient) do(req *http.Request, v interface{}) (*http.Response, error) {
|
||||
resp, err := c.HTTPClient.Do(req)
|
||||
if err != nil {
|
||||
return nil, err
|
||||
|
@ -12,9 +12,10 @@ import (
|
||||
|
||||
"k8s.io/utils/pointer"
|
||||
|
||||
"github.com/ory/hydra-maester/hydra"
|
||||
"github.com/stretchr/testify/assert"
|
||||
"github.com/stretchr/testify/require"
|
||||
|
||||
"github.com/ory/hydra-maester/hydra"
|
||||
)
|
||||
|
||||
const (
|
||||
@ -60,7 +61,7 @@ func TestCRUD(t *testing.T) {
|
||||
|
||||
assert := assert.New(t)
|
||||
|
||||
c := hydra.Client{
|
||||
c := hydra.InternalClient{
|
||||
HTTPClient: &http.Client{},
|
||||
HydraURL: url.URL{Scheme: schemeHTTP},
|
||||
}
|
||||
@ -397,7 +398,7 @@ func TestCRUD(t *testing.T) {
|
||||
})
|
||||
}
|
||||
|
||||
func runServer(c *hydra.Client, h http.HandlerFunc) {
|
||||
func runServer(c *hydra.InternalClient, h http.HandlerFunc) {
|
||||
s := httptest.NewServer(h)
|
||||
serverUrl, _ := url.Parse(s.URL)
|
||||
c.HydraURL = *serverUrl.ResolveReference(&url.URL{Path: clientsEndpoint})
|
||||
|
@ -2,8 +2,12 @@ package hydra
|
||||
|
||||
import (
|
||||
"encoding/json"
|
||||
"fmt"
|
||||
|
||||
"github.com/pkg/errors"
|
||||
"k8s.io/utils/pointer"
|
||||
|
||||
hydrav1alpha1 "github.com/ory/hydra-maester/api/v1alpha1"
|
||||
)
|
||||
|
||||
// OAuth2ClientJSON represents an OAuth2 client digestible by ORY Hydra
|
||||
@ -23,7 +27,8 @@ type OAuth2ClientJSON struct {
|
||||
Metadata json.RawMessage `json:"metadata,omitempty"`
|
||||
}
|
||||
|
||||
// Oauth2ClientCredentials represents client ID and password fetched from a Kubernetes secret
|
||||
// Oauth2ClientCredentials represents client ID and password fetched from a
|
||||
// Kubernetes secret
|
||||
type Oauth2ClientCredentials struct {
|
||||
ID []byte
|
||||
Password []byte
|
||||
@ -36,3 +41,49 @@ func (oj *OAuth2ClientJSON) WithCredentials(credentials *Oauth2ClientCredentials
|
||||
}
|
||||
return oj
|
||||
}
|
||||
|
||||
// FromOAuth2Client converts an OAuth2Client into a OAuth2ClientJSON object that represents an OAuth2 InternalClient digestible by ORY Hydra
|
||||
func FromOAuth2Client(c *hydrav1alpha1.OAuth2Client) (*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 &OAuth2ClientJSON{
|
||||
ClientName: c.Spec.ClientName,
|
||||
GrantTypes: grantToStringSlice(c.Spec.GrantTypes),
|
||||
ResponseTypes: responseToStringSlice(c.Spec.ResponseTypes),
|
||||
RedirectURIs: redirectToStringSlice(c.Spec.RedirectURIs),
|
||||
PostLogoutRedirectURIs: redirectToStringSlice(c.Spec.PostLogoutRedirectURIs),
|
||||
AllowedCorsOrigins: redirectToStringSlice(c.Spec.AllowedCorsOrigins),
|
||||
Audience: c.Spec.Audience,
|
||||
Scope: c.Spec.Scope,
|
||||
Owner: fmt.Sprintf("%s/%s", c.Name, c.Namespace),
|
||||
TokenEndpointAuthMethod: string(c.Spec.TokenEndpointAuthMethod),
|
||||
Metadata: meta,
|
||||
}, nil
|
||||
}
|
||||
|
||||
func responseToStringSlice(rt []hydrav1alpha1.ResponseType) []string {
|
||||
var output = make([]string, len(rt))
|
||||
for i, elem := range rt {
|
||||
output[i] = string(elem)
|
||||
}
|
||||
return output
|
||||
}
|
||||
|
||||
func grantToStringSlice(gt []hydrav1alpha1.GrantType) []string {
|
||||
var output = make([]string, len(gt))
|
||||
for i, elem := range gt {
|
||||
output[i] = string(elem)
|
||||
}
|
||||
return output
|
||||
}
|
||||
|
||||
func redirectToStringSlice(ru []hydrav1alpha1.RedirectURI) []string {
|
||||
var output = make([]string, len(ru))
|
||||
for i, elem := range ru {
|
||||
output[i] = string(elem)
|
||||
}
|
||||
return output
|
||||
}
|
||||
|
Reference in New Issue
Block a user