Skip to content

Commit

Permalink
--wip-- [skip ci]
Browse files Browse the repository at this point in the history
  • Loading branch information
future-pirate-king committed Dec 19, 2024
1 parent e952fda commit 2db1b4d
Show file tree
Hide file tree
Showing 42 changed files with 634 additions and 632 deletions.
13 changes: 13 additions & 0 deletions app/adapters/available-automated-device.ts
Original file line number Diff line number Diff line change
@@ -0,0 +1,13 @@
import CommondrfNestedAdapter from './commondrf-nested';

export default class AvailableAutomatedDeviceAdapter extends CommondrfNestedAdapter {
setNestedUrlNamespace(projectId: string) {
this.namespace = `${this.namespace_v2}/projects/${projectId}`;
}
}

declare module 'ember-data/types/registries/adapter' {
export default interface AdapterRegistry {
'available-automated-device': AvailableAutomatedDeviceAdapter;
}
}
30 changes: 30 additions & 0 deletions app/adapters/commondrf-nested.ts
Original file line number Diff line number Diff line change
@@ -0,0 +1,30 @@
import CommonDRFAdapter from './commondrf';
import { underscore } from '@ember/string';
import type ModelRegistry from 'ember-data/types/registries/model';

export default class CommondrfNestedAdapter extends CommonDRFAdapter {
namespace = '';
pathTypeName: keyof ModelRegistry | null = null;

pathForType(type: keyof ModelRegistry) {
return underscore(super.pathForType(this.pathTypeName || type));
}

handleResponse(
status: number,
headers: object,
payload: object,
requestData: object
) {
if (status >= 400 && this.namespace === '') {
throw new Error(
'setNestUrlNamespace should be called before making a request'
);
}

// reset namespace
this.namespace = '';

return super.handleResponse(status, headers, payload, requestData);
}
}
17 changes: 17 additions & 0 deletions app/adapters/ds-automation-preference.ts
Original file line number Diff line number Diff line change
@@ -0,0 +1,17 @@
import CommondrfNestedAdapter from './commondrf-nested';

export default class DsAutomationPreferenceAdapter extends CommondrfNestedAdapter {
pathForType() {
return 'automation_preference';
}

setNestedUrlNamespace(profileId: string) {
this.namespace = `${this.namespace_v2}/profiles/${profileId}`;
}
}

declare module 'ember-data/types/registries/adapter' {
export default interface AdapterRegistry {
'ds-automation-preference': DsAutomationPreferenceAdapter;
}
}
113 changes: 31 additions & 82 deletions app/components/file-details/dynamic-scan/action/index.hbs
Original file line number Diff line number Diff line change
@@ -1,87 +1,36 @@
<AkStack @direction='column' @alignItems='center' @spacing='1'>
{{! TODO: Logic should be replaced by comments when full DAST feature is ready }}
{{#if @dynamicScan.isReadyOrRunning}}
{{#if @isAutomatedScan}}
<AkButton
local-class='dynamic-scan-btn'
@variant='outlined'
@color='neutral'
@disabled={{not @file.isActive}}
{{on 'click' (perform this.dynamicShutdown)}}
data-test-fileDetails-dynamicScanAction-cancelBtn
>
<:leftIcon>
{{#if this.dynamicShutdown.isRunning}}
<AkLoader @color='secondary' @size={{13}} />
{{else}}
<AkIcon @iconName='close' />
{{/if}}
</:leftIcon>

<:default>{{t 'cancelScan'}}</:default>
</AkButton>
{{else}}
<AkButton
data-test-fileDetails-dynamicScanAction-stopBtn
local-class='dynamic-scan-btn'
{{on 'click' (perform this.dynamicShutdown)}}
@disabled={{not @file.isActive}}
>
<:leftIcon>
{{#if this.dynamicShutdown.isRunning}}
<AkLoader @size={{13}} />
{{else}}
<AkIcon @iconName='stop-circle' />
{{/if}}
</:leftIcon>

<:default>{{t 'stop'}}</:default>
</AkButton>
{{/if}}
<AkButton
local-class='dynamic-scan-btn'
data-test-fileDetails-dynamicScanAction='{{this.dynamicScanActionButton.testId}}'
{{on 'click' this.dynamicScanActionButton.onClick}}
@disabled={{or (not @file.isActive) this.dynamicScanActionButton.loading}}
@variant={{this.dynamicScanActionButton.variant}}
@color={{this.dynamicScanActionButton.color}}
@loading={{this.dynamicScanActionButton.loading}}
>
<:leftIcon>
<AkIcon @iconName={{this.dynamicScanActionButton.icon}} />
</:leftIcon>

{{else if (or @file.isDynamicDone @dynamicScan.isDynamicStatusError)}}
<AkButton
local-class='dynamic-scan-btn'
data-test-fileDetails-dynamicScanAction-restartBtn
data-test-cy='dynamicScan-restartBtn'
{{on 'click' this.openDynamicScanDrawer}}
@disabled={{not @file.isActive}}
>
<:leftIcon>
<AkIcon @iconName='refresh' />
</:leftIcon>
<:default>
{{this.dynamicScanActionButton.text}}
</:default>
</AkButton>

<:default>{{@dynamicScanText}}</:default>
</AkButton>
{{else}}
<AkButton
local-class='dynamic-scan-btn'
data-test-fileDetails-dynamicScanAction-startBtn
{{on 'click' this.openDynamicScanDrawer}}
@disabled={{not @file.isActive}}
{{#if this.showDynamicScanDrawer}}
<ProjectPreferences::Provider
@profileId={{this.profileId}}
@platform={{this.projectPlatform}}
@project={{@file.project.content}}
as |dpContext|
>
<:leftIcon>
<AkIcon @iconName='play-arrow' />
</:leftIcon>

<:default>{{@dynamicScanText}}</:default>
</AkButton>
<FileDetails::DynamicScan::Action::Drawer
@onClose={{this.closeDynamicScanDrawer}}
@file={{@file}}
@dpContext={{dpContext}}
@isAutomatedScan={{@isAutomatedScan}}
@onScanStart={{@onScanStart}}
/>
</ProjectPreferences::Provider>
{{/if}}
</AkStack>

{{#if this.showDynamicScanDrawer}}
<ProjectPreferences::Provider
@profileId={{this.profileId}}
@platform={{this.projectPlatform}}
@project={{@file.project.content}}
as |dpContext|
>
<FileDetails::DynamicScan::Action::Drawer
@onClose={{this.closeDynamicScanDrawer}}
@file={{@file}}
@dpContext={{dpContext}}
@isAutomatedScan={{@isAutomatedScan}}
@onScanStart={{@onScanStart}}
/>
</ProjectPreferences::Provider>
{{/if}}
</AkStack>
50 changes: 45 additions & 5 deletions app/components/file-details/dynamic-scan/action/index.ts
Original file line number Diff line number Diff line change
Expand Up @@ -3,6 +3,7 @@ import { tracked } from '@glimmer/tracking';
import { inject as service } from '@ember/service';
import { task } from 'ember-concurrency';
import { action } from '@ember/object';
import type IntlService from 'ember-intl/services/intl';

import ENV from 'irene/config/environment';
import triggerAnalytics from 'irene/utils/trigger-analytics';
Expand All @@ -21,7 +22,7 @@ export interface DynamicScanActionSignature {
}

export default class DynamicScanActionComponent extends Component<DynamicScanActionSignature> {
@service declare ajax: any;
@service declare intl: IntlService;
@service('notifications') declare notify: NotificationService;

@tracked showDynamicScanDrawer = false;
Expand All @@ -38,6 +39,49 @@ export default class DynamicScanActionComponent extends Component<DynamicScanAct
return this.file.profile.get('id');
}

get dynamicScanActionButton() {
if (this.args.dynamicScan?.isStarting) {
return {
icon: 'close',
text: this.intl.t('cancelScan'),
testId: 'cancelBtn',
variant: 'outlined' as const,
color: 'neutral' as const,
onClick: () => this.dynamicShutdown.perform(),
loading: this.dynamicShutdown.isRunning,
};
}

if (this.args.dynamicScan?.isReadyOrRunning) {
return {
icon: 'stop-circle',
text: this.intl.t('stop'),
testId: 'stopBtn',
loading: this.dynamicShutdown.isRunning,
onClick: () => this.dynamicShutdown.perform(),
};
}

if (
this.args.dynamicScan?.isCompleted ||
this.args.dynamicScan?.isStatusError
) {
return {
icon: 'refresh',
text: this.args.dynamicScanText,
testId: 'restartBtn',
onClick: this.openDynamicScanDrawer,
};
}

return {
icon: 'play-arrow',
text: this.args.dynamicScanText,
testId: 'startBtn',
onClick: this.openDynamicScanDrawer,
};
}

@action
openDynamicScanDrawer() {
triggerAnalytics(
Expand All @@ -54,15 +98,11 @@ export default class DynamicScanActionComponent extends Component<DynamicScanAct
}

dynamicShutdown = task({ drop: true }, async () => {
this.args.dynamicScan?.setShuttingDown();

try {
await this.args.dynamicScan?.destroyRecord();

this.args.onScanShutdown?.();
} catch (error) {
this.args.dynamicScan?.setNone();

this.notify.error((error as AdapterError).payload.error);
}
});
Expand Down
3 changes: 2 additions & 1 deletion app/components/file-details/dynamic-scan/automated/index.hbs
Original file line number Diff line number Diff line change
@@ -1,4 +1,4 @@
{{#if this.fetchDynamicscan.isRunning}}
{{#if (or this.getDynamicscanMode.isRunning this.fetchDynamicscan.isRunning)}}
<AkStack
local-class='loading-container'
@alignItems='center'
Expand Down Expand Up @@ -43,6 +43,7 @@
<FileDetails::DynamicScan::Action
@file={{@file}}
@dynamicScanText={{t 'dastTabs.automatedDAST'}}
@onScanStart={{this.handleStartScan}}
@onScanShutdown={{this.handleFullscreenClose}}
@isAutomatedScan={{true}}
@dynamicScan={{this.dynamicScan}}
Expand Down
13 changes: 11 additions & 2 deletions app/components/file-details/dynamic-scan/automated/index.ts
Original file line number Diff line number Diff line change
Expand Up @@ -8,6 +8,7 @@ import type IntlService from 'ember-intl/services/intl';
import type RouterService from '@ember/routing/router-service';
import type Store from '@ember-data/store';

import ENUMS from 'irene/enums';
import parseError from 'irene/utils/parse-error';
import type DynamicscanModel from 'irene/models/dynamicscan';
import type FileModel from 'irene/models/file';
Expand Down Expand Up @@ -54,6 +55,11 @@ export default class FileDetailsDastAutomated extends Component<FileDetailsDastA
);
}

@action
handleStartScan(dynamicScan: DynamicscanModel) {
this.dynamicScan = dynamicScan;
}

getDynamicscanMode = task(async () => {
try {
const dynScanMode = await waitForPromise(
Expand All @@ -69,10 +75,13 @@ export default class FileDetailsDastAutomated extends Component<FileDetailsDastA
});

fetchDynamicscan = task(async () => {
const id = this.args.profileId;
const file = this.args.file;

try {
this.dynamicScan = await this.store.findRecord('dynamicscan', id);
this.dynamicScan = await file.getLastDynamicScan(
file.id,
ENUMS.DYNAMIC_MODE.AUTOMATED
);
} catch (e) {
this.notify.error(parseError(e, this.intl.t('pleaseTryAgain')));
}
Expand Down
31 changes: 23 additions & 8 deletions app/components/file-details/dynamic-scan/header/index.ts
Original file line number Diff line number Diff line change
Expand Up @@ -6,6 +6,16 @@ import type Store from '@ember-data/store';

import type DynamicscanModel from 'irene/models/dynamicscan';
import type FileModel from 'irene/models/file';
import type ConfigurationService from 'irene/services/configuration';

interface TabItem {
id: string;
label: string;
route: string;
activeRoutes: string;
inProgress?: boolean;
count?: number;
}

export interface FileDetailsDastHeaderSignature {
Args: {
Expand All @@ -19,6 +29,7 @@ export default class FileDetailsDastHeader extends Component<FileDetailsDastHead
@service declare intl: IntlService;
@service declare router: RouterService;
@service declare store: Store;
@service declare configuration: ConfigurationService;
@service('notifications') declare notify: NotificationService;

get file() {
Expand All @@ -37,6 +48,10 @@ export default class FileDetailsDastHeader extends Component<FileDetailsDastHead
return this.args.dynamicScan?.isRunning;
}

get orgIsAnEnterprise() {
return this.configuration.serverData.enterprise;
}

get tabs() {
return [
{
Expand All @@ -45,21 +60,21 @@ export default class FileDetailsDastHeader extends Component<FileDetailsDastHead
route: 'authenticated.dashboard.file.dynamic-scan.manual',
activeRoutes: 'authenticated.dashboard.file.dynamic-scan.manual',
},
// {
// id: 'automated-dast',
// label: this.intl.t('dastTabs.automatedDAST'),
// route: 'authenticated.dashboard.file.dynamic-scan.automated',
// activeRoutes: 'authenticated.dashboard.file.dynamic-scan.automated',
// inProgress: this.isAutomatedScanRunning,
// },
!this.orgIsAnEnterprise && {
id: 'automated-dast',
label: this.intl.t('dastTabs.automatedDAST'),
route: 'authenticated.dashboard.file.dynamic-scan.automated',
activeRoutes: 'authenticated.dashboard.file.dynamic-scan.automated',
inProgress: this.isAutomatedScanRunning,
},
{
id: 'dast-results',
label: this.intl.t('dastTabs.dastResults'),
route: 'authenticated.dashboard.file.dynamic-scan.results',
activeRoutes: 'authenticated.dashboard.file.dynamic-scan.results',
count: this.args.file.dynamicVulnerabilityCount,
},
];
].filter(Boolean) as TabItem[];
}
}

Expand Down
4 changes: 1 addition & 3 deletions app/components/file-details/dynamic-scan/manual/index.ts
Original file line number Diff line number Diff line change
Expand Up @@ -41,9 +41,7 @@ export default class FileDetailsDastManual extends Component<FileDetailsDastManu
}

get showActionButton() {
if (this.dynamicScan?.isReady || this.dynamicScan?.isStatusError) {
return true;
} else if (this.dynamicScan?.isDynamicStatusInProgress) {
if (this.dynamicScan?.isShuttingDown) {
return false;
}

Expand Down
Loading

0 comments on commit 2db1b4d

Please sign in to comment.