Rick Watson
5 years ago
11 changed files with 263 additions and 120 deletions
-
2interface/.env.development
-
2interface/src/AppRouting.js
-
2interface/src/components/MenuAppBar.js
-
21interface/src/containers/ManageUsers.js
-
28interface/src/containers/Security.js
-
32interface/src/containers/SecuritySettings.js
-
187interface/src/forms/ManageUsersForm.js
-
97interface/src/forms/SecuritySettingsForm.js
-
2interface/src/forms/UserForm.js
-
8src/SecurityManager.cpp
-
2src/SecurityManager.h
@ -1 +1 @@ |
|||
REACT_APP_ENDPOINT_ROOT=http://192.168.0.16/rest/ |
|||
REACT_APP_ENDPOINT_ROOT=http://192.168.0.11/rest/ |
@ -1,15 +1,35 @@ |
|||
import React, { Component } from 'react'; |
|||
import { Redirect, Switch } from 'react-router-dom' |
|||
|
|||
import Tabs from '@material-ui/core/Tabs'; |
|||
import Tab from '@material-ui/core/Tab'; |
|||
|
|||
import AuthenticatedRoute from '../authentication/AuthenticatedRoute'; |
|||
import MenuAppBar from '../components/MenuAppBar'; |
|||
import ManageUsers from './ManageUsers'; |
|||
import SecuritySettings from './SecuritySettings'; |
|||
|
|||
class Security extends Component { |
|||
|
|||
handleTabChange = (event, path) => { |
|||
this.props.history.push(path); |
|||
}; |
|||
|
|||
render() { |
|||
return ( |
|||
<MenuAppBar sectionTitle="Security"> |
|||
<ManageUsers /> |
|||
</MenuAppBar> |
|||
<MenuAppBar sectionTitle="Security"> |
|||
<Tabs value={this.props.match.url} onChange={this.handleTabChange} indicatorColor="primary" textColor="primary" variant="fullWidth"> |
|||
<Tab value="/security/users" label="Manage Users" /> |
|||
<Tab value="/security/settings" label="Security Settings" /> |
|||
</Tabs> |
|||
<Switch> |
|||
<AuthenticatedRoute exact={true} path="/security/users" component={ManageUsers} /> |
|||
<AuthenticatedRoute exact={true} path="/security/settings" component={SecuritySettings} /> |
|||
<Redirect to="/security/users" /> |
|||
</Switch> |
|||
</MenuAppBar> |
|||
) |
|||
} |
|||
} |
|||
|
|||
export default Security |
|||
export default Security; |
@ -0,0 +1,32 @@ |
|||
import React, { Component } from 'react'; |
|||
|
|||
import { USERS_ENDPOINT } from '../constants/Endpoints'; |
|||
import { restComponent } from '../components/RestComponent'; |
|||
import SecuritySettingsForm from '../forms/SecuritySettingsForm'; |
|||
import SectionContent from '../components/SectionContent'; |
|||
|
|||
class SecuritySettings extends Component { |
|||
|
|||
componentDidMount() { |
|||
this.props.loadData(); |
|||
} |
|||
|
|||
render() { |
|||
const { data, fetched, errorMessage } = this.props; |
|||
return ( |
|||
<SectionContent title="Security Settings"> |
|||
<SecuritySettingsForm |
|||
securitySettings={data} |
|||
securitySettingsFetched={fetched} |
|||
errorMessage={errorMessage} |
|||
onSubmit={this.props.saveData} |
|||
onReset={this.props.loadData} |
|||
handleValueChange={this.props.handleValueChange} |
|||
/> |
|||
</SectionContent> |
|||
) |
|||
} |
|||
|
|||
} |
|||
|
|||
export default restComponent(USERS_ENDPOINT, SecuritySettings); |
@ -0,0 +1,97 @@ |
|||
import React from 'react'; |
|||
import PropTypes from 'prop-types'; |
|||
import { ValidatorForm } from 'react-material-ui-form-validator'; |
|||
|
|||
import { withStyles } from '@material-ui/core/styles'; |
|||
import Button from '@material-ui/core/Button'; |
|||
import LinearProgress from '@material-ui/core/LinearProgress'; |
|||
import Typography from '@material-ui/core/Typography'; |
|||
import Box from '@material-ui/core/Box'; |
|||
|
|||
import PasswordValidator from '../components/PasswordValidator'; |
|||
import { withAuthenticationContext } from '../authentication/Context'; |
|||
|
|||
const styles = theme => ({ |
|||
loadingSettings: { |
|||
margin: theme.spacing.unit, |
|||
}, |
|||
loadingSettingsDetails: { |
|||
margin: theme.spacing.unit * 4, |
|||
textAlign: "center" |
|||
}, |
|||
textField: { |
|||
width: "100%" |
|||
}, |
|||
button: { |
|||
marginRight: theme.spacing.unit * 2, |
|||
marginTop: theme.spacing.unit * 2, |
|||
} |
|||
}); |
|||
|
|||
class SecuritySettingsForm extends React.Component { |
|||
|
|||
onSubmit = () => { |
|||
this.props.onSubmit(); |
|||
this.props.authenticationContext.refresh(); |
|||
} |
|||
|
|||
render() { |
|||
const { classes, securitySettingsFetched, securitySettings, errorMessage, handleValueChange, onReset } = this.props; |
|||
return ( |
|||
!securitySettingsFetched ? |
|||
<div className={classes.loadingSettings}> |
|||
<LinearProgress className={classes.loadingSettingsDetails} /> |
|||
<Typography variant="h4" className={classes.loadingSettingsDetails}> |
|||
Loading... |
|||
</Typography> |
|||
</div> |
|||
: |
|||
securitySettings ? |
|||
<ValidatorForm onSubmit={this.onSubmit} ref="SecuritySettingsForm"> |
|||
<PasswordValidator |
|||
validators={['required', 'matchRegexp:^.{0,64}$']} |
|||
errorMessages={['JWT Secret Required', 'JWT Secret must be 64 characters or less']} |
|||
name="jwt_secret" |
|||
label="JWT Secret" |
|||
className={classes.textField} |
|||
value={securitySettings.jwt_secret} |
|||
onChange={handleValueChange('jwt_secret')} |
|||
margin="normal" |
|||
/> |
|||
<Typography component="div" variant="body1"> |
|||
<Box bgcolor="primary.main" color="primary.contrastText" p={2} m={2}> |
|||
If you modify the JWT Secret, all users will be logged out. |
|||
</Box> |
|||
</Typography> |
|||
<Button variant="contained" color="primary" className={classes.button} type="submit"> |
|||
Save |
|||
</Button> |
|||
<Button variant="contained" color="secondary" className={classes.button} onClick={onReset}> |
|||
Reset |
|||
</Button> |
|||
</ValidatorForm> |
|||
: |
|||
<div className={classes.loadingSettings}> |
|||
<Typography variant="h4" className={classes.loadingSettingsDetails}> |
|||
{errorMessage} |
|||
</Typography> |
|||
<Button variant="contained" color="secondary" className={classes.button} onClick={onReset}> |
|||
Reset |
|||
</Button> |
|||
</div> |
|||
); |
|||
} |
|||
} |
|||
|
|||
SecuritySettingsForm.propTypes = { |
|||
classes: PropTypes.object.isRequired, |
|||
securitySettingsFetched: PropTypes.bool.isRequired, |
|||
securitySettings: PropTypes.object, |
|||
errorMessage: PropTypes.string, |
|||
onSubmit: PropTypes.func.isRequired, |
|||
onReset: PropTypes.func.isRequired, |
|||
handleValueChange: PropTypes.func.isRequired, |
|||
authenticationContext: PropTypes.object.isRequired, |
|||
}; |
|||
|
|||
export default withAuthenticationContext(withStyles(styles)(SecuritySettingsForm)); |
Write
Preview
Loading…
Cancel
Save
Reference in new issue