Commit 1bbca1d4 authored by Bobby Rullo's avatar Bobby Rullo

schema: tweaks to make Client API more regular

parent c2c7f03f
package adminschema
import (
"errors"
"net/url"
"github.com/coreos/dex/client"
"github.com/coreos/go-oidc/oidc"
)
func MapSchemaClientToClient(sc Client) (client.Client, error) {
c := client.Client{
Credentials: oidc.ClientCredentials{
ID: sc.Id,
Secret: sc.Secret,
},
Metadata: oidc.ClientMetadata{
RedirectURIs: make([]url.URL, len(sc.RedirectURIs)),
},
}
for i, ru := range sc.RedirectURIs {
if ru == "" {
return client.Client{}, errors.New("redirect URL empty")
}
u, err := url.Parse(ru)
if err != nil {
return client.Client{}, errors.New("redirect URL invalid")
}
c.Metadata.RedirectURIs[i] = *u
}
c.Metadata.ClientName = sc.ClientName
if sc.LogoURI != "" {
logoURI, err := url.Parse(sc.LogoURI)
if err != nil {
return client.Client{}, errors.New("logoURI invalid")
}
c.Metadata.LogoURI = logoURI
}
if sc.ClientURI != "" {
clientURI, err := url.Parse(sc.ClientURI)
if err != nil {
return client.Client{}, errors.New("clientURI invalid")
}
c.Metadata.ClientURI = clientURI
}
return c, nil
}
func MapClientToSchemaClient(c client.Client) Client {
cl := Client{
Id: c.Credentials.ID,
Secret: c.Credentials.Secret,
RedirectURIs: make([]string, len(c.Metadata.RedirectURIs)),
}
for i, u := range c.Metadata.RedirectURIs {
cl.RedirectURIs[i] = u.String()
}
cl.ClientName = c.Metadata.ClientName
if c.Metadata.LogoURI != nil {
cl.LogoURI = c.Metadata.LogoURI.String()
}
if c.Metadata.ClientURI != nil {
cl.ClientURI = c.Metadata.ClientURI.String()
}
return cl
}
package adminschema
import (
"net/url"
"testing"
"github.com/coreos/go-oidc/oidc"
"github.com/kylelemons/godebug/pretty"
"github.com/coreos/dex/client"
)
func TestMapSchemaClientToClient(t *testing.T) {
tests := []struct {
sc Client
want client.Client
wantErr bool
}{
{
sc: Client{
Id: "123",
Secret: "sec_123",
RedirectURIs: []string{
"https://client.example.com",
"https://client2.example.com",
},
ClientName: "Bill",
LogoURI: "https://logo.example.com",
ClientURI: "https://clientURI.example.com",
},
want: client.Client{
Credentials: oidc.ClientCredentials{
ID: "123",
Secret: "sec_123",
},
Metadata: oidc.ClientMetadata{
RedirectURIs: []url.URL{
*mustParseURL(t, "https://client.example.com"),
*mustParseURL(t, "https://client2.example.com"),
},
ClientName: "Bill",
LogoURI: mustParseURL(t, "https://logo.example.com"),
ClientURI: mustParseURL(t, "https://clientURI.example.com"),
},
},
}, {
sc: Client{
Id: "123",
Secret: "sec_123",
RedirectURIs: []string{
"ht.d://p * * *",
},
},
wantErr: true,
},
}
for i, tt := range tests {
got, err := MapSchemaClientToClient(tt.sc)
if tt.wantErr {
if err == nil {
t.Errorf("case %d: want non-nil error", i)
t.Logf(pretty.Sprint(got))
}
continue
}
if err != nil {
t.Errorf("case %d: unexpected error mapping: %v", i, err)
}
if diff := pretty.Compare(tt.want, got); diff != "" {
t.Errorf("case %d: Compare(want, got): %v", i, diff)
}
}
}
func TestMapClientToClientSchema(t *testing.T) {
tests := []struct {
c client.Client
want Client
}{
{
want: Client{
Id: "123",
Secret: "sec_123",
RedirectURIs: []string{
"https://client.example.com",
"https://client2.example.com",
},
ClientName: "Bill",
LogoURI: "https://logo.example.com",
ClientURI: "https://clientURI.example.com",
},
c: client.Client{
Credentials: oidc.ClientCredentials{
ID: "123",
Secret: "sec_123",
},
Metadata: oidc.ClientMetadata{
RedirectURIs: []url.URL{
*mustParseURL(t, "https://client.example.com"),
*mustParseURL(t, "https://client2.example.com"),
},
ClientName: "Bill",
LogoURI: mustParseURL(t, "https://logo.example.com"),
ClientURI: mustParseURL(t, "https://clientURI.example.com"),
},
},
},
}
for i, tt := range tests {
got := MapClientToSchemaClient(tt.c)
if diff := pretty.Compare(tt.want, got); diff != "" {
t.Errorf("case %d: Compare(want, got): %v", i, diff)
}
}
}
func mustParseURL(t *testing.T, s string) *url.URL {
u, err := url.Parse(s)
if err != nil {
t.Fatalf("Cannot parse %v as url: %v", s, err)
}
return u
}
...@@ -45,50 +45,59 @@ ...@@ -45,50 +45,59 @@
} }
} }
}, },
"ClientCreateRequest": { "Client": {
"id": "ClientCreateRequest", "id": "Client",
"type": "object", "type": "object",
"description": "A request to register a client with dex.",
"properties": { "properties": {
"id": {
"type": "string",
"description": "The client ID. Ignored in client create requests."
},
"secret": {
"type": "string",
"description": "The client secret. Ignored in client create requests."
},
"isAdmin": { "isAdmin": {
"type": "boolean" "type": "boolean"
}, },
"client": { "redirectURIs": {
"type": "object",
"properties": {
"redirect_uris": {
"type": "array", "type": "array",
"items": { "items": {
"type": "string" "type": "string"
}, },
"description": "REQUIRED. Array of Redirection URI values used by the Client. One of these registered Redirection URI values MUST exactly match the redirect_uri parameter value used in each Authorization Request, with the matching performed as described in Section 6.2.1 of [RFC3986] ( Berners-Lee, T., Fielding, R., and L. Masinter, “Uniform Resource Identifier (URI): Generic Syntax,” January 2005. ) (Simple String Comparison)." "description": "REQUIRED. Array of Redirection URI values used by the Client. One of these registered Redirection URI values MUST exactly match the redirect_uri parameter value used in each Authorization Request, with the matching performed as described in Section 6.2.1 of [RFC3986] ( Berners-Lee, T., Fielding, R., and L. Masinter, “Uniform Resource Identifier (URI): Generic Syntax,” January 2005. ) (Simple String Comparison)."
}, },
"client_name": { "clientName": {
"type": "string", "type": "string",
"description": "OPTIONAL. Name of the Client to be presented to the End-User. If desired, representation of this Claim in different languages and scripts is represented as described in Section 2.1 ( Metadata Languages and Scripts ) ." "description": "OPTIONAL. Name of the Client to be presented to the End-User. If desired, representation of this Claim in different languages and scripts is represented as described in Section 2.1 ( Metadata Languages and Scripts ) ."
}, },
"logo_uri": { "logoURI": {
"type": "string", "type": "string",
"description": "OPTIONAL. URL that references a logo for the Client application. If present, the server SHOULD display this image to the End-User during approval. The value of this field MUST point to a valid image file. If desired, representation of this Claim in different languages and scripts is represented as described in Section 2.1 ( Metadata Languages and Scripts ) ." "description": "OPTIONAL. URL that references a logo for the Client application. If present, the server SHOULD display this image to the End-User during approval. The value of this field MUST point to a valid image file. If desired, representation of this Claim in different languages and scripts is represented as described in Section 2.1 ( Metadata Languages and Scripts ) ."
}, },
"client_uri": { "clientURI": {
"type": "string", "type": "string",
"description": "OPTIONAL. URL of the home page of the Client. The value of this field MUST point to a valid Web page. If present, the server SHOULD display this URL to the End-User in a followable fashion. If desired, representation of this Claim in different languages and scripts is represented as described in Section 2.1 ( Metadata Languages and Scripts ) ." "description": "OPTIONAL. URL of the home page of the Client. The value of this field MUST point to a valid Web page. If present, the server SHOULD display this URL to the End-User in a followable fashion. If desired, representation of this Claim in different languages and scripts is represented as described in Section 2.1 ( Metadata Languages and Scripts ) ."
} }
} }
},
"ClientCreateRequest": {
"id": "ClientCreateRequest",
"type": "object",
"description": "A request to register a client with dex.",
"properties": {
"client": {
"$ref": "Client"
} }
} }
}, },
"ClientRegistrationResponse": { "ClientCreateResponse": {
"id": "ClientRegistrationResponse", "id": "ClientCreateResponse",
"type": "object", "type": "object",
"description": "Upon successful registration, an ID and secret is assigned to the client.", "description": "Upon successful registration, an ID and secret is assigned to the client.",
"properties": { "properties": {
"client_id": { "client":{
"type": "string" "$ref": "Client"
},
"client_secret": {
"type": "string"
} }
} }
} }
...@@ -154,7 +163,7 @@ ...@@ -154,7 +163,7 @@
"$ref": "ClientCreateRequest" "$ref": "ClientCreateRequest"
}, },
"response": { "response": {
"$ref": "ClientRegistrationResponse" "$ref": "ClientCreateResponse"
} }
} }
} }
......
Markdown is supported
0% or
You are about to add 0 people to the discussion. Proceed with caution.
Finish editing this message first!
Please register or to comment