U
    ô‰Vb›:  ã                   @   s    d Z dZdZddlmZmZmZmZmZ ddl	m
Z
mZ ddlmZmZmZmZmZmZmZ ddlmZmZmZ ddlmZmZ dd	lmZ G d
d„ de
ƒZdS )zCopyright 2021, 3LizzGPL version 3zinfo@3liz.orgé    )ÚQgisÚQgsExpressionÚQgsMapLayerÚ
QgsProjectÚQgsVectorLayer)ÚQgsAccessControlFilterÚQgsServerInterface)Úget_lizmap_configÚget_lizmap_groupsÚget_lizmap_layer_login_filterÚget_lizmap_layers_configÚget_lizmap_override_filterÚget_lizmap_user_loginÚis_editing_context)ÚALL_FEATURESÚNO_FEATURESÚFilterByPolygon)ÚLoggerÚ	profiling)Úto_boolc                       s    e Zd Zeddœ‡ fdd„Zeedœ‡ fdd„Zeedœ‡ fdd	„Ze	e
jdœ‡ fd
d„Zedœ‡ fdd„Zeeedœdd„ƒZeeeeedœdd„ƒZ‡  ZS )ÚLizmapAccessControlFilterN)Úserver_ifaceÚreturnc                    s   t ƒ  |¡ || _d S )N)ÚsuperÚ__init__Úiface)Úselfr   ©Ú	__class__© ú>/var/qgis-server/plugins/lizmap/server/lizmap_accesscontrol.pyr   "   s    z"LizmapAccessControlFilter.__init__)Úlayerr   c                    s`   dt j  krdk s"n dt jkrJt d¡ |  |¡}|r>|S tƒ  |¡S d}t |¡ tS dS )z( Return an additional expression filter i%y  i{y  ir{  zLizmap layerFilterExpressionzkLizmap layerFilterExpression disabled, you should consider upgrading QGIS Server to >= 3.10.13 or >= 3.16.2N)	r   ÚQGIS_VERSION_INTr   ÚinfoÚget_lizmap_layer_filterr   ÚlayerFilterExpressionÚcriticalr   )r   r!   Ú
filter_expÚmessager   r   r    r%   '   s    "

ÿ
z/LizmapAccessControlFilter.layerFilterExpressionc                    s(   t  d¡ |  |¡}|r|S tƒ  |¡S )z; Return an additional subset string (typically SQL) filter zLizmap layerFilterSubsetString)r   r#   r$   r   ÚlayerFilterSubsetString)r   r!   r'   r   r   r    r)   9   s
    

z1LizmapAccessControlFilter.layerFilterSubsetStringc                    sÖ  t ƒ  |¡}t| j ¡ ƒ}t| j ¡ ƒ}t ¡ }| ¡ }| 	dd¡|krf||d< t
|ƒ|d< | |¡ t|ƒdkrv|S t| j ¡ ƒ}|sŒ|S t|ƒ}|sœ|S | ¡ }	| ¡ }
d|krð|d rð|
|d krÊ|d |
 rÊ|d |
 }d}d|krL|d rL|d  d¡}d	d
„ |D ƒ}t|ƒdkrF|D ]}||kr.d}q.nd}nd}|r¶d|kr¶|d r¶|d |
 d }t|d ƒ|_t|d ƒ|_tt|d ƒt|d ƒgƒ|_nd |_ |_|_n$t d|	|
f ¡ d |_ |_|_nt d¡ d |_ |_|_|	|ks ||	 s2t d|	 ¡ |S ||	 }d|ksN|d s`t d|	 ¡ |S dd
„ |d D ƒ}|D ]*}||krvt d||	f ¡ |  S qvt dd |¡|	f ¡ d|_d |_ |_|_|S )z Return the layer rights Úlizmap_userNÚlizmap_user_groupsr   ZeditionLayersFZaclú,c                 S   s   g | ]}|  ¡ ‘qS r   ©Ústrip©Ú.0Úgr   r   r    Ú
<listcomp>t   s     z>LizmapAccessControlFilter.layerPermissions.<locals>.<listcomp>TÚcapabilitiesZcreateFeatureÚdeleteFeatureZmodifyAttributeZmodifyGeometryz,No edition config defined for layer: %s (%s)z"Lizmap config has no editionLayerszLizmap config has no layer: %sÚgroup_visibilityz(No Lizmap layer group visibility for: %sc                 S   s   g | ]}|  ¡ ‘qS r   r-   r/   r   r   r    r2   °   s     z4Group %s is in Lizmap layer group visibility for: %sz5Groups %s is in Lizmap layer group visibility for: %sú, )r   ÚlayerPermissionsr
   r   ÚrequestHandlerr   r   ÚinstanceÚcustomVariablesÚgetÚlistÚsetCustomVariablesÚlenr	   ÚconfigFilePathr   ÚnameÚidÚsplitr   Z	canInsertZ	canDeleteÚanyZ	canUpdater   r#   ÚjoinZcanRead)r   r!   ZrightsÚgroupsÚ
user_loginÚprojectÚ
custom_varÚcfgÚ
cfg_layersÚ
layer_nameÚlayer_idZ
edit_layerZcan_editZ
group_editr1   Zedit_layer_capÚ	cfg_layerr5   r   r   r    r7   B   s†    




þ


ÿ


ÿÿz*LizmapAccessControlFilter.layerPermissions)r   c           	         sà   t ƒ  ¡ }t| j ¡ ƒ}t|ƒdkr(|S t| j ¡ ƒ}|s>|S t|ƒ}|sN|S d}| 	¡ D ]N\}}d|ksZ|d stqZdd„ |d D ƒ}t|ƒdkr |d dkr qZd} qªqZ|rÜt|ƒdkrÊ|d dkrÊd	S d	 
tt|ƒƒ¡S |S )
z! The key used to cache documents r   Fr5   c                 S   s   g | ]}|  ¡ ‘qS r   r-   r/   r   r   r    r2   ì   s     z6LizmapAccessControlFilter.cacheKey.<locals>.<listcomp>é   Ú Tz@@)r   ÚcacheKeyr
   r   r8   r>   r	   r?   r   ÚitemsrD   r<   Úset)	r   Zdefault_cache_keyrE   rI   rJ   Zhas_group_visibilityZl_namerM   r5   r   r   r    rP   Ì   s0    
z"LizmapAccessControlFilter.cacheKeyc              
   C   sö  t | j ¡ ƒrtS t| j ¡ ƒ}t| j ¡ ƒ}t|ƒdkrB|sBtS t| j ¡ ƒ}|sXtS t	|ƒ}|shtS | 
¡ }||kr|tS z`t| j ¡ ƒ}t| d¡||dd}t}	| ¡ rÚ| ¡ sÌt d t¡¡ tW S | |¡\}	}
W nF tk
r" } z&t |¡ t d t¡¡ t W Y ¢S d}~X Y nX |	r:t d |	¡¡ t||ƒ}|sX|	rT|	S tS d	|k}|r‚t|d	 ƒr‚|	r~|	S tS |d
 }t|ƒdkrÒ|d dkrÒ|dkrÒt |d¡}|	rÎd |	|¡S |S |  |||¡}|	ròd |	|¡S |S )z/ Get lizmap layer filter based on login filter r   Zfilter_by_polygonF)Zuse_st_relationshipzOThe filter by polygon configuration is not valid.
 All features are hidden : {}z\An error occurred when trying to read the filtering by polygon.
All features are hidden : {}Nz1The polygon filter subset string is not null : {}Zedition_onlyÚfilterAttributerN   rO   Úallz	{} AND {})r   r   r8   r   r
   r   r>   r	   r?   r   r@   r   r   r;   Zis_filteredZis_validr   r&   Úformatr   Z
subset_sqlÚ	ExceptionÚlog_exceptionr#   r   r   r   ÚcreateFieldEqualityExpressionÚ_filter_by_login)r   r!   rE   rF   rI   rJ   rK   Zedition_contextZfilter_polygon_configZpolygon_filterÚ_ÚeÚcfg_layer_login_filterZis_edition_onlyÚ	attributeZlogin_filterr   r   r    r$   ÿ   s~       ÿÿÿ
ÿÿ
&z1LizmapAccessControlFilter.get_lizmap_layer_filter)r\   rE   Úloginr   c                 C   s`   g }t | d ƒr"| t |¡¡ ndd„ |D ƒ}| t d¡¡ d t | d ¡d |¡¡}|S )zþ Build the string according to the filter by login configuration.

        :param cfg_layer_login_filter: The Lizmap Filter by login configuration.
        :param groups: List of groups for the current user
        :param login: The current user
        ÚfilterPrivatec                 S   s   g | ]}t  |¡‘qS r   )r   ÚquotedStringr/   r   r   r    r2   l  s     z>LizmapAccessControlFilter._filter_by_login.<locals>.<listcomp>rT   z
{} IN ({})rS   r6   )r   Úappendr   r`   rU   ZquotedColumnRefrD   )r\   rE   r^   Zquoted_valuesZlayer_filterr   r   r    rY   \  s    	þz*LizmapAccessControlFilter._filter_by_login)Ú__name__Ú
__module__Ú__qualname__r   r   r   Ústrr%   r)   r   r   ZLayerPermissionsr7   rP   r   r$   ÚstaticmethodÚdictÚtuplerY   Ú__classcell__r   r   r   r    r       s   	 3\r   N)Ú__copyright__Ú__license__Ú	__email__Ú	qgis.corer   r   r   r   r   Úqgis.serverr   r   Úlizmap.server.corer	   r
   r   r   r   r   r   Zlizmap.server.filter_by_polygonr   r   r   Úlizmap.server.loggerr   r   Úlizmap.server.toolsr   r   r   r   r   r    Ú<module>   s   $	