2016-05-29 27 views
2

鑑於以下結果:我如何過濾REST調用基於角色和當前用戶的上下文中環路(服務器端)

有3種型號:

  1. 公司
  2. 員工(來自用戶)
  3. 位置

公司通過位置(有很多,有很多)鏈接到員工

有2個角色:

  1. 管理
  2. 用戶

我想我的REST API配置如下:

管理登錄,可以訪問所有REST功能。

"accessType": "*", 
    "principalType": "ROLE", 
    "principalId": "admin", 
    "permission": "ALLOW" 

用戶登錄:

GET /公司:只返回當前用戶具有一個位置的公司。

GET/companies /#id:只允許當前用戶在該公司有職位。

+0

您可能會增加出現的任何'/ companies'端點被稱爲後的生命週期方法,並修改'where'或'include'過濾器,只包括公司裏有一個記錄'位置'模型。然後可以在返回數據之前手動過濾結果。 不幸的是,環回不允許你基於[n級屬性](https://github.com/strongloop/loopback/issues/517)(內連接)進行篩選 - 儘管在問題上給出+1加快意識。 – J3Y

回答

1

根據J3Y的評論,我寫了下面的函數。

請注意,該功能不是重寫模型ACL。


的方法如下這些步驟:

1:訪問當前用戶的用戶ID 通過環回當前上下文

如果沒有通過身份驗證的用戶,請退出該功能。

2:當前用戶的負載作用,使用RoleMapping表

如果當前用戶角色不是「用戶」,退出功能。

3:負載位置我們的當前用戶的,創造企業的數組編號,他的工作在

4:重寫當前查詢

  • 用於/公司電話,注入一個地址條件爲id
  • for/companies /#id,如果請求測試id匹配其中一個允許的id,否則返回錯誤401

Company.observe('access', function (ctx, next) { 
    /* Observe the access to companies 
    * If the role of the logged user is 'user', will restrict access to only custom set of data 
    * Otherwise, will access all data */ 

    // Access loopback current Context to get userID through accessToken 
    var loopbackCtx = loopback.getCurrentContext(); 
    var accessToken = loopbackCtx && loopbackCtx.get('accessToken'); 
    var userId = accessToken && accessToken.userId; 

    if (!userId) { 
     // without connected user. proceed without hook 
     return next(); 
    } 

    // Will perform a query in the RoleMapping Model to findout the current role of connected user 
    var RoleMapping = app.models.RoleMapping; 
    var roleQuery = { 
     where: { 
     "principalId": userId, 
     "roleId": 2 // role 2: user 
     } 
    }; 

    RoleMapping.findOne(roleQuery, function (err, result) { 

     if (!result) { 
     //no matching role, proceed without hook 
     return next(); 
     } 

     // found one match in the RoleMapping table. must now restrict results in accordance with positions of the current employee 

     // Looking for positions for the current employee 
     var position = app.models.position; 
     var positionQuery = { 
     where: { 
      "employeeId": userId 
     } 
     }; 

     position.find(positionQuery, function (err, results) { 
     // from the position list, create a list of companies 

     var allowedCompanies = []; 
     results.forEach(function (result) { 
      allowedCompanies.push(result.companyId); 
     }); 

     //use the list of allowed companies to restrict results 
     if (!ctx.query.where) { 
      // typically call from a find() without arguments (findall) 
      // will inject a new condition 
      ctx.query = { 
      where: { 
       "id": { inq: allowedCompanies} 
      } 
      } 
     } 
     else { 
      if (ctx.query.where.id && Number.isInteger(ctx.query.where.id)) { 
      // typically call from a find({ id: ..)} 
      // will authorize or not access to the company data 
      console.log(ctx.query.where.id); 
      if (allowedCompanies.indexOf(ctx.query.where.id) == -1) { 
       // the id is not in the permited scope, will return a 401 error 
       var error = new Error(); 
       error.name = "Error"; 
       error.status = 401; 
       error.statusCode = 401; 
       error.message = 'Authorization Required'; 
       error.code = 'AUTHORIZATION_REQUIRED'; 
       return next(error); 
      } 
      } 
      // other calls (with inq) are not yet implemented 
     } 

     return next(); 
     }); 

    }); 

}); 
相關問題