
    6h                        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*                   G d d             Ze j*                   G d d	             Ze j*                   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jD                  jF                  jH                        Z$y)    N)OrderedDictdefaultdict)TupleDictOptionalListSetType)*)	CmfEntityc                   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   r0   r   setr1   r	   r2   r
   cmfmodels	BaseModelr3   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   rC   rC   >   s    r   rC   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	 	 	 	 	 	 	 	 	 	 	 	 	 	 d1d
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d2d       Zed3d       Zed4d       Zed        Zed        ZdZed        Z ed        Z!e e"ddgddd      d5d               Z#e e$d!"      d5d#              Z%ed6d$       Z& fd%Z'ed&        Z( fd'Z)d( Z* fd)Z+d* Z,d+ Z-d, Z.d- Z/d5 fd.	Z0d/ Z1d0 Z2 xZ3S )7CmfAccessList TN	_ACL_DATAi subject_list_aclc                     dd| j                   gg dg}t        j                  j                  |      D ]  }|j	                           y )N	parent_id=)sys_typerK   autofilter)r   r7   CmfAccessRuler)   delete)self
acl_filteracl_items      r   clear_auto_aclzCmfAccessList.clear_auto_aclK   sE    "C13LM
,,111D 	HOO	r   c                    t        dt        j                          d       t               }h d}| j	                  g d      }|D ]  }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 ]  }|j                   r|j"                  |vr?t        dt        j                          d| d|j                    d|j"                   d	       ]|j                   D ch c]!  }t%        j&                  |j                        # }	}|j(                  r-|j(                  D 
ch c]  }
t%        j&                  |
       c}
nd}|r|j*                  j-                  |       t/        |	|j0                  xr t%        j&                  |j0                        |t%        j&                  |j"                              }|j                  j3                  |j4                        }|s@t        dt        j                          d| d|j4                   d|j"                   d	       |j6                  dk(  r|j8                  j                  |       |j:                  j                  |        t<        j                  j>                  jA                         D ]+  }|jB                  dk(  s||jD                  |jF                  <   - |tH        _%        t        dt        j                          dtM        |       dtM        |       d       yc c}w c c}
w )u   
        TODO: что делаем, если загрузка acl падает??? Всё разрешаем или всё запрещаем?
        zload_acl_data(pid z): start>   denyr?   r@   rA   	denyWrite)r   r!   r    fields)r   r   r   r    r!   OR)r   rK   N)r   rK   F)rJ   rL   r   r   r   r   rO   rZ   z): skip z due to empty subjects(z) or invalid access_level()N)r   r   r   r   z due to absent access_list(rM   staticz
): loaded z acl, z rules)'printosgetpidr+   slistr   r   r   r   r    r!   r,   r0   appendr7   rP   r   r   sysinternr   r1   updater   r   getrJ   rL   r%   r$   r6   r8   iter_subclassesacl_typer2   
class_namerE   rG   len)clsacl_datavalid_access_levelsaccess_listsaccess_listaccess_list_dataaccess_rulesaccess_rulesubjectsubjects_data
field_nameobject_fields_dataaccess_rule_datamodels                 r   load_acl_datazCmfAccessList.load_acl_dataP   sc   
 	"299;-x89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^+^(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#(Xk]1+2G2G1H I00;0H0H/ILM  ##v- ++223CD --445EFC!	GF ZZ))99; 	PE~~)JO55e6F6FG	P #+"299;-z#l:K9LFSVWcSdReeklmC Y!es   &N8N=c                 :    | j                   }|xr |j                  S )u   Набор полей, по которым существуют правила, чтобы не проверять всё подряд.)rG   r1   )rl   rm   s     r   r1   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?   rA   r@   rW   rX   )r   r   r   r   rC   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,   rg   g
new_acl_idr_   r`   ra   CmfACLNotFoundErrorr   CmfErrorrc   	itertoolschainr$   r%   r    )acl_keyr,   r   rm   	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?   rA   r?   rA   r@   rW   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)
r5   
ValueErrorrC   getattrr7   acl_default_user_policyr   tupler9   
setdefault)rm   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?   r@   rA   r@   )acl_allow_createacl_static_owner_write_fieldsacl_static_self_write_fieldsacl_static_user_write_fieldsr7   	CmfPersonrg   r   oldr   current_userin_person_groupacl_static_public_fieldsr   r9   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_static4  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_static   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   )rG   CmfACLNotInitializedErrorr2   rg   rd   re   r3   _full_accessr1   r   rk   _CACHE_MAX_SIZE	getsizeofr_   r   isliceitems)r   rm   r   	cache_keyobject_field_checked_policy_
cache_sizekvr   r   r   rl   r   r|   r   r   r}   r~   r   r   r!   stats            r   check_with_acl_dataz7CmfAccessList.check_access.<locals>.check_with_acl_dataa  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=   r@   acl_owned_projects--r   r[   cmf_owner_idrK   cmf_owner_assistantsINrZ   rO   
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   r7   rE   subject_full_group_listanonymous_usersharelink_anonymous_userCmfPersonGroupsharelink_groupr   r   r   hasattr
startswith	api_scoperg   r   check_project_role_accesscheck_accessr   r   r   r   is_not_null%project_perm_timetrackerhistory_cacheCmfSecurityLevelcheck_perm_security_levelr   
CmfProjectrb   r   r   argsREDIS_DBredis_new_acl_keytimesleepr_   current_personr   CmfPermissionError)&rl   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c                    |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_idrK   parent_modelr   rJ   r\   rY   )r   r   r7   rP   r   RelationCacherb   rJ   rd   re   r   cmfutilget_obj_by_id)rt   
subject_idr   rZ   _kwargsgroup_model_namesrelation_filterrelationr	  group_idr   s              r   r   z%CmfAccessList.subject_full_group_listy  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)rt   r  r   rJ   r   r   r   r   )rZ   rO   order_by)r   r7   rP   rb   r)   rJ   )
rl   rt   r  rZ   rO   r   r  	member_ofrelated_rulesr   s
             r   rH   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)r7   r   admin_groupr   r   r  rg_member_ofall_parents
is_supportr   r  r   r   r   r   r   r'  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   )rl   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   r5   r   r  r7   rE   r   configIS_AUTHORIZATORr   r   r   _CmfAccessList__guest_group_idr   r   guest_groupr   r   sharelink_access_requestsharelink_access_grantedr   r   )rl   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                  |       yy)u  
        Нужно по списку субъектов получить список затронутых ACL и вызвать
            trigger_reload(access_list_ids)

        TODO: плохо, что ищем по текущим данным ACL, которые могут устареть.
            Можно перенести эту логику на серверный обработчик события
        T)r  r   N)access_list_ids)r5   rf   r   r   rG   r,   valuesr%   r$   intersectionr   r   r   trigger_reload)rl   subjects_idsr:  affected_subjects_idsr  rm   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#''/	
 ? r   r:  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   rE   rG   r0   rg   )acl_id_list_acl_id_full_idsprocess_acl_lists     r   rL  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   r/   z8CmfAccessList.proccess_chanded_acl_job.<locals>.<lambda>$  s    
1i8P r   r   r:   r   r   perm_effective_acl_idr   e   )rZ   rO   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   r7   rE   rz   r5   rG   r,   rg   r   r)   r  iter_modelsrk   	CMF_CACHEinvalidate_idsrj   rb   r   )r:  drop_all_cacher  r,   
model_listpctpct_stepry   r   obj_idsrK  rL  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)
r_   r  r  _acl_need_reloadr6   appcmf_contextr7   rE   rz   r   r   r   handlerz,CmfAccessList.on_acl_change.<locals>.handlerC  so    /1JJqM57#( WW((* 9((6689 9 029 9s   BBzacl::reload spawn handlerT)r_   ra  geventspawn)datar  rd  s      r   on_acl_changezCmfAccessList.on_acl_change>  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 }t	        | j
                  d|i       y c c}w )Nzacl::reload triggerr\  r:  access_list_id)kwargs)r_   cmf_emit_server_eventr   rc   schedule_deferred_jobr[  )rl   rj  r:  job_access_list_ids       r   r=  zCmfAccessList.trigger_reloadS  s    #%  &!'"$_^S%8$_`b #2 ?"))#n*=>?!"9<LcR`Na;bc%%n5!"94@!%c::DUWiCjk %`s   B)c                 *    t         |          g dz   S )N)r   policyparent)supersave_preload_fields)rR   	__class__s    r   rs  z!CmfAccessList.save_preload_fieldsi  s    w*,/OOOr   c                     d|  S )NzCmfAccessList::created:r   )r  s    r   r  zCmfAccessList._new_acl_keyl  s    (11r   c                    | j                  | j                         | j                  rIt        j                  j                  | j                  | j                        t        j                  d       t        | (  di |S )NrA  )exr   )r=  r   r   r   r  r5   r  r   r   rr  save)rR   rk  rt  s     r   rx  zCmfAccessList.savep  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   namerP  perm_inherit_acl_idperm_acl_idr[   rP  rK   r{  r|  r   )r   r   r   rP  r{  r|  r    )r6   r7   r   rh   extendrb   r   )rR   r  r	  ry   s       r   find_acl_usagezCmfAccessList.find_acl_usagex  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    ссылок, rA  r   )r~  CmfOrmIntegrityErrorrk   r=  r   rr  rQ   )rR   rk  usagert  s      r   rQ   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   rR   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   )rR   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)r7   rP   rr  _acl_spread_inheritance)rR   r  rt  s     r   r  z%CmfAccessList._acl_spread_inheritance  s'    #112Mw.].KKr   c                     | j                          | j                  rd| _        | j                  d       t        j                  j                  | j                         y )NFT	only_data)save_preparer   rx  r7   rE   r=  r   )rR   _rules     r   save_rule_hookzCmfAccessList.save_rule_hook  sB    ==!DMIII%++DGG4r   c                 $   | j                          | j                  sKt        j                  j	                  dd| gdd|j
                  gg      sd| _        | j                  d       t        j                  j                  | j
                         y )Nrq  rK   r   z!=rN   Tr  )	r  r   r7   rP   rb   r   rx  rE   r=  )rR   r   s     r   delete_rule_hookzCmfAccessList.delete_rule_hook  sv    }}V%9%9%?%?!3-dDGG/DE &@ &G DMIII%++DGG4r   )NNNNNNNNNNTNNN)NNFN)NNNNN)r%  Tr.   r   )4r   r   r   __doc__TEXKOM_no_cacherG   r+   r   r   r6   rZ   cmf_access_listrE   api_methodsrU   classmethodrz   r1   r   r   r7   r8   r4   r&   r   staticmethodr   rH   r%  r'  r-  r4  r8  r@  cmf_deferred_jobr[  on_server_eventrh  r=  rs  r  rx  r~  rQ   r  r  r  r  r  r  r  __classcell__)rt  s   @r   rE   rE   B   s   
OIwO**,,::FFJ
 
K
 An AnF 1 1
  .2*.*.*.-1'+>B*..2%) ,0\%c]\ #3-\ #3-	\
 #3-\ &c]\  }\ &cjj&:&:;\ "$\ 'sm\ TN\ \|  " I I   % %     "F "FH @ @2 (9':BX\hjlJ2l J2X 45 6 & l l*P 2 2&(L
55r   rE   )%r'   r   rd   r  collectionsr   r   typingr   r   r   r   r	   r
   re  cmf.includecmf.appr6   cmf.fields.cmf_access_list
cmf.modelsr   	dataclassr   r   r+   r5   _acl_changed_idsr9   r   _policy_prioritiesr   r   	ExceptionrC   rZ   r  rE   r   r   r   <module>r     s      
  0 9 9    !      O O O H H H 5 02 4u- 2 
 ./	y 	n5CJJ..<< n5r   