Skip to content

Commit

Permalink
feat: use mapping for security cards keys
Browse files Browse the repository at this point in the history
  • Loading branch information
arunjaindev committed Jan 8, 2025
1 parent 7161915 commit db86e02
Show file tree
Hide file tree
Showing 9 changed files with 119 additions and 96 deletions.
8 changes: 3 additions & 5 deletions src/Assets/Icon/ic-shield-check.svg
Loading
Sorry, something went wrong. Reload?
Sorry, we cannot display this file.
Sorry, this file is invalid so it cannot be displayed.
Original file line number Diff line number Diff line change
Expand Up @@ -3,9 +3,10 @@ import { ReactComponent as ICShieldWarning } from '@Icons/ic-shield-warning-outl
import { ReactComponent as ICShieldSecure } from '@Icons/ic-shield-check.svg'
import { ReactComponent as ICArrowRight } from '@Icons/ic-caret-down-small.svg'
import { SecurityCardProps } from './types'
import { CATEGORIES, SeveritiesDTO, SUB_CATEGORIES } from '../SecurityModal/types'
import { CATEGORIES, SUB_CATEGORIES } from '../SecurityModal/types'
import { CATEGORY_LABELS, SEVERITIES } from '../SecurityModal/constants'
import './securityCard.scss'
import { SEVERITIES } from '../SecurityModal/constants'
import { getTotalSeverities } from '../utils'

const SecurityCard = ({
category,
Expand All @@ -14,9 +15,7 @@ const SecurityCard = ({
handleCardClick,
rootClassName = '',
}: SecurityCardProps) => {
const totalCount = Object.entries(severityCount)
.filter(([key]) => key !== SeveritiesDTO.SUCCESSES)
.reduce((acc, [, value]) => acc + value, 0)
const totalCount = getTotalSeverities(severityCount)

const hasThreats: boolean = !!totalCount

Expand All @@ -30,11 +29,11 @@ const SecurityCard = ({
const getScanType = () => {
switch (category) {
case CATEGORIES.KUBERNETES_MANIFEST:
return 'Manifest Scan'
return CATEGORY_LABELS.KUBERNETES_MANIFEST
case CATEGORIES.CODE_SCAN:
return 'Code Scan'
return CATEGORY_LABELS.CODE_SCAN
default:
return 'Image Scan'
return CATEGORY_LABELS.IMAGE_SCAN
}
}

Expand Down Expand Up @@ -64,12 +63,19 @@ const SecurityCard = ({

const { title, subtitle } = getTitleSubtitle()

const onKeyDown = (event) => {
if (event.key === 'Enter' || event.key === 'Space') {
handleCardClick()
}
}

return (
<div
className={`${rootClassName} min-w-500 w-50 bcn-0 p-20 flexbox-col dc__gap-16 br-8 dc__border security-card security-card${hasThreats ? '--threat' : '--secure'}`}
className={`${rootClassName} w-100 bcn-0 p-20 flexbox-col dc__gap-16 br-8 dc__border security-card security-card${hasThreats ? '--threat' : '--secure'}`}
role="button"
tabIndex={0}
onClick={handleCardClick}
onKeyDown={onKeyDown}
>
<div className="flexbox dc__content-space">
<div className="flexbox-col">
Expand All @@ -79,7 +85,11 @@ const SecurityCard = ({
<ICArrowRight className="icon-dim-20 dc__flip-270 scb-5 arrow-right" />
</div>
</div>
{hasThreats ? <ICShieldWarning className="icon-dim-24" /> : <ICShieldSecure className="icon-dim-24" />}
{hasThreats ? (
<ICShieldWarning className="icon-dim-24" />
) : (
<ICShieldSecure className="icon-dim-24 scg-5" />
)}
</div>
<div className="flexbox-col dc__gap-12">
{hasThreats || severityCount.success ? (
Expand Down
Original file line number Diff line number Diff line change
Expand Up @@ -6,6 +6,8 @@ import { CATEGORIES, SecurityModalStateType, SUB_CATEGORIES } from '../SecurityM
import { SecurityCardProps, SecurityDetailsCardsProps } from './types'
import { SecurityModal } from '../SecurityModal'
import { DEFAULT_SECURITY_MODAL_IMAGE_STATE } from '../SecurityModal/constants'
import { ScanSubCategories } from '../types'
import './securityCard.scss'

const SecurityDetailsCards = ({ scanResult, Sidebar }: SecurityDetailsCardsProps) => {
const [showSecurityModal, setShowSecurityModal] = useState<boolean>(false)
Expand Down Expand Up @@ -33,6 +35,9 @@ const SecurityDetailsCards = ({ scanResult, Sidebar }: SecurityDetailsCardsProps
setShowSecurityModal(false)
}

const isValidSubCategory = (subCategory: ScanSubCategories): boolean =>
Object.values(SUB_CATEGORIES).includes(subCategory)

return (
<>
<div className="flexbox-col dc__gap-20">
Expand All @@ -42,21 +47,20 @@ const SecurityDetailsCards = ({ scanResult, Sidebar }: SecurityDetailsCardsProps
<span className="fs-13 fw-6 lh-1-5 cn-9">Image Scan</span>
<ScannedByToolModal scanToolId={imageScanToolId} />
</div>
<div className="flexbox dc__gap-12">
<SecurityCard
category={CATEGORIES.IMAGE_SCAN}
subCategory={SUB_CATEGORIES.VULNERABILITIES}
severityCount={imageScan.vulnerability?.summary?.severities}
handleCardClick={() =>
handleCardClick(CATEGORIES.IMAGE_SCAN, SUB_CATEGORIES.VULNERABILITIES)
<div className="dc__grid security-cards">
{Object.keys(imageScan).map((subCategory: SecurityCardProps['subCategory']) => {
if (!isValidSubCategory(subCategory)) {
return null
}
/>
<SecurityCard
category={CATEGORIES.IMAGE_SCAN}
subCategory={SUB_CATEGORIES.LICENSE}
severityCount={imageScan.license?.summary?.severities}
handleCardClick={() => handleCardClick(CATEGORIES.IMAGE_SCAN, SUB_CATEGORIES.LICENSE)}
/>
return (
<SecurityCard
category={CATEGORIES.IMAGE_SCAN}
subCategory={subCategory}
severityCount={imageScan[subCategory]?.summary.severities}
handleCardClick={() => handleCardClick(CATEGORIES.IMAGE_SCAN, subCategory)}
/>
)
})}
</div>
</div>
) : null}
Expand All @@ -66,39 +70,24 @@ const SecurityDetailsCards = ({ scanResult, Sidebar }: SecurityDetailsCardsProps
<span className="fs-13 fw-6 lh-1-5 cn-9">Code Scan</span>
<ScannedByToolModal scanToolId={codeScanToolId} />
</div>
<div className="flexbox dc__gap-12">
<SecurityCard
category={CATEGORIES.CODE_SCAN}
subCategory={SUB_CATEGORIES.VULNERABILITIES}
severityCount={codeScan.vulnerability?.summary.severities}
handleCardClick={() =>
handleCardClick(CATEGORIES.CODE_SCAN, SUB_CATEGORIES.VULNERABILITIES)
<div className="dc__grid security-cards">
{Object.keys(codeScan).map((subCategory: SecurityCardProps['subCategory']) => {
if (!isValidSubCategory(subCategory)) {
return null
}
/>
<SecurityCard
category={CATEGORIES.CODE_SCAN}
subCategory={SUB_CATEGORIES.LICENSE}
severityCount={codeScan.license?.summary?.severities}
handleCardClick={() => handleCardClick(CATEGORIES.CODE_SCAN, SUB_CATEGORIES.LICENSE)}
/>
</div>
<div className="flexbox dc__gap-12">
<SecurityCard
category={CATEGORIES.CODE_SCAN}
subCategory={SUB_CATEGORIES.MISCONFIGURATIONS}
severityCount={codeScan.misConfigurations?.misConfSummary?.status}
handleCardClick={() =>
handleCardClick(CATEGORIES.CODE_SCAN, SUB_CATEGORIES.MISCONFIGURATIONS)
}
/>
<SecurityCard
category={CATEGORIES.CODE_SCAN}
subCategory={SUB_CATEGORIES.EXPOSED_SECRETS}
severityCount={codeScan.exposedSecrets?.summary?.severities}
handleCardClick={() =>
handleCardClick(CATEGORIES.CODE_SCAN, SUB_CATEGORIES.EXPOSED_SECRETS)
}
/>
const severityCount =
subCategory === 'misConfigurations'
? codeScan.misConfigurations?.misConfSummary?.status
: codeScan[subCategory]?.summary?.severities
return (
<SecurityCard
category={CATEGORIES.CODE_SCAN}
subCategory={subCategory}
severityCount={severityCount}
handleCardClick={() => handleCardClick(CATEGORIES.CODE_SCAN, subCategory)}
/>
)
})}
</div>
</div>
) : null}
Expand All @@ -108,23 +97,26 @@ const SecurityDetailsCards = ({ scanResult, Sidebar }: SecurityDetailsCardsProps
<span className="fs-13 fw-6 lh-1-5 cn-9">Manifest Scan</span>
<ScannedByToolModal scanToolId={manifestScanToolId} />
</div>
<div className="flexbox dc__gap-12">
<SecurityCard
category={CATEGORIES.KUBERNETES_MANIFEST}
subCategory={SUB_CATEGORIES.MISCONFIGURATIONS}
severityCount={kubernetesManifest.misConfigurations?.misConfSummary?.status}
handleCardClick={() =>
handleCardClick(CATEGORIES.KUBERNETES_MANIFEST, SUB_CATEGORIES.MISCONFIGURATIONS)
}
/>
<SecurityCard
category={CATEGORIES.KUBERNETES_MANIFEST}
subCategory={SUB_CATEGORIES.EXPOSED_SECRETS}
severityCount={kubernetesManifest.exposedSecrets?.summary?.severities}
handleCardClick={() =>
handleCardClick(CATEGORIES.KUBERNETES_MANIFEST, SUB_CATEGORIES.EXPOSED_SECRETS)
<div className="dc__grid security-cards">
{Object.keys(kubernetesManifest).map((subCategory: SecurityCardProps['subCategory']) => {
if (!isValidSubCategory(subCategory)) {
return null
}
/>
const severityCount =
subCategory === 'misConfigurations'
? kubernetesManifest.misConfigurations?.misConfSummary?.status
: kubernetesManifest[subCategory]?.summary?.severities
return (
<SecurityCard
category={CATEGORIES.KUBERNETES_MANIFEST}
subCategory={subCategory}
severityCount={severityCount}
handleCardClick={() =>
handleCardClick(CATEGORIES.KUBERNETES_MANIFEST, subCategory)
}
/>
)
})}
</div>
</div>
) : null}
Expand Down
Original file line number Diff line number Diff line change
@@ -1,9 +1,9 @@
.security-card {
&--threat {
background: radial-gradient(25.91% 100% at 100% 0%, #FDE7E7 0%, #FFF 100%);
background: radial-gradient(25.91% 100% at 100% 0%, var(--R100) 0%, var(--N0) 100%);
}
&--secure {
background: radial-gradient(25.91% 100% at 100% 0%, #E9FBF4 0%, #FFF 100%);
background: radial-gradient(25.91% 100% at 100% 0%, var(--G100) 0%, var(--N0) 100%);
}

.arrow-right {
Expand All @@ -19,4 +19,10 @@
color: var(--B500);
}
}
}

.security-cards {
grid-template-columns: 1fr 1fr;
grid-row-gap: 12px;
grid-column-gap: 12px;
}
16 changes: 4 additions & 12 deletions src/Shared/Components/Security/SecurityDetailsCards/types.tsx
Original file line number Diff line number Diff line change
@@ -1,17 +1,9 @@
import {
CATEGORIES,
ScanResultDTO,
SecurityModalPropsType,
SeveritiesDTO,
SUB_CATEGORIES,
} from '../SecurityModal/types'

type Categories = keyof typeof CATEGORIES
type SubCategories = keyof typeof SUB_CATEGORIES
import { ScanResultDTO, SecurityModalPropsType, SeveritiesDTO } from '../SecurityModal/types'
import { ScanCategories, ScanSubCategories } from '../types'

export interface SecurityCardProps {
category: (typeof CATEGORIES)[Categories]
subCategory: (typeof SUB_CATEGORIES)[SubCategories]
category: ScanCategories
subCategory: ScanSubCategories
severityCount: Partial<Record<SeveritiesDTO, number>>
handleCardClick: () => void
rootClassName?: string
Expand Down
2 changes: 1 addition & 1 deletion src/Shared/Components/Security/SecurityModal/index.ts
Original file line number Diff line number Diff line change
Expand Up @@ -15,8 +15,8 @@ export type {
SidebarDataType,
GetResourceScanDetailsPayloadType,
GetResourceScanDetailsResponseType,
SeveritiesDTO,
} from './types'
export { SeveritiesDTO } from './types'
export { getSidebarData, getProgressingStateForStatus } from './config'
export { CATEGORY_LABELS } from './constants'
export { getSecurityScan } from './service'
Original file line number Diff line number Diff line change
Expand Up @@ -47,18 +47,18 @@ const Vulnerabilities = ({
}
}, [scanResultResponse])

if (!isScanEnabled || !scanResultResponse?.result.isImageScanEnabled) {
if (scanResultLoading) {
return (
<div className="security-tab-empty">
<p className="security-tab-empty__title">Scan is Disabled</p>
<Progressing />
</div>
)
}

if (scanResultLoading) {
if (!isScanEnabled || !scanResultResponse?.result?.isImageScanEnabled) {
return (
<div className="security-tab-empty">
<Progressing />
<p className="security-tab-empty__title">Scan is Disabled</p>
</div>
)
}
Expand Down
4 changes: 4 additions & 0 deletions src/Shared/Components/Security/types.tsx
Original file line number Diff line number Diff line change
@@ -0,0 +1,4 @@
import { CATEGORIES, SUB_CATEGORIES } from './SecurityModal/types'

export type ScanCategories = (typeof CATEGORIES)[keyof typeof CATEGORIES]
export type ScanSubCategories = (typeof SUB_CATEGORIES)[keyof typeof SUB_CATEGORIES]
21 changes: 21 additions & 0 deletions src/Shared/Components/Security/utils.tsx
Original file line number Diff line number Diff line change
@@ -1,2 +1,23 @@
import { ScanResultDTO, SeveritiesDTO } from './SecurityModal'

export const getCVEUrlFromCVEName = (cveName: string): string =>
`https://cve.mitre.org/cgi-bin/cvename.cgi?name=${cveName}`

export const getTotalSeverities = (severityCount: Partial<Record<SeveritiesDTO, number>>) =>
Object.entries(severityCount)
.filter(([key]) => key !== SeveritiesDTO.SUCCESSES)
.reduce((acc, [, value]) => acc + value, 0)

export const getSecurityThreatsArray = (scanResult: ScanResultDTO): Partial<Record<SeveritiesDTO, number>>[] => {
const { imageScan, codeScan, kubernetesManifest } = scanResult
return [
imageScan?.vulnerability?.summary?.severities || {},
imageScan?.license?.summary?.severities || {},
codeScan?.vulnerability?.summary.severities || {},
codeScan?.license?.summary?.severities || {},
codeScan?.misConfigurations?.misConfSummary?.status || {},
codeScan?.exposedSecrets?.summary?.severities || {},
kubernetesManifest?.misConfigurations?.misConfSummary?.status || {},
kubernetesManifest?.exposedSecrets?.summary?.severities || {},
]
}

0 comments on commit db86e02

Please sign in to comment.