Skip to content

Commit

Permalink
client: Introduce SubjectType to OAuth2 Clients
Browse files Browse the repository at this point in the history
This patch introduces field `subject_type` to OAuth 2.0 Clients. See #950

Signed-off-by: arekkas <[email protected]>
  • Loading branch information
arekkas authored and arekkas committed Aug 10, 2018
1 parent 5093152 commit e99d820
Show file tree
Hide file tree
Showing 7 changed files with 77 additions and 3 deletions.
4 changes: 4 additions & 0 deletions client/client.go
Original file line number Diff line number Diff line change
Expand Up @@ -98,6 +98,10 @@ type Client struct {
// measured in UTC until the date/time of expiration.
SecretExpiresAt int `json:"client_secret_expires_at"`

// SubjectType requested for responses to this Client. The subject_types_supported Discovery parameter contains a
// list of the supported subject_type values for this server. Valid types include `pairwise` and `public`.
SubjectType string `json:"subject_type"`

// URL using the https scheme to be used in calculating Pseudonymous Identifiers by the OP. The URL references a
// file with a single JSON array of redirect_uri values.
SectorIdentifierURI string `json:"sector_identifier_uri,omitempty"`
Expand Down
3 changes: 2 additions & 1 deletion client/handler.go
Original file line number Diff line number Diff line change
Expand Up @@ -45,11 +45,12 @@ func NewHandler(
manager Manager,
h herodot.Writer,
defaultClientScopes []string,
subjectTypes []string,
) *Handler {
return &Handler{
Manager: manager,
H: h,
Validator: NewValidator(defaultClientScopes),
Validator: NewValidator(defaultClientScopes, subjectTypes),
}
}

Expand Down
13 changes: 13 additions & 0 deletions client/manager_0_sql_migrations_test.go
Original file line number Diff line number Diff line change
Expand Up @@ -81,6 +81,15 @@ var createClientMigrations = []*migrate.Migration{
`DELETE FROM hydra_client WHERE id='5-data'`,
},
},
{
Id: "6-data",
Up: []string{
`INSERT INTO hydra_client (id, client_name, client_secret, redirect_uris, grant_types, response_types, scope, owner, policy_uri, tos_uri, client_uri, logo_uri, contacts, client_secret_expires_at, sector_identifier_uri, jwks, jwks_uri, token_endpoint_auth_method, request_uris, request_object_signing_alg, userinfo_signed_response_alg, subject_type) VALUES ('6-data', 'some-client', 'abcdef', 'http://localhost|http://google', 'authorize_code|implicit', 'token|id_token', 'foo|bar', 'aeneas', 'http://policy', 'http://tos', 'http://client', 'http://logo', 'aeneas|foo', 0, 'http://sector', '{"keys": []}', 'http://jwks', 'none', 'http://uri1|http://uri2', 'rs256', 'rs526', 'public')`,
},
Down: []string{
`DELETE FROM hydra_client WHERE id='6-data'`,
},
},
}

var migrations = map[string]*migrate.MemoryMigrationSource{
Expand All @@ -97,6 +106,8 @@ var migrations = map[string]*migrate.MemoryMigrationSource{
createClientMigrations[3],
client.Migrations["mysql"].Migrations[4],
createClientMigrations[4],
client.Migrations["mysql"].Migrations[5],
createClientMigrations[5],
},
},
"postgres": {
Expand All @@ -112,6 +123,8 @@ var migrations = map[string]*migrate.MemoryMigrationSource{
createClientMigrations[3],
client.Migrations["postgres"].Migrations[4],
createClientMigrations[4],
client.Migrations["postgres"].Migrations[5],
createClientMigrations[5],
},
},
}
Expand Down
15 changes: 15 additions & 0 deletions client/manager_sql.go
Original file line number Diff line number Diff line change
Expand Up @@ -99,6 +99,15 @@ var sharedMigrations = []*migrate.Migration{
`UPDATE hydra_client SET public=TRUE WHERE token_endpoint_auth_method='none'`,
},
},
{
Id: "6",
Up: []string{
`ALTER TABLE hydra_client ADD subject_type VARCHAR(15) NOT NULL DEFAULT ''`,
},
Down: []string{
`ALTER TABLE hydra_client DROP COLUMN subject_type`,
},
},
}

var Migrations = map[string]*migrate.MemoryMigrationSource{
Expand All @@ -123,6 +132,7 @@ var Migrations = map[string]*migrate.MemoryMigrationSource{
},
},
sharedMigrations[3],
sharedMigrations[4],
}},
"postgres": {Migrations: []*migrate.Migration{
sharedMigrations[0],
Expand All @@ -145,6 +155,7 @@ var Migrations = map[string]*migrate.MemoryMigrationSource{
},
},
sharedMigrations[3],
sharedMigrations[4],
}},
}

Expand Down Expand Up @@ -173,6 +184,7 @@ type sqlData struct {
JSONWebKeys string `db:"jwks"`
TokenEndpointAuthMethod string `db:"token_endpoint_auth_method"`
RequestURIs string `db:"request_uris"`
SubjectType string `db:"subject_type"`
RequestObjectSigningAlgorithm string `db:"request_object_signing_alg"`
UserinfoSignedResponseAlg string `db:"userinfo_signed_response_alg"`
}
Expand All @@ -189,6 +201,7 @@ var sqlParams = []string{
"policy_uri",
"tos_uri",
"client_uri",
"subject_type",
"logo_uri",
"contacts",
"client_secret_expires_at",
Expand Down Expand Up @@ -234,6 +247,7 @@ func sqlDataFromClient(d *Client) (*sqlData, error) {
RequestObjectSigningAlgorithm: d.RequestObjectSigningAlgorithm,
RequestURIs: strings.Join(d.RequestURIs, "|"),
UserinfoSignedResponseAlg: d.UserinfoSignedResponseAlg,
SubjectType: d.SubjectType,
}, nil
}

Expand All @@ -259,6 +273,7 @@ func (d *sqlData) ToClient() (*Client, error) {
RequestObjectSigningAlgorithm: d.RequestObjectSigningAlgorithm,
RequestURIs: stringsx.Splitx(d.RequestURIs, "|"),
UserinfoSignedResponseAlg: d.UserinfoSignedResponseAlg,
SubjectType: d.SubjectType,
}

if d.JSONWebKeys != "" {
Expand Down
2 changes: 1 addition & 1 deletion client/sdk_test.go
Original file line number Diff line number Diff line change
Expand Up @@ -59,7 +59,7 @@ func createTestClient(prefix string) hydra.OAuth2Client {

func TestClientSDK(t *testing.T) {
manager := client.NewMemoryManager(nil)
handler := client.NewHandler(manager, herodot.NewJSONWriter(nil), []string{"foo", "bar"})
handler := client.NewHandler(manager, herodot.NewJSONWriter(nil), []string{"foo", "bar"}, []string{"public"})

router := httprouter.New()
handler.SetRoutes(router)
Expand Down
26 changes: 25 additions & 1 deletion client/validator.go
Original file line number Diff line number Diff line change
Expand Up @@ -37,13 +37,25 @@ import (
type Validator struct {
c *http.Client
DefaultClientScopes []string
SubjectTypes []string
}

func NewValidator(
defaultClientScopes []string) *Validator {
defaultClientScopes []string,
subjectTypes []string,
) *Validator {
if len(subjectTypes) == 0 {
subjectTypes = []string{"public"}
}

subjectTypes = stringslice.Filter(subjectTypes, func(s string) bool {
return !(s == "public" || s == "pairwise")
})

return &Validator{
c: http.DefaultClient,
DefaultClientScopes: defaultClientScopes,
SubjectTypes: subjectTypes,
}
}

Expand Down Expand Up @@ -94,6 +106,18 @@ func (v *Validator) Validate(c *Client) error {
}
}

if c.SubjectType != "" {
if !stringslice.Has(v.SubjectTypes, c.SubjectType) {
return errors.WithStack(fosite.ErrInvalidRequest.WithHint(fmt.Sprintf("Subject type %s is not supported by server, only %v are allowed.", c.SubjectType, v.SubjectTypes)))
}
} else {
if !stringslice.Has(v.SubjectTypes, "public") {
c.SubjectType = "public"
} else {
c.SubjectType = v.SubjectTypes[0]
}
}

return nil
}

Expand Down
17 changes: 17 additions & 0 deletions client/validator_test.go
Original file line number Diff line number Diff line change
Expand Up @@ -34,6 +34,7 @@ import (
func TestValidate(t *testing.T) {
v := &Validator{
DefaultClientScopes: []string{"openid"},
SubjectTypes: []string{"public", "pairwise"},
}
for k, tc := range []struct {
in *Client
Expand Down Expand Up @@ -72,6 +73,22 @@ func TestValidate(t *testing.T) {
in: &Client{ClientID: "foo", JSONWebKeys: &jose.JSONWebKeySet{}, JSONWebKeysURI: "asdf", TokenEndpointAuthMethod: "private_key_jwt"},
expectErr: true,
},
{
in: &Client{ClientID: "foo"},
check: func(t *testing.T, c *Client) {
assert.Equal(t, "public", c.SubjectType)
},
},
{
in: &Client{ClientID: "foo", SubjectType: "pairwise"},
check: func(t *testing.T, c *Client) {
assert.Equal(t, "pairwise", c.SubjectType)
},
},
{
in: &Client{ClientID: "foo", SubjectType: "foo"},
expectErr: true,
},
} {
t.Run(fmt.Sprintf("case=%d", k), func(t *testing.T) {
err := v.Validate(tc.in)
Expand Down

0 comments on commit e99d820

Please sign in to comment.