o
    "i                     @   sx   d Z ddlmZ ddlmZmZ ddlmZ ddlm	Z	m
Z
mZmZmZ ddlmZ ddlZeeZG dd	 d	ZdS )
z
Permission management service
    )Session)ListDict)Role)get_enforceradd_permission_for_roleremove_permission_for_rolecheck_permissionget_redis_client)AppExceptionNc                   @   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	e
eef  fddZedefddZ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dedefddZdS )PermissionServicez Service for managing permissions)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||}zJ|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 Casbin-first atomic approach   角色不存在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_cacheloggerinfolenerror
add_policy)r   r   r    r!   roleenforcer	role_codedomainold_policiespermr&   r'   successepolicy rD   N/lsinfo/ai/hellotax_ai/base_platform/app/services/access/permission_service.pyassign_permissions   s>   




z$PermissionService.assign_permissionsc                 C   sb   ddl m} | ttj|k }|sg S d|j }t|ddp$d}|||}dd |D S )z*Get all permissions for a role from Casbinr   )get_permissions_for_roler%   r!   c                 S   s   g | ]}|d  |d dqS )      )r&   r'   rD   ).0prD   rD   rE   
<listcomp>`   s    z:PermissionService.get_role_permissions.<locals>.<listcomp>)	app.core.permissionsrG   r)   r   r*   r+   r,   r.   getattr)r   r   rG   r;   r=   r!   policiesrD   rD   rE   get_role_permissionsR   s   
z&PermissionService.get_role_permissionsc              
   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 )
z!Invalidate Redis cache for tenantzperm:*:z:*:*r   Td   )matchcountu,   ✅ Invalidated permission cache for tenant u#   ⚠️ Failed to invalidate cache: N)r
   scanr   r6   r7   r4   warning)r!   redis_clientpatterncursorkeysrB   rD   rD   rE   r5   e   s    
z#PermissionService._invalidate_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)rJ   r&   rD   rD   rE   rL   y   s    
z=PermissionService.get_available_resources.<locals>.<listcomp>)r   	RESOURCESrD   rD   rD   rE   get_available_resourcesv   s   z)PermissionService.get_available_resourcesmenu_idc           	      C   b   |  ttj|k }|stddd| }d}d|j }t||||}|r/t	| |S )zGrant menu permission to roler#   r$   menu:viewr%   )
r)   r   r*   r+   r,   r   r.   r   r   r5   	r   r   r^   r!   r;   r&   r'   r=   rA   rD   rD   rE   grant_menu_permission~      


z'PermissionService.grant_menu_permissionc           	      C   r_   )z Revoke menu permission from roler#   r$   r`   ra   r%   )
r)   r   r*   r+   r,   r   r.   r   r   r5   rb   rD   rD   rE   revoke_menu_permission   rd   z(PermissionService.revoke_menu_permissionuser_idc                 C   s   d| }d}t | |||S )z)Check if user has permission to view menur`   ra   )r	   )rf   r^   r!   r&   r'   rD   rD   rE   check_menu_permission   s   
z'PermissionService.check_menu_permissionN)__name__
__module____qualname____doc__r\   r[   staticmethodr   intr   r   r/   boolrF   rP   r5   anyr]   rc   re   rg   rD   rD   rD   rE   r      s8    4$   r   )rk   sqlalchemy.ormr   typingr   r   app.models.roler   rM   r   r   r   r	   r
   app.core.exceptionsr   logging	getLoggerrh   r6   r   rD   rD   rD   rE   <module>   s    
