
    Id;                     h   d dl mZ d dlZd dlmZmZ d dlmZ d dlmZ d dl	m
Z
mZmZmZ d dlmZ d dlmZ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      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      Z G d de      Zy)     )IntEnumN)ABCMetaabstractmethod)datetime)ElementTree)DnMessageElementstring_to_time
timestring)GUID)ndr_pack
ndr_unpackc                   8    e Zd ZdZddZed        Zed        Zy)FieldaM  Base class for all fields.

    Each field will need to implement from_db_value and to_db_value.

    A field must correctly support converting both single valued fields,
    and list type fields.

    The only thing many=True does is say the field "prefers" to be a list,
    but really any field can be a list or single value.
    Nc                 h    || _         || _        || _        | j                  r
|g | _        y|| _        y)aD  Creates a new field, should be subclassed.

        :param name: Ldb field name.
        :param many: If true always convert field to a list when loaded.
        :param default: Default value or callback method (obj is first argument)
        :param hidden: If this is True, exclude the field when calling as_dict()
        N)namemanyhiddendefault)selfr   r   r   r   s        C/usr/lib/python3/dist-packages/samba/netcmd/domain/models/fields.py__init__zField.__init__/   s4     		 99DL"DL    c                      y)zConverts value read from the database to Python value.

        :param ldb: Ldb connection
        :param value: MessageElement value from the database
        :returns: Parsed value as Python type
        N )r   ldbvalues      r   from_db_valuezField.from_db_valueB   s     	r   c                      y)a,  Converts value to database value.

        This should return a MessageElement or None, where None means
        the field will be unset on the next save.

        :param value: Input value from Python field
        :param flags: MessageElement flags
        :returns: MessageElement or None
        Nr   )r   r   flagss      r   to_db_valuezField.to_db_valueL   s     	r   )FNF)__name__
__module____qualname____doc__r   r   r   r!   r   r   r   r   r   #   s4    	#&   
 
r   r   )	metaclassc                       e Zd ZdZd Zd Zy)IntegerFieldz5A simple integer field, can be an int or list of int.c                     |yt        |      dkD  s| j                  r|D cg c]  }t        |       c}S t        |d         S c c}w )z-Convert MessageElement to int or list of int.N   r   )lenr   intr   r   r   items       r   r   zIntegerField.from_db_value]   sC    =Z!^tyy*/0$CI00uQx=  1   Ac                     |yt        |t              r.t        |D cg c]  }t        |       c}|| j                        S t        t        |      || j                        S c c}w )z-Convert int or list of int to MessageElement.N
isinstancelistr	   strr   r   r   r    r.   s       r   r!   zIntegerField.to_db_valuef   [    =t$!',-tT-udiiA A "#e*eTYY?? .   A"Nr"   r#   r$   r%   r   r!   r   r   r   r(   r(   Z   s    ?!@r   r(   c                       e Zd ZdZd Zd Zy)BinaryFieldzSimilar to StringField but using bytes instead of str.

    This tends to be quite easy because a MessageElement already uses bytes.
    c                     |yt        |      dkD  s| j                  r|D cg c]  }t        |       c}S t        |d         S c c}w )zConvert MessageElement to bytes or list of bytes.

        The values on the MessageElement should already be bytes so the
        cast to bytes() is likely not needed in from_db_value.
        Nr*   r   )r+   r   bytesr-   s       r   r   zBinaryField.from_db_valuew   sE     =Z!^tyy,12DE$K22q?" 3r/   c                     |yt        |t              r.t        |D cg c]  }t        |       c}|| j                        S t        t        |      || j                        S c c}w )z1Convert bytes or list of bytes to MessageElement.N)r2   r3   r	   r<   r   r5   s       r   r!   zBinaryField.to_db_value   s[    =t$!)./t/		C C "%,tyyAA 0r7   Nr8   r   r   r   r:   r:   q   s    
#Br   r:   c                       e Zd ZdZd Zd Zy)StringFieldz6A simple string field, may contain str or list of str.c                     |yt        |      dkD  s| j                  r|D cg c]  }t        |       c}S t        |      S c c}w )z-Convert MessageElement to str or list of str.Nr*   r+   r   r4   r-   s       r   r   zStringField.from_db_value   s?    =Z!^tyy*/0$CI00u: 1s   Ac                     |yt        |t              r.t        |D cg c]  }t        |       c}|| j                        S t        t        |      || j                        S c c}w )z-Convert str or list of str to MessageElement.Nr1   r5   s       r   r!   zStringField.to_db_value   r6   r7   Nr8   r   r   r   r?   r?      s    @@r   r?   c                   6     e Zd ZdZd fd	Zd Zd Zd Z xZS )	EnumFieldz(A field based around Python's Enum type.c                 6    || _         t        | 	  |||       y)z0Create a new EnumField for the given enum class.N)enumsuperr   )r   r   rF   r   r   	__class__s        r   r   zEnumField.__init__   s    	tW-r   c                     t        | j                  t              r#| j                  t        t	        |                  S | j                  t	        |            S )zvReturn Enum instance from value.

        Has a special case for IntEnum as the constructor only accepts int.
        )
issubclassrF   r   r,   r4   )r   r   s     r   enum_from_valuezEnumField.enum_from_value   s<    
 dii)99SU_--99SZ((r   c                     |yt        |      dkD  s| j                  r|D cg c]  }| j                  |       c}S | j                  |      S c c}w )z/Convert MessageElement to enum or list of enum.Nr*   )r+   r   rK   r-   s       r   r   zEnumField.from_db_value   sN    =Z!^tyy;@A4D((.AA''.. Bs   Ac                     |yt        |t              r8t        |D cg c]  }t        |j                         c}|| j
                        S t        t        |j                        || j
                        S c c}w )z/Convert enum or list of enum to MessageElement.N)r2   r3   r	   r4   r   r   r5   s       r   r!   zEnumField.to_db_value   sd    =t$!-23TTZZ3UDIIG G "#ekk"2E499EE 4   A6FN)	r"   r#   r$   r%   r   rK   r   r!   __classcell__rH   s   @r   rD   rD      s    2.
)/Fr   rD   c                       e Zd ZdZd Zd Zy)DateTimeFieldz8A field for parsing ldb timestamps into Python datetime.c           
          |yt        |      dkD  s| j                  r5|D cg c])  }t        j                  t	        t        |                  + c}S t        j                  t	        t        |                  S c c}w )z7Convert MessageElement to datetime or list of datetime.Nr*   )r+   r   r   fromtimestampr
   r4   r-   s       r   r   zDateTimeField.from_db_value   sk    =Z!^tyy %' **>#d)+DE ' ' )).U*DEE's   .A:c                 >   |yt        |t              rJt        |D cg c])  }t        t	        t        j                  |                  + c}|| j                        S t        t        t	        t        j                  |                  || j                        S c c}w )z7Convert datetime or list of datetime to MessageElement.N)r2   r3   r	   r   r,   r   	timestampr   r5   s       r   r!   zDateTimeField.to_db_value   s    =t$!GLMtC 2 24 89:Mtyy" " "*S1C1CE1J-K"L"'4 4 Ns   .BNr8   r   r   r   rS   rS      s    BF
4r   rS   c                   0     e Zd ZdZd fd	Zd Zd Z xZS )RelatedFieldzA field that automatically fetches the related objects.

    Use sparingly, can be a little slow. If in doubt just use DnField instead.
    c                 6    || _         t        | 	  |||       y)z.Create a new RelatedField for the given model.N)modelrG   r   )r   r   r[   r   r   rH   s        r   r   zRelatedField.__init__   s    
tW-r   c                 "   |yt        |      dkD  s| j                  r>|D cg c]2  }| j                  j                  |t	        |t        |                  4 c}S | j                  j                  |t	        |t        |                  S c c}w )zConvert Message element to related object or list of objects.

        Note that fetching related items is not using any sort of lazy
        loading so use this field sparingly.
        Nr*   )dn)r+   r   r[   getr   r4   r-   s       r   r   zRelatedField.from_db_value   sr     =Z!^tyyKPQ4DJJNN32c3t9+=N>QQ::>>#"S#e**=>>> Rs   7Bc                     |yt        |t              r8t        |D cg c]  }t        |j                         c}|| j
                        S t        t        |j                        || j
                        S c c}w )z<Convert related object or list of objects to MessageElement.N)r2   r3   r	   r4   r]   r   r5   s       r   r!   zRelatedField.to_db_value   sc    =t$!*/0$TWW0%D D "#ehh-		BB 1rN   rO   )r"   r#   r$   r%   r   r   r!   rP   rQ   s   @r   rY   rY      s    
.
?Cr   rY   c                       e Zd ZdZd Zd Zy)DnFieldz5A Dn field parses the current field into a Dn object.c           	          |yt        |t              r|S t        |      dkD  s| j                  r#|D cg c]  }t        |t	        |             c}S t        |t	        |            S c c}w )z<Convert MessageElement to a Dn object or list of Dn objects.Nr*   )r2   r   r+   r   r4   r-   s       r   r   zDnField.from_db_value  s\    =r"LZ!^tyy3894BsCI&99c3u:&& :s   A(c                     |yt        |t              r.t        |D cg c]  }t        |       c}|| j                        S t        t        |      || j                        S c c}w )z>Convert Dn object or list of Dn objects into a MessageElement.Nr1   r5   s       r   r!   zDnField.to_db_value  r6   r7   Nr8   r   r   r   ra   ra   	  s    ?	'@r   ra   c                       e Zd ZdZd Zd Zy)	GUIDFieldz4A GUID field decodes fields containing binary GUIDs.c           	          |yt        |      dkD  s| j                  r'|D cg c]  }t        t        t        |             c}S t        t        t        |d               S c c}w )z=Convert MessageElement with a GUID into a str or list of str.Nr*   r   )r+   r   r4   r   r   r-   s       r   r   zGUIDField.from_db_value%  sT    =Z!^tyy<ABDC
4./BBz$a122 Cs    A!c           
          |yt        |t              r7t        |D cg c]  }t        t	        |             c}|| j
                        S t        t        t	        |            || j
                        S c c}w )z*Convert str with GUID into MessageElement.N)r2   r3   r	   r   r   r   r5   s       r   r!   zGUIDField.to_db_value.  se    =t$!278$$t*%8%L L "(4;"7		JJ 9s   A4Nr8   r   r   r   re   re   "  s    >3Kr   re   c                       e Zd ZdZd Zd Zy)BooleanFieldz6A simple boolean field, can be a bool or list of bool.c                     |yt        |      dkD  s| j                  r|D cg c]  }t        |      dk(   c}S t        |      dk(  S c c}w )z3Convert MessageElement into a bool or list of bool.Nr*   TRUErA   r-   s       r   r   zBooleanField.from_db_value<  sI    =Z!^tyy49:DCI'::u:'' ;s   Ac           
      *   |yt        |t              rEt        |D cg c]$  }t        t	        |            j                         & c}|| j                        S t        t        t	        |            j                         || j                        S c c}w )z3Convert bool or list of bool into a MessageElement.N)r2   r3   r	   r4   boolupperr   r5   s       r   r!   zBooleanField.to_db_valueE  sv    =t$!5:;TT$Z&&(;UDIIO O "#d5k"2"8"8":E499MM <s   )BNr8   r   r   r   ri   ri   9  s    @(Nr   ri   c                   (    e Zd ZdZddddZd Zd Zy)	PossibleClaimValuesFieldaq  Field for parsing possible values XML for claim types.

    This field will be represented by a list of dicts as follows:

    [
        {"ValueGUID": <GUID>},
        {"ValueDisplayName: "Display name"},
        {"ValueDescription: "Optional description or None for no description"},
        {"Value": <Value>},
    ]

    Note that the GUID needs to be created client-side when adding entries,
    leaving it as None then saving it doesn't generate the GUID.

    The field itself just converts the XML to list and vice versa, it doesn't
    automatically generate GUIDs for entries, this is entirely up to the caller.
    z http://www.w3.org/2001/XMLSchemaz)http://www.w3.org/2001/XMLSchema-instancezChttp://schemas.microsoft.com/2010/08/ActiveDirectory/PossibleValues)xsdxsi c           
         |t        j                  t        |            }|j                  d| j                        }g }|j                  d| j                        D ]  }|j                  |j                  d| j                        j                  |j                  d| j                        j                  |j                  d| j                        j                  |j                  d| j                        j                  d        |S y)	z/Parse MessageElement with XML to list of dicts.N
StringListItem	ValueGUIDValueDisplayNameValueDescriptionValue)rw   rx   ry   rz   )r   
fromstringr4   find	NAMESPACEfindallappendtext)r   r   r   rootstring_listvaluesr.   s          r   r   z&PossibleClaimValuesField.from_db_valuej  s    ))#e*5D))L$..AKF#++FDNNC !%;!G!L!L(,		2D26..)BBF$(,		2D26..)BBF$!YYw?DD  M r   c                 `   |yt        |t              r|}n|g}t        |      dk(  ryt        j                  d      }| j
                  j                         D ]2  \  }}|dk(  r|j                  d|       |j                  d| |       4 t        j                  |d      }|D ]  }t        j                  |d      }	t        j                  |	d	      }
|d	   |
_	        t        j                  |	d
      }|d
   |_	        t        j                  |	d      }|d   |_	        t        j                  |	d      }|d   |_	         t        j                         }t        j                  |      j                  |ddd       t        |j                         j                  d      || j                         S )z6Convert list of dicts back to XML as a MessageElement.Nr   PossibleClaimValuesrs   xmlnszxmlns:ru   rv   rw   rx   ry   rz   zutf-16TF)encodingxml_declarationshort_empty_elements)r2   r3   r+   r   Elementr}   itemsset
SubElementr   ioBytesIOwriter	   getvaluedecoder   )r   r   r    possible_valuesr   r   urlr   	item_dictr.   	item_guid	item_name	item_desc
item_valueouts                  r   r!   z$PossibleClaimValuesField.to_db_value}  s   = eT"#O$gO 1$ ""#89--/ 	/ID#rz#&6$#.		/ ",,T<@ ) 		1I))+v>D#..t[AI&{3IN#..t5GHI&'9:IN#..t5GHI&'9:IN$//g>J'0JO		1 jjl%++C5=<@AF 	, 	H clln33H=udiiPPr   N)r"   r#   r$   r%   r}   r   r!   r   r   r   rp   rp   P  s$    ( 2:QI&2Qr   rp   )rF   r   r   abcr   r   r   	xml.etreer   r   r   r	   r
   r   samba.dcerpc.miscr   	samba.ndrr   r   r   r(   r:   r?   rD   rS   rY   ra   re   ri   rp   r   r   r   <module>r      s   .  	 '  ! > > " *4g 4n@5 @.B% B<@% @.#F #FL4E 44 C5  CF@e @2K K.N5 N._Qu _Qr   