Skip to content

Bugfixes and improvements #2847

New issue

Have a question about this project? Sign up for a free GitHub account to open an issue and contact its maintainers and the community.

By clicking “Sign up for GitHub”, you agree to our terms of service and privacy statement. We’ll occasionally send you account related emails.

Already on GitHub? Sign in to your account

Merged
merged 6 commits into from
Aug 21, 2024
Merged
Show file tree
Hide file tree
Changes from all commits
Commits
File filter

Filter by extension

Filter by extension

Conversations
Failed to load comments.
Loading
Jump to
Jump to file
Failed to load files.
Loading
Diff view
Diff view
10 changes: 6 additions & 4 deletions src/components/tables/CippDatatable.jsx
Original file line number Diff line number Diff line change
Expand Up @@ -14,16 +14,18 @@ export default function CippDatatable({ path, params, ...rest }) {
refetch,
} = useListDatatableQuery({ path, params: { $filter: graphFilter, ...params } })

let anonimized = false // Assuming default value is false
let anonymized = false // Assuming default value is false
const regex = new RegExp('^[A-Z0-9]+$')
const principalNameOrUPN =
data[0]?.userPrincipalName ??
data[0]?.UPN ??
data[0]?.Owner ??
data.Results?.[0]?.upn ??
data.Results?.[0]?.userPrincipalName
data.Results?.[0]?.userPrincipalName ??
data.Results?.[0]?.Owner

if (principalNameOrUPN && regex.test(principalNameOrUPN)) {
anonimized = true
anonymized = true
}

var defaultFilterText = ''
Expand All @@ -32,7 +34,7 @@ export default function CippDatatable({ path, params, ...rest }) {
}
return (
<>
{anonimized && (
{anonymized && (
<CCallout color="info">
This table might contain anonymized data. Please check this
<a
Expand Down
138 changes: 92 additions & 46 deletions src/components/utilities/CippAppPermissionBuilder.jsx
Original file line number Diff line number Diff line change
Expand Up @@ -34,14 +34,22 @@ import { Editor } from '@monaco-editor/react'
import { useSelector } from 'react-redux'
import { CippCallout } from '../layout'

const CippAppPermissionBuilder = ({ onSubmit, currentPermissions = {}, isSubmitting }) => {
const CippAppPermissionBuilder = ({
onSubmit,
currentPermissions = {},
isSubmitting,
colSize = 8,
removePermissionConfirm = true,
appDisplayName = 'CIPP-SAM',
}) => {
const [selectedApp, setSelectedApp] = useState([])
const [permissionsImported, setPermissionsImported] = useState(false)
const [newPermissions, setNewPermissions] = useState({})
const [importedManifest, setImportedManifest] = useState(null)
const [manifestVisible, setManifestVisible] = useState(false)
const currentTheme = useSelector((state) => state.app.currentTheme)
const [calloutMessage, setCalloutMessage] = useState(null)
const [initialPermissions, setInitialPermissions] = useState()

const {
data: servicePrincipals = [],
Expand All @@ -59,35 +67,49 @@ const CippAppPermissionBuilder = ({ onSubmit, currentPermissions = {}, isSubmitt
var servicePrincipal = selectedApp.find((sp) => sp?.appId === appId)
var newServicePrincipals = selectedApp.filter((sp) => sp?.appId !== appId)

ModalService.confirm({
title: 'Remove Service Principal',
body: `Are you sure you want to remove ${servicePrincipal.displayName}?`,
onConfirm: () => {
setSelectedApp(newServicePrincipals)
var updatedPermissions = JSON.parse(JSON.stringify(newPermissions))
delete updatedPermissions.Permissions[appId]
setNewPermissions(updatedPermissions)
},
})
if (removePermissionConfirm) {
ModalService.confirm({
title: 'Remove Service Principal',
body: `Are you sure you want to remove ${servicePrincipal.displayName}?`,
onConfirm: () => {
setSelectedApp(newServicePrincipals)
var updatedPermissions = JSON.parse(JSON.stringify(newPermissions))
delete updatedPermissions.Permissions[appId]
setNewPermissions(updatedPermissions)
},
})
} else {
setSelectedApp(newServicePrincipals)
var updatedPermissions = JSON.parse(JSON.stringify(newPermissions))
delete updatedPermissions.Permissions[appId]
setNewPermissions(updatedPermissions)
}
}

const confirmReset = () => {
ModalService.confirm({
title: 'Reset to Default',
body: 'Are you sure you want to reset all permissions to default?',
onConfirm: () => {
setSelectedApp([])
setPermissionsImported(false)
setManifestVisible(false)
setCalloutMessage('Permissions reset to default.')
},
})
if (removePermissionConfirm) {
ModalService.confirm({
title: 'Reset to Default',
body: 'Are you sure you want to reset all permissions to default?',
onConfirm: () => {
setSelectedApp([])
setPermissionsImported(false)
setManifestVisible(false)
setCalloutMessage('Permissions reset to default.')
},
})
} else {
setSelectedApp([])
setPermissionsImported(false)
setManifestVisible(false)
setCalloutMessage('Permissions reset to default.')
}
}

const handleSubmit = (values) => {
if (onSubmit) {
var postBody = {
Permissions: newPermissions,
Permissions: newPermissions.Permissions,
}
onSubmit(postBody)
}
Expand Down Expand Up @@ -127,30 +149,43 @@ const CippAppPermissionBuilder = ({ onSubmit, currentPermissions = {}, isSubmitt
}

const removePermissionRow = (servicePrincipal, permissionType, permissionId, permissionValue) => {
// modal confirm
ModalService.confirm({
title: 'Remove Permission',
body: `Are you sure you want to remove the permission: ${permissionValue}?`,
onConfirm: () => {
var updatedPermissions = JSON.parse(JSON.stringify(newPermissions))
var currentPermission = updatedPermissions?.Permissions[servicePrincipal][permissionType]
var newPermission = []
if (currentPermission) {
currentPermission.map((perm) => {
if (perm.id !== permissionId) {
newPermission.push(perm)
}
})
}
updatedPermissions.Permissions[servicePrincipal][permissionType] = newPermission
setNewPermissions(updatedPermissions)
},
})
if (removePermissionConfirm) {
ModalService.confirm({
title: 'Remove Permission',
body: `Are you sure you want to remove the permission: ${permissionValue}?`,
onConfirm: () => {
var updatedPermissions = JSON.parse(JSON.stringify(newPermissions))
var currentPermission = updatedPermissions?.Permissions[servicePrincipal][permissionType]
var newPermission = []
if (currentPermission) {
currentPermission.map((perm) => {
if (perm.id !== permissionId) {
newPermission.push(perm)
}
})
}
updatedPermissions.Permissions[servicePrincipal][permissionType] = newPermission
setNewPermissions(updatedPermissions)
},
})
} else {
var updatedPermissions = JSON.parse(JSON.stringify(newPermissions))
var currentPermission = updatedPermissions?.Permissions[servicePrincipal][permissionType]
var newPermission = []
if (currentPermission) {
currentPermission.map((perm) => {
if (perm.id !== permissionId) {
newPermission.push(perm)
}
})
}
updatedPermissions.Permissions[servicePrincipal][permissionType] = newPermission
setNewPermissions(updatedPermissions)
}
}

const generateManifest = (appDisplayName = 'CIPP-SAM', prompt = false) => {
if (prompt) {
// modal input form for appDisplayName
const generateManifest = ({ appDisplayName = 'CIPP-SAM', prompt = false }) => {
if (prompt || appDisplayName === '') {
ModalService.prompt({
title: 'Generate Manifest',
body: 'Please enter the display name for the application.',
Expand Down Expand Up @@ -337,6 +372,11 @@ const CippAppPermissionBuilder = ({ onSubmit, currentPermissions = {}, isSubmitt
},
},
})
} else if (spSuccess & (currentPermissions !== initialPermissions)) {
setSelectedApp([])
setNewPermissions(currentPermissions)
setInitialPermissions(currentPermissions)
setPermissionsImported(false)
} else if (spSuccess && initialAppIds.length > 0 && permissionsImported == false) {
var newApps = []
initialAppIds?.map((appId) => {
Expand All @@ -350,17 +390,20 @@ const CippAppPermissionBuilder = ({ onSubmit, currentPermissions = {}, isSubmitt
})
setSelectedApp(newApps)
setNewPermissions(currentPermissions)
setInitialPermissions(currentPermissions)
setPermissionsImported(true)
}
}, [
currentPermissions,
initialPermissions,
permissionsImported,
spSuccess,
selectedApp,
servicePrincipals,
setSelectedApp,
setPermissionsImported,
setNewPermissions,
setInitialPermissions,
])

const ApiPermissionRow = ({ servicePrincipal = null }) => {
Expand Down Expand Up @@ -679,7 +722,7 @@ const CippAppPermissionBuilder = ({ onSubmit, currentPermissions = {}, isSubmitt
return (
<CForm onSubmit={handleSubmit}>
<CRow className="mb-3">
<CCol xl={8} md={12} className="mb-3">
<CCol xl={colSize} md={12} className="mb-3">
<CRow className="mb-3">
<CCol xl={8}>
{servicePrincipals?.Metadata?.Success && (
Expand Down Expand Up @@ -738,7 +781,7 @@ const CippAppPermissionBuilder = ({ onSubmit, currentPermissions = {}, isSubmitt
<CTooltip content="Download Manifest">
<CButton
onClick={() => {
generateManifest()
generateManifest({ appDisplayName: appDisplayName })
}}
className={`circular-button`}
title={'+'}
Expand Down Expand Up @@ -957,6 +1000,9 @@ CippAppPermissionBuilder.propTypes = {
onSubmit: PropTypes.func,
currentPermissions: PropTypes.object,
isSubmitting: PropTypes.bool,
colSize: PropTypes.number,
removePermissionConfirm: PropTypes.bool,
appDisplayName: PropTypes.string,
}

export default CippAppPermissionBuilder
140 changes: 140 additions & 0 deletions src/views/cipp/AppApprovalTemplates.jsx
Original file line number Diff line number Diff line change
@@ -0,0 +1,140 @@
import React from 'react'
import {
CCol,
CRow,
CCallout,
CSpinner,
CButton,
CFormInput,
CFormLabel,
CTooltip,
} from '@coreui/react'
import { Field, Form, FormSpy } from 'react-final-form'
import { FontAwesomeIcon } from '@fortawesome/react-fontawesome'
import { faExclamationTriangle } from '@fortawesome/free-solid-svg-icons'
import { CippPageList, CippWizard } from 'src/components/layout'
import { cellDateFormatter, CippTable, WizardTableField } from 'src/components/tables'
import PropTypes from 'prop-types'
import {
Condition,
RFFCFormCheck,
RFFCFormInput,
RFFCFormSwitch,
RFFSelectSearch,
} from 'src/components/forms'
import { useLazyGenericPostRequestQuery } from 'src/store/api/app'
import CippButtonCard from 'src/components/contentcards/CippButtonCard'
import { cellGenericFormatter } from 'src/components/tables/CellGenericFormat'
import { CippOffcanvas } from 'src/components/utilities'
import CippAppPermissionBuilder from 'src/components/utilities/CippAppPermissionBuilder'

const AppApprovalTemplates = () => {
const [editorVisible, setEditorVisible] = React.useState(false)
const [selectedTemplate, setSelectedTemplate] = React.useState(null)
const templateNameRef = React.useRef(null)
const [genericPostRequest, postResults] = useLazyGenericPostRequestQuery()

const onSubmit = (values) => {
var body = {
TemplateName: templateNameRef.current.value,
Permissions: values.Permissions,
}
if (selectedTemplate?.TemplateId) {
body.TemplateId = selectedTemplate.TemplateId
}

console.log(body)
genericPostRequest({
path: '/api/ExecAppPermissionTemplate?Action=Save',
values: body,
}).then(() => {})
}
const titleButton = (
<CButton
onClick={() => {
setSelectedTemplate({})
templateNameRef.current.value = ''
setEditorVisible(true)
}}
>
<FontAwesomeIcon icon="plus" /> Add Template
</CButton>
)
return (
<>
<CippPageList
capabilities={{ allTenants: true, helpContext: 'https://google.com' }}
title="App Approval Templates"
tenantSelector={false}
titleButton={titleButton}
datatable={{
tableProps: {
selectableRows: true,
},
path: '/api/ExecAppPermissionTemplate',
columns: [
{
name: 'Name',
selector: (row) => row['TemplateName'],
sortable: true,
exportSelector: 'TemplateName',
},
{
name: 'Updated By',
selector: (row) => row['UpdatedBy'],
sortable: true,
exportSelector: 'UpdatedBy',
},
{
name: 'Updated At',
selector: (row) => row['Timestamp'],
sortable: true,
exportSelector: 'Timestamp',
cell: cellDateFormatter({ format: 'short' }),
},
{
name: 'Actions',
cell: (row) => (
<CTooltip content="Edit Template">
<CButton
size="sm"
variant="ghost"
onClick={() => {
setSelectedTemplate(row)
templateNameRef.current.value = row.TemplateName
setEditorVisible(true)
}}
>
<FontAwesomeIcon icon="edit" size="sm" />
</CButton>
</CTooltip>
),
},
],
reportName: 'AppApprovalTemplates',
}}
/>
<CippOffcanvas
title="Manage Template"
addedClass="offcanvas-large"
visible={editorVisible}
placement="end"
hideFunction={() => setEditorVisible(false)}
>
<CFormLabel>Template Name</CFormLabel>
<CFormInput name="TemplateName" className="mb-3" ref={templateNameRef} />
<CFormLabel>Permissions</CFormLabel>
<CippAppPermissionBuilder
colSize={12}
currentPermissions={selectedTemplate}
onSubmit={onSubmit}
isSubmitting={false}
removePermissionConfirm={false}
appDisplayName={templateNameRef.current?.value}
/>
</CippOffcanvas>
</>
)
}

export default AppApprovalTemplates
Loading
Loading