@@ -235,54 +235,6 @@ func reqPackageAccess(accessMode perm.AccessMode) func(ctx *context.APIContext)
235235 }
236236}
237237
238- // if a token is being used for auth, we check that it contains the required scope
239- // if a token is not being used, reqToken will enforce other sign in methods
240- func tokenRequiresScopes (requiredScopeCategories ... auth_model.AccessTokenScopeCategory ) func (ctx * context.APIContext ) {
241- return func (ctx * context.APIContext ) {
242- // no scope required
243- if len (requiredScopeCategories ) == 0 {
244- return
245- }
246-
247- // Need OAuth2 token to be present.
248- scope , scopeExists := ctx .Data ["ApiTokenScope" ].(auth_model.AccessTokenScope )
249- if ctx .Data ["IsApiToken" ] != true || ! scopeExists {
250- return
251- }
252-
253- // use the http method to determine the access level
254- requiredScopeLevel := auth_model .Read
255- if ctx .Req .Method == "POST" || ctx .Req .Method == "PUT" || ctx .Req .Method == "PATCH" || ctx .Req .Method == "DELETE" {
256- requiredScopeLevel = auth_model .Write
257- }
258-
259- // get the required scope for the given access level and category
260- requiredScopes := auth_model .GetRequiredScopes (requiredScopeLevel , requiredScopeCategories ... )
261- allow , err := scope .HasScope (requiredScopes ... )
262- if err != nil {
263- ctx .Error (http .StatusForbidden , "tokenRequiresScope" , "checking scope failed: " + err .Error ())
264- return
265- }
266-
267- if ! allow {
268- ctx .Error (http .StatusForbidden , "tokenRequiresScope" , fmt .Sprintf ("token does not have at least one of required scope(s): %v" , requiredScopes ))
269- return
270- }
271-
272- ctx .Data ["requiredScopeCategories" ] = requiredScopeCategories
273-
274- // check if scope only applies to public resources
275- publicOnly , err := scope .PublicOnly ()
276- if err != nil {
277- ctx .Error (http .StatusForbidden , "tokenRequiresScope" , "parsing public resource scope failed: " + err .Error ())
278- return
279- }
280-
281- // assign to true so that those searching should only filter public repositories/users/organizations
282- ctx .PublicOnly = publicOnly
283- }
284- }
285-
286238func checkTokenPublicOnly () func (ctx * context.APIContext ) {
287239 return func (ctx * context.APIContext ) {
288240 if ! ctx .PublicOnly {
@@ -296,12 +248,16 @@ func checkTokenPublicOnly() func(ctx *context.APIContext) {
296248
297249 // public Only permission check
298250 switch {
299- case auth_model .ContainsCategory (requiredScopeCategories , auth_model .AccessTokenScopeCategoryRepository ),
300- auth_model .ContainsCategory (requiredScopeCategories , auth_model .AccessTokenScopeCategoryIssue ):
251+ case auth_model .ContainsCategory (requiredScopeCategories , auth_model .AccessTokenScopeCategoryRepository ):
301252 if ctx .Repo .Repository != nil && ctx .Repo .Repository .IsPrivate {
302253 ctx .Error (http .StatusForbidden , "reqToken" , "token scope is limited to public repos" )
303254 return
304255 }
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+ }
305261 case auth_model .ContainsCategory (requiredScopeCategories , auth_model .AccessTokenScopeCategoryOrganization ):
306262 if ctx .Org .Organization != nil && ctx .Org .Organization .Visibility != api .VisibleTypePublic {
307263 ctx .Error (http .StatusForbidden , "reqToken" , "token scope is limited to public orgs" )
@@ -335,6 +291,54 @@ func checkTokenPublicOnly() func(ctx *context.APIContext) {
335291 }
336292}
337293
294+ // if a token is being used for auth, we check that it contains the required scope
295+ // if a token is not being used, reqToken will enforce other sign in methods
296+ func tokenRequiresScopes (requiredScopeCategories ... auth_model.AccessTokenScopeCategory ) func (ctx * context.APIContext ) {
297+ return func (ctx * context.APIContext ) {
298+ // no scope required
299+ if len (requiredScopeCategories ) == 0 {
300+ return
301+ }
302+
303+ // Need OAuth2 token to be present.
304+ scope , scopeExists := ctx .Data ["ApiTokenScope" ].(auth_model.AccessTokenScope )
305+ if ctx .Data ["IsApiToken" ] != true || ! scopeExists {
306+ return
307+ }
308+
309+ // use the http method to determine the access level
310+ requiredScopeLevel := auth_model .Read
311+ if ctx .Req .Method == "POST" || ctx .Req .Method == "PUT" || ctx .Req .Method == "PATCH" || ctx .Req .Method == "DELETE" {
312+ requiredScopeLevel = auth_model .Write
313+ }
314+
315+ // get the required scope for the given access level and category
316+ requiredScopes := auth_model .GetRequiredScopes (requiredScopeLevel , requiredScopeCategories ... )
317+ allow , err := scope .HasScope (requiredScopes ... )
318+ if err != nil {
319+ ctx .Error (http .StatusForbidden , "tokenRequiresScope" , "checking scope failed: " + err .Error ())
320+ return
321+ }
322+
323+ if ! allow {
324+ ctx .Error (http .StatusForbidden , "tokenRequiresScope" , fmt .Sprintf ("token does not have at least one of required scope(s): %v" , requiredScopes ))
325+ return
326+ }
327+
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 ())
334+ return
335+ }
336+
337+ // assign to true so that those searching should only filter public repositories/users/organizations
338+ ctx .PublicOnly = publicOnly
339+ }
340+ }
341+
338342// Contexter middleware already checks token for user sign in process.
339343func reqToken () func (ctx * context.APIContext ) {
340344 return func (ctx * context.APIContext ) {
@@ -941,17 +945,17 @@ func Routes() *web.Router {
941945 // Notifications (requires 'notifications' scope)
942946 m .Group ("/notifications" , func () {
943947 m .Combo ("" ).
944- Get (notify .ListNotifications ).
945- Put (notify .ReadNotifications )
946- m .Get ("/new" , notify .NewAvailable )
948+ Get (reqToken (), notify .ListNotifications ).
949+ Put (reqToken (), notify .ReadNotifications )
950+ m .Get ("/new" , reqToken (), notify .NewAvailable )
947951 m .Combo ("/threads/{id}" ).
948- Get (notify .GetThread ).
949- Patch (notify .ReadThread )
950- }, reqToken (), tokenRequiresScopes (auth_model .AccessTokenScopeCategoryNotification ))
952+ Get (reqToken (), notify .GetThread ).
953+ Patch (reqToken (), notify .ReadThread )
954+ }, tokenRequiresScopes (auth_model .AccessTokenScopeCategoryNotification ))
951955
952956 // Users (requires user scope)
953957 m .Group ("/users" , func () {
954- m .Get ("/search" , reqExploreSignIn (), tokenRequiresScopes ( auth_model . AccessTokenScopeCategoryUser ), user .Search )
958+ m .Get ("/search" , reqExploreSignIn (), user .Search )
955959
956960 m .Group ("/{username}" , func () {
957961 m .Get ("" , reqExploreSignIn (), user .GetInfo )
0 commit comments