
    ji}                        U d dl Z d dlZd dlZd dlZd dlmZmZ d dlmZm	Z	m
Z
mZmZmZ d dlZd dl d dlZd dlZd dlmZ ej,                  rd dlmZ e j2                   G d d             Ze j2                   G d	 d
             Ze j2                   G d d             Z e       Zi ae	eef   e d<   d dddZ! e"h d      Z# G d de$      Z% G d dejL                  jN                  jP                        Z(y)    N)OrderedDictdefaultdict)TupleDictOptionalListSetType)*)	CmfEntity)cmf_access_list_metricsc                   R    e Zd ZU dZee   ed<   dZeed<   dZee   ed<   dZ	eed<   y)AccessRuleDataNsubjectsobject_modelobject_fieldsaccess_level)
__name__
__module____qualname__r   r	   str__annotations__r   r   r        ./cmf/models/cmf_access_list.pyr   r      s2    Hc#hL#"M3s8"L#r   r   c                       e Zd ZU dZeed<   dZeed<   dZeed<   dZ	eed<   dZ
eed<    ej                  e      Zee   ed<    ej                  e      Zee   ed	<   y)
AccessListDataNdisabledidcodeinherit_acl_idobject_owner_iddefault_factorycustom_rules
auto_rules)r   r   r   r   boolr   r   r   r    r!   r"   dataclassesfieldlistr%   r   r   r&   r   r   r   r   r      sk    HdBND#NCOS):):):4)PL$~&P'8{'8'8'NJ^$Nr   r   c                   b   e Zd ZU  ej                  e      Zeee	f   e
d<    ej                  d       Zeeee   f   e
d<    ej                  e      Zee   e
d<    ej                  e      Zeeeej&                  j(                     f   e
d<    ej                  e      Zeeef   e
d<   y)	AclDatar#   aclc                       t        t              S N)r   r*   r   r   r   <lambda>zAclData.<lambda>(   s    U`aeUf r   acl_inherit_byused_fieldsstatic_access_control_modelscacheN)r   r   r   r(   r)   dictr-   r   r   r   r   r1   r   setr2   r	   r3   r
   cmfmodels	BaseModelr4   r   r   r   r   r,   r,   %   s    %6[%6%6t%LCc>!	"L+<;+<+<Mf+gNDd3i(g-K--cBKSBJ[+J[J[lpJq $sD1E1E,F'F"Gq 1 1 1$ GE4uGr   r,   _acl_cache_granted_tuplesd      )defaultreadonlyprivate>   fullreadwritec                       e Zd Zy)_AclStopN)r   r   r   r   r   r   rD   rD   @   s    r   rD   c                       e Zd ZU dZdZdZeed<   dZe	j                  j                  j                  j                  dgz   Zd Zed        Zed	        Ze	 	 	 	 	 	 	 	 	 	 	 	 	 	 d2d
ee   dee   dee   dee   dee   dee   dee	j(                  j*                     dee   dee   dee   fd       Zed3d       Zed4d       Zed5d       Zed        Zed        ZdZed        Z ed        Z!e e"ddgddd       d6d!              Z#e e$d"#      d6d$              Z%ed7d%       Z& fd&Z'ed'        Z( fd(Z)d) Z* fd*Z+d+ Z,d, Z-d- Z.d. Z/d6 fd/	Z0d0 Z1d1 Z2 xZ3S )8CmfAccessList TN	_ACL_DATAi subject_list_aclc                     dd| j                   gg dg}t        j                  j                  |dg      D ]  }|j	                           y )N	parent_id=)sys_typerL   autorM   filterfields)r   r8   CmfAccessRuler*   delete)self
acl_filteracl_items      r   clear_auto_aclzCmfAccessList.clear_auto_aclM   sI    "C13LM
,,11ZL1Y 	HOO	r   c                 	   t        dt        j                          d       t        j	                  dd      }d}d}d}d}d}t               }h d}| j                  g d      }	|	D ]  }
|d	z  }t        |
j                  |
j                  |
j                  |
j                  |
j                  
      }||j                  |j                  <   ||j                  |j                  <   |
j                  s|j                  |
j                     j                  |
j                          t         j"                  j                  dg dg dgg d      }|D ]  }|d	z  }|j$                  r|j&                  |vrD|d	z  }t        dt        j                          d| d|j$                   d|j&                   d	       g|j$                  D ch c]!  }t)        j*                  |j                        # }}|j,                  r-|j,                  D ch c]  }t)        j*                  |       c}nd}|r|j.                  j1                  |       t3        ||j4                  xr t)        j*                  |j4                        |t)        j*                  |j&                              }|j                  j7                  |j8                        }|sE|d	z  }t        dt        j                          d| d|j8                   d|j&                   d	       |j:                  dk(  r"|d	z  }|j<                  j                  |       |j>                  j                  |        t@        j                   jB                  jE                         D ]+  }|jF                  dk(  s||jH                  |jJ                  <   - |tL        _'         |        tP        jR                  rtT        jV                  jY                  d	       tT        jZ                  jY                  |       tT        j\                  jY                  |       tT        j^                  jY                  |       tT        j`                  jY                  |       tT        jb                  jY                  |       t        dt        j                          dte        |	       dte        |       d       yc c}w c c}w )u   
        TODO: что делаем, если загрузка acl падает??? Всё разрешаем или всё запрещаем?
        zload_acl_data(pid z): startload_acl_datar<   r   >   denyr@   rA   rB   	denyWrite)r   r"   r!   rQ      )r   r   r    r!   r"   OR)r   rL   N)r   rL   F)rK   rM   r   r   r   r   rO   z): skip z due to empty subjects(z) or invalid access_level()N)r   r   r   r   z due to absent access_list(rN   staticz
): loaded z acl, z rules)3printosgetpidcmfutilmake_prof_pointr,   slistr   r   r   r    r!   r"   r-   r1   appendr8   rR   r   r   sysinternr   r2   updater   r   getrK   rM   r&   r%   r7   r9   iter_subclassesacl_typer3   
class_namerF   rH   configMETRICS_ACCESS_LISTr   rY   rB   access_listaccess_ruleaccess_rule_absentaccess_rule_emptyaccess_rule_autolen)cls
prof_pointaccess_list_countaccess_rule_countaccess_rule_absent_countaccess_rule_empty_countaccess_rule_auto_countacl_datavalid_access_levelsaccess_listsrq   access_list_dataaccess_rulesrr   subjectsubjects_data
field_nameobject_fields_dataaccess_rule_datamodels                       r   rY   zCmfAccessList.load_acl_dataR   sU   
 	"299;-x89,,_cB
#$ "#!"9L yy(YyZ' 
	[K"-$--+..{GWGW*99;KfKf h 3CHLL)../0@HLL),,-))''(B(BCJJ;>>Z
	[ ++1113KLi 2 k ( %	GK"'';+C+CK^+^'1,'(Xk]-k.B.B-C D00;0H0H/ILM CNCWCWXSZZ

3XMX ,, LWKdKd!eZ#**Z"8!e26 !$$++,>?-&[5M5M5vRUR\R\]h]u]uRv0szz+JbJb?c e  (||//0E0EF#(A-((Xk]1+2G2G1H I00;0H0H/ILM  ##v-&!+& ++223CD --445EFK%	GN ZZ))99; 	PE~~)JO55e6F6FG	P #+%%#1177:#//556GH#//556GH#66<<=UV#55;;<ST#44::;QR"299;-z#l:K9LFSVWcSdReeklmY Y!es   &SSc                 :    | j                   }|xr |j                  S )u   Набор полей, по которым существуют правила, чтобы не проверять всё подряд.)rH   r2   )rw   r~   s     r   r2   zCmfAccessList.used_fields   s     ==0H000r   initial_acl_keyr   object_fieldr   r"   	object_idobject_instanceobject_dictobject_parent_idis_newc                 4   
 !"#$% t         j                  }d9"$fd	 "#$
f
d! ! #
%fd}d|vr$t               t         _        t         j                  %n|d   %d%vrdD ]  }%j	                  |d        %dxx   d	z  cc<   d}}rj                  d
g       j                  j                  #j                  $t        j                  j                  d      "t         j                  k(  }t         j                  k(  rt        j                  j                         }"j!                  |j                  j                         n`t         j"                  }|r#|j                  j                  #|j                  $nd#d$|d   "|d   }|d   s|d   r%dxx   d	z  cc<   t$        }|Nt'        t        d      r=|	sr8j)                  d      r&|s#|d   sd}|	r|	j)                  d      r|	}rj)                  d      r}|r| #  }ss| # }| t         j*                   }|d   j-                  |d      }|du rt        j.                  j1                  dd|d      srt         j*                  dk(  r7t        j                  j3                  d|	|t         j                  
      sAt5        i       }t5        i       t         j6                  |<   ndt         j6                  |<   n|n|}|!t'        t        d      rrj)                  d      r|st         j8                  sd}rj-                  d      }n#j:                  j<                  rj:                   }|r| #  }t         j>                  j-                  |d      }|du r~t         j"                  j                  k7  rMt        j.                  j1                  dd|d      s(t5        i       }t5        i       t         j>                  |<   ndt         j>                  |<   n|n|}|\|rZd}|	r|	j)                  d      r|	}t        j@                  jC                  ||      }|dk(  rn|d k(  rt5        d!h      }nt5        i       }|r|	rp#rnsltE        t         d"d      }|Ot        jF                  jI                  d#d$gd%d&d'#gd(d)#ggg*      D ch c]  }|j                   }}|t         _%        |	|v rt$        }|		  |       }	 |r||vrd}|sh|rft[        d.t         j\                   d/ d0# d1| d2 d3 d4 d5| d6 d7xr t        j^                  j-                         d8       ta        |      |S c c}w # tL        $ rv}|jN                  d	   }tP        jR                  j-                   jU                  |            }| ||d+   k(  r  |d,   d-|        tW        jX                  d	       Y d}~nd}~ww xY w|):u  
        Проверка/получение прав доступа к объекту или его полю.
        Возвращает список доступных прав.
        Если raise_error == True, то генерирует стандартную ошибку о недостаточности прав доступа.
        Если текущий пользователь админ, или владелец объекта, или проверка прав отключена, то выдаём полные права.

        :param object_parent_id:
        TODO: object_instance может быть без филдов при sget и is_web_public
        :param object_instance:
        :param is_new:
        :param object_id:
        :param object_dict:
        :param initial_acl_key: id/code - списка доступа, по которому начинанать поиск.
        :param object_model: имя модели объекта, если пременимо
        :param object_field: поле объекта, если применимо
        :param access_level: если указан, то проверяется наличие конкретного уровня доступа.
        :param object_owner_id: владелец объекта, параметр для удобства,
            если указан и совпадает с текущим пользователем, то получаем полные права.
        :param raise_error: определяет: return False или raise CmfPermissionError
        :param checking_person - если указан, проверяются его права, а не сессионный g.current_person
        :param perm_security_level_allowed_ids - ?
        :param checked_policy - объект проверен бизнес логикой и нужно использовать указанную политику
        :return: Set[str]/False/raise CmfPermissionError
        Nc                 |   	
 	
fd	fd fdt               
t               	g 	 r         d       |rM|dv r d        d        d       t        |dk(  r d       t        |d	k(  r	 t        t        d
|      rTrRt        t              }|j
                  }|dk(  rn0|dk(  r d       t        |d	k(  rt        t        d d| d      r d        d        d       t        
      }t        j                  ||      }|S # t        $ r Y .w xY w)Nc                 2    | vrj                  |        y y r/   )add)access_level_deniedgranteds    r   	add_grantzBCmfAccessList.check_access.<locals>.calc_access.<locals>.add_grant   s     .KK. /r   c                    | j                   r| j                   k(  r| j                  r| j                  v r| j                  z  r| j                  dk(  r d        d        d       t        | j                  dk(  rt        | j                  dk(  r#j                  d       j                  d       y | j                  dk(  r d        d       y | j                  dk(  r	 d       y y y y y )Nr@   rB   rA   rZ   r[   )r   r   r   r   rD   r   )ruler   r   r   r   r   s    r   
check_rulezCCmfAccessList.check_access.<locals>.calc_access.<locals>.check_rule   s    **d.?.?<.O!//<4CUCU3U!DMM1((F2!&)!'*!&)&**f4&**k9

6*

7+**g5!'*!&)**f4!&) 5 2 4V /Pr   c           	          j                   j                  |       }|sI| t        j                  k(  ry t	        d|  d dt
        j                                 t        d|  |       |j                  v r)t	        d|j                   d        t        d|        j                  |j                         t        j                  |j                  |j                        D ]
  } |        |j                  r |j                        S y )Nz.   !!!    CmfAccessList.check_access: acl_key z not found, processed z, pid=u   Не загружен ACL z0   !!!    CmfAccessList.check_access: recursion z in u+   !!! Кольцевые ссылки у ACL )r-   rk   g
new_acl_idra   rb   rc   CmfACLNotFoundErrorr   CmfErrorrg   	itertoolschainr%   r&   r!   )acl_keyr-   r   r~   	check_aclr   processed_aclss      r   r   zBCmfAccessList.check_access.<locals>.calc_access.<locals>.check_acl   s   ll&&w/!,,.$$+9,B>BRRXY[YbYbYdXegh .0J7).TV]^^66^+LSVVHTXYgXhij"%PQXPY#Z[[%%cff- &OOC,<,<cnnM %Dt$%%%$S%7%788 &r   global)r@   rB   r@   rB   rA   rZ   z@Invalid policy value checked_policy, allowed: read, write, fulllr=   r>   zInvalid model acl policy z.acl_default_user_policy(z!), valid: default, readonly, deny)
r6   
ValueErrorrD   getattrr8   acl_default_user_policyr   tupler:   
setdefault)r~   checked_policyr   	model_clsmodel_policygranted_tupler   r   r   r   r   r   r   current_person__member_ofr   is_local_userr   s   ` `   @@@@@@@r   calc_accessz/CmfAccessList.check_access.<locals>.calc_access   s   /* *,94 eGUFN0H-"o. (# "%)::!&)!'*!&) #N (61!&) #N (61 #N )^`np p  M ' =I#,#D#DL#y0%3!&)&%/&&7~E^_k^l m> ?@ @
 !f%g&f% "'NM5@@P]^M    s   CD/ /	D;:D;c                   
 d}	r| j                   rd}nډk(  r| j                  r| j                  v rd}nv r| j                  r| j                  v rd}nr| j                  r| j                  v rd}nxrv| t        j
                  k(  rc
r
j                  dd      r'rM	rj                  s?nj                  j                  s(}|st        j                  }|j                  d      rd}|rd}n#| j                  rvr| j                  v }nd}|rt        h d      }n|rt        dh      }n
t               }t        j                  ||      S )NFT
user_localContactAdmins)
group_code>   r@   rA   rB   rA   )acl_allow_createacl_static_owner_write_fieldsacl_static_self_write_fieldsacl_static_user_write_fieldsr8   	CmfPersonrk   r   oldr   current_userin_person_groupacl_static_public_fieldsr   r:   r   )static_acl_modelallow_write_chk_person
allow_readresult_checking_personr   current_person_idr   r   r   r   r   r   r"   s        r   calc_staticz/CmfAccessList.check_access.<locals>.calc_staticJ  sb   K*;;" $55(FF$(8(V(VV"77(EE$(8(U(UU"#3#P#P$(8(U(UU" #3v7G7G#G!+//,*M'v1K1K[j[u[u[y[y-""#..K../.J"&K!
#<<H\^g  pI  _I!-1A1Z1Z!ZJ "&J 9:/' -77IIr   c                     d } j                   }|st        d      |j                  j                        }|rt	        j
                        xr t	        j
                        xr t	        j
                        xr t	        j
                        xr t	        j
                        f}|j                  j                  |      } | dxx   dz  cc<   ndxx   dz  cc<    
|      } | rk(  rdxx   dz  cc<   t        } | }|j                  vrd }}|s#rj                  d      }nrt        dd       }t	        j
                        xr t	        j
                        xr t	        j
                        |xr t	        j
                  |      |xr t	        j
                  |      f}|j                  j                  |      } | dxx   dz  cc<   | S dxx   dz  cc<    	|||	      } | |j                  |<   t        |j                        j                  kD  rt	        j                  |j                        t        |j                        t	        j                  |      z  z   }t        d
t        |j                         d|dz   d       t        j                  |j                  j!                         j                  dz        D ci c]  \  }}||
 c}}|_        | S c c}}w )Nu8   Система ACL не инициализированаacl_check_cache_staticr]   acl_check_calc_staticacl_check_owner_skip_acl_policyacl_check_cacheacl_check_calc)r   r   z!CmfAccessList: shrink cache, len z, size i   z Kb   )rH   CmfACLNotInitializedErrorr3   rk   rh   ri   r4   _full_accessr2   r   rv   _CACHE_MAX_SIZE	getsizeofra   r   isliceitems)r   r~   r   	cache_keyobject_field_checked_policy_
cache_sizekvr   r   r   rw   r   r   r   r   r   r   r   r   r"   stats            r   check_with_acl_dataz7CmfAccessList.check_access.<locals>.check_with_acl_dataw  s   G}}H/0jkk'DDHHV JJ017#**Y"7#C

?(C =SZZ%= =SZZ%=	 #..,,Y7&12a7201Q61)*:;G ":K'K/0A50*G ,x';';;$(M"0&"*5//-*H(*1/=RV*W JJ01#C

?(C =SZZ%=!?cjj&?#C

?(CE	 #..,,Y7&*+q0+ N )*a/*)(?anoG07HNN9- 8>>*S-@-@@%(]]8>>%B3x~~CVWZWdWdenWoCo%o
?HNN@S?TT[\fhl\l[mmpqs
 .7-=-=hnn>R>R>TVYViViklVl-m*o%)QAqD*oN*os   %K=profiler_data	acl_check)r   acl_check_skipr   r   r   r   r   r   r]   r   Tid_onlyFr   current_user_is_anonymousdisable_permissionsacl_admin_moder   CmfProjectPermSchemezCmfProject:#current_user_is_sharelink_anonymousproject_perm_browse_cache.zPPP-PR-BROWSE)project_id_simplecheckobj_dict_simplecheckobjraise_errorpub_api)
r   r   r"   r   r   r   r   perm_security_level_allowed_idsr   r   zCmfTimeTrackerHistory:
project_idzPPP-WORKLOG-VIEWr@   r>   rA   acl_owned_projects--r   r^   cmf_owner_idrL   cmf_owner_assistantsINrQ   rP   
request_iddebugz2CmfAccessList.check_access(): waiting for loading z   !!!   ACL access denied for z(or z)(z), request z	, to acl=z, model=z, field=z
(requsted z), object_owner_id=(r_   )NN)1r   __dict__r   r   r   load_fieldsr   valuer   r8   rF   subject_full_group_listanonymous_usersharelink_anonymous_userCmfPersonGroupsharelink_groupr   r   r   hasattr
startswith	api_scoperk   r   check_project_role_accesscheck_accessr   r   r   r   is_not_null%project_perm_timetrackerhistory_cacheCmfSecurityLevelcheck_perm_security_levelr   
CmfProjectrf   r   r   argsREDIS_DBredis_new_acl_keytimesleepra   current_personr   CmfPermissionError)&rw   r   r   r   r   r"   r   r   r   r   r   r   r   r   r   _CmfAccessList__gr   stat_keyresultrequested_object_fieldr   r   _userr   ppp_cache_keyppp_ressec_res_acl_owned_projectsprojecteacl_idr   r   r   r   r   r   r   s&   ```` ```` ` ` `                 @@@@@@r   r  zCmfAccessList.check_access   s   R jjn	! n	!`+	J +	JZG	 G	 G	R #%)mAO??D'Dd"G -
 !,- 	[Q!- ''7 / 2 2 8 8+66M(.(<(<(T(TUdnr(T(s%(71;K;K(K%!"<"<<"("7"7"G"G"I)--o.@.@.F.FG NNE$)HHNN! % 0 0$(! %(+,G(H%(+,G(H%()S1A-B%&!+&% >gf.DE%)	8L8L]8[1#>c:dJ$4$?$?$N-
Y11-@&
 $.,/@.A) M"? (2l3D2E$FM#0/!++ ?9:>>}cRc> "66PPQUWfhrfqUd]b	 Q e !"y 8V=Q=Q=^=^0?ll{,1YYi,7Yx/=qO_O_	 >_ >a
 &+2YF
 JOrA77FEI33MB_ %F>gf.DE)"6"67O"P1!:_:_J(__\:
 ++77 / : :;
#-,/@.A) MAAEEmUXYc>&!..*;*;;FD_D_DyDyz~  AShrfqUd]b	 Ez Ee "'rQVWYQZ??N RV??N_$F>=J$4$?$?$N-
--GGHgistG& J&xr >.3D'")!-A4"H"* $*#4#4#:#:$($< $~s<M&N!7@Q?R S U $; $'   JJ'# ' (;$#66%n,. L6F+1!2B2B1C4GXXZ[lZmmx  zF  yG G*+ ,&x~ZH^G_ `$$3#4Ao6o&JZJZJ^J^_nJo5ppqst %\3I?[[S'" ' %^^//0@0@0HI
%\!22 GQRXQYZ[

1	 ns   $VV 	XA,XXFc                    |s| r| j                   j                  }t        j                  j                  j                  }dd|gdd|gg}t        j
                  j                  |dg      D ch c]-  }|j                  rt        j                  |j                        / }}|j                  t        j                  |             |r|S |D 	ch c]  }	t        j                  |	|      x}
s|
  }}	|S c c}w c c}	w )Nchild_idrL   parent_modelr   rK   rO   r\   )r   r   r8   rR   r   RelationCacherf   rK   rh   ri   r   rd   get_obj_by_id)r   
subject_idr   rQ   _kwargsgroup_model_namesrelation_filterrelationr  group_idr   s              r   r   z%CmfAccessList.subject_full_group_list  s    g ))J"0099@@&Z8>4Qb:cd #0066oWbVc6d#!! JJx))*# #
 	

3::j)*M&,h(8M8Mh_e8M8f1f1f#hh# is   -2C4C9,C9c                     | j                  ||d      }t        j                  j                  dgddt	        |      g      }|sg }|dd|D 	cg c]  }	|	j
                   c}	gg}| j	                  |||      S c c}	w )	NT)r   r$  r   rK   r   r   r   r   )rQ   rP   order_by)r   r8   rR   rf   r*   rK   )
rw   r   r$  rQ   rP   r+  r%  	member_ofrelated_rulesr   s
             r   rI   zCmfAccessList.subject_list_acl  s    //J`d/e	,,22;-Q[]acghqcrPs2tF4='Q4'QRSxxvfxxHH (Rs   A:
c                 `    t         j                  st         j                  ry|rt        |       y)NTF)r   r   r   r  )messager   s     r   check_admin_modezCmfAccessList.check_admin_mode  s'      A$4$4$W--r   c                  >   t         j                  j                         j                  t        j
                  j                  j                  d      vr5t        j                  s%t        j                  j                  st        d      dt        _        dt        _        y )NTr   activate_admin_mode)r8   r   admin_groupr   r   r  rg_member_ofall_parents
is_supportr   r  r   r   r   r   r   r2  z!CmfAccessList.activate_admin_mode  si      ,,.119I9I9V9V9b9bko9b9pp)B)B$%:;; $r   c                 F    dt         _        dt         _        dt         _        y)u   Первоначальная инициализация контекста, чтобы работали g.current_person, в т.ч. создание пользователей.TN)r   r   r   r   )rw   s    r   init_contextzCmfAccessList.init_context  s     !%&*#r   c                 *   t        t        dd      t        _        t        j                  r0t        j                  s dt        _        t               t        _        n+t        j                  t        j                  k(  t        _        t        j                  j                  t        j                  d      t        _        t        j                  st        j                  j                  st        j                  t        j                  k7  r~t        j                   dk7  rk| j"                  s6t%        t        j&                  j)                         j*                        | _        t        j                  j-                  | j"                         t        j
                  rdt        _        t        j.                  rct        j0                  rRt        j&                  j3                         }t        j                  j-                  |j*                  j4                         yyy)u\   Сейчас уже должны быть рабочие g.current_person и g.system_personr   NTr   sd_api)r   APPr   r   system_personr   r6   r   r  r8   rF   r   ro   IS_AUTHORIZATORr   r   r  _CmfAccessList__guest_group_idr   r   guest_groupr   r   sharelink_access_requestsharelink_access_grantedr   r   )rw   r   s     r   setup_contextzCmfAccessList.setup_context  sT    !(-BD I  #A*-%A' //1??BA*0*>*>*V*VWXWgWgqu*V*vA' ..,,77((A,<,<<x/+++.v/D/D/P/P/R/U/U+VC(++//0D0DE$(A! %%!*D*D$33CCEO''++O,>,>,D,DE +E%r   c                    t               }t               }|D ]-  }|j                  | j                  t        |      d             / | j                  }|sy|j
                  j                         D ]Z  }g |j                  |j                  D ]:  }|j                  |j                        s|j                  |j                          Z \ |r| j                  |d       yy)u  
        Нужно по списку субъектов получить список затронутых ACL и вызвать
            trigger_reload(access_list_ids)

        TODO: плохо, что ищем по текущим данным ACL, которые могут устареть.
            Можно перенести эту логику на серверный обработчик события
        T)r$  r   NF)access_list_idsuser_show_acl_apply_progress)r6   rj   r   r   rH   r-   valuesr&   r%   intersectionr   r   r   trigger_reload)rw   subjects_idsrD  affected_subjects_idsr$  r~   r-   r   s           r   subject_changed_hookz"CmfAccessList.subject_changed_hook  s     % #& 	pJ!(()D)DPST^P_im)D)no	p ==<<&&( 	C<#..<3+;+;< (55dmmD#''/	
 ]bc r   rD  u,   Применение изменений ACL 
   )	only_onceonly_once_argsdescriptionshow_bg_progressbar	countdownc           	        
 t         j                  d       t        j                  j	                          d}t               
| sd g} 
fd| D ]z  }|d}t         j                  d        n_t        j                  j                  j                  |      }|sJ|j                  dk(  rd}t         j                  d        n |g       | |st         j                  d|  d	
        t        t        j                  d
             }d}dt        |      z  }|D ]  }||z  }|r!t        j                  |j                   d        ,|j#                  ddgddt        
      gddg      D ch c]  }|j$                   }	}|	sjt         j                  d|j                    dt        |	              t        |	      dkD  rCt         j                  d|j                           t        j                  |j                   d        t        j                  |j                   |	        t         j                  d       y c c}w )Nzacl::proccess_chanded_acl startFc                     | sy | D ]G  }|v rj                  |        t        j                  j                  j	                  |             I y r/   )r   rF   rH   r1   rk   )acl_id_list_acl_id_full_idsprocess_acl_lists     r   rW  z@CmfAccessList.proccess_chanded_acl_job.<locals>.process_acl_list   sP    ' Vh&W% !8!8!G!G!K!KG!TU	Vr   Tz8process_changed_acl(): acl_id is None, drop_all_cache!!!r   z(process_changed_acl(): drop_all_cache!!!z#process_changed_acl(): changed_acl=z, affected_acl=c                 "    t        | t              S r/   )
issubclassr   )ms    r   r0   z8CmfAccessList.proccess_chanded_acl_job.<locals>.<lambda>:  s    
1i8P r   r   r;   r   r   perm_effective_acl_idr   e   )rQ   rP   slicez3acl::proccess_chanded_acl run invalidate_ids model=z len=z>acl::proccess_chanded_acl too many, flush all cache for model=zacl::proccess_chanded_acl end)r   r   r8   rF   rY   r6   rH   r-   rk   r    r*   rd   iter_modelsrv   	CMF_CACHEinvalidate_idsrn   rf   r   )rD  drop_all_cacher  r-   
model_listpctpct_stepr   r   obj_idsrV  rW  s             @@r   proccess_chanded_acl_jobz&CmfAccessList.proccess_chanded_acl_job  s:   
 	
13
 	**, 5#fO	V & 	'F~!%RS))--11&9Cxx8#!%BCfX&	' GG9/9J/ZbYcde'--.PQR
Z( 	@E8OC (()9)94@ !;;tTlD[]acghpcqCr{|  B  {C;  DE EG E GGI%JZJZI[[`adelam`nop7|c! XY^YiYiXjkl(()9)94@$$U%5%5w?)	@* 	
/1Es   ,H<CmfAccessList:changed)channelc                 N    d }t        d       dat        j                  |       y )Nc                  $   t        d       t        j                  d       t        rSt        d       dat        j
                  j                         5  t        j                  j                          d d d        y t        d       y # 1 sw Y   y xY w)Nzacl::reload handler spawned   zacl::reload handler do reloadFzacl::reload handler skip)
ra   r  r  _acl_need_reloadr7   appcmf_contextr8   rF   rY   r   r   r   handlerz,CmfAccessList.on_acl_change.<locals>.handlerY  so    /1JJqM57#( WW((* 9((6689 9 029 9s   BBzacl::reload spawn handlerT)ra   rl  geventspawn)datar%  ro  s      r   on_acl_changezCmfAccessList.on_acl_changeT  s$    

	3 	)+Wr   c           
         t        d       g }|Ft        dd|D cg c]  }t        |       c}i       |D ]  }|j                  t        |              r)t        ddt        |      i       |j                  |       nt        dd        d }|rAt        j
                  j                  t        j                  j                  j                         t        | j                  d|i       y c c}w )Nzacl::reload triggerrg  rD  access_list_id)kwargs)ra   cmf_emit_server_eventr   rg   r   deferred_force_show_progressbarr   r8   rF   rf  nameschedule_deferred_job)rw   ru  rD  rE  job_access_list_ids        r   rH  zCmfAccessList.trigger_reloadi  s    #%  &!'"$_^S%8$_`b #2 ?"))#n*=>?!"9<LcR`Na;bc%%n5!"94@!%'--11&2F2F2_2_2d2dec::DUWiCjk %`s   C,c                 *    t         |          g dz   S )N)r   policyparent)supersave_preload_fields)rT   	__class__s    r   r  z!CmfAccessList.save_preload_fields  s    w*,/OOOr   c                     d|  S )NzCmfAccessList::created:r   )r  s    r   r  zCmfAccessList._new_acl_key  s    (11r   c                    | j                  | j                         | j                  rIt        j                  j                  | j                  | j                        t        j                  d       t        | (  di |S )NrL  )exr   )rH  r   r   r  r  r6   r  r   r   r  save)rT   rv  r  s     r   r  zCmfAccessList.save  s\    DGG$;; NNt0091<<BOw|%f%%r   c                 d   g }t         j                  j                  j                         D ]Q  }|j	                  |j                  g dddd| j                  gdd| j                  gdd| j                  gg             S |j	                  | j                  g dd	d| j                  g             |S )
N)r   r   r    ry  r[  perm_inherit_acl_idperm_acl_idr^   r[  rL   r  r  r   )r   r   r    r[  r  r  r!   )r7   r8   r   rl   extendrf   r   )rT   r%  r  r   s       r   find_acl_usagezCmfAccessList.find_acl_usage  s    ZZ))99; 	5EMM%++r,c477;*C9"C1	3 & 4 5	5 	djjf$c4773 ! 5 	6 r   c           
          | j                         }|r t        d|  dt        |       d|d d        | j                  | j                         t        |   di |S )Nu)   Не возможно удалить acl u,   , т.к. на него существует u    ссылок, rL  r   )r  CmfOrmIntegrityErrorrv   rH  r   r  rS   )rT   rv  usager  s      r   rS   zCmfAccessList.delete  s    ##%&;D6Amnqrwnxmy  zI  JO  PS  QS  JT  IU  VW WDGG$w~'''r   c                      y r/   r   rT   s    r   _calc_perm_parentzCmfAccessList._calc_perm_parent      r   c                      y r/   r   r  s    r   _calc_perm_has_aclz CmfAccessList._calc_perm_has_acl  r  r   c                      y r/   r   )rT   r%  s     r   _calc_perm_aclzCmfAccessList._calc_perm_acl  r  r   c                      y r/   r   r  s    r   _calc_perm_effective_aclz&CmfAccessList._calc_perm_effective_acl  r  r   c                 J    |st         j                  g}t        |   |      S )N)spread_models)r8   rR   r  _acl_spread_inheritance)rT   r  r  s     r   r  z%CmfAccessList._acl_spread_inheritance  s'    #112Mw.].KKr   c                     | j                          | j                  rd| _        | j                  d       |j                  dk7  r,t        j
                  j                  | j                  d       y y )NFT	only_datarN   rE  )save_preparer   r  rM   r8   rF   rH  r   rT   r   s     r   save_rule_hookzCmfAccessList.save_rule_hook  sY    ==!DMIII%==F"  //VZ/[ #r   c                 H   | j                          | j                  sKt        j                  j	                  dd| gdd|j
                  gg      sd| _        | j                  d       |j                  dk7  r,t        j                  j                  | j
                  d	       y y )
Nr~  rL   r   z!=)rP   Tr  rN   r  )
r  r   r8   rR   rf   r   r  rM   rF   rH  r  s     r   delete_rule_hookzCmfAccessList.delete_rule_hook  s    }}V%9%9%?%?!3-dDGG/DE &@ &G DMIII%==F"  //VZ/[ #r   )NNNNNNNNNNTNNN)NNFN)NNNNN)r0  Tr/   )NNF)4r   r   r   __doc__TEXKOM_no_cacherH   r,   r   r   r7   rQ   cmf_access_listrF   api_methodsrW   classmethodrY   r2   r   r   r8   r9   r5   r'   r  staticmethodr   rI   r0  r2  r8  r>  rB  rK  cmf_deferred_jobrf  on_server_eventrs  rH  r  r  r  r  rS   r  r  r  r  r  r  r  __classcell__)r  s   @r   rF   rF   D   s   
OIwO**,,::FFJ
 
K
 Un Unn 1 1
  .2*.*.*.-1'+>B*..2%) ,0\%c]\ #3-\ #3-	\
 #3-\ &c]\  }\ &cjj&:&:;\ "$\ 'sm\ TN\ \|  " I I   % %     "F "FH d d2 (9':BX]ikmJ2m J2X 45 6 & l l.P 2 2&(L
\	\r   rF   ))r(   r   rh   r  collectionsr   r   typingr   r   r   r   r	   r
   rp  cmf.includecmf.appr7   cmf.fields.cmf_access_list
cmf.modelsr   ro   rp   cmf.metricsr   	dataclassr   r   r,   r6   _acl_changed_idsr:   r   _policy_prioritiesr   r   	ExceptionrD   rQ   r  rF   r   r   r   <module>r     s      
  0 9 9    !  	3    O O O H H H 5 02 4u- 2 
 ./	y 	I\CJJ..<< I\r   