Skip to content
New issue

Have a question about this project? Sign up for a free GitHub account to open an issue and contact its maintainers and the community.

By clicking “Sign up for GitHub”, you agree to our terms of service and privacy statement. We’ll occasionally send you account related emails.

Already on GitHub? Sign in to your account

Handle existing Boefje name #3573

Merged
merged 181 commits into from
Oct 2, 2024
Merged
Show file tree
Hide file tree
Changes from all commits
Commits
Show all changes
181 commits
Select commit Hold shift + click to select a range
7f5b70c
Init boefje setup page
madelondohmen Aug 14, 2024
af53653
Update form
madelondohmen Aug 19, 2024
8d8fe18
Update form page
madelondohmen Aug 20, 2024
4dee801
Update boefje detail page
madelondohmen Aug 20, 2024
32748b1
Update settings section
madelondohmen Aug 20, 2024
cc3229c
Add container image section
madelondohmen Aug 20, 2024
35a7374
Changes on boefje detail page
madelondohmen Aug 20, 2024
9e317eb
Merge remote-tracking branch 'origin/main' into feature/add-new-boefje
madelondohmen Aug 22, 2024
c815078
Merge branch 'main' into feature/add-new-boefje
madelondohmen Aug 22, 2024
b7c2023
Update boefje setup form
madelondohmen Aug 22, 2024
23be912
Handle form submit
madelondohmen Aug 22, 2024
e9ddf34
Small fixes
madelondohmen Aug 23, 2024
e67af07
Add produces
madelondohmen Aug 23, 2024
dd4cb49
Fix empty section on boefje detail page
madelondohmen Aug 23, 2024
88791f3
Update translations
madelondohmen Aug 23, 2024
c429a72
Merge branch 'main' into feature/add-new-boefje
madelondohmen Aug 23, 2024
c9ca645
Add boefje permission
madelondohmen Aug 26, 2024
b9ffb9b
Small changes
madelondohmen Aug 26, 2024
3232249
Update schema help text
madelondohmen Aug 26, 2024
ce4efa0
Fix parse_boefje
madelondohmen Aug 26, 2024
c55e1e1
Handle wrong schema input
madelondohmen Aug 26, 2024
8bc48f3
Update tests
madelondohmen Aug 26, 2024
00d0181
Small fixes
madelondohmen Aug 27, 2024
bde6c8e
Fixing type and create_plugin
madelondohmen Aug 27, 2024
0a6d501
Fix create_plugin
madelondohmen Aug 28, 2024
30e38f6
Fixes in form_valid
madelondohmen Aug 28, 2024
f8d7350
Fix produces section when data is empty
madelondohmen Aug 28, 2024
2ebf22c
Merge branch 'main' into feature/add-new-boefje
madelondohmen Aug 28, 2024
bad59c9
Create new variant boefjes
madelondohmen Aug 29, 2024
23e519c
Add explanation
madelondohmen Aug 29, 2024
cc5452d
Small changes
madelondohmen Aug 29, 2024
af692ec
Fix redirect to original boefje page
madelondohmen Aug 29, 2024
2a74e4a
Only show container section if present
madelondohmen Aug 29, 2024
f193ef0
Add explanation
madelondohmen Aug 29, 2024
1442788
Only show container section if present
madelondohmen Aug 29, 2024
71fe36b
Remove empty documentation url
madelondohmen Aug 29, 2024
14cc84c
Fix tests
madelondohmen Aug 29, 2024
e5690f9
Update helper texts in setup form
madelondohmen Sep 2, 2024
d05ea69
Change 'mimetypes' to 'mime types'
madelondohmen Sep 2, 2024
db0d503
Update translations
madelondohmen Sep 2, 2024
ef1977c
Fix running a newly created boefje: use the mime-types and do not onl…
Donnype Sep 2, 2024
bc107ae
Update boefje detail page
madelondohmen Sep 3, 2024
dd18964
Add API to filter on oci_image
Donnype Sep 3, 2024
9eb24c5
Update produces helper text
madelondohmen Sep 3, 2024
6609c74
Merge branch 'main' into feature/add-new-boefje
madelondohmen Sep 3, 2024
2da33ba
Add variants to boefje details page
madelondohmen Sep 3, 2024
d09bb1c
Merge branch 'main' into feature/add-new-boefje
madelondohmen Sep 4, 2024
e62c2d5
Styling fixes in boefje detail page
madelondohmen Sep 4, 2024
8551aff
Update boefje setup form
madelondohmen Sep 4, 2024
125c72b
Boefje setup fixes
madelondohmen Sep 4, 2024
e6f22c4
Add enabled disabled tags
madelondohmen Sep 4, 2024
7c3520d
Add new variant created confirmation
madelondohmen Sep 4, 2024
ae10b60
Update translations
madelondohmen Sep 4, 2024
2489404
Merge branch 'main' into feature/add-new-boefje
madelondohmen Sep 4, 2024
32d5281
Merge branch 'feature/add-new-boefje' into feature/duplicate-boefje
madelondohmen Sep 4, 2024
95ca510
Update translations
madelondohmen Sep 4, 2024
66a56d6
Fix tests
madelondohmen Sep 4, 2024
9533b8a
Merge branch 'main' into feature/add-new-boefje
madelondohmen Sep 5, 2024
8d36d78
Merge branch 'main' into feature/add-new-boefje
Donnype Sep 5, 2024
4adee5d
Merge branch 'main' into feature/add-new-boefje
madelondohmen Sep 9, 2024
a2c77cf
Fix merge conflicts for environment keys
Donnype Sep 9, 2024
1ed5a90
Merge branch 'feature/add-new-boefje' into feature/update-boefje
madelondohmen Sep 9, 2024
1719238
Merge branch 'main' into feature/add-new-boefje
Donnype Sep 9, 2024
7d65b09
Show boefje name in normalizer task table
madelondohmen Sep 10, 2024
55dd63b
Edit boefje variants
madelondohmen Sep 10, 2024
5950871
Merge branch 'main' into feature/add-new-boefje
madelondohmen Sep 10, 2024
5ee198f
Code improvements
madelondohmen Sep 10, 2024
fb895a5
Code improvements
madelondohmen Sep 10, 2024
753ebf7
Fix patching the scan profile field and refactor the SQLAlchemy patch…
Donnype Sep 10, 2024
bb26db4
Merge branch 'feature/add-new-boefje' into feature/duplicate-boefje
madelondohmen Sep 10, 2024
83ac05f
Merge branch 'feature/duplicate-boefje' into feature/update-boefje
madelondohmen Sep 10, 2024
61c8071
Merge branch 'main' into feature/duplicate-boefje
madelondohmen Sep 11, 2024
0b75cfa
Merge branch 'feature/duplicate-boefje' into feature/update-boefje
madelondohmen Sep 11, 2024
182bf17
Merge branch 'main' into feature/duplicate-boefje
madelondohmen Sep 11, 2024
36e55d8
Undo changes in layout of consumes and produces on boefje detail page
madelondohmen Sep 11, 2024
b565eb7
Merge branch 'feature/duplicate-boefje' of https://github.com/minvws/…
madelondohmen Sep 11, 2024
b088ba7
Update notifications
madelondohmen Sep 11, 2024
581d675
Update plugin_settings_list
madelondohmen Sep 11, 2024
f14a76d
Fix strip/split string
madelondohmen Sep 11, 2024
f3175d1
Change boefje id in normalizer table to name
madelondohmen Sep 11, 2024
b963285
Fix boefje variant plugin_id
madelondohmen Sep 11, 2024
a7e7e26
Merge branch 'main' into feature/duplicate-boefje
madelondohmen Sep 11, 2024
e24dc69
Update translations
madelondohmen Sep 12, 2024
0fb2f67
Fix rocky test
madelondohmen Sep 12, 2024
f5461c9
Merge branch 'feature/duplicate-boefje' of https://github.com/minvws/…
madelondohmen Sep 12, 2024
3d5f36a
Fix conftest
madelondohmen Sep 12, 2024
3131216
Merge branch 'feature/duplicate-boefje' into feature/update-boefje
madelondohmen Sep 12, 2024
d5052db
Fix plugin_id and return_to_plugin_id
madelondohmen Sep 12, 2024
6ab52e9
Fix edit page title
madelondohmen Sep 12, 2024
eb5a82d
Update breadcrumbs text
madelondohmen Sep 12, 2024
66ac089
Fix arguments bug
madelondohmen Sep 12, 2024
70d2968
Merge branch 'main' into feature/duplicate-boefje
madelondohmen Sep 12, 2024
aa1e104
Merge branch 'main' into feature/duplicate-boefje
madelondohmen Sep 12, 2024
18a8d57
Fix tests
madelondohmen Sep 16, 2024
8cb5464
Small fix
madelondohmen Sep 16, 2024
0e7bb7c
Merge branch 'feature/duplicate-boefje' of https://github.com/minvws/…
madelondohmen Sep 16, 2024
dcb40cd
Merge branch 'feature/duplicate-boefje' into feature/update-boefje
madelondohmen Sep 16, 2024
ca37f0f
Merge branch 'main' into feature/duplicate-boefje
madelondohmen Sep 17, 2024
5db74f9
Fix test_filter_plugins
madelondohmen Sep 17, 2024
7a1e2c7
Merge branch 'main' into feature/duplicate-boefje
madelondohmen Sep 17, 2024
5b23c4a
Merge branch 'feature/duplicate-boefje' into feature/update-boefje
madelondohmen Sep 17, 2024
cc661ff
Changes from feedback
madelondohmen Sep 17, 2024
031b57b
Update breadcrumbs and urls
madelondohmen Sep 17, 2024
d2c6476
Update helper texts in setup form
madelondohmen Sep 17, 2024
6445d2a
Add Boefje ID to variant table
madelondohmen Sep 17, 2024
88a4f35
Update translations
madelondohmen Sep 17, 2024
02a72b4
Add age and fix creation date
madelondohmen Sep 17, 2024
907e66d
Add new tests for boefje variant setup and edit boefje
madelondohmen Sep 17, 2024
88397de
Merge branch 'main' into feature/update-boefje
madelondohmen Sep 18, 2024
4c82299
Fix when variant.created is None
madelondohmen Sep 18, 2024
430c2fe
Merge branch 'main' into feature/update-boefje
madelondohmen Sep 18, 2024
36f2bbf
Fix tests
madelondohmen Sep 18, 2024
4618113
Merge branch 'feature/update-boefje' of https://github.com/minvws/nl-…
madelondohmen Sep 18, 2024
46f7f0a
Add unique constraint to database plugin names and align API behavior
Donnype Sep 18, 2024
af1a28c
Merge branch 'main' into feature/enforce-unique-plugin-names
Donnype Sep 19, 2024
c60ac61
Better error message and check for existence of the name in the local…
Donnype Sep 19, 2024
6d9ea1a
Merge branch 'main' into feature/enforce-unique-plugin-names
Donnype Sep 23, 2024
2e37b02
Merge branch 'feature/update-boefje' into feature/enforce-unique-plug…
madelondohmen Sep 23, 2024
4d973ef
Merge branch 'main' into feature/enforce-unique-plugin-names
underdarknl Sep 23, 2024
e5c02fd
Merge branch 'feature/enforce-unique-plugin-names' into feature/handl…
madelondohmen Sep 23, 2024
09e010e
Add exepction
madelondohmen Sep 23, 2024
68dcd19
Merge branch 'feature/enforce-unique-plugin-names' of https://github.…
madelondohmen Sep 23, 2024
630fae9
Merge branch 'feature/enforce-unique-plugin-names' into feature/handl…
madelondohmen Sep 23, 2024
2474123
Add exepction
madelondohmen Sep 23, 2024
c489a65
Move boefjes save logic to form and validation
Rieven Sep 23, 2024
0e50a00
Fix creating and editing boefje variants and optimize code
madelondohmen Sep 23, 2024
b1745d2
Small fixes, removes duplicate code
madelondohmen Sep 23, 2024
f925387
Merge branch 'main' into feature/handle-existing-plugin-name
madelondohmen Sep 23, 2024
d8381d3
Change exception to HTTPStatusError
madelondohmen Sep 24, 2024
acbd463
Update translations
madelondohmen Sep 24, 2024
0493caa
Add DuplicateNameError and handle correctly
madelondohmen Sep 24, 2024
46a6aff
Merge branch 'main' into feature/handle-existing-plugin-name
madelondohmen Sep 24, 2024
662cd28
Fix boefje_schema
madelondohmen Sep 24, 2024
965edf2
Merge branch 'main' into feature/handle-existing-plugin-name
madelondohmen Sep 25, 2024
36d667b
Update translations
madelondohmen Sep 25, 2024
3bbdb06
Merge branch 'feature/handle-existing-plugin-name' of https://github.…
madelondohmen Sep 25, 2024
fe5f2ea
Optimize setup method
madelondohmen Sep 25, 2024
646dcfa
Update rocky/tools/forms/boefje.py
madelondohmen Sep 25, 2024
f9aa776
Remove str from uuid
madelondohmen Sep 25, 2024
072cee9
Merge branch 'feature/handle-existing-plugin-name' of https://github.…
madelondohmen Sep 25, 2024
14af128
Add form_valid and remove clean
madelondohmen Sep 26, 2024
ac41f8e
Move position of try-except
madelondohmen Sep 27, 2024
3777bed
Updated logging
ammar92 Sep 27, 2024
462da07
Make exception in katalogus client more specific
madelondohmen Sep 27, 2024
2e4492f
dont allow editing static boefjes
noamblitz Sep 27, 2024
b9156c6
merge main
noamblitz Sep 27, 2024
f8a43e0
fix error catching
noamblitz Sep 27, 2024
9634b58
make lang
noamblitz Sep 27, 2024
f8dea10
update tests
noamblitz Sep 27, 2024
a3e985e
use httpx codes
noamblitz Sep 27, 2024
d824035
use httpx code
noamblitz Sep 27, 2024
4233aab
update tests
noamblitz Sep 27, 2024
51e925d
update tests
noamblitz Sep 27, 2024
a1a6bad
leave out status codes
noamblitz Sep 27, 2024
43de494
update tests....
noamblitz Sep 27, 2024
986ef50
Remove status code
madelondohmen Sep 27, 2024
ca8174f
Add DuplicateIdError
madelondohmen Sep 27, 2024
6b693f3
Update translations
madelondohmen Sep 27, 2024
e02d26c
Rework
ammar92 Sep 29, 2024
e384d42
Fixed regression
ammar92 Sep 29, 2024
dab1c79
Revert "Rework"
ammar92 Oct 1, 2024
434ecf3
Rework
ammar92 Oct 1, 2024
36a5d4b
Language update
ammar92 Oct 1, 2024
c031db5
Merge branch 'main' into feature/handle-existing-plugin-name
ammar92 Oct 1, 2024
4d7f3b4
Language update
ammar92 Oct 1, 2024
47d05f5
Fixed types
ammar92 Oct 1, 2024
a98254d
Fix
ammar92 Oct 1, 2024
acdb4e5
Fix
ammar92 Oct 1, 2024
bafa6ca
Fix
ammar92 Oct 1, 2024
3342546
Merge remote-tracking branch 'origin/feature/handle-existing-plugin-n…
ammar92 Oct 1, 2024
7758bb9
Fix exception for create_boefje
madelondohmen Oct 1, 2024
49b7625
Remove id and name exceptions and create generic exception
madelondohmen Oct 1, 2024
5651125
Update translations
madelondohmen Oct 1, 2024
9cbdb10
Merge branch 'main' into feature/handle-existing-plugin-name
madelondohmen Oct 1, 2024
aecd580
Fix
ammar92 Oct 2, 2024
ea83c9b
Merge branch 'main' into feature/handle-existing-plugin-name
madelondohmen Oct 2, 2024
724e6e8
Fixed `KATalogusHTTPStatusError` and unit test
ammar92 Oct 2, 2024
d58febd
WIP: integrate worker with report scheduling
Donnype Oct 2, 2024
a621aca
Fixed unit test in boefje module
ammar92 Oct 2, 2024
5b473d7
Merge remote-tracking branch 'origin/feature/handle-existing-plugin-n…
ammar92 Oct 2, 2024
d0d42c0
"message" should be "detail"
Donnype Oct 2, 2024
File filter

Filter by extension

Filter by extension

Conversations
Failed to load comments.
Loading
Jump to
Jump to file
Failed to load files.
Loading
Diff view
Diff view
28 changes: 20 additions & 8 deletions boefjes/boefjes/dependencies/plugins.py
Original file line number Diff line number Diff line change
Expand Up @@ -16,8 +16,8 @@
from boefjes.sql.plugin_storage import create_plugin_storage
from boefjes.storage.interfaces import (
ConfigStorage,
ExistingPluginId,
ExistingPluginName,
DuplicatePlugin,
IntegrityError,
NotFound,
PluginNotFound,
PluginStorage,
Expand Down Expand Up @@ -107,28 +107,40 @@ def upsert_settings(self, settings: dict, organisation_id: str, plugin_id: str):
def create_boefje(self, boefje: Boefje) -> None:
try:
self.local_repo.by_id(boefje.id)
raise ExistingPluginId(boefje.id)
raise DuplicatePlugin("id")
except KeyError:
try:
plugin = self.local_repo.by_name(boefje.name)

if plugin.type == "boefje":
raise ExistingPluginName(boefje.name)
raise DuplicatePlugin("name")
else:
self.plugin_storage.create_boefje(boefje)
try:
with self.plugin_storage as storage:
storage.create_boefje(boefje)
except IntegrityError as error:
raise DuplicatePlugin(self._translate_duplicate_plugin(error.message))
except KeyError:
self.plugin_storage.create_boefje(boefje)
try:
with self.plugin_storage as storage:
storage.create_boefje(boefje)
except IntegrityError as error:
raise DuplicatePlugin(self._translate_duplicate_plugin(error.message))

def _translate_duplicate_plugin(self, error_message):
translations = {"boefje_plugin_id": "id", "boefje_name": "name"}
return next((value for key, value in translations.items() if key in error_message), None)

def create_normalizer(self, normalizer: Normalizer) -> None:
try:
self.local_repo.by_id(normalizer.id)
raise ExistingPluginId(normalizer.id)
raise DuplicatePlugin("id")
except KeyError:
try:
plugin = self.local_repo.by_name(normalizer.name)

if plugin.types == "normalizer":
raise ExistingPluginName(normalizer.name)
raise DuplicatePlugin("name")
else:
self.plugin_storage.create_normalizer(normalizer)
except KeyError:
Expand Down
31 changes: 22 additions & 9 deletions boefjes/boefjes/katalogus/plugins.py
Original file line number Diff line number Diff line change
@@ -1,6 +1,7 @@
import datetime
from functools import partial

import structlog
from croniter import croniter
from fastapi import APIRouter, Body, Depends, HTTPException, status
from fastapi.responses import FileResponse, JSONResponse, Response
Expand All @@ -17,14 +18,16 @@
from boefjes.katalogus.organisations import check_organisation_exists
from boefjes.models import FilterParameters, PaginationParameters, PluginType
from boefjes.sql.plugin_storage import get_plugin_storage
from boefjes.storage.interfaces import PluginStorage
from boefjes.storage.interfaces import DuplicatePlugin, IntegrityError, NotAllowed, PluginStorage

router = APIRouter(
prefix="/organisations/{organisation_id}",
tags=["plugins"],
dependencies=[Depends(check_organisation_exists)],
)

logger = structlog.get_logger(__name__)


# check if query matches plugin id, name or description
def _plugin_matches_query(plugin: PluginType, query: str) -> bool:
Expand Down Expand Up @@ -96,14 +99,17 @@ def get_plugin(

@router.post("/plugins", status_code=status.HTTP_201_CREATED)
def add_plugin(plugin: PluginType, plugin_service: PluginService = Depends(get_plugin_service)):
with plugin_service as service:
plugin.static = False # Creation through the API implies that these cannot be static
try:
with plugin_service as service:
plugin.static = False # Creation through the API implies that these cannot be static

if plugin.type == "boefje":
return service.create_boefje(plugin)
if plugin.type == "boefje":
return service.create_boefje(plugin)

if plugin.type == "normalizer":
return service.create_normalizer(plugin)
if plugin.type == "normalizer":
return service.create_normalizer(plugin)
except DuplicatePlugin as error:
raise HTTPException(status.HTTP_400_BAD_REQUEST, error.message)

raise HTTPException(status.HTTP_400_BAD_REQUEST, "Creation of Bits is not supported")

Expand Down Expand Up @@ -164,8 +170,15 @@ def update_boefje(
boefje: BoefjeIn,
storage: PluginStorage = Depends(get_plugin_storage),
):
with storage as p:
p.update_boefje(boefje_id, boefje.model_dump(exclude_unset=True))
# todo: update boefje should be done in the plugin service
try:
with storage as p:
try:
p.update_boefje(boefje_id, boefje.model_dump(exclude_unset=True))
except NotAllowed:
raise HTTPException(status.HTTP_403_FORBIDDEN, "Updating a static plugin is not allowed")
except IntegrityError as error:
raise HTTPException(status.HTTP_400_BAD_REQUEST, error.message)


@router.delete("/boefjes/{boefje_id}", status_code=status.HTTP_204_NO_CONTENT)
Expand Down
2 changes: 1 addition & 1 deletion boefjes/boefjes/sql/db.py
Original file line number Diff line number Diff line change
Expand Up @@ -43,7 +43,7 @@ def session_managed_iterator(service_factory: Callable[[Session], Any]) -> Itera
try:
yield service
except Exception as error:
logger.exception("An error occurred: %s. Rolling back session", error)
logger.error("An error occurred: %s. Rolling back session", error)
session.rollback()
raise error
finally:
Expand Down
7 changes: 4 additions & 3 deletions boefjes/boefjes/sql/session.py
Original file line number Diff line number Diff line change
Expand Up @@ -30,7 +30,7 @@ def __enter__(self) -> Self:

def __exit__(self, exc_type: type[Exception], exc_value: str, exc_traceback: str) -> None: # noqa: F841
if exc_type is not None:
logger.error("An error occurred: %s. Rolling back session", exc_value, exc_info=True)
logger.error("An error occurred: %s. Rolling back session", exc_value)
self.session.rollback()

return
Expand All @@ -45,5 +45,6 @@ def __exit__(self, exc_type: type[Exception], exc_value: str, exc_traceback: str
except exc.DatabaseError as e:
raise StorageError("A storage error occurred") from e
finally:
logger.exception("Committing failed, rolling back")
self.session.rollback()
if exc_type is not None or self.session.is_active:
logger.debug("Committing failed, rolling back")
self.session.rollback()
11 changes: 3 additions & 8 deletions boefjes/boefjes/storage/interfaces.py
Original file line number Diff line number Diff line change
Expand Up @@ -55,14 +55,9 @@ def __init__(self, plugin_id: str):
super().__init__(f"Plugin with id '{plugin_id}' is static, so updating it is not allowed")


class ExistingPluginId(NotAllowed):
def __init__(self, plugin_id: str):
super().__init__(f"Plugin id '{plugin_id}' is already used")


class ExistingPluginName(NotAllowed):
def __init__(self, plugin_name: str):
super().__init__(f"Plugin name '{plugin_name}' is already used")
class DuplicatePlugin(NotAllowed):
def __init__(self, key: str):
super().__init__(f"Duplicate plugin {key}")


class OrganisationStorage(ABC):
Expand Down
1 change: 0 additions & 1 deletion boefjes/tests/conftest.py
Original file line number Diff line number Diff line change
Expand Up @@ -121,7 +121,6 @@ def handle(self, item: BoefjeMeta | NormalizerMeta):
time.sleep(self.sleep_time)

if str(item.id) == "9071c9fd-2b9f-440f-a524-ef1ca4824fd4":
time.sleep(0.1)
raise self.exception()

self.queue.put(item)
Expand Down
13 changes: 5 additions & 8 deletions boefjes/tests/integration/test_api.py
Original file line number Diff line number Diff line change
Expand Up @@ -45,12 +45,12 @@ def test_cannot_add_plugin_reserved_id(test_client, organisation):
boefje = Boefje(id="dns-records", name="My test boefje", static=False)
response = test_client.post(f"/v1/organisations/{organisation.id}/plugins", content=boefje.model_dump_json())
assert response.status_code == 400
assert response.json() == {"message": "Plugin id 'dns-records' is already used"}
assert response.json() == {"detail": "Duplicate plugin id"}

normalizer = Normalizer(id="kat_nmap_normalize", name="My test normalizer")
response = test_client.post(f"/v1/organisations/{organisation.id}/plugins", content=normalizer.model_dump_json())
assert response.status_code == 400
assert response.json() == {"message": "Plugin id 'kat_nmap_normalize' is already used"}
assert response.json() == {"detail": "Duplicate plugin id"}


def test_add_boefje(test_client, organisation):
Expand Down Expand Up @@ -80,7 +80,7 @@ def test_cannot_add_static_plugin_with_duplicate_name(test_client, organisation)
boefje = Boefje(id="test_plugin", name="DNS records", static=False)
response = test_client.post(f"/v1/organisations/{organisation.id}/plugins", content=boefje.model_dump_json())
assert response.status_code == 400
assert response.json() == {"message": "Plugin name 'DNS records' is already used"}
assert response.json() == {"detail": "Duplicate plugin name"}


def test_cannot_add_plugin_with_duplicate_name(test_client, organisation):
Expand All @@ -91,10 +91,7 @@ def test_cannot_add_plugin_with_duplicate_name(test_client, organisation):
boefje = Boefje(id="test_plugin_2", name="My test boefje", static=False)
response = test_client.post(f"/v1/organisations/{organisation.id}/plugins", content=boefje.model_dump_json())
assert response.status_code == 400
assert response.json() == {
"message": 'duplicate key value violates unique constraint "unique_boefje_name"\n'
"DETAIL: Key (name)=(My test boefje) already exists.\n"
}
assert response.json() == {"detail": "Duplicate plugin name"}

normalizer = Normalizer(id="test_normalizer", name="My test normalizer", static=False)
response = test_client.post(f"/v1/organisations/{organisation.id}/plugins", content=normalizer.model_dump_json())
Expand Down Expand Up @@ -238,7 +235,7 @@ def test_cannot_update_static_plugins(test_client, organisation):
assert response.json()["enabled"] is True

response = test_client.patch(f"/v1/organisations/{organisation.id}/boefjes/dns-records", json={"version": "v1.2"})
assert response.status_code == 400
assert response.status_code == 403

response = test_client.get(f"/v1/organisations/{organisation.id}/plugins/dns-records")
assert response.json()["version"] != "v1.2"
Expand Down
1 change: 1 addition & 0 deletions boefjes/tests/test_app.py
Original file line number Diff line number Diff line change
Expand Up @@ -95,6 +95,7 @@ def test_two_processes_handler_exception(manager: SchedulerWorkerManager, item_h

# We expect the first two patches to set the task status to running of both task and then process 1 to finish, as
# the exception has been set up with a small delay.
assert len(patched_tasks) == 6
assert sorted(patched_tasks[:3]) == sorted(
[
("70da7d4f-f41f-4940-901b-d98a92e9014b", "running"), # Process 1
Expand Down
102 changes: 72 additions & 30 deletions rocky/katalogus/client.py
Original file line number Diff line number Diff line change
@@ -1,3 +1,4 @@
import json
from io import BytesIO

import httpx
Expand Down Expand Up @@ -68,19 +69,47 @@ def serialize_produces(self, produces: set[type[OOI]]):


class KATalogusError(Exception):
message: str = _("The KATalogus has an unexpected error. Check the logs for further details.")
@property
def message(self):
return self._message

def __init__(self, message: str | None = None):
if message is None:
message = _("The KATalogus has an unexpected error. Check the logs for further details.")

self._message = message

super().__init__(message)

def __str__(self):
return str(self.message)
return self._message


class DuplicatePluginError(KATalogusError):
def __init__(self, error_message: str):
super().__init__(error_message)


class DuplicateNameError(KATalogusError):
def __init__(self):
super().__init__(_("Boefje with this name already exists."))


class DuplicateIdError(KATalogusError):
def __init__(self):
super().__init__(_("Boefje with this ID already exists."))


class KATalogusNotAllowedError(KATalogusError):
def __init__(self):
super().__init__(_("Editing this boefje is not allowed because it is static."))


class KATalogusHTTPStatusError(KATalogusError):
def __init__(self, *args: object, status_code: str | None = None) -> None:
super().__init__(*args)
status_message = ""
if status_code is not None:
status_message = f"{status_code}: "
self.message = status_message + _("A HTTP error occurred. Check logs for more info.")
def __init__(self, error: httpx.HTTPStatusError):
self.error = error

super().__init__(_("An HTTP %d error occurred. Check logs for more info.").format(error.response.status_code))


class KATalogusClientV1:
Expand Down Expand Up @@ -111,7 +140,7 @@ def get_plugins(self, **params) -> list[Plugin]:
response = self.session.get(f"{self.organization_uri}/plugins", params=params)
response.raise_for_status()
except httpx.HTTPStatusError as error:
raise KATalogusHTTPStatusError(status_code=str(error.response.status_code))
raise KATalogusHTTPStatusError(error)
return [parse_plugin(plugin) for plugin in response.json()]

def get_plugin(self, plugin_id: str) -> Plugin:
Expand Down Expand Up @@ -210,29 +239,42 @@ def get_cover(self, boefje_id: str) -> BytesIO:
return BytesIO(response.content)

def create_plugin(self, plugin: Plugin) -> None:
response = self.session.post(
f"{self.organization_uri}/plugins",
headers={"Content-Type": "application/json"},
content=plugin.model_dump_json(exclude_none=True),
)
response.raise_for_status()

if response.status_code == codes.CREATED:
logger.info("Plugin %s", plugin.name)
else:
logger.info("Plugin %s could not be created", plugin.name)
try:
response = self.session.post(
f"{self.organization_uri}/plugins",
headers={"Content-Type": "application/json"},
content=plugin.model_dump_json(exclude_none=True),
)
response.raise_for_status()
except httpx.HTTPStatusError as error:
if error.response.status_code == codes.CREATED:
logger.info("Plugin %s created", plugin.name)
else:
logger.info("Plugin %s could not be created", plugin.name)
error_message = json.loads(error.response.text).get("detail")
if error.response.status_code == codes.BAD_REQUEST and "Duplicate plugin" in error_message:
raise DuplicatePluginError(error_message)
else:
raise error

def edit_plugin(self, plugin: Plugin) -> None:
response = self.session.patch(
f"{self.organization_uri}/boefjes/{plugin.id}",
content=plugin.model_dump_json(exclude_none=True),
)
response.raise_for_status()

if response.status_code == codes.CREATED:
logger.info("Plugin %s", plugin.name)
else:
logger.info("Plugin %s could not be created", plugin.name)
try:
response = self.session.patch(
f"{self.organization_uri}/boefjes/{plugin.id}",
content=plugin.model_dump_json(exclude_none=True),
)
response.raise_for_status()
except httpx.HTTPStatusError as error:
if error.response.status_code == codes.CREATED:
logger.info("Plugin %s updated", plugin.name)
else:
logger.info("Plugin %s could not be updated", plugin.name)
if error.response.status_code == codes.BAD_REQUEST and "duplicate key" in error.response.text:
raise DuplicatePluginError("Duplicate plugin name")
if error.response.status_code in [codes.FORBIDDEN, codes.NOT_FOUND]:
raise KATalogusNotAllowedError
else:
raise error


def parse_boefje(boefje: dict) -> Boefje:
Expand Down
Loading