
    jO                        d Z ddlmZ ddlZddlZddlZddlZddlmZ ddZ	ddZ
ddZddZdd	Zdd
ZddZddZy)z:Owner-only filesystem primitives for nutrition onboarding.    )annotationsN)Pathc                v   t        |      j                         }t        |       j                         }	 |j                         }|ut	        j
                  |j                        rt        d      t	        j                  |j                        r!|j                  t        j                         k7  rt        d      	 |j                  |      }|}|j                  D ]  }||z  }	 |j                         }	t	        j
                  |	j                        rt        d      |	j                  t        j                         k7  rt        d      ||k7  sut	        j                  |	j                        rt        d       y # t        $ r d }Y Gw xY w# t        $ r}t        d      |d }~ww xY w# t        $ r Y w xY w)Nz-onboarding profile root must not be a symlinkz0onboarding profile root must be owner-controlledz#onboarding path escapes the profilez.onboarding path ancestor must not be a symlinkz1onboarding path ancestor must be owner-controlledz,onboarding path ancestor must be a directory)r   absolutelstatFileNotFoundErrorstatS_ISLNKst_mode
ValueErrorS_ISDIRst_uidosgetuidrelative_toparts)
pathprofile_rootroottarget	root_inforelativeexccurrentpartinfos
             /home/cube/projects/richard/traning coach/task-12-independent-verification-r9/build/hermes-full/dualcoach/profile/checkin_cli/nutrition_onboarding_fs.pyvalidate_profile_pathr      s{   &&(D$Z  "FJJL	 <<	))*LMM||I--.)2B2Bbiik2QOPPI%%d+ G4	==?D <<%MNN;;"))+%PQQfT\\$,,%?KLL   	  I>?SHI ! 		s;   E= <F $F,=FF	F)F$$F),	F87F8c                   t        |      j                         }t        |       j                         }	 |j                  |      }t        j
                  t        j                  z  t        j                  z  t        t        dd      z  }	 t	        j                  ||      }g }|}		 t	        j                  |      }
|
j                  t	        j                         k7  sAt        j                  |
j                         r"t        j"                  |
j                         dz  rt        d      |j$                  D ]_  }d}	 t	        j                  ||	d	      }t        j&                  |j                         rt        d
      t	        j                  |||	      }t	        j                  |      }|j0                  |j2                  f|j0                  |j2                  fk7  st        j                  |j                         rg|j                  t	        j                         k7  sFt        j"                  |j                         dz  s$|rBt        j"                  |j                         dk7  r t	        j4                  |       t        d      |j7                  |       |}	b 	 t9        |      D ]  }t	        j4                  |        t	        j4                  |       y# t        $ r}t        d      |d}~ww xY w# t        $ r}t        d      |d}~ww xY w# t(        $ ry d}t	        j*                  |d|	       t	        j                  |||	      }t	        j,                  |d       t	        j.                  |	       t	        j                  ||	d	      }Y w xY w# t9        |      D ]  }t	        j4                  |        t	        j4                  |       w xY w)zOCreate/verify a profile-relative directory tree through retained no-follow fds.z(onboarding directory escapes the profileN
O_NOFOLLOWr   z/onboarding profile root cannot be opened safely   z*onboarding profile root must be owner-onlyF)dir_fdfollow_symlinksz3onboarding directory ancestor must not be a symlink)r"   T  z5onboarding directory ancestor must be owner-only 0700)r   r   r   r   r   O_RDONLYO_DIRECTORY	O_CLOEXECgetattropenOSErrorfstatr   r   r	   r   r   S_IMODEr   r
   r   mkdirfchmodfsyncst_devst_inocloseappendreversed)r   r   r   r   r   r   flagsroot_fddescriptors	parent_fdr   	componentcreatedbeforechild_fdopened
descriptors                    r    ensure_private_profile_directoryr?   +   s   &&(D$Z  "FN%%d+ KK"..(2<<7'"lTU:VVEU''$&  KI&HHW%			+<<	 1 12||I--.6IJJ!IGG9eT <</$%Z[[779eIFXXh'F.6==&--2PP||FNN3==BIIK/<</%7V^^ < E" !XYYx( I5 (8 #;/JHHZ  0
_  NCD#MN
  UJKQTTU  % UE)<779eIF		(E*#9eTU0 #;/JHHZ  0
sb   K 
K/ %BN :LEN 	K,K''K,/	L	8LL	A>N
N NN <Oc                R   | j                         }t        j                  |j                        st        j                  |j                        st        d      |j                  t        j                         k7  s"t        j                  |j                        dk7  rt        d      y )Nz:onboarding path must be a regular directory, not a symlinkr$   z'onboarding directory must be owner-only)
r   r	   r
   r   r   r   r   r   r   r,   r   r   s     r   validate_private_directoryrB   c   sp    ::<D||DLL!dll)CUVV{{biik!T\\$,,%?5%HBCC &I    c                   | j                         }t        j                  |j                        st        j                  |j                        st        d      |j                  dk7  rt        d      |j                  t        j                         k7  s"t        j                  |j                        dk7  rt        d      y )Nz.onboarding file must be regular, not a symlink   z'onboarding file must not be hard-linked  z"onboarding file must be owner-only)r   r	   r
   r   S_ISREGr   st_nlinkr   r   r   r,   rA   s     r   validate_private_filerI   k   s    ::<D||DLL!dll)CIJJ}}BCC{{biik!T\\$,,%?5%H=>> &IrC   c                   | j                         rt        |        y t        j                  | t        j                  t        j
                  z  t        j                  z  d      }t        j                  |d      5 }|j                  |       |j                          t        j                  |j                                d d d        y # 1 sw Y   y xY w)NrF   wb)existsrI   r   r)   O_CREATO_EXCLO_WRONLYfdopenwriteflushr/   fileno)r   contentr>   handles       r   create_private_filerV   u   s    {{}d#rzzBII5CUKJ	:t	$W
! 
%	$	$s   :ACCc                    t        j                  | t         j                  t         j                  z        }	 t        j                  |       t        j
                  |       y # t        j
                  |       w xY w)N)r   r)   r%   r&   r/   r2   )r   r>   s     r   fsync_directoryrX      sI    r{{R^^;<J

s   A" "A9c                    t        |        t        j                  | j                  d            }t	        |t
              st        d      |S )Nutf-8)encodingz'private JSON document must be an object)rI   jsonloads	read_text
isinstancedictr   )r   values     r   read_private_jsonrb      s>    $JJt~~w~78EeT"BCCLrC   c                   t        j                  |ddd      j                  d      }t        j                  d| j
                   d| j                        \  }}t        |      }	 t        j                  |d       t        j                  |d	      5 }|j                  |       |j                          t        j                  |j                                d d d        t        j                  ||        | j!                  d       t#        | j                         |j%                  d
       y # 1 sw Y   XxY w# |j%                  d
       w xY w)NFT),:)ensure_ascii	sort_keys
separatorsrZ   .)prefixdirrF   rK   )
missing_ok)r\   dumpsencodetempfilemkstempnameparentr   r   r.   rP   rQ   rR   r/   rS   replacechmodrX   unlink)r   documentpayloadfd	temporary	temp_pathrU   s          r   atomic_write_private_jsonr{      s   jj	
 fWo  $$a		{!,<$++NMB	YI
*
		"eYYr4 FLL!LLNHHV]]_% ! 	

9d#

5$D) !  	D)s&   ',D; AD/AD; /D84D; ;E)r   r   r   r   returnNone)r   r   r|   r}   )r   r   rT   bytesr|   r}   )r   r   r|   dict[str, object])r   r   rv   r   r|   r}   )__doc__
__future__r   r\   r   r	   ro   pathlibr   r   r?   rB   rI   rV   rX   rb   r{    rC   r   <module>r      sE    @ "  	   M>5pD?"*rC   