Secured.js 2.19 KB
Newer Older
ddcat1115's avatar
ddcat1115 committed
1
import React from 'react';
2
import Exception from '../Exception';
ddcat1115's avatar
ddcat1115 committed
3
import CheckPermissions from './CheckPermissions';
4

ddcat1115's avatar
ddcat1115 committed
5 6 7 8
/**
 * 默认不能访问任何页面
 * default is "NULL"
 */
afc163's avatar
afc163 committed
9
const Exception403 = () => <Exception type="403" />;
ddcat1115's avatar
ddcat1115 committed
10

11 12 13 14 15 16 17
export const isComponentClass = component => {
  if (!component) return false;
  const proto = Object.getPrototypeOf(component);
  if (proto === React.Component || proto === Function.prototype) return true;
  return isComponentClass(proto);
};

jim's avatar
jim committed
18 19 20 21
// Determine whether the incoming component has been instantiated
// AuthorizedRoute is already instantiated
// Authorized  render is already instantiated, children is no instantiated
// Secured is not instantiated
jim's avatar
jim committed
22
const checkIsInstantiation = target => {
23 24 25 26 27 28
  if (isComponentClass(target)) {
    const Target = target;
    return props => <Target {...props} />;
  }
  if (React.isValidElement(target)) {
    return props => React.cloneElement(target, props);
jim's avatar
jim committed
29 30 31 32
  }
  return () => target;
};

ddcat1115's avatar
ddcat1115 committed
33
/**
34 35 36 37
 * 用于判断是否拥有权限访问此 view 权限
 * authority 支持传入 string, () => boolean | Promise
 * e.g. 'user' 只有 user 用户能访问
 * e.g. 'user,admin' user 和 admin 都能访问
ddcat1115's avatar
ddcat1115 committed
38 39
 * e.g. ()=>boolean 返回true能访问,返回false不能访问
 * e.g. Promise  then 能访问   catch不能访问
40
 * e.g. authority support incoming string, () => boolean | Promise
ddcat1115's avatar
ddcat1115 committed
41 42 43 44 45 46 47 48 49 50 51 52 53 54 55 56 57 58 59 60
 * e.g. 'user' only user user can access
 * e.g. 'user, admin' user and admin can access
 * e.g. () => boolean true to be able to visit, return false can not be accessed
 * e.g. Promise then can not access the visit to catch
 * @param {string | function | Promise} authority
 * @param {ReactNode} error 非必需参数
 */
const authorize = (authority, error) => {
  /**
   * conversion into a class
   * 防止传入字符串时找不到staticContext造成报错
   * String parameters can cause staticContext not found error
   */
  let classError = false;
  if (error) {
    classError = () => error;
  }
  if (!authority) {
    throw new Error('authority is required');
  }
EthanWan's avatar
EthanWan committed
61 62
  return function decideAuthority(target) {
    const component = CheckPermissions(authority, target, classError || Exception403);
jim's avatar
jim committed
63
    return checkIsInstantiation(component);
ddcat1115's avatar
ddcat1115 committed
64 65 66 67
  };
};

export default authorize;