@@ -235,6 +235,62 @@ func reqPackageAccess(accessMode perm.AccessMode) func(ctx *context.APIContext)
235
235
}
236
236
}
237
237
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
+
238
294
// if a token is being used for auth, we check that it contains the required scope
239
295
// if a token is not being used, reqToken will enforce other sign in methods
240
296
func tokenRequiresScopes (requiredScopeCategories ... auth_model.AccessTokenScopeCategory ) func (ctx * context.APIContext ) {
@@ -250,9 +306,6 @@ func tokenRequiresScopes(requiredScopeCategories ...auth_model.AccessTokenScopeC
250
306
return
251
307
}
252
308
253
- ctx .Data ["ApiTokenScopePublicRepoOnly" ] = false
254
- ctx .Data ["ApiTokenScopePublicOrgOnly" ] = false
255
-
256
309
// use the http method to determine the access level
257
310
requiredScopeLevel := auth_model .Read
258
311
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
261
314
262
315
// get the required scope for the given access level and category
263
316
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 ... )
267
318
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 ())
269
320
return
270
321
}
271
322
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 ))
279
325
return
280
326
}
281
327
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 ())
283
334
return
284
335
}
285
336
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
287
339
}
288
340
}
289
341
@@ -295,25 +347,6 @@ func reqToken() func(ctx *context.APIContext) {
295
347
return
296
348
}
297
349
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
-
317
350
if ctx .IsSigned {
318
351
return
319
352
}
@@ -879,11 +912,11 @@ func Routes() *web.Router {
879
912
m .Group ("/user/{username}" , func () {
880
913
m .Get ("" , activitypub .Person )
881
914
m .Post ("/inbox" , activitypub .ReqHTTPSignature (), activitypub .PersonInbox )
882
- }, context .UserAssignmentAPI ())
915
+ }, context .UserAssignmentAPI (), checkTokenPublicOnly () )
883
916
m .Group ("/user-id/{user-id}" , func () {
884
917
m .Get ("" , activitypub .Person )
885
918
m .Post ("/inbox" , activitypub .ReqHTTPSignature (), activitypub .PersonInbox )
886
- }, context .UserIDAssignmentAPI ())
919
+ }, context .UserIDAssignmentAPI (), checkTokenPublicOnly () )
887
920
}, tokenRequiresScopes (auth_model .AccessTokenScopeCategoryActivityPub ))
888
921
}
889
922
@@ -939,7 +972,7 @@ func Routes() *web.Router {
939
972
}, reqSelfOrAdmin (), reqBasicOrRevProxyAuth ())
940
973
941
974
m .Get ("/activities/feeds" , user .ListUserActivityFeeds )
942
- }, context .UserAssignmentAPI (), individualPermsChecker )
975
+ }, context .UserAssignmentAPI (), checkTokenPublicOnly (), individualPermsChecker )
943
976
}, tokenRequiresScopes (auth_model .AccessTokenScopeCategoryUser ))
944
977
945
978
// Users (requires user scope)
@@ -957,7 +990,7 @@ func Routes() *web.Router {
957
990
m .Get ("/starred" , user .GetStarredRepos )
958
991
959
992
m .Get ("/subscriptions" , user .GetWatchedRepos )
960
- }, context .UserAssignmentAPI ())
993
+ }, context .UserAssignmentAPI (), checkTokenPublicOnly () )
961
994
}, tokenRequiresScopes (auth_model .AccessTokenScopeCategoryUser ), reqToken ())
962
995
963
996
// Users (requires user scope)
@@ -1044,7 +1077,7 @@ func Routes() *web.Router {
1044
1077
m .Get ("" , user .IsStarring )
1045
1078
m .Put ("" , user .Star )
1046
1079
m .Delete ("" , user .Unstar )
1047
- }, repoAssignment ())
1080
+ }, repoAssignment (), checkTokenPublicOnly () )
1048
1081
}, tokenRequiresScopes (auth_model .AccessTokenScopeCategoryRepository ))
1049
1082
m .Get ("/times" , repo .ListMyTrackedTimes )
1050
1083
m .Get ("/stopwatches" , repo .GetStopwatches )
@@ -1069,18 +1102,20 @@ func Routes() *web.Router {
1069
1102
m .Get ("" , user .CheckUserBlock )
1070
1103
m .Put ("" , user .BlockUser )
1071
1104
m .Delete ("" , user .UnblockUser )
1072
- }, context .UserAssignmentAPI ())
1105
+ }, context .UserAssignmentAPI (), checkTokenPublicOnly () )
1073
1106
})
1074
1107
}, tokenRequiresScopes (auth_model .AccessTokenScopeCategoryUser ), reqToken ())
1075
1108
1076
1109
// Repositories (requires repo scope, org scope)
1077
1110
m .Post ("/org/{org}/repos" ,
1111
+ // FIXME: we need org in context
1078
1112
tokenRequiresScopes (auth_model .AccessTokenScopeCategoryOrganization , auth_model .AccessTokenScopeCategoryRepository ),
1079
1113
reqToken (),
1080
1114
bind (api.CreateRepoOption {}),
1081
1115
repo .CreateOrgRepoDeprecated )
1082
1116
1083
1117
// requires repo scope
1118
+ // FIXME: Don't expose repository id outside of the system
1084
1119
m .Combo ("/repositories/{id}" , reqToken (), tokenRequiresScopes (auth_model .AccessTokenScopeCategoryRepository )).Get (repo .GetByID )
1085
1120
1086
1121
// Repos (requires repo scope)
@@ -1334,7 +1369,7 @@ func Routes() *web.Router {
1334
1369
m .Post ("" , bind (api.UpdateRepoAvatarOption {}), repo .UpdateAvatar )
1335
1370
m .Delete ("" , repo .DeleteAvatar )
1336
1371
}, reqAdmin (), reqToken ())
1337
- }, repoAssignment ())
1372
+ }, repoAssignment (), checkTokenPublicOnly () )
1338
1373
}, tokenRequiresScopes (auth_model .AccessTokenScopeCategoryRepository ))
1339
1374
1340
1375
// Notifications (requires notifications scope)
@@ -1343,7 +1378,7 @@ func Routes() *web.Router {
1343
1378
m .Combo ("/notifications" , reqToken ()).
1344
1379
Get (notify .ListRepoNotifications ).
1345
1380
Put (notify .ReadRepoNotifications )
1346
- }, repoAssignment ())
1381
+ }, repoAssignment (), checkTokenPublicOnly () )
1347
1382
}, tokenRequiresScopes (auth_model .AccessTokenScopeCategoryNotification ))
1348
1383
1349
1384
// Issue (requires issue scope)
@@ -1457,7 +1492,7 @@ func Routes() *web.Router {
1457
1492
Patch (reqToken (), reqRepoWriter (unit .TypeIssues , unit .TypePullRequests ), bind (api.EditMilestoneOption {}), repo .EditMilestone ).
1458
1493
Delete (reqToken (), reqRepoWriter (unit .TypeIssues , unit .TypePullRequests ), repo .DeleteMilestone )
1459
1494
})
1460
- }, repoAssignment ())
1495
+ }, repoAssignment (), checkTokenPublicOnly () )
1461
1496
}, tokenRequiresScopes (auth_model .AccessTokenScopeCategoryIssue ))
1462
1497
1463
1498
// 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 {
1468
1503
m .Get ("/files" , reqToken (), packages .ListPackageFiles )
1469
1504
})
1470
1505
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 () )
1472
1507
1473
1508
// Organizations
1474
1509
m .Get ("/user/orgs" , reqToken (), tokenRequiresScopes (auth_model .AccessTokenScopeCategoryUser , auth_model .AccessTokenScopeCategoryOrganization ), org .ListMyOrgs )
1475
1510
m .Group ("/users/{username}/orgs" , func () {
1476
1511
m .Get ("" , reqToken (), org .ListUserOrgs )
1477
1512
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 () )
1479
1514
m .Post ("/orgs" , tokenRequiresScopes (auth_model .AccessTokenScopeCategoryOrganization ), reqToken (), bind (api.CreateOrgOption {}), org .Create )
1480
1515
m .Get ("/orgs" , org .GetAll , tokenRequiresScopes (auth_model .AccessTokenScopeCategoryOrganization ))
1481
1516
m .Group ("/orgs/{org}" , func () {
@@ -1533,7 +1568,7 @@ func Routes() *web.Router {
1533
1568
m .Delete ("" , org .UnblockUser )
1534
1569
})
1535
1570
}, reqToken (), reqOrgOwnership ())
1536
- }, tokenRequiresScopes (auth_model .AccessTokenScopeCategoryOrganization ), orgAssignment (true ))
1571
+ }, tokenRequiresScopes (auth_model .AccessTokenScopeCategoryOrganization ), orgAssignment (true ), checkTokenPublicOnly () )
1537
1572
m .Group ("/teams/{teamid}" , func () {
1538
1573
m .Combo ("" ).Get (reqToken (), org .GetTeam ).
1539
1574
Patch (reqToken (), reqOrgOwnership (), bind (api.EditTeamOption {}), org .EditTeam ).
@@ -1553,7 +1588,7 @@ func Routes() *web.Router {
1553
1588
Get (reqToken (), org .GetTeamRepo )
1554
1589
})
1555
1590
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 () )
1557
1592
1558
1593
m .Group ("/admin" , func () {
1559
1594
m .Group ("/cron" , func () {
0 commit comments