
    ti                        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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 j4                   G d d             Ze j4                   G d	 d
             Ze j4                   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jN                  jP                  jR                        Z)y)    N)OrderedDictdefaultdict)TupleDictOptionalListSetTypeLiteral)*)	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   r2   r   setr3   r	   r4   r
   cmfmodels	BaseModelr5   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   rE   rE   @   s    r   rE   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dZed3d
       Ze	 	 	 	 	 	 	 	 	 	 	 	 	 	 d4d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d5d       Zed6d       Zed7d       Zed        Zed        Z dZ!ed        Z"ed        Z#e e$ddgddd !      d3d"              Z%e e&d#$      d3d%              Z'ed8d&       Z( fd'Z)ed(        Z* fd)Z+d* Z, fd+Z-d, Z.d- Z/d. Z0d/ Z1d3 fd0	Z2d1 Z3d2 Z4 xZ5S )9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_typerM   autorN   filterfields)r    r9   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   >   denyrA   rB   rC   	denyWrite)r   r#   r"   rR      )r   r    r!   r"   r#   OR)r   rM   N)r   rM   F)rL   rN   r   r   r   r   rP   z): skip z due to empty subjects(z) or invalid access_level()N)r   r   r   r   z due to absent access_list(rO   staticz
): loaded z acl, z rules)3printosgetpidcmfutilmake_prof_pointr-   slistr   r   r    r!   r"   r#   r.   r2   appendr9   rS   r   r   sysinternr   r3   updater   r   getrL   rN   r'   r&   r8   r:   iter_subclassesacl_typer4   
class_namerG   rI   configMETRICS_ACCESS_LISTr   rZ   rC   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_listsrr   access_list_dataaccess_rulesrs   subjectsubjects_data
field_nameobject_fields_dataaccess_rule_datamodels                       r   rZ   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   Набор полей, по которым существуют правила, чтобы не проверять всё подряд.)rI   r3   )rx   r   s     r   r3   zCmfAccessList.used_fields   s     ==0H000r   c                     | j                   s6t        t        j                  j	                         j
                        | _         |t        j                  }| j                   |v S r0   )!_CmfAccessList__ib_admin_group_idr   r9   CmfPersonGroupib_admin_groupr    gcurrent_person__member_of)rx   r   s     r   is_ib_adminzCmfAccessList.is_ib_admin   sQ    &&&)&*?*?*N*N*P*S*S&TC#$,()(C(C%&&*CCCr   initial_acl_keyr   object_fieldr   r#   	object_idobject_instanceobject_dictobject_parent_idis_newc                    
$%&'() t         j                  }d= &(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$        }d+k(  rr}ntM              }tN        jQ                  |d         }|rx|jR                  rl|j-                  d,      }|rYt        jT                  jW                  ||jR                  j                  -      } | r"| jY                  |d   .      st[        |      |		  |       }	 |r||vrd}|sh|rftk        d2t         jl                   d3 d4' d5| d6 d7 d8 d9| d: d;xr t        jn                  j-                         d<       t[        |      |S c c}w # t\        $ rv}!|!j^                  d	   }"t`        jb                  j-                   je                  |"            }#|# |#|d/   k(  r  |d0   d1|"        tg        jh                  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
|      d }rrt        t              }|j
                  }|dk7  r*|j                  rj                        r|j                  }|dk(  rd}n2|dk(  rd}n*|d	k(  rd	}n"t        d||j
                  |j                        |srd}|dk(  r d        d        d       n"|dk(  r	 d       n|d	k(  s|snt        d|      t              }t        j                  ||      }|S # t        $ r Y .w xY w)Nc                 2    | vrj                  |        y y r0   )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 )NrA   rC   rB   r[   r\   )r   r   r   r   rE   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.   rl   r   
new_acl_idrb   rc   rd   CmfACLNotFoundErrorr    CmfErrorrh   	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)rA   rC   rA   rC   rB   r[   z@Invalid policy value checked_policy, allowed: read, write, fulllr>   )r   r?   model_policydefault_policy)r7   
ValueErrorrE   getattrr9   acl_default_user_policyacl_default_ib_admin_policyr   tupler;   
setdefault)r   checked_policyr   r   	model_clsr   granted_tupler   r   r   r   r   r   r   rx   r   r   is_local_userr   s   ` `    @@@@@@@r   calc_accessz/CmfAccessList.check_access.<locals>.calc_access   s   /* *,94 eGUFN0HC"o. (# "%)::!&)!'*!&) #N (61!&) #N (61 #N )^`np p
 QUM ' =I#,#D#DL %	1%AAOOF_O`'0'L'L#y0)/%3)3%/)/(*L%==y?d?df f &- &,N!V+f%g&f%#z1f%#v-^$%5~FF
 "'NM5@@P]^M    s   D2F 	FF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>   rA   rB   rC   rB   )acl_allow_createacl_static_owner_write_fieldsacl_static_self_write_fieldsacl_static_user_write_fieldsr9   	CmfPersonrl   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_staticn  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   )rI   CmfACLNotInitializedErrorr4   rl   ri   rj   r5   _full_accessr3   r   rw   _CACHE_MAX_SIZE	getsizeofrb   r   isliceitems)r   r   r   	cache_keyobject_field_checked_policy_
cache_sizekvr   r   r   rx   r   r   r   r   r   r   r   r   r#   stats            r   check_with_acl_dataz7CmfAccessList.check_access.<locals>.check_with_acl_data  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-VIEWrA   r?   rB   acl_owned_projects--r    r_   cmf_owner_idrM   cmf_owner_assistantsINrR   rQ   CmfAttachmentcategory_id)r   	scheme_id)r   
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)8r   __dict__r   r   r   load_fieldsr    valuer   r9   rG   subject_full_group_listanonymous_usersharelink_anonymous_userr   sharelink_groupr   r   r   hasattr
startswith	api_scoperl   r   check_project_role_accesscheck_accessr   r   r   r   is_not_null%project_perm_timetrackerhistory_cacheCmfSecurityLevelcheck_perm_security_levelr   
CmfProjectrg   r   r6   APPget_cache_projectattachment_scheme_idCmfAttachmentSchemeCategoryget_cache_instancecheck_category_accessCmfPermissionErrorr   argsREDIS_DBredis_new_acl_keytimesleeprb   current_personr   )*rx   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object_datacache_projectr   scheme_categoryeacl_idr  r   r   r   r   r   r   s*   ```` ```` ` ` `                     @@@@@@r   r  zCmfAccessList.check_access   s[   R jjD	! D	!L+	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% ?*)"?311+l2KLM 55"-//-"@K"*0*L*L*_*_(3&3&H&H&N&N +` + +#2#H#HT_`lTm#H#n&8G]_n&o on,. L6F+1!2B2B1C4GXXZ[lZmmx  zF  yG G*+ ,&x~ZH^G_ `$$3#4Ao6o&JZJZJ^J^_nJo5ppqst %\3I?[[{'J ' %^^//0@0@0HI
%\!22 GQRXQYZ[

1	 ns   %X59X: :	Z9A,Z44Z9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_idrM   parent_modelr   rL   rP   r]   )r    r  r9   rS   r   RelationCacherg   rL   ri   rj   r   re   get_obj_by_id)r   
subject_idr   rR   _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   r7  r   rL   r   r   r   r    )rR   rQ   order_by)r  r9   rS   rg   r+   rL   )
rx   r   r7  rR   rQ   r>  r8  	member_ofrelated_rulesr   s
             r   rJ   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)r9   r   admin_groupr    r   r"  rg_member_ofall_parents
is_supportr   r  r   r   r   r   r   rE  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   )rx   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   r  r   r   system_personr   r7   r   r"  r9   rG   r  rp   IS_AUTHORIZATORr   r  r  _CmfAccessList__guest_group_idr   r   guest_groupr    r   sharelink_access_requestsharelink_access_grantedr
  r  )rx   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)r7  r   NF)access_list_idsuser_show_acl_apply_progress)r7   rk   r  r   rI   r.   valuesr'   r&   intersectionr   r   r    trigger_reload)rx   subjects_idsrV  affected_subjects_idsr7  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   rV  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 r0   )r   rG   rI   r2   rl   )acl_id_list_acl_id_full_idsprocess_acl_lists     r   ri  z@CmfAccessList.proccess_chanded_acl_job.<locals>.process_acl_listX  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 r0   )
issubclassr   )ms    r   r1   z8CmfAccessList.proccess_chanded_acl_job.<locals>.<lambda>r  s    
1i8P r   r   r<   r   r    perm_effective_acl_idr   e   )rR   rQ   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  r9   rG   rZ   r7   rI   r.   rl   r!   r+   re   iter_modelsrw   	CMF_CACHEinvalidate_idsro   rg   r    )rV  drop_all_cacher1  r.   
model_listpctpct_stepr   r   obj_idsrh  ri  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)
rb   r   r!  _acl_need_reloadr8   appcmf_contextr9   rG   rZ   r   r   r   handlerz,CmfAccessList.on_acl_change.<locals>.handler  so    /1JJqM57#( WW((* 9((6689 9 029 9s   BBzacl::reload spawn handlerT)rb   r~  geventspawn)datar8  r  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 }|rAt        j
                  j                  t        j                  j                  j                         t        | j                  d|i       y c c}w )Nzacl::reload triggerry  rV  access_list_id)kwargs)rb   cmf_emit_server_eventr   rh   r   deferred_force_show_progressbarr   r9   rG   rx  nameschedule_deferred_job)rx   r  rV  rW  job_access_list_ids        r   rZ  zCmfAccessList.trigger_reload  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)rU   	__class__s    r   r  z!CmfAccessList.save_preload_fields  s    w*,/OOOr   c                     d|  S )NzCmfAccessList::created:r   )r1  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 )Nr^  )exr   )rZ  r    r   r  r  r7   r  r   r  r  save)rU   r  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!   r  rm  perm_inherit_acl_idperm_acl_idr_   rm  rM   r  r  r   )r   r    r!   rm  r  r  r"   )r8   r9   r   rm   extendrg   r    )rU   r8  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    ссылок, r^  r   )r  CmfOrmIntegrityErrorrw   rZ  r    r  rT   )rU   r  usager  s      r   rT   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 r0   r   rU   s    r   _calc_perm_parentzCmfAccessList._calc_perm_parent      r   c                      y r0   r   r  s    r   _calc_perm_has_aclz CmfAccessList._calc_perm_has_acl  r  r   c                      y r0   r   )rU   r8  s     r   _calc_perm_aclzCmfAccessList._calc_perm_acl  r  r   c                      y r0   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)r9   rS   r  _acl_spread_inheritance)rU   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_datarO   rW  )save_preparer   r  rN   r9   rG   rZ  r    rU   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  rM   r    z!=)rQ   Tr  rO   r  )
r  r   r9   rS   rg   r    r  rN   rG   rZ  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   r0   )NNNNNNNNNNTNNN)NNFN)NNNNN)rC  T)NNF)6r   r   r   __doc__TEXKOM_no_cacherI   r-   r   r   r8   rR   cmf_access_listrG   api_methodsrX   classmethodrZ   r3   r   r   r   r   r9   r:   r6   r(   r  staticmethodr  rJ   rC  rE  rK  rP  rT  r]  cmf_deferred_jobrx  on_server_eventr  rZ  r  r  r  r  rT   r  r  r  r  r  r  r  __classcell__)r  s   @r   rG   rG   D   s   
OIwO**,,::FFJ
 
K
 Un Unn 1 1 D D  .2*.*.*.-1'+>B*..2%) ,0F%c]F #3-F #3-	F
 #3-F &c]F  }F &cjj&:&:;F "$F 'smF TNF FP  " 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   rG   )*r)   r   ri   r   collectionsr   r   typingr   r   r   r   r	   r
   r   r  cmf.includecmf.appr8   cmf.fields.cmf_access_list
cmf.modelsr   rp   rq   cmf.metricsr   	dataclassr   r   r-   r7   _acl_changed_idsr;   r   _policy_prioritiesr   r   	ExceptionrE   rR   r  rG   r   r   r   <module>r     s     
  0 B B B    !  	3    O O O H H H 5 02 4u- 2 
 ./	y 	A\CJJ..<< A\r   