
    	]jY$                     >   d Z ddlmZ ddlmZ ddlmZ ddlmZ ddl	m
Z
 ddlmZ  G d d	e      Z G d
 de      Z G d de      Z G d de      Z G d de
j"                        Z eej&                        Z eej*                        Z eej.                        Zy)zThis file and its contents are licensed under the Apache License 2.0. Please see the included NOTICE for copyright information and LICENSE for a copy of the license.
    all_permissions)	load_func)settings)FlexFieldsModelSerializer)serializers)Userc                        e Zd Z ej                  dd      Z ej                  d      Z ej                  d      Z ej                  dd      Z	d Z
d Zd	 Zd
 Z fdZ G d d      Z xZS )BaseUserSerializer?T)default	read_only)r   last_activity_cached)r   sourcec                     |j                   S N)
avatar_urlselfinstances     H/root/env/lib/python3.12/site-packages/label_studio/users/serializers.py
get_avatarzBaseUserSerializer.get_avatar   s    """    c                 B    |j                  | j                  |            S r   )get_initials_is_deletedr   s     r   r   zBaseUserSerializer.get_initials   s    $$T%5%5h%?@@r   c                     |j                   }|dddS |j                  }d}|j                  ,|j                  j                  |j                  j                  }||dS )N )titleemail)active_organizationr   
created_byr    )r   r   organizationr   r    s        r   get_active_organization_metaz/BaseUserSerializer.get_active_organization_meta   sg    33"--"""".<3J3J3P3P3\ ++11E//r   c                 P   d| j                   v r| j                   d   j                  n4d| j                   v r$| j                   d   j                  j                  nd sy|j                  j	                         }t        fd|D        d       }|syt        |j                        S )NuserrequestFc              3   @   K   | ]  }|j                   k(  r|  y wr   )organization_id).0organization_memberorg_ids     r   	<genexpr>z1BaseUserSerializer._is_deleted.<locals>.<genexpr>3   s'      '&66&@ $s   T)contextactive_organization_idr&   
om_throughallnextbool
deleted_at)r   r   organization_membersorganization_member_for_userr,   s       @r   r   zBaseUserSerializer._is_deleted%   s    T\\!\\&)@@F$,,&\\),11HHFF  (22668'++?
 (
$ ,0;;<<r   c                 F   |j                   }d}|| j                  vri | j                  |<   || j                  |   vrt        |   |      | j                  |   |<   | j	                  |      r#dD ]  }|dk(  rdnd| j                  |   |   |<     | j                  |   |   S )zXReturns user with cache, this helps to avoid multiple s3/gcs links resolving for avatars
user_cache)username
first_name	last_namer    r;   r	   Deleted)idr.   superto_representationr   )r   r   uidkeyfield	__class__s        r   r?   z$BaseUserSerializer.to_representation>   s     kkdll" "DLLdll3''%*W%>x%HDLLc"H%I ^:?;:NT]S!#&u-^ ||C %%r   c                       e Zd ZeZdZy)BaseUserSerializer.Meta)r=   r:   r;   r9   r    last_activitycustom_hotkeysavatarinitialsphoner!   active_organization_metaallow_newslettersdate_joinedN__name__
__module____qualname__r	   modelfields r   r   MetarE   O   s    
r   rU   )rO   rP   rQ   r   SerializerMethodFieldrI   rH   rK   DateTimeFieldrF   r   r   r$   r   r?   rU   __classcell__)rC   s   @r   r   r      su    0{00MH.[..>F@{@@4P-K--E[\M#A0=2&"
 
r   r   c                   6    e Zd Z G d dej                        Zy)BaseUserSerializerUpdatec                       e Zd ZdZy)BaseUserSerializerUpdate.Meta)r    N)rO   rP   rQ   read_only_fieldsrT   r   r   rU   r\   d   s    %r   rU   N)rO   rP   rQ   r   rU   rT   r   r   rZ   rZ   c   s    &!&& &r   rZ   c                   j    e Zd Z ej                         Z G d dej                        Zdee	   fdZ
y)BaseWhoAmIUserSerializerc                   >    e Zd Zej                  j
                  dz   Zy)BaseWhoAmIUserSerializer.Meta)permissionsN)rO   rP   rQ   r   rU   rS   rT   r   r   rU   ra   k   s    #((//2BBr   rU   returnc                 @    t         D cg c]  \  }}|	 c}}S c c}}w r   r   )r   r&   _perms       r   get_permissionsz(BaseWhoAmIUserSerializer.get_permissionsn   s    $34D444s   N)rO   rP   rQ   r   rV   rb   r   rU   liststrrg   rT   r   r   r_   r_   h   s7    3+335KC!&& C5tCy 5r   r_   c                        e Zd Z G d d      Zy)UserSimpleSerializerc                       e Zd ZeZdZy)UserSimpleSerializer.Meta)r=   r:   r;   r    rH   NrN   rT   r   r   rU   rm   s   s    Er   rU   N)rO   rP   rQ   rU   rT   r   r   rk   rk   r   s    F Fr   rk   c                   J    e Zd Z ej                  d      Zg dZdZd Zd Z	y)HotkeysSerializerT)required)zctrl+alt+deletezcmd+alt+escapezalt+f4zctrl+alt+esczcmd+option+esczctrl+shift+esczcmd+shift+qzalt+tabzcmd+tabz
ctrl+alt+tz	cmd+space   c                    t        |t              st        j                  d      t	        |      | j
                  kD  r#t        j                  d| j
                   d      |j                         D ]  \  }}t        |t              r|st        j                  d| d      t	        |      dkD  rt        j                  d| d      d|vrt        j                  d| d	      |j                  dd
      \  }}|j                         r|j                         st        j                  d| d      t        |t              st        j                  d| d      d|vrt        j                  d| d      |d   }|j                  dd      }t        |t              r|st        j                  d| d      t	        |      dkD  rt        j                  d| d      |j                         j                         }|| j                  v rt        j                  d| d      d|v r)t        |t              st        j                  d| d      | j                  ||        |S )z
        Validates the hotkey format and enforces security constraints.
        Expected format: {"section:action": {"key": "key_combination", "active": boolean}}
        The "active" field is optional and defaults to true.
        z#custom_hotkeys must be a dictionaryzCannot define more than z custom hotkeyszAction key 'z' must be a non-empty stringd   z"' is too long (max 100 characters):z$' must be in 'section:action' format   z.' must have non-empty section and action partszHotkey data for 'z' must be a dictionaryrA   z"Missing 'key' in hotkey data for ''activeTzKey combination for '2   z!' is too long (max 50 characters)Key combination 'z%' is not allowed for security reasonszActive flag for 'z' must be a boolean)
isinstancedictr   ValidationErrorlenMAX_HOTKEYSitemsri   splitstripgetlowerDANGEROUS_KEY_COMBINATIONSr3   _validate_key_format)	r   rG   
action_keyhotkey_datasectionaction	key_comborw   normalized_keys	            r   validate_custom_hotkeysz)HotkeysSerializer.validate_custom_hotkeys   s    .$/--.STT ~!1!11--0HIYIYHZZi.jkk'5';';'= 6	=#Jj#.j!11LLh2ijj :$!11LLn2opp *$!11LLp2qrr(..sA6OGV ==?&,,.!11":,.\] 
 k40!114Ej\Qg2hii K'!114VWaVbbc2dee#E*I !__Xt4F i-Y!114I*Uq2rss 9~"!11+J<7XY 
 '__.446N!@!@@!114Ei[Pu2vww ;&z&$/G!114Ej\Qd2eff %%i<m6	=p r   c                    ddl }|j                  d      }|j                  |      st        j                  d| d| d      |j                  d      D cg c]  }|j                          }}g d}|dd	 D ]?  }|j                         |vst        |      d
kD  s%t        j                  d| d| d       yc c}w )z~
        Basic validation of key combination format for security.
        Prevents injection of malicious characters.
        r   Nz7^[a-zA-Z0-9\+\-\s\[\]\\;\'\".,/`~!@#$%^&*()_={}|:<>?]+$ry   z' for 'z' contains invalid characters+)ctrlcmdcommandaltoptionshiftmeta   zInvalid modifier or key 'z' in key combination 'rv   )	recompilematchr   r|   r   r   r   r}   )r   r   r   r   allowed_patternpartpartsvalid_modifierss           r   r   z&HotkeysSerializer._validate_key_format   s     	 **%_`$$Y/--#I;gj\A^_ 
 +4//#*>?$??V#2J 	xDzz|?2s4y2~!114MdVSijsittu2vww	x @s   B;N)
rO   rP   rQ   r   	DictFieldrG   r   r~   r   r   rT   r   r   ro   ro   x   s0    *[**D9N" KENxr   ro   N)__doc__core.permissionsr   core.utils.commonr   django.confr   rest_flex_fieldsr   rest_frameworkr   users.modelsr	   r   rZ   r_   rk   
Serializerro   USER_SERIALIZERUserSerializerWHOAMI_USER_SERIALIZERWhoAmIUserSerializerUSER_SERIALIZER_UPDATEUserSerializerUpdaterT   r   r   <module>r      s    , '   6 & U
2 U
p&1 &
51 5F- Frx.. rxj 8334 !@!@A  !@!@A r   