@@ -6,6 +6,8 @@ package oauth2_provider //nolint
66import (
77 "context"
88 "fmt"
9+ "slices"
10+ "strings"
911
1012 auth "code.gitea.io/gitea/models/auth"
1113 "code.gitea.io/gitea/models/db"
@@ -69,6 +71,30 @@ type AccessTokenResponse struct {
6971 IDToken string `json:"id_token,omitempty"`
7072}
7173
74+ // GrantAdditionalScopes returns valid scopes coming from grant
75+ func GrantAdditionalScopes (grantScopes string ) auth.AccessTokenScope {
76+ // scopes_supported from templates/user/auth/oidc_wellknown.tmpl
77+ scopesSupported := []string {
78+ "openid" ,
79+ "profile" ,
80+ "email" ,
81+ "groups" ,
82+ }
83+
84+ var tokenScopes []string
85+ for _ , tokenScope := range strings .Split (grantScopes , " " ) {
86+ if slices .Index (scopesSupported , tokenScope ) == - 1 {
87+ tokenScopes = append (tokenScopes , tokenScope )
88+ }
89+ }
90+
91+ accessTokenScope := auth .AccessTokenScope (strings .Join (tokenScopes , "," ))
92+ if accessTokenWithAdditionalScopes , err := accessTokenScope .Normalize (); err == nil && len (tokenScopes ) > 0 {
93+ return accessTokenWithAdditionalScopes
94+ }
95+ return auth .AccessTokenScopeAll
96+ }
97+
7298func NewAccessTokenResponse (ctx context.Context , grant * auth.OAuth2Grant , serverKey , clientKey JWTSigningKey ) (* AccessTokenResponse , * AccessTokenError ) {
7399 if setting .OAuth2 .InvalidateRefreshTokens {
74100 if err := grant .IncreaseCounter (ctx ); err != nil {
@@ -161,7 +187,10 @@ func NewAccessTokenResponse(ctx context.Context, grant *auth.OAuth2Grant, server
161187 idToken .EmailVerified = user .IsActive
162188 }
163189 if grant .ScopeContains ("groups" ) {
164- groups , err := GetOAuthGroupsForUser (ctx , user )
190+ accessTokenScope := GrantAdditionalScopes (grant .Scope )
191+ onlyPublicGroups , _ := accessTokenScope .PublicOnly ()
192+
193+ groups , err := GetOAuthGroupsForUser (ctx , user , onlyPublicGroups )
165194 if err != nil {
166195 log .Error ("Error getting groups: %v" , err )
167196 return nil , & AccessTokenError {
@@ -192,10 +221,10 @@ func NewAccessTokenResponse(ctx context.Context, grant *auth.OAuth2Grant, server
192221
193222// returns a list of "org" and "org:team" strings,
194223// that the given user is a part of.
195- func GetOAuthGroupsForUser (ctx context.Context , user * user_model.User ) ([]string , error ) {
224+ func GetOAuthGroupsForUser (ctx context.Context , user * user_model.User , onlyPublicGroups bool ) ([]string , error ) {
196225 orgs , err := db .Find [org_model.Organization ](ctx , org_model.FindOrgOptions {
197226 UserID : user .ID ,
198- IncludePrivate : true ,
227+ IncludePrivate : ! onlyPublicGroups ,
199228 })
200229 if err != nil {
201230 return nil , fmt .Errorf ("GetUserOrgList: %w" , err )
0 commit comments