forked from KelvinTegelaar/CIPP
-
Notifications
You must be signed in to change notification settings - Fork 0
Commit
This commit does not belong to any branch on this repository, and may belong to a fork outside of the repository.
Merge branch 'KelvinTegelaar:dev' into dev
- Loading branch information
Showing
5 changed files
with
293 additions
and
20 deletions.
There are no files selected for viewing
This file contains bidirectional Unicode text that may be interpreted or compiled differently than what appears below. To review, open the file in an editor that reveals hidden Unicode characters.
Learn more about bidirectional Unicode characters
This file contains bidirectional Unicode text that may be interpreted or compiled differently than what appears below. To review, open the file in an editor that reveals hidden Unicode characters.
Learn more about bidirectional Unicode characters
This file contains bidirectional Unicode text that may be interpreted or compiled differently than what appears below. To review, open the file in an editor that reveals hidden Unicode characters.
Learn more about bidirectional Unicode characters
This file contains bidirectional Unicode text that may be interpreted or compiled differently than what appears below. To review, open the file in an editor that reveals hidden Unicode characters.
Learn more about bidirectional Unicode characters
Original file line number | Diff line number | Diff line change |
---|---|---|
@@ -0,0 +1,281 @@ | ||
import React, { useState } from 'react' | ||
import { CButton, CCallout, CCol, CForm, CRow, CSpinner, CTooltip } from '@coreui/react' | ||
import { useSelector } from 'react-redux' | ||
import { Field, Form } from 'react-final-form' | ||
import { RFFCFormInput, RFFSelectSearch } from 'src/components/forms' | ||
import { useLazyGenericGetRequestQuery, useLazyGenericPostRequestQuery } from 'src/store/api/app' | ||
import { FontAwesomeIcon } from '@fortawesome/react-fontawesome' | ||
import { faCircleNotch, faEdit, faEye } from '@fortawesome/free-solid-svg-icons' | ||
import { CippContentCard, CippPage, CippPageList } from 'src/components/layout' | ||
import 'react-datepicker/dist/react-datepicker.css' | ||
import { TenantSelector } from 'src/components/utilities' | ||
import arrayMutators from 'final-form-arrays' | ||
import 'react-datepicker/dist/react-datepicker.css' | ||
import { useListUsersQuery } from 'src/store/api/users' | ||
import { useListConditionalAccessPoliciesQuery } from 'src/store/api/tenants' | ||
import { TableContentCard } from 'src/components/contentcards' | ||
import { cellGenericFormatter } from 'src/components/tables/CellGenericFormat' | ||
import countryList from 'src/data/countryList' | ||
|
||
const TestCAPolicy = () => { | ||
const [ExecuteGetRequest, getResults] = useLazyGenericGetRequestQuery() | ||
const currentDate = new Date() | ||
const [startDate, setStartDate] = useState(currentDate) | ||
const [endDate, setEndDate] = useState(currentDate) | ||
|
||
const tenantDomain = useSelector((state) => state.app.currentTenant.defaultDomainName) | ||
const [refreshState, setRefreshState] = useState(false) | ||
const [genericPostRequest, postResults] = useLazyGenericPostRequestQuery() | ||
|
||
const onSubmit = (values) => { | ||
genericPostRequest({ | ||
path: '/api/ExecCACheck', | ||
values: { tenantFilter: tenantDomain, ...values }, | ||
}).then((res) => { | ||
setRefreshState(res.requestId) | ||
}) | ||
} | ||
|
||
const { | ||
data: users = [], | ||
isFetching: usersIsFetching, | ||
error: usersError, | ||
} = useListUsersQuery({ tenantDomain }) | ||
|
||
const { | ||
data: caPolicies = [], | ||
isFetching: caIsFetching, | ||
error: caError, | ||
} = useListConditionalAccessPoliciesQuery({ domain: tenantDomain }) | ||
const columns = [ | ||
{ | ||
name: 'Display Name', | ||
selector: (row) => row['displayName'], | ||
sortable: true, | ||
cell: cellGenericFormatter(), | ||
exportSelector: 'displayName', | ||
}, | ||
{ | ||
name: 'State', | ||
selector: (row) => row['state'], | ||
sortable: true, | ||
cell: cellGenericFormatter(), | ||
exportSelector: 'state', | ||
}, | ||
{ | ||
name: 'Policy Applied', | ||
selector: (row) => row['policyApplies'], | ||
sortable: true, | ||
cell: cellGenericFormatter(), | ||
exportSelector: 'policyApplies', | ||
}, | ||
{ | ||
name: 'Reasons for not applying', | ||
selector: (row) => row['reasons'], | ||
sortable: true, | ||
exportSelector: 'reasons', | ||
}, | ||
] | ||
return ( | ||
<CippPage title={`Add Schedule`} tenantSelector={false}> | ||
<> | ||
<CRow> | ||
<CCol md={4}> | ||
<CippContentCard title="Test Conditional Access Policy" icon={faEdit}> | ||
<Form | ||
onSubmit={onSubmit} | ||
mutators={{ | ||
...arrayMutators, | ||
}} | ||
render={({ handleSubmit, submitting, values }) => { | ||
return ( | ||
<CForm onSubmit={handleSubmit}> | ||
<p> | ||
Test your conditional access policies before putting them in production. The | ||
returned results will show you if the user is allowed or denied access based | ||
on the policy. | ||
</p> | ||
<CRow className="mb-3"> | ||
<CCol> | ||
<label>Tenant</label> | ||
<Field name="tenantFilter">{(props) => <TenantSelector />}</Field> | ||
</CCol> | ||
</CRow> | ||
<CRow className="mb-3"> | ||
<hr /> | ||
Mandatory Parameters: | ||
</CRow> | ||
<CRow className="mb-3"> | ||
<CCol> | ||
<RFFSelectSearch | ||
label={'Select a user to test'} | ||
values={users?.map((user) => ({ | ||
value: user.id, | ||
name: `${user.displayName} <${user.userPrincipalName}>`, | ||
}))} | ||
placeholder={!usersIsFetching ? 'Select user' : 'Loading...'} | ||
name="UserId" | ||
/> | ||
</CCol> | ||
</CRow> | ||
<CRow className="mb-3"> | ||
<CCol> | ||
<RFFSelectSearch | ||
label={'Select the application to test.'} | ||
values={caPolicies?.map((ca) => ({ | ||
value: ca.id, | ||
name: `${ca.displayName}`, | ||
}))} | ||
placeholder={!caIsFetching ? 'Select Application' : 'Loading...'} | ||
name="includeApplications" | ||
/> | ||
</CCol> | ||
</CRow> | ||
<CRow className="mb-3"> | ||
<hr /> | ||
Optional Parameters: | ||
</CRow> | ||
<CRow className="mb-3"> | ||
<CCol> | ||
<RFFSelectSearch | ||
values={countryList.map(({ Code, Name }) => ({ | ||
value: Code, | ||
name: Name, | ||
}))} | ||
name="country" | ||
placeholder="Type to search..." | ||
label="Test from this country" | ||
/> | ||
</CCol> | ||
</CRow> | ||
<CRow className="mb-3"> | ||
<CCol> | ||
<RFFCFormInput | ||
placeholder="8.8.8.8" | ||
label="Test from this IP" | ||
name="IpAddress" | ||
/> | ||
</CCol> | ||
</CRow> | ||
<CRow className="mb-3"> | ||
<CCol> | ||
<RFFSelectSearch | ||
label={'Select the device platform to test'} | ||
values={[ | ||
{ value: 'Windows', name: 'Windows' }, | ||
{ value: 'iOS', name: 'iOS' }, | ||
{ value: 'Android', name: 'Android' }, | ||
{ value: 'MacOS', name: 'MacOS' }, | ||
{ value: 'Linux', name: 'Linux' }, | ||
]} | ||
placeholder={!caIsFetching ? 'Select platform' : 'Loading...'} | ||
name="devicePlatform" | ||
/> | ||
</CCol> | ||
</CRow> | ||
<CRow className="mb-3"> | ||
<CCol> | ||
<RFFSelectSearch | ||
label={'Select the client application type to test'} | ||
values={[ | ||
{ value: 'all', name: 'All' }, | ||
{ value: 'Browser', name: 'Browser' }, | ||
{ | ||
value: 'mobileAppsAndDesktopClients', | ||
name: 'Mobile apps and desktop clients', | ||
}, | ||
{ value: 'exchangeActiveSync', name: 'Exchange ActiveSync' }, | ||
{ value: 'easSupported', name: 'EAS supported' }, | ||
{ value: 'other', name: 'Other clients' }, | ||
]} | ||
placeholder={!caIsFetching ? 'Select client application' : 'Loading...'} | ||
name="clientAppType" | ||
/> | ||
</CCol> | ||
</CRow> | ||
<CRow className="mb-3"> | ||
<CCol> | ||
<RFFSelectSearch | ||
label={'Select the sign in risk level of the user signing in.'} | ||
values={[ | ||
{ value: 'low', name: 'Low' }, | ||
{ value: 'medium', name: 'Medium' }, | ||
{ value: 'high', name: 'High' }, | ||
{ value: 'none', name: 'None' }, | ||
]} | ||
placeholder={!caIsFetching ? 'Select Sign-in risk' : 'Loading...'} | ||
name="SignInRiskLevel" | ||
/> | ||
</CCol> | ||
</CRow> | ||
<CRow className="mb-3"> | ||
<CCol> | ||
<RFFSelectSearch | ||
label={'Select the user risk level of the user signing in.'} | ||
values={[ | ||
{ value: 'low', name: 'Low' }, | ||
{ value: 'medium', name: 'Medium' }, | ||
{ value: 'high', name: 'High' }, | ||
{ value: 'none', name: 'None' }, | ||
]} | ||
placeholder={!caIsFetching ? 'Select User Risk' : 'Loading...'} | ||
name="userRiskLevel" | ||
/> | ||
</CCol> | ||
</CRow> | ||
<CRow> | ||
<CCol md={6}> | ||
<CButton type="submit" disabled={submitting}> | ||
Test policies | ||
{postResults.isFetching && ( | ||
<FontAwesomeIcon | ||
icon={faCircleNotch} | ||
spin | ||
className="ms-2" | ||
size="1x" | ||
/> | ||
)} | ||
</CButton> | ||
</CCol> | ||
</CRow> | ||
{postResults.isSuccess && ( | ||
<CCallout color="success"> | ||
<li> | ||
{postResults.data?.Results?.value | ||
? 'Test succesful. See the table for the results.' | ||
: postResults.data.Results} | ||
</li> | ||
</CCallout> | ||
)} | ||
{getResults.isFetching && ( | ||
<CCallout color="info"> | ||
<CSpinner>Loading</CSpinner> | ||
</CCallout> | ||
)} | ||
{getResults.isSuccess && ( | ||
<CCallout color="info">{getResults.data?.Results}</CCallout> | ||
)} | ||
{getResults.isError && ( | ||
<CCallout color="danger"> | ||
Could not connect to API: {getResults.error.message} | ||
</CCallout> | ||
)} | ||
</CForm> | ||
) | ||
}} | ||
/> | ||
</CippContentCard> | ||
</CCol> | ||
<CCol md={8}> | ||
<TableContentCard | ||
title="Results" | ||
table={{ data: postResults.data?.Results?.value, columns: columns }} | ||
/> | ||
</CCol> | ||
</CRow> | ||
</> | ||
</CippPage> | ||
) | ||
} | ||
|
||
export default TestCAPolicy |
This file contains bidirectional Unicode text that may be interpreted or compiled differently than what appears below. To review, open the file in an editor that reveals hidden Unicode characters.
Learn more about bidirectional Unicode characters