diff --git a/CHANGELOG.md b/CHANGELOG.md index 4cc0ac0e..3e3392ea 100644 --- a/CHANGELOG.md +++ b/CHANGELOG.md @@ -41,6 +41,8 @@ to remain consistent with CLI flags. You should specify `code_challenge_method` - [#1760](https://github.com/oauth2-proxy/oauth2-proxy/pull/1760) Option to configure API routes +- [#1750](https://github.com/oauth2-proxy/oauth2-proxy/pull/1750) Fix Nextcloud provider + # V7.3.0 diff --git a/providers/nextcloud.go b/providers/nextcloud.go index 882fc63e..beffb19a 100644 --- a/providers/nextcloud.go +++ b/providers/nextcloud.go @@ -1,6 +1,14 @@ package providers -import "github.com/oauth2-proxy/oauth2-proxy/v7/pkg/apis/options" +import ( + "context" + "fmt" + + "github.com/oauth2-proxy/oauth2-proxy/v7/pkg/apis/options" + "github.com/oauth2-proxy/oauth2-proxy/v7/pkg/apis/sessions" + "github.com/oauth2-proxy/oauth2-proxy/v7/pkg/logger" + "github.com/oauth2-proxy/oauth2-proxy/v7/pkg/requests" +) // NextcloudProvider represents an Nextcloud based Identity Provider type NextcloudProvider struct { @@ -22,3 +30,51 @@ func NewNextcloudProvider(p *ProviderData) *NextcloudProvider { } return &NextcloudProvider{ProviderData: p} } + +// EnrichSession uses the Nextcloud userinfo endpoint to populate +// the session's email, user, and groups. +func (p *NextcloudProvider) EnrichSession(ctx context.Context, s *sessions.SessionState) error { + // Fallback to ValidateURL if ProfileURL not set for legacy compatibility + profileURL := p.ValidateURL.String() + if p.ProfileURL.String() != "" { + profileURL = p.ProfileURL.String() + } + + json, err := requests.New(profileURL). + WithContext(ctx). + SetHeader("Authorization", "Bearer "+s.AccessToken). + Do(). + UnmarshalJSON() + if err != nil { + logger.Errorf("failed making request %v", err) + return err + } + + groups, err := json.GetPath("ocs", "data", "groups").StringArray() + if err == nil { + for _, group := range groups { + if group != "" { + s.Groups = append(s.Groups, group) + } + } + } + + user, err := json.GetPath("ocs", "data", "id").String() + if err != nil { + return fmt.Errorf("unable to extract id from userinfo endpoint: %v", err) + } + s.User = user + + email, err := json.GetPath("ocs", "data", "email").String() + if err != nil { + return fmt.Errorf("unable to extract email from userinfo endpoint: %v", err) + } + s.Email = email + + return nil +} + +// ValidateSession validates the AccessToken +func (p *NextcloudProvider) ValidateSession(ctx context.Context, s *sessions.SessionState) bool { + return validateToken(ctx, p, s.AccessToken, makeOIDCHeader(s.AccessToken)) +}