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

Create User Invitation API #35575

Open
wants to merge 40 commits into
base: master
Choose a base branch
from
Open
Show file tree
Hide file tree
Changes from 1 commit
Commits
Show all changes
40 commits
Select commit Hold shift + click to select a range
ca1ecbf
bug: preoperty does not need to be invoked. Also missing argument
Jtang-1 Dec 20, 2024
ce6056f
bug: correctly handle "None" vs "''" inputs.
Jtang-1 Dec 30, 2024
cbaf5c1
refactor: the validation in LocationValidator is only applicable if l…
Jtang-1 Dec 30, 2024
62d503e
adds validation for required fields and distinguinsh allowed paramete…
Jtang-1 Dec 31, 2024
beb96d3
require primary and assigned locations to be provided at the same tim…
Jtang-1 Dec 31, 2024
fe413ee
set up InvitationResource
Jtang-1 Jan 1, 2025
1652405
bug: these values should be updated even if there is an existing Invi…
Jtang-1 Jan 1, 2025
e6648ab
feat: create access function for coordinating all validation
Jtang-1 Jan 1, 2025
976b6fd
feat: perform validation upon post
Jtang-1 Jan 1, 2025
660d7b8
feat: create invitation upon post
Jtang-1 Jan 1, 2025
054444b
bug: cache only the portion that takes long. The filtering varies per…
Jtang-1 Jan 1, 2025
e5f7080
dehydrate fields to display string representation of objects
Jtang-1 Jan 2, 2025
2671b90
move InvitationResource to v1
Jtang-1 Jan 2, 2025
42a365f
Merge branch 'master' into jt/create_user_invitation_api
Jtang-1 Jan 3, 2025
dcf7e2d
test invitation resource post
Jtang-1 Jan 3, 2025
6736e25
spacing fix
Jtang-1 Jan 3, 2025
1069011
skip validation of tableau groups and tableau role if there is no input
Jtang-1 Jan 3, 2025
6bbe446
fix test failure for test_simple_is_valid
Jtang-1 Jan 3, 2025
c47ea27
test: set up profile to avoid mocking
Jtang-1 Jan 3, 2025
2c53356
fix: prevents user data from being set directly if it's already defin…
Jtang-1 Jan 3, 2025
b1f5659
bug: the kwargs are used to match and the default is used to update o…
Jtang-1 Jan 3, 2025
3cca0a2
for a webuser, its email should be used not its username
Jtang-1 Jan 7, 2025
441c4cd
prefactor: extract out getting location ids from sitecode so that the…
Jtang-1 Jan 7, 2025
45b6d91
use location_id isn't of location site code as the parameter input. T…
Jtang-1 Jan 7, 2025
5ea1f51
bug: needs the location ids not the location object
Jtang-1 Jan 7, 2025
8443b53
bug: correctly handle if error is a lazytext
Jtang-1 Jan 7, 2025
3df5eef
Merge branch 'master' into jt/create_user_invitation_api
Jtang-1 Jan 7, 2025
dae8ced
test: update to support location id as input instead of sitecode
Jtang-1 Jan 7, 2025
2e2e06e
test: update test for call to new validation function
Jtang-1 Jan 7, 2025
33ca737
test: update parameters for switching to location ids instead of site…
Jtang-1 Jan 7, 2025
e5dc28d
refactor/bug: parameter names for api and invite won't always align s…
Jtang-1 Jan 7, 2025
37104f3
define a dataclass to consolidate api parameter inputs
Jtang-1 Jan 9, 2025
24f97a1
delete print statement
Jtang-1 Jan 9, 2025
180055c
bug: use data from spec after it has been popped
Jtang-1 Jan 9, 2025
ceffe61
Merge branch 'master' into jt/create_user_invitation_api
Jtang-1 Jan 14, 2025
09d6a55
clarify error message for conflicting user data and profile
Jtang-1 Jan 14, 2025
8927a13
remove fluff
Jtang-1 Jan 14, 2025
c91c1e8
avoid unnecessary fetch of primary location
Jtang-1 Jan 16, 2025
272b854
test: update assertion string
Jtang-1 Jan 16, 2025
de5e846
delete file that was accidently added
Jtang-1 Jan 16, 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
5 changes: 5 additions & 0 deletions corehq/apps/api/tests/test_validation.py
Original file line number Diff line number Diff line change
Expand Up @@ -5,6 +5,7 @@
from corehq.apps.custom_data_fields.models import (
CustomDataFieldsDefinition,
CustomDataFieldsProfile,
Field,
)
from corehq.apps.domain.models import Domain
from corehq.apps.users.models import WebUser
Expand Down Expand Up @@ -124,6 +125,10 @@ def test_validate_profile_with_no_profile_input(self):
self.definition.profile_required_for_user_type = []
self.definition.save()

def test_validate_profile_with_conflicting_user_data(self):
self.assertEqual(self.validator.validate_custom_data_with_profile({'imaginary': 'yes'}, 'character'),
["'imaginary' cannot be set directly"])

def test_validate_email(self):
self.assertIsNone(self.validator.validate_email("[email protected]", True))

Expand Down
21 changes: 20 additions & 1 deletion corehq/apps/api/validation.py
Original file line number Diff line number Diff line change
Expand Up @@ -17,6 +17,7 @@
)
from corehq.apps.users.validation import validate_primary_location_assignment
from corehq.apps.registration.validation import AdminInvitesUserFormValidator
from corehq.apps.custom_data_fields.models import PROFILE_SLUG


class WebUserResourceValidator():
Expand All @@ -33,6 +34,7 @@ def is_valid(self, data, is_post):
(self.validate_role, [data.get("role")]),
(self.validate_profile, [data.get("profile"), is_post]),
(self.validate_custom_data, [data.get("custom_user_data"), data.get("profile")]),
(self.validate_custom_data_with_profile, [data.get("custom_user_data"), data.get("profile")]),
(self.validate_email, [data.get("email"), is_post]),
(self.validate_locations, [data.get("username"), data.get("assigned_locations"),
data.get("primary_location")]),
Expand All @@ -43,8 +45,10 @@ def is_valid(self, data, is_post):

for validator, args in validators:
error = validator(*args)
if error:
if error and isinstance(error, str):
errors.append(error)
elif isinstance(error, list):
errors += error

return errors

Expand Down Expand Up @@ -100,6 +104,21 @@ def validate_custom_data(self, custom_data, profile_name):
spec = {'data': custom_data, 'user_profile': profile_name}
return custom_data_validator.validate_spec(spec)

def validate_custom_data_with_profile(self, custom_data, profile_name):
if custom_data is None or profile_name is None:
return

errors = []
profile = self.profiles_by_name.get(profile_name)

system_fields = set(profile.fields.keys()) if profile else set()
system_fields.add(PROFILE_SLUG)

for key in custom_data.keys():
if key in system_fields:
errors.append(_("'{}' cannot be set directly").format(key))
Jtang-1 marked this conversation as resolved.
Show resolved Hide resolved
return errors

def validate_email(self, email, is_post):
if is_post and email is not None:
error = AdminInvitesUserFormValidator.validate_email(self.domain, email)
Expand Down
Loading