@@ -1,6 +1,14 @@
11package providers
22
3−import "github.com/oauth2-proxy/oauth2-proxy/v7/pkg/apis/options"
3+import (
4+ "context"
5+ "fmt"
6+
7+ "github.com/oauth2-proxy/oauth2-proxy/v7/pkg/apis/options"
8+ "github.com/oauth2-proxy/oauth2-proxy/v7/pkg/apis/sessions"
9+ "github.com/oauth2-proxy/oauth2-proxy/v7/pkg/logger"
10+ "github.com/oauth2-proxy/oauth2-proxy/v7/pkg/requests"
11+)
412
513// NextcloudProvider represents an Nextcloud based Identity Provider
614type NextcloudProvider struct {
@@ -22,3 +30,51 @@ func NewNextcloudProvider(p *ProviderData) *NextcloudProvider {
2230 }
2331 return &NextcloudProvider{ProviderData: p}
2432}
33+
34+// EnrichSession uses the Nextcloud userinfo endpoint to populate
35+// the session's email, user, and groups.
36+func (p *NextcloudProvider) EnrichSession(ctx context.Context, s *sessions.SessionState) error {
37+ // Fallback to ValidateURL if ProfileURL not set for legacy compatibility
38+ profileURL := p.ValidateURL.String()
39+ if p.ProfileURL.String() != "" {
40+ profileURL = p.ProfileURL.String()
41+ }
42+
43+ json, err := requests.New(profileURL).
44+ WithContext(ctx).
45+ SetHeader("Authorization", "Bearer "+s.AccessToken).
46+ Do().
47+ UnmarshalJSON()
48+ if err != nil {
49+ logger.Errorf("failed making request %v", err)
50+ return err
51+ }
52+
53+ groups, err := json.GetPath("ocs", "data", "groups").StringArray()
54+ if err == nil {
55+ for _, group := range groups {
56+ if group != "" {
57+ s.Groups = append(s.Groups, group)
58+ }
59+ }
60+ }
61+
62+ user, err := json.GetPath("ocs", "data", "id").String()
63+ if err != nil {
64+ return fmt.Errorf("unable to extract id from userinfo endpoint: %v", err)
65+ }
66+ s.User = user
67+
68+ email, err := json.GetPath("ocs", "data", "email").String()
69+ if err != nil {
70+ return fmt.Errorf("unable to extract email from userinfo endpoint: %v", err)
71+ }
72+ s.Email = email
73+
74+ return nil
75+}
76+
77+// ValidateSession validates the AccessToken
78+func (p *NextcloudProvider) ValidateSession(ctx context.Context, s *sessions.SessionState) bool {
79+ return validateToken(ctx, p, s.AccessToken, makeOIDCHeader(s.AccessToken))
80+}