diff --git a/netbox/users/forms/bulk_edit.py b/netbox/users/forms/bulk_edit.py index 8d63f1406..2eaac4ef9 100644 --- a/netbox/users/forms/bulk_edit.py +++ b/netbox/users/forms/bulk_edit.py @@ -1,7 +1,8 @@ from django import forms from django.utils.translation import gettext_lazy as _ + from users.models import * -from utilities.forms import BootstrapMixin, BulkEditForm, add_blank_choice +from utilities.forms import BootstrapMixin, BulkEditForm from utilities.forms.widgets import BulkEditNullBooleanSelect __all__ = ( @@ -12,28 +13,72 @@ __all__ = ( class UserBulkEditForm(BootstrapMixin, forms.Form): - pk = forms.ModelMultipleChoiceField(queryset=NetBoxUser.objects.all(), widget=forms.MultipleHiddenInput) - first_name = forms.CharField(label=_('First name'), max_length=150, required=False) - last_name = forms.CharField(label=_('Last name'), max_length=150, required=False) - is_active = forms.NullBooleanField(required=False, widget=BulkEditNullBooleanSelect, label=_('Active')) - is_staff = forms.NullBooleanField(required=False, widget=BulkEditNullBooleanSelect, label=_('Staff status')) - is_superuser = forms.NullBooleanField(required=False, widget=BulkEditNullBooleanSelect, label=_('Superuser status')) + pk = forms.ModelMultipleChoiceField( + queryset=NetBoxUser.objects.all(), + widget=forms.MultipleHiddenInput + ) + first_name = forms.CharField( + label=_('First name'), + max_length=150, + required=False + ) + last_name = forms.CharField( + label=_('Last name'), + max_length=150, + required=False + ) + is_active = forms.NullBooleanField( + required=False, + widget=BulkEditNullBooleanSelect, + label=_('Active') + ) + is_staff = forms.NullBooleanField( + required=False, + widget=BulkEditNullBooleanSelect, + label=_('Staff status') + ) + is_superuser = forms.NullBooleanField( + required=False, + widget=BulkEditNullBooleanSelect, + label=_('Superuser status') + ) model = NetBoxUser - fieldsets = ((None, ('first_name', 'last_name', 'is_active', 'is_staff', 'is_superuser')),) + fieldsets = ( + (None, ('first_name', 'last_name', 'is_active', 'is_staff', 'is_superuser')), + ) nullable_fields = ('first_name', 'last_name') class ObjectPermissionBulkEditForm(BootstrapMixin, forms.Form): - pk = forms.ModelMultipleChoiceField(queryset=ObjectPermission.objects.all(), widget=forms.MultipleHiddenInput) - description = forms.CharField(label=_('Description'), max_length=200, required=False) - enabled = forms.NullBooleanField(required=False, widget=BulkEditNullBooleanSelect, label=_('Enabled')) + pk = forms.ModelMultipleChoiceField( + queryset=ObjectPermission.objects.all(), + widget=forms.MultipleHiddenInput + ) + description = forms.CharField( + label=_('Description'), + max_length=200, + required=False + ) + enabled = forms.NullBooleanField( + required=False, + widget=BulkEditNullBooleanSelect, + label=_('Enabled') + ) model = ObjectPermission - fieldsets = ((None, ('enabled', 'description')),) + fieldsets = ( + (None, ('enabled', 'description')), + ) nullable_fields = ('description',) class UserTokenBulkEditForm(BulkEditForm): - pk = forms.ModelMultipleChoiceField(queryset=Token.objects.all(), widget=forms.MultipleHiddenInput) - description = forms.CharField(max_length=200, required=False) + pk = forms.ModelMultipleChoiceField( + queryset=Token.objects.all(), + widget=forms.MultipleHiddenInput + ) + description = forms.CharField( + max_length=200, + required=False + ) diff --git a/netbox/users/forms/model_forms.py b/netbox/users/forms/model_forms.py index 7af2d1654..ba0b11c5c 100644 --- a/netbox/users/forms/model_forms.py +++ b/netbox/users/forms/model_forms.py @@ -1,31 +1,24 @@ from django import forms from django.conf import settings from django.contrib.auth import get_user_model -from django.contrib.auth.forms import AuthenticationForm -from django.contrib.auth.forms import PasswordChangeForm as DjangoPasswordChangeForm from django.contrib.auth.models import Group from django.contrib.contenttypes.models import ContentType from django.contrib.postgres.forms import SimpleArrayField from django.core.exceptions import FieldError from django.utils.html import mark_safe -from django.utils.translation import gettext as _ from django.utils.translation import gettext_lazy as _ + from ipam.formfields import IPNetworkFormField from ipam.validators import prefix_validator +from netbox.preferences import PREFERENCES from users.constants import * from users.models import * -from users.models import Token, UserConfig from utilities.forms import BootstrapMixin -from utilities.forms.fields import ( - ContentTypeMultipleChoiceField, - DynamicModelMultipleChoiceField, -) +from utilities.forms.fields import ContentTypeMultipleChoiceField, DynamicModelMultipleChoiceField from utilities.forms.widgets import DateTimePicker from utilities.permissions import qs_filter_from_constraints from utilities.utils import flatten_dict -from netbox.preferences import PREFERENCES - __all__ = ( 'GroupForm', 'ObjectPermissionForm', @@ -36,16 +29,10 @@ __all__ = ( ) -class LoginForm(BootstrapMixin, AuthenticationForm): - pass - - -class PasswordChangeForm(BootstrapMixin, DjangoPasswordChangeForm): - pass - - class UserConfigFormMetaclass(forms.models.ModelFormMetaclass): + def __new__(mcs, name, bases, attrs): + # Emulate a declared field for each supported user preference preference_fields = {} for field_name, preference in PREFERENCES.items(): @@ -67,24 +54,28 @@ class UserConfigFormMetaclass(forms.models.ModelFormMetaclass): class UserConfigForm(BootstrapMixin, forms.ModelForm, metaclass=UserConfigFormMetaclass): fieldsets = ( - ( - _('User Interface'), - ( - 'pagination.per_page', - 'pagination.placement', - 'ui.colormode', - ), - ), - (_('Miscellaneous'), ('data_format',)), + (_('User Interface'), ( + 'pagination.per_page', + 'pagination.placement', + 'ui.colormode', + )), + (_('Miscellaneous'), ( + 'data_format', + )), ) # List of clearable preferences - pk = forms.MultipleChoiceField(label=_('Pk'), choices=[], required=False) + pk = forms.MultipleChoiceField( + label=_('Pk'), + choices=[], + required=False + ) class Meta: model = UserConfig fields = () def __init__(self, *args, instance=None, **kwargs): + # Get initial data from UserConfig instance initial_data = flatten_dict(instance.data) kwargs['initial'] = initial_data @@ -92,9 +83,12 @@ class UserConfigForm(BootstrapMixin, forms.ModelForm, metaclass=UserConfigFormMe super().__init__(*args, instance=instance, **kwargs) # Compile clearable preference choices - self.fields['pk'].choices = ((f'tables.{table_name}', '') for table_name in instance.data.get('tables', [])) + self.fields['pk'].choices = ( + (f'tables.{table_name}', '') for table_name in instance.data.get('tables', []) + ) def save(self, *args, **kwargs): + # Set UserConfig data for pref_name, value in self.cleaned_data.items(): if pref_name == 'pk': @@ -109,7 +103,9 @@ class UserConfigForm(BootstrapMixin, forms.ModelForm, metaclass=UserConfigFormMe @property def plugin_fields(self): - return [name for name in self.fields.keys() if name.startswith('plugins.')] + return [ + name for name in self.fields.keys() if name.startswith('plugins.') + ] class TokenForm(BootstrapMixin, forms.ModelForm): @@ -129,11 +125,7 @@ class TokenForm(BootstrapMixin, forms.ModelForm): class Meta: model = Token fields = [ - 'key', - 'write_enabled', - 'expires', - 'description', - 'allowed_ips', + 'key', 'write_enabled', 'expires', 'description', 'allowed_ips', ] widgets = { 'expires': DateTimePicker(), @@ -170,12 +162,7 @@ class UserTokenForm(BootstrapMixin, forms.ModelForm): class Meta: model = Token fields = [ - 'key', - 'user', - 'write_enabled', - 'expires', - 'description', - 'allowed_ips', + 'user', 'key', 'write_enabled', 'expires', 'description', 'allowed_ips', ] widgets = { 'expires': DateTimePicker(), @@ -201,7 +188,11 @@ class UserForm(BootstrapMixin, forms.ModelForm): required=True, help_text=_("Enter the same password as before, for verification."), ) - groups = DynamicModelMultipleChoiceField(label=_('Groups'), required=False, queryset=Group.objects.all()) + groups = DynamicModelMultipleChoiceField( + label=_('Groups'), + required=False, + queryset=Group.objects.all() + ) object_permissions = DynamicModelMultipleChoiceField( required=False, label=_('Permissions'), @@ -211,7 +202,7 @@ class UserForm(BootstrapMixin, forms.ModelForm): fieldsets = ( (_('User'), ('username', 'password', 'confirm_password', 'first_name', 'last_name', 'email')), - (_('Groups'), ('groups',)), + (_('Groups'), ('groups', )), (_('Status'), ('is_active', 'is_staff', 'is_superuser')), (_('Permissions'), ('object_permissions',)), ) @@ -219,15 +210,8 @@ class UserForm(BootstrapMixin, forms.ModelForm): class Meta: model = NetBoxUser fields = [ - 'username', - 'first_name', - 'last_name', - 'email', - 'groups', - 'object_permissions', - 'is_active', - 'is_staff', - 'is_superuser', + 'username', 'first_name', 'last_name', 'email', 'groups', 'object_permissions', + 'is_active', 'is_staff', 'is_superuser', ] def __init__(self, *args, **kwargs): @@ -257,6 +241,7 @@ class UserForm(BootstrapMixin, forms.ModelForm): return instance def clean(self): + # Check that password confirmation matches if password is set if self.cleaned_data['password'] and self.cleaned_data['password'] != self.cleaned_data['confirm_password']: raise forms.ValidationError(_("Passwords do not match! Please check your input and try again.")) @@ -271,14 +256,22 @@ class UserForm(BootstrapMixin, forms.ModelForm): qs = self._meta.model.objects.all() username = self.cleaned_data.get("username") - if username and qs.filter(username__iexact=username).exists(): - raise forms.ValidationError(_("user with this username already exists")) + if ( + username and qs.filter(username__iexact=username).exists() + ): + raise forms.ValidationError( + _("user with this username already exists") + ) return username class GroupForm(BootstrapMixin, forms.ModelForm): - users = DynamicModelMultipleChoiceField(label=_('Users'), required=False, queryset=get_user_model().objects.all()) + users = DynamicModelMultipleChoiceField( + label=_('Users'), + required=False, + queryset=get_user_model().objects.all() + ) object_permissions = DynamicModelMultipleChoiceField( required=False, label=_('Permissions'), @@ -287,17 +280,15 @@ class GroupForm(BootstrapMixin, forms.ModelForm): ) fieldsets = ( - (None, ('name',)), - (_('Users'), ('users',)), - (_('Permissions'), ('object_permissions',)), + (None, ('name', )), + (_('Users'), ('users', )), + (_('Permissions'), ('object_permissions', )), ) class Meta: model = NetBoxGroup fields = [ - 'name', - 'users', - 'object_permissions', + 'name', 'users', 'object_permissions', ] def __init__(self, *args, **kwargs): @@ -323,47 +314,49 @@ class ObjectPermissionForm(BootstrapMixin, forms.ModelForm): label=_('Object types'), queryset=ContentType.objects.all(), limit_choices_to=OBJECTPERMISSION_OBJECT_TYPES, - widget=forms.SelectMultiple(attrs={'size': 6}), + widget=forms.SelectMultiple(attrs={'size': 6}) + ) + can_view = forms.BooleanField( + required=False + ) + can_add = forms.BooleanField( + required=False + ) + can_change = forms.BooleanField( + required=False + ) + can_delete = forms.BooleanField( + required=False ) - can_view = forms.BooleanField(required=False) - can_add = forms.BooleanField(required=False) - can_change = forms.BooleanField(required=False) - can_delete = forms.BooleanField(required=False) actions = SimpleArrayField( label=_('Additional actions'), base_field=forms.CharField(), required=False, - help_text=_('Actions granted in addition to those listed above'), + help_text=_('Actions granted in addition to those listed above') + ) + users = DynamicModelMultipleChoiceField( + label=_('Users'), + required=False, + queryset=get_user_model().objects.all() + ) + groups = DynamicModelMultipleChoiceField( + label=_('Groups'), + required=False, + queryset=Group.objects.all() ) - users = DynamicModelMultipleChoiceField(label=_('Users'), required=False, queryset=get_user_model().objects.all()) - groups = DynamicModelMultipleChoiceField(label=_('Groups'), required=False, queryset=Group.objects.all()) fieldsets = ( - ( - None, - ( - 'name', - 'description', - 'enabled', - ), - ), + (None, ('name', 'description', 'enabled',)), (_('Actions'), ('can_view', 'can_add', 'can_change', 'can_delete', 'actions')), - (_('Objects'), ('object_types',)), + (_('Objects'), ('object_types', )), (_('Assignment'), ('groups', 'users')), - (_('Constraints'), ('constraints',)), + (_('Constraints'), ('constraints',)) ) class Meta: model = ObjectPermission fields = [ - 'name', - 'description', - 'enabled', - 'object_types', - 'users', - 'groups', - 'constraints', - 'actions', + 'name', 'description', 'enabled', 'object_types', 'users', 'groups', 'constraints', 'actions', ] help_texts = { 'constraints': _( @@ -421,6 +414,6 @@ class ObjectPermissionForm(BootstrapMixin, forms.ModelForm): } model.objects.filter(qs_filter_from_constraints(constraints, tokens)).exists() except FieldError as e: - raise forms.ValidationError( - {'constraints': _('Invalid filter for {model}: {e}').format(model=model, e=e)} - ) + raise forms.ValidationError({ + 'constraints': _('Invalid filter for {model}: {e}').format(model=model, e=e) + }) diff --git a/netbox/users/models.py b/netbox/users/models.py index 7b0e16965..2aa56cd6b 100644 --- a/netbox/users/models.py +++ b/netbox/users/models.py @@ -328,11 +328,11 @@ class UserToken(Token): objects = RestrictedQuerySet.as_manager() + # # Permissions # - class ObjectPermission(models.Model): """ A mapping of view, add, change, and/or delete permission for users and/or groups to an arbitrary set of objects diff --git a/netbox/users/tables.py b/netbox/users/tables.py index 9cb2af846..1c7f165d4 100644 --- a/netbox/users/tables.py +++ b/netbox/users/tables.py @@ -1,4 +1,3 @@ -from django.conf import settings import django_tables2 as tables from netbox.tables import NetBoxTable, columns @@ -34,27 +33,18 @@ class TokenActionsColumn(columns.ActionsColumn): class TokenTable(NetBoxTable): key = columns.TemplateColumn( - verbose_name='Key', template_code=TOKEN ) write_enabled = columns.BooleanColumn( verbose_name='Write' ) - created = columns.DateColumn( - verbose_name='Created', - ) - expired = columns.DateColumn( - verbose_name='Expired', - ) - last_used = columns.DateTimeColumn( - verbose_name='Last used', - ) + created = columns.DateColumn() + expired = columns.DateColumn() + last_used = columns.DateTimeColumn() allowed_ips = columns.TemplateColumn( - verbose_name='Allowed IPs', template_code=ALLOWED_IPS ) actions = TokenActionsColumn( - verbose_name='Actions', actions=('edit', 'delete'), extra_buttons=COPY_BUTTON ) @@ -102,24 +92,15 @@ class UserTokenTable(NetBoxTable): class UserTable(NetBoxTable): username = tables.Column( - verbose_name='Username', linkify=True ) groups = columns.ManyToManyColumn( - verbose_name='Groups', linkify_item=('users:netboxgroup', {'pk': tables.A('pk')}) ) - is_active = columns.BooleanColumn( - verbose_name='Is active', - ) - is_staff = columns.BooleanColumn( - verbose_name='Is staff', - ) - is_superuser = columns.BooleanColumn( - verbose_name='Is superuser', - ) + is_active = columns.BooleanColumn() + is_staff = columns.BooleanColumn() + is_superuser = columns.BooleanColumn() actions = columns.ActionsColumn( - verbose_name='Actions', actions=('edit', 'delete'), ) @@ -133,12 +114,8 @@ class UserTable(NetBoxTable): class GroupTable(NetBoxTable): - name = tables.Column( - verbose_name='Name', - linkify=True - ) + name = tables.Column(linkify=True) actions = columns.ActionsColumn( - verbose_name='Actions', actions=('edit', 'delete'), ) @@ -151,42 +128,23 @@ class GroupTable(NetBoxTable): class ObjectPermissionTable(NetBoxTable): - name = tables.Column( - verbose_name='Name', - linkify=True - ) - object_types = columns.ContentTypesColumn( - verbose_name='Object types', - ) - enabled = columns.BooleanColumn( - verbose_name='Enabled', - ) - can_view = columns.BooleanColumn( - verbose_name='Can view', - ) - can_add = columns.BooleanColumn( - verbose_name='Can add', - ) - can_change = columns.BooleanColumn( - verbose_name='Can change', - ) - can_delete = columns.BooleanColumn( - verbose_name='Can delete', - ) + name = tables.Column(linkify=True) + object_types = columns.ContentTypesColumn() + enabled = columns.BooleanColumn() + can_view = columns.BooleanColumn() + can_add = columns.BooleanColumn() + can_change = columns.BooleanColumn() + can_delete = columns.BooleanColumn() custom_actions = columns.ArrayColumn( - verbose_name='Custom actions', accessor=tables.A('actions') ) users = columns.ManyToManyColumn( - verbose_name='Users', linkify_item=('users:netboxuser', {'pk': tables.A('pk')}) ) groups = columns.ManyToManyColumn( - verbose_name='Groups', linkify_item=('users:netboxgroup', {'pk': tables.A('pk')}) ) actions = columns.ActionsColumn( - verbose_name='Actions', actions=('edit', 'delete'), ) diff --git a/netbox/users/views.py b/netbox/users/views.py index 7fe4f96b4..7f14adcdd 100644 --- a/netbox/users/views.py +++ b/netbox/users/views.py @@ -2,9 +2,7 @@ import logging from django.conf import settings from django.contrib import messages -from django.contrib.auth import login as auth_login -from django.contrib.auth import logout as auth_logout -from django.contrib.auth import update_session_auth_hash +from django.contrib.auth import login as auth_login, logout as auth_logout, update_session_auth_hash from django.contrib.auth.mixins import LoginRequiredMixin from django.contrib.auth.models import update_last_login from django.contrib.auth.signals import user_logged_in @@ -16,38 +14,27 @@ from django.utils.decorators import method_decorator from django.utils.http import url_has_allowed_host_and_scheme, urlencode from django.views.decorators.debug import sensitive_post_parameters from django.views.generic import View +from social_core.backends.utils import load_backends + from extras.models import Bookmark, ObjectChange from extras.tables import BookmarkTable, ObjectChangeTable -from social_core.backends.utils import load_backends -from utilities.forms import ConfirmationForm -from utilities.views import register_model_view - from netbox.authentication import get_auth_backend_display, get_saml_idps from netbox.config import get_config from netbox.views import generic - +from utilities.forms import ConfirmationForm +from utilities.views import register_model_view from . import filtersets, forms, tables -from .filtersets import TokenFilterSet, UserTokenFilterSet -from .models import ( - NetBoxGroup, - NetBoxUser, - ObjectPermission, - Token, - UserConfig, - UserToken, -) -from .tables import TokenTable, UserTokenTable +from .models import Token, UserConfig, NetBoxGroup, NetBoxUser, ObjectPermission, UserToken + # # Login/logout # - class LoginView(View): """ Perform user authentication via the web UI. """ - template_name = 'login.html' @method_decorator(sensitive_post_parameters('password')) @@ -89,14 +76,10 @@ class LoginView(View): logger = logging.getLogger('netbox.auth.login') return self.redirect_to_next(request, logger) - return render( - request, - self.template_name, - { - 'form': form, - 'auth_backends': self.get_auth_backends(request), - }, - ) + return render(request, self.template_name, { + 'form': form, + 'auth_backends': self.get_auth_backends(request), + }) def post(self, request): logger = logging.getLogger('netbox.auth.login') @@ -127,14 +110,10 @@ class LoginView(View): else: logger.debug(f"Login form validation failed for username: {form['username'].value()}") - return render( - request, - self.template_name, - { - 'form': form, - 'auth_backends': self.get_auth_backends(request), - }, - ) + return render(request, self.template_name, { + 'form': form, + 'auth_backends': self.get_auth_backends(request), + }) def redirect_to_next(self, request, logger): data = request.POST if request.method == "POST" else request.GET @@ -175,28 +154,23 @@ class LogoutView(View): # User profiles # - class ProfileView(LoginRequiredMixin, View): template_name = 'users/account/profile.html' def get(self, request): + # Compile changelog table - changelog = ( - ObjectChange.objects.valid_models() - .restrict(request.user, 'view') - .filter(user=request.user) - .prefetch_related('changed_object_type')[:20] - ) + changelog = ObjectChange.objects.valid_models().restrict(request.user, 'view').filter( + user=request.user + ).prefetch_related( + 'changed_object_type' + )[:20] changelog_table = ObjectChangeTable(changelog) - return render( - request, - self.template_name, - { - 'changelog_table': changelog_table, - 'active_tab': 'profile', - }, - ) + return render(request, self.template_name, { + 'changelog_table': changelog_table, + 'active_tab': 'profile', + }) class UserConfigView(LoginRequiredMixin, View): @@ -206,14 +180,10 @@ class UserConfigView(LoginRequiredMixin, View): userconfig = request.user.config form = forms.UserConfigForm(instance=userconfig) - return render( - request, - self.template_name, - { - 'form': form, - 'active_tab': 'preferences', - }, - ) + return render(request, self.template_name, { + 'form': form, + 'active_tab': 'preferences', + }) def post(self, request): userconfig = request.user.config @@ -225,14 +195,10 @@ class UserConfigView(LoginRequiredMixin, View): messages.success(request, "Your preferences have been updated.") return redirect('users:preferences') - return render( - request, - self.template_name, - { - 'form': form, - 'active_tab': 'preferences', - }, - ) + return render(request, self.template_name, { + 'form': form, + 'active_tab': 'preferences', + }) class ChangePasswordView(LoginRequiredMixin, View): @@ -246,14 +212,10 @@ class ChangePasswordView(LoginRequiredMixin, View): form = forms.PasswordChangeForm(user=request.user) - return render( - request, - self.template_name, - { - 'form': form, - 'active_tab': 'password', - }, - ) + return render(request, self.template_name, { + 'form': form, + 'active_tab': 'password', + }) def post(self, request): form = forms.PasswordChangeForm(user=request.user, data=request.POST) @@ -263,21 +225,16 @@ class ChangePasswordView(LoginRequiredMixin, View): messages.success(request, "Your password has been changed successfully.") return redirect('users:profile') - return render( - request, - self.template_name, - { - 'form': form, - 'active_tab': 'change_password', - }, - ) + return render(request, self.template_name, { + 'form': form, + 'active_tab': 'change_password', + }) # # Bookmarks # - class BookmarkListView(LoginRequiredMixin, generic.ObjectListView): table = BookmarkTable template_name = 'users/account/bookmarks.html' @@ -295,27 +252,26 @@ class BookmarkListView(LoginRequiredMixin, generic.ObjectListView): # API tokens # - class TokenListView(LoginRequiredMixin, View): + def get(self, request): + tokens = Token.objects.filter(user=request.user) table = tables.TokenTable(tokens) table.configure(request) - return render( - request, - 'users/account/api_tokens.html', - { - 'tokens': tokens, - 'active_tab': 'api-tokens', - 'table': table, - }, - ) + return render(request, 'users/account/api_tokens.html', { + 'tokens': tokens, + 'active_tab': 'api-tokens', + 'table': table, + }) @register_model_view(Token, 'edit') class TokenEditView(LoginRequiredMixin, View): + def get(self, request, pk=None): + if pk: token = get_object_or_404(Token.objects.filter(user=request.user), pk=pk) else: @@ -323,17 +279,14 @@ class TokenEditView(LoginRequiredMixin, View): form = forms.TokenForm(instance=token) - return render( - request, - 'generic/object_edit.html', - { - 'object': token, - 'form': form, - 'return_url': reverse('users:token_list'), - }, - ) + return render(request, 'generic/object_edit.html', { + 'object': token, + 'form': form, + 'return_url': reverse('users:token_list'), + }) def post(self, request, pk=None): + if pk: token = get_object_or_404(Token.objects.filter(user=request.user), pk=pk) form = forms.TokenForm(request.POST, instance=token) @@ -342,6 +295,7 @@ class TokenEditView(LoginRequiredMixin, View): form = forms.TokenForm(request.POST) if form.is_valid(): + token = form.save(commit=False) token.user = request.user token.save() @@ -350,52 +304,43 @@ class TokenEditView(LoginRequiredMixin, View): messages.success(request, msg) if not pk and not settings.ALLOW_TOKEN_RETRIEVAL: - return render( - request, - 'users/account/api_token.html', - { - 'object': token, - 'key': token.key, - 'return_url': reverse('users:token_list'), - }, - ) + return render(request, 'users/account/api_token.html', { + 'object': token, + 'key': token.key, + 'return_url': reverse('users:token_list'), + }) elif '_addanother' in request.POST: return redirect(request.path) else: return redirect('users:token_list') - return render( - request, - 'generic/object_edit.html', - { - 'object': token, - 'form': form, - 'return_url': reverse('users:token_list'), - 'disable_addanother': not settings.ALLOW_TOKEN_RETRIEVAL, - }, - ) + return render(request, 'generic/object_edit.html', { + 'object': token, + 'form': form, + 'return_url': reverse('users:token_list'), + 'disable_addanother': not settings.ALLOW_TOKEN_RETRIEVAL + }) @register_model_view(Token, 'delete') class TokenDeleteView(LoginRequiredMixin, View): + def get(self, request, pk): + token = get_object_or_404(Token.objects.filter(user=request.user), pk=pk) initial_data = { 'return_url': reverse('users:token_list'), } form = ConfirmationForm(initial=initial_data) - return render( - request, - 'generic/object_delete.html', - { - 'object': token, - 'form': form, - 'return_url': reverse('users:token_list'), - }, - ) + return render(request, 'generic/object_delete.html', { + 'object': token, + 'form': form, + 'return_url': reverse('users:token_list'), + }) def post(self, request, pk): + token = get_object_or_404(Token.objects.filter(user=request.user), pk=pk) form = ConfirmationForm(request.POST) if form.is_valid(): @@ -403,27 +348,22 @@ class TokenDeleteView(LoginRequiredMixin, View): messages.success(request, "Token deleted") return redirect('users:token_list') - return render( - request, - 'generic/object_delete.html', - { - 'object': token, - 'form': form, - 'return_url': reverse('users:token_list'), - }, - ) + return render(request, 'generic/object_delete.html', { + 'object': token, + 'form': form, + 'return_url': reverse('users:token_list'), + }) # # User Token # - class UserTokenListView(generic.ObjectListView): queryset = UserToken.objects.all() - filterset = UserTokenFilterSet + filterset = filtersets.UserTokenFilterSet filterset_form = forms.UserTokenFilterForm - table = UserTokenTable + table = tables.UserTokenTable @register_model_view(UserToken) @@ -452,20 +392,19 @@ class UserTokenBulkImportView(generic.BulkImportView): class UserTokenBulkEditView(generic.BulkEditView): queryset = UserToken.objects.all() - table = TokenTable + table = tables.TokenTable form = forms.UserTokenBulkEditForm class UserTokenBulkDeleteView(generic.BulkDeleteView): queryset = UserToken.objects.all() - table = UserTokenTable + table = tables.UserTokenTable # # Users # - class UserListView(generic.ObjectListView): queryset = NetBoxUser.objects.all() filterset = filtersets.UserFilterSet @@ -555,7 +494,6 @@ class GroupBulkDeleteView(generic.BulkDeleteView): filterset = filtersets.GroupFilterSet table = tables.GroupTable - # # ObjectPermissions #