diff --git a/pkg/oidc/authorization.go b/pkg/oidc/authorization.go index c3245f6..02c5603 100644 --- a/pkg/oidc/authorization.go +++ b/pkg/oidc/authorization.go @@ -19,10 +19,10 @@ const ( DisplayTouch Display = "touch" DisplayWAP Display = "wap" - PromptNone = "none" - PromptLogin = "login" - PromptConsent = "consent" - PromptSelectAccount = "select_account" + PromptNone Prompt = "none" + PromptLogin Prompt = "login" + PromptConsent Prompt = "consent" + PromptSelectAccount Prompt = "select_account" GrantTypeCode GrantType = "authorization_code" @@ -63,14 +63,6 @@ type AuthRequest struct { CodeChallengeMethod CodeChallengeMethod `schema:"code_challenge_method"` } -// func (a *AuthRequest) GetID() string { -// return a.ID -// } - -// func (a *AuthRequest) GetClientID() string { -// return a.ClientID -// } - func (a *AuthRequest) GetRedirectURI() string { return a.RedirectURI } @@ -119,32 +111,6 @@ type TokenExchangeRequest struct { requestedTokenType string `schema:"requested_token_type"` } -// func (a *AuthRequest) UnmarshalText(text []byte) error { -// // var f formAuthRequest -// log.Println(string(text)) -// return nil -// } - -// type formAuthRequest struct { -// Scopes string `schema:"scope"` -// ResponseType string `schema:"response_type"` -// ClientID string `schema:"client_id"` -// RedirectURI string `schema:"redirect_uri"` //TODO: type - -// State string `schema:"state"` - -// // ResponseMode TODO: ? - -// Nonce string `schema:"nonce"` -// Display string `schema:"display"` -// Prompt string `schema:"prompt"` -// MaxAge uint32 `schema:"max_age"` -// UILocales string `schema:"ui_locales"` -// IDTokenHint string `schema:"id_token_hint"` -// LoginHint string `schema:"login_hint"` -// ACRValues []string `schema:"acr_values"` -// } - type Scopes []string func (s *Scopes) UnmarshalText(text []byte) error { diff --git a/pkg/oidc/identity_provider.go b/pkg/oidc/identity_provider.go deleted file mode 100644 index b5124fe..0000000 --- a/pkg/oidc/identity_provider.go +++ /dev/null @@ -1,13 +0,0 @@ -package oidc - -// import "net/http" - -// type IdentityProvider interface { -// // Configuration -// // Storage() Storage -// HandleDiscovery(w http.ResponseWriter, r *http.Request) -// HandleAuthorize(w http.ResponseWriter, r *http.Request) -// HandleExchange(w http.ResponseWriter, r *http.Request) -// HandleUserinfo(w http.ResponseWriter, r *http.Request) -// HttpHandler() *http.Server -// } diff --git a/pkg/oidc/token.go b/pkg/oidc/token.go index c00061d..6ebae5c 100644 --- a/pkg/oidc/token.go +++ b/pkg/oidc/token.go @@ -2,6 +2,7 @@ package oidc import ( "encoding/json" + "strings" "time" "github.com/caos/oidc/pkg/utils" @@ -31,10 +32,13 @@ func (t *IDTokenClaims) UnmarshalJSON(b []byte) error { if err := json.Unmarshal(b, &i); err != nil { return err } + audience := i.Audiences + if len(audience) == 1 { + audience = strings.Split(audience[0], " ") + } t.Issuer = i.Issuer t.Subject = i.Subject - // t.Audiences = strings.Split(i.Audiences, " ") - t.Audiences = i.Audiences + t.Audiences = audience t.Expiration = time.Unix(i.Expiration, 0).UTC() t.IssuedAt = time.Unix(i.IssuedAt, 0).UTC() t.AuthTime = time.Unix(i.AuthTime, 0).UTC() @@ -49,9 +53,8 @@ func (t *IDTokenClaims) UnmarshalJSON(b []byte) error { func (t *IDTokenClaims) MarshalJSON() ([]byte, error) { j := jsonIDToken{ - Issuer: t.Issuer, - Subject: t.Subject, - // Audiences: strings.Join(t.Audiences, " "), + Issuer: t.Issuer, + Subject: t.Subject, Audiences: t.Audiences, Expiration: t.Expiration.Unix(), IssuedAt: t.IssuedAt.Unix(), @@ -66,8 +69,6 @@ func (t *IDTokenClaims) MarshalJSON() ([]byte, error) { return json.Marshal(j) } -// type jsonTime time.Time - type jsonIDToken struct { Issuer string `json:"iss,omitempty"` Subject string `json:"sub,omitempty"` diff --git a/pkg/oidc/userinfo.go b/pkg/oidc/userinfo.go index f2a399c..5e99d09 100644 --- a/pkg/oidc/userinfo.go +++ b/pkg/oidc/userinfo.go @@ -3,12 +3,9 @@ package oidc import ( "encoding/json" "time" -) -type Test struct { - Userinfo - Add string `json:"add,omitempty"` -} + "golang.org/x/text/language" +) type Userinfo struct { Subject string @@ -20,64 +17,27 @@ type Userinfo struct { 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 + 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 { @@ -95,7 +55,20 @@ type UserinfoEmail struct { } func marshalUserinfoProfile(i UserinfoProfile, claims map[string]interface{}) { + claims["name"] = i.Name + claims["given_name"] = i.GivenName + claims["family_name"] = i.FamilyName + claims["middle_name"] = i.MiddleName + claims["nickname"] = i.Nickname + claims["profile"] = i.Profile + claims["picture"] = i.Picture + claims["website"] = i.Website + claims["gender"] = i.Gender + claims["birthdate"] = i.Birthdate + claims["Zoneinfo"] = i.Zoneinfo + claims["locale"] = i.Locale.String() claims["updated_at"] = i.UpdatedAt.UTC().Unix() + claims["preferred_username"] = i.PreferredUsername } func marshalUserinfoEmail(i UserinfoEmail, claims map[string]interface{}) { @@ -119,7 +92,6 @@ func marshalUserinfoAddress(i *UserinfoAddress, claims map[string]interface{}) { address["street_address"] = i.StreetAddress } claims["address"] = address - // claims["email_verified"] = i.EmailVerified } func marshalUserinfoPhone(i UserinfoPhone, claims map[string]interface{}) { @@ -127,101 +99,16 @@ func marshalUserinfoPhone(i UserinfoPhone, claims map[string]interface{}) { 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) } diff --git a/pkg/op/mock/authorizer.mock.go b/pkg/op/mock/authorizer.mock.go index 55c8c21..48f9aed 100644 --- a/pkg/op/mock/authorizer.mock.go +++ b/pkg/op/mock/authorizer.mock.go @@ -34,6 +34,20 @@ func (m *MockAuthorizer) EXPECT() *MockAuthorizerMockRecorder { return m.recorder } +// Crypto mocks base method +func (m *MockAuthorizer) Crypto() op.Crypto { + m.ctrl.T.Helper() + ret := m.ctrl.Call(m, "Crypto") + ret0, _ := ret[0].(op.Crypto) + return ret0 +} + +// Crypto indicates an expected call of Crypto +func (mr *MockAuthorizerMockRecorder) Crypto() *gomock.Call { + mr.mock.ctrl.T.Helper() + return mr.mock.ctrl.RecordCallWithMethodType(mr.mock, "Crypto", reflect.TypeOf((*MockAuthorizer)(nil).Crypto)) +} + // Decoder mocks base method func (m *MockAuthorizer) Decoder() *schema.Decoder { m.ctrl.T.Helper() diff --git a/pkg/op/mock/storage.mock.go b/pkg/op/mock/storage.mock.go index 69133ba..ee85922 100644 --- a/pkg/op/mock/storage.mock.go +++ b/pkg/op/mock/storage.mock.go @@ -35,21 +35,6 @@ func (m *MockStorage) EXPECT() *MockStorageMockRecorder { return m.recorder } -// AuthRequestByCode mocks base method -func (m *MockStorage) AuthRequestByCode(arg0 string) (op.AuthRequest, error) { - m.ctrl.T.Helper() - ret := m.ctrl.Call(m, "AuthRequestByCode", arg0) - ret0, _ := ret[0].(op.AuthRequest) - ret1, _ := ret[1].(error) - return ret0, ret1 -} - -// AuthRequestByCode indicates an expected call of AuthRequestByCode -func (mr *MockStorageMockRecorder) AuthRequestByCode(arg0 interface{}) *gomock.Call { - mr.mock.ctrl.T.Helper() - return mr.mock.ctrl.RecordCallWithMethodType(mr.mock, "AuthRequestByCode", reflect.TypeOf((*MockStorage)(nil).AuthRequestByCode), arg0) -} - // AuthRequestByID mocks base method func (m *MockStorage) AuthRequestByID(arg0 string) (op.AuthRequest, error) { m.ctrl.T.Helper() @@ -94,18 +79,18 @@ func (mr *MockStorageMockRecorder) CreateAuthRequest(arg0 interface{}) *gomock.C return mr.mock.ctrl.RecordCallWithMethodType(mr.mock, "CreateAuthRequest", reflect.TypeOf((*MockStorage)(nil).CreateAuthRequest), arg0) } -// DeleteAuthRequestAndCode mocks base method -func (m *MockStorage) DeleteAuthRequestAndCode(arg0, arg1 string) error { +// DeleteAuthRequest mocks base method +func (m *MockStorage) DeleteAuthRequest(arg0 string) error { m.ctrl.T.Helper() - ret := m.ctrl.Call(m, "DeleteAuthRequestAndCode", arg0, arg1) + ret := m.ctrl.Call(m, "DeleteAuthRequest", arg0) ret0, _ := ret[0].(error) return ret0 } -// DeleteAuthRequestAndCode indicates an expected call of DeleteAuthRequestAndCode -func (mr *MockStorageMockRecorder) DeleteAuthRequestAndCode(arg0, arg1 interface{}) *gomock.Call { +// DeleteAuthRequest indicates an expected call of DeleteAuthRequest +func (mr *MockStorageMockRecorder) DeleteAuthRequest(arg0 interface{}) *gomock.Call { mr.mock.ctrl.T.Helper() - return mr.mock.ctrl.RecordCallWithMethodType(mr.mock, "DeleteAuthRequestAndCode", reflect.TypeOf((*MockStorage)(nil).DeleteAuthRequestAndCode), arg0, arg1) + return mr.mock.ctrl.RecordCallWithMethodType(mr.mock, "DeleteAuthRequest", reflect.TypeOf((*MockStorage)(nil).DeleteAuthRequest), arg0) } // GetClientByClientID mocks base method diff --git a/pkg/op/storage.go b/pkg/op/storage.go index 0971532..5c23d6a 100644 --- a/pkg/op/storage.go +++ b/pkg/op/storage.go @@ -35,7 +35,7 @@ type AuthRequest interface { GetAudience() []string GetAuthTime() time.Time GetClientID() string - GetCode() string + // GetCode() string GetCodeChallenge() *oidc.CodeChallenge GetNonce() string GetRedirectURI() string