praetorian-cli 2.2.2__py3-none-any.whl → 2.2.4__py3-none-any.whl
This diff represents the content of publicly available package versions that have been released to one of the supported registries. The information contained in this diff is provided for informational purposes only and reflects changes between package versions as they appear in their respective public registries.
- praetorian_cli/handlers/add.py +47 -7
- praetorian_cli/handlers/cli_decorators.py +1 -1
- praetorian_cli/handlers/delete.py +15 -2
- praetorian_cli/handlers/get.py +48 -2
- praetorian_cli/handlers/link.py +29 -1
- praetorian_cli/handlers/list.py +30 -9
- praetorian_cli/handlers/unlink.py +29 -1
- praetorian_cli/handlers/update.py +3 -3
- praetorian_cli/sdk/chariot.py +6 -12
- praetorian_cli/sdk/entities/assets.py +30 -12
- praetorian_cli/sdk/entities/schema.py +27 -0
- praetorian_cli/sdk/entities/seeds.py +108 -56
- praetorian_cli/sdk/entities/webpage.py +180 -0
- praetorian_cli/sdk/mcp_server.py +2 -3
- praetorian_cli/sdk/model/globals.py +2 -0
- praetorian_cli/sdk/model/query.py +8 -1
- praetorian_cli/sdk/model/utils.py +2 -8
- praetorian_cli/sdk/test/test_asset.py +38 -2
- praetorian_cli/sdk/test/test_seed.py +13 -14
- praetorian_cli/sdk/test/test_webpage.py +46 -0
- praetorian_cli/sdk/test/test_z_cli.py +53 -24
- praetorian_cli/sdk/test/utils.py +21 -4
- {praetorian_cli-2.2.2.dist-info → praetorian_cli-2.2.4.dist-info}/METADATA +1 -1
- {praetorian_cli-2.2.2.dist-info → praetorian_cli-2.2.4.dist-info}/RECORD +28 -25
- {praetorian_cli-2.2.2.dist-info → praetorian_cli-2.2.4.dist-info}/WHEEL +0 -0
- {praetorian_cli-2.2.2.dist-info → praetorian_cli-2.2.4.dist-info}/entry_points.txt +0 -0
- {praetorian_cli-2.2.2.dist-info → praetorian_cli-2.2.4.dist-info}/licenses/LICENSE +0 -0
- {praetorian_cli-2.2.2.dist-info → praetorian_cli-2.2.4.dist-info}/top_level.txt +0 -0
praetorian_cli/handlers/add.py
CHANGED
|
@@ -29,6 +29,9 @@ def asset(sdk, name, dns, asset_type, status, surface):
|
|
|
29
29
|
Add an asset to the Chariot database. This command requires a DNS name for the asset.
|
|
30
30
|
Optionally, a name can be provided to give the asset more specific information,
|
|
31
31
|
such as IP address. If no name is provided, the DNS name will be used as the name.
|
|
32
|
+
The DNS is the group and the name is the specific identifier. This is for legacy reasons.
|
|
33
|
+
|
|
34
|
+
The type can be one of the following: asset, addomain, repository, webapplication.
|
|
32
35
|
|
|
33
36
|
\b
|
|
34
37
|
Example assets:
|
|
@@ -41,6 +44,7 @@ def asset(sdk, name, dns, asset_type, status, surface):
|
|
|
41
44
|
- praetorian chariot add asset --dns example.com
|
|
42
45
|
- praetorian chariot add asset --dns example.com --name 1.2.3.4
|
|
43
46
|
- praetorian chariot add asset --dns internal.example.com --name 10.2.3.4 --surface internal
|
|
47
|
+
- praetorian chariot add asset --dns https://example.com --name 'Example Web Application' --type webapplication
|
|
44
48
|
"""
|
|
45
49
|
if not name:
|
|
46
50
|
name = dns
|
|
@@ -196,21 +200,39 @@ def attribute(sdk, key, name, value):
|
|
|
196
200
|
|
|
197
201
|
@add.command()
|
|
198
202
|
@cli_handler
|
|
199
|
-
@click.option('-
|
|
203
|
+
@click.option('-t', '--type', 'seed_type', default='asset', help='Asset type (e.g., asset, addomain)')
|
|
200
204
|
@click.option('-s', '--status', type=click.Choice([s.value for s in Seed]),
|
|
201
205
|
default=Seed.PENDING.value, help='The status of the seed', show_default=True)
|
|
202
|
-
|
|
206
|
+
@click.option('-f', '--field', 'field_list', multiple=True,
|
|
207
|
+
help='Field in format name:value (can be specified multiple times)')
|
|
208
|
+
def seed(sdk, seed_type, status, field_list):
|
|
203
209
|
""" Add a seed
|
|
204
210
|
|
|
205
|
-
Add a seed to the Chariot database.
|
|
206
|
-
|
|
211
|
+
Add a seed to the Chariot database. Seeds are now assets with special labeling.
|
|
212
|
+
You can specify the asset type and provide dynamic fields using --fields.
|
|
207
213
|
|
|
208
214
|
\b
|
|
209
215
|
Example usages:
|
|
210
|
-
- praetorian chariot add seed --dns
|
|
211
|
-
- praetorian chariot add seed --dns
|
|
216
|
+
- praetorian chariot add seed --type asset --field dns:example.com
|
|
217
|
+
- praetorian chariot add seed --type asset --field dns:example.com --status A
|
|
218
|
+
- praetorian chariot add seed --type asset --field dns:example.com --field name:1.2.3.4
|
|
219
|
+
- praetorian chariot add seed --type addomain --field domain:corp.local --field objectid:S-1-5-21-2701466056-1043032755-2418290285
|
|
212
220
|
"""
|
|
213
|
-
|
|
221
|
+
# Collect dynamic fields from the --fields option
|
|
222
|
+
dynamic_fields = {}
|
|
223
|
+
|
|
224
|
+
# Parse field_list entries (name:value format)
|
|
225
|
+
for field in field_list:
|
|
226
|
+
if ':' in field:
|
|
227
|
+
# Split only once to allow colons in the value
|
|
228
|
+
name, value = field.split(':', 1)
|
|
229
|
+
dynamic_fields[name] = value
|
|
230
|
+
else:
|
|
231
|
+
error(f"Field '{field}' is not in the format name:value")
|
|
232
|
+
return
|
|
233
|
+
|
|
234
|
+
# Call the updated add method with type and dynamic fields
|
|
235
|
+
sdk.seeds.add(status=status, seed_type=seed_type, **dynamic_fields)
|
|
214
236
|
|
|
215
237
|
|
|
216
238
|
@add.command()
|
|
@@ -310,3 +332,21 @@ def key(sdk, name, expires):
|
|
|
310
332
|
return
|
|
311
333
|
click.echo(f'API key created: {result.get("key", "N/A")}')
|
|
312
334
|
click.echo(f'Secret (save this, it will not be shown again): {result["secret"]}')
|
|
335
|
+
|
|
336
|
+
|
|
337
|
+
@add.command()
|
|
338
|
+
@cli_handler
|
|
339
|
+
@click.option('-u', '--url', required=True, help='The full URL of the page')
|
|
340
|
+
@click.option('-p', '--parent', required=False, help='Optional key of the parent WebApplication')
|
|
341
|
+
def webpage(sdk, url, parent):
|
|
342
|
+
""" Add a Webpage
|
|
343
|
+
|
|
344
|
+
Add a web page to the Chariot database. Webpages can optionally be associated
|
|
345
|
+
with a parent WebApplication or exist independently.
|
|
346
|
+
|
|
347
|
+
\b
|
|
348
|
+
Example usages:
|
|
349
|
+
- praetorian chariot add webpage --url https://app.example.com/login
|
|
350
|
+
- praetorian chariot add webpage --url https://app.example.com/admin --parent "#webapplication#https://app.example.com"
|
|
351
|
+
"""
|
|
352
|
+
sdk.webpage.add(url, parent)
|
|
@@ -68,7 +68,7 @@ def list_params(filter_by, has_details=True, has_filter=True, has_type=False):
|
|
|
68
68
|
|
|
69
69
|
|
|
70
70
|
def pagination(func):
|
|
71
|
-
func = click.option('-o', '--offset', default=
|
|
71
|
+
func = click.option('-o', '--offset', default=0, help='List results from an offset')(func)
|
|
72
72
|
func = click.option('-p', '--page', type=click.Choice(('first', 'all')), default='first',
|
|
73
73
|
help='Pagination mode. "all" pages up to 10,000 pages.', show_default=True)(func)
|
|
74
74
|
return func
|
|
@@ -88,11 +88,12 @@ def seed(chariot, key):
|
|
|
88
88
|
|
|
89
89
|
\b
|
|
90
90
|
Arguments:
|
|
91
|
-
- KEY: the key of an existing seed
|
|
91
|
+
- KEY: the key of an existing seed (now uses asset key format)
|
|
92
92
|
|
|
93
93
|
\b
|
|
94
94
|
Example usage:
|
|
95
|
-
- praetorian chariot delete seed "#
|
|
95
|
+
- praetorian chariot delete seed "#asset#example.com#example.com"
|
|
96
|
+
- praetorian chariot delete seed "#addomain#corp.local#corp.local"
|
|
96
97
|
"""
|
|
97
98
|
chariot.seeds.delete(key)
|
|
98
99
|
|
|
@@ -181,3 +182,15 @@ def key(chariot, key):
|
|
|
181
182
|
- praetorian chariot delete key "#key#550e8400-e29b-41d4-a716-446655440000"
|
|
182
183
|
"""
|
|
183
184
|
chariot.keys.delete(key)
|
|
185
|
+
|
|
186
|
+
@delete.command()
|
|
187
|
+
@cli_handler
|
|
188
|
+
@click.argument('key', required=True)
|
|
189
|
+
def webpage(chariot, key):
|
|
190
|
+
""" Delete a webpage
|
|
191
|
+
|
|
192
|
+
\b
|
|
193
|
+
Arguments:
|
|
194
|
+
- KEY: the key of an existing webpage
|
|
195
|
+
"""
|
|
196
|
+
chariot.webpage.delete(key)
|
praetorian_cli/handlers/get.py
CHANGED
|
@@ -186,11 +186,12 @@ def seed(chariot, key):
|
|
|
186
186
|
|
|
187
187
|
\b
|
|
188
188
|
Argument:
|
|
189
|
-
- KEY: the key of an existing
|
|
189
|
+
- KEY: the key of an existing seed (now uses asset key format)
|
|
190
190
|
|
|
191
191
|
\b
|
|
192
192
|
Example usages:
|
|
193
|
-
- praetorian chariot get
|
|
193
|
+
- praetorian chariot get seed "#asset#example.com#example.com"
|
|
194
|
+
- praetorian chariot get seed "#addomain#corp.local#corp.local"
|
|
194
195
|
"""
|
|
195
196
|
print_json(chariot.seeds.get(key))
|
|
196
197
|
|
|
@@ -295,3 +296,48 @@ def scanner(chariot, key):
|
|
|
295
296
|
- praetorian chariot get scanner "#scanner#127.0.0.1"
|
|
296
297
|
"""
|
|
297
298
|
print_json(chariot.scanners.get(key))
|
|
299
|
+
|
|
300
|
+
|
|
301
|
+
@get.command()
|
|
302
|
+
@cli_handler
|
|
303
|
+
@click.argument('key', required=True)
|
|
304
|
+
def webpage(chariot, key):
|
|
305
|
+
""" Get Webpage details
|
|
306
|
+
|
|
307
|
+
Retrieve detailed information about a specific web page, including
|
|
308
|
+
its URL, method, authentication requirements, and other metadata.
|
|
309
|
+
|
|
310
|
+
\b
|
|
311
|
+
Argument:
|
|
312
|
+
- KEY: the key of an existing Webpage
|
|
313
|
+
|
|
314
|
+
\b
|
|
315
|
+
Example usages:
|
|
316
|
+
- praetorian chariot get webpage "#webpage#https://app.example.com/dashboard"
|
|
317
|
+
"""
|
|
318
|
+
print_json(chariot.webpage.get(key))
|
|
319
|
+
|
|
320
|
+
@click.option('-t', '--type', help='Optional specific entity type (e.g., asset, risk, attribute)')
|
|
321
|
+
@click.option('-d', '--details', is_flag=True, help='Further retrieve the details of the schema')
|
|
322
|
+
def schema(chariot, type, details):
|
|
323
|
+
""" Get Chariot entity schema
|
|
324
|
+
|
|
325
|
+
\b
|
|
326
|
+
Returns the JSON schema for Chariot entities. Optionally filter for a
|
|
327
|
+
specific entity type.
|
|
328
|
+
|
|
329
|
+
\b
|
|
330
|
+
Example usages:
|
|
331
|
+
- praetorian chariot get schema
|
|
332
|
+
- praetorian chariot get schema --type asset
|
|
333
|
+
- praetorian chariot get schema --type asset --details
|
|
334
|
+
"""
|
|
335
|
+
data = chariot.schema.get(type)
|
|
336
|
+
if type:
|
|
337
|
+
data = {type: data[type]}
|
|
338
|
+
|
|
339
|
+
if details:
|
|
340
|
+
print_json(data)
|
|
341
|
+
else:
|
|
342
|
+
for hit in data:
|
|
343
|
+
click.echo(hit)
|
praetorian_cli/handlers/link.py
CHANGED
|
@@ -6,7 +6,7 @@ from praetorian_cli.handlers.cli_decorators import cli_handler
|
|
|
6
6
|
|
|
7
7
|
@chariot.group()
|
|
8
8
|
def link():
|
|
9
|
-
"""
|
|
9
|
+
""" Link resources to other entities """
|
|
10
10
|
pass
|
|
11
11
|
|
|
12
12
|
|
|
@@ -30,3 +30,31 @@ def account(chariot, username):
|
|
|
30
30
|
- praetorian chariot link account john@praetorian.com
|
|
31
31
|
"""
|
|
32
32
|
chariot.accounts.add_collaborator(username)
|
|
33
|
+
|
|
34
|
+
|
|
35
|
+
@link.command('webpage-source')
|
|
36
|
+
@cli_handler
|
|
37
|
+
@click.argument('webpage_key')
|
|
38
|
+
@click.argument('entity_key')
|
|
39
|
+
def webpage_source(chariot, webpage_key, entity_key):
|
|
40
|
+
""" Link a file or repository to a webpage as source code
|
|
41
|
+
|
|
42
|
+
This associates source code files or repositories with webpages
|
|
43
|
+
to track where webpage content originates from.
|
|
44
|
+
|
|
45
|
+
\b
|
|
46
|
+
Arguments:
|
|
47
|
+
- WEBPAGE_KEY: The webpage key in format #webpage#{url}
|
|
48
|
+
- ENTITY_KEY: The file or repository key to link
|
|
49
|
+
Format: #file#{path} or #repository#{url}#{name}
|
|
50
|
+
|
|
51
|
+
\b
|
|
52
|
+
Example usages:
|
|
53
|
+
- praetorian chariot link webpage-source "#webpage#https://example.com" "#file#proofs/scan.txt"
|
|
54
|
+
- praetorian chariot link webpage-source "#webpage#https://example.com/login" "#repository#https://github.com/org/repo.git#repo.git"
|
|
55
|
+
"""
|
|
56
|
+
result = chariot.webpage.link_source(webpage_key, entity_key)
|
|
57
|
+
if result:
|
|
58
|
+
click.echo(f"Successfully linked {entity_key} to {webpage_key}")
|
|
59
|
+
if 'artifacts' in result:
|
|
60
|
+
click.echo(f"Webpage now has {len(result['artifacts'])} linked artifacts")
|
praetorian_cli/handlers/list.py
CHANGED
|
@@ -26,7 +26,7 @@ def assets(chariot, filter, model_type, details, offset, page):
|
|
|
26
26
|
- praetorian chariot list assets --page all
|
|
27
27
|
- praetorian chariot list assets --type repository
|
|
28
28
|
"""
|
|
29
|
-
render_list_results(chariot.assets.list(filter, model_type,
|
|
29
|
+
render_list_results(chariot.assets.list(filter, model_type, pagination_size(page)), details)
|
|
30
30
|
|
|
31
31
|
|
|
32
32
|
@list.command()
|
|
@@ -178,24 +178,23 @@ def attributes(chariot, filter, key, details, offset, page):
|
|
|
178
178
|
|
|
179
179
|
@list.command()
|
|
180
180
|
@list_params('DNS')
|
|
181
|
-
@click.option('-t', '--type',
|
|
181
|
+
@click.option('-t', '--type', help='Filter by seed type (e.g., asset, addomain)')
|
|
182
182
|
def seeds(chariot, type, filter, details, offset, page):
|
|
183
183
|
""" List seeds
|
|
184
184
|
|
|
185
|
-
Retrieve and display a list of seeds.
|
|
185
|
+
Retrieve and display a list of seeds. Seeds are now assets with the 'Seed' label.
|
|
186
186
|
|
|
187
187
|
\b
|
|
188
188
|
Example usages:
|
|
189
189
|
- praetorian chariot list seeds
|
|
190
|
-
- praetorian chariot list seeds --type
|
|
191
|
-
- praetorian chariot list seeds --type
|
|
190
|
+
- praetorian chariot list seeds --type asset
|
|
191
|
+
- praetorian chariot list seeds --type addomain
|
|
192
|
+
- praetorian chariot list seeds --type asset --filter example.com
|
|
192
193
|
- praetorian chariot list seeds --details
|
|
193
194
|
- praetorian chariot list seeds --page all
|
|
194
195
|
"""
|
|
195
|
-
|
|
196
|
-
|
|
197
|
-
|
|
198
|
-
render_list_results(chariot.seeds.list(type, filter, offset, pagination_size(page)), details)
|
|
196
|
+
# Note: filter restriction removed since we're using different key format now
|
|
197
|
+
render_list_results(chariot.seeds.list(type, filter, pagination_size(page)), details)
|
|
199
198
|
|
|
200
199
|
|
|
201
200
|
@list.command()
|
|
@@ -369,3 +368,25 @@ def scanners(chariot, filter, details, offset, page):
|
|
|
369
368
|
- praetorian chariot list scanners --page all
|
|
370
369
|
"""
|
|
371
370
|
render_list_results(chariot.scanners.list(filter, offset, pagination_size(page)), details)
|
|
371
|
+
|
|
372
|
+
|
|
373
|
+
@list.command()
|
|
374
|
+
@click.option('--parent', required=False, help='Optional WebApp key to filter pages')
|
|
375
|
+
@click.option('-f', '--filter', required=False, help='Optional URL to filter pages')
|
|
376
|
+
@click.option('-d', '--details', is_flag=True, default=False, help='Show detailed information')
|
|
377
|
+
@pagination
|
|
378
|
+
@cli_handler
|
|
379
|
+
def webpages(chariot, parent, filter, details, offset, page):
|
|
380
|
+
""" List WebPages
|
|
381
|
+
|
|
382
|
+
Retrieve and display a list of pages/URLs. Can optionally filter by specific WebApplication.
|
|
383
|
+
|
|
384
|
+
\b
|
|
385
|
+
Example usages:
|
|
386
|
+
- praetorian chariot list webpages
|
|
387
|
+
- praetorian chariot list webpages --parent "#webapplication#https://app.example.com"
|
|
388
|
+
- praetorian chariot list webpages --filter /login
|
|
389
|
+
- praetorian chariot list webpages --parent "#webapplication#https://app.example.com" --details
|
|
390
|
+
- praetorian chariot list webpages --page all
|
|
391
|
+
"""
|
|
392
|
+
render_list_results(chariot.webpage.list(parent, filter, offset, pagination_size(page)), details)
|
|
@@ -6,7 +6,7 @@ from praetorian_cli.handlers.cli_decorators import cli_handler
|
|
|
6
6
|
|
|
7
7
|
@chariot.group()
|
|
8
8
|
def unlink():
|
|
9
|
-
""" Remove
|
|
9
|
+
""" Remove links between resources """
|
|
10
10
|
pass
|
|
11
11
|
|
|
12
12
|
|
|
@@ -25,3 +25,31 @@ def account(chariot, username):
|
|
|
25
25
|
- praetorian chariot unlink account john@praetorian.com
|
|
26
26
|
"""
|
|
27
27
|
chariot.accounts.delete_collaborator(username)
|
|
28
|
+
|
|
29
|
+
|
|
30
|
+
@unlink.command('webpage-source')
|
|
31
|
+
@cli_handler
|
|
32
|
+
@click.argument('webpage_key')
|
|
33
|
+
@click.argument('entity_key')
|
|
34
|
+
def webpage_source(chariot, webpage_key, entity_key):
|
|
35
|
+
""" Unlink a file or repository from a webpage's source code
|
|
36
|
+
|
|
37
|
+
This removes the association between source code files or
|
|
38
|
+
repositories and webpages.
|
|
39
|
+
|
|
40
|
+
\b
|
|
41
|
+
Arguments:
|
|
42
|
+
- WEBPAGE_KEY: The webpage key in format #webpage#{url}
|
|
43
|
+
- ENTITY_KEY: The file or repository key to unlink
|
|
44
|
+
Format: #file#{path} or #repository#{url}#{name}
|
|
45
|
+
|
|
46
|
+
\b
|
|
47
|
+
Example usages:
|
|
48
|
+
- praetorian chariot unlink webpage-source "#webpage#https://example.com" "#file#proofs/scan.txt"
|
|
49
|
+
- praetorian chariot unlink webpage-source "#webpage#https://example.com/login" "#repository#https://github.com/org/repo.git#repo.git"
|
|
50
|
+
"""
|
|
51
|
+
result = chariot.webpage.unlink_source(webpage_key, entity_key)
|
|
52
|
+
if result:
|
|
53
|
+
click.echo(f"Successfully unlinked {entity_key} from {webpage_key}")
|
|
54
|
+
if 'artifacts' in result:
|
|
55
|
+
click.echo(f"Webpage now has {len(result['artifacts'])} linked artifacts")
|
|
@@ -65,12 +65,12 @@ def seed(chariot, key, status):
|
|
|
65
65
|
|
|
66
66
|
\b
|
|
67
67
|
Example usages:
|
|
68
|
-
- praetorian chariot update seed "#
|
|
69
|
-
- praetorian chariot update seed "#
|
|
68
|
+
- praetorian chariot update seed "#asset#example.com#example.com" -s A
|
|
69
|
+
- praetorian chariot update seed "#asset#1.1.1.0/24#1.1.1.0/24" -s F
|
|
70
70
|
"""
|
|
71
|
+
|
|
71
72
|
chariot.seeds.update(key, status)
|
|
72
73
|
|
|
73
|
-
|
|
74
74
|
@update.command()
|
|
75
75
|
@cli_handler
|
|
76
76
|
@click.argument('key', required=True)
|
praetorian_cli/sdk/chariot.py
CHANGED
|
@@ -16,10 +16,12 @@ from praetorian_cli.sdk.entities.keys import Keys
|
|
|
16
16
|
from praetorian_cli.sdk.entities.preseeds import Preseeds
|
|
17
17
|
from praetorian_cli.sdk.entities.risks import Risks
|
|
18
18
|
from praetorian_cli.sdk.entities.scanners import Scanners
|
|
19
|
+
from praetorian_cli.sdk.entities.schema import Schema
|
|
19
20
|
from praetorian_cli.sdk.entities.search import Search
|
|
20
21
|
from praetorian_cli.sdk.entities.seeds import Seeds
|
|
21
22
|
from praetorian_cli.sdk.entities.settings import Settings
|
|
22
23
|
from praetorian_cli.sdk.entities.statistics import Statistics
|
|
24
|
+
from praetorian_cli.sdk.entities.webpage import Webpage
|
|
23
25
|
from praetorian_cli.sdk.entities.webhook import Webhook
|
|
24
26
|
from praetorian_cli.sdk.keychain import Keychain
|
|
25
27
|
from praetorian_cli.sdk.model.globals import GLOBAL_FLAG
|
|
@@ -51,6 +53,8 @@ class Chariot:
|
|
|
51
53
|
self.keys = Keys(self)
|
|
52
54
|
self.capabilities = Capabilities(self)
|
|
53
55
|
self.credentials = Credentials(self)
|
|
56
|
+
self.webpage = Webpage(self)
|
|
57
|
+
self.schema = Schema(self)
|
|
54
58
|
self.proxy = proxy
|
|
55
59
|
|
|
56
60
|
if self.proxy == '' and os.environ.get('CHARIOT_PROXY'):
|
|
@@ -70,26 +74,16 @@ class Chariot:
|
|
|
70
74
|
kwargs['proxies'] = {'http': self.proxy, 'https': self.proxy}
|
|
71
75
|
kwargs['verify'] = False
|
|
72
76
|
|
|
73
|
-
self.
|
|
77
|
+
self.add_beta_url_param(kwargs)
|
|
74
78
|
|
|
75
79
|
return requests.request(method, url, headers=self.keychain.headers(), **kwargs)
|
|
76
80
|
|
|
77
|
-
def
|
|
78
|
-
if method == 'GET' or method == 'DELETE':
|
|
79
|
-
self._add_beta_url_param(kwargs)
|
|
80
|
-
else:
|
|
81
|
-
self._add_beta_json_param(kwargs)
|
|
82
|
-
|
|
83
|
-
def _add_beta_url_param(self, kwargs: dict):
|
|
81
|
+
def add_beta_url_param(self, kwargs: dict):
|
|
84
82
|
if 'params' in kwargs:
|
|
85
83
|
kwargs['params']['beta'] = 'true'
|
|
86
84
|
else:
|
|
87
85
|
kwargs['params'] = {'beta': 'true'}
|
|
88
86
|
|
|
89
|
-
def _add_beta_json_param(self, kwargs: dict):
|
|
90
|
-
if 'json' in kwargs:
|
|
91
|
-
kwargs['json']['beta'] = True
|
|
92
|
-
|
|
93
87
|
def my(self, params: dict, pages=1) -> dict:
|
|
94
88
|
final_resp = dict()
|
|
95
89
|
|
|
@@ -1,5 +1,6 @@
|
|
|
1
|
+
from praetorian_cli.handlers.utils import error
|
|
1
2
|
from praetorian_cli.sdk.model.globals import Asset, Kind
|
|
2
|
-
from praetorian_cli.sdk.model.query import Relationship, Node, Query, asset_of_key, RISK_NODE, ATTRIBUTE_NODE
|
|
3
|
+
from praetorian_cli.sdk.model.query import Relationship, Node, Query, Filter, KIND_TO_LABEL, asset_of_key, RISK_NODE, ATTRIBUTE_NODE
|
|
3
4
|
|
|
4
5
|
|
|
5
6
|
class Assets:
|
|
@@ -76,27 +77,44 @@ class Assets:
|
|
|
76
77
|
"""
|
|
77
78
|
return self.api.delete_by_key('asset', key)
|
|
78
79
|
|
|
79
|
-
def list(self,
|
|
80
|
+
def list(self, key_prefix='', asset_type='', pages=100000) -> tuple:
|
|
80
81
|
"""
|
|
81
82
|
List assets.
|
|
82
83
|
|
|
83
|
-
:param
|
|
84
|
-
:type
|
|
84
|
+
:param key_prefix: Supply this to perform prefix-filtering of the asset key. E.g., '#asset#example.com' or '#addomain#sevenkingdoms'
|
|
85
|
+
:type key_prefix: str
|
|
85
86
|
:param asset_type: The type of asset to filter by
|
|
86
87
|
:type asset_type: str
|
|
87
|
-
:param offset: The offset of the page you want to retrieve results. If this is not supplied, this function retrieves from the first page
|
|
88
|
-
:type offset: str or None
|
|
89
88
|
:param pages: The number of pages of results to retrieve. <mcp>Start with one page of results unless specifically requested.</mcp>
|
|
90
89
|
:type pages: int
|
|
91
90
|
:return: A tuple containing (list of assets, next page offset)
|
|
92
91
|
:rtype: tuple
|
|
93
92
|
"""
|
|
94
|
-
|
|
95
|
-
if
|
|
96
|
-
|
|
97
|
-
|
|
98
|
-
asset_type =
|
|
99
|
-
|
|
93
|
+
|
|
94
|
+
if asset_type in KIND_TO_LABEL:
|
|
95
|
+
asset_type = KIND_TO_LABEL[asset_type]
|
|
96
|
+
elif not asset_type:
|
|
97
|
+
asset_type = Node.Label.ASSET
|
|
98
|
+
else:
|
|
99
|
+
raise ValueError(f'Invalid asset type: {asset_type}')
|
|
100
|
+
|
|
101
|
+
node = Node(
|
|
102
|
+
labels=[asset_type],
|
|
103
|
+
filters=[]
|
|
104
|
+
)
|
|
105
|
+
|
|
106
|
+
key_filter = Filter(
|
|
107
|
+
field=Filter.Field.KEY,
|
|
108
|
+
operator=Filter.Operator.STARTS_WITH,
|
|
109
|
+
value=key_prefix
|
|
110
|
+
)
|
|
111
|
+
|
|
112
|
+
if key_prefix:
|
|
113
|
+
node.filters.append(key_filter)
|
|
114
|
+
|
|
115
|
+
query = Query(node=node)
|
|
116
|
+
|
|
117
|
+
return self.api.search.by_query(query, pages)
|
|
100
118
|
|
|
101
119
|
def attributes(self, key):
|
|
102
120
|
"""
|
|
@@ -0,0 +1,27 @@
|
|
|
1
|
+
class Schema:
|
|
2
|
+
"""Access Chariot entity schemas via the SDK.
|
|
3
|
+
|
|
4
|
+
Methods in this class are accessed from `sdk.schema`, where `sdk` is an
|
|
5
|
+
instance of `Chariot`.
|
|
6
|
+
"""
|
|
7
|
+
|
|
8
|
+
def __init__(self, api):
|
|
9
|
+
self.api = api
|
|
10
|
+
|
|
11
|
+
def get(self, entity_type: str | None = None) -> dict:
|
|
12
|
+
"""Get schema information for entity types.
|
|
13
|
+
|
|
14
|
+
Args:
|
|
15
|
+
entity_type: Optional specific entity type. If provided and it exists,
|
|
16
|
+
only that schema is returned. If not provided, all schemas are returned.
|
|
17
|
+
|
|
18
|
+
Returns:
|
|
19
|
+
dict: Schema information.
|
|
20
|
+
"""
|
|
21
|
+
result = self.api.get('schema', )
|
|
22
|
+
if entity_type:
|
|
23
|
+
if entity_type not in result:
|
|
24
|
+
return {}
|
|
25
|
+
return {entity_type: result[entity_type]}
|
|
26
|
+
return result
|
|
27
|
+
|