[bug 783707] Allow disabling of users

This commit is contained in:
Rehan Dalal 2013-02-19 18:54:15 -05:00
Родитель 238ec06c87
Коммит a2a85134db
8 изменённых файлов: 80 добавлений и 5 удалений

Просмотреть файл

@ -70,7 +70,8 @@ class Profile(ModelBase):
verbose_name=_lazy(u'Preferred language for email')) verbose_name=_lazy(u'Preferred language for email'))
class Meta(object): 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): def __unicode__(self):
return unicode(self.user) return unicode(self.user)

Просмотреть файл

@ -44,6 +44,17 @@
{{ private_message(profile.user) }} {{ private_message(profile.user) }}
{% endif %} {% endif %}
</div> </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 %} {% if num_answers or num_questions or num_solutions or num_documents %}
<section class="contributions"> <section class="contributions">
<h2>Contributions</h2> <h2>Contributions</h2>

Просмотреть файл

@ -382,6 +382,24 @@ class ViewProfileTests(TestCaseBase):
eq_(200, r.status_code) eq_(200, r.status_code)
assert '2 documents' in r.content 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): class PasswordChangeTests(TestCaseBase):

Просмотреть файл

@ -16,7 +16,7 @@ from sumo.tests import TestCase, LocalizingClient, send_mail_raise_smtp
from sumo.urlresolvers import reverse from sumo.urlresolvers import reverse
from users import ERROR_SEND_EMAIL from users import ERROR_SEND_EMAIL
from users.models import Profile, RegistrationProfile, EmailChange, Setting 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): class RegisterTests(TestCase):
@ -453,3 +453,22 @@ class UserProfileTests(TestCase):
def test_profile_post(self): def test_profile_post(self):
res = self.client.post(self.url) res = self.client.post(self.url)
eq_(405, res.status_code) 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'^/settings$', views.edit_settings, name='users.edit_settings'),
url(r'^/avatar$', views.edit_avatar, name='users.edit_avatar'), url(r'^/avatar$', views.edit_avatar, name='users.edit_avatar'),
url(r'^/avatar/delete$', views.delete_avatar, name='users.delete_avatar'), url(r'^/avatar/delete$', views.delete_avatar, name='users.delete_avatar'),
url(r'^/deactivate$', views.deactivate, name='users.deactivate'),
# Password reset # Password reset
url(r'^/pwreset$', views.password_reset, name='users.pw_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.core import mail
from django.http import (HttpResponsePermanentRedirect, HttpResponseRedirect, from django.http import (HttpResponsePermanentRedirect, HttpResponseRedirect,
Http404) 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.shortcuts import get_object_or_404
from django.template.loader import render_to_string from django.template.loader import render_to_string
from django.utils.http import base36_to_int from django.utils.http import base36_to_int
@ -22,7 +23,8 @@ from statsd import statsd
from tidings.tasks import claim_watches from tidings.tasks import claim_watches
from tower import ugettext as _ 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, from questions.models import (Question, user_num_answers, user_num_questions,
user_num_solutions) user_num_solutions)
from sumo import email_utils from sumo import email_utils
@ -35,6 +37,7 @@ from users.forms import (ProfileForm, AvatarForm, EmailConfirmationForm,
AuthenticationForm, EmailChangeForm, SetPasswordForm, AuthenticationForm, EmailChangeForm, SetPasswordForm,
PasswordChangeForm, SettingsForm, ForgotUsernameForm, PasswordChangeForm, SettingsForm, ForgotUsernameForm,
RegisterForm) RegisterForm)
from users.helpers import profile_url
from users.models import (Profile, RegistrationProfile, from users.models import (Profile, RegistrationProfile,
EmailChange) EmailChange)
from users.utils import (handle_login, handle_register, 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') @mobile_template('users/{mobile/}profile.html')
def profile(request, template, user_id): def profile(request, template, user_id):
user_profile = get_object_or_404( 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() groups = user_profile.user.groups.all()
return jingo.render(request, template, { return jingo.render(request, template, {
@ -299,6 +306,15 @@ def profile(request, template, user_id):
'num_documents': user_num_documents(user_profile.user),}) '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 @require_GET
def documents_contributed(request, user_id): def documents_contributed(request, user_id):
user_profile = get_object_or_404( user_profile = get_object_or_404(

Просмотреть файл

@ -11,6 +11,11 @@ article {
} }
} }
#deactivated-msg {
color: #cc0000;
font-weight: bold;
}
#user-nav { #user-nav {
margin-bottom: 20px; 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');