Skip to content

[feature] Made RegisteredUser model support multi-tenancy #692#698

Draft
pandafy wants to merge 1 commit intomasterfrom
issues/692-different-identity-verification
Draft

[feature] Made RegisteredUser model support multi-tenancy #692#698
pandafy wants to merge 1 commit intomasterfrom
issues/692-different-identity-verification

Conversation

@pandafy
Copy link
Copy Markdown
Member

@pandafy pandafy commented Mar 30, 2026

Checklist

  • I have read the OpenWISP Contributing Guidelines.
  • I have manually tested the changes proposed in this pull request.
  • I have written new test cases for new code and/or updated existing tests for changes to existing code.
  • I have updated the documentation.

Reference to Existing Issue

Closes #692

Description of Changes

  • Updated the RegisteredUser model to support organization-specific records.
  • Changed the primary key to UUID and added organization as a nullable ForeignKey.
  • Modified related code across the application to handle multiple registered users per organization.
  • Updated tests to reflect changes in the RegisteredUser model and ensure proper functionality.
  • Added migration scripts to handle the transition from the old model to the new schema.

- Updated the RegisteredUser model to support organization-specific records.
- Changed the primary key to UUID and added organization as a nullable ForeignKey.
- Modified related code across the application to handle multiple registered users per organization.
- Updated tests to reflect changes in the RegisteredUser model and ensure proper functionality.
- Added migration scripts to handle the transition from the old model to the new schema.

Closes #692
@coderabbitai
Copy link
Copy Markdown

coderabbitai bot commented Mar 30, 2026

Caution

Review failed

An error occurred during the review process. Please try again later.

📝 Walkthrough

Walkthrough

This pull request refactors the RegisteredUser model from a one-to-one relationship (single global registration per user) to a one-to-many relationship (organization-scoped registrations per user). A nullable organization foreign key is added with unique constraints on (user, organization) and a separate constraint for global-only records where organization IS NULL. The database schema is migrated to support UUID primary keys and multiple records per user. API serializers, admin inlines, and verification helpers are updated to accept and use organization context when retrieving or creating registrations. Integration points (SAML, social login, monitoring tasks, authorization checks) are adjusted to query organization-specific RegisteredUser records. Test fixtures throughout the codebase are updated to include organization associations.

Sequence Diagram(s)

sequenceDiagram
    autonumber
    participant User
    participant API as Authorization API
    participant RegisteredUsers as RegisteredUser<br/>(multiple per org)
    participant Org as Organization Context

    rect rgba(100, 150, 200, 0.5)
    Note over User,Org: Old Flow (One Global RegisteredUser)
    User->>API: Request with org_id
    API->>API: Check user.registered_user.is_verified
    Note over API: Single global verification<br/>regardless of org
    API->>User: Allow/Deny (global state)
    end

    rect rgba(150, 200, 100, 0.5)
    Note over User,Org: New Flow (Org-Scoped RegisteredUsers)
    User->>API: Request with org_id
    API->>Org: Extract organization from request
    API->>RegisteredUsers: Query registered_users.filter(organization=org_id)
    RegisteredUsers->>RegisteredUsers: Return org-specific record<br/>or global (org_id=NULL)
    RegisteredUsers->>API: is_verified, method for this org
    API->>User: Allow/Deny (org-specific verification)
    end
Loading

Estimated code review effort

🎯 4 (Complex) | ⏱️ ~75 minutes

✨ Finishing Touches
🧪 Generate unit tests (beta)
  • Create PR with unit tests
  • Commit unit tests in branch issues/692-different-identity-verification

Comment @coderabbitai help to get the list of available commands and usage tips.

Copy link
Copy Markdown
Member Author

Choose a reason for hiding this comment

The reason will be displayed to describe this comment to others. Learn more.

⚠️ WARNING: This is AI generated migration file which uses raw SQL. I'll update this migration to follow the Django migration framework.

Copy link
Copy Markdown
Member Author

Choose a reason for hiding this comment

The reason will be displayed to describe this comment to others. Learn more.

SQLite cannot modify primary keys in place, so Django works around this by rebuilding the entire table when a PK or certain fields are altered. During your migration, the table rebuild temporarily ends up with both the old implicit PK and the new id column, which leads to the duplicate column name: id error. This typically happens when adding a new PK column and removing the old PK within the same schema transition. Splitting the operations into separate migrations avoids the conflict because each table rebuild sees a consistent schema.

@openwisp-companion
Copy link
Copy Markdown

Multiple Flake8 Violations and Test Failures

Hello @pandafy,
(Analysis for commit 248fa3b)

  • Code Style/QA: There are several Flake8 violations, including unused imports and lines that are too long.

  • Fix: Run openwisp-qa-format to automatically fix most style issues.

  • For E501 (line too long) errors, manually shorten the lines in the specified files.

  • For F823 (local variable '_' defined in enclosing scope on line X referenced before assignment), manually fix the variable usage in openwisp_radius/api/views.py.

  • Test Failure: The test_export_users_command in openwisp_radius/tests/test_users_integration.py failed due to an incorrect number of arguments being passed.

  • Fix: Adjust the call_command arguments in the test to match the expected signature.

  • Test Failure: The test_radius_user_serializer in openwisp_radius/tests/test_api/test_api.py failed due to an assertion error, indicating a mismatch in the serialized data.

  • Fix: Inspect the expected and actual output in the test to identify and correct the discrepancy in the serializer or the test data.

  • Test Failure: The test_validate_phone_token_400_no_token and test_validate_phone_token_400_no_token tests in openwisp_radius/tests/test_api/test_phone_verification.py failed with UnboundLocalError. This indicates an issue with how the local variable '_' is being accessed.

  • Fix: Review the logic in openwisp_radius/api/views.py around line 761 and 754 to ensure the variable '_' is properly initialized or handled before being referenced.

  • Test Failure: The test_export_users_command in openwisp_radius/tests/test_users_integration.py failed with a TypeError related to select_related.

  • Fix: Correct the select_related usage in the export_users command or the test setup to ensure the specified fields are available. The error message Invalid field name(s) given in select_related: 'registered_user' suggests that 'registered_user' might not be a valid field for select_related in that context.

  • Infrastructure: The Coveralls report failed to generate. This is a known flaky service and is not actionable by the contributor. The CI will proceed.

Sign up for free to join this conversation on GitHub. Already have an account? Sign in to comment

Labels

None yet

Projects

Status: To do (general)

Development

Successfully merging this pull request may close these issues.

[feature] Allow users joining different organizations having different identity verification rules

1 participant