1
0
mirror of https://gitlab.com/psono/psono-admin-client synced 2025-04-19 03:22:17 +03:00

Added policies

Signed-off-by: Sascha Pfeiffer <sascha.pfeiffer@esaqa.com>
This commit is contained in:
Sascha Pfeiffer 2023-11-14 13:44:11 +01:00
parent 5bc3b34dac
commit a4924002ff
19 changed files with 1749 additions and 94 deletions

View File

@ -3,7 +3,7 @@
[![coverage report](https://gitlab.com/psono/psono-admin-client/badges/master/coverage.svg)](https://gitlab.com/psono/psono-admin-client/commits/master)
[![Code Climate](https://codeclimate.com/github/psono/psono-admin-client/badges/gpa.svg)](https://codeclimate.com/github/psono/psono-admin-client)
[![build status](https://img.shields.io/docker/pulls/psono/psono-admin-client.svg)](https://hub.docker.com/r/psono/psono-admin-client/)
[![Discord](https://img.shields.io/badge/Discord-join%20chat-738bd7.svg)](https://discord.gg/RuSvEjj)
[![Discord](https://img.shields.io/badge/Discord-join%20chat-738bd7.svg)](https://discord.gg/VmBMzTSbGV)
[![POEditor](https://img.shields.io/badge/POEditor-Help%20translate-brightgreen.svg)](https://poeditor.com/join/project?hash=xwGlVVPZbM)
# Canonical source

View File

@ -1,4 +1,37 @@
{
"SETTINGS": "Einstellungen",
"OVERWRITE": "Überschreiben",
"VALUE": "Wert",
"POLICY_COMPLIANCE_DISABLE_API_KEYS": "API Keys deaktivieren",
"POLICY_COMPLIANCE_DISABLE_DELETE_ACCOUNT": "Account löschen deaktivieren",
"POLICY_COMPLIANCE_DISABLE_EMERGENCY_CODES": "Notfall Codes deaktivieren",
"POLICY_COMPLIANCE_DISABLE_EXPORT": "Export deaktivieren",
"POLICY_COMPLIANCE_DISABLE_EXPORT_OF_SHARED_ITEMS": "Export von gesharten Einträgen deaktivieren",
"POLICY_COMPLIANCE_DISABLE_FILE_REPOSITORIES": "Daten Repositories deaktivieren",
"POLICY_COMPLIANCE_DISABLE_LINK_SHARES": "Link shares deaktivieren",
"POLICY_COMPLIANCE_DISABLE_OFFLINE_MODE": "Offline Mode deaktivieren",
"POLICY_COMPLIANCE_DISABLE_SHARES": "Shares deaktivieren",
"POLICY_COMPLIANCE_DISABLE_RECOVERY_CODES": "Wiederherstellungs Codes deaktivieren",
"POLICY_COMPLIANCE_DISABLE_UNMANAGED_GROUPS": "Ungemanagte Gruppen deaktivieren",
"POLICY_COMPLIANCE_ENFORCE_2FA": "Zwei-Faktor erzwingen",
"POLICY_COMPLIANCE_ENFORCE_CENTRAL_SECURITY_REPORTS": "Zentrale Security Reports erzwingen",
"POLICY_DISABLE_CENTRAL_SECURITY_REPORTS": "Zentrale Security Reports deaktivieren",
"POLICY_DISABLE_CALLBACKS": "Callbacks deaktivieren",
"POLICY_ALLOW_USER_SEARCH_BY_EMAIL": "Suche von Nutzern mit E-Mail Adressen erlauben",
"POLICY_ALLOW_USER_SEARCH_BY_USERNAME_PARTIAL": "Suche von Nutzern mit partiellen Nutzernamen erlauben",
"POLICY_COMPLIANCE_CENTRAL_SECURITY_REPORT_SECURITY_RECURRENCE_INTERVAL": "Wiederholungsintervall in Sekunden für zentrale Security Reports",
"POLICY_COMPLIANCE_MAX_OFFLINE_CACHE_TIME_VALID": "Maximales Alter in Sekunden seit der letzten Serververbindung des Offline Caches",
"POLICY_COMPLIANCE_PASSWORD_GENERATOR_DEFAULT_PASSWORD_LENGTH": "Passwortgenerator Default Einstellung für die Länge von Passwörtern",
"POLICY_COMPLIANCE_PASSWORD_GENERATOR_DEFAULT_LETTERS_UPPERCASE": "Passwortgenerator Default Einstellung für die Großbuchstaben",
"POLICY_COMPLIANCE_PASSWORD_GENERATOR_DEFAULT_LETTERS_LOWERCASE": "Passwortgenerator Default Einstellung für die Kleinbuchstaben",
"POLICY_COMPLIANCE_PASSWORD_GENERATOR_DEFAULT_NUMBERS": "Passwortgenerator Default Einstellung für die Zahlen",
"POLICY_COMPLIANCE_PASSWORD_GENERATOR_DEFAULT_SPECIAL_CHARS": "Passwortgenerator Default Einstellung für die Sonderzeichen",
"POLICY_ALLOWED_FILE_REPOSITORY_TYPES": "Erlaubte Datei Repository Typen",
"POLICY_ALLOWED_SECOND_FACTORS": "Erlaubte zweite Faktoren",
"CONFIGURATION": "Konfiguration",
"POLICY_DETAILS": "Richtlinie Details",
"EDIT_POLICY": "Richtlinie bearbeiten",
"UPDATE_POLICY_DETAILS": "Richtlinien Details aktualisieren",
"LAST_UPDATED_IN_DAYS": "Zuletzt Geändert (days)",
"CREATED_IN_DAYS": "Erstellt (days)",
"SCIM": "SCIM",
@ -215,7 +248,7 @@
"CREATION_DATE": "Erstellungsdatum",
"NAME": "Name",
"POVIDER_ID": "Anbieter ID",
"UPDATE_GROUP_DETAILS": "Gruppen details aktualisieren",
"UPDATE_GROUP_DETAILS": "Gruppen Details aktualisieren",
"APPROVE_UNSAFE": "Genehmigen (unsicher)",
"DISAPPROVE_UNSAFE": "Verweigern (sicher)",
"SEND": "Senden",
@ -245,6 +278,12 @@
"OIDC": "OIDC",
"DASHBOARD": "Dashboard",
"USERS": "Benutzer",
"CREATE_POLICY": "Richtlinien erstellen",
"PRIORITY": "Priorität",
"EDIT": "Bearbeiten",
"POLICY": "Richtlinie",
"POLICIES": "Richtlinien",
"POLICY_LIST_INFO": "Diese Liste zeigt alle konfigurierten Richtlinien.",
"SESSIONS": "Sessions",
"MEMBERSHIPS": "Mitgliedschaften",
"DUOS": "Duos",
@ -264,7 +303,7 @@
"SAVE": "Speichern",
"REGISTRATION_DATE": "Registrierungs-Datum",
"PUBLIC_KEY": "Öffentlicher Schlüssel",
"UPDATE_USER_DETAILS": "Benutzer details aktualisieren",
"UPDATE_USER_DETAILS": "Benutzer Details aktualisieren",
"EDIT_USER": "Benutzer Bearbeiten",
"SERVER_ASKS_FOR_YOUR_PLAINTEXT_PASSWORD": "Server frägt nach deinem Klartext-Passwort",
"ACCEPTING_THIS_WILL_SEND_YOUR_PLAIN_PASSWORD": "Wenn sie die Anfrage genehmigen werden sie ihr Klartext-Passwort zum Server übermitteln. Sie sollten dies nur tun, wenn sie LDAP oder eine ähnliche Authentifizierungsmethode einsetzen. Sie können diese Anfrage abweisen was aber zu einem Authentifizierungsfehler führen kann.",

View File

@ -1,4 +1,37 @@
{
"SETTINGS": "Settings",
"OVERWRITE": "Overwrite",
"VALUE": "Value",
"POLICY_COMPLIANCE_DISABLE_API_KEYS": "Disable API Keys",
"POLICY_COMPLIANCE_DISABLE_DELETE_ACCOUNT": "Disable delete account",
"POLICY_COMPLIANCE_DISABLE_EMERGENCY_CODES": "Disable emergency codes",
"POLICY_COMPLIANCE_DISABLE_EXPORT": "Disable export",
"POLICY_COMPLIANCE_DISABLE_EXPORT_OF_SHARED_ITEMS": "Disable export of shared items",
"POLICY_COMPLIANCE_DISABLE_FILE_REPOSITORIES": "Disable file repositories",
"POLICY_COMPLIANCE_DISABLE_LINK_SHARES": "Disable link shares",
"POLICY_COMPLIANCE_DISABLE_OFFLINE_MODE": "Disable offline mode",
"POLICY_COMPLIANCE_DISABLE_SHARES": "Disable shares",
"POLICY_COMPLIANCE_DISABLE_RECOVERY_CODES": "Disable recovery codes",
"POLICY_COMPLIANCE_DISABLE_UNMANAGED_GROUPS": "Disable unmananged groups",
"POLICY_COMPLIANCE_ENFORCE_2FA": "Enforce second factor",
"POLICY_COMPLIANCE_ENFORCE_CENTRAL_SECURITY_REPORTS": "Enforce central security reports",
"POLICY_DISABLE_CENTRAL_SECURITY_REPORTS": "Disable central security reports",
"POLICY_DISABLE_CALLBACKS": "Disable callbacks",
"POLICY_ALLOW_USER_SEARCH_BY_EMAIL": "Allow user search by email",
"POLICY_ALLOW_USER_SEARCH_BY_USERNAME_PARTIAL": "Allow user search by partial username",
"POLICY_COMPLIANCE_CENTRAL_SECURITY_REPORT_SECURITY_RECURRENCE_INTERVAL": "Recurrency interval in seconds for central security reports",
"POLICY_COMPLIANCE_MAX_OFFLINE_CACHE_TIME_VALID": "Maximum age in seconds till last server connection of the offline cache",
"POLICY_COMPLIANCE_PASSWORD_GENERATOR_DEFAULT_PASSWORD_LENGTH": "Passwordgenerator default setting for the length of passwords",
"POLICY_COMPLIANCE_PASSWORD_GENERATOR_DEFAULT_LETTERS_UPPERCASE": "Passwordgenerator default setting for the uppercase letters",
"POLICY_COMPLIANCE_PASSWORD_GENERATOR_DEFAULT_LETTERS_LOWERCASE": "Passwordgenerator default setting for the lowercase letters",
"POLICY_COMPLIANCE_PASSWORD_GENERATOR_DEFAULT_NUMBERS": "Passwordgenerator default setting for the numbers",
"POLICY_COMPLIANCE_PASSWORD_GENERATOR_DEFAULT_SPECIAL_CHARS": "Passwordgenerator default setting for the special characters",
"POLICY_ALLOWED_FILE_REPOSITORY_TYPES": "Allowed file repository types",
"POLICY_ALLOWED_SECOND_FACTORS": "Allowed second factors",
"CONFIGURATION": "Configuration",
"POLICY_DETAILS": "Policy Details",
"EDIT_POLICY": "Edit policy",
"UPDATE_POLICY_DETAILS": "Update the policy details",
"LAST_UPDATED_IN_DAYS": "Last Updated (days)",
"CREATED_IN_DAYS": "Created (days)",
"SCIM": "SCIM",
@ -245,6 +278,12 @@
"OIDC": "OIDC",
"DASHBOARD": "Dashboard",
"USERS": "Users",
"CREATE_POLICY": "Create Policy",
"PRIORITY": "Priority",
"EDIT": "Edit",
"POLICY": "Policy",
"POLICIES": "Policies",
"POLICY_LIST_INFO": "This list shows all configured policies.",
"SESSIONS": "Sessions",
"MEMBERSHIPS": "Memberships",
"DUOS": "Duos",

View File

@ -223,6 +223,15 @@ class UsersCard extends React.Component {
<CustomMaterialTable
tableRef={this.props.groupTableRef}
columns={[
{
field: 'mapped',
title: t('MAPPED'),
customSort: (a, b) => {
return (
a.mapped_raw - b.mapped_raw
);
},
},
{ field: 'name', title: t('NAME') },
{
field: 'create_date',

View File

@ -10,6 +10,7 @@ import { Header, Footer, Sidebar, Notification } from '../../components';
import otherLinks from '../../routes/other';
import sidebarLinks from '../../routes/sidebar';
import eeLinks from '../../routes/ee';
import ldapLinks from '../../routes/ldap';
import samlLinks from '../../routes/saml';
import oidcLinks from '../../routes/oidc';
@ -56,25 +57,33 @@ class App extends React.Component {
const { classes, ...rest } = this.props;
let variableLinks = [];
if (this.props.state.server.type === 'EE') {
eeLinks.forEach(function (link) {
variableLinks.push(link);
});
}
if (
this.props.state.server.type === 'EE' &&
this.props.state.server.authentication_methods.indexOf('LDAP') !==
-1
-1
) {
ldapLinks.forEach(function (link) {
variableLinks.push(link);
});
}
if (
this.props.state.server.type === 'EE' &&
this.props.state.server.authentication_methods.indexOf('SAML') !==
-1
-1
) {
samlLinks.forEach(function (link) {
variableLinks.push(link);
});
}
if (
this.props.state.server.type === 'EE' &&
this.props.state.server.authentication_methods.indexOf('OIDC') !==
-1
-1
) {
oidcLinks.forEach(function (link) {
variableLinks.push(link);

View File

@ -0,0 +1,86 @@
import React from 'react';
import { Switch, Route, Redirect, matchPath } from 'react-router-dom';
import sidebarRoutes from '../../routes/sidebar';
import eeRoutes from '../../routes/ee';
import ldapRoutes from '../../routes/ldap';
import samlRoutes from '../../routes/saml';
import oidcRoutes from '../../routes/oidc';
import otherRoutes from '../../routes/other';
const SwitchRoutes = (props) => {
const { actions, state, store, ...rest } = props;
let variableLinks = [];
if (state.server.type === 'EE') {
eeRoutes.forEach(function (route) {
variableLinks.push(route);
});
}
if (
state.server.type === 'EE' &&
state.server.authentication_methods.indexOf('LDAP') !== -1
) {
ldapRoutes.forEach(function (route) {
variableLinks.push(route);
});
}
if (
state.server.type === 'EE' &&
state.server.authentication_methods.indexOf('SAML') !== -1
) {
samlRoutes.forEach(function (route) {
variableLinks.push(route);
});
}
if (
state.server.type === 'EE' &&
state.server.authentication_methods.indexOf('OIDC') !== -1
) {
oidcRoutes.forEach(function (route) {
variableLinks.push(route);
});
}
const routes = otherRoutes.concat(variableLinks, sidebarRoutes);
let match = null;
for (let i = 0; i < routes.length; i++) {
match = matchPath(props.location.pathname, routes[i].path);
if (match !== null) {
break;
}
}
return (
<Switch>
{routes.map((prop, key) => {
if (prop.redirect)
return (
<Redirect
from={prop.path}
to={prop.to}
key={key}
{...rest}
/>
);
return (
<Route
path={prop.path}
render={() => (
<prop.component
actions={actions}
state={state}
store={store}
match={match}
/>
)}
key={key}
{...rest}
/>
);
})}
</Switch>
);
};
export default SwitchRoutes;

View File

@ -1,80 +0,0 @@
import React from 'react';
import PropTypes from 'prop-types';
import { withStyles } from '@material-ui/core';
import { Switch, Route, Redirect, matchPath } from 'react-router-dom';
import sidebarRoutes from '../../routes/sidebar';
import ldapRoutes from '../../routes/ldap';
import samlRoutes from '../../routes/saml';
import oidcRoutes from '../../routes/oidc';
import otherRoutes from '../../routes/other';
import appStyle from '../../assets/jss/material-dashboard-react/appStyle';
class switchRoutes extends React.Component {
render() {
const { actions, state, store, ...rest } = this.props;
let variableLinks = [];
if (state.server.authentication_methods.indexOf('LDAP') !== -1) {
ldapRoutes.forEach(function(route) {
variableLinks.push(route);
});
}
if (state.server.authentication_methods.indexOf('SAML') !== -1) {
samlRoutes.forEach(function(route) {
variableLinks.push(route);
});
}
if (state.server.authentication_methods.indexOf('OIDC') !== -1) {
oidcRoutes.forEach(function(route) {
variableLinks.push(route);
});
}
const routes = otherRoutes.concat(variableLinks, sidebarRoutes);
let match = null;
for (let i = 0; i < routes.length; i++) {
match = matchPath(this.props.location.pathname, routes[i].path);
if (match !== null) {
break;
}
}
return (
<Switch>
{routes.map((prop, key) => {
if (prop.redirect)
return (
<Redirect
from={prop.path}
to={prop.to}
key={key}
{...rest}
/>
);
return (
<Route
path={prop.path}
render={() => (
<prop.component
actions={actions}
state={state}
store={store}
match={match}
/>
)}
key={key}
{...rest}
/>
);
})}
</Switch>
);
}
}
switchRoutes.propTypes = {
classes: PropTypes.object.isRequired
};
export default withStyles(appStyle)(switchRoutes);

View File

@ -20,7 +20,7 @@ const style = {
backgroundSize: 'cover',
display: 'flex',
'justify-content': 'center',
'align-items': 'center'
'align-items': 'center',
},
content: {
width: '100%',
@ -29,8 +29,8 @@ const style = {
content: '',
opacity: '.8',
position: 'absolute',
background: '#000'
}
background: '#000',
},
};
class Login extends React.Component {
@ -67,7 +67,7 @@ class Login extends React.Component {
Login.propTypes = {
store: PropTypes.object.isRequired,
classes: PropTypes.object.isRequired
classes: PropTypes.object.isRequired,
};
function mapStateToProps(state) {

15
src/routes/ee.js Normal file
View File

@ -0,0 +1,15 @@
import { Policy } from '@material-ui/icons';
import Policies from '../views/Policies/Index';
let routes = [
{
path: '/policies',
sidebarName: 'POLICIES',
navbarName: 'POLICIES',
icon: Policy,
component: Policies,
},
];
export default routes;

View File

@ -5,7 +5,7 @@ const indexRoutes = [
{ path: '/saml/token/:saml_token_id', component: Login },
{ path: '/oidc/token/:oidc_token_id', component: Login },
{ path: '/login', component: Login },
{ path: '/', component: Index }
{ path: '/', component: Index },
];
export default indexRoutes;

View File

@ -8,8 +8,8 @@ let routes = [
sidebarName: 'OIDC',
navbarName: 'OIDC',
icon: Business,
component: OIDC
}
component: OIDC,
},
];
export default routes;

View File

@ -2,9 +2,11 @@ import SecurityReportEdit from '../views/SecurityReport/Edit';
import UserEdit from '../views/User/Edit';
import GroupEdit from '../views/Group/Edit';
import GroupCreate from '../views/Group/Create';
import PolicyCreate from '../views/Policies/Create';
import PolicyEdit from '../views/Policies/Edit';
import UserCreate from '../views/User/Create';
import { Person, Group, Timeline } from '@material-ui/icons';
import { Person, Group, Policy, Timeline } from '@material-ui/icons';
let routes = [
{
@ -21,6 +23,13 @@ let routes = [
icon: Timeline,
component: SecurityReportEdit,
},
{
path: '/policy/:policy_id',
sidebarName: 'POLICY',
navbarName: 'POLICY',
icon: Policy,
component: PolicyEdit,
},
{
path: '/group/:group_id',
sidebarName: 'GROUP',
@ -28,6 +37,13 @@ let routes = [
icon: Group,
component: GroupEdit,
},
{
path: '/policies/create',
sidebarName: 'CREATE_POLICY',
navbarName: 'CREATE_POLICY',
icon: Policy,
component: PolicyCreate,
},
{
path: '/groups/create',
sidebarName: 'CREATE_GROUP',

View File

@ -1,6 +1,7 @@
import DashboardPage from '../views/Dashboard/Index';
//import UserProfile from '../views/UserProfile/UserProfile.jsx';
import Users from '../views/Users/Index';
import Policies from '../views/Policies/Index';
import SecurityReports from '../views/SecurityReports/Index';
// import TableList from '../views/TableList/TableList.jsx';
// import Typography from '../views/Typography/Typography.jsx';
@ -10,6 +11,7 @@ import SecurityReports from '../views/SecurityReports/Index';
import {
Dashboard,
Person,
Policy,
Timeline,
// ContentPaste,
// LibraryBooks,
@ -17,6 +19,7 @@ import {
// LocationOn,
// Notifications
} from '@material-ui/icons';
import store from '../services/store';
let routes = [
{

View File

@ -1037,6 +1037,251 @@ function admin_delete_session(token, session_secret_key, session_id) {
return call(method, endpoint, data, headers, session_secret_key);
}
/**
* GET: Returns a list of all policys (for administrators) or the policy details of a single policy
*
* @param {string} token authentication token of the user, returned by authentication_login(email, authkey)
* @param {string} session_secret_key The session secret key
* @param {uuid} [policy_id] (optional) The policy id
* @param {object} [params] (optional) Other search params
*
* @returns {Promise<AxiosResponse<any>>}
*/
function admin_policy(token, session_secret_key, policy_id, params) {
const endpoint = '/admin/policy/' + (!policy_id ? '' : policy_id + '/');
const method = 'GET';
const data = null;
const queryParams =
!params || Object.keys(params).length === 0
? ''
: '?' + new URLSearchParams(params).toString();
const headers = {
Authorization: 'Token ' + token,
};
return call(
method,
endpoint + queryParams,
data,
headers,
session_secret_key
);
}
/**
* POST: Creates a policy (for administrators)
* (EE Only)
*
* @param {string} token authentication token of the user, returned by authentication_login(email, authkey)
* @param {string} session_secret_key The session secret key
* @param {string} title The title of the policy to create
* @param {object} config The config of the policy to create
* @param {double} priority The priority of the policy to create
*
* @returns {Promise<AxiosResponse<any>>}
*/
function admin_create_policy(
token,
session_secret_key,
title,
config,
priority
) {
const endpoint = '/admin/policy/';
const method = 'POST';
const data = {
title: title,
config: config,
priority: priority,
};
const headers = {
Authorization: 'Token ' + token,
};
return call(method, endpoint, data, headers, session_secret_key);
}
/**
* POST: Creates a policy group mapping (for administrators)
* (EE Only)
*
* @param {string} token authentication token of the user, returned by authentication_login(email, authkey)
* @param {string} session_secret_key The session secret key
* @param {uuid} policy_id The id of the policy to create the group mapping
* @param {uuid} group_id The id of the group to create the group mapping
*
* @returns {Promise<AxiosResponse<any>>}
*/
function admin_policy_create_group_map(
token,
session_secret_key,
policy_id,
group_id
) {
const endpoint = '/admin/policy/group/map/';
const method = 'POST';
const data = {
policy_id: policy_id,
group_id: group_id,
};
const headers = {
Authorization: 'Token ' + token,
};
return call(method, endpoint, data, headers, session_secret_key);
}
/**
* DELETE: Deletes a policy group map (for administrators)
*
* @param {string} token authentication token of the user, returned by authentication_login(email, authkey)
* @param {string} session_secret_key The session secret key
* @param {uuid} policy_id The policy id of the group mapping to delete
* @param {uuid} group_id The group id of the group mapping to delete
*
* @returns {Promise<AxiosResponse<any>>}
*/
function admin_policy_delete_group_map(
token,
session_secret_key,
policy_id,
group_id
) {
const endpoint = '/admin/policy/group/map/';
const method = 'DELETE';
const data = {
policy_id: policy_id,
group_id: group_id,
};
const headers = {
'Content-Type': 'application/json',
Authorization: 'Token ' + token,
};
return call(method, endpoint, data, headers, session_secret_key);
}
/**
* POST: Creates a policy user mapping (for administrators)
* (EE Only)
*
* @param {string} token authentication token of the user, returned by authentication_login(email, authkey)
* @param {string} session_secret_key The session secret key
* @param {uuid} policy_id The id of the policy to create the user mapping
* @param {uuid} user_id The id of the user to create the user mapping
*
* @returns {Promise<AxiosResponse<any>>}
*/
function admin_policy_create_user_map(
token,
session_secret_key,
policy_id,
user_id
) {
const endpoint = '/admin/policy/user/map/';
const method = 'POST';
const data = {
policy_id: policy_id,
user_id: user_id,
};
const headers = {
Authorization: 'Token ' + token,
};
return call(method, endpoint, data, headers, session_secret_key);
}
/**
* DELETE: Deletes a policy user map (for administrators)
*
* @param {string} token authentication token of the user, returned by authentication_login(email, authkey)
* @param {string} session_secret_key The session secret key
* @param {uuid} policy_id The policy id of the user mapping to delete
* @param {uuid} user_id The user id of the user mapping to delete
*
* @returns {Promise<AxiosResponse<any>>}
*/
function admin_policy_delete_user_map(
token,
session_secret_key,
policy_id,
user_id
) {
const endpoint = '/admin/policy/user/map/';
const method = 'DELETE';
const data = {
policy_id: policy_id,
user_id: user_id,
};
const headers = {
'Content-Type': 'application/json',
Authorization: 'Token ' + token,
};
return call(method, endpoint, data, headers, session_secret_key);
}
/**
* PUT: Updates a policy (for administrators)
* (EE Only)
*
* @param {string} token authentication token of the user, returned by authentication_login(email, authkey)
* @param {string} session_secret_key The session secret key
* @param {string} policy_id The id of the policy to update
* @param {string} title The title of the policy to update
* @param {object} config The config of the policy to update
* @param {double} priority The priority of the policy to update
*
* @returns {Promise<AxiosResponse<any>>}
*/
function admin_update_policy(
token,
session_secret_key,
policy_id,
title,
config,
priority
) {
const endpoint = '/admin/policy/';
const method = 'PUT';
const data = {
policy_id: policy_id,
title: title,
config: config,
priority: priority,
};
const headers = {
Authorization: 'Token ' + token,
};
return call(method, endpoint, data, headers, session_secret_key);
}
/**
* DELETE: Deletes a policy (for administrators)
*
* @param {string} token authentication token of the user, returned by authentication_login(email, authkey)
* @param {string} session_secret_key The session secret key
* @param {uuid} policy_id The policy id of the group to delete
*
* @returns {Promise<AxiosResponse<any>>}
*/
function admin_delete_policy(token, session_secret_key, policy_id) {
const endpoint = '/admin/policy/';
const method = 'DELETE';
const data = {
policy_id: policy_id,
};
const headers = {
'Content-Type': 'application/json',
Authorization: 'Token ' + token,
};
return call(method, endpoint, data, headers, session_secret_key);
}
/**
* POST: Creates a managed group (for administrators)
* (EE Only)
@ -3233,6 +3478,14 @@ const service = {
admin_create_user,
admin_delete_user,
admin_delete_session,
admin_policy,
admin_policy_create_group_map,
admin_policy_delete_group_map,
admin_policy_create_user_map,
admin_policy_delete_user_map,
admin_create_policy,
admin_update_policy,
admin_delete_policy,
admin_create_group,
admin_delete_group,
admin_update_membership,

View File

@ -0,0 +1,115 @@
import React, { useState } from 'react';
import { useTranslation } from 'react-i18next';
import { Redirect } from 'react-router-dom';
import { Grid } from '@material-ui/core';
import {
RegularCard,
CustomInput,
GridItem,
Button,
SnackbarContent,
} from '../../components/index';
import psono_server from '../../services/api-server';
import store from '../../services/store';
const PolicyCreate = (props) => {
const { t } = useTranslation();
const [errorsDict, setErrorsDict] = useState({});
const [redirectTo, setRedirectTo] = useState('');
const [title, setTitle] = useState('');
const createPolicy = () => {
setErrorsDict({});
const onSuccess = (data) => {
setRedirectTo('/policy/' + data.data.policy_id);
};
const onError = (data) => {
setErrorsDict(data.data);
};
psono_server
.admin_create_policy(
store.getState().user.token,
store.getState().user.session_secret_key,
title,
{},
0
)
.then(onSuccess, onError);
};
if (redirectTo) {
return <Redirect to={redirectTo} />;
}
return (
<div>
<Grid container>
<GridItem xs={12} sm={12} md={12}>
<RegularCard
cardTitle={t('CREATE_POLICY')}
cardSubtitle={t('ADD_NECESSARY_DETAILS_BELOW')}
content={
<div>
<Grid container>
<GridItem xs={12} sm={12} md={12}>
<CustomInput
labelText={t('TITLE')}
id="title"
helperText={
errorsDict.hasOwnProperty(
'title'
)
? t(errorsDict['title'])
: ''
}
formControlProps={{
fullWidth: true,
}}
inputProps={{
value: title,
onChange: (event) =>
setTitle(
event.target.value
),
}}
error={errorsDict.hasOwnProperty(
'title'
)}
/>
</GridItem>
</Grid>
</div>
}
footer={
<div>
<Button
color="primary"
onClick={createPolicy}
disabled={!title}
>
{t('CREATE_POLICY')}
</Button>
{errorsDict.hasOwnProperty(
'non_field_errors'
) ? (
<SnackbarContent
message={t(
errorsDict['non_field_errors']
)}
color="danger"
/>
) : (
''
)}
</div>
}
/>
</GridItem>
</Grid>
</div>
);
};
export default PolicyCreate;

1007
src/views/Policies/Edit.jsx Normal file

File diff suppressed because it is too large Load Diff

View File

@ -0,0 +1,144 @@
import React, { useRef } from 'react';
import { withStyles, Grid } from '@material-ui/core';
import { useTranslation, withTranslation } from 'react-i18next';
import { compose } from 'redux';
import moment from 'moment';
import PropTypes from 'prop-types';
import { Redirect } from 'react-router-dom';
import { CustomMaterialTable, GridItem, RegularCard } from '../../components';
import dashboardStyle from '../../assets/jss/material-dashboard-react/dashboardStyle';
import psono_server from '../../services/api-server';
import store from '../../services/store';
import { Edit } from '@material-ui/icons';
import Add from '@material-ui/icons/Add';
import Delete from '@material-ui/icons/Delete';
const Policies = () => {
const { t } = useTranslation();
const policyTableRef = useRef(null);
const [redirectTo, setRedirectTo] = React.useState('');
const onDeletePolicies = (selected_policy) => {
psono_server
.admin_delete_policy(
store.getState().user.token,
store.getState().user.session_secret_key,
selected_policy.id
)
.then(() => {
policyTableRef.current &&
policyTableRef.current.onQueryChange();
});
};
const onEditPolicy = (selected_policy) => {
setRedirectTo('/policy/' + selected_policy.id);
};
const onCreatePolicy = () => {
setRedirectTo('/policies/create/');
};
const loadPolicies = (query) => {
const params = {
page_size: query.pageSize,
search: query.search,
page: query.page,
};
if (query.orderBy) {
if (query.orderDirection === 'asc') {
params['ordering'] = query.orderBy.field;
} else {
params['ordering'] = '-' + query.orderBy.field;
}
}
return psono_server
.admin_policy(
store.getState().user.token,
store.getState().user.session_secret_key,
undefined,
params
)
.then((response) => {
const { policies } = response.data;
policies.forEach((u) => {
u.create_date = moment(u.create_date).format(
'YYYY-MM-DD HH:mm:ss'
);
});
return {
data: policies,
page: query.page,
pageSize: query.pageSize,
totalCount: response.data.count,
};
});
};
if (redirectTo) {
return <Redirect to={redirectTo} />;
}
return (
<div>
<Grid container>
<GridItem xs={12} sm={12} md={12}>
<RegularCard
headerColor="orange"
cardTitle={t('POLICIES')}
cardSubtitle={t('POLICY_LIST_INFO')}
content={
<CustomMaterialTable
tableRef={policyTableRef}
columns={[
{
field: 'priority',
title: t('PRIORITY'),
},
{
field: 'title',
title: t('TITLE'),
},
{
field: 'create_date',
title: t('CREATED_AT'),
},
]}
data={loadPolicies}
title={''}
actions={[
{
tooltip: t('EDIT'),
icon: Edit,
onClick: (evt, selectedPolicy) =>
onEditPolicy(selectedPolicy),
},
{
tooltip: t('DELETE'),
icon: Delete,
onClick: (evt, selectedPolicy) =>
onDeletePolicies(selectedPolicy),
},
{
tooltip: t('CREATE_POLICY'),
isFreeAction: true,
icon: Add,
onClick: (evt) => onCreatePolicy(),
},
]}
/>
}
/>
</GridItem>
</Grid>
</div>
);
};
Policies.propTypes = {
classes: PropTypes.object.isRequired,
};
export default compose(withTranslation(), withStyles(dashboardStyle))(Policies);