@@ -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.Route {
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.Route {
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.Route {
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.Route {
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.Route {
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) 
@@ -1321,7 +1356,7 @@ func Routes() *web.Route {
13211356					m .Post ("" , bind (api.UpdateRepoAvatarOption {}), repo .UpdateAvatar )
13221357					m .Delete ("" , repo .DeleteAvatar )
13231358				}, reqAdmin (), reqToken ())
1324- 			}, repoAssignment ())
1359+ 			}, repoAssignment (),  checkTokenPublicOnly () )
13251360		}, tokenRequiresScopes (auth_model .AccessTokenScopeCategoryRepository ))
13261361
13271362		// Notifications (requires notifications scope) 
@@ -1330,7 +1365,7 @@ func Routes() *web.Route {
13301365				m .Combo ("/notifications" , reqToken ()).
13311366					Get (notify .ListRepoNotifications ).
13321367					Put (notify .ReadRepoNotifications )
1333- 			}, repoAssignment ())
1368+ 			}, repoAssignment (),  checkTokenPublicOnly () )
13341369		}, tokenRequiresScopes (auth_model .AccessTokenScopeCategoryNotification ))
13351370
13361371		// Issue (requires issue scope) 
@@ -1444,7 +1479,7 @@ func Routes() *web.Route {
14441479						Patch (reqToken (), reqRepoWriter (unit .TypeIssues , unit .TypePullRequests ), bind (api.EditMilestoneOption {}), repo .EditMilestone ).
14451480						Delete (reqToken (), reqRepoWriter (unit .TypeIssues , unit .TypePullRequests ), repo .DeleteMilestone )
14461481				})
1447- 			}, repoAssignment ())
1482+ 			}, repoAssignment (),  checkTokenPublicOnly () )
14481483		}, tokenRequiresScopes (auth_model .AccessTokenScopeCategoryIssue ))
14491484
14501485		// NOTE: these are Gitea package management API - see packages.CommonRoutes and packages.DockerContainerRoutes for endpoints that implement package manager APIs 
@@ -1455,14 +1490,14 @@ func Routes() *web.Route {
14551490				m .Get ("/files" , reqToken (), packages .ListPackageFiles )
14561491			})
14571492			m .Get ("/" , reqToken (), packages .ListPackages )
1458- 		}, tokenRequiresScopes (auth_model .AccessTokenScopeCategoryPackage ), context .UserAssignmentAPI (), context .PackageAssignmentAPI (), reqPackageAccess (perm .AccessModeRead ))
1493+ 		}, tokenRequiresScopes (auth_model .AccessTokenScopeCategoryPackage ), context .UserAssignmentAPI (), context .PackageAssignmentAPI (), reqPackageAccess (perm .AccessModeRead ),  checkTokenPublicOnly () )
14591494
14601495		// Organizations 
14611496		m .Get ("/user/orgs" , reqToken (), tokenRequiresScopes (auth_model .AccessTokenScopeCategoryUser , auth_model .AccessTokenScopeCategoryOrganization ), org .ListMyOrgs )
14621497		m .Group ("/users/{username}/orgs" , func () {
14631498			m .Get ("" , reqToken (), org .ListUserOrgs )
14641499			m .Get ("/{org}/permissions" , reqToken (), org .GetUserOrgsPermissions )
1465- 		}, tokenRequiresScopes (auth_model .AccessTokenScopeCategoryUser , auth_model .AccessTokenScopeCategoryOrganization ), context .UserAssignmentAPI ())
1500+ 		}, tokenRequiresScopes (auth_model .AccessTokenScopeCategoryUser , auth_model .AccessTokenScopeCategoryOrganization ), context .UserAssignmentAPI (),  checkTokenPublicOnly () )
14661501		m .Post ("/orgs" , tokenRequiresScopes (auth_model .AccessTokenScopeCategoryOrganization ), reqToken (), bind (api.CreateOrgOption {}), org .Create )
14671502		m .Get ("/orgs" , org .GetAll , tokenRequiresScopes (auth_model .AccessTokenScopeCategoryOrganization ))
14681503		m .Group ("/orgs/{org}" , func () {
@@ -1520,7 +1555,7 @@ func Routes() *web.Route {
15201555					m .Delete ("" , org .UnblockUser )
15211556				})
15221557			}, reqToken (), reqOrgOwnership ())
1523- 		}, tokenRequiresScopes (auth_model .AccessTokenScopeCategoryOrganization ), orgAssignment (true ))
1558+ 		}, tokenRequiresScopes (auth_model .AccessTokenScopeCategoryOrganization ), orgAssignment (true ),  checkTokenPublicOnly () )
15241559		m .Group ("/teams/{teamid}" , func () {
15251560			m .Combo ("" ).Get (reqToken (), org .GetTeam ).
15261561				Patch (reqToken (), reqOrgOwnership (), bind (api.EditTeamOption {}), org .EditTeam ).
@@ -1540,7 +1575,7 @@ func Routes() *web.Route {
15401575					Get (reqToken (), org .GetTeamRepo )
15411576			})
15421577			m .Get ("/activities/feeds" , org .ListTeamActivityFeeds )
1543- 		}, tokenRequiresScopes (auth_model .AccessTokenScopeCategoryOrganization ), orgAssignment (false , true ), reqToken (), reqTeamMembership ())
1578+ 		}, tokenRequiresScopes (auth_model .AccessTokenScopeCategoryOrganization ), orgAssignment (false , true ), reqToken (), reqTeamMembership (),  checkTokenPublicOnly () )
15441579
15451580		m .Group ("/admin" , func () {
15461581			m .Group ("/cron" , func () {
0 commit comments