-
Notifications
You must be signed in to change notification settings - Fork 77
feat: Add global REQUIRE_REASONS config option #378
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
base: main
Are you sure you want to change the base?
Changes from all commits
File filter
Filter by extension
Conversations
Jump to
Diff view
Diff view
There are no files selected for viewing
| Original file line number | Diff line number | Diff line change | ||||||||||||||||||||||||||
|---|---|---|---|---|---|---|---|---|---|---|---|---|---|---|---|---|---|---|---|---|---|---|---|---|---|---|---|---|
|
|
@@ -43,7 +43,7 @@ import { | |||||||||||||||||||||||||||
| } from '../../api/apiSchemas'; | ||||||||||||||||||||||||||||
| import {canManageGroup} from '../../authorization'; | ||||||||||||||||||||||||||||
| import {minTagTime, minTagTimeGroups} from '../../helpers'; | ||||||||||||||||||||||||||||
| import accessConfig from '../../config/accessConfig'; | ||||||||||||||||||||||||||||
| import accessConfig, {requireReasons} from '../../config/accessConfig'; | ||||||||||||||||||||||||||||
|
|
||||||||||||||||||||||||||||
| dayjs.extend(IsSameOrBefore); | ||||||||||||||||||||||||||||
|
|
||||||||||||||||||||||||||||
|
|
@@ -442,6 +442,7 @@ function CreateRequestContainer(props: CreateRequestContainerProps) { | |||||||||||||||||||||||||||
| name="reason" | ||||||||||||||||||||||||||||
| multiline | ||||||||||||||||||||||||||||
| rows={4} | ||||||||||||||||||||||||||||
| required={requireReasons} | ||||||||||||||||||||||||||||
| validation={{maxLength: 1024}} | ||||||||||||||||||||||||||||
|
||||||||||||||||||||||||||||
| validation={{maxLength: 1024}} | |
| validation={{ | |
| maxLength: 1024, | |
| validate: (value) => { | |
| if (!requireReasons) { | |
| return true; | |
| } | |
| if (typeof value !== 'string') { | |
| return 'Reason is required'; | |
| } | |
| return value.trim().length > 0 || 'Reason is required'; | |
| }, | |
| }} |
| Original file line number | Diff line number | Diff line change |
|---|---|---|
| @@ -1,3 +1,4 @@ | ||
| import pytest | ||
| from datetime import datetime, timedelta | ||
| from typing import Any | ||
|
|
||
|
|
@@ -807,3 +808,41 @@ def test_auto_resolve_create_access_request_with_time_limit_constraint_tag( | |
| assert user == kwargs["requester"] | ||
| assert len(kwargs["group_tags"]) == 1 | ||
| assert tag in kwargs["group_tags"] | ||
|
|
||
|
|
||
| @pytest.mark.parametrize("app", [{"REQUIRE_REASONS": True}, {"REQUIRE_REASONS": False}], indirect=True) | ||
| def test_create_access_request_require_reasons( | ||
| app: Flask, client: FlaskClient, db: SQLAlchemy, okta_group: OktaGroup | ||
| ) -> None: | ||
| require_reasons = app.config.get("REQUIRE_REASONS", False) | ||
| access_requests_url = url_for("api-access-requests.access_requests") | ||
|
|
||
| db.session.add(okta_group) | ||
| db.session.commit() | ||
|
|
||
| if require_reasons: | ||
| data = { | ||
| "group_id": okta_group.id, | ||
| "group_owner": False, | ||
| "reason": "", | ||
| } | ||
| rep = client.post(access_requests_url, json=data) | ||
| assert rep.status_code == 400 | ||
| assert "Reason must be between 1 and 1024 characters" in str(rep.get_json()) | ||
|
|
||
| data["reason"] = " " | ||
| rep = client.post(access_requests_url, json=data) | ||
| assert rep.status_code == 400 | ||
| assert "Reason must be between 1 and 1024 characters" in str(rep.get_json()) | ||
|
|
||
| data["reason"] = "Valid reason" | ||
| rep = client.post(access_requests_url, json=data) | ||
| assert rep.status_code == 201 | ||
| else: | ||
| data = { | ||
| "group_id": okta_group.id, | ||
| "group_owner": False, | ||
| "reason": "", | ||
| } | ||
| rep = client.post(access_requests_url, json=data) | ||
| assert rep.status_code == 201 | ||
|
Comment on lines
+813
to
+848
|
||
There was a problem hiding this comment.
Choose a reason for hiding this comment
The reason will be displayed to describe this comment to others. Learn more.
When REQUIRE_REASONS is enabled and the client explicitly sends JSON null for reason, this branch calls self.fail("required"), which produces Marshmallow’s generic “Missing data for required field.” message. That’s inconsistent with the other reason validation errors and with the intended “non-empty, max 1024” rule. Consider raising a consistent ValidationError for the None/null case (e.g., the same message used for empty/whitespace).