зеркало из https://github.com/mozilla/kitsune.git
[bug 783707] Allow disabling of users
This commit is contained in:
Родитель
238ec06c87
Коммит
a2a85134db
|
@ -70,7 +70,8 @@ class Profile(ModelBase):
|
|||
verbose_name=_lazy(u'Preferred language for email'))
|
||||
|
||||
class Meta(object):
|
||||
permissions = (('view_karma_points', 'Can view karma points'),)
|
||||
permissions = (('view_karma_points', 'Can view karma points'),
|
||||
('deactivate_users', 'Can deactivate users'),)
|
||||
|
||||
def __unicode__(self):
|
||||
return unicode(self.user)
|
||||
|
|
|
@ -44,6 +44,17 @@
|
|||
{{ private_message(profile.user) }}
|
||||
{% endif %}
|
||||
</div>
|
||||
{% if user.id != profile.user.id and user.has_perm('users.deactivate_users') %}
|
||||
{% if profile.user.is_active %}
|
||||
<form id="deactivate-form" method="post" action="{{ url('users.deactivate') }}">
|
||||
{{ csrf() }}
|
||||
<input type="hidden" name="user_id" value="{{ profile.user.id }}">
|
||||
<input type="submit" value="{{ _('Deactivate this user') }}">
|
||||
</form>
|
||||
{% else %}
|
||||
<div id="deactivated-msg">{{ _('This user has been deactivated.') }}</div>
|
||||
{% endif %}
|
||||
{% endif %}
|
||||
{% if num_answers or num_questions or num_solutions or num_documents %}
|
||||
<section class="contributions">
|
||||
<h2>Contributions</h2>
|
||||
|
|
|
@ -382,6 +382,24 @@ class ViewProfileTests(TestCaseBase):
|
|||
eq_(200, r.status_code)
|
||||
assert '2 documents' in r.content
|
||||
|
||||
def test_deactivate_button(self):
|
||||
"""Check that the deactivate button is shown appropriately"""
|
||||
p = profile()
|
||||
r = self.client.get(reverse('users.profile', args=[p.user.id]))
|
||||
assert 'Deactivate this user' not in r.content
|
||||
|
||||
add_permission(self.u, Profile, 'deactivate_users')
|
||||
self.client.login(username=self.u.username, password='testpass')
|
||||
r = self.client.get(reverse('users.profile', args=[p.user.id]))
|
||||
assert 'Deactivate this user' in r.content
|
||||
|
||||
p.user.is_active = False
|
||||
p.user.save()
|
||||
r = self.client.get(reverse('users.profile', args=[p.user.id]))
|
||||
assert 'This user has been deactivated.' in r.content
|
||||
|
||||
r = self.client.get(reverse('users.profile', args=[self.u.id]))
|
||||
assert 'Deactivate this user' not in r.content
|
||||
|
||||
class PasswordChangeTests(TestCaseBase):
|
||||
|
||||
|
|
|
@ -16,7 +16,7 @@ from sumo.tests import TestCase, LocalizingClient, send_mail_raise_smtp
|
|||
from sumo.urlresolvers import reverse
|
||||
from users import ERROR_SEND_EMAIL
|
||||
from users.models import Profile, RegistrationProfile, EmailChange, Setting
|
||||
from users.tests import profile, user, group
|
||||
from users.tests import profile, user, group, add_permission
|
||||
|
||||
|
||||
class RegisterTests(TestCase):
|
||||
|
@ -453,3 +453,22 @@ class UserProfileTests(TestCase):
|
|||
def test_profile_post(self):
|
||||
res = self.client.post(self.url)
|
||||
eq_(405, res.status_code)
|
||||
|
||||
def test_profile_deactivate(self):
|
||||
"""Test user deactivation"""
|
||||
p = profile()
|
||||
|
||||
self.client.login(username=self.u.username, password='testpass')
|
||||
res = self.client.post(reverse('users.deactivate', locale='en-US'),
|
||||
{'user_id': p.user.id})
|
||||
|
||||
eq_(403, res.status_code)
|
||||
|
||||
add_permission(self.u, Profile, 'deactivate_users')
|
||||
res = self.client.post(reverse('users.deactivate', locale='en-US'),
|
||||
{'user_id': p.user.id})
|
||||
|
||||
eq_(302, res.status_code)
|
||||
|
||||
p = Profile.objects.get(user_id=p.user_id)
|
||||
assert not p.user.is_active
|
||||
|
|
|
@ -40,6 +40,7 @@ users_patterns = patterns('',
|
|||
url(r'^/settings$', views.edit_settings, name='users.edit_settings'),
|
||||
url(r'^/avatar$', views.edit_avatar, name='users.edit_avatar'),
|
||||
url(r'^/avatar/delete$', views.delete_avatar, name='users.delete_avatar'),
|
||||
url(r'^/deactivate$', views.deactivate, name='users.deactivate'),
|
||||
|
||||
# Password reset
|
||||
url(r'^/pwreset$', views.password_reset, name='users.pw_reset'),
|
||||
|
|
|
@ -10,7 +10,8 @@ from django.contrib.sites.models import Site
|
|||
from django.core import mail
|
||||
from django.http import (HttpResponsePermanentRedirect, HttpResponseRedirect,
|
||||
Http404)
|
||||
from django.views.decorators.http import require_http_methods, require_GET
|
||||
from django.views.decorators.http import (require_http_methods, require_GET,
|
||||
require_POST)
|
||||
from django.shortcuts import get_object_or_404
|
||||
from django.template.loader import render_to_string
|
||||
from django.utils.http import base36_to_int
|
||||
|
@ -22,7 +23,8 @@ from statsd import statsd
|
|||
from tidings.tasks import claim_watches
|
||||
from tower import ugettext as _
|
||||
|
||||
from access.decorators import logout_required, login_required
|
||||
from access.decorators import (logout_required, login_required,
|
||||
permission_required)
|
||||
from questions.models import (Question, user_num_answers, user_num_questions,
|
||||
user_num_solutions)
|
||||
from sumo import email_utils
|
||||
|
@ -35,6 +37,7 @@ from users.forms import (ProfileForm, AvatarForm, EmailConfirmationForm,
|
|||
AuthenticationForm, EmailChangeForm, SetPasswordForm,
|
||||
PasswordChangeForm, SettingsForm, ForgotUsernameForm,
|
||||
RegisterForm)
|
||||
from users.helpers import profile_url
|
||||
from users.models import (Profile, RegistrationProfile,
|
||||
EmailChange)
|
||||
from users.utils import (handle_login, handle_register,
|
||||
|
@ -287,7 +290,11 @@ def confirm_change_email(request, activation_key):
|
|||
@mobile_template('users/{mobile/}profile.html')
|
||||
def profile(request, template, user_id):
|
||||
user_profile = get_object_or_404(
|
||||
Profile, user__id=user_id, user__is_active=True)
|
||||
Profile, user__id=user_id)
|
||||
|
||||
if not (request.user.has_perm('users.deactivate_users')
|
||||
or user_profile.user.is_active):
|
||||
raise Http404('No Profile matches the given query.')
|
||||
|
||||
groups = user_profile.user.groups.all()
|
||||
return jingo.render(request, template, {
|
||||
|
@ -299,6 +306,15 @@ def profile(request, template, user_id):
|
|||
'num_documents': user_num_documents(user_profile.user),})
|
||||
|
||||
|
||||
@require_POST
|
||||
@permission_required('users.deactivate_users')
|
||||
def deactivate(request):
|
||||
user = get_object_or_404(User, id=request.POST['user_id'], is_active=True)
|
||||
user.is_active = False
|
||||
user.save()
|
||||
return HttpResponseRedirect(profile_url(user))
|
||||
|
||||
|
||||
@require_GET
|
||||
def documents_contributed(request, user_id):
|
||||
user_profile = get_object_or_404(
|
||||
|
|
|
@ -11,6 +11,11 @@ article {
|
|||
}
|
||||
}
|
||||
|
||||
#deactivated-msg {
|
||||
color: #cc0000;
|
||||
font-weight: bold;
|
||||
}
|
||||
|
||||
#user-nav {
|
||||
margin-bottom: 20px;
|
||||
}
|
||||
|
|
|
@ -0,0 +1,4 @@
|
|||
SET @ct = (SELECT id from django_content_type WHERE name='profile' AND app_label='users');
|
||||
|
||||
INSERT INTO auth_permission (`name`, `content_type_id`, `codename`) VALUES
|
||||
('Can deactivate users', @ct, 'deactivate_users');
|
Загрузка…
Ссылка в новой задаче