import {Component} from 'react';
import Alert from 'sentry/components/alert';
import {t} from 'sentry/locale';
import {Config, Organization, Scope} from 'sentry/types';
import {isRenderFunc} from 'sentry/utils/isRenderFunc';
import withConfig from 'sentry/utils/withConfig';
import withOrganization from 'sentry/utils/withOrganization';
const DEFAULT_NO_ACCESS_MESSAGE = (
{t('You do not have sufficient permissions to access this.')}
);
// Props that function children will get.
export type ChildRenderProps = {
hasAccess: boolean;
hasSuperuser: boolean;
};
type ChildFunction = (props: ChildRenderProps) => React.ReactNode;
type DefaultProps = {
/**
* List of required access levels
*/
access: Scope[];
/**
* Custom renderer function for "no access" message OR `true` to use
* default message. `false` will suppress message.
*/
renderNoAccessMessage: ChildFunction | boolean;
/**
* Requires superuser
*/
isSuperuser?: boolean;
/**
* Should the component require all access levels or just one or more.
*/
requireAll?: boolean;
};
const defaultProps: DefaultProps = {
renderNoAccessMessage: false,
isSuperuser: false,
requireAll: true,
access: [],
};
type Props = {
/**
* Configuration from ConfigStore
*/
config: Config;
/**
* Current Organization
*/
organization: Organization;
/**
* Children can be a node or a function as child.
*/
children?: React.ReactNode | ChildFunction;
} & Partial;
/**
* Component to handle access restrictions.
*/
class Access extends Component {
static defaultProps = defaultProps;
render() {
const {
organization,
config,
access,
requireAll,
isSuperuser,
renderNoAccessMessage,
children,
} = this.props;
const {access: orgAccess} = organization || {access: []};
const method = requireAll ? 'every' : 'some';
const hasAccess = !access || access[method](acc => orgAccess.includes(acc));
const hasSuperuser = !!(config.user && config.user.isSuperuser);
const renderProps: ChildRenderProps = {
hasAccess,
hasSuperuser,
};
const render = hasAccess && (!isSuperuser || hasSuperuser);
if (!render && typeof renderNoAccessMessage === 'function') {
return renderNoAccessMessage(renderProps);
}
if (!render && renderNoAccessMessage) {
return DEFAULT_NO_ACCESS_MESSAGE;
}
if (isRenderFunc(children)) {
return children(renderProps);
}
return render ? children : null;
}
}
export default withOrganization(withConfig(Access));