diff --git a/netbox/users/forms/model_forms.py b/netbox/users/forms/model_forms.py
index 15d16d052..8c20f5350 100644
--- a/netbox/users/forms/model_forms.py
+++ b/netbox/users/forms/model_forms.py
@@ -199,25 +199,30 @@ class UserForm(BootstrapMixin, forms.ModelForm):
# Adjust form fields depending if Add or Edit
if self.instance.pk:
self.fields['object_permissions'].initial = self.instance.object_permissions.all().values_list('id', flat=True)
- self.fields['password'].disabled = True
- self.fields['password'].required = False
- self.fields['password'].help_text = _(
- "Raw passwords are not stored, so there is no way to see this "
- "user’s password, but you can change the password using "
- 'this form.'
- ).format(url=reverse('users:change_user_password', args=[self.instance.pk]))
- print(self.fields['password'].help_text)
- del self.fields['confirm_password']
+ pw_field = self.fields['password']
+ pwc_field = self.fields['confirm_password']
+ pw_field.required = False
+ pw_field.widget.attrs.pop('required')
+ pw_field.help_text = _("Leave empty to keep the old password.")
+ pwc_field.required = False
+ pwc_field.widget.attrs.pop('required')
def save(self, *args, **kwargs):
+ edited = getattr(self, 'instance', None)
instance = super().save(*args, **kwargs)
instance.object_permissions.set(self.cleaned_data['object_permissions'])
+
+ # On edit, check if we have to save the password
+ if edited and self.cleaned_data.get("password"):
+ instance.set_password(self.cleaned_data.get("password"))
+ instance.save()
+
return instance
def clean(self):
cleaned_data = super().clean()
instance = getattr(self, 'instance', None)
- if not instance:
+ if not instance or cleaned_data.get("password"):
password = cleaned_data.get("password")
confirm_password = cleaned_data.get("confirm_password")
diff --git a/netbox/users/urls.py b/netbox/users/urls.py
index 6e9f3ef70..815a39ec8 100644
--- a/netbox/users/urls.py
+++ b/netbox/users/urls.py
@@ -18,7 +18,6 @@ urlpatterns = [
path('users/edit/', views.NetBoxUserBulkEditView.as_view(), name='netboxuser_bulk_edit'),
path('users/delete/', views.NetBoxUserBulkDeleteView.as_view(), name='netboxuser_bulk_delete'),
path('users//', include(get_model_urls('users', 'netboxuser'))),
- path('users/password//', views.NetBoxUserChangePasswordView.as_view(), name='change_user_password'),
# Groups
path('groups/', views.NetBoxGroupListView.as_view(), name='netboxgroup_list'),
diff --git a/netbox/users/views.py b/netbox/users/views.py
index 1f997ca38..79a3d23e0 100644
--- a/netbox/users/views.py
+++ b/netbox/users/views.py
@@ -414,52 +414,6 @@ class NetBoxUserBulkDeleteView(generic.BulkDeleteView):
return get_permission_for_model(User, 'delete')
-class NetBoxUserChangePasswordView(LoginRequiredMixin, View):
- template_name = 'users/passworduser.html'
- queryset = User.objects.all()
-
- def get_object(self, **kwargs):
- """
- Return an object for editing. If no keyword arguments have been specified, this will be a new instance.
- """
- if not kwargs:
- # We're creating a new object
- return self.queryset.model()
- return get_object_or_404(self.queryset, **kwargs)
-
- def get(self, request, *args, **kwargs):
- obj = self.get_object(**kwargs)
-
- # LDAP users cannot change their password here
- if getattr(obj, 'ldap_username', None):
- messages.warning(request, "LDAP-authenticated user credentials cannot be changed within NetBox.")
- return redirect('users:netboxuser_list')
-
- form = forms.PasswordSetForm(user=obj)
-
- return render(request, self.template_name, {
- 'form': form,
- 'active_tab': 'password',
- 'object': obj,
- })
-
- def post(self, request, *args, **kwargs):
- obj = self.get_object(**kwargs)
-
- form = forms.PasswordSetForm(user=obj, data=request.POST)
- if form.is_valid():
- form.save()
- update_session_auth_hash(request, form.user)
- messages.success(request, "The password has been changed successfully.")
- return redirect('users:netboxuser_list')
-
- return render(request, self.template_name, {
- 'form': form,
- 'active_tab': 'password',
- 'object': obj,
- })
-
-
#
# Groups
#