Skip to content

Commit

Permalink
feat: add restart discovery functionality
Browse files Browse the repository at this point in the history
  • Loading branch information
bramkor committed Dec 17, 2024
1 parent 5ae04c1 commit 7561e27
Show file tree
Hide file tree
Showing 4 changed files with 106 additions and 31 deletions.
17 changes: 17 additions & 0 deletions .github/workflows/test.yml
Original file line number Diff line number Diff line change
Expand Up @@ -44,3 +44,20 @@ jobs:
discovery_id: ${{ steps.discovery.outputs.id }}
project_id: ${{ vars.PROJECT_ID }}
hostname: ${{ vars.HOSTNAME }}
- name: Rerun Bright Discovery 🏁
id: discovery-rerun
uses: ./release
with:
api_token: ${{ secrets.BRIGHTSEC_TOKEN }}
name: GitHub discovery rerun ${{ github.sha }}
project_id: ${{ vars.PROJECT_ID }}
hostname: ${{ vars.HOSTNAME }}
restart_discovery_id: ${{ steps.discovery.outputs.id }}
- name: Stop the discovery 🛑
id: stop
uses: NeuraLegion/stop-discovery@release
with:
api_token: ${{ secrets.BRIGHTSEC_TOKEN }}
discovery_id: ${{ steps.discovery-rerun.outputs.id }}
project_id: ${{ vars.PROJECT_ID }}
hostname: ${{ vars.HOSTNAME }}
10 changes: 9 additions & 1 deletion README.md
Original file line number Diff line number Diff line change
Expand Up @@ -54,10 +54,18 @@ _Example:_ `api_token: ${{ secrets.BRIGHTSEC_TOKEN }}`

### `project_id`

Provide project-id for the discovery.
**Required**. Provide project-id for the discovery.

_Example:_ `project_id: ${{ vars.PROJECT_ID }}`

### `restart_discovery_id`

**Required** when restarting an existing discovery by its ID.

Please make sure to only use the necessary parameters. Otherwise, you will get a response with the parameter usage requirements.

_Example:_ `restart_discovery_id: ai3LG8DmVn9Rn1YeqCNRGQ)`

### `discovery_types`

**Required**. Array of discovery types. The following types are available:
Expand Down
3 changes: 3 additions & 0 deletions action.yml
Original file line number Diff line number Diff line change
Expand Up @@ -7,6 +7,9 @@ inputs:
api_token:
description: 'Api Token. You can generate it in Organization section'
required: true
restart_discovery_id:
description: 'Discovery ID to restart'
required: false
hostname:
description: 'Hostname. Default is app.brighsec.com'
required: false
Expand Down
107 changes: 77 additions & 30 deletions src/index.ts
Original file line number Diff line number Diff line change
Expand Up @@ -22,6 +22,7 @@ const getArray = <T = string>(inputName: string): T[] | undefined => {
const apiToken = core.getInput('api_token', { required: true });
const name = core.getInput('name');
const projectId = core.getInput('project_id');
const restartDiscoveryId = core.getInput('restart_discovery_id');
const authObjectId = core.getInput('auth_object_id');
const fileId = core.getInput('file_id');
const crawlerUrls = getArray('crawler_urls');
Expand All @@ -35,7 +36,7 @@ const subdomainsCrawl =
const maxInteractionsChainLength =
parseInt(core.getInput('interactions_depth'), 10) || 3;
const optimizedCrawler =
(core.getInput('smart') || 'false').toLowerCase() === 'true';
(core.getInput('smart') || 'true').toLowerCase() === 'true';
const repeaters = getArray('repeaters');

const baseUrl = hostname ? `https://${hostname}` : 'https://app.brightsec.com';
Expand All @@ -46,6 +47,27 @@ const client = new HttpClient('GitHub Actions', [], {
headers: { authorization: `Api-Key ${apiToken}` }
});

const rerun = async (uuid: string, discoveryName?: string) => {
try {
const response = await client.postJson<DiscoveryID>(
`${baseUrl}/api/v2/projects/${projectId}/discoveries/${uuid}/rerun`,
{ name: discoveryName || 'GitHub Actions' }
);

if (response.statusCode < 300 && response.result) {
const { result } = response;
const url = `${baseUrl}/api/v2/projects/${projectId}/discoveries/${result.id}`;

core.setOutput('url', url);
core.setOutput('id', result.id);
} else {
core.setFailed(`Failed retest. Status code: ${response.statusCode}`);
}
} catch (err: any) {
core.setFailed(`Failed (${err.statusCode}) ${err.message}`);
}
};

const create = async (discoveryConfig: Config) => {
try {
const response = await client.postJson<DiscoveryID>(
Expand All @@ -69,35 +91,60 @@ const create = async (discoveryConfig: Config) => {
}
};

const discoveryTypes = !discoveryTypesIn?.length
? [Discovery.ARCHIVE]
: discoveryTypesIn;
const config: Config = {
name,
discoveryTypes,
subdomainsCrawl,
maxInteractionsChainLength,
poolSize,
optimizedCrawler,
...(authObjectId ? { authObjectId } : {}),
...(repeaters ? { repeaters } : {}),
...(crawlerUrls ? { crawlerUrls } : {}),
...(fileId ? { fileId } : {}),
...(hostsFilter?.length ? { hostsFilter } : {}),
...(excludedEntryPoints?.length
? {
exclusions: {
requests: excludedEntryPoints
if (restartDiscoveryId) {
if (
!(
fileId ||
projectId ||
crawlerUrls ||
discoveryTypesIn ||
hostsFilter ||
authObjectId ||
repeaters ||
excludedEntryPoints ||
subdomainsCrawl ||
maxInteractionsChainLength ||
poolSize ||
optimizedCrawler
)
) {
rerun(restartDiscoveryId, name);
} else {
core.setFailed(
"You don't need parameters, other than api_token, restart_discovery_id, project_id and name, if you just want to rerun an existing discovery"
);
}
} else {
const discoveryTypes = !discoveryTypesIn?.length
? [Discovery.ARCHIVE]
: discoveryTypesIn;
const config: Config = {
name,
discoveryTypes,
subdomainsCrawl,
maxInteractionsChainLength,
poolSize,
optimizedCrawler,
...(authObjectId ? { authObjectId } : {}),
...(repeaters ? { repeaters } : {}),
...(crawlerUrls ? { crawlerUrls } : {}),
...(fileId ? { fileId } : {}),
...(hostsFilter?.length ? { hostsFilter } : {}),
...(excludedEntryPoints?.length
? {
exclusions: {
requests: excludedEntryPoints
}
}
}
: {})
};
: {})
};

try {
validateConfig(config);
} catch (e: any) {
core.setFailed(e.message);
throw e;
}
try {
validateConfig(config);
} catch (e: any) {
core.setFailed(e.message);
throw e;
}

create(config);
create(config);
}

0 comments on commit 7561e27

Please sign in to comment.