userinfo and more

This commit is contained in:
Livio Amstutz 2019-12-10 14:50:39 +01:00
parent 7210be8e4b
commit 85814fb69a
12 changed files with 702 additions and 134 deletions

View file

@ -75,7 +75,7 @@ func (a *AuthRequest) GetNonce() string {
}
func (a *AuthRequest) GetRedirectURI() string {
return "https://op.certification.openid.net:62054/authz_cb"
return a.RedirectURI
// return "http://localhost:5556/auth/callback"
}
@ -104,7 +104,7 @@ var (
)
func (s *AuthStorage) CreateAuthRequest(authReq *oidc.AuthRequest) (op.AuthRequest, error) {
a = &AuthRequest{ID: "id", ClientID: authReq.ClientID, ResponseType: authReq.ResponseType, Nonce: authReq.Nonce}
a = &AuthRequest{ID: "id", ClientID: authReq.ClientID, ResponseType: authReq.ResponseType, Nonce: authReq.Nonce, RedirectURI: authReq.RedirectURI}
return a, nil
}
func (s *OPStorage) GetClientByClientID(id string) (op.Client, error) {
@ -134,21 +134,7 @@ func (s *AuthStorage) DeleteAuthRequestAndCode(string, string) error {
return nil
}
func (s *AuthStorage) AuthRequestByID(id string) (op.AuthRequest, error) {
if id == "none" {
return nil, errors.New("not found")
}
var responseType oidc.ResponseType
if id == "code" {
responseType = oidc.ResponseTypeCode
} else if id == "id" {
responseType = oidc.ResponseTypeIDTokenOnly
} else {
responseType = oidc.ResponseTypeIDToken
}
return &AuthRequest{
ResponseType: responseType,
RedirectURI: "/callback",
}, nil
return a, nil
}
func (s *AuthStorage) GetSigningKey() (*jose.SigningKey, error) {
@ -166,6 +152,49 @@ func (s *AuthStorage) GetKeySet() (jose.JSONWebKeySet, error) {
}, nil
}
func (s *OPStorage) GetUserinfoFromScopes([]string) (interface{}, error) {
return &oidc.Test{
Userinfo: oidc.Userinfo{
Subject: a.GetSubject(),
Address: &oidc.UserinfoAddress{
StreetAddress: "Hjkhkj 789\ndsf",
},
UserinfoEmail: oidc.UserinfoEmail{
Email: "test",
EmailVerified: true,
},
UserinfoPhone: oidc.UserinfoPhone{
PhoneNumber: "sadsa",
PhoneNumberVerified: true,
},
UserinfoProfile: oidc.UserinfoProfile{
UpdatedAt: time.Now(),
},
// Claims: map[string]interface{}{
// "test": "test",
// "hkjh": "",
// },
},
Add: "jkhnkj",
}, nil
}
type info struct {
Subject string
}
func (i *info) GetSubject() string {
return i.Subject
}
func (i *info) Claims() map[string]interface{} {
return map[string]interface{}{
"hodor": "hoidoir",
"email": "asdfd",
"emailVerfied": true,
}
}
type ConfClient struct {
applicationType op.ApplicationType
}
@ -177,8 +206,8 @@ func (c *ConfClient) RedirectURIs() []string {
"http://localhost:5556/auth/callback",
"custom://callback",
"https://localhost:8443/test/a/instructions-example/callback",
"https://op.certification.openid.net:62054/authz_cb",
"https://op.certification.openid.net:62054/authz_post",
"https://op.certification.openid.net:62064/authz_cb",
"https://op.certification.openid.net:62064/authz_post",
}
}

233
pkg/oidc/userinfo.go Normal file
View file

@ -0,0 +1,233 @@
package oidc
import (
"encoding/json"
"time"
)
type Test struct {
Userinfo
Add string `json:"add,omitempty"`
}
type Userinfo struct {
Subject string
Address *UserinfoAddress
UserinfoProfile
UserinfoEmail
UserinfoPhone
claims map[string]interface{}
}
// type UserinfoJSON struct {
// Subject string `json:"subject,omitempty"`
// Address *UserinfoAddress `json:"address,omitempty"`
// Email string `json:"email,omitempty"`
// EmailVerified bool `json:"email_verified,omitempty"`
// UserinfoProfileJSON
// PhoneNumber string `json:"phone_number,omitempty"`
// PhoneNumberVerified bool `json:"phone_number_verified,omitempty"`
// Claims map[string]interface{} `json:",omitempty"`
// }
// type Claims map[string]interface{}
type UserinfoPhone struct {
PhoneNumber string
PhoneNumberVerified bool
}
type UserinfoProfile struct {
Name string
GivenName string
FamilyName string
MiddleName string
Nickname string
Profile string
Picture string
Website string
Gender Gender
Birthdate string
Zoneinfo string
// Locale language.Tag
UpdatedAt time.Time
PreferredUsername string
}
// func (i *UserinfoProfile) MarshalJSON() ([]byte, error) {
// j := new(UserinfoProfileJSON)
// j.UpdatedAt = i.UpdatedAt
// return json.Marshal(j)
// }
type UserinfoProfileJSON struct {
Name string `json:"name,omitempty"`
GivenName string `json:"given_name,omitempty"`
FamilyName string `json:"family_name,omitempty"`
MiddleName string `json:"middle_name,omitempty"`
Nickname string `json:"nickname,omitempty"`
Profile string `json:"profile,omitempty"`
Picture string `json:"picture,omitempty"`
Website string `json:"website,omitempty"`
Gender Gender `json:"gender,omitempty"`
Birthdate string `json:"birthdate,omitempty"`
Zoneinfo string `json:"zoneinfo,omitempty"`
// Locale language.Tag `json:"locale,omitempty"`
UpdatedAt int64 `json:"updated_at,omitempty"`
PreferredUsername string `json:"preferred_username,omitempty"`
}
type Gender string
type UserinfoAddress struct {
Formatted string
StreetAddress string
Locality string
Region string
PostalCode string
Country string
}
type UserinfoEmail struct {
Email string
EmailVerified bool
}
func marshalUserinfoProfile(i UserinfoProfile, claims map[string]interface{}) {
claims["updated_at"] = i.UpdatedAt.UTC().Unix()
}
func marshalUserinfoEmail(i UserinfoEmail, claims map[string]interface{}) {
if i.Email != "" {
claims["email"] = i.Email
}
if i.EmailVerified {
claims["email_verified"] = i.EmailVerified
}
}
func marshalUserinfoAddress(i *UserinfoAddress, claims map[string]interface{}) {
if i == nil {
return
}
address := make(map[string]interface{})
if i.Formatted != "" {
address["formatted"] = i.Formatted
}
if i.StreetAddress != "" {
address["street_address"] = i.StreetAddress
}
claims["address"] = address
// claims["email_verified"] = i.EmailVerified
}
func marshalUserinfoPhone(i UserinfoPhone, claims map[string]interface{}) {
claims["phone_number"] = i.PhoneNumber
claims["phone_number_verified"] = i.PhoneNumberVerified
}
// func copyClaims(j *Claims, i map[string]interface{}) {
// // *j, _ = json.Marshal(i)
// }
// func (p Userinfo) MarshalJSON() ([]byte, error) {
// j := new(UserinfoJSON)
// j.Subject = p.Subject
// b, _ := json.Marshal(j)
// var m map[string]json.RawMessage
// json.Unmarshal(b, &m)
// // Add tags to the map, possibly overriding struct fields
// // for k, v := range p.Claims {
// // // if overriding struct fields is not acceptable:
// // // if _, ok := m[k]; ok { continue }
// // b, _ = json.Marshal(v)
// // ms[k] = json.RawMessage(b)
// // }
// return json.Marshal(m)
// }
func (i *Userinfo) MarshalJSON() ([]byte, error) {
claims := i.claims
if claims == nil {
claims = make(map[string]interface{})
}
// j := new(UserinfoJSON)
// j.Subject = i.Subject
// j.Address = i.Address
// j.Email = i.Email
// j.EmailVerified = i.EmailVerified
// j.PhoneNumber = i.PhoneNumber
// j.PhoneNumberVerified = i.PhoneNumberVerified
// j.Claims = make(map[string]interface{})
// claims := map[string]interface{}{
// "sdsa": "jajfi",
// "a23r": "",
// }
// j.Claims["Sdsa"] = "sads"
// j.Claims["3454"] = ""
// st := new(structpb.Struct)
// b, _ := json.Marshal(j)
// err := jsonpb.Unmarshal(bytes.NewReader(b), st)
// if err != nil {
// return nil, err
// }
// fmt.Println("st", st)
// m := new(jsonpb.Marshaler)
// m.EmitDefaults = false
// s, _ := m.MarshalToString(st)
// return []byte(s), nil
// claims["phone_number"] = i.PhoneNumber
claims["sub"] = i.Subject
marshalUserinfoAddress(i.Address, claims)
marshalUserinfoEmail(i.UserinfoEmail, claims)
marshalUserinfoPhone(i.UserinfoPhone, claims)
marshalUserinfoProfile(i.UserinfoProfile, claims)
// for k, v := range claims {
// j.Claims[k] = v
// }
// j.Claims = Claims(m)
// copyClaims(&j.Claims, i.Claims)
// j.Claims, _ = json.Marshal(i.Claims)
// j.Subject = i.Subject
// if j.Claims == nil {
// j.Claims = make(map[string]interface{})
// }
// j.Claims["sub"] = i.Subject
// if i.Address != nil {
// j.Claims["address"] = i.Address
// }
// if i.Email != "" {
// j.Claims["email"] = i.Email
// }
// if i.EmailVerified {
// j.Claims["email_verified"] = i.EmailVerified
// }
// if i.PhoneNumber != "" {
// j.Claims["phone_number"] = i.PhoneNumber
// }
// if i.PhoneNumberVerified {
// j.Claims["phone_number_verified"] = i.PhoneNumberVerified
// }
// if !i.UpdatedAt.IsZero() {
// j.Claims["updated_at"] = i.UpdatedAt.UTC().Unix()
// }
return json.Marshal(claims)
}
func (i *Userinfo) UnmmarshalJSON(data []byte) error {
if err := json.Unmarshal(data, i); err != nil {
return err
}
return json.Unmarshal(data, i.claims)
}

View file

@ -14,7 +14,6 @@ type Configuration interface {
KeysEndpoint() Endpoint
// SupportedScopes() []string
AuthMethodBasicSupported() bool
AuthMethodPostSupported() bool
Port() string

View file

@ -16,8 +16,8 @@ const (
defaultUserinfoEndpoint = "userinfo"
defaultKeysEndpoint = "keys"
authMethodBasic = "client_secret_basic"
authMethodPost = "client_secret_post"
AuthMethodBasic = "client_secret_basic"
AuthMethodPost = "client_secret_post"
DefaultIDTokenValidity = time.Duration(5 * time.Minute)
)
@ -251,5 +251,5 @@ func (p *DefaultOP) handleTokenExchange(w http.ResponseWriter, r *http.Request)
}
func (p *DefaultOP) HandleUserinfo(w http.ResponseWriter, r *http.Request) {
w.Write([]byte("ok"))
Userinfo(w, r, p)
}

View file

@ -20,27 +20,38 @@ func CreateDiscoveryConfig(c Configuration, s Signer) *oidc.DiscoveryConfigurati
UserinfoEndpoint: c.UserinfoEndpoint().Absolute(c.Issuer()),
// EndSessionEndpoint: c.TokenEndpoint().Absolute(c.Issuer())(c.EndSessionEndpoint),
// CheckSessionIframe: c.TokenEndpoint().Absolute(c.Issuer())(c.CheckSessionIframe),
JwksURI: c.KeysEndpoint().Absolute(c.Issuer()),
ScopesSupported: scopes(c),
ResponseTypesSupported: responseTypes(c),
GrantTypesSupported: grantTypes(c),
// ClaimsSupported: oidc.SupportedClaims,
IDTokenSigningAlgValuesSupported: sigAlgorithms(s),
SubjectTypesSupported: subjectTypes(c),
TokenEndpointAuthMethodsSupported: authMethods(c.AuthMethodBasicSupported(), c.AuthMethodPostSupported()),
JwksURI: c.KeysEndpoint().Absolute(c.Issuer()),
ScopesSupported: Scopes(c),
ResponseTypesSupported: ResponseTypes(c),
GrantTypesSupported: GrantTypes(c),
ClaimsSupported: SupportedClaims(c),
IDTokenSigningAlgValuesSupported: SigAlgorithms(s),
SubjectTypesSupported: SubjectTypes(c),
TokenEndpointAuthMethodsSupported: AuthMethods(c),
}
}
func scopes(c Configuration) []string {
return []string{
"openid",
"profile",
"email",
"phone",
} //TODO: config
const (
ScopeOpenID = "openid"
ScopeProfile = "profile"
ScopeEmail = "email"
ScopePhone = "phone"
ScopeAddress = "address"
)
var DefaultSupportedScopes = []string{
ScopeOpenID,
ScopeProfile,
ScopeEmail,
ScopePhone,
ScopeAddress,
}
func responseTypes(c Configuration) []string {
func Scopes(c Configuration) []string {
return DefaultSupportedScopes //TODO: config
}
func ResponseTypes(c Configuration) []string {
return []string{
"code",
"id_token",
@ -51,7 +62,7 @@ func responseTypes(c Configuration) []string {
}
}
func grantTypes(c Configuration) []string {
func GrantTypes(c Configuration) []string {
return []string{
"client_credentials",
"authorization_code",
@ -60,23 +71,49 @@ func grantTypes(c Configuration) []string {
}
}
func sigAlgorithms(s Signer) []string {
func SupportedClaims(c Configuration) []string {
return []string{ //TODO: config
"sub",
"aud",
"exp",
"iat",
"iss",
"auth_time",
"nonce",
"acr",
"amr",
"c_hash",
"at_hash",
"act",
"scopes",
"client_id",
"azp",
"preferred_username",
"name",
"family_name",
"given_name",
"locale",
"email",
"email_verified",
"phone_number",
"phone_number_verified",
}
}
func SigAlgorithms(s Signer) []string {
return []string{string(s.SignatureAlgorithm())}
}
func subjectTypes(c Configuration) []string {
func SubjectTypes(c Configuration) []string {
return []string{"public"} //TODO: config
}
func authMethods(basic, post bool) []string {
authMethods := make([]string, 0, 2)
if basic {
// if c.AuthMethodBasicSupported() {
authMethods = append(authMethods, authMethodBasic)
func AuthMethods(c Configuration) []string {
authMethods := []string{
AuthMethodBasic,
}
if post {
// if c.AuthMethodPostSupported() {
authMethods = append(authMethods, authMethodPost)
if c.AuthMethodPostSupported() {
authMethods = append(authMethods, AuthMethodPost)
}
return authMethods
}

View file

@ -1,4 +1,4 @@
package op
package op_test
import (
"net/http"
@ -6,9 +6,12 @@ import (
"reflect"
"testing"
"github.com/stretchr/testify/require"
"github.com/caos/oidc/pkg/oidc"
"github.com/caos/oidc/pkg/op"
"github.com/caos/oidc/pkg/op/mock"
"github.com/golang/mock/gomock"
"github.com/stretchr/testify/require"
"gopkg.in/square/go-jose.v2"
)
func TestDiscover(t *testing.T) {
@ -30,7 +33,7 @@ func TestDiscover(t *testing.T) {
}
for _, tt := range tests {
t.Run(tt.name, func(t *testing.T) {
Discover(tt.args.w, tt.args.config)
op.Discover(tt.args.w, tt.args.config)
rec := tt.args.w.(*httptest.ResponseRecorder)
require.Equal(t, http.StatusOK, rec.Code)
require.Equal(t, `{"issuer":"https://issuer.com"}`, rec.Body.String())
@ -40,8 +43,8 @@ func TestDiscover(t *testing.T) {
func TestCreateDiscoveryConfig(t *testing.T) {
type args struct {
c Configuration
s Signer
c op.Configuration
s op.Signer
}
tests := []struct {
name string
@ -52,7 +55,7 @@ func TestCreateDiscoveryConfig(t *testing.T) {
}
for _, tt := range tests {
t.Run(tt.name, func(t *testing.T) {
if got := CreateDiscoveryConfig(tt.args.c, tt.args.s); !reflect.DeepEqual(got, tt.want) {
if got := op.CreateDiscoveryConfig(tt.args.c, tt.args.s); !reflect.DeepEqual(got, tt.want) {
t.Errorf("CreateDiscoveryConfig() = %v, want %v", got, tt.want)
}
})
@ -61,27 +64,31 @@ func TestCreateDiscoveryConfig(t *testing.T) {
func Test_scopes(t *testing.T) {
type args struct {
c Configuration
c op.Configuration
}
tests := []struct {
name string
args args
want []string
}{
// TODO: Add test cases.
{
"default Scopes",
args{},
op.DefaultSupportedScopes,
},
}
for _, tt := range tests {
t.Run(tt.name, func(t *testing.T) {
if got := scopes(tt.args.c); !reflect.DeepEqual(got, tt.want) {
if got := op.Scopes(tt.args.c); !reflect.DeepEqual(got, tt.want) {
t.Errorf("scopes() = %v, want %v", got, tt.want)
}
})
}
}
func Test_responseTypes(t *testing.T) {
func Test_ResponseTypes(t *testing.T) {
type args struct {
c Configuration
c op.Configuration
}
tests := []struct {
name string
@ -92,16 +99,16 @@ func Test_responseTypes(t *testing.T) {
}
for _, tt := range tests {
t.Run(tt.name, func(t *testing.T) {
if got := responseTypes(tt.args.c); !reflect.DeepEqual(got, tt.want) {
if got := op.ResponseTypes(tt.args.c); !reflect.DeepEqual(got, tt.want) {
t.Errorf("responseTypes() = %v, want %v", got, tt.want)
}
})
}
}
func Test_grantTypes(t *testing.T) {
func Test_GrantTypes(t *testing.T) {
type args struct {
c Configuration
c op.Configuration
}
tests := []struct {
name string
@ -112,64 +119,64 @@ func Test_grantTypes(t *testing.T) {
}
for _, tt := range tests {
t.Run(tt.name, func(t *testing.T) {
if got := grantTypes(tt.args.c); !reflect.DeepEqual(got, tt.want) {
if got := op.GrantTypes(tt.args.c); !reflect.DeepEqual(got, tt.want) {
t.Errorf("grantTypes() = %v, want %v", got, tt.want)
}
})
}
}
// func Test_sigAlgorithms(t *testing.T) {
// type args struct {
// s Signer
// }
// tests := []struct {
// name string
// args args
// want []string
// }{
// {
// "",
// args{},
// []string{"RS256"},
// },
// }
// for _, tt := range tests {
// t.Run(tt.name, func(t *testing.T) {
// if got := sigAlgorithms(tt.args.s); !reflect.DeepEqual(got, tt.want) {
// t.Errorf("sigAlgorithms() = %v, want %v", got, tt.want)
// }
// })
// }
// }
// func Test_subjectTypes(t *testing.T) {
// type args struct {
// c Configuration
// }
// tests := []struct {
// name string
// args args
// want []string
// }{
// {
// "none",
// args{func()}
// }
// }
// for _, tt := range tests {
// t.Run(tt.name, func(t *testing.T) {
// if got := subjectTypes(tt.args.c); !reflect.DeepEqual(got, tt.want) {
// t.Errorf("subjectTypes() = %v, want %v", got, tt.want)
// }
// })
// }
// }
func Test_authMethods(t *testing.T) {
func TestSupportedClaims(t *testing.T) {
type args struct {
basic bool
post bool
c op.Configuration
}
tests := []struct {
name string
args args
want []string
}{
// TODO: Add test cases.
}
for _, tt := range tests {
t.Run(tt.name, func(t *testing.T) {
if got := op.SupportedClaims(tt.args.c); !reflect.DeepEqual(got, tt.want) {
t.Errorf("SupportedClaims() = %v, want %v", got, tt.want)
}
})
}
}
func Test_SigAlgorithms(t *testing.T) {
m := mock.NewMockSigner(gomock.NewController((t)))
type args struct {
s op.Signer
}
tests := []struct {
name string
args args
want []string
}{
{
"",
args{func() op.Signer {
m.EXPECT().SignatureAlgorithm().Return(jose.RS256)
return m
}()},
[]string{"RS256"},
},
}
for _, tt := range tests {
t.Run(tt.name, func(t *testing.T) {
if got := op.SigAlgorithms(tt.args.s); !reflect.DeepEqual(got, tt.want) {
t.Errorf("sigAlgorithms() = %v, want %v", got, tt.want)
}
})
}
}
func Test_SubjectTypes(t *testing.T) {
type args struct {
c op.Configuration
}
tests := []struct {
name string
@ -178,28 +185,49 @@ func Test_authMethods(t *testing.T) {
}{
{
"none",
args{false, false},
[]string{},
},
{
"basic",
args{true, false},
[]string{authMethodBasic},
},
{
"post",
args{false, true},
[]string{authMethodPost},
},
{
"basic and post",
args{true, true},
[]string{authMethodBasic, authMethodPost},
args{},
[]string{"public"},
},
}
for _, tt := range tests {
t.Run(tt.name, func(t *testing.T) {
if got := authMethods(tt.args.basic, tt.args.post); !reflect.DeepEqual(got, tt.want) {
if got := op.SubjectTypes(tt.args.c); !reflect.DeepEqual(got, tt.want) {
t.Errorf("subjectTypes() = %v, want %v", got, tt.want)
}
})
}
}
func Test_AuthMethods(t *testing.T) {
m := mock.NewMockConfiguration(gomock.NewController((t)))
type args struct {
c op.Configuration
}
tests := []struct {
name string
args args
want []string
}{
{
"imlicit basic",
args{func() op.Configuration {
m.EXPECT().AuthMethodPostSupported().Return(false)
return m
}()},
[]string{op.AuthMethodBasic},
},
{
"basic and post",
args{func() op.Configuration {
m.EXPECT().AuthMethodPostSupported().Return(true)
return m
}()},
[]string{op.AuthMethodBasic, op.AuthMethodPost},
},
}
for _, tt := range tests {
t.Run(tt.name, func(t *testing.T) {
if got := op.AuthMethods(tt.args.c); !reflect.DeepEqual(got, tt.want) {
t.Errorf("authMethods() = %v, want %v", got, tt.want)
}
})

View file

@ -0,0 +1,132 @@
// Code generated by MockGen. DO NOT EDIT.
// Source: github.com/caos/oidc/pkg/op (interfaces: Configuration)
// Package mock is a generated GoMock package.
package mock
import (
op "github.com/caos/oidc/pkg/op"
gomock "github.com/golang/mock/gomock"
reflect "reflect"
)
// MockConfiguration is a mock of Configuration interface
type MockConfiguration struct {
ctrl *gomock.Controller
recorder *MockConfigurationMockRecorder
}
// MockConfigurationMockRecorder is the mock recorder for MockConfiguration
type MockConfigurationMockRecorder struct {
mock *MockConfiguration
}
// NewMockConfiguration creates a new mock instance
func NewMockConfiguration(ctrl *gomock.Controller) *MockConfiguration {
mock := &MockConfiguration{ctrl: ctrl}
mock.recorder = &MockConfigurationMockRecorder{mock}
return mock
}
// EXPECT returns an object that allows the caller to indicate expected use
func (m *MockConfiguration) EXPECT() *MockConfigurationMockRecorder {
return m.recorder
}
// AuthMethodPostSupported mocks base method
func (m *MockConfiguration) AuthMethodPostSupported() bool {
m.ctrl.T.Helper()
ret := m.ctrl.Call(m, "AuthMethodPostSupported")
ret0, _ := ret[0].(bool)
return ret0
}
// AuthMethodPostSupported indicates an expected call of AuthMethodPostSupported
func (mr *MockConfigurationMockRecorder) AuthMethodPostSupported() *gomock.Call {
mr.mock.ctrl.T.Helper()
return mr.mock.ctrl.RecordCallWithMethodType(mr.mock, "AuthMethodPostSupported", reflect.TypeOf((*MockConfiguration)(nil).AuthMethodPostSupported))
}
// AuthorizationEndpoint mocks base method
func (m *MockConfiguration) AuthorizationEndpoint() op.Endpoint {
m.ctrl.T.Helper()
ret := m.ctrl.Call(m, "AuthorizationEndpoint")
ret0, _ := ret[0].(op.Endpoint)
return ret0
}
// AuthorizationEndpoint indicates an expected call of AuthorizationEndpoint
func (mr *MockConfigurationMockRecorder) AuthorizationEndpoint() *gomock.Call {
mr.mock.ctrl.T.Helper()
return mr.mock.ctrl.RecordCallWithMethodType(mr.mock, "AuthorizationEndpoint", reflect.TypeOf((*MockConfiguration)(nil).AuthorizationEndpoint))
}
// Issuer mocks base method
func (m *MockConfiguration) Issuer() string {
m.ctrl.T.Helper()
ret := m.ctrl.Call(m, "Issuer")
ret0, _ := ret[0].(string)
return ret0
}
// Issuer indicates an expected call of Issuer
func (mr *MockConfigurationMockRecorder) Issuer() *gomock.Call {
mr.mock.ctrl.T.Helper()
return mr.mock.ctrl.RecordCallWithMethodType(mr.mock, "Issuer", reflect.TypeOf((*MockConfiguration)(nil).Issuer))
}
// KeysEndpoint mocks base method
func (m *MockConfiguration) KeysEndpoint() op.Endpoint {
m.ctrl.T.Helper()
ret := m.ctrl.Call(m, "KeysEndpoint")
ret0, _ := ret[0].(op.Endpoint)
return ret0
}
// KeysEndpoint indicates an expected call of KeysEndpoint
func (mr *MockConfigurationMockRecorder) KeysEndpoint() *gomock.Call {
mr.mock.ctrl.T.Helper()
return mr.mock.ctrl.RecordCallWithMethodType(mr.mock, "KeysEndpoint", reflect.TypeOf((*MockConfiguration)(nil).KeysEndpoint))
}
// Port mocks base method
func (m *MockConfiguration) Port() string {
m.ctrl.T.Helper()
ret := m.ctrl.Call(m, "Port")
ret0, _ := ret[0].(string)
return ret0
}
// Port indicates an expected call of Port
func (mr *MockConfigurationMockRecorder) Port() *gomock.Call {
mr.mock.ctrl.T.Helper()
return mr.mock.ctrl.RecordCallWithMethodType(mr.mock, "Port", reflect.TypeOf((*MockConfiguration)(nil).Port))
}
// TokenEndpoint mocks base method
func (m *MockConfiguration) TokenEndpoint() op.Endpoint {
m.ctrl.T.Helper()
ret := m.ctrl.Call(m, "TokenEndpoint")
ret0, _ := ret[0].(op.Endpoint)
return ret0
}
// TokenEndpoint indicates an expected call of TokenEndpoint
func (mr *MockConfigurationMockRecorder) TokenEndpoint() *gomock.Call {
mr.mock.ctrl.T.Helper()
return mr.mock.ctrl.RecordCallWithMethodType(mr.mock, "TokenEndpoint", reflect.TypeOf((*MockConfiguration)(nil).TokenEndpoint))
}
// UserinfoEndpoint mocks base method
func (m *MockConfiguration) UserinfoEndpoint() op.Endpoint {
m.ctrl.T.Helper()
ret := m.ctrl.Call(m, "UserinfoEndpoint")
ret0, _ := ret[0].(op.Endpoint)
return ret0
}
// UserinfoEndpoint indicates an expected call of UserinfoEndpoint
func (mr *MockConfigurationMockRecorder) UserinfoEndpoint() *gomock.Call {
mr.mock.ctrl.T.Helper()
return mr.mock.ctrl.RecordCallWithMethodType(mr.mock, "UserinfoEndpoint", reflect.TypeOf((*MockConfiguration)(nil).UserinfoEndpoint))
}

View file

@ -3,3 +3,5 @@ package mock
//go:generate mockgen -package mock -destination ./storage.mock.go github.com/caos/oidc/pkg/op Storage
//go:generate mockgen -package mock -destination ./authorizer.mock.go github.com/caos/oidc/pkg/op Authorizer
//go:generate mockgen -package mock -destination ./client.mock.go github.com/caos/oidc/pkg/op Client
//go:generate mockgen -package mock -destination ./configuration.mock.go github.com/caos/oidc/pkg/op Configuration
//go:generate mockgen -package mock -destination ./signer.mock.go github.com/caos/oidc/pkg/op Signer

View file

@ -0,0 +1,64 @@
// Code generated by MockGen. DO NOT EDIT.
// Source: github.com/caos/oidc/pkg/op (interfaces: Signer)
// Package mock is a generated GoMock package.
package mock
import (
oidc "github.com/caos/oidc/pkg/oidc"
gomock "github.com/golang/mock/gomock"
go_jose_v2 "gopkg.in/square/go-jose.v2"
reflect "reflect"
)
// MockSigner is a mock of Signer interface
type MockSigner struct {
ctrl *gomock.Controller
recorder *MockSignerMockRecorder
}
// MockSignerMockRecorder is the mock recorder for MockSigner
type MockSignerMockRecorder struct {
mock *MockSigner
}
// NewMockSigner creates a new mock instance
func NewMockSigner(ctrl *gomock.Controller) *MockSigner {
mock := &MockSigner{ctrl: ctrl}
mock.recorder = &MockSignerMockRecorder{mock}
return mock
}
// EXPECT returns an object that allows the caller to indicate expected use
func (m *MockSigner) EXPECT() *MockSignerMockRecorder {
return m.recorder
}
// SignIDToken mocks base method
func (m *MockSigner) SignIDToken(arg0 *oidc.IDTokenClaims) (string, error) {
m.ctrl.T.Helper()
ret := m.ctrl.Call(m, "SignIDToken", arg0)
ret0, _ := ret[0].(string)
ret1, _ := ret[1].(error)
return ret0, ret1
}
// SignIDToken indicates an expected call of SignIDToken
func (mr *MockSignerMockRecorder) SignIDToken(arg0 interface{}) *gomock.Call {
mr.mock.ctrl.T.Helper()
return mr.mock.ctrl.RecordCallWithMethodType(mr.mock, "SignIDToken", reflect.TypeOf((*MockSigner)(nil).SignIDToken), arg0)
}
// SignatureAlgorithm mocks base method
func (m *MockSigner) SignatureAlgorithm() go_jose_v2.SignatureAlgorithm {
m.ctrl.T.Helper()
ret := m.ctrl.Call(m, "SignatureAlgorithm")
ret0, _ := ret[0].(go_jose_v2.SignatureAlgorithm)
return ret0
}
// SignatureAlgorithm indicates an expected call of SignatureAlgorithm
func (mr *MockSignerMockRecorder) SignatureAlgorithm() *gomock.Call {
mr.mock.ctrl.T.Helper()
return mr.mock.ctrl.RecordCallWithMethodType(mr.mock, "SignatureAlgorithm", reflect.TypeOf((*MockSigner)(nil).SignatureAlgorithm))
}

View file

@ -168,3 +168,18 @@ func (mr *MockStorageMockRecorder) GetSigningKey() *gomock.Call {
mr.mock.ctrl.T.Helper()
return mr.mock.ctrl.RecordCallWithMethodType(mr.mock, "GetSigningKey", reflect.TypeOf((*MockStorage)(nil).GetSigningKey))
}
// GetUserinfoFromScopes mocks base method
func (m *MockStorage) GetUserinfoFromScopes(arg0 []string) (*oidc.Userinfo, error) {
m.ctrl.T.Helper()
ret := m.ctrl.Call(m, "GetUserinfoFromScopes", arg0)
ret0, _ := ret[0].(*oidc.Userinfo)
ret1, _ := ret[1].(error)
return ret0, ret1
}
// GetUserinfoFromScopes indicates an expected call of GetUserinfoFromScopes
func (mr *MockStorageMockRecorder) GetUserinfoFromScopes(arg0 interface{}) *gomock.Call {
mr.mock.ctrl.T.Helper()
return mr.mock.ctrl.RecordCallWithMethodType(mr.mock, "GetUserinfoFromScopes", reflect.TypeOf((*MockStorage)(nil).GetUserinfoFromScopes), arg0)
}

View file

@ -22,6 +22,7 @@ type OPStorage interface {
GetClientByClientID(string) (Client, error)
AuthorizeClientIDSecret(string, string) (Client, error)
AuthorizeClientIDCodeVerifier(string, string) (Client, error)
GetUserinfoFromScopes([]string) (*oidc.Userinfo, error)
}
type Storage interface {

28
pkg/op/userinfo.go Normal file
View file

@ -0,0 +1,28 @@
package op
import (
"net/http"
"github.com/caos/oidc/pkg/utils"
)
type UserinfoProvider interface {
Storage() Storage
}
func Userinfo(w http.ResponseWriter, r *http.Request, userinfoProvider UserinfoProvider) {
scopes, err := ScopesFromAccessToken(w, r)
if err != nil {
return
}
info, err := userinfoProvider.Storage().GetUserinfoFromScopes(scopes)
if err != nil {
utils.MarshalJSON(w, err)
return
}
utils.MarshalJSON(w, info)
}
func ScopesFromAccessToken(w http.ResponseWriter, r *http.Request) ([]string, error) {
return []string{}, nil
}