mmisp-lib 0.1.0__tar.gz
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.
- mmisp_lib-0.1.0/PKG-INFO +77 -0
- mmisp_lib-0.1.0/README.md +47 -0
- mmisp_lib-0.1.0/pyproject.toml +50 -0
- mmisp_lib-0.1.0/setup.cfg +4 -0
- mmisp_lib-0.1.0/src/mmisp/api_schemas/__init__.py +0 -0
- mmisp_lib-0.1.0/src/mmisp/api_schemas/attributes/__init__.py +0 -0
- mmisp_lib-0.1.0/src/mmisp/api_schemas/attributes/add_attribute_body.py +34 -0
- mmisp_lib-0.1.0/src/mmisp/api_schemas/attributes/add_attribute_response.py +33 -0
- mmisp_lib-0.1.0/src/mmisp/api_schemas/attributes/add_remove_tag_attribute_response.py +13 -0
- mmisp_lib-0.1.0/src/mmisp/api_schemas/attributes/delete_attribute_response.py +8 -0
- mmisp_lib-0.1.0/src/mmisp/api_schemas/attributes/delete_selected_attribute_body.py +9 -0
- mmisp_lib-0.1.0/src/mmisp/api_schemas/attributes/delete_selected_attribute_response.py +13 -0
- mmisp_lib-0.1.0/src/mmisp/api_schemas/attributes/edit_attribute_body.py +24 -0
- mmisp_lib-0.1.0/src/mmisp/api_schemas/attributes/edit_attributes_response.py +42 -0
- mmisp_lib-0.1.0/src/mmisp/api_schemas/attributes/get_all_attributes_response.py +38 -0
- mmisp_lib-0.1.0/src/mmisp/api_schemas/attributes/get_attribute_response.py +41 -0
- mmisp_lib-0.1.0/src/mmisp/api_schemas/attributes/get_attribute_statistics_response.py +137 -0
- mmisp_lib-0.1.0/src/mmisp/api_schemas/attributes/get_describe_types_response.py +29 -0
- mmisp_lib-0.1.0/src/mmisp/api_schemas/attributes/restore_attribute_reponse.py +25 -0
- mmisp_lib-0.1.0/src/mmisp/api_schemas/attributes/search_attributes_body.py +74 -0
- mmisp_lib-0.1.0/src/mmisp/api_schemas/attributes/search_attributes_response.py +52 -0
- mmisp_lib-0.1.0/src/mmisp/api_schemas/auth_keys/__init__.py +0 -0
- mmisp_lib-0.1.0/src/mmisp/api_schemas/auth_keys/add_auth_key_body.py +10 -0
- mmisp_lib-0.1.0/src/mmisp/api_schemas/auth_keys/add_auth_key_response.py +20 -0
- mmisp_lib-0.1.0/src/mmisp/api_schemas/auth_keys/edit_auth_key_body.py +8 -0
- mmisp_lib-0.1.0/src/mmisp/api_schemas/auth_keys/edit_auth_key_response.py +24 -0
- mmisp_lib-0.1.0/src/mmisp/api_schemas/auth_keys/search_auth_keys_body.py +17 -0
- mmisp_lib-0.1.0/src/mmisp/api_schemas/auth_keys/search_get_all_auth_keys_users_response.py +28 -0
- mmisp_lib-0.1.0/src/mmisp/api_schemas/auth_keys/view_auth_key_response.py +24 -0
- mmisp_lib-0.1.0/src/mmisp/api_schemas/authentication/__init__.py +0 -0
- mmisp_lib-0.1.0/src/mmisp/api_schemas/authentication/exchange_token_login_body.py +5 -0
- mmisp_lib-0.1.0/src/mmisp/api_schemas/authentication/password_login_body.py +6 -0
- mmisp_lib-0.1.0/src/mmisp/api_schemas/authentication/start_login_body.py +5 -0
- mmisp_lib-0.1.0/src/mmisp/api_schemas/authentication/start_login_response.py +21 -0
- mmisp_lib-0.1.0/src/mmisp/api_schemas/authentication/token_response.py +5 -0
- mmisp_lib-0.1.0/src/mmisp/api_schemas/events/FreeTextImportWorkerBody.py +17 -0
- mmisp_lib-0.1.0/src/mmisp/api_schemas/events/__init__.py +0 -0
- mmisp_lib-0.1.0/src/mmisp/api_schemas/events/add_attribute_via_free_text_import_event_body.py +12 -0
- mmisp_lib-0.1.0/src/mmisp/api_schemas/events/add_attribute_via_free_text_import_event_response.py +14 -0
- mmisp_lib-0.1.0/src/mmisp/api_schemas/events/add_edit_get_event_response.py +234 -0
- mmisp_lib-0.1.0/src/mmisp/api_schemas/events/add_event_body.py +30 -0
- mmisp_lib-0.1.0/src/mmisp/api_schemas/events/add_remove_tag_events_response.py +11 -0
- mmisp_lib-0.1.0/src/mmisp/api_schemas/events/delete_event_response.py +14 -0
- mmisp_lib-0.1.0/src/mmisp/api_schemas/events/edit_event_body.py +28 -0
- mmisp_lib-0.1.0/src/mmisp/api_schemas/events/get_all_events_response.py +99 -0
- mmisp_lib-0.1.0/src/mmisp/api_schemas/events/get_event_response.py +8 -0
- mmisp_lib-0.1.0/src/mmisp/api_schemas/events/index_events_body.py +30 -0
- mmisp_lib-0.1.0/src/mmisp/api_schemas/events/index_events_response.py +40 -0
- mmisp_lib-0.1.0/src/mmisp/api_schemas/events/publish_event_response.py +13 -0
- mmisp_lib-0.1.0/src/mmisp/api_schemas/events/search_events_body.py +43 -0
- mmisp_lib-0.1.0/src/mmisp/api_schemas/events/search_events_response.py +10 -0
- mmisp_lib-0.1.0/src/mmisp/api_schemas/events/unpublish_event_response.py +13 -0
- mmisp_lib-0.1.0/src/mmisp/api_schemas/feeds/__init__.py +0 -0
- mmisp_lib-0.1.0/src/mmisp/api_schemas/feeds/cache_feed_response.py +12 -0
- mmisp_lib-0.1.0/src/mmisp/api_schemas/feeds/create_feed_body.py +30 -0
- mmisp_lib-0.1.0/src/mmisp/api_schemas/feeds/enable_disable_feed_response.py +10 -0
- mmisp_lib-0.1.0/src/mmisp/api_schemas/feeds/fetch_feeds_response.py +8 -0
- mmisp_lib-0.1.0/src/mmisp/api_schemas/feeds/get_feed_response.py +47 -0
- mmisp_lib-0.1.0/src/mmisp/api_schemas/feeds/toggle_feed_body.py +8 -0
- mmisp_lib-0.1.0/src/mmisp/api_schemas/feeds/update_feed_body.py +30 -0
- mmisp_lib-0.1.0/src/mmisp/api_schemas/galaxies/__init__.py +0 -0
- mmisp_lib-0.1.0/src/mmisp/api_schemas/galaxies/attach_galaxy_cluster_body.py +12 -0
- mmisp_lib-0.1.0/src/mmisp/api_schemas/galaxies/attach_galaxy_cluster_response.py +10 -0
- mmisp_lib-0.1.0/src/mmisp/api_schemas/galaxies/delete_force_update_import_galaxy_response.py +12 -0
- mmisp_lib-0.1.0/src/mmisp/api_schemas/galaxies/export_galaxies_body.py +16 -0
- mmisp_lib-0.1.0/src/mmisp/api_schemas/galaxies/export_galaxies_response.py +44 -0
- mmisp_lib-0.1.0/src/mmisp/api_schemas/galaxies/galaxy_schema.py +18 -0
- mmisp_lib-0.1.0/src/mmisp/api_schemas/galaxies/get_all_search_galaxies_response.py +22 -0
- mmisp_lib-0.1.0/src/mmisp/api_schemas/galaxies/get_galaxy_response.py +37 -0
- mmisp_lib-0.1.0/src/mmisp/api_schemas/galaxies/import_galaxies_body.py +15 -0
- mmisp_lib-0.1.0/src/mmisp/api_schemas/galaxies/search_galaxies_body.py +22 -0
- mmisp_lib-0.1.0/src/mmisp/api_schemas/noticelists/__init__.py +0 -0
- mmisp_lib-0.1.0/src/mmisp/api_schemas/noticelists/get_all_noticelist_response.py +10 -0
- mmisp_lib-0.1.0/src/mmisp/api_schemas/noticelists/get_noticelist_response.py +38 -0
- mmisp_lib-0.1.0/src/mmisp/api_schemas/objects/__init__.py +0 -0
- mmisp_lib-0.1.0/src/mmisp/api_schemas/objects/create_object_body.py +19 -0
- mmisp_lib-0.1.0/src/mmisp/api_schemas/objects/get_object_response.py +50 -0
- mmisp_lib-0.1.0/src/mmisp/api_schemas/objects/search_objects_body.py +49 -0
- mmisp_lib-0.1.0/src/mmisp/api_schemas/organisations/__init__.py +0 -0
- mmisp_lib-0.1.0/src/mmisp/api_schemas/organisations/organisation.py +24 -0
- mmisp_lib-0.1.0/src/mmisp/api_schemas/roles/__init__.py +0 -0
- mmisp_lib-0.1.0/src/mmisp/api_schemas/roles/role.py +71 -0
- mmisp_lib-0.1.0/src/mmisp/api_schemas/sharing_groups/__init__.py +0 -0
- mmisp_lib-0.1.0/src/mmisp/api_schemas/sharing_groups/add_org_to_sharing_group_body.py +6 -0
- mmisp_lib-0.1.0/src/mmisp/api_schemas/sharing_groups/add_org_to_sharing_group_legacy_body.py +5 -0
- mmisp_lib-0.1.0/src/mmisp/api_schemas/sharing_groups/add_server_to_sharing_group_body.py +6 -0
- mmisp_lib-0.1.0/src/mmisp/api_schemas/sharing_groups/add_server_to_sharing_group_legacy_body.py +5 -0
- mmisp_lib-0.1.0/src/mmisp/api_schemas/sharing_groups/create_sharing_group_body.py +12 -0
- mmisp_lib-0.1.0/src/mmisp/api_schemas/sharing_groups/create_sharing_group_legacy_body.py +23 -0
- mmisp_lib-0.1.0/src/mmisp/api_schemas/sharing_groups/create_sharing_group_legacy_response.py +18 -0
- mmisp_lib-0.1.0/src/mmisp/api_schemas/sharing_groups/delete_sharing_group_legacy_response.py +5 -0
- mmisp_lib-0.1.0/src/mmisp/api_schemas/sharing_groups/get_all_sharing_groups_response.py +53 -0
- mmisp_lib-0.1.0/src/mmisp/api_schemas/sharing_groups/get_sharing_group_info_response.py +44 -0
- mmisp_lib-0.1.0/src/mmisp/api_schemas/sharing_groups/sharing_group.py +19 -0
- mmisp_lib-0.1.0/src/mmisp/api_schemas/sharing_groups/sharing_group_org.py +8 -0
- mmisp_lib-0.1.0/src/mmisp/api_schemas/sharing_groups/sharing_group_server.py +8 -0
- mmisp_lib-0.1.0/src/mmisp/api_schemas/sharing_groups/update_sharing_group_body.py +10 -0
- mmisp_lib-0.1.0/src/mmisp/api_schemas/sharing_groups/update_sharing_group_legacy_body.py +28 -0
- mmisp_lib-0.1.0/src/mmisp/api_schemas/sharing_groups/view_update_sharing_group_legacy_response.py +40 -0
- mmisp_lib-0.1.0/src/mmisp/api_schemas/sightings/__init__.py +0 -0
- mmisp_lib-0.1.0/src/mmisp/api_schemas/sightings/create_sighting_body.py +49 -0
- mmisp_lib-0.1.0/src/mmisp/api_schemas/sightings/get_sighting_response.py +27 -0
- mmisp_lib-0.1.0/src/mmisp/api_schemas/standard_status_response.py +13 -0
- mmisp_lib-0.1.0/src/mmisp/api_schemas/tags/__init__.py +0 -0
- mmisp_lib-0.1.0/src/mmisp/api_schemas/tags/create_tag_body.py +15 -0
- mmisp_lib-0.1.0/src/mmisp/api_schemas/tags/delete_tag_response.py +10 -0
- mmisp_lib-0.1.0/src/mmisp/api_schemas/tags/get_tag_response.py +31 -0
- mmisp_lib-0.1.0/src/mmisp/api_schemas/tags/search_tags_response.py +26 -0
- mmisp_lib-0.1.0/src/mmisp/api_schemas/tags/update_tag_body.py +15 -0
- mmisp_lib-0.1.0/src/mmisp/api_schemas/taxonomies/__init__.py +0 -0
- mmisp_lib-0.1.0/src/mmisp/api_schemas/taxonomies/export_taxonomies_response.py +30 -0
- mmisp_lib-0.1.0/src/mmisp/api_schemas/taxonomies/get_taxonomy_by_id_response.py +30 -0
- mmisp_lib-0.1.0/src/mmisp/api_schemas/taxonomies/get_taxonomy_response.py +21 -0
- mmisp_lib-0.1.0/src/mmisp/api_schemas/taxonomies/get_taxonomy_tags_response.py +32 -0
- mmisp_lib-0.1.0/src/mmisp/api_schemas/user_settings/__init__.py +0 -0
- mmisp_lib-0.1.0/src/mmisp/api_schemas/user_settings/get_uid_user_setting_response.py +21 -0
- mmisp_lib-0.1.0/src/mmisp/api_schemas/user_settings/get_user_settings_response.py +13 -0
- mmisp_lib-0.1.0/src/mmisp/api_schemas/user_settings/search_user_setting_body.py +7 -0
- mmisp_lib-0.1.0/src/mmisp/api_schemas/user_settings/search_user_setting_response.py +11 -0
- mmisp_lib-0.1.0/src/mmisp/api_schemas/user_settings/set_user_setting_body.py +5 -0
- mmisp_lib-0.1.0/src/mmisp/api_schemas/user_settings/set_user_setting_response.py +13 -0
- mmisp_lib-0.1.0/src/mmisp/api_schemas/user_settings/view_user_setting_response.py +13 -0
- mmisp_lib-0.1.0/src/mmisp/api_schemas/users/__init__.py +0 -0
- mmisp_lib-0.1.0/src/mmisp/api_schemas/users/user.py +42 -0
- mmisp_lib-0.1.0/src/mmisp/api_schemas/users/users_view_me_response.py +12 -0
- mmisp_lib-0.1.0/src/mmisp/api_schemas/warninglists/__init__.py +0 -0
- mmisp_lib-0.1.0/src/mmisp/api_schemas/warninglists/check_value_warninglists_body.py +8 -0
- mmisp_lib-0.1.0/src/mmisp/api_schemas/warninglists/check_value_warninglists_response.py +14 -0
- mmisp_lib-0.1.0/src/mmisp/api_schemas/warninglists/create_warninglist_body.py +220 -0
- mmisp_lib-0.1.0/src/mmisp/api_schemas/warninglists/delete_warninglist_response.py +13 -0
- mmisp_lib-0.1.0/src/mmisp/api_schemas/warninglists/get_selected_all_warninglists_response.py +14 -0
- mmisp_lib-0.1.0/src/mmisp/api_schemas/warninglists/get_selected_warninglists_body.py +9 -0
- mmisp_lib-0.1.0/src/mmisp/api_schemas/warninglists/toggle_enable_warninglists_body.py +10 -0
- mmisp_lib-0.1.0/src/mmisp/api_schemas/warninglists/toggle_enable_warninglists_response.py +10 -0
- mmisp_lib-0.1.0/src/mmisp/api_schemas/warninglists/warninglist_response.py +42 -0
- mmisp_lib-0.1.0/src/mmisp/db/__init__.py +0 -0
- mmisp_lib-0.1.0/src/mmisp/db/config.py +17 -0
- mmisp_lib-0.1.0/src/mmisp/db/database.py +42 -0
- mmisp_lib-0.1.0/src/mmisp/db/models/__init__.py +0 -0
- mmisp_lib-0.1.0/src/mmisp/db/models/attribute.py +92 -0
- mmisp_lib-0.1.0/src/mmisp/db/models/auth_key.py +24 -0
- mmisp_lib-0.1.0/src/mmisp/db/models/event.py +62 -0
- mmisp_lib-0.1.0/src/mmisp/db/models/feed.py +32 -0
- mmisp_lib-0.1.0/src/mmisp/db/models/galaxy.py +22 -0
- mmisp_lib-0.1.0/src/mmisp/db/models/galaxy_cluster.py +52 -0
- mmisp_lib-0.1.0/src/mmisp/db/models/identity_provider.py +22 -0
- mmisp_lib-0.1.0/src/mmisp/db/models/noticelist.py +22 -0
- mmisp_lib-0.1.0/src/mmisp/db/models/object.py +39 -0
- mmisp_lib-0.1.0/src/mmisp/db/models/organisation.py +26 -0
- mmisp_lib-0.1.0/src/mmisp/db/models/role.py +42 -0
- mmisp_lib-0.1.0/src/mmisp/db/models/server.py +33 -0
- mmisp_lib-0.1.0/src/mmisp/db/models/sharing_group.py +43 -0
- mmisp_lib-0.1.0/src/mmisp/db/models/sighting.py +21 -0
- mmisp_lib-0.1.0/src/mmisp/db/models/tag.py +19 -0
- mmisp_lib-0.1.0/src/mmisp/db/models/taxonomy.py +41 -0
- mmisp_lib-0.1.0/src/mmisp/db/models/user.py +44 -0
- mmisp_lib-0.1.0/src/mmisp/db/models/user_setting.py +29 -0
- mmisp_lib-0.1.0/src/mmisp/db/models/warninglist.py +33 -0
- mmisp_lib-0.1.0/src/mmisp/db/print_changes.py +59 -0
- mmisp_lib-0.1.0/src/mmisp/lib/__init__.py +0 -0
- mmisp_lib-0.1.0/src/mmisp/lib/attributes.py +1386 -0
- mmisp_lib-0.1.0/src/mmisp_lib.egg-info/PKG-INFO +77 -0
- mmisp_lib-0.1.0/src/mmisp_lib.egg-info/SOURCES.txt +164 -0
- mmisp_lib-0.1.0/src/mmisp_lib.egg-info/dependency_links.txt +1 -0
- mmisp_lib-0.1.0/src/mmisp_lib.egg-info/requires.txt +25 -0
- mmisp_lib-0.1.0/src/mmisp_lib.egg-info/top_level.txt +1 -0
mmisp_lib-0.1.0/PKG-INFO
ADDED
@@ -0,0 +1,77 @@
|
|
1
|
+
Metadata-Version: 2.1
|
2
|
+
Name: mmisp-lib
|
3
|
+
Version: 0.1.0
|
4
|
+
Requires-Python: >=3.11.0
|
5
|
+
Description-Content-Type: text/markdown
|
6
|
+
Requires-Dist: fastapi==0.104.1
|
7
|
+
Requires-Dist: SQLAlchemy[asyncio]==1.4.46
|
8
|
+
Requires-Dist: pydantic==1.10.13
|
9
|
+
Requires-Dist: uvicorn==0.24.0.post1
|
10
|
+
Requires-Dist: python-dotenv==1.0.0
|
11
|
+
Requires-Dist: alembic==1.8.1
|
12
|
+
Requires-Dist: aiomysql==0.2.0
|
13
|
+
Requires-Dist: aiosqlite==0.20.0
|
14
|
+
Requires-Dist: PyJWT==2.8.0
|
15
|
+
Requires-Dist: httpx==0.26.0
|
16
|
+
Requires-Dist: passlib==1.7.4
|
17
|
+
Requires-Dist: argon2-cffi==23.1.0
|
18
|
+
Requires-Dist: bcrypt==4.1.2
|
19
|
+
Requires-Dist: nanoid==2.0.0
|
20
|
+
Requires-Dist: cryptography==42.0.5
|
21
|
+
Provides-Extra: dev
|
22
|
+
Requires-Dist: ruff==0.3.7; extra == "dev"
|
23
|
+
Requires-Dist: mypy==1.8.0; extra == "dev"
|
24
|
+
Requires-Dist: pre-commit==3.6.0; extra == "dev"
|
25
|
+
Requires-Dist: pytest==8.0.0; extra == "dev"
|
26
|
+
Requires-Dist: pytest-asyncio==0.23.5.post1; extra == "dev"
|
27
|
+
Requires-Dist: pytest-cov==4.1.0; extra == "dev"
|
28
|
+
Requires-Dist: respx==0.20.2; extra == "dev"
|
29
|
+
Requires-Dist: mysql-connector-python==8.3.0; extra == "dev"
|
30
|
+
|
31
|
+
# Modern MISP - API
|
32
|
+
|
33
|
+
[](https://github.com/astral-sh/ruff) [](https://conventionalcommits.org)
|
34
|
+
|
35
|
+
## Requirements
|
36
|
+
|
37
|
+
- [Docker](https://www.docker.com) `latest-stable`
|
38
|
+
|
39
|
+
## Getting Started
|
40
|
+
|
41
|
+
Clone the project and install Python version `3.11.0`. It is recommended to install Python using [pyenv](https://github.com/pyenv/pyenv#installation). Then install all dependencies by typing `make setup` into your terminal and start your local database container using `make up`.
|
42
|
+
|
43
|
+
Create a file called `.env` and copy the contents of `.env.example` into it. Finally, start the development server using `make dev`.
|
44
|
+
|
45
|
+
You should now be able to access the api on `localhost:4000`.
|
46
|
+
|
47
|
+
Run tests using `make test` (local database container required running) or `make test/lite`.
|
48
|
+
|
49
|
+
## Setting up your IDE
|
50
|
+
|
51
|
+
Be sure to use the newly created virtual env as your interpreter (`./venv/bin/python`). Also install the [Ruff](https://docs.astral.sh/ruff/integrations/) extension for your IDE and set `Ruff` as your default code formatter. It is recommended to activate formatting your code on every save.
|
52
|
+
|
53
|
+
## Best Practices
|
54
|
+
|
55
|
+
### General Guidelines
|
56
|
+
|
57
|
+
The following are some guidelines for writing code, in no particular order:
|
58
|
+
|
59
|
+
- Try to write clean code
|
60
|
+
- Use the "early return" pattern, do you really need that `else` block?
|
61
|
+
- Add correct types wherever possible, reduce `Any` occurrences as much as possible
|
62
|
+
- Reduce database calls
|
63
|
+
- Be consistent within your code, and within the rest of the codebase
|
64
|
+
- Use whitespace generously, to group and separate lines of code
|
65
|
+
- Be explicit, magic is great until it is not
|
66
|
+
|
67
|
+
### Endpoint Ordering
|
68
|
+
|
69
|
+
Try to order endpoints using CRUD so that the following order is achieved:
|
70
|
+
|
71
|
+
- Create a {resource}
|
72
|
+
- Read / Get a {resource}
|
73
|
+
- Update a {resource}
|
74
|
+
- Delete a {resource}
|
75
|
+
- Get all {resource}s
|
76
|
+
- More niche endpoints
|
77
|
+
- Deprecated endpoints
|
@@ -0,0 +1,47 @@
|
|
1
|
+
# Modern MISP - API
|
2
|
+
|
3
|
+
[](https://github.com/astral-sh/ruff) [](https://conventionalcommits.org)
|
4
|
+
|
5
|
+
## Requirements
|
6
|
+
|
7
|
+
- [Docker](https://www.docker.com) `latest-stable`
|
8
|
+
|
9
|
+
## Getting Started
|
10
|
+
|
11
|
+
Clone the project and install Python version `3.11.0`. It is recommended to install Python using [pyenv](https://github.com/pyenv/pyenv#installation). Then install all dependencies by typing `make setup` into your terminal and start your local database container using `make up`.
|
12
|
+
|
13
|
+
Create a file called `.env` and copy the contents of `.env.example` into it. Finally, start the development server using `make dev`.
|
14
|
+
|
15
|
+
You should now be able to access the api on `localhost:4000`.
|
16
|
+
|
17
|
+
Run tests using `make test` (local database container required running) or `make test/lite`.
|
18
|
+
|
19
|
+
## Setting up your IDE
|
20
|
+
|
21
|
+
Be sure to use the newly created virtual env as your interpreter (`./venv/bin/python`). Also install the [Ruff](https://docs.astral.sh/ruff/integrations/) extension for your IDE and set `Ruff` as your default code formatter. It is recommended to activate formatting your code on every save.
|
22
|
+
|
23
|
+
## Best Practices
|
24
|
+
|
25
|
+
### General Guidelines
|
26
|
+
|
27
|
+
The following are some guidelines for writing code, in no particular order:
|
28
|
+
|
29
|
+
- Try to write clean code
|
30
|
+
- Use the "early return" pattern, do you really need that `else` block?
|
31
|
+
- Add correct types wherever possible, reduce `Any` occurrences as much as possible
|
32
|
+
- Reduce database calls
|
33
|
+
- Be consistent within your code, and within the rest of the codebase
|
34
|
+
- Use whitespace generously, to group and separate lines of code
|
35
|
+
- Be explicit, magic is great until it is not
|
36
|
+
|
37
|
+
### Endpoint Ordering
|
38
|
+
|
39
|
+
Try to order endpoints using CRUD so that the following order is achieved:
|
40
|
+
|
41
|
+
- Create a {resource}
|
42
|
+
- Read / Get a {resource}
|
43
|
+
- Update a {resource}
|
44
|
+
- Delete a {resource}
|
45
|
+
- Get all {resource}s
|
46
|
+
- More niche endpoints
|
47
|
+
- Deprecated endpoints
|
@@ -0,0 +1,50 @@
|
|
1
|
+
[project]
|
2
|
+
name = "mmisp-lib"
|
3
|
+
version = "0.1.0"
|
4
|
+
description = ""
|
5
|
+
authors = []
|
6
|
+
readme = "README.md"
|
7
|
+
requires-python = ">=3.11.0"
|
8
|
+
|
9
|
+
|
10
|
+
dependencies = [
|
11
|
+
"fastapi==0.104.1",
|
12
|
+
"SQLAlchemy[asyncio]==1.4.46",
|
13
|
+
"pydantic==1.10.13",
|
14
|
+
"uvicorn==0.24.0.post1",
|
15
|
+
"python-dotenv==1.0.0",
|
16
|
+
"alembic==1.8.1",
|
17
|
+
"aiomysql==0.2.0",
|
18
|
+
"aiosqlite==0.20.0",
|
19
|
+
"PyJWT==2.8.0",
|
20
|
+
"httpx==0.26.0",
|
21
|
+
"passlib==1.7.4",
|
22
|
+
"argon2-cffi==23.1.0",
|
23
|
+
"bcrypt==4.1.2",
|
24
|
+
"nanoid==2.0.0",
|
25
|
+
"cryptography==42.0.5",
|
26
|
+
]
|
27
|
+
|
28
|
+
|
29
|
+
[project.optional-dependencies]
|
30
|
+
dev = [
|
31
|
+
"ruff==0.3.7",
|
32
|
+
"mypy==1.8.0",
|
33
|
+
"pre-commit==3.6.0",
|
34
|
+
"pytest==8.0.0",
|
35
|
+
"pytest-asyncio==0.23.5.post1",
|
36
|
+
"pytest-cov==4.1.0",
|
37
|
+
"respx==0.20.2",
|
38
|
+
"mysql-connector-python==8.3.0",
|
39
|
+
]
|
40
|
+
|
41
|
+
[tool.ruff]
|
42
|
+
fix = true
|
43
|
+
line-length = 120
|
44
|
+
required-version = "0.3.7"
|
45
|
+
select = ["E", "F", "W", "I", "ICN", "ANN"]
|
46
|
+
ignore = ["ANN002", "ANN003", "ANN401"]
|
47
|
+
src = ["src"]
|
48
|
+
|
49
|
+
[tool.coverage.run]
|
50
|
+
concurrency = ["greenlet", "thread"]
|
File without changes
|
File without changes
|
@@ -0,0 +1,34 @@
|
|
1
|
+
from typing import Any, Optional
|
2
|
+
|
3
|
+
from pydantic import BaseModel, root_validator
|
4
|
+
|
5
|
+
|
6
|
+
class AddAttributeBody(BaseModel):
|
7
|
+
type: str
|
8
|
+
value: Optional[str]
|
9
|
+
value1: Optional[str]
|
10
|
+
value2: str | None = None
|
11
|
+
event_id: str | None = None
|
12
|
+
object_id: str | None = None
|
13
|
+
object_relation: str | None = None
|
14
|
+
category: str | None = None
|
15
|
+
to_ids: bool | None = None
|
16
|
+
uuid: str | None = None
|
17
|
+
timestamp: str | None = None
|
18
|
+
distribution: str | None = None
|
19
|
+
sharing_group_id: str | None = None
|
20
|
+
comment: str | None = None
|
21
|
+
deleted: bool | None = None
|
22
|
+
disable_correlation: bool | None = None
|
23
|
+
first_seen: str | None = None
|
24
|
+
last_seen: str | None = None
|
25
|
+
|
26
|
+
@root_validator
|
27
|
+
def ensure_value_or_value1_is_set(cls, data: dict[str, Any]) -> Optional[dict[str, Any]]: # noqa: ANN101
|
28
|
+
required_values: list[str] = [str(data.get("value")), str(data.get("value1"))]
|
29
|
+
if all(item is None for item in required_values):
|
30
|
+
raise ValueError("value or value1 has to be set")
|
31
|
+
return data
|
32
|
+
|
33
|
+
class Config:
|
34
|
+
orm_mode = True
|
@@ -0,0 +1,33 @@
|
|
1
|
+
from typing import Optional
|
2
|
+
|
3
|
+
from pydantic import BaseModel, Field
|
4
|
+
|
5
|
+
|
6
|
+
class AddAttributeAttributes(BaseModel):
|
7
|
+
id: str
|
8
|
+
event_id: str
|
9
|
+
object_id: str
|
10
|
+
object_relation: Optional[str] = Field(..., nullable=True)
|
11
|
+
category: str
|
12
|
+
type: str
|
13
|
+
value: str
|
14
|
+
value1: str
|
15
|
+
value2: str
|
16
|
+
to_ids: bool
|
17
|
+
uuid: str
|
18
|
+
timestamp: str
|
19
|
+
distribution: str
|
20
|
+
sharing_group_id: str
|
21
|
+
comment: str
|
22
|
+
deleted: bool
|
23
|
+
disable_correlation: bool
|
24
|
+
first_seen: Optional[str] = Field(..., nullable=True)
|
25
|
+
last_seen: Optional[str] = Field(..., nullable=True)
|
26
|
+
attribute_tag: list[str] = Field([], alias="AttributeTag")
|
27
|
+
|
28
|
+
|
29
|
+
class AddAttributeResponse(BaseModel):
|
30
|
+
Attribute: AddAttributeAttributes
|
31
|
+
|
32
|
+
class Config:
|
33
|
+
orm_mode = True
|
@@ -0,0 +1,24 @@
|
|
1
|
+
from pydantic import BaseModel
|
2
|
+
|
3
|
+
|
4
|
+
class EditAttributeBody(BaseModel):
|
5
|
+
type: str | None = None
|
6
|
+
value: str | None = None
|
7
|
+
value1: str | None = None
|
8
|
+
value2: str | None = None
|
9
|
+
object_id: str | None = None
|
10
|
+
object_relation: str | None = None
|
11
|
+
category: str | None = None
|
12
|
+
to_ids: bool | None = None
|
13
|
+
uuid: str | None = None
|
14
|
+
timestamp: str | None = None
|
15
|
+
distribution: str | None = None
|
16
|
+
sharing_group_id: str | None = None
|
17
|
+
comment: str | None = None
|
18
|
+
deleted: bool | None = None
|
19
|
+
disable_correlation: bool | None = None
|
20
|
+
first_seen: str | None = None
|
21
|
+
last_seen: str | None = None
|
22
|
+
|
23
|
+
class Config:
|
24
|
+
orm_mode = True
|
@@ -0,0 +1,42 @@
|
|
1
|
+
from pydantic import BaseModel
|
2
|
+
|
3
|
+
|
4
|
+
class EditAttributeTag(BaseModel):
|
5
|
+
id: str
|
6
|
+
name: str
|
7
|
+
colour: str
|
8
|
+
exportable: str
|
9
|
+
user_id: str
|
10
|
+
hide_tag: bool
|
11
|
+
numerical_value: int
|
12
|
+
is_galaxy: bool
|
13
|
+
is_costum_galaxy: bool
|
14
|
+
local_only: bool
|
15
|
+
|
16
|
+
|
17
|
+
class EditAttributeAttributes(BaseModel):
|
18
|
+
id: str
|
19
|
+
event_id: str
|
20
|
+
object_id: str
|
21
|
+
object_relation: str | None = None
|
22
|
+
category: str
|
23
|
+
type: str
|
24
|
+
value: str
|
25
|
+
to_ids: bool
|
26
|
+
uuid: str
|
27
|
+
timestamp: str
|
28
|
+
distribution: str
|
29
|
+
sharing_group_id: str
|
30
|
+
comment: str | None = None
|
31
|
+
deleted: bool
|
32
|
+
disable_correlation: bool
|
33
|
+
first_seen: str | None = None
|
34
|
+
last_seen: str | None = None
|
35
|
+
tag: list[EditAttributeTag]
|
36
|
+
|
37
|
+
|
38
|
+
class EditAttributeResponse(BaseModel):
|
39
|
+
Attribute: EditAttributeAttributes
|
40
|
+
|
41
|
+
class Config:
|
42
|
+
orm_mode = True
|
@@ -0,0 +1,38 @@
|
|
1
|
+
from typing import Any, Dict, Optional
|
2
|
+
|
3
|
+
from pydantic import BaseModel, validator
|
4
|
+
|
5
|
+
|
6
|
+
class GetAllAttributesResponse(BaseModel):
|
7
|
+
id: str
|
8
|
+
event_id: str | None = None
|
9
|
+
object_id: str | None = None
|
10
|
+
object_relation: str | None = None
|
11
|
+
category: str | None = None
|
12
|
+
type: str
|
13
|
+
value1: str | None = None
|
14
|
+
value2: str | None = None
|
15
|
+
to_ids: bool | None = None
|
16
|
+
uuid: str | None = None
|
17
|
+
timestamp: str | None = None
|
18
|
+
distribution: str | None = None
|
19
|
+
sharing_group_id: str | None = None
|
20
|
+
comment: str | None = None
|
21
|
+
deleted: bool | None = None
|
22
|
+
disable_correlation: bool | None = None
|
23
|
+
first_seen: str | None = None
|
24
|
+
last_seen: str | None = None
|
25
|
+
value: str | None = None
|
26
|
+
|
27
|
+
@validator("sharing_group_id", always=True)
|
28
|
+
def check_sharing_group_id(cls, value: Any, values: Dict[str, Any]) -> Optional[int]: # noqa: ANN101
|
29
|
+
"""
|
30
|
+
If distribution equals 4, sharing_group_id will be shown.
|
31
|
+
"""
|
32
|
+
distribution = values.get("distribution", None)
|
33
|
+
if distribution == "4" and value is not None:
|
34
|
+
return value
|
35
|
+
return None
|
36
|
+
|
37
|
+
class Config:
|
38
|
+
orm_mode = True
|
@@ -0,0 +1,41 @@
|
|
1
|
+
from typing import Optional
|
2
|
+
|
3
|
+
from pydantic import BaseModel, Field
|
4
|
+
|
5
|
+
|
6
|
+
class GetAttributeTag(BaseModel):
|
7
|
+
id: str
|
8
|
+
name: str
|
9
|
+
colour: str
|
10
|
+
numerical_value: int | None = None
|
11
|
+
is_galaxy: bool
|
12
|
+
local: bool
|
13
|
+
|
14
|
+
|
15
|
+
class GetAttributeAttributes(BaseModel):
|
16
|
+
id: str
|
17
|
+
event_id: str
|
18
|
+
object_id: str
|
19
|
+
object_relation: Optional[str] = Field(..., nullable=True)
|
20
|
+
category: str
|
21
|
+
type: str
|
22
|
+
value: str
|
23
|
+
to_ids: bool
|
24
|
+
uuid: str
|
25
|
+
timestamp: str
|
26
|
+
distribution: str
|
27
|
+
sharing_group_id: str
|
28
|
+
comment: str | None = None
|
29
|
+
deleted: bool
|
30
|
+
disable_correlation: bool
|
31
|
+
first_seen: Optional[str] = Field(..., nullable=True)
|
32
|
+
last_seen: Optional[str] = Field(..., nullable=True)
|
33
|
+
event_uuid: str
|
34
|
+
tag: list[GetAttributeTag] | None = None
|
35
|
+
|
36
|
+
|
37
|
+
class GetAttributeResponse(BaseModel):
|
38
|
+
Attribute: GetAttributeAttributes
|
39
|
+
|
40
|
+
class Config:
|
41
|
+
orm_mode = True
|
@@ -0,0 +1,137 @@
|
|
1
|
+
from pydantic import BaseModel, Field
|
2
|
+
|
3
|
+
|
4
|
+
class GetAttributeStatisticsTypesResponse(BaseModel):
|
5
|
+
as_: str = Field(alias="AS")
|
6
|
+
attachment: str
|
7
|
+
authentihash: str
|
8
|
+
boolean: str
|
9
|
+
btc: str
|
10
|
+
campaign_id: str = Field(alias="campaign-id")
|
11
|
+
campaign_name: str = Field(alias="campaign-name")
|
12
|
+
comment: str
|
13
|
+
cookie: str
|
14
|
+
counter: str
|
15
|
+
cpe: str
|
16
|
+
date_of_birth: str = Field(alias="date-of-birth")
|
17
|
+
datetime: str
|
18
|
+
dns_soa_email: str = Field(alias="dns-soa-email")
|
19
|
+
domain: str
|
20
|
+
domain_ip: str = Field(alias="domain|ip")
|
21
|
+
email: str
|
22
|
+
email_attachment: str = Field(alias="email-attachment")
|
23
|
+
email_body: str = Field(alias="email-body")
|
24
|
+
email_dst: str = Field(alias="email-dst")
|
25
|
+
email_message_id: str = Field(alias="email-message-id")
|
26
|
+
email_mime_boundary: str = Field(alias="email-mime-boundary")
|
27
|
+
email_reply_to: str = Field(alias="email-reply-to")
|
28
|
+
email_src: str = Field(alias="email-src")
|
29
|
+
email_src_display_name: str = Field(alias="email-src-display-name")
|
30
|
+
email_subject: str = Field(alias="email-subject")
|
31
|
+
email_x_mailer: str = Field(alias="email-x-mailer")
|
32
|
+
filename: str
|
33
|
+
filename_pattern: str = Field(alias="filename-pattern")
|
34
|
+
filename_md5: str = Field(alias="filename|md5")
|
35
|
+
filename_sha1: str = Field(alias="filename|sha1")
|
36
|
+
filename_sha256: str = Field(alias="filename|sha256")
|
37
|
+
first_name: str = Field(alias="first-name")
|
38
|
+
float: str
|
39
|
+
full_name: str = Field(alias="full-name")
|
40
|
+
gender: str
|
41
|
+
github_repository: str = Field(alias="github-repository")
|
42
|
+
github_username: str = Field(alias="github-username")
|
43
|
+
hex: str
|
44
|
+
hostname: str
|
45
|
+
http_method: str = Field(alias="http-method")
|
46
|
+
imphash: str
|
47
|
+
ip_dst: str = Field(alias="ip-dst")
|
48
|
+
ip_dst_port: str = Field(alias="ip-dst|port")
|
49
|
+
ip_src: str = Field(alias="ip-src")
|
50
|
+
ip_src_port: str = Field(alias="ip-src|port")
|
51
|
+
ja3_fingerprint_md5: str = Field(alias="ja3-fingerprint-md5")
|
52
|
+
jabber_id: str = Field(alias="jabber-id")
|
53
|
+
jarm_fingerprint: str = Field(alias="jarm-fingerprint")
|
54
|
+
last_name: str = Field(alias="last-name")
|
55
|
+
link: str
|
56
|
+
malware_sample: str = Field(alias="malware-sample")
|
57
|
+
md5: str
|
58
|
+
mime_type: str = Field(alias="mime-type")
|
59
|
+
mobile_application_id: str = Field(alias="mobile-application-id")
|
60
|
+
mutex: str
|
61
|
+
named_pipe: str = Field(alias="named pipe")
|
62
|
+
nationality: str
|
63
|
+
other: str
|
64
|
+
passport_country: str = Field(alias="passport-country")
|
65
|
+
passport_expiration: str = Field(alias="passport-expiration")
|
66
|
+
passport_number: str = Field(alias="passport-number")
|
67
|
+
pattern_in_file: str = Field(alias="pattern-in-file")
|
68
|
+
pattern_in_memory: str = Field(alias="pattern-in-memory")
|
69
|
+
pattern_in_traffic: str = Field(alias="pattern-in-traffic")
|
70
|
+
pdb: str
|
71
|
+
pehash: str
|
72
|
+
phone_number: str = Field(alias="phone-number")
|
73
|
+
place_of_birth: str = Field(alias="place-of-birth")
|
74
|
+
port: str
|
75
|
+
regkey: str
|
76
|
+
regkey_value: str = Field(alias="regkey|value")
|
77
|
+
sha1: str
|
78
|
+
sha224: str
|
79
|
+
sha256: str
|
80
|
+
sha384: str
|
81
|
+
sha512: str
|
82
|
+
sigma: str
|
83
|
+
size_in_bytes: str = Field(alias="size-in-bytes")
|
84
|
+
snort: str
|
85
|
+
ssdeep: str
|
86
|
+
stix2_pattern: str = Field(alias="stix2-pattern")
|
87
|
+
target_external: str = Field(alias="target-external")
|
88
|
+
target_location: str = Field(alias="target-location")
|
89
|
+
target_machine: str = Field(alias="target-machine")
|
90
|
+
target_org: str = Field(alias="target-org")
|
91
|
+
target_user: str = Field(alias="target-user")
|
92
|
+
text: str
|
93
|
+
threat_actor: str = Field(alias="threat-actor")
|
94
|
+
tlsh: str
|
95
|
+
uri: str
|
96
|
+
url: str
|
97
|
+
user_agent: str = Field(alias="user-agent")
|
98
|
+
vhash: str
|
99
|
+
vulnerability: str
|
100
|
+
weakness: str
|
101
|
+
whois_creation_date: str = Field(alias="whois-creation-date")
|
102
|
+
whois_registrant_email: str = Field(alias="whois-registrant-email")
|
103
|
+
whois_registrant_name: str = Field(alias="whois-registrant-name")
|
104
|
+
whois_registrant_org: str = Field(alias="whois-registrant-org")
|
105
|
+
whois_registrant_phone: str = Field(alias="whois-registrant-phone")
|
106
|
+
whois_registrar: str = Field(alias="whois-registrar")
|
107
|
+
windows_scheduled_task: str = Field(alias="windows-scheduled-task")
|
108
|
+
windows_service_name: str = Field(alias="windows-service-name")
|
109
|
+
x509_fingerprint_md5: str = Field(alias="x509-fingerprint-md5")
|
110
|
+
x509_fingerprint_sha1: str = Field(alias="x509-fingerprint-sha1")
|
111
|
+
x509_fingerprint_sha256: str = Field(alias="x509-fingerprint-sha256")
|
112
|
+
yara: str
|
113
|
+
|
114
|
+
class Config:
|
115
|
+
orm_mode = True
|
116
|
+
|
117
|
+
|
118
|
+
class GetAttributeStatisticsCategoriesResponse(BaseModel):
|
119
|
+
antivirus_detection: str = Field(alias="Antivirus detection")
|
120
|
+
artifacts_dropped: str = Field(alias="Artifacts dropped")
|
121
|
+
attribution: str = Field(alias="Attribution")
|
122
|
+
external_analysis: str = Field(alias="External analysis")
|
123
|
+
financial_fraud: str = Field(alias="Financial fraud")
|
124
|
+
internal_reference: str = Field(alias="Internal reference")
|
125
|
+
network_activity: str = Field(alias="Network activity")
|
126
|
+
other: str = Field(alias="Other")
|
127
|
+
payload_delivery: str = Field(alias="Payload delivery")
|
128
|
+
payload_installation: str = Field(alias="Payload installation")
|
129
|
+
payload_type: str = Field(alias="Payload type")
|
130
|
+
persistence_mechanism: str = Field(alias="Persistence mechanism")
|
131
|
+
person: str = Field(alias="Person")
|
132
|
+
social_network: str = Field(alias="Social network")
|
133
|
+
support__tool: str = Field(alias="Support Tool")
|
134
|
+
targeting_data: str = Field(alias="Targeting data")
|
135
|
+
|
136
|
+
class Config:
|
137
|
+
orm_mode = True
|
@@ -0,0 +1,29 @@
|
|
1
|
+
from pydantic import BaseModel
|
2
|
+
|
3
|
+
from mmisp.lib.attributes import AttributeCategories, default_category, inverted_categories, to_ids
|
4
|
+
|
5
|
+
|
6
|
+
class GetDescribeTypesAttributes(BaseModel):
|
7
|
+
sane_defaults: dict = {}
|
8
|
+
for k, v in to_ids.items():
|
9
|
+
sane_defaults.update(
|
10
|
+
{
|
11
|
+
k: {
|
12
|
+
"default_category": default_category[k],
|
13
|
+
"to_ids": v,
|
14
|
+
}
|
15
|
+
}
|
16
|
+
)
|
17
|
+
|
18
|
+
types: list[str] = list(default_category.keys())
|
19
|
+
|
20
|
+
categories: list[str] = [member.value for member in AttributeCategories]
|
21
|
+
|
22
|
+
category_type_mappings: dict = inverted_categories
|
23
|
+
|
24
|
+
|
25
|
+
class GetDescribeTypesResponse(BaseModel):
|
26
|
+
result: GetDescribeTypesAttributes
|
27
|
+
|
28
|
+
class Config:
|
29
|
+
orm_mode = True
|
@@ -0,0 +1,25 @@
|
|
1
|
+
from pydantic import BaseModel
|
2
|
+
|
3
|
+
|
4
|
+
class RestoreAttributeResponse(BaseModel):
|
5
|
+
id: str
|
6
|
+
event_id: str
|
7
|
+
object_id: str
|
8
|
+
object_relation: str
|
9
|
+
category: str
|
10
|
+
type: str
|
11
|
+
value: str
|
12
|
+
to_ids: bool
|
13
|
+
uuid: str
|
14
|
+
timestamp: str
|
15
|
+
distribution: str
|
16
|
+
sharing_group_id: str
|
17
|
+
comment: str
|
18
|
+
deleted: bool
|
19
|
+
disable_correlation: bool
|
20
|
+
first_seen: str
|
21
|
+
last_seen: str
|
22
|
+
event_uuid: str # new
|
23
|
+
|
24
|
+
class Config:
|
25
|
+
orm_mode = True
|