Skip to content

Commit

Permalink
implement dependency tree for sbom
Browse files Browse the repository at this point in the history
  • Loading branch information
avzz-19 committed Feb 5, 2025
1 parent 6dea053 commit b363b42
Show file tree
Hide file tree
Showing 39 changed files with 1,902 additions and 126 deletions.
1 change: 1 addition & 0 deletions app/adapters/commondrf.d.ts
Original file line number Diff line number Diff line change
Expand Up @@ -7,6 +7,7 @@ export default class CommonDRFAdapter extends RESTAdapter {
host: string;
namespace: string;
namespace_v2: string;
namespace_v3: string;
addTrailingSlashes: boolean;

@service declare organization: OrganizationService;
Expand Down
1 change: 1 addition & 0 deletions app/adapters/commondrf.js
Original file line number Diff line number Diff line change
Expand Up @@ -6,6 +6,7 @@ export default class CommonDRFAdapter extends DRFAuthenticationBase {
host = ENV.host;
namespace = ENV.namespace;
namespace_v2 = ENV.namespace_v2;
namespace_v3 = ENV.namespace_v3;
addTrailingSlashes = false;

@service organization;
Expand Down
67 changes: 60 additions & 7 deletions app/adapters/sbom-component.ts
Original file line number Diff line number Diff line change
Expand Up @@ -2,7 +2,7 @@ import commondrf from './commondrf';

export default class SbomComponentAdapter extends commondrf {
_buildURL(modelName?: string | number, id?: string | number) {
const baseURL = `${this.namespace_v2}/sb_files`;
const baseURL = `${this.namespace_v3}/sb_files`;

if (id) {
return this.buildURLFromBase(`${baseURL}/${encodeURIComponent(id)}`);
Expand All @@ -26,18 +26,71 @@ export default class SbomComponentAdapter extends commondrf {
return sbomComponentUrl;
}

_buildDependencyURL(
modelName: string | number,
sbomFileId: string | number,
componentId: string | number
) {
const componentUrl = this._buildNestedURL(
modelName,
sbomFileId,
componentId
);

return `${componentUrl}/dependencies`;
}

_buildParentsURL(
modelName: string | number,
sbomFileId: string | number,
componentId: string | number
) {
const componentUrl = this._buildNestedURL(
modelName,
sbomFileId,
componentId
);

return `${componentUrl}/parents`;
}

urlForQuery(
query: { sbomFileId: string | number },
query:
| { sbomFileId: string | number }
| {
type: number;
sbomFileId: string | number;
componentId?: string | number;
},
modelName: string | number
) {
if ('type' in query && query.componentId) {
if (query.type === 1) {
return this._buildDependencyURL(
modelName,
query.sbomFileId,
query.componentId
);
} else if (query.type === 2) {
return this._buildParentsURL(
modelName,
query.sbomFileId,
query.componentId
);
}
}

return this._buildNestedURL(modelName, query.sbomFileId);
}

urlForQueryRecord(query: { sbomComponentId: string | number }) {
const baseURL = `${this.namespace_v2}/sb_components`;

return this.buildURLFromBase(
`${baseURL}/${encodeURIComponent(query.sbomComponentId)}`
urlForQueryRecord(
query: { sbomComponentId: string | number; sbomFileId: string | number },
modelName: string | number
) {
return this._buildNestedURL(
modelName,
query.sbomFileId,
query.sbomComponentId
);
}
}
Expand Down
57 changes: 21 additions & 36 deletions app/components/sbom/component-details/index.hbs
Original file line number Diff line number Diff line change
@@ -1,45 +1,30 @@
<div class='py-1' data-test-sbomComponentDetails-container>
<AkStack class='mb-3' @direction='column' @spacing='0.5'>
<AkTypography data-test-sbomComponentDetails-title @variant='h5'>
{{t 'sbomModule.componentDetails'}}
<AkStack local-class='summary-header-root' @direction='column' class='p-2'>
<AkTypography
data-test-sbomComponentDetails-headerTitleLabel
@color='textSecondary'
>
{{t 'sbomModule.componentName'}}
</AkTypography>

<AkTypography
data-test-sbomComponentDetails-description
@variant='body2'
@color='textSecondary'
data-test-sbomComponentDetails-headerTitleValue
@variant='h5'
local-class='summary-header-value'
>
{{t 'sbomModule.componentDetailsDescription'}}
{{this.componentName}}
</AkTypography>
</AkStack>

<Sbom::SummaryHeader>
<:summary>
<AkStack class='p-1'>
<AkTypography
data-test-sbomComponentDetails-headerTitleLabel
{{style width='160px'}}
@color='textSecondary'
>
{{t 'sbomModule.componentName'}}
</AkTypography>

<AkTypography
data-test-sbomComponentDetails-headerTitleValue
@variant='h6'
>
{{@sbomComponent.name}}
</AkTypography>
</AkStack>
</:summary>

<:collapsibleContent>
<Sbom::ComponentDetails::Summary @sbomComponent={{@sbomComponent}} />
</:collapsibleContent>
</Sbom::SummaryHeader>

<Sbom::ComponentDetails::Vulnerabilities
class='mt-3'
@sbomComponent={{@sbomComponent}}
/>
<AkTabs class='mt-3' as |Akt|>
{{#each this.tabs as |item|}}
<Akt.tabItem
@id={{item.id}}
@route={{item.route}}
@currentWhen={{item.activeRoutes}}
>
{{item.label}}
</Akt.tabItem>
{{/each}}
</AkTabs>
</div>
10 changes: 10 additions & 0 deletions app/components/sbom/component-details/index.scss
Original file line number Diff line number Diff line change
@@ -0,0 +1,10 @@
.summary-header-root {
border-radius: var(--sbom-summary-header-border-radius);
border: 1px solid var(--sbom-summary-header-border-color);
box-sizing: border-box;
}

.summary-header-value {
font-family: monospace;
margin-top: 0.3em;
}
32 changes: 30 additions & 2 deletions app/components/sbom/component-details/index.ts
Original file line number Diff line number Diff line change
@@ -1,13 +1,16 @@
import { inject as service } from '@ember/service';
import Component from '@glimmer/component';

import SbomComponentModel from 'irene/models/sbom-component';
import IntlService from 'ember-intl/services/intl';
import type SbomComponentModel from 'irene/models/sbom-component';
import type IntlService from 'ember-intl/services/intl';

export interface SbomComponentDetailsSignature {
Args: {
sbomComponent: SbomComponentModel | null;
};
Blocks: {
default: [];
};
}

export default class SbomComponentDetailsComponent extends Component<SbomComponentDetailsSignature> {
Expand All @@ -20,6 +23,31 @@ export default class SbomComponentDetailsComponent extends Component<SbomCompone
get sbomProject() {
return this.sbomFile?.get('sbProject');
}

get componentName() {
const bomRef = this.args.sbomComponent?.bomRef;

const trucatedBomref = bomRef?.substring(0, bomRef.lastIndexOf(':'));
return `${trucatedBomref} : ${this.args.sbomComponent?.name}`;
}

get tabs() {
return [
{
id: 'overview',
label: this.intl.t('overview'),
route: 'authenticated.dashboard.sbom.component-details.overview',
activeRoutes: 'authenticated.dashboard.sbom.component-details.overview',
},
{
id: 'vulnerabilities',
label: this.intl.t('vulnerabilities'),
route: 'authenticated.dashboard.sbom.component-details.vulnerabilities',
activeRoutes:
'authenticated.dashboard.sbom.component-details.vulnerabilities',
},
];
}
}

declare module '@glint/environment-ember-loose/registry' {
Expand Down
36 changes: 36 additions & 0 deletions app/components/sbom/component-details/overview/index.hbs
Original file line number Diff line number Diff line change
@@ -0,0 +1,36 @@
<AkStack local-class='section-container' @direction='column'>
<AkStack @width='full' local-class='header-container'>
<AkTypography @variant='h6' @fontWeight='medium'>
{{t 'sbomModule.componentDetails'}}
</AkTypography>
</AkStack>

<AkStack class='p-1' @width='full'>
<Sbom::ComponentDetails::Summary
local-class='component-details'
@sbomComponent={{@sbomComponent}}
/>
</AkStack>
</AkStack>

{{#if this.isNotOutdated}}
<AkStack @direction='column'>
<AkStack @width='full' local-class='header-container full-border'>
<AkTypography @variant='h6' @fontWeight='medium'>
{{t 'dependencyTree'}}
</AkTypography>
</AkStack>

<Sbom::ScanDetails::ComponentTree
@sbomProject={{this.sbomProject}}
@sbomFile={{this.sbomFile}}
@packageName={{this.packageName}}
@updateExpandedNodes={{this.updateExpandedNodes}}
@expandedNodes={{this.expandedNodes}}
@treeNodes={{this.treeNodes}}
@updateTreeNodes={{this.updateTreeNodes}}
@parentId={{this.parentId}}
@componentId={{this.componentId}}
/>
</AkStack>
{{/if}}
24 changes: 24 additions & 0 deletions app/components/sbom/component-details/overview/index.scss
Original file line number Diff line number Diff line change
@@ -0,0 +1,24 @@
.section-container {
border: 1px solid var(--sbom-component-details-overview-border-color);
border-radius: var(--sbom-component-details-overview-border-radius);
margin-top: 1em;
}

.header-container {
background-color: var(--sbom-component-details-overview-background-color);
border-bottom: 1px solid var(--sbom-component-details-overview-border-color);
padding: 0.5em 1em;

&.full-border {
border-color: var(--sbom-component-details-overview-border-color);
border-width: 1px 1px 0px 1px;
border-top-left-radius: var(--sbom-component-details-overview-border-radius);
border-top-right-radius: var(--sbom-component-details-overview-border-radius);
border-style: solid;
margin-top: 1em;
}
}

.component-details {
width: 100%;
}
Loading

0 comments on commit b363b42

Please sign in to comment.