-
Larbi Gharib authored
Change-Id: I818f87efd508a3240d2a4b2cac8afb4d2faa3603
Larbi Gharib authoredChange-Id: I818f87efd508a3240d2a4b2cac8afb4d2faa3603
Code owners
Assign users and groups as approvers for specific file changes. Learn more.
EditBlueprintPermissions.js 18.78 KiB
import React from "react";
import { Link, useHistory } from "react-router-dom";
// @material-ui/core components
import { makeStyles } from "@material-ui/core/styles";
import Checkbox from "@material-ui/core/Checkbox";
import classnames from "classnames";
// core components
import Grid from "@material-ui/core/Grid";
import GridItem from "components/Grid/GridItem.js";
import GridContainer from "components/Grid/GridContainer.js";
import Card from "components/Card/Card.js";
import CardHeader from "components/Card/CardHeader.js";
import CardIcon from "components/Card/CardIcon.js";
import CardBody from "components/Card/CardBody.js";
import FormGroup from "@material-ui/core/FormGroup";
import FormControlLabel from "@material-ui/core/FormControlLabel";
import Button from "components/CustomButtons/Button.js";
import AddCircleOutlineIcon from '@material-ui/icons/AddCircleOutline';
import Avatar from "@material-ui/core/Avatar";
import Table from "@material-ui/core/Table";
import TableHead from '@material-ui/core/TableHead';
import TableRow from "@material-ui/core/TableRow";
import TableBody from "@material-ui/core/TableBody";
import TableCell from "@material-ui/core/TableCell";
import Snackbar from "@material-ui/core/Snackbar";
import { hexToRgb, blackColor } from "assets/jss/material-dashboard-react.js";
import PriorityHighOutlinedIcon from "@material-ui/icons/PriorityHighOutlined";
import noProfilePicture from "assets/img/faces/no-profile-picture.png";
import axios from "axios";
import configApiCall from "../../api";
import {
api_path_blueprints,
api_path_get_user_directory_search,
api_path_get_ns_name_from_addr,
api_path_get_user_profile
} from "../../globalUrls";
import TemporaryDrawer from "components/Drawer/Drawer"
import dashboardStyle from "assets/jss/material-dashboard-react/views/dashboardStyle.js";
import MuiAlert from "@material-ui/lab/Alert";
import i18next from "i18next";
import auth from "auth.js";
const styles = (theme) => ({
...dashboardStyle,
root: {
flexGrow: 1,
},
cardCategoryWhite: {
color: "rgba(255,255,255,.62)",
margin: "0",
fontSize: "14px",
marginTop: "0",
marginBottom: "0",
},
cardTitleWhite: {
color: "#FFFFFF",
marginTop: "0px",
minHeight: "auto",
fontWeight: "300",
fontFamily: "'Roboto', 'Helvetica', 'Arial', sans-serif",
marginBottom: "3px",
textDecoration: "none",
},
input: {
display: "none",
},
profileAsBackground: {
backgroundSize: "100% 100%",
width: "80px",
height: "80px",
},
centerIconMiddle: {
position: "relative",
top: "20px",
left: "15px",
},
editProfilePicture: {
borderRadius: "50%",
width: "200px",
height: "200px",
boxShadow:
"0 6px 8px -12px rgba(" +
hexToRgb(blackColor) +
", 0.56), 0 4px 25px 0px rgba(" +
hexToRgb(blackColor) +
", 0.12), 0 8px 10px -5px rgba(" +
hexToRgb(blackColor) +
", 0.2)",
},
dialogPaper: {
minHeight: "60vh",
maxHeight: "60vh",
minWidth: "80vh",
maxWidth: "80vh",
},
});
const useStyles = makeStyles(styles);
function Alert(props) {
return <MuiAlert elevation={6} variant="filled" {...props} />;
}
export default function EditBlueprintPermissions(props) {
const classes = useStyles();
const history = useHistory();
const tableCellClasses = classnames(classes.tableCell);
const [openDrawer, setOpenDrawer] = React.useState(false);
const [users, setUsers] = React.useState([]);
const [blueprintModerators, setBlueprintModerators] = React.useState([]);
const [videoEnabled, setVideoEnabled] = React.useState(true);
const [publicInCalls, setPublicInCalls] = React.useState(true);
const [autoAnswer, setAutoAnswer] = React.useState(false);
const [peerDiscovery, setPeerDiscovery] = React.useState(true);
const [rendezVous, setRendezVous] = React.useState(false);
const [defaultModerators, setDefaultModerators] = React.useState("");
const [upnpEnabled, setUpnpEnabled] = React.useState(true);
const [turnEnabled, setTurnEnabled] = React.useState(true);
const [turnServer, setTurnServer] = React.useState("turn.jami.net");
const [turnServerUserName, setTurnServerUserName] = React.useState("ring");
const [turnServerPassword, setTurnServerPassword] = React.useState("ring");
const [proxyEnabled, setProxyEnabled] = React.useState(false);
const [proxyServer, setProxyServer] = React.useState("dhtproxy.jami.net");
const [dhtProxyListUrl, setDhtProxyListUrl] = React.useState("");
const [open, setOpen] = React.useState(false);
const [message, setMessage] = React.useState(false);
const [severity, setSeverity] = React.useState("success");
const searchUsers = (value) => {
axios(
configApiCall(
api_path_get_user_directory_search,
"GET",
{ queryString: value ? value : "*", page: "1" },
null
)
)
.then((response) => {
let profiles = [];
const profilesResults = response.data.profiles;
profilesResults.forEach((profile) =>{
let existingUser = false;
users.forEach((user)=>{
if(profile.username === user.username) existingUser = true;
})
if(!existingUser) profiles.push(profile);
})
setUsers(profiles);
})
.catch((error) => {
console.log(error);
setUsers([]);
if (error.response.status === 401) {
auth.authenticated = false;
history.push("/");
}
});
};
React.useEffect(() => {
searchUsers();
axios(
configApiCall(
api_path_blueprints + "?name=" + props.blueprintName,
"GET",
null,
null
)
)
.then((response) => {
let policyData = JSON.parse(response.data.policyData);
setVideoEnabled(policyData["videoEnabled"]);
setPublicInCalls(policyData["publicInCalls"]);
setAutoAnswer(policyData["autoAnswer"]);
setPeerDiscovery(policyData["peerDiscovery"]);
setRendezVous(policyData["rendezVous"]);
setDefaultModerators(policyData["defaultModerators"]);
setUpnpEnabled(policyData["upnpEnabled"]);
setTurnEnabled(policyData["turnEnabled"]);
setTurnServer(policyData["turnServer"]);
setTurnServerUserName(policyData["turnServerUserName"]);
setTurnServerPassword(policyData["turnServerPassword"]);
setProxyEnabled(policyData["proxyEnabled"]);
setProxyServer(policyData["proxyServer"]);
setDhtProxyListUrl(policyData["dhtProxyListUrl"]);
policyData["defaultModerators"].split("/").forEach((id) => {
if(id !== "undefined" && id !== ""){
axios(configApiCall(api_path_get_ns_name_from_addr + id), null, null).then((usernameResponse) => {
let username = usernameResponse.data.name;
axios(configApiCall(api_path_get_user_profile + username), null, null).then((userProfileResponse) => {
let userProfiles = blueprintModerators;
userProfileResponse.data["id"] = id;
userProfiles.push(userProfileResponse.data)
setBlueprintModerators(userProfiles);
// This state update is added to refresh the list of moderators
setOpenDrawer(true);
setOpenDrawer(false);
});
});
}
})
})
.catch((error) => {
console.log(
"Error fetching blueprint permissions : " +
props.blueprintName +
" " +
error
);
});
}, [props.blueprintName]);
const handleUpdatePermissions = (field, value) => {
let data = {
videoEnabled: videoEnabled,
publicInCalls: publicInCalls,
autoAnswer: autoAnswer,
peerDiscovery: peerDiscovery,
accountDiscovery: peerDiscovery,
accountPublish: peerDiscovery,
rendezVous: rendezVous,
defaultModerators: defaultModerators,
upnpEnabled: upnpEnabled,
turnEnabled: turnEnabled,
turnServer: turnServer,
turnServerUserName: turnServerUserName,
turnServerPassword: turnServerPassword,
proxyEnabled: proxyEnabled,
proxyServer: proxyServer,
dhtProxyListUrl: dhtProxyListUrl,
};
if (field === "peerDiscovery") {
data.peerDiscovery = value;
data.accountDiscovery = value;
data.accountPublish = value;
} else {
data[field] = value;
}
if (turnEnabled === undefined) {
delete data.turnEnabled;
delete data.turnServer;
delete data.turnServerUserName;
delete data.turnServerPassword;
}
if (proxyEnabled === undefined) {
delete data.proxyEnabled;
delete data.proxyServer;
delete data.dhtProxyListUrl;
}
axios(
configApiCall(
api_path_blueprints + "?name=" + props.blueprintName,
"PUT",
data,
null
)
)
.then((response) => {
setOpen(false);
setSeverity("success");
setOpen(true);
setMessage(i18next.t("updated_blueprint_permissions_successfully", "Blueprint permissions successfully updated."));
})
.catch((error) => {
setOpen(false);
setSeverity("error");
setOpen(true);
setMessage(i18next.t("error_updating_blueprint_permissions", "Error occurred while updating blueprint permissions.") + error + "!");
});
};
const handleClose = () => {
setOpen(false);
};
const addModeratorToBlueprint = (user) => {
handleUpdatePermissions("defaultModerators", defaultModerators + user.id + "/");
setDefaultModerators(defaultModerators + user.id + "/");
let newBlueprintModerators = blueprintModerators;
newBlueprintModerators.push(user);
setBlueprintModerators(newBlueprintModerators);
}
const removeModeratorFromBlueprint = (user) => {
let newDefaultModerators = defaultModerators.replace( user.id + "/", "")
handleUpdatePermissions("defaultModerators", newDefaultModerators);
setDefaultModerators(newDefaultModerators);
let newBlueprintModerators = blueprintModerators;
newBlueprintModerators.splice(newBlueprintModerators.indexOf(user), 1);
setBlueprintModerators(newBlueprintModerators);
}
return (
<div>
<Snackbar
anchorOrigin={{ vertical: "bottom", horizontal: "right" }}
open={open}
onClose={handleClose}
message={message}
key={"bottomright"}
>
<Alert onClose={handleClose} severity={severity}>
{message}
</Alert>
</Snackbar>
<TemporaryDrawer
openDrawer={openDrawer}
setOpenDrawer={setOpenDrawer}
direction="right"
placeholder={i18next.t("add_moderator_to_blueprint", "Add moderator to blueprint ...")}
searchTargets={searchUsers}
targets={users}
existingTargets={blueprintModerators}
addElementToTarget={addModeratorToBlueprint}
type="user"
/>
<GridContainer>
<GridItem xs={12} sm={12} md={6}>
<Card profile>
<CardHeader color="info" stats icon>
<CardIcon color="info">
<PriorityHighOutlinedIcon />
</CardIcon>
<p className={classes.cardCategory}>{i18next.t("permissions", "Permissions")}</p>
<h3 className={classes.cardTitle}>{props.blueprintName}</h3>
</CardHeader>
<CardBody profile>
<div className={classes.root}>
<Grid container spacing={5}>
<Grid item xs={12} sm={12} md={12}>
<FormGroup row>
<FormControlLabel
control={
<Checkbox
checked={videoEnabled}
color="primary"
onChange={(e) => {
setVideoEnabled(e.target.checked);
handleUpdatePermissions(
"videoEnabled",
e.target.checked
);
}}
name="videoEnabled"
/>
}
label={i18next.t("allow_video_calls", "Allow video calls")}
/>
</FormGroup>
<FormGroup row>
<FormControlLabel
control={
<Checkbox
checked={publicInCalls}
color="primary"
onChange={(e) => {
setPublicInCalls(e.target.checked);
handleUpdatePermissions(
"publicInCalls",
e.target.checked
);
}}
name="publicInCalls"
/>
}
label={i18next.t("allow_incoming_calls_from_unknown_contacts", "Allow incoming calls from unknown contacts")}
/>
</FormGroup>
<FormGroup row>
<FormControlLabel
control={
<Checkbox
checked={autoAnswer}
color="primary"
onChange={(e) => {
setAutoAnswer(e.target.checked);
handleUpdatePermissions(
"autoAnswer",
e.target.checked
);
}}
name="autoAnswer"
/>
}
label={i18next.t("auto_answer_calss", "Auto answer calls")}
/>
</FormGroup>
<FormGroup row>
<FormControlLabel
control={
<Checkbox
checked={peerDiscovery}
color="primary"
onChange={(e) => {
setPeerDiscovery(e.target.checked);
handleUpdatePermissions(
"peerDiscovery",
e.target.checked
);
}}
name="peerDiscovery"
/>
}
label={i18next.t("allow_use_of_jami_in_local_lan", "Allow Jami usage on the local LAN")}
/>
</FormGroup>
<FormGroup row>
<FormControlLabel
control={
<Checkbox
checked={rendezVous}
color="primary"
onChange={(e) => {
setRendezVous(e.target.checked);
handleUpdatePermissions(
"rendezVous",
e.target.checked
);
}}
name="rendezVous"
/>
}
label={i18next.t("convert_your_account_into_a_rendezvous_point", "Activate this account into rendezvous mode")}
/>
</FormGroup>
</Grid>
</Grid>
</div>
</CardBody>
</Card>
</GridItem>
<GridItem xs={12} sm={12} md={12}>
<Button color="primary" onClick={() => {setOpenDrawer(true)}}><AddCircleOutlineIcon /> {i18next.t("add_moderator_to", "Add moderator to")} {props.blueprintName}</Button>
<Table className={classes.table}>
<TableHead>
<TableRow>
<TableCell align="left"></TableCell>
<TableCell align="left">{i18next.t("username", "Username")}</TableCell>
<TableCell align="left">{i18next.t("first_name", "First name")}</TableCell>
<TableCell align="left">{i18next.t("last_name", "Last name")}</TableCell>
<TableCell align="right">{i18next.t("action", "Action")}</TableCell>
</TableRow>
</TableHead>
<TableBody>
{blueprintModerators.map(user =>
<TableRow key={user.username} className={classes.tableRow}>
<TableCell className={tableCellClasses}>
<Link to={`/user/${user.username}`}>
<Avatar
style={{ marginRight: "10px" }}
alt={user.username}
src={
user.profilePicture
? "data:image/png;base64, " + user.profilePicture
: noProfilePicture
}
/>
</Link>
</TableCell>
<TableCell className={tableCellClasses}>
<Link to={`/user/${user.username}`}>{user.username}</Link>
</TableCell>
<TableCell className={tableCellClasses}>
<Link to={`/user/${user.username}`}>{user.firstName}</Link>
</TableCell>
<TableCell className={tableCellClasses}>
<Link to={`/user/${user.username}`}>{user.lastName}</Link>
</TableCell>
<TableCell align="right" className={classes.tableActions}>
<Button color="primary" onClick={() => removeModeratorFromBlueprint(user)}>{i18next.t("remove_moderator", "Remove moderator")}</Button>
</TableCell>
</TableRow>
)}
</TableBody>
</Table>
</GridItem>
</GridContainer>
</div>
);
}