schema: tweaks to make Client API more regular

This commit is contained in:
Bobby Rullo 2016-04-15 17:22:59 -07:00
parent c2c7f03f47
commit 1bbca1d43c
3 changed files with 256 additions and 45 deletions

View file

@ -0,0 +1,73 @@
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
}

View file

@ -0,0 +1,129 @@
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
}

View file

@ -45,53 +45,62 @@
}
}
},
"ClientCreateRequest": {
"id": "ClientCreateRequest",
"type": "object",
"description": "A request to register a client with dex.",
"properties": {
"isAdmin": {
"type": "boolean"
},
"client": {
"type": "object",
"properties": {
"redirect_uris": {
"type": "array",
"items": {
"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)."
},
"client_name": {
"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 ) ."
},
"logo_uri": {
"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 ) ."
},
"client_uri": {
"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 ) ."
}
}
}
"Client": {
"id": "Client",
"type": "object",
"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": {
"type": "boolean"
},
"redirectURIs": {
"type": "array",
"items": {
"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)."
},
"clientName": {
"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 ) ."
},
"logoURI": {
"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 ) ."
},
"clientURI": {
"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 ) ."
}
}
},
"ClientRegistrationResponse": {
"id": "ClientRegistrationResponse",
"type": "object",
"description": "Upon successful registration, an ID and secret is assigned to the client.",
"properties": {
"client_id": {
"type": "string"
},
"client_secret": {
"type": "string"
}
}
"ClientCreateRequest": {
"id": "ClientCreateRequest",
"type": "object",
"description": "A request to register a client with dex.",
"properties": {
"client": {
"$ref": "Client"
}
}
},
"ClientCreateResponse": {
"id": "ClientCreateResponse",
"type": "object",
"description": "Upon successful registration, an ID and secret is assigned to the client.",
"properties": {
"client":{
"$ref": "Client"
}
}
}
},
"resources": {
"Admin": {
@ -154,7 +163,7 @@
"$ref": "ClientCreateRequest"
},
"response": {
"$ref": "ClientRegistrationResponse"
"$ref": "ClientCreateResponse"
}
}
}