can.js 1.8 KB

12345678910111213141516171819202122232425262728293031323334353637383940414243444546474849505152535455565758596061626364656667686970717273747576777879
  1. const model = require('../../models/');
  2. const AccessControl = require('accesscontrol').AccessControl;
  3. const createError = require('http-errors');
  4. const base = require('./base');
  5. /**
  6. * Check is user has permission.
  7. * @param {*} action
  8. * @param {*} resource
  9. * @returns
  10. */
  11. function need(action, resource) {
  12. return (req, res, next) => {
  13. (async () => {
  14. let ac = await getAc(req);
  15. let role = 'user';
  16. let perm = ac.permission({ role, action, resource });
  17. if (!perm.granted) throw createError(403, '权限不够');
  18. next();
  19. })().catch(next)
  20. };
  21. }
  22. async function readAny(req, resource) {
  23. if(!req.ac) throw 'ac no build';
  24. /**@type {AccessControl} */
  25. let ac = req.ac;
  26. return ac.can('user').readAny(resource).granted;
  27. }
  28. /**
  29. *
  30. * @param {string} userId
  31. * @returns {AccessControl}
  32. */
  33. async function buildAc(userId) {
  34. let user = await model.User.findById(userId).populate('roles');
  35. let grants = [];
  36. if (['chengen', 'guoziyun'].includes(user.username)) {
  37. grants = base.fullGrants();
  38. } else {
  39. user.roles.forEach(role => {
  40. grants = grants.concat(role.grants);
  41. })
  42. }
  43. // console.log('grants', grants);
  44. grants = grantsTransform(grants);
  45. // console.log('grants2ac', grants);
  46. return new AccessControl(grants);
  47. }
  48. /**
  49. *
  50. * @param {import('express').Request} req
  51. * @returns {AccessControl}
  52. */
  53. async function getAc(req) {
  54. if(req.ac) return req.ac;
  55. req.ac = await buildAc(req.session.user._id);
  56. return req.ac;
  57. }
  58. function grantsTransform(grants) {
  59. return grants.map(item => {
  60. let { resource, action, possession, attributes } = item;
  61. return {
  62. role: 'user',
  63. resource, attributes,
  64. action: `${action}:${possession}`,
  65. }
  66. })
  67. }
  68. module.exports = { need, buildAc, getAc, readAny }