@@ -235,6 +235,62 @@ func reqPackageAccess(accessMode perm.AccessMode) func(ctx *context.APIContext)
235235 }
236236}
237237
238+ func checkTokenPublicOnly () func (ctx * context.APIContext ) {
239+ return func (ctx * context.APIContext ) {
240+ if ! ctx .PublicOnly {
241+ return
242+ }
243+
244+ requiredScopeCategories , ok := ctx .Data ["requiredScopeCategories" ].([]auth_model.AccessTokenScopeCategory )
245+ if ! ok || len (requiredScopeCategories ) == 0 {
246+ return
247+ }
248+
249+ // public Only permission check
250+ switch {
251+ case auth_model .ContainsCategory (requiredScopeCategories , auth_model .AccessTokenScopeCategoryRepository ):
252+ if ctx .Repo .Repository != nil && ctx .Repo .Repository .IsPrivate {
253+ ctx .Error (http .StatusForbidden , "reqToken" , "token scope is limited to public repos" )
254+ return
255+ }
256+ case auth_model .ContainsCategory (requiredScopeCategories , auth_model .AccessTokenScopeCategoryIssue ):
257+ if ctx .Repo .Repository != nil && ctx .Repo .Repository .IsPrivate {
258+ ctx .Error (http .StatusForbidden , "reqToken" , "token scope is limited to public issues" )
259+ return
260+ }
261+ case auth_model .ContainsCategory (requiredScopeCategories , auth_model .AccessTokenScopeCategoryOrganization ):
262+ if ctx .Org .Organization != nil && ctx .Org .Organization .Visibility != api .VisibleTypePublic {
263+ ctx .Error (http .StatusForbidden , "reqToken" , "token scope is limited to public orgs" )
264+ return
265+ }
266+ if ctx .ContextUser != nil && ctx .ContextUser .IsOrganization () && ctx .ContextUser .Visibility != api .VisibleTypePublic {
267+ ctx .Error (http .StatusForbidden , "reqToken" , "token scope is limited to public orgs" )
268+ return
269+ }
270+ case auth_model .ContainsCategory (requiredScopeCategories , auth_model .AccessTokenScopeCategoryUser ):
271+ if ctx .ContextUser != nil && ctx .ContextUser .IsUser () && ctx .ContextUser .Visibility != api .VisibleTypePublic {
272+ ctx .Error (http .StatusForbidden , "reqToken" , "token scope is limited to public users" )
273+ return
274+ }
275+ case auth_model .ContainsCategory (requiredScopeCategories , auth_model .AccessTokenScopeCategoryActivityPub ):
276+ if ctx .ContextUser != nil && ctx .ContextUser .IsUser () && ctx .ContextUser .Visibility != api .VisibleTypePublic {
277+ ctx .Error (http .StatusForbidden , "reqToken" , "token scope is limited to public activitypub" )
278+ return
279+ }
280+ case auth_model .ContainsCategory (requiredScopeCategories , auth_model .AccessTokenScopeCategoryNotification ):
281+ if ctx .Repo .Repository != nil && ctx .Repo .Repository .IsPrivate {
282+ ctx .Error (http .StatusForbidden , "reqToken" , "token scope is limited to public notifications" )
283+ return
284+ }
285+ case auth_model .ContainsCategory (requiredScopeCategories , auth_model .AccessTokenScopeCategoryPackage ):
286+ if ctx .Package != nil && ctx .Package .Owner .Visibility .IsPrivate () {
287+ ctx .Error (http .StatusForbidden , "reqToken" , "token scope is limited to public packages" )
288+ return
289+ }
290+ }
291+ }
292+ }
293+
238294// if a token is being used for auth, we check that it contains the required scope
239295// if a token is not being used, reqToken will enforce other sign in methods
240296func tokenRequiresScopes (requiredScopeCategories ... auth_model.AccessTokenScopeCategory ) func (ctx * context.APIContext ) {
@@ -250,9 +306,6 @@ func tokenRequiresScopes(requiredScopeCategories ...auth_model.AccessTokenScopeC
250306 return
251307 }
252308
253- ctx .Data ["ApiTokenScopePublicRepoOnly" ] = false
254- ctx .Data ["ApiTokenScopePublicOrgOnly" ] = false
255-
256309 // use the http method to determine the access level
257310 requiredScopeLevel := auth_model .Read
258311 if ctx .Req .Method == "POST" || ctx .Req .Method == "PUT" || ctx .Req .Method == "PATCH" || ctx .Req .Method == "DELETE" {
@@ -261,29 +314,28 @@ func tokenRequiresScopes(requiredScopeCategories ...auth_model.AccessTokenScopeC
261314
262315 // get the required scope for the given access level and category
263316 requiredScopes := auth_model .GetRequiredScopes (requiredScopeLevel , requiredScopeCategories ... )
264-
265- // check if scope only applies to public resources
266- publicOnly , err := scope .PublicOnly ()
317+ allow , err := scope .HasScope (requiredScopes ... )
267318 if err != nil {
268- ctx .Error (http .StatusForbidden , "tokenRequiresScope" , "parsing public resource scope failed: " + err .Error ())
319+ ctx .Error (http .StatusForbidden , "tokenRequiresScope" , "checking scope failed: " + err .Error ())
269320 return
270321 }
271322
272- // this context is used by the middleware in the specific route
273- ctx .Data ["ApiTokenScopePublicRepoOnly" ] = publicOnly && auth_model .ContainsCategory (requiredScopeCategories , auth_model .AccessTokenScopeCategoryRepository )
274- ctx .Data ["ApiTokenScopePublicOrgOnly" ] = publicOnly && auth_model .ContainsCategory (requiredScopeCategories , auth_model .AccessTokenScopeCategoryOrganization )
275-
276- allow , err := scope .HasScope (requiredScopes ... )
277- if err != nil {
278- ctx .Error (http .StatusForbidden , "tokenRequiresScope" , "checking scope failed: " + err .Error ())
323+ if ! allow {
324+ ctx .Error (http .StatusForbidden , "tokenRequiresScope" , fmt .Sprintf ("token does not have at least one of required scope(s): %v" , requiredScopes ))
279325 return
280326 }
281327
282- if allow {
328+ ctx .Data ["requiredScopeCategories" ] = requiredScopeCategories
329+
330+ // check if scope only applies to public resources
331+ publicOnly , err := scope .PublicOnly ()
332+ if err != nil {
333+ ctx .Error (http .StatusForbidden , "tokenRequiresScope" , "parsing public resource scope failed: " + err .Error ())
283334 return
284335 }
285336
286- ctx .Error (http .StatusForbidden , "tokenRequiresScope" , fmt .Sprintf ("token does not have at least one of required scope(s): %v" , requiredScopes ))
337+ // assign to true so that those searching should only filter public repositories/users/organizations
338+ ctx .PublicOnly = publicOnly
287339 }
288340}
289341
@@ -295,25 +347,6 @@ func reqToken() func(ctx *context.APIContext) {
295347 return
296348 }
297349
298- if true == ctx .Data ["IsApiToken" ] {
299- publicRepo , pubRepoExists := ctx .Data ["ApiTokenScopePublicRepoOnly" ]
300- publicOrg , pubOrgExists := ctx .Data ["ApiTokenScopePublicOrgOnly" ]
301-
302- if pubRepoExists && publicRepo .(bool ) &&
303- ctx .Repo .Repository != nil && ctx .Repo .Repository .IsPrivate {
304- ctx .Error (http .StatusForbidden , "reqToken" , "token scope is limited to public repos" )
305- return
306- }
307-
308- if pubOrgExists && publicOrg .(bool ) &&
309- ctx .Org .Organization != nil && ctx .Org .Organization .Visibility != api .VisibleTypePublic {
310- ctx .Error (http .StatusForbidden , "reqToken" , "token scope is limited to public orgs" )
311- return
312- }
313-
314- return
315- }
316-
317350 if ctx .IsSigned {
318351 return
319352 }
@@ -879,11 +912,11 @@ func Routes() *web.Router {
879912 m .Group ("/user/{username}" , func () {
880913 m .Get ("" , activitypub .Person )
881914 m .Post ("/inbox" , activitypub .ReqHTTPSignature (), activitypub .PersonInbox )
882- }, context .UserAssignmentAPI ())
915+ }, context .UserAssignmentAPI (), checkTokenPublicOnly () )
883916 m .Group ("/user-id/{user-id}" , func () {
884917 m .Get ("" , activitypub .Person )
885918 m .Post ("/inbox" , activitypub .ReqHTTPSignature (), activitypub .PersonInbox )
886- }, context .UserIDAssignmentAPI ())
919+ }, context .UserIDAssignmentAPI (), checkTokenPublicOnly () )
887920 }, tokenRequiresScopes (auth_model .AccessTokenScopeCategoryActivityPub ))
888921 }
889922
@@ -939,7 +972,7 @@ func Routes() *web.Router {
939972 }, reqSelfOrAdmin (), reqBasicOrRevProxyAuth ())
940973
941974 m .Get ("/activities/feeds" , user .ListUserActivityFeeds )
942- }, context .UserAssignmentAPI (), individualPermsChecker )
975+ }, context .UserAssignmentAPI (), checkTokenPublicOnly (), individualPermsChecker )
943976 }, tokenRequiresScopes (auth_model .AccessTokenScopeCategoryUser ))
944977
945978 // Users (requires user scope)
@@ -957,7 +990,7 @@ func Routes() *web.Router {
957990 m .Get ("/starred" , user .GetStarredRepos )
958991
959992 m .Get ("/subscriptions" , user .GetWatchedRepos )
960- }, context .UserAssignmentAPI ())
993+ }, context .UserAssignmentAPI (), checkTokenPublicOnly () )
961994 }, tokenRequiresScopes (auth_model .AccessTokenScopeCategoryUser ), reqToken ())
962995
963996 // Users (requires user scope)
@@ -1044,7 +1077,7 @@ func Routes() *web.Router {
10441077 m .Get ("" , user .IsStarring )
10451078 m .Put ("" , user .Star )
10461079 m .Delete ("" , user .Unstar )
1047- }, repoAssignment ())
1080+ }, repoAssignment (), checkTokenPublicOnly () )
10481081 }, tokenRequiresScopes (auth_model .AccessTokenScopeCategoryRepository ))
10491082 m .Get ("/times" , repo .ListMyTrackedTimes )
10501083 m .Get ("/stopwatches" , repo .GetStopwatches )
@@ -1069,18 +1102,20 @@ func Routes() *web.Router {
10691102 m .Get ("" , user .CheckUserBlock )
10701103 m .Put ("" , user .BlockUser )
10711104 m .Delete ("" , user .UnblockUser )
1072- }, context .UserAssignmentAPI ())
1105+ }, context .UserAssignmentAPI (), checkTokenPublicOnly () )
10731106 })
10741107 }, tokenRequiresScopes (auth_model .AccessTokenScopeCategoryUser ), reqToken ())
10751108
10761109 // Repositories (requires repo scope, org scope)
10771110 m .Post ("/org/{org}/repos" ,
1111+ // FIXME: we need org in context
10781112 tokenRequiresScopes (auth_model .AccessTokenScopeCategoryOrganization , auth_model .AccessTokenScopeCategoryRepository ),
10791113 reqToken (),
10801114 bind (api.CreateRepoOption {}),
10811115 repo .CreateOrgRepoDeprecated )
10821116
10831117 // requires repo scope
1118+ // FIXME: Don't expose repository id outside of the system
10841119 m .Combo ("/repositories/{id}" , reqToken (), tokenRequiresScopes (auth_model .AccessTokenScopeCategoryRepository )).Get (repo .GetByID )
10851120
10861121 // Repos (requires repo scope)
@@ -1334,7 +1369,7 @@ func Routes() *web.Router {
13341369 m .Post ("" , bind (api.UpdateRepoAvatarOption {}), repo .UpdateAvatar )
13351370 m .Delete ("" , repo .DeleteAvatar )
13361371 }, reqAdmin (), reqToken ())
1337- }, repoAssignment ())
1372+ }, repoAssignment (), checkTokenPublicOnly () )
13381373 }, tokenRequiresScopes (auth_model .AccessTokenScopeCategoryRepository ))
13391374
13401375 // Notifications (requires notifications scope)
@@ -1343,7 +1378,7 @@ func Routes() *web.Router {
13431378 m .Combo ("/notifications" , reqToken ()).
13441379 Get (notify .ListRepoNotifications ).
13451380 Put (notify .ReadRepoNotifications )
1346- }, repoAssignment ())
1381+ }, repoAssignment (), checkTokenPublicOnly () )
13471382 }, tokenRequiresScopes (auth_model .AccessTokenScopeCategoryNotification ))
13481383
13491384 // Issue (requires issue scope)
@@ -1457,7 +1492,7 @@ func Routes() *web.Router {
14571492 Patch (reqToken (), reqRepoWriter (unit .TypeIssues , unit .TypePullRequests ), bind (api.EditMilestoneOption {}), repo .EditMilestone ).
14581493 Delete (reqToken (), reqRepoWriter (unit .TypeIssues , unit .TypePullRequests ), repo .DeleteMilestone )
14591494 })
1460- }, repoAssignment ())
1495+ }, repoAssignment (), checkTokenPublicOnly () )
14611496 }, tokenRequiresScopes (auth_model .AccessTokenScopeCategoryIssue ))
14621497
14631498 // NOTE: these are Gitea package management API - see packages.CommonRoutes and packages.DockerContainerRoutes for endpoints that implement package manager APIs
@@ -1468,14 +1503,14 @@ func Routes() *web.Router {
14681503 m .Get ("/files" , reqToken (), packages .ListPackageFiles )
14691504 })
14701505 m .Get ("/" , reqToken (), packages .ListPackages )
1471- }, tokenRequiresScopes (auth_model .AccessTokenScopeCategoryPackage ), context .UserAssignmentAPI (), context .PackageAssignmentAPI (), reqPackageAccess (perm .AccessModeRead ))
1506+ }, tokenRequiresScopes (auth_model .AccessTokenScopeCategoryPackage ), context .UserAssignmentAPI (), context .PackageAssignmentAPI (), reqPackageAccess (perm .AccessModeRead ), checkTokenPublicOnly () )
14721507
14731508 // Organizations
14741509 m .Get ("/user/orgs" , reqToken (), tokenRequiresScopes (auth_model .AccessTokenScopeCategoryUser , auth_model .AccessTokenScopeCategoryOrganization ), org .ListMyOrgs )
14751510 m .Group ("/users/{username}/orgs" , func () {
14761511 m .Get ("" , reqToken (), org .ListUserOrgs )
14771512 m .Get ("/{org}/permissions" , reqToken (), org .GetUserOrgsPermissions )
1478- }, tokenRequiresScopes (auth_model .AccessTokenScopeCategoryUser , auth_model .AccessTokenScopeCategoryOrganization ), context .UserAssignmentAPI ())
1513+ }, tokenRequiresScopes (auth_model .AccessTokenScopeCategoryUser , auth_model .AccessTokenScopeCategoryOrganization ), context .UserAssignmentAPI (), checkTokenPublicOnly () )
14791514 m .Post ("/orgs" , tokenRequiresScopes (auth_model .AccessTokenScopeCategoryOrganization ), reqToken (), bind (api.CreateOrgOption {}), org .Create )
14801515 m .Get ("/orgs" , org .GetAll , tokenRequiresScopes (auth_model .AccessTokenScopeCategoryOrganization ))
14811516 m .Group ("/orgs/{org}" , func () {
@@ -1533,7 +1568,7 @@ func Routes() *web.Router {
15331568 m .Delete ("" , org .UnblockUser )
15341569 })
15351570 }, reqToken (), reqOrgOwnership ())
1536- }, tokenRequiresScopes (auth_model .AccessTokenScopeCategoryOrganization ), orgAssignment (true ))
1571+ }, tokenRequiresScopes (auth_model .AccessTokenScopeCategoryOrganization ), orgAssignment (true ), checkTokenPublicOnly () )
15371572 m .Group ("/teams/{teamid}" , func () {
15381573 m .Combo ("" ).Get (reqToken (), org .GetTeam ).
15391574 Patch (reqToken (), reqOrgOwnership (), bind (api.EditTeamOption {}), org .EditTeam ).
@@ -1553,7 +1588,7 @@ func Routes() *web.Router {
15531588 Get (reqToken (), org .GetTeamRepo )
15541589 })
15551590 m .Get ("/activities/feeds" , org .ListTeamActivityFeeds )
1556- }, tokenRequiresScopes (auth_model .AccessTokenScopeCategoryOrganization ), orgAssignment (false , true ), reqToken (), reqTeamMembership ())
1591+ }, tokenRequiresScopes (auth_model .AccessTokenScopeCategoryOrganization ), orgAssignment (false , true ), reqToken (), reqTeamMembership (), checkTokenPublicOnly () )
15571592
15581593 m .Group ("/admin" , func () {
15591594 m .Group ("/cron" , func () {
0 commit comments