Skip to content
New issue

Have a question about this project? Sign up for a free GitHub account to open an issue and contact its maintainers and the community.

By clicking “Sign up for GitHub”, you agree to our terms of service and privacy statement. We’ll occasionally send you account related emails.

Already on GitHub? Sign in to your account

[HOLD]#159687667 Enable manager to delete users and trainers from a gym #21

Open
wants to merge 1 commit into
base: develop
Choose a base branch
from
Open
Show file tree
Hide file tree
Changes from all commits
Commits
File filter

Filter by extension

Filter by extension

Conversations
Failed to load comments.
Loading
Jump to
Jump to file
Failed to load files.
Loading
Diff view
Diff view
40 changes: 40 additions & 0 deletions wger/gym/forms.py
Original file line number Diff line number Diff line change
Expand Up @@ -20,6 +20,8 @@

from wger.core.forms import UserPersonalInformationForm
from wger.utils.widgets import BootstrapSelectMultiple
from wger.gym.models import GymAdminConfig
from django.db.utils import IntegrityError


class GymUserPermisssionForm(forms.ModelForm):
Expand Down Expand Up @@ -91,3 +93,41 @@ def clean_username(self):
return username
raise forms.ValidationError(
_("A user with that username already exists."))


class GymAddExistingUserForm(GymUserPermisssionForm):
'''
Form used when adding a user to a gym
'''

class Meta:
model = GymAdminConfig
widgets = {'role': BootstrapSelectMultiple()}
fields = ('username', 'role',)

username = forms.RegexField(label=_("Username"),
max_length=30,
regex=r'^[\w.@+-]+$',
help_text=_("Required. 30 characters or fewer. Letters, digits and "
"@/./+/-/_ only."),
error_messages={
'invalid': _("This value may contain only letters, numbers and "
"@/.//-/_ characters.")})

def clean_username(self):
'''
Since User.username is unique, this check is redundant,
but it sets a nicer error message than the ORM. See #13147.
'''
username = self.cleaned_data["username"]
try:
user = User._default_manager.get(username=username)
except User.DoesNotExist:
raise forms.ValidationError(
_("Username does not exists."))

if user.userprofile.gym_id is not None:
raise forms.ValidationError(
_(str(username) + " already belongs to a gym."))

return username
16 changes: 13 additions & 3 deletions wger/gym/templates/gym/member_list.html
Original file line number Diff line number Diff line change
Expand Up @@ -428,8 +428,18 @@ <h4>{% trans "Emails" %}</h4>
{# #}
{% block options %}
{% if perms.gym.manage_gym or perms.gym.manage_gyms %}
<a href="{% url 'gym:gym:add-user' gym.pk %}" class="btn btn-success btn-sm wger-modal-dialog">
{% trans "Add member" %}
</a>
<div class="btn-group pull-right">
<button type="button" class="btn btn-success btn-sm dropdown-toggle" data-toggle="dropdown">
{% trans "Add Member" %} <span class="caret"></span>
</button>
<ul class="dropdown-menu" role="menu">
<li>
<a href="{% url 'gym:gym:add-user' gym.pk %}" class="wger-modal-dialog">{% trans "New User"%}</a>
</li>
<li>
<a href="{% url 'gym:gym:add-user-existing' gym.pk %}" class="wger-modal-dialog">{% trans "Existing User"%}</a>
</li>
</ul>
</div>
{% endif %}
{% endblock %}
56 changes: 56 additions & 0 deletions wger/gym/tests/test_add_existing_user.py
Original file line number Diff line number Diff line change
@@ -0,0 +1,56 @@
from django.core.urlresolvers import reverse
from wger.core.tests.base_testcase import WorkoutManagerTestCase
from wger.gym.models import GymAdminConfig
from django.contrib.auth.models import User


class GymAddExistingUserTestCase(WorkoutManagerTestCase):
'''
Tests admin adding users to gyms
'''
def add_existing_user(self, fail=False, logged_in=True, role='admin'):
'''
Helper function to add users
'''
GymAdminConfig.objects.all().delete()

self.client.post(reverse('gym:gym:add-user', kwargs={'gym_pk': 1}),
{'first_name': 'Cletus',
'last_name': 'Spuckle',
'username': 'cletus',
'email': '[email protected]',
'role': str(role)})

user = GymAdminConfig.objects.first()
if not fail:
user_pk = user.user_id if user else 4
self.client.post(
reverse('gym:gym:delete-user', kwargs={'user_pk': user_pk}))

response = self.client.post(reverse('gym:gym:add-user-existing', kwargs={'gym_pk': 1}),
{'username': 'cletus', 'role': str(role)})

if fail:
self.assertEqual(response.status_code, 403)
else:
self.assertEqual(response.status_code, 302)

def test_delete_user_authorized(self):
"""
Tests deleting a user an authorized user
"""
self.user_login('admin')
self.add_existing_user()

def test_delete_user_unauthorized(self):
"""
Tests deleting a user an unauthorized user
"""
self.user_login('test')
self.add_existing_user(fail=True)

def test_delete_user_not_logged_in(self):
"""
Tests deleting a user an unauthorized user
"""
self.add_existing_user(fail=True, logged_in=False)
5 changes: 4 additions & 1 deletion wger/gym/tests/test_user.py
Original file line number Diff line number Diff line change
Expand Up @@ -22,7 +22,10 @@
from wger.core.models import UserProfile
from wger.core.tests.base_testcase import WorkoutManagerTestCase
from wger.gym.models import Gym
from wger.gym.models import GymAdminConfig
from wger.gym.models import (
GymAdminConfig,
GymUserConfig
)


class GymAddUserTestCase(WorkoutManagerTestCase):
Expand Down
3 changes: 3 additions & 0 deletions wger/gym/urls.py
Original file line number Diff line number Diff line change
Expand Up @@ -51,6 +51,9 @@
url(r'^(?P<gym_pk>\d+)/add-member$',
gym.GymAddUserView.as_view(),
name='add-user'),
url(r'^(?P<gym_pk>\d+)/add-member-existing$',
gym.GymAddExistingUserView.as_view(),
name='add-user-existing'),
url(r'^add$',
gym.GymAddView.as_view(),
name='add'),
Expand Down
80 changes: 75 additions & 5 deletions wger/gym/views/gym.py
Original file line number Diff line number Diff line change
Expand Up @@ -39,7 +39,11 @@
UpdateView
)

from wger.gym.forms import GymUserAddForm, GymUserPermisssionForm
from wger.gym.forms import (
GymUserAddForm,
GymAddExistingUserForm,
GymUserPermisssionForm
)
from wger.gym.helpers import (
get_user_last_activity,
is_any_gym_admin,
Expand Down Expand Up @@ -179,12 +183,15 @@ def delete_user(request, user_pk):

user_matched = GymUserConfig.objects.filter(user_id=member.id).first() or \
GymAdminConfig.objects.filter(user_id=member.id).first()
gym_id = user_matched.gym_id

if user_matched:
member = User.objects.filter(pk=user_pk).first()
member.delete()
member.userprofile.gym_id = None
member.userprofile.save()
user_matched.delete()

return HttpResponseRedirect(reverse("gym:gym:user-list", kwargs={'pk': user_matched.gym_id}))
return HttpResponseRedirect(reverse("gym:gym:user-list", kwargs={'pk': gym_id}))


@login_required()
Expand Down Expand Up @@ -359,8 +366,8 @@ class GymAddUserView(WgerFormMixin,
View to add a user to a new gym
'''

model = User
title = ugettext_lazy('Add user to gym')
model = GymAdminConfig
title = ugettext_lazy('Add new user to gym')
success_url = reverse_lazy('gym:gym:new-user-data')
permission_required = ('gym.manage_gym', 'gym.manage_gyms')
form_class = GymUserAddForm
Expand Down Expand Up @@ -450,6 +457,69 @@ def get_context_data(self, **kwargs):
return context


class GymAddExistingUserView(GymAddUserView):
'''
View to add a user to a new gym
'''

model = GymAdminConfig
title = ugettext_lazy('Add existing user to gym')
success_url = reverse_lazy('gym:gym:new-user-data')
permission_required = ('gym.manage_gym', 'gym.manage_gyms')
form_class = GymAddExistingUserForm

def form_valid(self, form):
'''
Create the user, set the user permissions and gym
'''
permissions = ['gym_member', 'gym_trainer', 'gym_manager', 'general_gym_manager']
gym = Gym.objects.get(pk=self.kwargs['gym_pk'])
user = User.objects.filter(username=form.cleaned_data['username']).first()
form.instance = user

# Update profile
user.userprofile.gym = gym
user.userprofile.save()

# Remove all previously set permissions
for perm in permissions:
user.groups.remove(Group.objects.get(name=str(perm)))

# Set appropriate permission groups
if 'user' in form.cleaned_data['role']:
user.groups.add(Group.objects.get(name='gym_member'))
if 'trainer' in form.cleaned_data['role']:
user.groups.add(Group.objects.get(name='gym_trainer'))
if 'admin' in form.cleaned_data['role']:
user.groups.add(Group.objects.get(name='gym_manager'))
if 'manager' in form.cleaned_data['role']:
user.groups.add(Group.objects.get(name='general_gym_manager'))

self.request.session['gym.user'] = {'user_pk': user.pk,
'password': '-/-'}

# Create config
if is_any_gym_admin(user):
config = GymAdminConfig()
else:
config = GymUserConfig()

config.user = user
config.gym = gym
config.save()

return super(GymAddUserView, self).form_valid(form)

def get_context_data(self, **kwargs):
'''
Send some additional data to the template
'''
context = super(GymAddExistingUserView, self).get_context_data(**kwargs)
context['form_action'] = reverse('gym:gym:add-user-existing',
kwargs={'gym_pk': self.kwargs['gym_pk']})
return context


class GymUpdateView(WgerFormMixin, LoginRequiredMixin,
PermissionRequiredMixin, UpdateView):
'''
Expand Down