Restrict pages access by unauthorized users
This commit is contained in:
parent
d91cbb3f56
commit
52a857d296
3 changed files with 76 additions and 18 deletions
34
app/soapbox/features/ui/components/column_forbidden.js
Normal file
34
app/soapbox/features/ui/components/column_forbidden.js
Normal file
|
@ -0,0 +1,34 @@
|
|||
import React from 'react';
|
||||
import PropTypes from 'prop-types';
|
||||
import { defineMessages, injectIntl } from 'react-intl';
|
||||
|
||||
import Column from './column';
|
||||
import ColumnHeader from './column_header';
|
||||
|
||||
const messages = defineMessages({
|
||||
title: { id: 'column_forbidden.title', defaultMessage: 'Forbidden' },
|
||||
body: { id: 'column_forbidden.body', defaultMessage: 'You do not have permission to access this page.' },
|
||||
});
|
||||
|
||||
class ColumnForbidden extends React.PureComponent {
|
||||
|
||||
static propTypes = {
|
||||
intl: PropTypes.object.isRequired,
|
||||
}
|
||||
|
||||
render() {
|
||||
const { intl: { formatMessage } } = this.props;
|
||||
|
||||
return (
|
||||
<Column>
|
||||
<ColumnHeader icon='exclamation-circle' type={formatMessage(messages.title)} />
|
||||
<div className='error-column'>
|
||||
{formatMessage(messages.body)}
|
||||
</div>
|
||||
</Column>
|
||||
);
|
||||
}
|
||||
|
||||
}
|
||||
|
||||
export default injectIntl(ColumnForbidden);
|
|
@ -317,14 +317,14 @@ class SwitchingColumnsArea extends React.PureComponent {
|
|||
<WrappedRoute path='/settings/import' page={DefaultPage} component={ImportData} content={children} />
|
||||
<WrappedRoute path='/settings/aliases' page={DefaultPage} component={Aliases} content={children} />
|
||||
<WrappedRoute path='/backups' page={DefaultPage} component={Backups} content={children} />
|
||||
<WrappedRoute path='/soapbox/config' page={DefaultPage} component={SoapboxConfig} content={children} />
|
||||
<WrappedRoute path='/soapbox/config' adminOnly page={DefaultPage} component={SoapboxConfig} content={children} />
|
||||
|
||||
<Redirect from='/admin/dashboard' to='/admin' exact />
|
||||
<WrappedRoute path='/admin' page={AdminPage} component={Dashboard} content={children} exact />
|
||||
<WrappedRoute path='/admin/approval' page={AdminPage} component={AwaitingApproval} content={children} exact />
|
||||
<WrappedRoute path='/admin/reports' page={AdminPage} component={Reports} content={children} exact />
|
||||
<WrappedRoute path='/admin/log' page={AdminPage} component={ModerationLog} content={children} exact />
|
||||
<WrappedRoute path='/admin/users' page={AdminPage} component={UserIndex} content={children} exact />
|
||||
<WrappedRoute path='/admin' staffOnly page={AdminPage} component={Dashboard} content={children} exact />
|
||||
<WrappedRoute path='/admin/approval' staffOnly page={AdminPage} component={AwaitingApproval} content={children} exact />
|
||||
<WrappedRoute path='/admin/reports' staffOnly page={AdminPage} component={Reports} content={children} exact />
|
||||
<WrappedRoute path='/admin/log' staffOnly page={AdminPage} component={ModerationLog} content={children} exact />
|
||||
<WrappedRoute path='/admin/users' staffOnly page={AdminPage} component={UserIndex} content={children} exact />
|
||||
<WrappedRoute path='/info' page={EmptyPage} component={ServerInfo} content={children} />
|
||||
|
||||
<WrappedRoute path='/developers/apps/create' page={DefaultPage} component={CreateApp} content={children} />
|
||||
|
|
|
@ -1,16 +1,20 @@
|
|||
import React from 'react';
|
||||
import { connect } from 'react-redux';
|
||||
import PropTypes from 'prop-types';
|
||||
import SoapboxPropTypes from 'soapbox/utils/soapbox_prop_types';
|
||||
import ImmutablePropTypes from 'react-immutable-proptypes';
|
||||
import { Redirect, Route } from 'react-router-dom';
|
||||
import ColumnsAreaContainer from '../containers/columns_area_container';
|
||||
import ColumnLoading from '../components/column_loading';
|
||||
import ColumnForbidden from '../components/column_forbidden';
|
||||
import BundleColumnError from '../components/bundle_column_error';
|
||||
import BundleContainer from '../containers/bundle_container';
|
||||
import { isStaff, isAdmin } from 'soapbox/utils/accounts';
|
||||
|
||||
const mapStateToProps = state => {
|
||||
const me = state.get('me');
|
||||
|
||||
return {
|
||||
me: state.get('me'),
|
||||
account: state.getIn(['accounts', me]),
|
||||
};
|
||||
};
|
||||
|
||||
|
@ -22,8 +26,10 @@ class WrappedRoute extends React.Component {
|
|||
content: PropTypes.node,
|
||||
componentParams: PropTypes.object,
|
||||
layout: PropTypes.object,
|
||||
account: ImmutablePropTypes.map,
|
||||
publicRoute: PropTypes.bool,
|
||||
me: SoapboxPropTypes.me,
|
||||
staffOnly: PropTypes.bool,
|
||||
adminOnly: PropTypes.bool,
|
||||
};
|
||||
|
||||
static defaultProps = {
|
||||
|
@ -72,6 +78,14 @@ class WrappedRoute extends React.Component {
|
|||
);
|
||||
}
|
||||
|
||||
renderForbidden = () => {
|
||||
return (
|
||||
<ColumnsAreaContainer layout={this.props.layout}>
|
||||
<ColumnForbidden />
|
||||
</ColumnsAreaContainer>
|
||||
);
|
||||
}
|
||||
|
||||
renderError = (props) => {
|
||||
return (
|
||||
<ColumnsAreaContainer layout={this.props.layout}>
|
||||
|
@ -80,16 +94,26 @@ class WrappedRoute extends React.Component {
|
|||
);
|
||||
}
|
||||
|
||||
render() {
|
||||
const { component: Component, content, publicRoute, me, ...rest } = this.props;
|
||||
loginRedirect = () => {
|
||||
const actualUrl = encodeURIComponent(`${this.props.computedMatch.url}${this.props.location.search}`); // eslint-disable-line react/prop-types
|
||||
return <Redirect to={`/auth/sign_in?redirect_uri=${actualUrl}`} />;
|
||||
}
|
||||
|
||||
if (!publicRoute && me === false) {
|
||||
const actualUrl = encodeURIComponent(`${this.props.computedMatch.url}${this.props.location.search}`); // eslint-disable-line react/prop-types
|
||||
return <Redirect to={`/auth/sign_in?redirect_uri=${actualUrl}`} />;
|
||||
// return <Route path={this.props.path} component={() => {
|
||||
// window.location.href = `/auth/sign_in?redirect_uri=${actualUrl}`;
|
||||
// return null;
|
||||
// }}/>
|
||||
render() {
|
||||
const { component: Component, content, account, publicRoute, staffOnly, adminOnly, ...rest } = this.props;
|
||||
|
||||
const authorized = [
|
||||
account || publicRoute,
|
||||
staffOnly ? account && isStaff(account) : true,
|
||||
adminOnly ? account && isAdmin(account) : true,
|
||||
].every(c => c);
|
||||
|
||||
if (!authorized) {
|
||||
if (!account) {
|
||||
return this.loginRedirect();
|
||||
} else {
|
||||
return this.renderForbidden();
|
||||
}
|
||||
}
|
||||
|
||||
return <Route {...rest} render={this.renderComponent} />;
|
||||
|
|
Loading…
Reference in a new issue