
    >Tf-                     L   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 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 dZ G d de          Z G d de          Z G d de          Z G d d          Z G d d          Z G d d          Zd dZ d!dZ!dS )"    )Iterable)settings)AccessMixin)ImproperlyConfigured)reverse)NoReverseMatch)url_has_allowed_host_and_scheme)gettext_lazy)PluginConfig)registry)get_related_models   )resolve_permission)ConditionalLoginRequiredMixin"ContentTypePermissionRequiredMixinGetRelatedModelsMixinGetReturnURLMixinObjectPermissionRequiredMixinViewTabget_viewnameregister_model_viewc                   "     e Zd ZdZ fdZ xZS )r   zm
    Similar to Django's LoginRequiredMixin, but enforces authentication only if LOGIN_REQUIRED is True.
    c                     t           j        r |j        j        s|                                 S  t                      j        |g|R i |S N)r   LOGIN_REQUIREDuseris_authenticatedhandle_no_permissionsuperdispatchselfrequestargskwargs	__class__s       4/var/www/html/netbox-4.1.3/netbox/utilities/views.pyr    z&ConditionalLoginRequiredMixin.dispatch$   sS    " 	/7<+H 	/,,...uww9$999&999    )__name__
__module____qualname____doc__r    __classcell__r&   s   @r'   r   r       sB         : : : : : : : : :r(   r   c                   B     e Zd ZdZ e            Zd Zd Z fdZ xZ	S )r   a  
    Similar to Django's built-in PermissionRequiredMixin, but extended to check model-level permission assignments.
    This is related to ObjectPermissionRequiredMixin, except that it does not enforce object-level permissions,
    and fits within NetBox's custom permission enforcement system.

    additional_permissions: An optional iterable of statically declared permissions to evaluate in addition to those
                            derived from the object type
    c                 v    t          t          d                              | j        j                            )h
        Return the specific permission necessary to perform the requested action on an object.
        zB{self.__class__.__name__} must implement get_required_permission()
class_nameNotImplementedError_formatr&   r)   r"   s    r'   get_required_permissionz:ContentTypePermissionRequiredMixin.get_required_permission5   s?     "!$h"i"i"p"p~. #q #
 #
   	r(   c                     | j         j        }|                                 }|                    |g| j        R           rdS dS )NTF)r#   r   r9   	has_permsadditional_permissions)r"   r   permission_requireds      r'   has_permissionz1ContentTypePermissionRequiredMixin.has_permission=   sM    | "::<< >>.M1LMMNN 	4ur(   c                     |                                  s|                                 S  t                      j        |g|R i |S r   )r>   r   r   r    r!   s       r'   r    z+ContentTypePermissionRequiredMixin.dispatchG   sP    ""$$ 	/,,...uww9$999&999r(   
r)   r*   r+   r,   listr<   r9   r>   r    r-   r.   s   @r'   r   r   *   sn          "TVV    : : : : : : : : :r(   r   c                   B     e Zd ZdZ e            Zd Zd Z fdZ xZ	S )r   a  
    Similar to Django's built-in PermissionRequiredMixin, but extended to check for both model-level and object-level
    permission assignments. If the user has only object-level permissions assigned, the view's queryset is filtered
    to return only those objects on which the user is permitted to perform the specified action.

    additional_permissions: An optional iterable of statically declared permissions to evaluate in addition to those
                            derived from the object type
    c                 v    t          t          d                              | j        j                            )r1   z5{class_name} must implement get_required_permission()r2   r4   r8   s    r'   r9   z5ObjectPermissionRequiredMixin.get_required_permissionY   s?     "!$["\"\"c"c~. #d #
 #
   	r(   c                     | j         j        }|                                 }|                    |g| j        R           r7t          |          d         }| j                            ||          | _        dS dS )Nr   TF)r#   r   r9   r;   r<   r   querysetrestrict)r"   r   r=   actions       r'   r>   z,ObjectPermissionRequiredMixin.has_permissiona   s{    | "::<< >>.M1LMMNN 	 ((;<<Q?F M224@@DM4ur(   c                 "   t          | d          s:t          t          d                              | j        j                            |                                 s|                                 S  t                      j	        |g|R i |S )NrE   zz{class_name} has no queryset defined. ObjectPermissionRequiredMixin may only be used on views which define a base querysetr2   )
hasattrr   r6   r7   r&   r)   r>   r   r   r    r!   s       r'   r    z&ObjectPermissionRequiredMixin.dispatchp   s    tZ(( 	&3  &DN$;&<<	   ""$$ 	/,,...uww9$999&999r(   r@   r.   s   @r'   r   r   N   sn          "TVV    : : : : : : : : :r(   r   c                       e Zd ZdZdZddZdS )r   zc
    Provides logic for determining where a user should be redirected after processing a form.
    Nc                    |j                             d          p|j                            d          }|rt          |d           r|S |+|j        r$t          |d          r|                                S | j        t          | j                  S t          | d          rA| j	        j
        j        }	 t          |j         d|j         d          S # t          $ r Y nw xY wt          d          S )N
return_url)allowed_hostsget_absolute_urlrE   :_listhome)GETgetPOSTr	   pkrI   rN   default_return_urlr   rE   model_meta	app_label
model_namer   )r"   r#   objrL   
model_optss        r'   get_return_urlz GetReturnURLMixin.get_return_url   s    [__\22Tgl6F6F|6T6T
 	9*TXYYY 	 ?sv?'#7I*J*J?''))) ".42333 4$$ 	,2J*"6UU9NUUUVVV!    vs   4C 
C C r   )r)   r*   r+   r,   rV   r]    r(   r'   r   r      s:               r(   r   c                       e Zd ZdZg g fdZdS )r   zZ
    Provides logic for collecting all related models for the currently viewed model.
    c                     | j         j        t          fdt          d                    }fd|D             }|                    |           t          |d           S )a  
        Get related models of the view's `queryset` model without those listed in `omit`. Will be sorted alphabetical.

        Args:
            request: Current request being processed.
            instance: The instance related models should be looked up for. A list of instances can be passed to match
                related objects in this list (e.g. to find sites of a region including child regions).
            omit: Remove relationships to these models from the result. Needs to be passed, if related models don't
                provide a `_list` view.
            extra: Add extra models to the list of automatically determined related models. Can be used to add indirect
                relationships.
        c                 ,    | d         uo	| d         vS Nr   r^   )mrW   omits    r'   <lambda>z:GetRelatedModelsMixin.get_related_models.<locals>.<lambda>   s    ad%'<AaD,< r(   Fc           
          g | ]S\  }} |j                             j        d           j        di t	          t
                    r| din|i| dfTS )view__in_idr^   )objectsrF   r   filter
isinstancer   ).0rW   fieldinstancer#   s      r'   
<listcomp>z<GetRelatedModelsMixin.get_related_models.<locals>.<listcomp>   s     

 

 

 u D&&w|V<<C  !(H55+^^^X..* 
 

 

 

r(   c                 T    | d         j         j        j                                        S rb   )rW   rX   verbose_namelower)xs    r'   re   z:GetRelatedModelsMixin.get_related_models.<locals>.<lambda>   s    AaDJ4D4Q4W4W4Y4Y r(   )key)rE   rW   rk   r   extendsorted)r"   r#   ro   rd   extrarelatedrelated_modelsrW   s    ```   @r'   r   z(GetRelatedModelsMixin.get_related_models   s     #<<<<<ue,,
 



 

 

 

 

 !(

 

 

 	e$$$n*Y*YZZZZr(   N)r)   r*   r+   r,   r   r^   r(   r'   r   r      s?          :<2  [  [  [  [  [  [r(   r   c                   &    e Zd ZdZddZd Zd ZdS )	r   a  
    ViewTabs are used for navigation among multiple object-specific views, such as the changelog or journal for
    a particular object.

    Args:
        label: Human-friendly text
        badge: A static value or callable to display alongside the label (optional). If a callable is used, it must
            accept a single argument representing the object being viewed.
        weight: Numeric weight to influence ordering among other tabs (default: 1000)
        permission: The permission required to display the tab (optional).
        hide_if_empty: If true, the tab will be displayed only if its badge has a meaningful value. (Tabs without a
            badge are always displayed.)
    N  Fc                 L    || _         || _        || _        || _        || _        d S r   )labelbadgeweight
permissionhide_if_empty)r"   r~   r   r   r   r   s         r'   __init__zViewTab.__init__   s,    

$*r(   c                 p    |                      |          }| j        r| j        r|sdS | j        || j        dS )z5Return the attributes needed to render a tab in HTML.N)r~   r   r   )_get_badge_valuer   r   r~   r   )r"   ro   badge_values      r'   renderzViewTab.render   sQ    ++H55: 	$, 	[ 	4Z k
 
 	
r(   c                 t    | j         sd S t          | j                   r|                      |          S | j         S r   )r   callable)r"   ro   s     r'   r   zViewTab._get_badge_value   s=    z 	4DJ 	(::h'''zr(   )Nr|   NF)r)   r*   r+   r,   r   r   r   r^   r(   r'   r   r      sP         + + + +	
 	
 	
    r(   r   NFc                     t          | j        j        t                    }| j        j        }| j        j        }|r| d| }|rd| }|r| d| }n| d| }|rd| }|r| d| }|S )a.  
    Return the view name for the given model and action, if valid.

    :param model: The model or instance to which the view applies
    :param action: A string indicating the desired action (if any); e.g. "add" or "list"
    :param rest_api: A boolean indicating whether this is a REST API view
    z-api:zplugins-api:-rO   zplugins:r6   )rl   rX   
app_configr   rY   rZ   )rW   rG   rest_api	is_pluginrY   rZ   viewnames          r'   r   r      s     5;1<@@I%I'J .22j22 	10h00H 	."--V--H  ..*.. 	-,(,,H 	."--V--HOr(    c                       fd}|S )a  
    This decorator can be used to "attach" a view to any model in NetBox. This is typically used to inject
    additional tabs within a model's detail view. For example, to add a custom tab to NetBox's dcim.Site model:

        @register_model_view(Site, 'myview', path='my-custom-view')
        class MyView(ObjectView):
            ...

    This will automatically create a URL path for MyView at `/dcim/sites/<id>/my-custom-view/` which can be
    resolved using the view name `dcim:site_myview'.

    Args:
        model: The Django model class with which this view will be associated.
        name: The string used to form the view's name for URL resolution (e.g. via `reverse()`). This will be appended
            to the name of the base view for the model using an underscore. If blank, the model name will be used.
        path: The URL path by which the view can be reached (optional). If not provided, `name` will be used.
        kwargs: A dictionary of keyword arguments for the view to include when registering its URL path (optional).
    c                     j         j        }j         j        }|t          d         |         vrg t          d         |         |<   t          d         |         |                             | ppi d           | S )Nviews)namerg   pathr%   )rX   rY   rZ   r   append)clsrY   rZ   r%   rW   r   r   s      r'   _wrapperz%register_model_view.<locals>._wrapper&  s    K)	[+
Xg.y99979HWi(4)$Z077LDl	9
 9
 	 	 	 
r(   r^   )rW   r   r   r%   r   s   ```` r'   r   r     s5    &         Or(   )NF)r   NN)"typingr   django.confr   django.contrib.auth.mixinsr   django.core.exceptionsr   django.urlsr   django.urls.exceptionsr   django.utils.httpr	   django.utils.translationr
   r6   netbox.pluginsr   netbox.registryr   utilities.relationsr   permissionsr   __all__r   r   r   r   r   r   r   r   r^   r(   r'   <module>r      s                     2 2 2 2 2 2 7 7 7 7 7 7       1 1 1 1 1 1 = = = = = = 6 6 6 6 6 6 ' ' ' ' ' ' $ $ $ $ $ $ 2 2 2 2 2 2 + + + + + +	 : : : : :K : : :!: !: !: !: !:)F !: !: !:H/: /: /: /: /:$A /: /: /:d       D%[ %[ %[ %[ %[ %[ %[ %[P% % % % % % % %X   :# # # # # #r(   