This commit is contained in:
Livio Amstutz 2019-12-17 15:16:48 +01:00
parent d3d9e676c0
commit 35aa88b939
7 changed files with 60 additions and 220 deletions

View file

@ -19,10 +19,10 @@ const (
DisplayTouch Display = "touch" DisplayTouch Display = "touch"
DisplayWAP Display = "wap" DisplayWAP Display = "wap"
PromptNone = "none" PromptNone Prompt = "none"
PromptLogin = "login" PromptLogin Prompt = "login"
PromptConsent = "consent" PromptConsent Prompt = "consent"
PromptSelectAccount = "select_account" PromptSelectAccount Prompt = "select_account"
GrantTypeCode GrantType = "authorization_code" GrantTypeCode GrantType = "authorization_code"
@ -63,14 +63,6 @@ type AuthRequest struct {
CodeChallengeMethod CodeChallengeMethod `schema:"code_challenge_method"` 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 { func (a *AuthRequest) GetRedirectURI() string {
return a.RedirectURI return a.RedirectURI
} }
@ -119,32 +111,6 @@ type TokenExchangeRequest struct {
requestedTokenType string `schema:"requested_token_type"` 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 type Scopes []string
func (s *Scopes) UnmarshalText(text []byte) error { func (s *Scopes) UnmarshalText(text []byte) error {

View file

@ -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
// }

View file

@ -2,6 +2,7 @@ package oidc
import ( import (
"encoding/json" "encoding/json"
"strings"
"time" "time"
"github.com/caos/oidc/pkg/utils" "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 { if err := json.Unmarshal(b, &i); err != nil {
return err return err
} }
audience := i.Audiences
if len(audience) == 1 {
audience = strings.Split(audience[0], " ")
}
t.Issuer = i.Issuer t.Issuer = i.Issuer
t.Subject = i.Subject t.Subject = i.Subject
// t.Audiences = strings.Split(i.Audiences, " ") t.Audiences = audience
t.Audiences = i.Audiences
t.Expiration = time.Unix(i.Expiration, 0).UTC() t.Expiration = time.Unix(i.Expiration, 0).UTC()
t.IssuedAt = time.Unix(i.IssuedAt, 0).UTC() t.IssuedAt = time.Unix(i.IssuedAt, 0).UTC()
t.AuthTime = time.Unix(i.AuthTime, 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) { func (t *IDTokenClaims) MarshalJSON() ([]byte, error) {
j := jsonIDToken{ j := jsonIDToken{
Issuer: t.Issuer, Issuer: t.Issuer,
Subject: t.Subject, Subject: t.Subject,
// Audiences: strings.Join(t.Audiences, " "),
Audiences: t.Audiences, Audiences: t.Audiences,
Expiration: t.Expiration.Unix(), Expiration: t.Expiration.Unix(),
IssuedAt: t.IssuedAt.Unix(), IssuedAt: t.IssuedAt.Unix(),
@ -66,8 +69,6 @@ func (t *IDTokenClaims) MarshalJSON() ([]byte, error) {
return json.Marshal(j) return json.Marshal(j)
} }
// type jsonTime time.Time
type jsonIDToken struct { type jsonIDToken struct {
Issuer string `json:"iss,omitempty"` Issuer string `json:"iss,omitempty"`
Subject string `json:"sub,omitempty"` Subject string `json:"sub,omitempty"`

View file

@ -3,12 +3,9 @@ package oidc
import ( import (
"encoding/json" "encoding/json"
"time" "time"
)
type Test struct { "golang.org/x/text/language"
Userinfo )
Add string `json:"add,omitempty"`
}
type Userinfo struct { type Userinfo struct {
Subject string Subject string
@ -20,64 +17,27 @@ type Userinfo struct {
claims map[string]interface{} 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 { type UserinfoPhone struct {
PhoneNumber string PhoneNumber string
PhoneNumberVerified bool PhoneNumberVerified bool
} }
type UserinfoProfile struct { type UserinfoProfile struct {
Name string Name string
GivenName string GivenName string
FamilyName string FamilyName string
MiddleName string MiddleName string
Nickname string Nickname string
Profile string Profile string
Picture string Picture string
Website string Website string
Gender Gender Gender Gender
Birthdate string Birthdate string
Zoneinfo string Zoneinfo string
// Locale language.Tag Locale language.Tag
UpdatedAt time.Time UpdatedAt time.Time
PreferredUsername string 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 Gender string
type UserinfoAddress struct { type UserinfoAddress struct {
@ -95,7 +55,20 @@ type UserinfoEmail struct {
} }
func marshalUserinfoProfile(i UserinfoProfile, claims map[string]interface{}) { 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["updated_at"] = i.UpdatedAt.UTC().Unix()
claims["preferred_username"] = i.PreferredUsername
} }
func marshalUserinfoEmail(i UserinfoEmail, claims map[string]interface{}) { 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 address["street_address"] = i.StreetAddress
} }
claims["address"] = address claims["address"] = address
// claims["email_verified"] = i.EmailVerified
} }
func marshalUserinfoPhone(i UserinfoPhone, claims map[string]interface{}) { 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 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) { func (i *Userinfo) MarshalJSON() ([]byte, error) {
claims := i.claims claims := i.claims
if claims == nil { if claims == nil {
claims = make(map[string]interface{}) 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 claims["sub"] = i.Subject
marshalUserinfoAddress(i.Address, claims) marshalUserinfoAddress(i.Address, claims)
marshalUserinfoEmail(i.UserinfoEmail, claims) marshalUserinfoEmail(i.UserinfoEmail, claims)
marshalUserinfoPhone(i.UserinfoPhone, claims) marshalUserinfoPhone(i.UserinfoPhone, claims)
marshalUserinfoProfile(i.UserinfoProfile, 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) return json.Marshal(claims)
} }

View file

@ -34,6 +34,20 @@ func (m *MockAuthorizer) EXPECT() *MockAuthorizerMockRecorder {
return m.recorder 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 // Decoder mocks base method
func (m *MockAuthorizer) Decoder() *schema.Decoder { func (m *MockAuthorizer) Decoder() *schema.Decoder {
m.ctrl.T.Helper() m.ctrl.T.Helper()

View file

@ -35,21 +35,6 @@ func (m *MockStorage) EXPECT() *MockStorageMockRecorder {
return m.recorder 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 // AuthRequestByID mocks base method
func (m *MockStorage) AuthRequestByID(arg0 string) (op.AuthRequest, error) { func (m *MockStorage) AuthRequestByID(arg0 string) (op.AuthRequest, error) {
m.ctrl.T.Helper() 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) return mr.mock.ctrl.RecordCallWithMethodType(mr.mock, "CreateAuthRequest", reflect.TypeOf((*MockStorage)(nil).CreateAuthRequest), arg0)
} }
// DeleteAuthRequestAndCode mocks base method // DeleteAuthRequest mocks base method
func (m *MockStorage) DeleteAuthRequestAndCode(arg0, arg1 string) error { func (m *MockStorage) DeleteAuthRequest(arg0 string) error {
m.ctrl.T.Helper() m.ctrl.T.Helper()
ret := m.ctrl.Call(m, "DeleteAuthRequestAndCode", arg0, arg1) ret := m.ctrl.Call(m, "DeleteAuthRequest", arg0)
ret0, _ := ret[0].(error) ret0, _ := ret[0].(error)
return ret0 return ret0
} }
// DeleteAuthRequestAndCode indicates an expected call of DeleteAuthRequestAndCode // DeleteAuthRequest indicates an expected call of DeleteAuthRequest
func (mr *MockStorageMockRecorder) DeleteAuthRequestAndCode(arg0, arg1 interface{}) *gomock.Call { func (mr *MockStorageMockRecorder) DeleteAuthRequest(arg0 interface{}) *gomock.Call {
mr.mock.ctrl.T.Helper() 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 // GetClientByClientID mocks base method

View file

@ -35,7 +35,7 @@ type AuthRequest interface {
GetAudience() []string GetAudience() []string
GetAuthTime() time.Time GetAuthTime() time.Time
GetClientID() string GetClientID() string
GetCode() string // GetCode() string
GetCodeChallenge() *oidc.CodeChallenge GetCodeChallenge() *oidc.CodeChallenge
GetNonce() string GetNonce() string
GetRedirectURI() string GetRedirectURI() string