1
0
Fork 0
mirror of https://github.com/miniflux/v2.git synced 2025-09-15 18:57:04 +00:00

Add profile scope to OIDC integration to support accounts without email

This commit is contained in:
Frédéric Guillot 2023-09-08 19:52:28 -07:00
parent ab0c4ec0f5
commit fbce915d84
5 changed files with 44 additions and 17 deletions

View file

@ -28,10 +28,15 @@ type oidcProvider struct {
func NewOidcProvider(ctx context.Context, clientID, clientSecret, redirectURL, discoveryEndpoint string) (*oidcProvider, error) {
provider, err := oidc.NewProvider(ctx, discoveryEndpoint)
if err != nil {
return nil, err
return nil, fmt.Errorf(`oidc: failed to initialize provider %q: %w`, discoveryEndpoint, err)
}
return &oidcProvider{clientID: clientID, clientSecret: clientSecret, redirectURL: redirectURL, provider: provider}, nil
return &oidcProvider{
clientID: clientID,
clientSecret: clientSecret,
redirectURL: redirectURL,
provider: provider,
}, nil
}
func (o *oidcProvider) GetUserExtraKey() string {
@ -43,7 +48,7 @@ func (o *oidcProvider) GetConfig() *oauth2.Config {
RedirectURL: o.redirectURL,
ClientID: o.clientID,
ClientSecret: o.clientSecret,
Scopes: []string{"openid", "email"},
Scopes: []string{oidc.ScopeOpenID, "profile", "email"},
Endpoint: o.provider.Endpoint(),
}
}
@ -60,7 +65,22 @@ func (o *oidcProvider) GetProfile(ctx context.Context, code, codeVerifier string
return nil, fmt.Errorf(`oidc: failed to get user info: %w`, err)
}
profile := &Profile{Key: o.GetUserExtraKey(), ID: userInfo.Subject, Username: userInfo.Email}
profile := &Profile{
Key: o.GetUserExtraKey(),
ID: userInfo.Subject,
}
var userClaims userClaims
if err := userInfo.Claims(&userClaims); err != nil {
return nil, fmt.Errorf(`oidc: failed to parse user claims: %w`, err)
}
for _, value := range []string{userClaims.Email, userClaims.PreferredUsername, userClaims.Name, userClaims.Profile} {
if value != "" {
profile.Username = value
break
}
}
if profile.Username == "" {
return nil, ErrEmptyUsername
@ -80,3 +100,10 @@ func (o *oidcProvider) PopulateUserWithProfileID(user *model.User, profile *Prof
func (o *oidcProvider) UnsetUserProfileID(user *model.User) {
user.OpenIDConnectID = ""
}
type userClaims struct {
Email string `json:"email"`
Profile string `json:"profile"`
Name string `json:"name"`
PreferredUsername string `json:"preferred_username"`
}