tenant_app.py
Overview
tenant_app.py is a Flask blueprint module that provides RESTful API endpoints to manage users within tenants in the InfiniFlow platform. It handles user listing, invitation, removal, tenant listing for a user, and agreeing to tenant invitations. The module ensures authorization by validating the current user's identity against tenant or user IDs and integrates with the user and tenant database models via service layers.
This file acts as the controller layer between the frontend requests and backend services related to tenant-user management, including sending invitation emails asynchronously.
Detailed Explanation
Imports and Dependencies
Flask and Flask-Login: Provides request handling and user session management.
api.db and api.db.services: Service layers for database interaction regarding users and tenants.
api.utils: Utility functions for UUID generation, time computations, API response formatting, and email sending.
smtp_mail_server and settings: For email configuration and sending invitation emails.
Threading: To send emails asynchronously without blocking API responses.
API Endpoints (Flask Routes)
1. user_list(tenant_id)
Route: GET //user/list
Purpose: List all users associated with a given tenant.
Authorization: Only accessible if the logged-in user's ID matches the tenant ID.
Returns: JSON response with a list of users and their last update time in seconds (delta_seconds).
Parameters:
tenant_id(str): The ID of the tenant whose users are requested.
Response:
Success: JSON containing user list with additional
delta_secondsfield.Failure: Authorization error or server error.
Usage Example:
GET /1234/user/list
Authorization: Bearer <token>
2. create(tenant_id)
Route: POST /<tenant_id>/user
Purpose: Invite a user to join a tenant by email.
Authorization: Only accessible if current user ID matches tenant ID.
Input: JSON body containing:
email(string): Email of the user to invite.
Behavior:
Checks if the user with the given email exists.
Validates if the user is already part of the tenant and their role.
If not already invited or a member, creates an invite record with role
INVITE.Sends an invitation email asynchronously if SMTP is configured.
Returns:
Success: JSON with invited user info (id, avatar, email, nickname).
Failure: User not found or user already part of tenant with appropriate messages.
Usage Example:
POST /1234/user
Content-Type: application/json
Authorization: Bearer <token>
{
"email": "[email protected]"
}
3. rm(tenant_id, user_id)
Route: DELETE /<tenant_id>/user/<user_id>
Purpose: Remove a user from a tenant.
Authorization: Allowed if current user ID matches tenant ID or user ID being removed.
Returns: JSON indicating success or error.
Parameters:
tenant_id(str): Tenant ID.user_id(str): User ID to remove from tenant.
Usage Example:
DELETE /1234/user/5678
Authorization: Bearer <token>
4. tenant_list()
Route: GET /list
Purpose: Get the list of tenants that the current user belongs to.
Authorization: User must be logged in.
Returns: JSON list of tenants with delta_seconds indicating last update time.
Usage Example:
GET /list
Authorization: Bearer <token>
5. agree(tenant_id)
Route: PUT /agree/<tenant_id>
Purpose: Current user agrees to join the tenant (typically after invitation).
Authorization: User must be logged in.
Behavior: Updates the user's role in the tenant to NORMAL.
Returns: JSON indicating success or error.
Parameters:
tenant_id(str): Tenant the user agrees to join.
Usage Example:
PUT /agree/1234
Authorization: Bearer <token>
Important Implementation Details
Authorization Checks: Most endpoints verify that the
current_user.idmatches thetenant_idoruser_idto prevent unauthorized access.Service Layer Usage: Database operations are abstracted through
UserTenantServiceandUserService, promoting separation of concerns and easier testing.Invitation Email: When inviting a user, if SMTP is configured, an email is sent asynchronously in a separate thread to avoid blocking the API response.
Delta Seconds: The
delta_secondsutility computes the time difference between the current time and the last update time of user-tenant records, adding freshness context to API responses.Role and Status Enums: The user roles (
INVITE,NORMAL,OWNER) and status (VALID) are managed as enumerations for clarity and consistency.
Interaction with Other System Components
UserTenantService and UserService: These service classes perform CRUD operations on user-tenant relationships and users respectively, likely interfacing with the database models.
SMTP Mail Server: Used for sending invitation emails.
API Utilities: Helpers for JSON formatting, request validation, and error handling are leveraged for consistent API behavior.
Flask-Login: Manages user authentication and session, providing
current_usercontext.
This file is a core part of the user management subsystem, specifically focusing on tenant membership and invitations, and integrates tightly with the user identity and email notification subsystems.
Mermaid Class Diagram
classDiagram
class tenant_app {
+user_list(tenant_id)
+create(tenant_id)
+rm(tenant_id, user_id)
+tenant_list()
+agree(tenant_id)
}
class UserTenantService {
+get_by_tenant_id(tenant_id)
+query(user_id, tenant_id)
+save(id, user_id, tenant_id, invited_by, role, status)
+filter_delete(conditions)
+filter_update(conditions, updates)
+get_tenants_by_user_id(user_id)
}
class UserService {
+query(email)
+get_by_id(user_id)
}
tenant_app ..> UserTenantService : uses
tenant_app ..> UserService : uses
Summary
The tenant_app.py file implements user management APIs for tenants within InfiniFlow. It supports listing users, inviting new users, removing users, listing tenants for the current user, and accepting invitations. It enforces strict authorization, uses service classes for data access, and integrates asynchronous email notifications. This module is a crucial part of tenant-user relationship management, enabling secure and efficient collaboration within tenant boundaries.