diff --git a/src/_nav.jsx b/src/_nav.jsx index f4ea23a753d9..fbf1ff50f013 100644 --- a/src/_nav.jsx +++ b/src/_nav.jsx @@ -244,6 +244,11 @@ const _nav = [ name: 'Deploy CA Policies', to: '/tenant/conditional/deploy', }, + { + component: CNavItem, + name: 'CA Policy Tester', + to: '/tenant/conditional/test-policy', + }, { component: CNavItem, name: 'CA Vacation Mode', diff --git a/src/importsMap.jsx b/src/importsMap.jsx index fd9f92661d53..ab783b321471 100644 --- a/src/importsMap.jsx +++ b/src/importsMap.jsx @@ -43,6 +43,7 @@ import React from 'react' "/tenant/administration/app-consent-requests": React.lazy(() => import('./views/tenant/administration/ListAppConsentRequests')), "/tenant/conditional/list-policies": React.lazy(() => import('./views/tenant/conditional/ConditionalAccess')), "/tenant/conditional/deploy-vacation": React.lazy(() => import('./views/tenant/conditional/DeployVacation')), + "/tenant/conditional/test-policy": React.lazy(() => import('./views/tenant/conditional/TestCAPolicy')), "/tenant/conditional/list-named-locations": React.lazy(() => import('./views/tenant/conditional/NamedLocations')), "/tenant/conditional/deploy": React.lazy(() => import('./views/tenant/conditional/DeployCA')), "/tenant/conditional/deploy-named-location": React.lazy(() => import('./views/tenant/conditional/DeployNamedLocation')), diff --git a/src/routes.json b/src/routes.json index bdb96a077822..db9ee316185f 100644 --- a/src/routes.json +++ b/src/routes.json @@ -282,6 +282,12 @@ "component": "views/tenant/conditional/DeployVacation", "allowedRoles": ["admin", "editor", "readonly"] }, + { + "path": "/tenant/conditional/test-policy", + "name": "Test Conditional Access Policy", + "component": "views/tenant/conditional/TestCAPolicy", + "allowedRoles": ["admin", "editor", "readonly"] + }, { "path": "/tenant/conditional/list-named-locations", "name": "Named Locations", diff --git a/src/views/tenant/conditional/TestCAPolicy.jsx b/src/views/tenant/conditional/TestCAPolicy.jsx new file mode 100644 index 000000000000..fe402e7e8f9c --- /dev/null +++ b/src/views/tenant/conditional/TestCAPolicy.jsx @@ -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 ( + + <> + + + +
{ + return ( + +

+ 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. +

+ + + + {(props) => } + + + +
+ Mandatory Parameters: +
+ + + ({ + value: user.id, + name: `${user.displayName} <${user.userPrincipalName}>`, + }))} + placeholder={!usersIsFetching ? 'Select user' : 'Loading...'} + name="UserId" + /> + + + + + ({ + value: ca.id, + name: `${ca.displayName}`, + }))} + placeholder={!caIsFetching ? 'Select Application' : 'Loading...'} + name="includeApplications" + /> + + + +
+ Optional Parameters: +
+ + + ({ + value: Code, + name: Name, + }))} + name="country" + placeholder="Type to search..." + label="Test from this country" + /> + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + Test policies + {postResults.isFetching && ( + + )} + + + + {postResults.isSuccess && ( + +
  • + {postResults.data?.Results?.value + ? 'Test succesful. See the table for the results.' + : postResults.data.Results} +
  • +
    + )} + {getResults.isFetching && ( + + Loading + + )} + {getResults.isSuccess && ( + {getResults.data?.Results} + )} + {getResults.isError && ( + + Could not connect to API: {getResults.error.message} + + )} +
    + ) + }} + /> + + + + + + + + + ) +} + +export default TestCAPolicy diff --git a/src/views/tenant/standards/ListAppliedStandards.jsx b/src/views/tenant/standards/ListAppliedStandards.jsx index ccbde72fa071..6cb3eb94a3f2 100644 --- a/src/views/tenant/standards/ListAppliedStandards.jsx +++ b/src/views/tenant/standards/ListAppliedStandards.jsx @@ -235,26 +235,6 @@ const ApplyNewStandard = () => { values: { tenant: tenantDomain, ...values.standards }, }) } - const tableColumns = [ - { - name: 'Tenant', - selector: (row) => row['displayName'], - sortable: true, - exportSelector: 'displayName', - }, - - { - name: 'Applied Standards', - selector: (row) => row['StandardsExport'], - sortable: true, - exportSelector: 'StandardsExport', - }, - { - name: 'Actions', - cell: Offcanvas, - maxWidth: '80px', - }, - ] const [intuneGetRequest, intuneTemplates] = useLazyGenericGetRequestQuery() const [transportGetRequest, transportTemplates] = useLazyGenericGetRequestQuery() const [exConnectorGetRequest, exConnectorTemplates] = useLazyGenericGetRequestQuery()