Skip to content

Commit

Permalink
Merge pull request #2758 from JohnDuprey/dev
Browse files Browse the repository at this point in the history
Message Viewer, CIPP-SAM Roles, and misc fixes
  • Loading branch information
JohnDuprey authored Aug 1, 2024
2 parents f79e0c8 + 06ba66b commit 33966f4
Show file tree
Hide file tree
Showing 5 changed files with 166 additions and 49 deletions.
38 changes: 2 additions & 36 deletions src/views/cipp/app-settings/SettingsSuperAdmin.jsx
Original file line number Diff line number Diff line change
Expand Up @@ -7,6 +7,7 @@ import { CippCallout } from 'src/components/layout/index.js'
import CippAccordionItem from 'src/components/contentcards/CippAccordionItem'
import SettingsCustomRoles from 'src/views/cipp/app-settings/components/SettingsCustomRoles'
import CippButtonCard from 'src/components/contentcards/CippButtonCard'
import SettingsSAMRoles from './components/SettingsSAMRoles'

export function SettingsSuperAdmin() {
const partnerConfig = useGenericGetRequestQuery({
Expand Down Expand Up @@ -65,46 +66,11 @@ export function SettingsSuperAdmin() {
</p>
</CCol>
</CRow>
<CRow>
<CCol sm={12} md={12} className="mb-3">
<p className="fw-lighter">Tenant Mode</p>
<Form
onSubmit={onSubmit}
initialValues={partnerConfig.data}
render={({ handleSubmit }) => (
<>
{partnerConfig.isFetching && <CSpinner size="sm" className="me-2" />}
<CForm id="submitForm" onSubmit={handleSubmit}>
<RFFCFormRadio
name="TenantMode"
label="Multi Tenant - GDAP Mode"
value="default"
/>
<RFFCFormRadio
name="TenantMode"
label="Multi Tenant - Add Partner Tenant"
value="PartnerTenantAvailable"
/>
<RFFCFormRadio
name="TenantMode"
label="Single Tenant - Own Tenant Mode"
value="owntenant"
/>
</CForm>
</>
)}
/>
{webhookCreateResult.isSuccess && (
<CippCallout color="info" dismissible>
{webhookCreateResult?.data?.results}
</CippCallout>
)}
</CCol>
</CRow>
</>
</>
</CippButtonCard>
<SettingsCustomRoles />
<SettingsSAMRoles />
</>
)
}
150 changes: 150 additions & 0 deletions src/views/cipp/app-settings/components/SettingsSAMRoles.jsx
Original file line number Diff line number Diff line change
@@ -0,0 +1,150 @@
import React, { useEffect, useRef, useState } from 'react'
import {
CButton,
CCallout,
CCol,
CForm,
CRow,
CAccordion,
CAccordionHeader,
CAccordionBody,
CAccordionItem,
} from '@coreui/react'
import { Field, Form, FormSpy } from 'react-final-form'
import { RFFCFormRadioList, RFFSelectSearch } from 'src/components/forms'
import { useGenericGetRequestQuery, useLazyGenericPostRequestQuery } from 'src/store/api/app'
import { FontAwesomeIcon } from '@fortawesome/react-fontawesome'
import { TenantSelectorMultiple, ModalService, CippOffcanvas } from 'src/components/utilities'
import PropTypes from 'prop-types'
import { OnChange } from 'react-final-form-listeners'
import { useListTenantsQuery } from 'src/store/api/tenants'
import { OffcanvasListSection } from 'src/components/utilities/CippListOffcanvas'
import CippButtonCard from 'src/components/contentcards/CippButtonCard'
import GDAPRoles from 'src/data/GDAPRoles'

const SettingsSAMRoles = () => {
const [genericPostRequest, postResults] = useLazyGenericPostRequestQuery()
const [selectedTenant, setSelectedTenant] = useState([])
const tenantSelectorRef = useRef()
const {
data: tenants = [],
isFetching: tenantsFetching,
isSuccess: tenantSuccess,
} = useListTenantsQuery({
showAllTenantSelector: true,
})

const {
data: cippSAMRoles = [],
isFetching: roleListFetching,
isSuccess: roleListSuccess,
refetch: refetchRoleList,
} = useGenericGetRequestQuery({
path: 'api/ExecSAMRoles',
})

const handleTenantChange = (e) => {
setSelectedTenant(e)
}

const handleSubmit = async (values) => {
//filter on only objects that are 'true'
genericPostRequest({
path: '/api/ExecSAMRoles?Action=Update',
values: {
Roles: values.Roles,
Tenants: selectedTenant.map((tenant) => tenant.value),
},
}).then(() => {
refetchRoleList()
})
}

useEffect(() => {
if (roleListSuccess && cippSAMRoles.Tenants.length > 0) {
var selectedTenants = []
tenants.map((tenant) => {
if (cippSAMRoles.Tenants.includes(tenant.customerId)) {
selectedTenants.push({ label: tenant.displayName, value: tenant.customerId })
}
})
tenantSelectorRef.current.setValue(selectedTenants)
}
}, [cippSAMRoles, roleListSuccess, tenantSuccess, tenantSelectorRef, tenants])

return (
<CippButtonCard title="CIPP-SAM Roles" titleType="big" isFetching={roleListFetching}>
<>
<p className="me-1">
Add your CIPP-SAM application Service Principal directly to Admin Roles in the tenant.
This is an advanced use case where you need access to additional Graph endpoints or
Exchange Cmdlets otherwise unavailable via Delegated permissions.
</p>
<p className="small">
<FontAwesomeIcon icon="triangle-exclamation" className="me-2" /> This functionality is in
beta and should be treated as such. Roles are added during the Update Permissions process
or a CPV refresh.
</p>

{roleListSuccess && (
<Form
onSubmit={handleSubmit}
initialValues={cippSAMRoles}
render={({ handleSubmit, submitting, values }) => {
return (
<CForm onSubmit={handleSubmit}>
<CRow className="mb-3">
<CCol xl={8} md={12} className="mb-3">
<div className="mb-3">
<RFFSelectSearch
name="Roles"
label="Admin Roles"
values={GDAPRoles.map((role) => ({
name: role.Name,
value: role.ObjectId,
}))}
multi={true}
refreshFunction={() => refetchRoleList()}
placeholder="Select admin roles"
/>
</div>
<div className="mb-3">
<h5>Selected Tenants</h5>
<TenantSelectorMultiple
ref={tenantSelectorRef}
values={selectedTenant}
AllTenants={true}
valueIsDomain={true}
onChange={(e) => handleTenantChange(e)}
/>
</div>
</CCol>
</CRow>
<CRow className="me-3">
{postResults.isSuccess && (
<CCallout color="success">{postResults.data.Results}</CCallout>
)}
<CRow className="mb-3">
<CCol xl={4} md={12}>
<CButton className="me-2" type="submit" disabled={submitting}>
<FontAwesomeIcon
icon={postResults.isFetching ? 'circle-notch' : 'save'}
spin={postResults.isFetching}
className="me-2"
/>
Save
</CButton>
</CCol>
</CRow>
</CRow>
</CForm>
)
}}
/>
)}
</>
</CippButtonCard>
)
}

export default SettingsSAMRoles
2 changes: 1 addition & 1 deletion src/views/identity/administration/Users.jsx
Original file line number Diff line number Diff line change
Expand Up @@ -589,7 +589,7 @@ const Users = (row) => {
label: 'Revoke sessions',
color: 'info',
modal: true,
modalUrl: `/api/ExecRevokeSessions?Enable=true&TenantFilter=!Tenant&ID=!userPrincipalName`,
modalUrl: `/api/ExecRevokeSessions?Enable=true&TenantFilter=!Tenant&ID=!id&Username=!userPrincipalName`,
modalMessage: 'Are you sure you want to revoke all sessions for these users?',
},
{
Expand Down
23 changes: 12 additions & 11 deletions src/views/tenant/administration/SecureScore.jsx
Original file line number Diff line number Diff line change
Expand Up @@ -28,6 +28,8 @@ import { CellTip, cellGenericFormatter } from 'src/components/tables/CellGeneric
import { CippCallout } from 'src/components/layout'
import CippPrettyCard from 'src/components/contentcards/CippPrettyCard'
import { TableModalButton } from 'src/components/buttons'
import DOMPurify from 'dompurify'
import ReactHtmlParser from 'react-html-parser'

const SecureScore = () => {
const textRef = useRef()
Expand Down Expand Up @@ -66,6 +68,12 @@ const SecureScore = () => {
},
})

const sanitizeHtml = (html) => {
var sanitizedHtml = DOMPurify.sanitize(html)
var parsedHtml = ReactHtmlParser(sanitizedHtml)
return parsedHtml
}

useEffect(() => {
if (isSuccess) {
setTranslatedData(securescore.Results[0])
Expand Down Expand Up @@ -341,23 +349,16 @@ const SecureScore = () => {
<CCardText>
<h5>Description</h5>
<small className="text-medium-emphasis">
<div
dangerouslySetInnerHTML={{
__html: `${info.description} ${info.implementationStatus}`,
}}
/>
<div>
{sanitizeHtml(`${info.description} ${info.implementationStatus}`)}
</div>
</small>
</CCardText>
{info.scoreInPercentage !== 100 && (
<CCardText>
<h5>Remediation Recommendation</h5>
<small className="mb-3 text-medium-emphasis">
{
<div
className="mb-3"
dangerouslySetInnerHTML={{ __html: info.remediation }}
/>
}
{<div className="mb-3">{sanitizeHtml(info.remediation)}</div>}
</small>
</CCardText>
)}
Expand Down
2 changes: 1 addition & 1 deletion staticwebapp.config.json
Original file line number Diff line number Diff line change
Expand Up @@ -103,7 +103,7 @@
}
},
"globalHeaders": {
"content-security-policy": "default-src https: 'unsafe-eval' 'unsafe-inline'; object-src 'self' blob:; img-src 'self' blob: data: *"
"content-security-policy": "default-src https: blob: 'unsafe-eval' 'unsafe-inline'; object-src 'self' blob:; img-src 'self' blob: data: *"
},
"mimeTypes": {
".json": "text/json"
Expand Down

0 comments on commit 33966f4

Please sign in to comment.