o
    "il                     @   sx   d Z ddlmZmZ ddlmZ ddlZddlmZ ddl	m
Z
mZmZmZmZ ddlmZ eeZG dd	 d	ZdS )
z@
Unified Casbin-based permission service with atomic operations
    )ListDict)SessionN)Role)get_enforcerget_redis_clientadd_permission_for_roleremove_permission_for_roleget_permissions_for_role)AppExceptionc                   @   s   e Zd ZdZg dZg dZededede	e
eef  dedef
d	d
Zedededede	e
eef  fddZedededededef
ddZedededededef
ddZededefddZede	e
eef  fddZdS )CasbinPermissionServicez6Casbin-first permission service with atomic operations)usersrolesknowledge_basesknowledge_categoriesknowledge_tagsagents	workflows	documents
audit_logsmenus	providersmodels)readcreateupdatedeleteexecutedbrole_idpermissions	tenant_idreturnc              
   C   s`  |  ttj|k }|stdd|jrtddt }d|j }t	|}|
d||}zK|d|| |D ]*}	|	d}
|	d}|
rJ|sQtd	|	 t|||
|}|sdtd
|
 d| q:t|| tdt| d|j  W dS  ty } z(td|  |d|| |D ]}|j|  qtdt	| dt	| d}~ww )z
        Assign permissions to a role with atomic Casbin-first approach

        Transaction safety: Casbin operations are atomic with rollback support
           角色不存在Role not foundu   系统角色权限不可修改z*System role permissions cannot be modifiedrole:r   resourceactionzInvalid permission: zFailed to add permission: :u   ✅ Assigned z permissions to role Tu0   ❌ Permission assignment failed, rolling back: u   权限分配失败: zPermission assignment failed: N)queryr   filteridfirstr   	is_systemr   codestrget_filtered_policyremove_filtered_policyget
ValueErrorr   	Exceptionr   _invalidate_role_cacheloggerinfolenerror
add_policy)r   r   r    r!   roleenforcer	role_codedomainold_policiespermr&   r'   successepolicy rD   U/lsinfo/ai/hellotax_ai/base_platform/app/services/access/casbin_permission_service.pyassign_permissions   s>   



z*CasbinPermissionService.assign_permissionsc                 C   sF   | ttj| k }|sg S d|j }t||}dd |D S )z*Get all permissions for a role from Casbinr%   c                 S   s   g | ]}|d  |d dqS )      )r&   r'   rD   ).0prD   rD   rE   
<listcomp>_   s    z@CasbinPermissionService.get_role_permissions.<locals>.<listcomp>)r)   r   r*   r+   r,   r.   r
   )r   r!   r   r;   r=   policiesrD   rD   rE   get_role_permissionsU   s   
z,CasbinPermissionService.get_role_permissionsmenu_idc           	      C   d   |  ttj|k }|stddd| }d}d|j }t||||}|r0t	|| |S )zGrant menu permission to roler#   r$   menu:viewr%   )
r)   r   r*   r+   r,   r   r.   r   r   r5   	r   r   rN   r!   r;   r&   r'   r=   rA   rD   rD   rE   grant_menu_permissiond      

z-CasbinPermissionService.grant_menu_permissionc           	      C   rO   )z Revoke menu permission from roler#   r$   rP   rQ   r%   )
r)   r   r*   r+   r,   r   r.   r	   r   r5   rR   rD   rD   rE   revoke_menu_permissionu   rT   z.CasbinPermissionService.revoke_menu_permissionc              
   C   s   z.t  }d| d}d}	 |j||dd\}}|r|j|  |dkr#nqtd|  W d	S  tyI } ztd|  W Y d	}~d	S d	}~ww )
z3Invalidate Redis cache for all users with this rolezperm:*:z:*:*r   Td   )matchcountu,   ✅ Invalidated permission cache for tenant u#   ⚠️ Failed to invalidate cache: N)r   scanr   r6   r7   r4   warning)r   r!   redis_clientpatterncursorkeysrB   rD   rD   rE   r5      s    
z.CasbinPermissionService._invalidate_role_cachec                   C   s   dd t jD S )z+Get list of available resources and actionsc                 S   s   g | ]}|t jd qS ))r&   actions)r   ACTIONS)rI   r&   rD   rD   rE   rK      s    
zCCasbinPermissionService.get_available_resources.<locals>.<listcomp>)r   	RESOURCESrD   rD   rD   rE   get_available_resources   s   z/CasbinPermissionService.get_available_resourcesN)__name__
__module____qualname____doc__ra   r`   staticmethodr   intr   r   r/   boolrF   rM   rS   rU   r5   anyrb   rD   rD   rD   rE   r      s4    8(   r   )rf   typingr   r   sqlalchemy.ormr   loggingapp.models.roler   app.core.permissionsr   r   r   r	   r
   app.core.exceptionsr   	getLoggerrc   r6   r   rD   rD   rD   rE   <module>   s    
