Skip to content

Commit

Permalink
Merge branch 'KelvinTegelaar:main' into main
Browse files Browse the repository at this point in the history
  • Loading branch information
psreekumarinfx authored Feb 26, 2024
2 parents a065e48 + 54ce4a9 commit ecbeaf1
Show file tree
Hide file tree
Showing 5 changed files with 146 additions and 24 deletions.
2 changes: 1 addition & 1 deletion public/version_latest.txt
Original file line number Diff line number Diff line change
@@ -1 +1 @@
5.2.0
5.2.1
43 changes: 41 additions & 2 deletions src/components/forms/RFFComponents.jsx
Original file line number Diff line number Diff line change
Expand Up @@ -11,6 +11,7 @@ import {
CTooltip,
} from '@coreui/react'
import Select from 'react-select'
import Creatable, { useCreatable } from 'react-select/creatable'
import { Field } from 'react-final-form'
import { FieldArray } from 'react-final-form-arrays'
import React, { useState, useMemo, useRef } from 'react'
Expand Down Expand Up @@ -393,6 +394,7 @@ export const RFFSelectSearch = ({
disabled = false,
retainInput = true,
isLoading = false,
allowCreate = false,
refreshFunction,
props,
}) => {
Expand Down Expand Up @@ -433,7 +435,7 @@ export const RFFSelectSearch = ({
</CTooltip>
)}
</CFormLabel>
{onChange && (
{!allowCreate && onChange && (
<Select
className="react-select-container"
classNamePrefix="react-select"
Expand All @@ -452,7 +454,7 @@ export const RFFSelectSearch = ({
{...props}
/>
)}
{!onChange && (
{!allowCreate && !onChange && (
<Select
className="react-select-container"
classNamePrefix="react-select"
Expand All @@ -470,6 +472,43 @@ export const RFFSelectSearch = ({
{...props}
/>
)}
{allowCreate && onChange && (
<Creatable
className="react-select-container"
classNamePrefix="react-select"
{...input}
isClearable={false}
name={name}
id={name}
disabled={disabled}
options={selectSearchvalues}
placeholder={placeholder}
isMulti={multi}
onChange={onChange}
onInputChange={debounceOnInputChange}
inputValue={inputText}
isLoading={isLoading}
{...props}
/>
)}
{allowCreate && !onChange && (
<Creatable
className="react-select-container"
classNamePrefix="react-select"
{...input}
isClearable={true}
name={name}
id={name}
disabled={disabled}
options={selectSearchvalues}
placeholder={placeholder}
onInputChange={setOnInputChange}
isMulti={multi}
inputValue={inputText}
isLoading={isLoading}
{...props}
/>
)}
{meta.error && meta.touched && <span className="text-danger">{meta.error}</span>}
</div>
)
Expand Down
30 changes: 20 additions & 10 deletions src/views/identity/reports/MFAReport.jsx
Original file line number Diff line number Diff line change
Expand Up @@ -25,19 +25,20 @@ const columns = [
cell: cellBooleanFormatter({ colourless: true }),
exportSelector: 'isLicensed',
},
{
selector: (row) => row['PerUser'],
name: 'Per user MFA Status',
sortable: true,
exportSelector: 'PerUser',
},
{
selector: (row) => row['MFARegistration'],
name: 'Registered for Conditional MFA',
sortable: true,
cell: cellBooleanFormatter(),
exportSelector: 'MFARegistration',
},
{
selector: (row) => row['CoveredBySD'],
name: 'Enforced via Security Defaults',
sortable: true,
cell: cellBooleanFormatter({ colourless: true }),
exportSelector: 'CoveredBySD',
},
{
selector: (row) => row['CoveredByCA'],
name: 'Enforced via Conditional Access',
Expand All @@ -46,11 +47,10 @@ const columns = [
exportSelector: 'CoveredByCA',
},
{
selector: (row) => row['CoveredBySD'],
name: 'Enforced via Security Defaults',
selector: (row) => row['PerUser'],
name: 'Per user MFA Status',
sortable: true,
cell: cellBooleanFormatter({ colourless: true }),
exportSelector: 'CoveredBySD',
exportSelector: 'PerUser',
},
]

Expand Down Expand Up @@ -134,7 +134,17 @@ const MFAList = () => {
datatable={{
filterlist: [
{ filterName: 'Enabled users', filter: '"accountEnabled":true' },
{ filterName: 'Non-guest users', filter: 'Complex: UPN notlike #EXT#' },
{ filterName: 'Licensed users', filter: 'Complex: IsLicensed eq true' },
{
filterName: 'Enabled, licensed non-guest users missing MFA',
filter:
'Complex: UPN notlike #EXT#; IsLicensed eq true; accountEnabled eq true; MFARegistration eq false',
},
{
filterName: 'No MFA methods registered',
filter: 'Complex: MFARegistration eq false',
},
],
columns: tenant.defaultDomainName === 'AllTenants' ? Altcolumns : columns,
path: '/api/ListMFAUsers',
Expand Down
93 changes: 83 additions & 10 deletions src/views/tenant/administration/GraphExplorer.jsx
Original file line number Diff line number Diff line change
@@ -1,4 +1,4 @@
import React, { useEffect, useState, useRef } from 'react'
import React, { useEffect, useState, useRef, useMemo } from 'react'
import {
CAlert,
CButton,
Expand Down Expand Up @@ -31,6 +31,7 @@ import { OnChange } from 'react-final-form-listeners'
import { cellGenericFormatter } from 'src/components/tables/CellGenericFormat'
import PropTypes from 'prop-types'
import { CippCodeOffCanvas, ModalService } from 'src/components/utilities'
import { debounce } from 'lodash-es'

const GraphExplorer = () => {
const tenant = useSelector((state) => state.app.currentTenant)
Expand All @@ -39,6 +40,7 @@ const GraphExplorer = () => {
const [alertVisible, setAlertVisible] = useState()
const [random, setRandom] = useState('')
const [random2, setRandom2] = useState('')
const [random3, setRandom3] = useState('')
const [ocVisible, setOCVisible] = useState(false)
const [searchNow, setSearchNow] = useState(false)
const [visibleA, setVisibleA] = useState(true)
Expand All @@ -49,13 +51,30 @@ const GraphExplorer = () => {
}
const [execGraphRequest, graphrequest] = useLazyGenericGetRequestQuery()
const [execPostRequest, postResults] = useLazyGenericPostRequestQuery()
const [execPropRequest, availableProperties] = useLazyGenericGetRequestQuery()
const {
data: customPresets = [],
isFetching: presetsIsFetching,
error: presetsError,
} = useGenericGetRequestQuery({ path: '/api/ListGraphExplorerPresets', params: { random2 } })
const QueryColumns = { set: false, data: [] }

function endpointChange(value) {
execPropRequest({
path: '/api/ListGraphRequest',
params: {
Endpoint: value,
ListProperties: true,
TenantFilter: tenant.defaultDomainName,
IgnoreErrors: true,
random: (Math.random() + 1).toString(36).substring(7),
},
})
}
const debounceEndpointChange = useMemo(() => {
return debounce(endpointChange, 1000)
}, [endpointChange])

if (graphrequest.isSuccess) {
if (graphrequest.data?.Results?.length > 0) {
//set columns
Expand Down Expand Up @@ -217,10 +236,15 @@ const GraphExplorer = () => {

useEffect(() => {
if (params?.endpoint) {
var select = ''
if (params?.$select) {
select = params.$select.map((p) => p.value).join(',')
}
execGraphRequest({
path: 'api/ListGraphRequest',
params: {
...params,
$select: select,
random: random,
},
})
Expand All @@ -237,15 +261,36 @@ const GraphExplorer = () => {
{({ form }) => (
<OnChange name={field}>
{(value) => {
if (field == 'endpoint') {
debounceEndpointChange(value)
}
if (value?.value) {
let preset = presets.filter(function (obj) {
return obj.id === value.value
})
if (preset[0]?.id !== '') {
if (preset[0]?.params[set]) {
onChange(preset[0]?.params[set])
if (set == 'endpoint') {
debounceEndpointChange(preset[0]?.params[set])
}
if (set == '$select') {
if (preset[0]?.params[set]) {
var properties = preset[0].params[set].split(',')
var selectedProps = properties.map((prop) => {
return {
label: prop,
value: prop,
}
})
onChange(selectedProps)
} else {
onChange('')
}
} else {
onChange(preset[0][set])
if (preset[0]?.params[set]) {
onChange(preset[0]?.params[set])
} else {
onChange(preset[0][set])
}
}
}
}
Expand All @@ -263,6 +308,10 @@ const GraphExplorer = () => {

function getPresetProps(values) {
var newvals = Object.assign({}, values)
console.log(newvals)
if (newvals?.$select !== undefined && Array.isArray(newvals?.$select)) {
newvals.$select = newvals?.$select.map((p) => p.value).join(',')
}
delete newvals['reportTemplate']
delete newvals['tenantFilter']
delete newvals['IsShared']
Expand Down Expand Up @@ -454,19 +503,38 @@ const GraphExplorer = () => {
placeholder="Enter the Graph Endpoint you'd like to run the custom report for."
/>
<WhenFieldChanges field="reportTemplate" set="endpoint" />
<WhenFieldChanges field="endpoint" set="endpoint" />
<RFFCFormInput
type="text"
name="$filter"
label="Filter"
placeholder="Enter the filter string for the Graph query"
/>
<WhenFieldChanges field="reportTemplate" set="$filter" />
<RFFCFormInput
type="text"
name="$select"
label="Select"
placeholder="Select the columns to use for this query"
/>
<div className="mb-3">
<RFFSelectSearch
name="$select"
label="Select"
placeholder="Select the columns to use for this query"
retainInput={true}
multi={true}
values={
availableProperties?.data?.Results
? availableProperties?.data?.Results.map((prop) => {
return {
name: prop,
value: prop,
}
})
: []
}
allowCreate={true}
refreshFunction={() =>
setRandom3((Math.random() + 1).toString(36).substring(7))
}
isLoading={availableProperties.isFetching}
/>
</div>
<WhenFieldChanges field="reportTemplate" set="$select" />
<RFFCFormInput
type="text"
Expand Down Expand Up @@ -504,6 +572,11 @@ const GraphExplorer = () => {
<hr />
<CippPage title="Report Results" tenantSelector={false}>
{!searchNow && <span>Execute a search to get started.</span>}
{graphrequest.isFetching && (
<div className="my-2">
<CSpinner className="me-2" /> Loading Data
</div>
)}
{graphrequest.isSuccess && QueryColumns.set && searchNow && (
<CCard className="content-card">
<CCardHeader className="d-flex justify-content-between align-items-center">
Expand Down
2 changes: 1 addition & 1 deletion version_latest.txt
Original file line number Diff line number Diff line change
@@ -1 +1 @@
5.2.0
5.2.1

0 comments on commit ecbeaf1

Please sign in to comment.