All files / src/containers/AuthorizationHandler index.jsx

85.29% Statements 29/34
68.75% Branches 11/16
80% Functions 4/5
84.85% Lines 28/33
1 2 3 4 5 6 7 8 9 10 11 12 13 14 15 16 17 18 19 20 21 22 23 24 25 26 27 28 29 30 31 32 33 34 35 36 37 38 39 40 41 42 43 44 45 46 47 48 49 50 51 52 53 54 55 56 57 58 59 60 61 62 63 64 65 66 67 68 69 70 71 72 73 74 75 76 77 78 79 80 81 82 83 84 85 86 87 88 89                              1x 11x   11x   11x 7x     7x 7x 7x   7x 7x   4x     7x 2x 2x 2x     5x 2x     4x 2x       2x     1x                         3x 3x 10x 7x     3x           3x     3x                
import React from 'react';
import ReactGA from 'react-ga';
import PropTypes from 'prop-types';
import pure from 'recompose/pure';
import Raven from 'raven-js';
import connect from 'domain/connect';
import is from 'is_js';
import { actions as privilegesActions } from 'containers/Privileges';
import { bindActionCreators } from 'redux';
import AuthorisationErrorPage from 'components/AuthorisationErrorPage';
import ErrorPageConfig from 'domain/ErrorPageConfig';
import Config from 'domain/Config';
import log from 'domain/log';
import PageLoadingSpinner from 'components/PageLoadingSpinner';
 
export const AuthorizationHandler = (props) => {
  const { user, permissionChecks, children, havePrivilegesLoaded } = props;
 
  const spinner = <PageLoadingSpinner />;
 
  if (Config.get('featureLogin')) {
    Iif (! user) {
      return spinner;
    }
    const profile = user.get('profile');
    const userId = profile.sub;
    const email = profile.email;
 
    ReactGA.set({ userId });
    Raven.setUserContext({ email, id: userId });
  } else {
    return children;
  }
 
  if (! havePrivilegesLoaded()) {
    log.debug('PermissionHandler - Will call fetchPrivilegesIfNeeded()');
    props.fetchPrivilegesIfNeeded();
    return spinner;
  }
 
  if (is.undefined(permissionChecks)) {
    return children;
  }
 
  const forbiddenRoute = permissionChecks.find(({ canAccess }) => ! canAccess(props));
  Iif (is.undefined(forbiddenRoute)) {
    return children;
  }
 
  return <AuthorisationErrorPage {...props} />;
};
 
AuthorizationHandler.propTypes = {
  user: PropTypes.shape({
    get: PropTypes.function,
  }),
  permissionChecks: PropTypes.arrayOf(PropTypes.shape({
    canAccess: PropTypes.func.isRequired,
  })),
  children: PropTypes.node,
  havePrivilegesLoaded: PropTypes.func.isRequired,
  fetchPrivilegesIfNeeded: PropTypes.func.isRequired,
};
 
export function mapStateToProps(state, { routes }) {
  const user = state.get('singleSignOn').get('user');
  const permissionChecks = routes.filter((route) => {
    if (is.not.existy(route.canAccess)) {
      return false;
    }
 
    Iif (! PRODUCTION) {
      if (is.not.function(route.canAccess)) {
        throw new Error('canAccess in the route configuration should be a function');
      }
    }
 
    return true;
  });
 
  return { user, permissionChecks, config: ErrorPageConfig.get(routes) };
}
 
function mapDispatchToProps(dispatch) {
  return bindActionCreators(privilegesActions, dispatch);
}
 
export default connect(mapStateToProps, mapDispatchToProps)(pure(AuthorizationHandler));