U
    TGˆh“L  ã                   @   s¼   d Z dZdZddl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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" G dd„ de	ƒZ#dS )zCopyright 2021, 3LizzGPL version 3zinfo@3liz.orgé    )Ú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Ú
FilterType)ÚLoggerÚ	profiling)Úto_bool)ÚBING_DOMAINÚBING_KEYÚGOOGLE_DOMAINÚ
GOOGLE_KEYÚstrict_tos_checkc                       s   e Zd Zed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edœdd„ƒZeeeeeedœdd„ƒZ‡  ZS )ÚLizmapAccessControlFilterN)Úserver_ifaceÚreturnc                    sD   t ƒ  |¡ || _ttƒ| _ttƒ| _t 	d| j› d| j› ¡ d S )NzLayerAccessControl : Google z, Bing )
ÚsuperÚ__init__Úifacer   r   Ú_strict_googler   Ú_strict_bingr   Úinfo)Úselfr   ©Ú	__class__© úD/var/www/lizmap/lizmap/plugins/lizmap_server/lizmap_accesscontrol.pyr   $   s
    

z"LizmapAccessControlFilter.__init__)Úlayerr   c                    s.   t  d¡ | j|tjd}|r"|S tƒ  |¡S )z; Return an additional subset string (typically SQL) filter zLizmap layerFilterSubsetString©Úfilter_type)r   r#   Úget_lizmap_layer_filterr   ZSafeSqlQueryr   ÚlayerFilterSubsetString)r$   r)   Ú
filter_expr%   r'   r(   r-   ?   s
    
z1LizmapAccessControlFilter.layerFilterSubsetStringc                    s°  t ƒ  |¡}| ¡ }t ¡ }| j ¡ }| ¡ sx| d¡ 	¡ dkrxt
 d|› d| ¡ › d¡ d |_ |_ |_|_|S t|ƒ}t|ƒ}| ¡ }| dd¡|kr¾||d< t|ƒ|d	< | |¡ | d¡ 	¡ d
k}	|	rø| d¡ 	¡ dkrø| j ¡  |g¡ | ¡  ¡ }
t|
k}t|
k}|s |r2t
 d|› d¡ t| j ¡ ƒ}|s|rj| j  |_ |_ |_|_n"|rŒ| j   |_ |_ |_|_|S t!|ƒdkr®|s®|s®|S |d  dd¡}|r|st"t#ƒrd |_ |_ |_|_t
 $d|› d| %¡ › d¡ |S |d  dd¡}|rj|sjt"t&ƒrjd |_ |_ |_|_t
 $d|› d| %¡ › d¡ |S t'|ƒ}|s||S | (¡ }| d¡r¾||d kr’|d | r’|d | }d}| d¡r|d  )d¡}dd„ |D ƒ}t!|ƒdkr|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"|› d#|› d$¡ d |_ |_|_nt
 d%¡ d |_ |_|_||ksî|| st
 d&|› ¡ |S || }d'|ks|d' s2t
 d(|› ¡ |S d)d„ |d' D ƒ}|D ].}||krHt
 d*|› d+|› ¡ |  S qHt
 d,d- ,|¡› d+|› ¡ d|_d |_ |_|_|S ).z Return the layer rights ÚserviceÚWMSzlayerPermission: Layer z is invalid in ú!FÚlizmap_userNÚlizmap_user_groupsZWFSÚrequestZ
GETFEATUREzLayer 'zD' has been detected as an external layer which might need a API key.r   ÚoptionsZ	googleKeyÚ zThe layer 'zb' is protected by a licence, but the API key is not provided. Discarding the layer in the project Ú.ZbingKeyZeditionLayersZaclú,c                 S   s   g | ]}|  ¡ ‘qS r'   ©Ústrip©Ú.0Úgr'   r'   r(   Ú
<listcomp>¨   s     z>LizmapAccessControlFilter.layerPermissions.<locals>.<listcomp>TÚcapabilitiesZcreateFeatureÚdeleteFeatureZmodifyAttributeZmodifyGeometryz%No edition config defined for layer: z (ú)z"Lizmap config has no editionLayerszLizmap config has no layer: Úgroup_visibilityz&No Lizmap layer group visibility for: c                 S   s   g | ]}|  ¡ ‘qS r'   r9   r;   r'   r'   r(   r>   ä   s     zGroup z* is in Lizmap layer group visibility for: zGroups z, )-r   ÚlayerPermissionsÚnamer   Úinstancer    ÚrequestHandlerÚisValidÚ	parameterÚupperr   r#   ÚfileNameZcanReadZ	canInsertZ	canUpdateZ	canDeleter	   r   ÚcustomVariablesÚgetÚlistÚsetCustomVariablesÚaccessControlsZresolveFilterFeaturesÚsourceÚlowerr   r   r   ÚconfigFilePathr!   r"   Úlenr   r   ÚwarningÚbaseNamer   r   ÚidÚsplitr   ÚanyÚjoin)r$   r)   ÚrightsÚ
layer_nameÚprojectÚrequest_handlerÚgroupsÚ
user_loginÚ
custom_varZis_wfsZ
datasourceZ	is_googleZis_bingÚcfgZapi_keyÚ
cfg_layersÚlayer_idZ
edit_layerZcan_editZ
group_editr=   Zedit_layer_capÚ	cfg_layerrB   r%   r'   r(   rC   J   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   FrB   c                 S   s   g | ]}|  ¡ ‘qS r'   r9   r;   r'   r'   r(   r>     s     z6LizmapAccessControlFilter.cacheKey.<locals>.<listcomp>é   r6   Tz@@)r   ÚcacheKeyr	   r    rF   rS   r   rR   r   ÚitemsrY   rM   Úset)	r$   Zdefault_cache_keyr^   ra   rb   Zhas_group_visibilityZl_namerd   rB   r%   r'   r(   rf   ÷   s0    
z"LizmapAccessControlFilter.cacheKey)r)   r+   r   c              
   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 zvt| j ¡ ƒ}t| d¡|||d}	t}
|	 ¡ rð|	 ¡ sÌt d t¡¡ tW S |}|	 ¡ rât|gƒ}|	 |¡\}
}W nF tk
r8 } z&t |¡ t d t¡¡ t W Y ¢S d}~X Y nX |
rPt d|
› ¡ t||ƒ}|sn|
rj|
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_polygonr*   zOThe 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 : {}Nz/The polygon filter subset string is not null : Zedition_onlyÚfilterAttributere   r6   Úallz AND ) r   r    rF   r   r	   r   rS   r   rR   r   rD   r   r   rL   Zis_filteredZis_validr   ÚcriticalÚformatr   Zis_filtered_by_userÚtupleZ
subset_sqlÚ	ExceptionÚlog_exceptionr#   r
   r   r   ÚcreateFieldEqualityExpressionÚ_filter_by_loginÚdataProvider)r$   r)   r+   r^   r_   ra   rb   r[   Zedition_contextZfilter_polygon_configZpolygon_filterZgroups_or_userÚ_ÚeÚcfg_layer_login_filterZis_edition_onlyÚ	attributeZlogin_filterr'   r'   r(   r,   *  sŽ    üÿÿ

ÿÿ
&
üz1LizmapAccessControlFilter.get_lizmap_layer_filter)ru   r^   ÚloginÚproviderr   c                 C   s
  g }t | d ƒr| |¡ nt|ƒ}| d¡ g }t | d ¡}|D ]¶}g }t |¡}	| |› d|	› ¡ |dkrê|  d¡rêt |› d¡}
| |› d|
› ¡ t d	|› ¡}
| |› d|
› ¡ t d	|› d¡}
| |› d|
› ¡ | d
 |¡¡ qDd
 |¡}|S )aH   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
        :param provider: The layer data provider ('postgres' for example)
        ÚfilterPrivaterj   ri   z = ZpostgresZallow_multiple_acl_valuesz,%z LIKE z%,z OR )r   ÚappendrM   r   ZquotedColumnRefZquotedStringrL   rY   )ru   r^   rw   rx   ÚvaluesZvalue_filtersZquoted_fieldÚvalueÚfiltersZquoted_valueZquoted_like_valueZlayer_filterr'   r'   r(   rq   •  s*    



z*LizmapAccessControlFilter._filter_by_login)Ú__name__Ú
__module__Ú__qualname__r   r   r   Ústrr-   r   r   ÚLayerPermissionsrC   rf   r   r   r,   ÚstaticmethodÚdictrm   rq   Ú__classcell__r'   r'   r%   r(   r   "   s    .3jr   N)$Ú__copyright__Ú__license__Ú	__email__Ú	qgis.corer   r   r   r   Úqgis.serverr   r   Úlizmap_server.corer   r	   r
   r   r   r   r   Zlizmap_server.filter_by_polygonr   r   r   r   Úlizmap_server.loggerr   r   Úlizmap_server.toolsr   Zlizmap_server.tos_definitionsr   r   r   r   r   r   r'   r'   r'   r(   Ú<module>   s   $		