Feature/add user business access clean - #432
Open
delcroip wants to merge 49 commits into
Open
Conversation
…-SAS/feature-35794
…ss and ValidityMixin - Added UserBusinessAccess model with admin registration for user-specific business access control - Imported and exported ValidityMixin, OpenIMISBusinessModel, and UserBusinessAccess in models init - Removed HistoryBusinessModel class from history_model.py, likely moved to openimis_model for better separation of concerns - This refactoring improves code organization by centralizing business-related models and mixins, enhancing maintainability and modularity in the OpenIMIS core module.
… model - Updated uuid fields in HistoricalInteractiveUser and InteractiveUser models to use uuidv7 with db_index and unique constraints for better UUID handling. - Added new HistoricalUserBusinessAccess model to enable historical tracking of UserBusinessAccess changes, including fields for versioning, validity dates, and audit trails.
- Renamed migration file and updated dependency to follow admin user migration sequence - Added check_permissions import to utils module for enhanced permission validation - Modified test helper to separately handle staff and superuser flags for technical users, improving role management in tests
…ixin Add getter and setter properties for date_valid_to and date_valid_from in the ValidityMixin class to facilitate migration from versioned models by providing backward-compatible attribute names.
Co-authored-by: Copilot <175728472+Copilot@users.noreply.github.com>
Co-authored-by: Copilot <175728472+Copilot@users.noreply.github.com>
… Django User model - Changed "staff" to "is_staff" and "superuser" to "is_superuser" to align with Django's User model attributes, ensuring proper test user creation.
…ion methods - Extracted auto-provisioning user group logic into a dedicated `_auto_provisioning_user_group` method to reduce duplication. - Added `_create_interactive_user` method to handle interactive user creation separately from tech users. - Updated `create_user` and `create_superuser` to use the new interactive user creation and auto-provisioning flow. - Refactored `auto_provision_user` to call the extracted method, improving code readability and maintainability.
- Add @staticmethod decorator to id_from_global method in GraphQL test case - Modify InteractiveUser.is_superuser property and add setter for better user management - Refactor User.has_perms method to support business object permissions via UserBusinessAccess model - Include detailed docstring explaining the new permission evaluation logic with OR/AND support and time-bound access checks This improves fine-grained access control in openIMIS by allowing permissions tied to specific business objects, enhancing security and flexibility for user rights management.
Add a new Django management command `generate_permissions_map` that collects all GraphQL permissions, generates a sorted permissions map JSON file, and optionally syncs the Django Permission model with these permissions. This improves automation of permission management in the openIMIS backend by ensuring consistency between GQL-defined permissions and Django's permission system.
Include the is_superuser boolean in the UserSerializer fields to expose superuser status in API responses, enhancing user data visibility for administrative purposes.
…output and cleaner operation names - Change default output path from absolute '../../solution-builder/solution/permissions_map.json' to relative './permissions_map.json' for better portability - Strip 'mutation_' and 'query_' prefixes from operation names to simplify permission mappings and improve readability
- Refactored UserManager methods to properly handle language assignment and return user objects from auto_provision_user - Improved create_test_interactive_user to filter properties correctly for User and InteractiveUser models - Added _instance_to_gql_input method in openIMISGraphQLTestCase for converting model instances to GraphQL inputs with camelCase fields - Minor formatting and import additions for better code consistency and functionality
…ation - Added app_label = 'core' to Meta classes in Role, RoleRight, InteractiveUser, Officer, ClaimAdmin, UserRole, UserGroup, and RoleMutation models - Ensures models are correctly associated with the 'core' app, preventing potential issues in Django migrations and app registry
Replaced the `exclude` list parameter with a `map_mutation_field` dict. This allows renaming fields (e.g. uuid→i_user_id), conditional exclusion via special "_exclude_" value, and more flexible conversion of model instances to GraphQL mutation inputs. Updated impersonation tests to use the new helper, supply UUID-based clientMutationId, pass userTypes, verify mutation status via get_mutation_result, and create test users with custom_props.
Use data.get("roles", []) instead of data["roles"] in
create_or_update_interactive_user to prevent KeyError when the
roles key is missing from the input. Improves robustness of
user creation/update flow.
…ss and ValidityMixin - Added UserBusinessAccess model with admin registration for user-specific business access control - Imported and exported ValidityMixin, OpenIMISBusinessModel, and UserBusinessAccess in models init - Removed HistoryBusinessModel class from history_model.py, likely moved to openimis_model for better separation of concerns - This refactoring improves code organization by centralizing business-related models and mixins, enhancing maintainability and modularity in the OpenIMIS core module.
… model - Updated uuid fields in HistoricalInteractiveUser and InteractiveUser models to use uuidv7 with db_index and unique constraints for better UUID handling. - Added new HistoricalUserBusinessAccess model to enable historical tracking of UserBusinessAccess changes, including fields for versioning, validity dates, and audit trails.
Introduce a new `mutation_on_queryset_from_filter` decorator as a complement to `mutation_on_uuids_from_filter`. Instead of materializing a list of UUIDs from filtered results, the new decorator operates directly on a lazy Django queryset, avoiding unnecessary DB round-trips when mutation logic can work with a queryset directly. Key behaviors: - Applies JSON-serialized filters from `query_filters_field` as Django Q objects using the GQL type's `filter_fields` plus any explicit filter handlers. - If a queryset is already present in `data` under `queryset_key`, it further narrows it with the mutation filters, allowing callers to pre-apply row security or custom base filters. - If no queryset is provided, it falls back to `django_object.get_queryset(...)` with the effective user, ensuring model-level access control (ROW_SECURITY, location restrictions, etc.) is honored automatically. - Also updates `mutation_on_uuids_from_filter` to pass the current user through `get_queryset`, making it consistent with the new decorator. Export the new decorator from `core/gql/gql_mutations/__init__.py`.
Pass `silent=True` to `user.save()` when applying custom user properties in `create_test_interactive_user` to avoid triggering side effects such No change in the User exception
Add a `link_type` CharField to both `UserBusinessAccess` and `HistoricalUserBusinessAccess` models to support categorizing business access links. Includes database indexes on `(user, link_type)` and `(link_type, object_id)` for query performance. Also removes duplicate class definition that was present in the model file.
…ters Added `link_type` field to `list_display` and `list_filter` in the `UserBusinessAccessAdmin` class to improve visibility and filtering of business access records by their link type in the Django admin interface.
…_types field to UserGQLType - Move `UserTypeEnum` and user type constants (`UT_INTERACTIVE`, `UT_TECHNICAL`, `UT_OFFICER`, `UT_CLAIM_ADMIN`) from `schema.py` to a new `core/user_types.py` module for better separation of concerns - Add `user_types` field to `UserGQLType` with a permission-guarded resolver using `get_user_types` helper
- Add missing newline at end of `decorators.py` - Remove extra blank lines in `mutation_by_filter.py` and `jwt_authentication.py` - Fix missing spaces in dict literals (`"message":str(e)` → `"message": str(e)`) - Remove unused `e` variable in `except Throttled` clause - Remove trailing whitespace across multiple files - Remove unused imports (`os`, `settings`, `filter_validity`) in migration and management command files
Introduce a custom `createsuperuser` command that overrides Django's stock implementation to use openIMIS's `core.User.create_superuser` logic. The command supports: - Interactive and non-interactive (`--noinput`) modes - `--username`, `--password`, `--email`, `--last-name`, and `--other-names` arguments - `DJANGO_SUPERUSER_PASSWORD` environment variable for CI/Docker use The command is registered in `CoreConfig.ready()` by clearing Django's management command cache and pointing `createsuperuser` to the core module, ensuring the custom implementation takes precedence over Django's built-in one.
…ll user - Return `True` early if the user is a superuser, ensuring superusers are treated as IMIS administrators - Add a null check on `user` before calling `isinstance` to prevent potential `AttributeError` when `_u` is not set
- Refactor `check_authentication` to support bare decorator usage (no parentheses), explicit `user` argument, and thread-local user resolution via `get_current_user()` fallback - Extract core authentication and business access guard logic into a new `core/access.py` module (`guard_user_access`, `is_http_request`) to improve separation of concerns and reusability - Add `check_permissions` decorator to enforce `user.has_perms` checks with optional `access_requirements` fallback for business-level access - Support both HTTP view and service-layer usage patterns across all decorators, with consistent error responses per context
Refactored `user_authentication` to consolidate the auto-provision fallback into a single conditional, eliminating redundant early returns. Additionally, after successful authentication, `login()` is now called for staff users when a session is available. This ensures the Django session is properly initialized for staff users, which is required for session-based authentication flows (e.g., Django admin access).
The migration 0037 now includes a RunPython operation to set is_superuser=True for users with an active role of is_system=64.
Replace multiple queries fetching admin role and user IDs with a single filtered update on the User model using related fields. This improves efficiency and correctness by eliminating intermediate lists and ensuring all validity constraints are applied directly in the database.
The filter condition `validity_to__isnull=True` on the User model was incorrectly excluding users with a non-null validity_to from being migrated to superuser status. Removing it ensures all admin users are correctly made superusers.
Remove deprecated ClearUserContextMiddleware and CustomJSONWebTokenMiddleware along with related unused imports. The impersonation logic has been superseded by alternative implementation. Correct Permissions-Policy directive by adding missing equals sign for microphone.
|
| GitGuardian id | GitGuardian status | Secret | Commit | Filename | |
|---|---|---|---|---|---|
| 33827020 | Triggered | Username Password | 3089872 | core/tests/test_utils.py | View secret |
| 34430641 | Triggered | Generic Password | 110bd83 | core/tests/test_graphql.py | View secret |
| 34430642 | Triggered | Generic Password | 110bd83 | core/tests/test_graphql.py | View secret |
| 29130333 | Triggered | Generic Password | c73105d | core/tests/test_graphql.py | View secret |
| 33869950 | Triggered | Generic Password | 86ea8d2 | core/management/commands/createsuperuser.py | View secret |
🛠 Guidelines to remediate hardcoded secrets
- Understand the implications of revoking this secret by investigating where it is used in your code.
- Replace and store your secrets safely. Learn here the best practices.
- Revoke and rotate these secrets.
- If possible, rewrite git history. Rewriting git history is not a trivial act. You might completely break other contributing developers' workflow and you risk accidentally deleting legitimate data.
To avoid such incidents in the future consider
- following these best practices for managing and storing secrets including API keys and other credentials
- install secret detection on pre-commit to catch secret before it leaves your machine and ease remediation.
🦉 GitGuardian detects secrets in your source code to help developers and security teams secure the modern development process. You are seeing this because you or someone else with access to this repository has authorized GitGuardian to scan your pull request.
Member
Author
|
flake8 runs locally, the only line with defect is not part on the source branch. poke @zikani03, can you merge this block user creation with vite |
…y return type - Replace Python uuidv7() with cross-database GenerateUUIDv7 Func for native UUIDv7. - Change filter_validity in OpenIMISHistoryMixin to return a list of Q objects. - Update imports in history_model.py and openimis_model.py.
9 tasks
Member
|
@delcroip its a big changes i will review and will get you back |
- Raise ValueError for empty perm_list in has_role_perms - Add early return in has_perms when no perms and no access requirements - Catch ObjectDoesNotExist when fetching system role in update_or_create_user - Improve error message for invalid content_type_label
This file contains hidden or bidirectional Unicode text that may be interpreted or compiled differently than what appears below. To review, open the file in an editor that reveals hidden Unicode characters.
Learn more about bidirectional Unicode characters
Sign up for free
to join this conversation on GitHub.
Already have an account?
Sign in to comment
Add this suggestion to a batch that can be applied as a single commit.This suggestion is invalid because no changes were made to the code.Suggestions cannot be applied while the pull request is closed.Suggestions cannot be applied while viewing a subset of changes.Only one suggestion per line can be applied in a batch.Add this suggestion to a batch that can be applied as a single commit.Applying suggestions on deleted lines is not supported.You must change the existing code in this line in order to create a valid suggestion.Outdated suggestions cannot be applied.This suggestion has been applied or marked resolved.Suggestions cannot be applied from pending reviews.Suggestions cannot be applied on multi-line comments.Suggestions cannot be applied while the pull request is queued to merge.Suggestion cannot be applied right now. Please check back later.
Description
cleaned version of the feature/add-user-business-access PR without the inpersonification and GQL error handling
Type of Change
Related Issue(s) / Task(s)
Demo
Upload screenshots/gifs or link to any demo video here.
Checklist