From 623a365030d069ed94f5277b3699c6ef43da267c Mon Sep 17 00:00:00 2001 From: frikky Date: Mon, 22 Nov 2021 23:30:54 +0100 Subject: [PATCH] Added suborg management for users --- backend/go-app/go.mod | 2 +- backend/go-app/main.go | 2 +- frontend/src/views/Admin.jsx | 129 ++++++++++++++++++++++++++-- frontend/src/views/SettingsPage.jsx | 2 + frontend/src/views/Workflows.jsx | 2 +- 5 files changed, 127 insertions(+), 10 deletions(-) diff --git a/backend/go-app/go.mod b/backend/go-app/go.mod index 5395b0f1..b8d583fa 100644 --- a/backend/go-app/go.mod +++ b/backend/go-app/go.mod @@ -2,7 +2,7 @@ module main go 1.15 -//replace github.com/shuffle/shuffle-shared => ../../../../git/shuffle-shared +replace github.com/shuffle/shuffle-shared => ../../../../git/shuffle-shared //replace github.com/frikky/kin-openapi => ../../../../git/kin-openapi //replace github.com/frikky/go-elasticsearch => ../../../../git/go-elasticsearch diff --git a/backend/go-app/main.go b/backend/go-app/main.go index 29839575..d76fbb96 100644 --- a/backend/go-app/main.go +++ b/backend/go-app/main.go @@ -3056,7 +3056,7 @@ func buildSwaggerApp(resp http.ResponseWriter, body []byte, user shuffle.User) { if test.Editing && len(user.Id) > 0 { // Quick verification test ctx := context.Background() - app, err := shuffle.GetApp(ctx, test.Id, user) + app, err := shuffle.GetApp(ctx, test.Id, user, false) if err != nil { log.Printf("[WARNING] Error getting app when editing: %s", app.Name) resp.WriteHeader(401) diff --git a/frontend/src/views/Admin.jsx b/frontend/src/views/Admin.jsx index 2c8dc90a..ca59cc48 100644 --- a/frontend/src/views/Admin.jsx +++ b/frontend/src/views/Admin.jsx @@ -8,6 +8,8 @@ import { FormControl, InputLabel, Paper, + OutlinedInput, + Checkbox, Card, Tooltip, FormControlLabel, @@ -70,6 +72,19 @@ const useStyles = makeStyles({ }, }); +const ITEM_HEIGHT = 48; +const ITEM_PADDING_TOP = 8; +const MenuProps = { + PaperProps: { + style: { + maxHeight: ITEM_HEIGHT * 4.5 + ITEM_PADDING_TOP, + width: 500, + }, + }, + getContentAnchorEl: () => null, +} + + const Admin = (props) => { const { globalUrl, userdata } = props; @@ -88,6 +103,7 @@ const Admin = (props) => { const [loading, setLoading] = React.useState(false); const [selectedOrganization, setSelectedOrganization] = React.useState({}); + //console.log("Selected: ", selectedOrganization) const [organizationFeatures, setOrganizationFeatures] = React.useState({}); const [loginInfo, setLoginInfo] = React.useState(""); const [curTab, setCurTab] = React.useState(0); @@ -95,6 +111,7 @@ const Admin = (props) => { const [organizations, setOrganizations] = React.useState([]); const [orgSyncResponse, setOrgSyncResponse] = React.useState(""); const [userSettings, setUserSettings] = React.useState({}); + const [matchingOrganizations, setMatchingOrganizations] = React.useState([]); const [environments, setEnvironments] = React.useState([]); const [authentication, setAuthentication] = React.useState([]); @@ -1411,7 +1428,10 @@ const Admin = (props) => { alert.error("Failed setting user: " + responseJson.reason); } else { alert.success("Set the user field " + field + " to " + value); - setSelectedUserModalOpen(false); + + if (field !== "suborgs") { + setSelectedUserModalOpen(false); + } } }) .catch((error) => { @@ -1557,11 +1577,58 @@ const Admin = (props) => { ) : null; + const handleOrgEditChange = (event) => { + if (userdata.id === selectedUser.id) { + alert.info("Can't remove orgs from yourself") + return + } + + setMatchingOrganizations(event.target.value) + // Workaround for empty orgs + if (event.target.value.length === 0) { + event.target.value.push("REMOVE") + } + + setUser(selectedUser.id, "suborgs", event.target.value) + } + + const userOrgEdit = selectedUser.id !== undefined && selectedUser.orgs !== undefined && selectedUser.orgs !== null && selectedOrganization.child_orgs !== undefined && selectedOrganization.child_orgs !== null && selectedOrganization.child_orgs.length > 0 ? + + Accessible Sub-Organizations ({selectedUser.orgs? selectedUser.orgs.length-1 : 0}) + + + : null + const editUserModal = ( { setSelectedUserModalOpen(false); + setImage2FA(""); + setSecret2FA(""); }} PaperProps={{ style: { @@ -1620,6 +1687,7 @@ const Admin = (props) => { )} + {isCloud ? null : (
{
)} + + {userOrgEdit} { backgroundColor: theme.palette.inputColor, }} /> -
+
- {show2faSetup && isCloud ? ( + {show2faSetup ? (
{
); + + + const usersView = curTab === 1 ? (
@@ -2651,6 +2724,12 @@ const Admin = (props) => { primary="MFA" style={{ minWidth: 100, maxWidth: 100 }} /> + {selectedOrganization.child_orgs !== undefined && selectedOrganization.child_orgs !== null && selectedOrganization.child_orgs.length > 0 ? + + : null} { } style={{ minWidth: 100, maxWidth: 100 }} /> - + {selectedOrganization.child_orgs !== undefined && selectedOrganization.child_orgs !== null && selectedOrganization.child_orgs.length > 0 ? + + : null} + { setSelectedUserModalOpen(true); setSelectedUser(data); + + // Find matching orgs between current org and current user's access to those orgs + if (userdata.orgs !== undefined && userdata.orgs !== null && userdata.orgs.length > 0 && selectedOrganization.child_orgs !== undefined && selectedOrganization.child_orgs !== null && selectedOrganization.child_orgs.length > 0) { + console.log("In here?") + var active = [] + for (var key in userdata.orgs) { + console.log("ORG: ", userdata.orgs[key]) + const found = selectedOrganization.child_orgs.find(item => item.id === userdata.orgs[key].id) + if (found !== null && found !== undefined) { + + if (data.orgs === undefined || data.orgs === null) { + continue + } + + const subfound = data.orgs.find(item => item === found.id) + if (subfound !== null && subfound !== undefined) { + active.push(subfound) + } + } + } + + setMatchingOrganizations(active) + } }} > @@ -2822,14 +2930,17 @@ const Admin = (props) => { ) : null; const run2FASetup = (data) => { - console.log("2fa: ", data); + console.log("2fa: ", data, show2faSetup); if (!show2faSetup) { get2faCode(data.id); } else { // Should remove? + setImage2FA(""); + setSecret2FA(""); } setShow2faSetup(!show2faSetup); + //setShow2faSetup(true); }; const uploadFiles = (files) => { @@ -3788,6 +3899,7 @@ const Admin = (props) => { style={{}} variant="contained" color="primary" + disabled={userdata.admin !== "true"} onClick={() => { setModalOpen(true); }} @@ -3959,7 +4071,7 @@ const Admin = (props) => { // primary={environment.Registered ? "true" : "false"} const iconStyle = { marginRight: 10 }; - const data = ( + const data = (
{ /> Users @@ -3994,12 +4107,14 @@ const Admin = (props) => { /> Files /> Schedules @@ -4007,7 +4122,7 @@ const Admin = (props) => { /> Environments diff --git a/frontend/src/views/SettingsPage.jsx b/frontend/src/views/SettingsPage.jsx index b09fc5cb..7c6a4a87 100644 --- a/frontend/src/views/SettingsPage.jsx +++ b/frontend/src/views/SettingsPage.jsx @@ -426,6 +426,7 @@ const Settings = (props) => { }} /> ); + const landingpageData = (
@@ -789,6 +790,7 @@ const Settings = (props) => {
{userdata !== undefined && userdata.eth_info !== undefined && + userdata.eth_info.account !== undefined && userdata.eth_info.account.length > 0 ? (
Network: TBD diff --git a/frontend/src/views/Workflows.jsx b/frontend/src/views/Workflows.jsx index fa34eceb..c1688af1 100644 --- a/frontend/src/views/Workflows.jsx +++ b/frontend/src/views/Workflows.jsx @@ -2578,7 +2578,7 @@ const Workflows = (props) => { } return ( - +