HEX
Server: LiteSpeed
System: Linux shams.tasjeel.ae 5.14.0-611.5.1.el9_7.x86_64 #1 SMP PREEMPT_DYNAMIC Tue Nov 11 08:09:09 EST 2025 x86_64
User: infowars (1469)
PHP: 8.2.29
Disabled: NONE
Upload Files
File: //usr/lib/python3.9/site-packages/ipalib/__pycache__/parameters.cpython-39.opt-1.pyc
a

}�fk2�@sNdZddlZddlZddlZddlZddlZddlZddlmZm	Z	ddl
Z
ddlmZ
ddlZddlmZddlmZddlmZmZddlmZmZmZdd	lmZmZmZmZdd
l m!Z!m"Z"m#Z#ddlm$Z$m%Z%ddl&m'Z'm(Z(dd
l)m*Z*m+Z+m,Z,ddl&m-Z-m.Z.ddl/m0Z0ddl1m2Z2ddl3m4Z4dZ5dZ6e6Z7dd�Z8e
j9�rRe:Z;Gdd�de�Z<dd�Z=e>�Z?dd�ZGdd�de�Z@Gdd�de@�ZAGd d!�d!eA�ZBGd"d#�d#e@�ZCGd$d%�d%eC�ZDGd&d'�d'eC�ZEGd(d)�d)e@�ZFGd*d+�d+eF�ZGGd,d-�d-e@�ZHGd.d/�d/e@�ZIGd0d1�d1eF�ZJGd2d3�d3eJ�ZKGd4d5�d5eJ�ZLGd6d7�d7e@�ZMGd8d9�d9eM�ZNGd:d;�d;eM�ZOGd<d=�d=eM�ZPGd>d?�d?e@�ZQGd@dA�dAeJ�ZRGdBdC�dCeG�ZSGdDdE�dEe@�ZTGdFdG�dGeJ�ZUGdHdI�dIe@�ZVdJdK�ZWGdLdM�dMe@�ZXGdNdO�dOe@�ZYGdPdQ�dQe@�ZZe+e
jHe4ej[j\iZ]dRdS�Z^GdTdU�dUeJ�Z_dS)Va7
Parameter system for command plugins.

A `Param` instance can be used to describe an argument or option that a command
takes, or an attribute that a command returns.  The `Param` base class is not
used directly, but there are many subclasses for specific Python data types
(like `Str` or `Int`) and specific properties (like `Password`).

To create a `Param` instance, you must always provide the parameter *name*,
which should be the LDAP attribute name if the parameter describes the attribute
of an LDAP entry.  For example, we could create an `Str` instance describing the user's last-name attribute like this:

>>> from ipalib import Str
>>> sn = Str('sn')
>>> sn.name
'sn'

When creating a `Param`, there are also a number of optional kwargs which
which can provide additional meta-data and functionality.  For example, every
parameter has a *cli_name*, the name used on the command-line-interface.  By
default the *cli_name* is the same as the *name*:

>>> sn.cli_name
'sn'

But often the LDAP attribute name isn't user friendly for the command-line, so
you can override this with the *cli_name* kwarg:

>>> sn = Str('sn', cli_name='last')
>>> sn.name
'sn'
>>> sn.cli_name
'last'

Note that the RPC interfaces (and the internal processing pipeline) always use
the parameter *name*, regardless of what the *cli_name* might be.

A `Param` also has two translatable kwargs: *label* and *doc*.  These must both
be `Gettext` instances.  They both default to a place-holder `FixMe` instance,
a subclass of `Gettext` used to mark a missing translatable string:

>>> sn.label
FixMe('sn')
>>> sn.doc
FixMe('sn')

The *label* is a short phrase describing the parameter.  It's used on the CLI
when interactively prompting for values, and as a label for form inputs in the
web-UI.  The *label* should start with an initial capital.  For example:

>>> from ipalib import _
>>> sn = Str('sn',
...     cli_name='last',
...     label=_('Last name'),
... )
>>> sn.label
Gettext('Last name', domain='ipa', localedir=None)

The *doc* is a longer description of the parameter.  It's used on the CLI when
displaying the help information for a command, and as extra instruction for a
form input on the web-UI.  By default the *doc* is the same as the *label*:

>>> sn.doc
Gettext('Last name', domain='ipa', localedir=None)

But you can override this with the *doc* kwarg.  Like the *label*, the *doc*
should also start with an initial capital and should not end with any
punctuation.  For example:

>>> sn = Str('sn',
...     cli_name='last',
...     label=_('Last name'),
...     doc=_("The user's last name"),
... )
>>> sn.doc
Gettext("The user's last name", domain='ipa', localedir=None)

Demonstration aside, you should always provide at least the *label* so the
various UIs are translatable.  Only provide the *doc* if the parameter needs
a more detailed description for clarity.
�N)�MAXINT�MININT)�x509)�_)�
check_name)�ReadOnly�lock)�ConversionError�RequirementError�ValidationError)�PasswordMismatch�Base64DecodeError�CertificateFormatError�CertificateOperationError)�
TYPE_ERROR�CALLABLE_ERROR�LDAP_GENERALIZED_TIME_FORMAT)�Gettext�FixMe)�json_serialize�validate_idna_domain)�load_der_x509_certificate�IPACertificate�default_backend)�strip_csr_header�apirepr)�kerberos)�DN)�DNSNamel��l����cCs&|rdSt|tttjf�rdSdSdS)NFT)�
isinstance�int�float�decimal�Decimal��value�r&�5/usr/lib/python3.9/site-packages/ipalib/parameters.py�_is_null�s
r(c@s0eZdZdZdd�Zdd�Zdd�Zdd	�Zd
S)�DefaultFroma�
    Derive a default value from other supplied values.

    For example, say you wanted to create a default for the user's login from
    the user's first and last names. It could be implemented like this:

    >>> login = DefaultFrom(lambda first, last: first[0] + last)
    >>> login(first='John', last='Doe')
    'JDoe'

    If you do not explicitly provide keys when you create a `DefaultFrom`
    instance, the keys are implicitly derived from your callback by
    inspecting ``callback.func_code.co_varnames``. The keys are available
    through the ``DefaultFrom.keys`` instance attribute, like this:

    >>> login.keys
    ('first', 'last')

    The callback is available through the ``DefaultFrom.callback`` instance
    attribute, like this:

    >>> login.callback  # doctest:+ELLIPSIS
    <function <lambda> at 0x...>
    >>> login.callback.func_code.co_varnames  # The keys
    ('first', 'last')

    The keys can be explicitly provided as optional positional arguments after
    the callback. For example, this is equivalent to the ``login`` instance
    above:

    >>> login2 = DefaultFrom(lambda a, b: a[0] + b, 'first', 'last')
    >>> login2.keys
    ('first', 'last')
    >>> login2.callback.func_code.co_varnames  # Not the keys
    ('a', 'b')
    >>> login2(first='John', last='Doe')
    'JDoe'

    If any keys are missing when calling your `DefaultFrom` instance, your
    callback is not called and ``None`` is returned.  For example:

    >>> login(first='John', lastname='Doe') is None
    True
    >>> login() is None
    True

    Any additional keys are simply ignored, like this:

    >>> login(last='Doe', first='John', middle='Whatever')
    'JDoe'

    As above, because `DefaultFrom.__call__` takes only pure keyword
    arguments, they can be supplied in any order.

    Of course, the callback need not be a ``lambda`` expression. This third
    example is equivalent to both the ``login`` and ``login2`` instances
    above:

    >>> def get_login(first, last):
    ...     return first[0] + last
    ...
    >>> login3 = DefaultFrom(get_login)
    >>> login3.keys
    ('first', 'last')
    >>> login3.callback.func_code.co_varnames
    ('first', 'last')
    >>> login3(first='John', last='Doe')
    'JDoe'
    cGs�t|�sttd|t|�f��||_t|�dkr\|j}|jd@rHtd��|j	d|j
�|_n||_|jD](}t|�turhtt
dt|t|�f��qht|�dS)z�
        :param callback: The callable to call when all keys are present.
        :param keys: Optional keys used for source values.
        �callbackr�z3callback: variable-length argument list not allowedN�keys)�callable�	TypeErrorr�typer*�len�__code__�co_flags�
ValueError�co_varnames�co_argcountr,�strrr)�selfr*r,Zfc�keyr&r&r'�__init__�s"�

�zDefaultFrom.__init__cCs*tdd�|jD��}d|jjd�|�fS)Ncss|]}t|�VqdS�N��repr��.0�kr&r&r'�	<genexpr>��z'DefaultFrom.__repr__.<locals>.<genexpr>�%s(%s)�, )�tupler,�	__class__�__name__�join)r7�argsr&r&r'�__repr__�s
�zDefaultFrom.__repr__csHt�fdd�|jD��}d|vr$dSz|j|�WStyBYn0dS)z�
        Call the callback if all keys are present.

        If all keys are present, the callback is called and its return value is
        returned.  If any keys are missing, ``None`` is returned.

        :param kw: The keyword arguments.
        c3s|]}��|d�VqdSr:)�getr=��kwr&r'r@rAz'DefaultFrom.__call__.<locals>.<genexpr>N)rDr,r*�	Exception)r7rLZvalsr&rKr'�__call__�s	zDefaultFrom.__call__cCs|jSr:)r,�r7r&r&r'�__json__szDefaultFrom.__json__N)rF�
__module__�__qualname__�__doc__r9rIrNrPr&r&r&r'r)�s
Fr)cCs|t|�tur$ttdt|t|�f��tddd�tddd�tddd�d�}|d}||vrl|dd�||fS|tddd�fS)a�
    Parse shorthand ``spec`` into to ``(name, kw)``.

    The ``spec`` string determines the parameter name, whether the parameter is
    required, and whether the parameter is multivalue according the following
    syntax:

    ======  =====  ========  ==========
    Spec    Name   Required  Multivalue
    ======  =====  ========  ==========
    'var'   'var'  True      False
    'var?'  'var'  False     False
    'var*'  'var'  False     True
    'var+'  'var'  True      True
    ======  =====  ========  ==========

    For example,

    >>> parse_param_spec('login')
    ('login', {'required': True, 'multivalue': False})
    >>> parse_param_spec('gecos?')
    ('gecos', {'required': False, 'multivalue': False})
    >>> parse_param_spec('telephone_numbers*')
    ('telephone_numbers', {'required': False, 'multivalue': True})
    >>> parse_param_spec('group+')
    ('group', {'required': True, 'multivalue': True})

    :param spec: A spec string.
    �specF��required�
multivalueT)�?�*�+���N)r/r6r.r�dict)rT�_map�endr&r&r'�parse_param_specs�


�r_cCst�|�|Sr:)�
__messages�add)�messager&r&r'rDs
rc@s�eZdZdZed�Zed�Zed�ZdZde	dfde	dfde
e
�fd	e	efdfd
e	efdfdedfd
edfdedfde
dfdedfdedfdedfdedfde
dfde
dfde
e
�fde	efdfdedfdedfdedfde	dfdedfdedfdedffZed d!��Zd"d#�Zd$d%�Zd&d'�Zd(d)�Zd*d+�Zd,d-�Zd.d/�Zd0d1�Zd2d3�Zd4d5�Zd6d7�Zd8d9�Zd:d;�Z d<d=�Z!dJd>d?�Z"dKd@dA�Z#dLdBdC�Z$dDdE�Z%dFdG�Z&dHdI�Z'dS)M�Parama3
    Base class for all parameters.

    Param attributes:
    =================
    The behavior of Param class and subclasses can be controlled using the
    following set of attributes:

      - cli_name: option name in CLI
      - cli_short_name: one character version of cli_name
      - deprecated_cli_aliases: deprecated CLI aliases
      - label: very short description of the parameter. This value is used in
        when the Command output is printed to CLI or in a Command help
      - doc: parameter long description used in help
      - required: the parameter is marked as required for given Command
      - multivalue: indicates if the attribute is multivalued
      - primary_key: Command's parameter primary key is used for unique
        identification of an LDAP object and for sorting
      - normalizer: a custom function for Param value normalization
      - default_from: a custom function for generating default values of
        parameter instance
      - autofill: by default, only `required` parameters get a default value
        from the default_from function. When autofill is enabled, optional
        attributes get the default value filled too
      - query: this attribute is controlled by framework. When the `query`
        is enabled, framework assumes that the value is only queried and not
        inserted in the LDAP. Validation is then relaxed - custom
        parameter validators are skipped and only basic class validators are
        executed to check the parameter value
      - attribute: this attribute is controlled by framework and enabled for
        all LDAP objects parameters (unless parameter has "virtual_attribute"
        flag). All parameters with enabled `attribute` are being encoded and
        placed to an entry passed to LDAP Create/Update calls
      - include: a list of contexts where this parameter should be included.
        `Param.use_in_context()` provides further information.
      - exclude: a list of contexts where this parameter should be excluded.
        `Param.use_in_context()` provides further information.
      - flags: there are several flags that can be used to further tune the
        parameter behavior:
            * no_display (Output parameters only): do not display the parameter
            * no_create: do not include the parameter for crud.Create based
              commands
            * no_update: do not include the parameter for crud.Update based
              commands
            * no_search: do not include the parameter for crud.Search based
              commands
            * no_option: this attribute is not displayed in the CLI, usually
              because there's a better way of setting it (for example, a
              separate command)
            * virtual_attribute: the parameter is not stored physically in the
              LDAP and thus attribute `attribute` is not enabled
            * suppress_empty (Output parameters only): do not display parameter
              value when empty
            * ask_create: CLI asks for parameter value even when the parameter
              is not `required`. Applied for all crud.Create based commands
            * ask_update: CLI asks for parameter value even when the parameter
              is not `required`. Applied for all crud.Update based commands
            * req_update: The parameter is `required` in all crud.Update based
              commands
            * nonempty: This is an internal flag; a required attribute should
              be used instead of it.
              The value of this parameter must not be empty, but it may
              not be given at all. All crud.Update commands automatically
              convert required parameters to `nonempty` ones, so the value
              can be unspecified (unchanged) but cannot be deleted.
            * optional_create: do not require the parameter for crud.Create
              based commands
            * allow_mod_for_managed_permission: permission-mod allows changing
              the parameter for managed permissions
      - hint: this attribute is currently not used
      - alwaysask: when enabled, CLI asks for parameter value even when the
        parameter is not `required`
      - sortorder: used to sort a list of parameters for Command. See
        `Command.finalize()` for further information
      - confirm: if password, ask for confirmation
    Nzincorrect typezOnly one value is allowedF�cli_name�cli_short_nameZdeprecated_cli_aliases�label�docrVTrWZprimary_key�
normalizer�default_from�autofill�queryZ	attribute�include�exclude�flags�hintZ	alwaysaskZ	sortorder�Zoption_group�cli_metavar�
no_convert�
deprecatedZconfirmcCs|jfS)z$The allowed datatypes for this Param)r/rOr&r&r'�
allowed_types�szParam.allowed_typescOs,t|�\}}t|�d|vr(|d|d<d|vr<|d|d<|�dd�r`|jdtdff7_n|jd|jdff7_|�d�}t|�r�t|t�s�t|�|d<|jD]�\}}}|�|�}	|	du�rr|tt	fv�rt|	�t
ttt	fvr�||	�}	nt|	�tu�r||	g�}	|tu�r4t|	��s4t
t||	t|	�f��n4t|ttf��rht|	|��sht
t|||	t|	�f��|	||<q�|dvr�|�|d�q�|d�r�|d�r�|d|_n||_n |d�r�|d|_n
|d	|_t|�|_|jd=|jd=||_d
|jj|jf|_tdd�|jD���|j��sdt|�td
d�|jD��}
t
d|jd�dd�t|
�D��f��t|�|_|�d�du�r�|j|d<|�d�du�r�|jj��|d<|�d�du�r�t|j�|d<|�d�du�r�|d|d<g}|jD]r\}}}|�||�}	t||��r"td||jjf��t |||	�d|}|	du�r�t||��r�|�!t"||���q�t|j#�d|j$|j%fv�r�td|jd|j$d|j%f��t|�|_&||_'|j(�r�d|_)n|j&|j'|_)|j)D]"}
t|
��s�t
d|j|
f���q�|j*du�s t+|j*�dk�s td|j|j*f��t,|�dS)NrVrWT�defaultrirUrZrYrXz%s(%r)css|]}|dVqdS�rNr&�r>�tr&r&r'r@rAz!Param.__init__.<locals>.<genexpr>css|]}|dVqdSrvr&rwr&r&r'r@rAz%s: takes no such kwargs: %srCcss|]}t|�VqdSr:r;r=r&r&r'r@rArdrqrfrgz'kwarg %r conflicts with attribute on %sz_rule_%sz$%s: cannot have both %s=%r and %s=%rrlrmr&z"%s: rules must be callable; got %r�z5%s: cli_short_name can only be a single character: %s)-r_rrJ�kwargsrDr/r-rr)�	frozenset�list�setr6r.rr�pop�
param_specr\�
_Param__kw�namerErF�nice�
issupersetrG�sorted�_Param__clonekw�upperr�hasattrr3�setattr�append�getattrrdrlrm�class_rules�rulesrk�	all_rulesrer0r)r7r�r�rLZkw_from_specZdfr8�kindrur%Zextrar�Z	rule_name�ruler&r&r'r9�s�




���





��

�
��	


���zParam.__init__cCsd|jjd�|���fS)zQ
        Return an expresion that could construct this `Param` instance.
        rBrC)rErFrG�_Param__repr_iterrOr&r&r'rIOs�zParam.__repr__ccs�t|j�V|jD]}|jVqt|j�D]�}|j|}t|�rRt|d�rR|j}nLt|t	�rft
|�}n8t|ttt
f�r�tt|��}n|dkr�t|�}nt|�}d||fVq*dS)NrFrdz%s=%s)r<rr�rFr�r�r-r�rr r6rDr}r{rr|)r7r�r8r%r&r&r'Z__repr_iterXs





zParam.__repr_itercKs.t|�r|jfi|��}n|�|�|��}|S)z$
        One stop shopping.
        )r(�get_default�convert�	normalize)r7r%rLr&r&r'rNkszParam.__call__cCs|j}|s|j}|S)z�
        Return the right name of an attribute depending on usage.

        Normally errors should use cli_name, our "friendly" name. When
        using the API directly or *attr return the real name.
        )rdr�)r7r�r&r&r'�get_param_nameuszParam.get_param_nameccs@t|j�D]0}|j|}t|�r0t|d�r0|j}||fVq
dS)zW
        Iterate through ``(key,value)`` for all kwargs passed to constructor.
        rFN)r�r�r-r�rF)r7r8r%r&r&r'rL�s

zParam.kwcCs0|jdur|j|jvS|jdur,|j|jvSdS)a�
        Return ``True`` if this parameter should be used in ``env.context``.

        If a parameter is created with niether the ``include`` nor the
        ``exclude`` kwarg, this method will always return ``True``.  For
        example:

        >>> from ipalib.config import Env
        >>> param = Param('my_param')
        >>> param.use_in_context(Env(context='foo'))
        True
        >>> param.use_in_context(Env(context='bar'))
        True

        If a parameter is created with an ``include`` kwarg, this method will
        only return ``True`` if ``env.context`` is in ``include``.  For example:

        >>> param = Param('my_param', include=['foo', 'whatever'])
        >>> param.include
        frozenset(['foo', 'whatever'])
        >>> param.use_in_context(Env(context='foo'))
        True
        >>> param.use_in_context(Env(context='bar'))
        False

        If a paremeter is created with an ``exclude`` kwarg, this method will
        only return ``True`` if ``env.context`` is not in ``exclude``.  For
        example:

        >>> param = Param('my_param', exclude=['foo', 'whatever'])
        >>> param.exclude
        frozenset(['foo', 'whatever'])
        >>> param.use_in_context(Env(context='foo'))
        False
        >>> param.use_in_context(Env(context='bar'))
        True

        Note that the ``include`` and ``exclude`` kwargs are mutually exclusive
        and that at most one can be suppelied to `Param.__init__()`.  For
        example:

        >>> param = Param('nope', include=['foo'], exclude=['bar'])
        Traceback (most recent call last):
          ...
        ValueError: Param('nope'): cannot have both include=frozenset(['foo']) and exclude=frozenset(['bar'])

        So that subclasses can add additional logic based on other environment
        variables, the entire `config.Env` instance is passed in rather than
        just the value of ``env.context``.
        NT)rl�contextrm)r7�envr&r&r'�use_in_context�s
3

zParam.use_in_contextcCs|jr|durdS|S)a�
        Return a value safe for logging.

        This is used so that sensitive values like passwords don't get logged.
        For example:

        >>> p = Password('my_password')
        >>> p.safe_value(u'This is my password')
        u'********'
        >>> p.safe_value(None) is None
        True

        >>> s = Str('my_str')
        >>> s.safe_value(u'Some arbitrary value')
        u'Some arbitrary value'
        Nz********)�password�r7r%r&r&r'�
safe_value�szParam.safe_valuecKs|j|jfi|��S)zD
        Return a new `Param` instance similar to this one.
        )�clone_renamer�)r7�	overridesr&r&r'�clone�szParam.clonecKs|j||jfi|��S)zZ
        Return a new `Param` instance similar to this one, but named differently
        )�clone_retyperE)r7r�r�r&r&r'r��szParam.clone_renamecKs,t|j�}|�|�||g|j�Ri|��S)z\
        Return a new `Param` instance similar to this one, but of a different type
        )r\r��updater�)r7r��klassr�rLr&r&r'r��s

zParam.clone_retypecsF�jrt|�ttfvr|f}�jr8t�fdd�|D��S��|�SdS)a
        Normalize ``value`` using normalizer callback.

        For example:

        >>> param = Param('telephone',
        ...     normalizer=lambda value: value.replace('.', '-')
        ... )
        >>> param.normalize(u'800.123.4567')
        u'800-123-4567'

        If this `Param` instance was created with a normalizer callback and
        ``value`` is a unicode instance, the normalizer callback is called and
        *its* return value is returned.

        On the other hand, if this `Param` instance was *not* created with a
        normalizer callback, if ``value`` is *not* a unicode instance, or if an
        exception is caught when calling the normalizer callback, ``value`` is
        returned unchanged.

        :param value: A proposed value for this parameter.
        c3s|]}��|�VqdSr:)�_normalize_scalar�r>�vrOr&r'r@sz"Param.normalize.<locals>.<genexpr>N)rWr/rDr|r�r�r&rOr'r��s�zParam.normalizecCs6|jdur|Sz|�|�WSty0|YS0dS)zo
        Normalize a scalar value.

        This method is called once for each value in a multivalue.
        N)rhrMr�r&r&r'r�s
zParam._normalize_scalarcst�js�j�n�fdd��t|�r&dS�jrlt|�ttfvrB|f}t�fdd�|D��}t|�dkrhdS|S�|�S)a�
        Convert ``value`` to the Python type required by this parameter.

        For example:

        >>> scalar = Str('my_scalar')
        >>> scalar.type
        <type 'unicode'>
        >>> scalar.convert(43.2)
        u'43.2'

        (Note that `Str` is a subclass of `Param`.)

        All non-numeric, non-boolean values which evaluate to False will be
        converted to None.  For example:

        >>> scalar.convert(u'') is None  # An empty string
        True
        >>> scalar.convert([]) is None  # An empty list
        True

        Likewise, they will be filtered out of a multivalue parameter.
        For example:

        >>> multi = Str('my_multi', multivalue=True)
        >>> multi.convert([1.5, '', 17, None, u'Hello'])
        (u'1.5', u'17', u'Hello')
        >>> multi.convert([None, u'']) is None  # Filters to an empty list
        True

        Lastly, multivalue parameters will always return a ``tuple`` (assuming
        they don't return ``None`` as in the last example above).  For example:

        >>> multi.convert(42)  # Called with a scalar value
        (u'42',)
        >>> multi.convert([0, 1])  # Called with a list value
        (u'0', u'1')

        Note that how values are converted (and from what types they will be
        converted) completely depends upon how a subclass implements its
        `Param._convert_scalar()` method.  For example, see
        `Str._convert_scalar()`.

        :param value: A proposed value for this parameter.
        cst|t�r|S��|�Sr:)r�unicode�_convert_scalarr$rOr&r'r�Ls
zParam.convert.<locals>.convertNc3s|]}t|�s�|�VqdSr:)r(r�)r�r&r'r@Vsz Param.convert.<locals>.<genexpr>r)rrr�r(rWr/rDr|r0)r7r%�valuesr&)r�r7r'r�s.�z
Param.convertcCs6|jD]}t||�r|Sqt|jt|j�d��dS��0
        Convert a single scalar value.
        �r��errorN)rtrr	r��ugettext�
type_error)r7r%�indexrxr&r&r'r�^s


zParam._convert_scalarcCs�|dur,|js|r(d|jvr(t|jd��dS|jrFt|��td�d��|jr�t	|�t
urpttdt
|t	|�f��t
|�dkr�td��|D]}|�|�q�n
|�|�dS)	z�
        Check validity of ``value``.

        :param value: A proposed value for this parameter.
        :param supplied: True if this parameter was supplied explicitly.
        NZnonempty�r�zthis option is deprecatedr�r%ryz,value: empty tuple must be converted to None)rVrnr
r�rsrr�rrWr/rDr.rr0r3�_validate_scalar)r7r%Zsuppliedr�r&r&r'�validatehs$��zParam.validatecCsh|jD]}t||�rq6qtt|j|j|t|�f��|jD]&}|t|�}|dur<t|�	�|d��q<dS�Nr�)
rtrr.rr�r/r�r�rr�)r7r%r�rxr�r�r&r&r'r��s

�

zParam._validate_scalarcKsN|jdurH|jfi|��}|durHz|�|�|��WStyFYn0|jS)a/
        Return the static default or construct and return a dynamic default.

        (In these examples, we will use the `Str` and `Bytes` classes, which
        both subclass from `Param`.)

        The *default* static default is ``None``.  For example:

        >>> s = Str('my_str')
        >>> s.default is None
        True
        >>> s.get_default() is None
        True

        However, you can provide your own static default via the ``default``
        keyword argument when you create your `Param` instance.  For example:

        >>> s = Str('my_str', default=u'My Static Default')
        >>> s.default
        u'My Static Default'
        >>> s.get_default()
        u'My Static Default'

        If you need to generate a dynamic default from other supplied parameter
        values, provide a callback via the ``default_from`` keyword argument.
        This callback will be automatically wrapped in a `DefaultFrom` instance
        if it isn't one already (see the `DefaultFrom` class for all the gory
        details).  For example:

        >>> login = Str('login', default=u'my-static-login-default',
        ...     default_from=lambda first, last: (first[0] + last).lower(),
        ... )
        >>> isinstance(login.default_from, DefaultFrom)
        True
        >>> login.default_from.keys
        ('first', 'last')

        Then when all the keys needed by the `DefaultFrom` instance are present,
        the dynamic default is constructed and returned.  For example:

        >>> kw = dict(last=u'Doe', first=u'John')
        >>> login.get_default(**kw)
        u'jdoe'

        Or if any keys are missing, your *static* default is returned.
        For example:

        >>> kw = dict(first=u'John', department=u'Engineering')
        >>> login.get_default(**kw)
        u'my-static-login-default'
        N)rir�r�rMru)r7rLrur&r&r'r��s4
zParam.get_defaultcCs|Sr:r&r�r&r&r'�sort_key�szParam.sort_keycCs�i}|jD]`\}}}|ttfvr"q
tt||�t�rHtt||g��||<q
t||d�}|dur^q
t|�||<q
|jj	|d<|j
|d<|jj	|d<|S)N��classr�r/)rzr-r)rr�r{r|rrErFr�r/)r7Z	json_dict�ar?Z_d�valr&r&r'rP�s
zParam.__json__)N)N)N)(rFrQrRrSr/rr��scalar_errorr�r6r{r�boolr-r)r r�rz�propertyrtr9rIr�rNr�rLr�r�r�r�r�r�r�r�r�r�r�r�r�rPr&r&r&r'rcIsjR

�
	

9!
C




=rcc@sPeZdZdZeZed�Zej	de
e
gd��fde
e
gd��ffZ	d
dd	�ZdS)�BoolzG
    A parameter for boolean values (stored in the ``bool`` type).
    zmust be True or False�truths)ry�1T�trueZTRUE�
falsehoods)r�0FZfalseZFALSENcCs|t|�|jvr|St|t�r$|��}||jvr2dS||jvr@dSt|�ttfvrdt	|j
t|j�d��t	|j
t|j
�d��dS)r�TFr�N)r/rtrr6�lowerr�r�rDr|r	r�r�r�r��r7r%r�r&r&r'r��s


�zBool._convert_scalar)N)rFrQrRrSr�r/rr�rcrzr{r�r&r&r&r'r��s�r�cs eZdZdZ�fdd�Z�ZS)�FlagaR
    A boolean parameter that always gets filled in with a default value.

    This `Bool` subclass forces ``autofill=True`` in `Flag.__init__()`.  If no
    default is provided, it also fills in a default value of ``False``.
    Lastly, unlike the `Bool` class, the default must be either ``True`` or
    ``False`` and cannot be ``None``.

    For example:

    >>> flag = Flag('my_flag')
    >>> (flag.autofill, flag.default)
    (True, False)

    To have a default value of ``True``, create your `Flag` intance with
    ``default=True``.  For example:

    >>> flag = Flag('my_flag', default=True)
    >>> (flag.autofill, flag.default)
    (True, True)

    Also note that creating a `Flag` instance with ``autofill=False`` will have
    no effect.  For example:

    >>> flag = Flag('my_flag', autofill=False)
    >>> flag.autofill
    True
    csjd|d<d|vrd|d<t|d�turH|d}ttdt|t|�f��tt|�j|g|�Ri|��dS)NTrjruF)r/r�r.r�superr�r9)r7r�r�rLru�rEr&r'r9$s�z
Flag.__init__)rFrQrRrSr9�
__classcell__r&r&r�r'r�sr�c@seZdZdZddd�ZdS)�Numberz<
    Base class for the `Int` and `Decimal` parameters.
    NcCs�t|�|jvr|St|�tttfvrDz|�|�WStyBYn0t|�ttfvrht|j	t
|j�d��t|j	t
|j�d��dSr�)
r/rtr�r!r r3rDr|r	r�r�r�r�r�r&r&r'r�5s�zNumber._convert_scalar)N)rFrQrRrSr�r&r&r&r'r�0sr�cs�eZdZdZeZefZed�Ze	Z	e
Z
eZeZe
Z
ejdeee	�fdeee
�ffZedd��Z�fdd�Zdd
d�Zdd
�Zdd�Z�ZS)�IntzF
    A parameter for integer values (stored in the ``int`` type).
    �must be an integer�minvalue�maxvaluecCsxt|�tjvr|St|�tur&t|�St|�turld|vrFtt|��Stjrbt�	d|�rbt|d�St|d�St
|��dS)N�.z0[0-9]+�r)r/r�rtr!r r��six�PY3�re�matchr3r$r&r&r'�convert_intZs

zInt.convert_intcs�tt|�j|g|�Ri|��|j|jkrV|jdurV|jdurVtd|j|j|jf��|j|jkrztd|j�d|j����|j|jkr�td|j�d|j����dS)Nz2%s: minvalue > maxvalue (minvalue=%r, maxvalue=%r)z	minvalue z* outside range of safe JSON integer limit z	maxvalue )	r�r�r9r�r�r3r��MIN_SAFE_INTEGER�MAX_SAFE_INTEGER�r7r�r�rLr�r&r'r9ls& ��
��
��zInt.__init__NcCs:zt�|�WSty4t|��t|j�d��Yn0dSr��r�r�r3r	r�r�r�r�r&r&r'r�s�zInt._convert_scalarcCs&||jkr|d�t|jd�SdSdS)�'
        Check min constraint.
        zmust be at least %(minvalue)d�r�N�r�r\�r7rr%r&r&r'�_rule_minvalue�s

�zInt._rule_minvaluecCs&||jkr|d�t|jd�SdSdS)�'
        Check max constraint.
        zcan be at most %(maxvalue)d�r�N�r�r\r�r&r&r'�_rule_maxvalue�s

�zInt._rule_maxvalue)N)rFrQrRrSr r/rtrr�rr�
MAX_UINT32r�r�rcrz�staticmethodr�r9r�r�r�r�r&r&r�r'r�Fs&�


r�cs�eZdZdZejZed�Ze	j
dejdfdejdfdedfdedfd	e
d
ffZ
�fdd�Zd
d�Zdd�Zdd�Zdd�Zdd�Zdd�Zd�fdd�	Z�fdd�Z�ZS)r#aj
    A parameter for floating-point values (stored in the ``Decimal`` type).

    Python Decimal type helps overcome problems tied to plain "float" type,
    e.g. problem with representation or value comparison. In order to safely
    transfer the value over RPC libraries, it is being converted to string
    which is then converted back to Decimal number.
    zmust be a decimal numberr�Nr��	precision�exponentialF�numberclass)z-Normalz+Zeroz+Normalcs�dD]x}|�|�}|durqt|ttf�rzt�|�}Wn:tyr}z"td||t|�f��WYd}~n
d}~00|||<qtt|�j	|g|�Ri|��|j
dur�|jdur�|j
|jkr�td|j|j
|jf��|j
dur�|j
dkr�td|j��dS)N)r�r�ruz%s: cannot parse kwarg %s: %sz2%s: minvalue > maxvalue (minvalue=%s, maxvalue=%s)rz %s: precision must be at least 0)rJrr6r!r"r#rMr3r�r9r�r�r�r�)r7r�r�rLZkwparamr%�er�r&r'r9�s6

��

�
���zDecimal.__init__cCs&||jkr|d�t|jd�SdSdS)r�zmust be at least %(minvalue)sr�Nr�r�r&r&r'r��s

�zDecimal._rule_minvaluecCs&||jkr|d�t|jd�SdSdS)r�zcan be at most %(maxvalue)sr�Nr�r�r&r&r'r��s

�zDecimal._rule_maxvaluecCs>|��}||jvr:t|��td�t|d�|j�d�d��dS)NzWnumber class '%(cls)s' is not included in a list of allowed number classes: %(allowed)srC)�cls�allowedr�)Znumber_classr�rr�rr\rG)r7r%r�r&r&r'�_enforce_numberclass�s

���zDecimal._enforce_numberclassc
Csn|jdurjt�d�t|j�}z|�|�}Wn:tjyh}z t|��t|�d��WYd}~n
d}~00|S)N�
r�)	r�r"r#r �quantize�DecimalExceptionr	r�r�)r7r%Zquantize_expr�r&r&r'�_enforce_precision�s
�zDecimal._enforce_precisionc
Csn|jsjz(||��kr$|�t�d��n|��}Wn:tjyh}z t|��t	|�d��WYd}~n
d}~00|S)Nryr�)
r�Zto_integralr�r"r#r�r�r	r�r�)r7r%r�r&r&r'�_remove_exponents
���zDecimal._remove_exponentcCs"|�|�|�|�}|�|�}|S)z�
        This method is run in conversion and normalization methods to test
        that the Decimal number conforms to Parameter boundaries and then
        normalizes the value.
        )r�r�r�r�r&r&r'�_test_and_normalizes


zDecimal._test_and_normalizec
s~t|ttf�rXzt�|�}Wn:tjyV}z t|��t|�d��WYd}~n
d}~00t|tj�rn|�	|�St
t|��|�Sr�)rr6r!r"r#r�r	r�r�r�r�r��r7r%r�r�r�r&r'r�s�
zDecimal._convert_scalarcs&t|tj�r|�|�Stt|��|�Sr:)rr"r#r�r�r�r�r�r&r'r�)s
zDecimal._normalize_scalar)N)rFrQrRrSr"r#r/rr�rcrzr r�rDr9r�r�r�r�r�r�r�r�r�r&r&r�r'r#�s&	

�

r#cs\eZdZdZejdedfdedfdedfdefdffZdZdZ	�fdd�Z
d	d
�Z�ZS)�Dataa+
    Base class for the `Bytes` and `Str` parameters.

    Previously `Str` was as subclass of `Bytes`.  Now the common functionality
    has been split into this base class so that ``isinstance(foo, Bytes)`` wont
    be ``True`` when ``foo`` is actually an `Str` instance (which is confusing).
    �	minlengthN�	maxlength�length�pattern_errmsgcs�tt|�j|g|�Ri|��|jdusJ|jdur<|jdusJtd|j��|jdurr|jdkrrtd|j|jf��|jdur�|jdkr�td|j|jf��d|j|jfvr�|j|jkr�td|j|j|jf��n |j|jkr�td|j|jf��dS)Nz1%s: cannot mix length with minlength or maxlengthryz"%s: minlength must be >= 1; got %rz"%s: maxlength must be >= 1; got %rz6%s: minlength > maxlength (minlength=%r, maxlength=%r)z1%s: minlength == maxlength; use length=%d instead)r�r�r9r�r�r�r3r�r�r�r&r'r9Bs>����������z
Data.__init__cCsF|j�|�dur>|jr(|jt|jd�S|d�t|jd�SndSdS)z2
        Check pattern (regex) contraint.
        N)�patternz must match pattern "%(pattern)s")r�r��	re_errmsgr\r�r�r&r&r'�
_rule_patterncs�
zData._rule_pattern)
rFrQrRrSrcrzr r6r�r�r9r�r�r&r&r�r'r�/s
�!r�csfeZdZdZeZed�Zej	defdffZ	�fdd�Z
dd�Zd	d
�Zdd�Z
d�fd
d�	Z�ZS)�Bytesa(
    A parameter for binary data (stored in the ``str`` type).

    This class is named *Bytes* instead of *Str* so it's aligned with the
    Python v3 ``(str, unicode) => (bytes, str)`` clean-up.  See:

        http://docs.python.org/3.0/whatsnew/3.0.html

    Also see the `Str` parameter.
    zmust be binary datar�NcsX|�dd�durd|_nt�|d�|_|�dd�|_tt|�j|g|�Ri|��dS�Nr�r�)rJr��compiler�r�r�r9r�r�r&r'r9�s
zBytes.__init__cCs*t|�|jkr"|d�t|jd�SdSdS)�-
        Check minlength constraint.
        z$must be at least %(minlength)d bytes�r�N�r0r�r\r�r&r&r'�_rule_minlength�s
�zBytes._rule_minlengthcCs*t|�|jkr"|d�t|jd�SdSdS)�-
        Check maxlength constraint.
        z"can be at most %(maxlength)d bytes�r�N�r0r�r\r�r&r&r'�_rule_maxlength�s
�zBytes._rule_maxlengthcCs*t|�|jkr"|d�t|jd�SdSdS)�*
        Check length constraint.
        z must be exactly %(length)d bytes�r�N�r0r�r\r�r&r&r'�_rule_length�s
�zBytes._rule_lengthc
s`t|t�rPzt�|�}Wn6ttfyN}ztt|�d��WYd}~n
d}~00tt	|��
|�S)N��reason)rr��base64�	b64decoder.r3r
r6r�r�r�r�r�r&r'r��s
$zBytes._convert_scalar)N)rFrQrRrS�bytesr/rr�r�rzr9r�rrr�r�r&r&r�r'r�ss
�r�cs6eZdZejZed�Zee	e
fZd�fdd�	Z�Z
S)�Certificatezmust be a certificateNc
s�t|t�r,z|�d�}Wnty*Yn0t|t�r|zt�|�}Wn6ttfyz}zt	t
|�d��WYd}~n
d}~00t|t�r�zt|�}Wn2ty�}ztt
|�d��WYd}~n
d}~00t
t|��|�S)z�
        :param value: either DER certificate or base64 encoded certificate
        :returns: bytes representing value converted to DER format
        �asciirN�r�)rr
�decode�UnicodeDecodeErrorr�rr	r.r3r
r6rrr�rr�r�r�r&r'r��s 

$
$zCertificate._convert_scalar)N)rFrQrR�crypto_x509rr/rr�rr
r�rtr�r�r&r&r�r'r�s
rcs@eZdZejZed�Zejee	fZ
dd�Zd�fdd�	Z�Z
S)�CertificateSigningRequestz%must be a certificate signing requestcCs8z|�d�Wnty$|YS0t|�}t�|�S)a�
        Tries to get the DER representation of whatever we receive as an input

        :param value:
            bytes instance containing something we hope is a certificate
            signing request
        :returns:
            base64-decoded representation of whatever we found in case input
            had been something else than DER or something which resembles
            DER, in which case we would just return input
        zutf-8)rrrrr	r�r&r&r'Z__extract_der_from_input�s
z2CertificateSigningRequest.__extract_der_from_inputNc
s�t|t�r4z|�d�}Wnty2td��Yn0t|t�r�|�|�}ztj|t	�d�}Wn6t
y�}zttd�|d��WYd}~n
d}~00tt
|��|�S)a
        :param value:
            either DER csr, base64-encoded csr or an object implementing the
            cryptography.CertificateSigningRequest interface
        :returns:
            an object with the cryptography.CertificateSigningRequest interface
        rznot a valid CSR)Zbackendz0Failure decoding Certificate Signing Request: %sr
N)rr��encoderrr
�2_CertificateSigningRequest__extract_der_from_inputrZload_der_x509_csrrr3rr�rr�r�r�r&r'r��s$


�
��z)CertificateSigningRequest._convert_scalar)N)rFrQrRrrr/rr�r
r�rtrr�r�r&r&r�r'r�s
rcszeZdZdZejdefdfdedffZeZ	e
d�Z�fdd�Zdd	d
�Z
dd�Zd
d�Zdd�Zdd�Zdd�Z�ZS)�Stra1
    A parameter for Unicode text (stored in the ``unicode`` type).

    This class is named *Str* instead of *Unicode* so it's aligned with the
    Python v3 ``(str, unicode) => (bytes, str)`` clean-up.  See:

        http://docs.python.org/3.0/whatsnew/3.0.html

    Also see the `Bytes` parameter.
    r�N�noextrawhitespaceTzmust be Unicode textcs\|�dd�durd|_nt�|dtj�|_|�dd�|_tt|�j|g|�Ri|��dSr�)rJr�r��UNICODEr�r�rr9r�r�r&r'r9(s
zStr.__init__cCslt|�|jvr|St|�tttjfvr0|�|�St|�ttfvrTt|j	t
|j�d��t|j	t
|j�d��dSr�)
r/rtr r!r"r#rDr|r	r�r�r�r�r�r&r&r'r�0s
�zStr._convert_scalarcCs2|jdurdSt|�t|���kr*|d�SdSdS)z7
        Do not allow leading/trailing spaces.
        FNz+Leading and trailing spaces are not allowed)rr0�stripr�r&r&r'�_rule_noextrawhitespace=s

zStr._rule_noextrawhitespacecCs*t|�|jkr"|d�t|jd�SdSdS)r�z)must be at least %(minlength)d charactersr�Nr�r�r&r&r'r�Is
�zStr._rule_minlengthcCs*t|�|jkr"|d�t|jd�SdSdS)r�z'can be at most %(maxlength)d charactersr�Nrr�r&r&r'rUs
�zStr._rule_maxlengthcCs*t|�|jkr"|d�t|jd�SdSdS)rz%must be exactly %(length)d charactersrNrr�r&r&r'ras
�zStr._rule_lengthcCs|��Sr:)r�r�r&r&r'r�mszStr.sort_key)N)rFrQrRrSr�rzr6r�r�r/rr�r9r�rr�rrr�r�r&r&r�r'rs
�

rcs.eZdZdZ�fdd�Zd�fdd�	Z�ZS)�IA5Strz#
    An IA5String per RFC 4517
    cs"tt|�j|g|�Ri|��dSr:)r�rr9r�r�r&r'r9uszIA5Str.__init__NcsNt|t�r>|D].}t|�dkrt|��td�t|d�d��qtt|��	|�S)N�z&The character %(char)r is not allowed.)�charr�)
rr6�ordr	r�rr\r�rr�)r7r%r�rr�r&r'r�xs
��zIA5Str._convert_scalar)N)rFrQrRrSr9r�r�r&r&r�r'rpsrcsBeZdZdZejdefdfdedffZdZd	�fdd�	Z	�Z
S)
�PasswordzE
    A parameter for passwords (stored in the ``unicode`` type).
    r�NrFTcsJt|ttf�r:t|�dkr:|\}}||kr6t|jd��|}tt|��|�S)Nrpr�)	rrDr|r0rr�r�rr�)r7r%r�Zp1Zp2r�r&r'r��szPassword._convert_scalar)N)rFrQrRrSr�rzr6r�r�r�r�r&r&r�r'r�s
�rcs<eZdZdZejdee�ffZ�fdd�Zdd�Z�Z	S)�Enumz;
    Base class for parameters with enumerable values.
    r�cs�tdd�|�dt��D��|d<tt|�j|g|�Ri|��t|j�D]>\}}t|�|j	vrHd|j
|f}tt||j|t|�f��qHt
|j�dkr�td|j
��dS)NcSsg|]}t|��qSr&)r6r�r&r&r'�
<listcomp>�rAz!Enum.__init__.<locals>.<listcomp>r�rqz
%s values[%d]ryz$%s: list of values must not be empty)r6rJrDr�rr9�	enumerater�r/rtr�r.rr0r3)r7r�r�rL�ir��nr�r&r'r9�s ��z
Enum.__init__cKsb||jvrZt|j�dkr0|d�t|jdd�Sd�dd�|jD��}|d�t|d	�SndSdS)
Nryzmust be '%(value)s'rr$rCcss|]}d|VqdS)z'%s'Nr&)r>r%r&r&r'r@�rAz$Enum._rule_values.<locals>.<genexpr>zmust be one of %(values)s)r�)r�r0r\rG)r7rr%rLr�r&r&r'�_rule_values�s
zEnum._rule_values)
rFrQrRrSrcrzrDr9r#r�r&r&r�r'r�s
�rc@seZdZdZeZdS)�	BytesEnumzB
    Enumerable for binary data (stored in the ``str`` type).
    N�rFrQrRrSr�r/r&r&r&r'r$�sr$c@seZdZdZeZdS)�StrEnumay
    Enumerable for Unicode text (stored in the ``unicode`` type).

    For example:

    >>> enum = StrEnum('my_enum', values=(u'One', u'Two', u'Three'))
    >>> enum.validate(u'Two', 'cli') is None
    True
    >>> enum.validate(u'Four', 'cli')
    Traceback (most recent call last):
      ...
    ValidationError: invalid 'my_enum': must be one of 'One', 'Two', 'Three'
    Nr%r&r&r&r'r&�sr&c@s*eZdZdZeZefZejZddd�Z	dS)�IntEnumzC
    Enumerable for integer data (stored in the ``int`` type).
    NcCs:zt�|�WSty4t|��t|j�d��Yn0dSr�r�r�r&r&r'r��s�zIntEnum._convert_scalar)N)
rFrQrRrSr r/rtr�r�r�r&r&r&r'r'�s
r'c@s(eZdZdZeZddd�Zddd�ZdS)	�AnyzS
    A parameter capable of holding values of any type. For internal use only.
    NcCs|Sr:r&r�r&r&r'r��szAny._convert_scalarcCs0|jD]$}|t|�}|durt|j|d��qdSr�)r�r�rr�)r7r%r�r�r�r&r&r'r��s

zAny._validate_scalar)N)N)rFrQrRrS�objectr/r�r�r&r&r&r'r(�s
r(c@s.eZdZdZdZejdedfdedffZdS)�FilezhText file parameter type.

    Accepts file names and loads their content into the parameter value.
    �r�stdin_if_missingFrN�rFrQrRrSZ	open_moder�rzr�r&r&r&r'r*�s�r*c@s.eZdZdZdZejdedfdedffZdS)�
BinaryFilezBinary file parameter type
    �rbr,FrNr-r&r&r&r'r.s�r.cs@eZdZdZedddddgZejZed�Z	d�fd	d
�	Z
�ZS)�DateTimea�
    DateTime parameter type.

    Accepts LDAP Generalized time without in the following format:
       '%Y%m%d%H%M%SZ'

    Accepts subset of values defined by ISO 8601:
        '%Y-%m-%dT%H:%M:%SZ'
        '%Y-%m-%dT%H:%MZ'
        '%Y-%m-%dZ'

    Also accepts above formats using ' ' (space) as a separator instead of 'T'.

    Refer to the `man strftime` for the explanations for the %Y,%m,%d,%H.%M,%S.
    z%Y-%m-%dT%H:%M:%SZz%Y-%m-%dT%H:%MZz	%Y-%m-%dZz%Y-%m-%d %H:%M:%SZz%Y-%m-%d %H:%MZzmust be datetime valueNc	s�t|t�r�|dkr(tjjtjjd�}|S|jD]0}ztj�||�}|WSty\Yq.0q.t	d�d�
|j�}t|��|d��t
t|��|�S)N�now)Ztzz(does not match any of accepted formats: rCr�)rr6�datetimer1�timezoneZutc�accepted_formats�strptimer3rrGr	r�r�r0r�)r7r%r��timeZdate_formatr�r�r&r'r�,s"



��zDateTime._convert_scalar)N)rFrQrRrSrr4r2r/rr�r�r�r&r&r�r'r0s�r0c@s�eZdZdZdd�Zdd�Zd!dd	�Zd
d�Zdd
�Zdd�Z	dd�Z
dd�Zdd�Zdd�Z
dd�Zdd�Zdd�Zdd�Zd S)"�
AccessTimez�
    Access time parameter type.

    Accepts values conforming to generalizedTime as defined in RFC 4517
    section 3.3.13 without time zone information.
    cCsxt|�dkrtd��|��s$td��t|dd��}|dksD|dkrLtd��t|dd��}|dksl|dkrttd	��dS)
N�z&HHMM must be exactly 4 characters longzHHMM non-numericrrp�zHH out of range�;zMM out of range)r0r3�	isnumericr )r7rxZhhZmmr&r&r'�_check_HHMMLszAccessTime._check_HHMMcCs>|��r*t|�}|dks |dkr:td��n|dvr:td��dS)Nry�zday of the week out of range)ZMonZTueZWedZThuZFriZSatZSunzinvalid day of the week)r;r r3�r7rxr%r&r&r'�_check_dotwXs
zAccessTime._check_dotwryr8cCs�|��std��t|�}|dvr:|dks0|dkr�td��n�|dvr\|dksR|dkr�td��n^|dkr�|d	d
kr�|dd
ks�|dd
kr�|dks�|d
kr�td��n|dks�|dkr�td��dS)Nzday of the month non-numeric)ry��r=r�r�r+ry�zday of the month out of range)r8��	��rpr8r�di����r;r3r )r7rx�	month_numZyearr%r&r&r'�_check_dotm`s

$
zAccessTime._check_dotmcCs4|��std��t|�}|dks(|dkr0td��dS)Nzweek of the month non-numericryrCzweek of the month out of rangerJr>r&r&r'�_check_wotmrs
zAccessTime._check_wotmcCs4|��std��t|�}|dks(|dkr0td��dS)Nzweek of the year non-numericry�4zweek of the year out of rangerJr>r&r&r'�_check_wotyys
zAccessTime._check_wotycCs4|��std��t|�}|dks(|dkr0td��dS)Nzday of the year non-numericryimzday of the year out of rangerJr>r&r&r'�_check_doty�s
zAccessTime._check_dotycCs4|��std��t|�}|dks(|dkr0td��dS)Nzmonth number non-numericryr+zmonth number out of rangerJr>r&r&r'�_check_month_num�s
zAccessTime._check_month_numcCs�|�d�}|D]l}|std��|�d�}t|�dkr<td��|D]}||�q@t|�dkrt|d�t|d�krtd��qdS)N�,�invalid time range�-rprry)�splitr3r0r )r7rxZ
check_funcZ	intervalsr!r�r�r&r&r'�_check_interval�s


zAccessTime._check_intervalcCs2||dkrtd��|d7}|�|||j�|S)N�dayzinvalid week specifierry)r3rVr?�r7�tsr�r&r&r'�
_check_W_spec�s
zAccessTime._check_W_speccCsh||dkr4|�||d|j�|�||d�}n0||dkr\|d7}|�|||j�ntd��|S)N�weekryrprWzinvalid month specifier)rVrMrZrLr3rXr&r&r'�
_check_M_spec�szAccessTime._check_M_speccCs�||dkr8|d7}|�|||j�|�||d�}nd||dkrl|�||d|j�|�||d�}n0||dkr�|d7}|�|||j�ntd��|S)NZmonthryr[rprWzinvalid year specifier)rVrQr\rOrZrPr3rXr&r&r'�
_check_Y_spec�szAccessTime._check_Y_speccCs�t|�dvrtd��|��s$td��|�|dd��t|dd��}t|dd��}|�|dd�||�t|�dkr�|�|dd��n|�d	|dd
��t|�dkr�t|dd��}|dks�|dkr�td
��dS)N)r�r+�zincomplete generalized timeztime non-numericr8rCrr�r+z%s00r�r^�<zseconds out of range)r0r3r;rQr rLr<)r7rxZyear_numrK�sr&r&r'�_check_generalized�szAccessTime._check_generalizedcCs(|��}|ddkrzt|�dkr(td��|�|d�|ddkrJtd��|�|d	�t|d�t|d	�krxtd
��n�|ddk�rd}|ddkr�|�|d�}nD|dd
kr�|�|d�}n*|ddkr�|�|d�}n|ddkr�d}|du�rtd|d��|�||d|j	�ntd��dS)Nr�absoluter8zDinvalid format, must be 'absolute generalizedTime ~ generalizedTime'ryrp�~zinvalid time range separatorr@rSZperiodicZyearlyZmonthlyZweeklyZdailyz0period must be yearly, monthy or daily, got '%s'z!time neither absolute or periodic)
rUr0r3rar r]r\rZrVr<)r7r6rYr�r&r&r'�_check�s0

zAccessTime._checkc
Csrz|�|�Wn^tyH}z"t|��|jdd��WYd}~n.d}~0tylt|��td�d��Yn0dS)Nrr�zincomplete time value)rdr3rr�rH�
IndexErrorr�)r7rr%r�r&r&r'�_rule_required�s*�zAccessTime._rule_requiredN)ryr8)rFrQrRrSr<r?rLrMrOrPrQrVrZr\r]rardrfr&r&r&r'r7Es
r7c@seZdZeZddd�ZdS)�DNParamNc
Cs�t|�|jvr|St|�ttfvr6t|jt|j�d��zt|�}Wn8t	yz}z t|�
�t|�d��WYd}~n
d}~00|Sr�)r/rtrDr|r	r�r�r�rrMr�)r7r%r�Zdnr�r&r&r'r��s��zDNParam._convert_scalar)N)rFrQrRrr/r�r&r&r&r'rg�srgcCs>t|t�r|St|�tur6ttdttf|t|�f��t|�S)a�
    Create an `Str` instance from the shorthand ``spec``.

    This function allows you to create `Str` parameters (the most common) from
    a convenient shorthand that defines the parameter name, whether it is
    required, and whether it is multivalue.  (For the definition of the
    shorthand syntax, see the `parse_param_spec()` function.)

    If ``spec`` is an ``str`` instance, it will be used to create a new `Str`
    parameter, which will be returned.  For example:

    >>> s = create_param('hometown?')
    >>> s
    Str('hometown?')
    >>> (s.name, s.required, s.multivalue)
    ('hometown', False, False)

    On the other hand, if ``spec`` is already a `Param` instance, it is
    returned unchanged.  For example:

    >>> b = Bytes('cert')
    >>> create_param(b) is b
    True

    As a plugin author, you will not call this function directly (which would
    be no more convenient than simply creating the `Str` instance).  Instead,
    `frontend.Command` will call it for you when it evaluates the
    ``takes_args`` and ``takes_options`` attributes, and `frontend.Object`
    will call it for you when it evaluates the ``takes_params`` attribute.

    :param spec: A spec string or a `Param` instance.
    rT)rrcr/r6r.rr)rTr&r&r'�create_param
s!
�rhcsdeZdZdZeZed�Zej	de
dfde
dffZ	�fdd�Zd�fd	d
�	Zdd�Z
d
d�Z�ZS)�DNSNameParamz�
    Domain name parameter type.

    :only_absolute a domain name has to be absolute
        (makes it absolute from unicode input)
    :only_relative a domain name has to be relative
    zmust be DNS name�
only_absoluteF�
only_relativecs<tt|�j|g|�Ri|��|jr8|jr8td|j��dS)Nz(%s: cannot be both absolute and relative)r�rir9rjrkr3r�r�r�r&r'r9Fs
�zDNSNameParam.__init__Nc
s~t|t�rnzt|�Wn8tyN}z t|��t|�d��WYd}~n
d}~00t|�}|jrn|��sn|�	�}t
t|��|�Sr�)
rr�rr3r	r�rrj�is_absoluteZ
make_absoluter�rir�r�r�r&r'r�Ls
�zDNSNameParam._convert_scalarcCs|jr|��s|d�SdSdS)Nzmust be absolute)rjrlr�r&r&r'�_rule_only_absoluteZsz DNSNameParam._rule_only_absolutecCs|jr|��r|d�SdSdS)Nzmust be relative)rkrlr�r&r&r'�_rule_only_relative`sz DNSNameParam._rule_only_relative)N)rFrQrRrSrr/rr�rcrzr�r9r�rmrnr�r&r&r�r'ri7s�ric@seZdZdZeZed�ZdS)�Dictz%
    A parameter for dictionary.
    zmust be dictionaryN)rFrQrRrSr\r/rr�r&r&r&r'rogsrocsVeZdZdZejZed�Ze	j
dedffZ
edd��Z
d�fdd	�	Zd
d�Z�ZS)
�	Principalz!
    Kerberos principal name
    zmust be Kerberos principal�require_serviceFcCs
|jtfSr:)r/r�rOr&r&r'rt{szPrincipal.allowed_typesNc	sZt|t�rJzt�|�}Wn0tyHt|��td�t|d�d��Yn0t	t|��
|�S)Nz Malformed principal: '%(value)s'r$r�)rr�rrpr3r	r�rr\r�r�r�r�r&r'r�s
��zPrincipal._convert_scalarcCs$|jr |js t|��|d�d��dS)NzService principal is requiredr�)rqZ
is_servicerr�r�r&r&r'�_rule_require_service�s
�zPrincipal._rule_require_service)N)rFrQrRrSrrpr/rr�rcrzr�r�rtr�rrr�r&r&r�r'rpps�
rpc
Cs�g}t�}|��tjjf|��tjjfg}|D]�\}}|D]�}|j|vrJq:|�|j�t	|t
�sbq:|jrrtjj}n|j
}tdd�|jD��}t	|t�r�|tjf7}tj|}	|jr�tj|	}	|�tj|j|||	d��q:q.tj|tjtjtjfd�}
|
S)z�Create an inspect.Signature for a command

    :param command: ipa plugin instance (server or client)
    :return: inspect.Signature instance
    css|]}t�||�VqdSr:)�
_map_typesrJrwr&r&r'r@�sz#create_signature.<locals>.<genexpr>)ru�
annotation)Zreturn_annotation)r}�get_args�inspectZ	ParameterZPOSITIONAL_OR_KEYWORDZget_optionsZKEYWORD_ONLYr�rarrcrV�emptyrurDrtrir�Z	text_type�typing�UnionrW�Listr�Z	Signaturero�Textr()ZcommandZsignature_params�seenZargs_optionsZ	ipaparamsr�Zipaparamrurt�annZ	signaturer&r&r'�create_signature�sB�


�



���r~csReZdZdZeZefZdZej	de
dfde
dfde
dffZ	d�fd	d
�	Z�ZS)�SerialNumberz-Certificate serial number parameter type
    l	r�ryr��(r�Ncs�tt|��|�|�d�r,t|jtd�d��|��s�|���d�r�zt	|dd�d�Wq�t
y�t|jttd��d��Yq�0nt|jttd��d��|d	kr�t|jtd
�d��dS)NrTzmust be at least 0r��0xrp�zinvalid valid hexr�r�zinvalid serial number 0)r�rr��
startswithrr�r�isdigitr�r r3r�r�r&r'r��s0

�����
�zSerialNumber._validate_scalar)N)
rFrQrRrSr6r/rtZ	MAX_VALUErcrzr r�r�r&r&r�r'r�s�r)`rSr�r"rr2rvrxZ
xmlrpc.clientrrr�ZcryptographyrrZdns.nameZdnsZipalib.textrr�Zipalib.baserZipalib.plugablerrZ
ipalib.errorsr	r
rrr
rrZipalib.constantsrrrrrZipalib.utilrrZipalib.x509rrrrrZ	ipapythonrZipapython.dnrZipapython.dnsutilrr�r�r�r(r�r6r�r)r_r}r`rcr�r�r�r�r#r�r�rrrrrrr$r&r'r(r*r.r0r7rgrhrirorpr��Namersr~rr&r&r&r'�<module>s�R	|-!!*\DG$6\!
53*0	%�	7