Secured.tsx 2.4 KB

123456789101112131415161718192021222324252627282930313233343536373839404142434445464748495051525354555657585960616263646566
  1. import React from 'react';
  2. import CheckPermissions from './CheckPermissions';
  3. /**
  4. * 默认不能访问任何页面
  5. * default is "NULL"
  6. */
  7. const Exception403 = () => 403;
  8. export const isComponentClass = (component: React.ComponentClass | React.ReactNode): boolean => {
  9. if (!component) return false;
  10. const proto = Object.getPrototypeOf(component);
  11. if (proto === React.Component || proto === Function.prototype) return true;
  12. return isComponentClass(proto);
  13. };
  14. // Determine whether the incoming component has been instantiated
  15. // AuthorizedRoute is already instantiated
  16. // Authorized render is already instantiated, children is no instantiated
  17. // Secured is not instantiated
  18. const checkIsInstantiation = (target: React.ComponentClass | React.ReactNode) => {
  19. if (isComponentClass(target)) {
  20. const Target = target as React.ComponentClass;
  21. return (props: any) => <Target {...props} />;
  22. }
  23. if (React.isValidElement(target)) {
  24. return (props: any) => React.cloneElement(target, props);
  25. }
  26. return () => target;
  27. };
  28. /**
  29. * 用于判断是否拥有权限访问此 view 权限
  30. * authority 支持传入 string, () => boolean | Promise
  31. * e.g. 'user' 只有 user 用户能访问
  32. * e.g. 'user,admin' user 和 admin 都能访问
  33. * e.g. ()=>boolean 返回true能访问,返回false不能访问
  34. * e.g. Promise then 能访问 catch不能访问
  35. * e.g. authority support incoming string, () => boolean | Promise
  36. * e.g. 'user' only user user can access
  37. * e.g. 'user, admin' user and admin can access
  38. * e.g. () => boolean true to be able to visit, return false can not be accessed
  39. * e.g. Promise then can not access the visit to catch
  40. * @param {string | function | Promise} authority
  41. * @param {ReactNode} error 非必需参数
  42. */
  43. const authorize = (authority: string, error?: React.ReactNode) => {
  44. /**
  45. * conversion into a class
  46. * 防止传入字符串时找不到staticContext造成报错
  47. * String parameters can cause staticContext not found error
  48. */
  49. let classError: boolean | React.FunctionComponent = false;
  50. if (error) {
  51. classError = (() => error) as React.FunctionComponent;
  52. }
  53. if (!authority) {
  54. throw new Error('authority is required');
  55. }
  56. return function decideAuthority(target: React.ComponentClass | React.ReactNode) {
  57. const component = CheckPermissions(authority, target, classError || Exception403);
  58. return checkIsInstantiation(component);
  59. };
  60. };
  61. export default authorize;