|
7 | 7 |
|
8 | 8 |
|
9 | 9 | async def flush_pending_perm_ops(request): |
10 | | - """No-op — direct permissions are now saved immediately.""" |
11 | | - pass |
| 10 | + """Flush pending direct-permission writes for the user on the request.""" |
| 11 | + from sqlalchemy import delete |
| 12 | + |
| 13 | + from fastapi_admin_kit.auth.models import UserPermission |
| 14 | + from fastapi_admin_kit.db import get_db_session |
| 15 | + |
| 16 | + perm_ids = getattr(request.state, "_admin_perm_perm_ids", None) |
| 17 | + if not perm_ids or not isinstance(perm_ids, list): |
| 18 | + return |
| 19 | + |
| 20 | + # Get the user object from request state |
| 21 | + user_obj = getattr(request.state, "_admin_perm_user_obj", None) |
| 22 | + if user_obj is None: |
| 23 | + return |
| 24 | + |
| 25 | + request.state._admin_perm_perm_ids = None |
| 26 | + session = get_db_session(request) |
| 27 | + if session is None: |
| 28 | + return |
| 29 | + |
| 30 | + # Delete existing direct permissions |
| 31 | + await session.execute(delete(UserPermission).where(UserPermission.user_id == user_obj.id)) |
| 32 | + |
| 33 | + # Insert new permissions |
| 34 | + for perm_id in perm_ids: |
| 35 | + up = UserPermission(user_id=user_obj.id, permission_id=perm_id) |
| 36 | + session.add(up) |
12 | 37 |
|
13 | 38 |
|
14 | 39 | def _get_table_names() -> list[str]: |
@@ -89,50 +114,16 @@ def after_create(self, obj, request=None): |
89 | 114 | return |
90 | 115 | perm_data = getattr(request.state, "_admin_perm_data", None) |
91 | 116 | if perm_data: |
92 | | - self._save_direct_permissions_after_commit(obj, perm_data, request) |
| 117 | + request.state._admin_perm_perm_ids = perm_data |
| 118 | + request.state._admin_perm_user_obj = obj |
93 | 119 |
|
94 | 120 | def after_update(self, obj, request=None): |
95 | 121 | if request is None: |
96 | 122 | return |
97 | 123 | perm_data = getattr(request.state, "_admin_perm_data", None) |
98 | 124 | if perm_data: |
99 | | - self._save_direct_permissions_after_commit(obj, perm_data, request) |
100 | | - |
101 | | - def _save_direct_permissions_after_commit(self, obj, perm_data, request): |
102 | | - """Save direct user permissions after the user object is committed. |
103 | | -
|
104 | | - perm_data: list of permission IDs, e.g. [1, 3, 5] |
105 | | - """ |
106 | | - import asyncio |
107 | | - |
108 | | - from sqlalchemy import delete |
109 | | - |
110 | | - from fastapi_admin_kit.auth.models import UserPermission |
111 | | - |
112 | | - perm_ids = perm_data if isinstance(perm_data, list) else [] |
113 | | - |
114 | | - async def _do_save(): |
115 | | - from fastapi_admin_kit.db import get_db_session |
116 | | - |
117 | | - session = get_db_session(request) |
118 | | - # Delete existing direct permissions for this user |
119 | | - await session.execute(delete(UserPermission).where(UserPermission.user_id == obj.id)) |
120 | | - |
121 | | - # Insert new direct permissions |
122 | | - for perm_id in perm_ids: |
123 | | - up = UserPermission(user_id=obj.id, permission_id=perm_id) |
124 | | - session.add(up) |
125 | | - |
126 | | - await session.commit() |
127 | | - |
128 | | - try: |
129 | | - loop = asyncio.get_event_loop() |
130 | | - if loop.is_running(): |
131 | | - asyncio.ensure_future(_do_save()) |
132 | | - else: |
133 | | - loop.run_until_complete(_do_save()) |
134 | | - except RuntimeError: |
135 | | - asyncio.run(_do_save()) |
| 125 | + request.state._admin_perm_perm_ids = perm_data |
| 126 | + request.state._admin_perm_user_obj = obj |
136 | 127 |
|
137 | 128 | async def get_form_context(self, context, obj=None, request=None): |
138 | 129 | """Load direct permissions for the user being edited.""" |
@@ -168,26 +159,11 @@ async def get_form_context(self, context, obj=None, request=None): |
168 | 159 | return context |
169 | 160 |
|
170 | 161 | def process_form_data(self, data, request=None): |
171 | | - """Extract perm_data from form data and store on request for after_create/after_update.""" |
172 | | - import json |
173 | | - |
174 | | - perm_data_raw = data.pop("perm_data", None) |
175 | | - if perm_data_raw is None and request is not None: |
176 | | - # Fallback: try to get from request state if already parsed |
177 | | - perm_data_raw = getattr(request.state, "_admin_perm_data_raw", None) |
178 | | - |
179 | | - if perm_data_raw is not None: |
180 | | - try: |
181 | | - if isinstance(perm_data_raw, str): |
182 | | - perm_data = json.loads(perm_data_raw) |
183 | | - else: |
184 | | - perm_data = perm_data_raw |
185 | | - except (json.JSONDecodeError, TypeError): |
186 | | - perm_data = {} |
187 | | - |
188 | | - if request is not None and perm_data: |
189 | | - request.state._admin_perm_data = perm_data |
| 162 | + """Extract perm_data from request state and store for after_create/after_update. |
190 | 163 |
|
| 164 | + perm_data should already be extracted by the view and stored on |
| 165 | + request.state._admin_perm_data before this is called. |
| 166 | + """ |
191 | 167 | return data |
192 | 168 |
|
193 | 169 |
|
|
0 commit comments