Skip to content
Open
Show file tree
Hide file tree
Changes from all commits
Commits
Show all changes
67 commits
Select commit Hold shift + click to select a range
9a33abf
Started implementation of POST /api/v2/alerts-filters
Elise17 Oct 8, 2025
b7088fd
Fixed analysis check
Elise17 Oct 8, 2025
103ed2c
Added function _load
Elise17 Oct 8, 2025
82bfec6
Deprecated endpoint POST /filters/add in favor of POST /api/v2/alerts…
Elise17 Oct 8, 2025
5b1290e
Added test create alert when filter data is missing
Elise17 Oct 8, 2025
ea45b99
Added test test_create_alert_filter_should_return_filter_type
Elise17 Oct 8, 2025
4c5ddd6
Added test_create_alert_filter_should_return_filter_name
Elise17 Oct 8, 2025
0a0f63d
Added test_create_alert_filter_should_return_in_filter_data_alert_title
Elise17 Oct 8, 2025
af0bf2b
Started implementation of GET /api/v2/alerts-filters/{identifier}
Elise17 Oct 17, 2025
0c911fe
Fixed check analysis
Elise17 Oct 17, 2025
8559ad7
Fixed importation problem
Elise17 Oct 17, 2025
7440b09
Fixed static analysis
Elise17 Oct 17, 2025
0690eb0
Removed user in test
Elise17 Oct 17, 2025
1129b73
Added test_get_alert_filter_should_return_filter_name
Elise17 Oct 17, 2025
97a89e5
Deprecated endpoint GET /filters/{identifier}
Elise17 Oct 17, 2025
622b46a
Added test_get_alert_filter_should_return_404
Elise17 Oct 17, 2025
9a1fffd
Added test_get_alert_filter_should_return_404_when_user_has_not_creat…
Elise17 Oct 17, 2025
e4b4998
Fixed static analysis
Elise17 Oct 17, 2025
69e38c8
Started implementation of PUT /api/v2/alerts-filters/{identifier}
Elise17 Oct 21, 2025
ec809ef
Fixed static analysis
Elise17 Oct 21, 2025
f438d3b
Added test_update_alert_filter_should_return_filter_name
Elise17 Oct 21, 2025
930e94c
Added test_update_alert_filter_should_return_filter_description
Elise17 Oct 21, 2025
120bed5
Added test_update_alert_filter_should_return_filter_type
Elise17 Oct 21, 2025
48c0957
Added test_update_alert_filter_should_return_filter_data_alert_title
Elise17 Oct 21, 2025
657d441
Added test_update_alert_filter_should_return_404_when_alert_filter_is…
Elise17 Oct 21, 2025
1008f29
Removed identifietr in test_update_alert_filter_should_return_404_whe…
Elise17 Oct 21, 2025
78234ef
Deprecated endpoint POST /filters/update/{identifier}
Elise17 Oct 21, 2025
eb541cb
Started implmentation of endpoint DELETE /api/v2/alerts-filters/{iden…
Elise17 Oct 21, 2025
745739c
Added test_delete_alert_filter_should_return_404_when_alert_not_found
Elise17 Oct 21, 2025
74bf4ea
test_get_alert_filter_should_return_404_after_delete_alert_filter
Elise17 Oct 21, 2025
157d749
Deprecated endpoint DELETE /api/v2/alerts-filters/{identifier}
Elise17 Oct 21, 2025
9a5a4c7
Fixed check analysis
Elise17 Oct 21, 2025
cb3ec88
Changed indentation and added ValidationError
Elise17 Oct 21, 2025
8d345f3
Changed indentation and added ValidationError
Elise17 Oct 21, 2025
b68b34c
Added new test test_update_alert_filter_should_return_400
Elise17 Oct 21, 2025
2dbfb95
Renamed method
c8y3 Oct 6, 2025
d1986e9
Renamed method
c8y3 Oct 6, 2025
7a8cfc5
Aligned method call
c8y3 Oct 6, 2025
ddef892
Started implementation of GET /api/v2/manage/customers/{identifier}
c8y3 Oct 6, 2025
6096f3b
Moved code down into persistence layer
c8y3 Oct 8, 2025
c7c77d0
Removed unused imports
c8y3 Oct 8, 2025
115d9ae
Added tow new import constraints: do not import marshables and do not…
c8y3 Oct 8, 2025
497135d
One import per line
c8y3 Oct 8, 2025
2651462
Removed dead code
c8y3 Oct 8, 2025
358d2d1
One import per line
c8y3 Oct 8, 2025
2c041aa
Following calling conventions
c8y3 Oct 8, 2025
3a6204b
Moved code down into the business and persistence layers
c8y3 Oct 8, 2025
acd242b
Early return
c8y3 Oct 8, 2025
cef2751
Simple quotes
c8y3 Oct 8, 2025
3fe05d1
Introduced method to get a customer by its name
c8y3 Oct 8, 2025
99842fc
Ruff warning
c8y3 Oct 8, 2025
50b4982
Added method to create a customer in the business layer
c8y3 Oct 8, 2025
3282472
Added a TODO
c8y3 Oct 8, 2025
7791840
Do not import iris_current_user from app.business.cases
c8y3 Oct 8, 2025
573a842
Removed unnecessary method parameter
c8y3 Oct 8, 2025
5411f32
Parameter need not be optional
c8y3 Oct 8, 2025
c1a2036
Extracted method
c8y3 Oct 8, 2025
410cdac
Extracted method
c8y3 Oct 8, 2025
f009aba
Removed one call to iris_current_user from iris_engine
c8y3 Oct 8, 2025
e1e3691
Moved code down into models
c8y3 Oct 8, 2025
1754dbf
Moved test .env file at the top level as .env.tests.model
c8y3 Oct 22, 2025
7ceee59
Renamed method to follow conventions
c8y3 Oct 24, 2025
e73af4d
GET /api/v2/customers/{identifier} should return 404 when it doesn't …
c8y3 Oct 24, 2025
30f49e2
Renamed test
c8y3 Oct 24, 2025
31e8495
Deprecate GET /manage/customers/{client_id}
c8y3 Oct 24, 2025
f3163c8
GET /api/v2/manage/customers/{identifier} returns 403 when user has n…
c8y3 Oct 24, 2025
df5de76
Removed methods which seem to be dead
c8y3 Oct 24, 2025
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
File renamed without changes.
16 changes: 5 additions & 11 deletions .github/workflows/ci.yml
Original file line number Diff line number Diff line change
Expand Up @@ -131,10 +131,8 @@ jobs:
uses: actions/checkout@v4
- name: Start development server
run: |
# Even though, we use --env-file option when running docker compose, this is still necessary, because the compose has a env_file attribute :(
# TODO should move basic.env file, which is in directory tests, up. It's used in several places. Maybe, rename it into dev.env
cp tests/data/basic.env .env
docker compose --file docker-compose.dev.yml --env-file tests/data/basic.env up --detach --wait
cp .env.tests.model .env
docker compose --file docker-compose.dev.yml up --detach --wait
- name: Generate GraphQL documentation
run: |
npx spectaql@^3.0.2 source/spectaql/config.yml
Expand Down Expand Up @@ -170,9 +168,7 @@ jobs:
uses: actions/checkout@v4
- name: Start development server
run: |
# Even though, we use --env-file option when running docker compose, this is still necessary, because the compose has a env_file attribute :(
# TODO should move basic.env file, which is in directory tests, up. It's used in several places. Maybe, rename it into dev.env
cp tests/data/basic.env .env
cp .env.tests.model .env
docker compose --file docker-compose.dev.yml up --detach --wait
- name: Inspect development server start failure
if: ${{ failure() || cancelled() }}
Expand Down Expand Up @@ -226,8 +222,7 @@ jobs:
- name: Check out iris
uses: actions/checkout@v4
- name: Set up .env file
# TODO should move basic.env file, which is in directory tests, up. It's used in several places. Maybe, rename it into dev.env?
run: cp tests/data/basic.env .env
run: cp .env.tests.model .env
- name: Run tests
working-directory: tests_database_migration
run: |
Expand Down Expand Up @@ -277,8 +272,7 @@ jobs:
run: npx playwright install chromium firefox
- name: Start development server
run: |
# TODO should move basic.env file, which is in directory tests, up. It's used in several places. Maybe, rename it into dev.env
cp tests/data/basic.env .env
cp .env.tests.model .env
docker compose --file docker-compose.dev.yml up --detach --wait
- name: Run end to end tests
working-directory: e2e
Expand Down
16 changes: 15 additions & 1 deletion pyproject.toml
Original file line number Diff line number Diff line change
Expand Up @@ -24,7 +24,7 @@ allow_indirect_imports = true
[[tool.importlinter.contracts]]
name = "Do not import API layer from the business layer"
type = "forbidden"
source_modules = ["app.business.access_controls", "app.business.assets"]
source_modules = ["app.business.access_controls", "app.business.assets", "app.business.cases"]
forbidden_modules = "app.blueprints.iris_user"
allow_indirect_imports = true

Expand All @@ -42,3 +42,17 @@ source_modules = "app.datamgmt.dashboard"
forbidden_modules = "app.blueprints.iris_user"
allow_indirect_imports = true

[[tool.importlinter.contracts]]
name = "Do not import marshables from the persistence layer"
type = "forbidden"
source_modules = "app.datamgmt.manage.manage_case_state_db"
forbidden_modules = "app.schema.marshables"
allow_indirect_imports = true

[[tool.importlinter.contracts]]
name = "Do not import the engine from the persistence layer"
type = "forbidden"
source_modules = "app.datamgmt.case"
forbidden_modules = "app.iris_engine"
allow_indirect_imports = true

2 changes: 1 addition & 1 deletion source/app/blueprints/graphql/cases.py
Original file line number Diff line number Diff line change
Expand Up @@ -115,7 +115,7 @@ def mutate(root, info, name, description, client_id, soc_id=None, classification
schema = CaseSchema()
case = schema.load(request_data)
case_template_id = request_data.pop('case_template_id', None)
result = cases_create(case, case_template_id)
result = cases_create(iris_current_user, case, case_template_id)
return CaseCreate(case=result)


Expand Down
4 changes: 3 additions & 1 deletion source/app/blueprints/pages/manage/manage_cases_routes.py
Original file line number Diff line number Diff line change
Expand Up @@ -41,6 +41,7 @@
from app.blueprints.access_controls import ac_api_return_access_denied, ac_fast_check_current_user_has_case_access
from app.blueprints.access_controls import ac_requires
from app.blueprints.responses import response_error
from app.schema.marshables import CaseStateSchema

manage_cases_blueprint = Blueprint('manage_case',
__name__,
Expand Down Expand Up @@ -81,6 +82,7 @@ def _details_case(cur_id: int, caseid: int, url_redir: bool) -> Union[str, Respo

case_classifications = get_case_classifications_list()
case_states = get_case_states_list()
dumped_case_states = CaseStateSchema(many=True).dump(case_states)
user_is_server_administrator = ac_current_user_has_permission(Permissions.server_administrator)

customers = get_client_list(current_user_id=iris_current_user.id,
Expand All @@ -92,7 +94,7 @@ def _details_case(cur_id: int, caseid: int, url_redir: bool) -> Union[str, Respo
form = FlaskForm()

return render_template("modal_case_info_from_case.html", data=res, form=form, protagonists=protagonists,
case_classifications=case_classifications, case_states=case_states, customers=customers,
case_classifications=case_classifications, case_states=dumped_case_states, customers=customers,
severities=severities)


Expand Down
4 changes: 2 additions & 2 deletions source/app/blueprints/pages/manage/manage_customers_routes.py
Original file line number Diff line number Diff line change
Expand Up @@ -22,7 +22,7 @@
from flask import url_for
from flask_wtf import FlaskForm

from app.datamgmt.client.client_db import get_client
from app.datamgmt.client.client_db import get_customer
from app.datamgmt.client.client_db import get_client_api
from app.datamgmt.client.client_db import get_client_contact
from app.datamgmt.client.client_db import get_client_contacts
Expand Down Expand Up @@ -115,7 +115,7 @@ def view_customer_modal(client_id, caseid, url_redir):
return redirect(url_for('manage_customers.manage_customers', cid=caseid))

form = AddCustomerForm()
customer = get_client(client_id)
customer = get_customer(client_id)
if not customer:
return response_error("Invalid Customer ID")

Expand Down
4 changes: 2 additions & 2 deletions source/app/blueprints/rest/alerts_routes.py
Original file line number Diff line number Diff line change
Expand Up @@ -606,7 +606,7 @@ def alerts_escalate_route(alert_id) -> Response:
if not case:
return response_error('Failed to create case from alert')

ac_set_new_case_access(None, case.case_id, case.client_id)
ac_set_new_case_access(iris_current_user, case.case_id, case.client_id)

case = call_modules_hook('on_postload_case_create', data=case)

Expand Down Expand Up @@ -884,7 +884,7 @@ def alerts_batch_escalate_route() -> Response:
if not case:
return response_error('Failed to create case from alert')

ac_set_new_case_access(None, case.case_id, case.client_id)
ac_set_new_case_access(iris_current_user, case.case_id, case.client_id)

case = call_modules_hook('on_postload_case_create', data=case)

Expand Down
2 changes: 2 additions & 0 deletions source/app/blueprints/rest/api_v2_routes.py
Original file line number Diff line number Diff line change
Expand Up @@ -31,6 +31,7 @@
from app.blueprints.rest.v2.tags import tags_blueprint
from app.blueprints.rest.v2.tasks import tasks_blueprint
from app.blueprints.rest.v2.profile import profile_blueprint
from app.blueprints.rest.v2.alerts_filters import alerts_filters_blueprint


# Create root /api/v2 blueprint
Expand All @@ -50,3 +51,4 @@
rest_v2_blueprint.register_blueprint(manage_v2_blueprint)
rest_v2_blueprint.register_blueprint(tags_blueprint)
rest_v2_blueprint.register_blueprint(profile_blueprint)
rest_v2_blueprint.register_blueprint(alerts_filters_blueprint)
7 changes: 5 additions & 2 deletions source/app/blueprints/rest/case/case_ioc_routes.py
Original file line number Diff line number Diff line change
Expand Up @@ -51,12 +51,14 @@
from app.models.authorization import CaseAccessLevel
from app.schema.marshables import CommentSchema
from app.schema.marshables import IocSchema
from app.blueprints.access_controls import ac_requires_case_identifier, ac_fast_check_current_user_has_case_access
from app.blueprints.access_controls import ac_requires_case_identifier
from app.blueprints.access_controls import ac_fast_check_current_user_has_case_access
from app.blueprints.access_controls import ac_api_requires
from app.blueprints.access_controls import ac_api_return_access_denied
from app.blueprints.responses import response_error
from app.blueprints.responses import response_success
from app.iris_engine.module_handler.module_handler import call_deprecated_on_preload_modules_hook
from app.iris_engine.access_control.utils import ac_get_fast_user_cases_access

case_ioc_rest_blueprint = Blueprint('case_ioc_rest', __name__)

Expand All @@ -74,7 +76,8 @@ def case_list_ioc(caseid):
out = ioc._asdict()

# Get links of the IoCs seen in other cases
ial = get_ioc_links(ioc.ioc_id)
user_search_limitations = ac_get_fast_user_cases_access(iris_current_user.id)
ial = get_ioc_links(ioc.ioc_id, user_search_limitations)

out['link'] = [row._asdict() for row in ial]
# Legacy, must be changed next version
Expand Down
7 changes: 6 additions & 1 deletion source/app/blueprints/rest/filters_routes.py
Original file line number Diff line number Diff line change
Expand Up @@ -20,19 +20,21 @@
from werkzeug import Response

from app import db
from app.blueprints.iris_user import iris_current_user
from app.datamgmt.filters.filters_db import get_filter_by_id
from app.datamgmt.filters.filters_db import list_filters_by_type
from app.iris_engine.utils.tracker import track_activity
from app.schema.marshables import SavedFilterSchema
from app.blueprints.iris_user import iris_current_user
from app.blueprints.access_controls import ac_api_requires
from app.blueprints.responses import response_success
from app.blueprints.responses import response_error
from app.blueprints.rest.endpoints import endpoint_deprecated

saved_filters_rest_blueprint = Blueprint('saved_filters_rest', __name__)


@saved_filters_rest_blueprint.route('/filters/add', methods=['POST'])
@endpoint_deprecated('POST', '/api/v2/alerts-filters')
@ac_api_requires()
def filters_add_route() -> Response:
"""
Expand Down Expand Up @@ -66,6 +68,7 @@ def filters_add_route() -> Response:


@saved_filters_rest_blueprint.route('/filters/update/<int:filter_id>', methods=['POST'])
@endpoint_deprecated('PUT', '/api/v2/alerts-filters/{identifier}')
@ac_api_requires()
def filters_update_route(filter_id) -> Response:
"""
Expand Down Expand Up @@ -99,6 +102,7 @@ def filters_update_route(filter_id) -> Response:


@saved_filters_rest_blueprint.route('/filters/delete/<int:filter_id>', methods=['POST'])
@endpoint_deprecated('DELETE', '/api/v2/alerts-filters/{identifier}')
@ac_api_requires()
def filters_delete_route(filter_id) -> Response:
"""
Expand Down Expand Up @@ -128,6 +132,7 @@ def filters_delete_route(filter_id) -> Response:


@saved_filters_rest_blueprint.route('/filters/<int:filter_id>', methods=['GET'])
@endpoint_deprecated('GET', '/api/v2/alerts-filters/{identifier}')
@ac_api_requires()
def filters_get_route(filter_id) -> Response:
"""
Expand Down
3 changes: 2 additions & 1 deletion source/app/blueprints/rest/manage/manage_case_state.py
Original file line number Diff line number Diff line change
Expand Up @@ -45,7 +45,8 @@ def list_case_state() -> Response:
Flask Response object

"""
l_cl = get_case_states_list()
case_states = get_case_states_list()
l_cl = CaseStateSchema(many=True).dump(case_states)

return response_success("", data=l_cl)

Expand Down
2 changes: 1 addition & 1 deletion source/app/blueprints/rest/manage/manage_cases_routes.py
Original file line number Diff line number Diff line change
Expand Up @@ -251,7 +251,7 @@ def api_add_case():
request_data = call_deprecated_on_preload_modules_hook('case_create', request.get_json(), None)
case = case_schema.load(request_data)
case_template_id = request_data.pop('case_template_id', None)
result = cases_create(case, case_template_id)
result = cases_create(iris_current_user, case, case_template_id)
return response_success('Case created', data=case_schema.dump(result))
except ValidationError as e:
raise response_error('Data error', e.messages)
Expand Down
11 changes: 6 additions & 5 deletions source/app/blueprints/rest/manage/manage_customers_routes.py
Original file line number Diff line number Diff line change
Expand Up @@ -25,11 +25,11 @@
from app import ac_current_user_has_permission
from app.blueprints.access_controls import ac_api_requires
from app.blueprints.iris_user import iris_current_user
from app.datamgmt.client.client_db import create_client
from app.datamgmt.client.client_db import create_customer
from app.datamgmt.client.client_db import create_contact
from app.datamgmt.client.client_db import delete_client
from app.datamgmt.client.client_db import delete_contact
from app.datamgmt.client.client_db import get_client
from app.datamgmt.client.client_db import get_customer
from app.datamgmt.client.client_db import get_client_api
from app.datamgmt.client.client_db import get_client_cases
from app.datamgmt.client.client_db import get_client_contacts
Expand Down Expand Up @@ -62,6 +62,7 @@ def list_customers():


@manage_customers_rest_blueprint.route('/manage/customers/<int:client_id>', methods=['GET'])
@endpoint_deprecated('GET', '/api/v2/manage/customers/{identifier}')
@ac_api_requires(Permissions.customers_read)
@ac_api_requires_client_access()
def view_customer(client_id):
Expand All @@ -81,7 +82,7 @@ def customer_update_contact(client_id, contact_id):
if not request.is_json:
return response_error("Invalid request")

if not get_client(client_id):
if not get_customer(client_id):
return response_error(f"Invalid Customer ID {client_id}")

try:
Expand Down Expand Up @@ -110,7 +111,7 @@ def customer_add_contact(client_id):
if not request.is_json:
return response_error("Invalid request")

if not get_client(client_id):
if not get_customer(client_id):
return response_error(f"Invalid Customer ID {client_id}")

try:
Expand Down Expand Up @@ -250,7 +251,7 @@ def add_customers():
try:
customer = customer_schema.load(request.json)

create_client(customer)
create_customer(customer)
except ValidationError as e:
return response_error(msg='Error adding customer', data=e.messages)
except Exception as e:
Expand Down
4 changes: 2 additions & 2 deletions source/app/blueprints/rest/v2/alerts.py
Original file line number Diff line number Diff line change
Expand Up @@ -157,7 +157,7 @@ def create(self):
except BusinessProcessingError as e:
return response_api_error(e.get_message(), data=e.get_data())

def get(self, identifier):
def read(self, identifier):

try:
alert = alerts_get(iris_current_user, identifier)
Expand Down Expand Up @@ -255,7 +255,7 @@ def create_alert():
@alerts_blueprint.get('/<int:identifier>')
@ac_api_requires(Permissions.alerts_read)
def get_alert(identifier):
return alerts_operations.get(identifier)
return alerts_operations.read(identifier)


@alerts_blueprint.put('/<int:identifier>')
Expand Down
Loading
Loading