schema: tweaks to make Client API more regular
This commit is contained in:
parent
c2c7f03f47
commit
1bbca1d43c
3 changed files with 256 additions and 45 deletions
73
schema/adminschema/mapper.go
Normal file
73
schema/adminschema/mapper.go
Normal 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
|
||||
}
|
129
schema/adminschema/mapper_test.go
Normal file
129
schema/adminschema/mapper_test.go
Normal 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
|
||||
}
|
|
@ -45,50 +45,59 @@
|
|||
}
|
||||
}
|
||||
},
|
||||
"ClientCreateRequest": {
|
||||
"id": "ClientCreateRequest",
|
||||
"Client": {
|
||||
"id": "Client",
|
||||
"type": "object",
|
||||
"description": "A request to register a client with dex.",
|
||||
"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"
|
||||
},
|
||||
"client": {
|
||||
"type": "object",
|
||||
"properties": {
|
||||
"redirect_uris": {
|
||||
"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)."
|
||||
},
|
||||
"client_name": {
|
||||
"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 ) ."
|
||||
},
|
||||
"logo_uri": {
|
||||
"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 ) ."
|
||||
},
|
||||
"client_uri": {
|
||||
"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 ) ."
|
||||
}
|
||||
}
|
||||
},
|
||||
"ClientCreateRequest": {
|
||||
"id": "ClientCreateRequest",
|
||||
"type": "object",
|
||||
"description": "A request to register a client with dex.",
|
||||
"properties": {
|
||||
"client": {
|
||||
"$ref": "Client"
|
||||
}
|
||||
}
|
||||
},
|
||||
"ClientRegistrationResponse": {
|
||||
"id": "ClientRegistrationResponse",
|
||||
"ClientCreateResponse": {
|
||||
"id": "ClientCreateResponse",
|
||||
"type": "object",
|
||||
"description": "Upon successful registration, an ID and secret is assigned to the client.",
|
||||
"properties": {
|
||||
"client_id": {
|
||||
"type": "string"
|
||||
},
|
||||
"client_secret": {
|
||||
"type": "string"
|
||||
"client":{
|
||||
"$ref": "Client"
|
||||
}
|
||||
}
|
||||
}
|
||||
|
@ -154,7 +163,7 @@
|
|||
"$ref": "ClientCreateRequest"
|
||||
},
|
||||
"response": {
|
||||
"$ref": "ClientRegistrationResponse"
|
||||
"$ref": "ClientCreateResponse"
|
||||
}
|
||||
}
|
||||
}
|
||||
|
|
Reference in a new issue