Commit 6aab5288 authored by Tom van Bussel's avatar Tom van Bussel

Renamed Member to Profile and added User proxy

parent e9324074
......@@ -5,6 +5,8 @@ from django.contrib.auth.models import Permission
from django.db.models import Q
from django.utils import timezone
from members.models import Member
class CommitteeBackend(object):
"""Check permissions against committees"""
......@@ -20,11 +22,17 @@ class CommitteeBackend(object):
def _get_permissions(self, user, obj):
if not user.is_active or user.is_anonymous or obj is not None:
return set()
perm_cache_name = '_committee_perm_cache'
committees = user.committee_set.filter(
try:
member = Member.objects.get(pk=user.pk)
except Member.DoesNotExist:
return set()
committees = member.committee_set.filter(
Q(committeemembership__until=None) |
Q(committeemembership__until__gte=timezone.now())
)
perm_cache_name = '_committee_perm_cache'
if not hasattr(user, perm_cache_name):
perms = (Permission.objects
.filter(committee__in=committees)
......
from django import forms
from django.contrib.auth.models import User
from activemembers.models import CommitteeMembership
from members.models import Member
class CommitteeMembershipForm(forms.ModelForm):
member = forms.ModelChoiceField(
queryset=User.objects.order_by('first_name',
'last_name'))
queryset=Member.objects.order_by('first_name',
'last_name'))
class Meta:
model = CommitteeMembership
......
# -*- coding: utf-8 -*-
# Generated by Django 1.11.6 on 2017-10-13 12:16
from __future__ import unicode_literals
from django.db import migrations, models
import django.db.models.deletion
class Migration(migrations.Migration):
dependencies = [
('members', '0018_create_proxy_member'),
('activemembers', '0022_4_user_foreign_keys'),
]
operations = [
migrations.AlterField(
model_name='committee',
name='members',
field=models.ManyToManyField(through='activemembers.CommitteeMembership', to='members.Member'),
),
migrations.AlterField(
model_name='committeemembership',
name='member',
field=models.ForeignKey(on_delete=django.db.models.deletion.CASCADE, to='members.Member', verbose_name='Member'),
),
migrations.AlterField(
model_name='mentorship',
name='member',
field=models.ForeignKey(on_delete=django.db.models.deletion.CASCADE, to='members.Member', verbose_name='Member'),
),
]
import datetime
import logging
from django.contrib.auth.models import Permission, User
from django.contrib.auth.models import Permission
from django.core.exceptions import NON_FIELD_ERRORS, ValidationError
from django.core.validators import MinValueValidator
from django.db import models
......@@ -69,7 +69,7 @@ class Committee(models.Model, metaclass=ModelTranslateMeta):
)
members = models.ManyToManyField(
User,
'members.Member',
through='CommitteeMembership'
)
......@@ -206,7 +206,7 @@ class CommitteeMembership(models.Model, metaclass=ModelTranslateMeta):
active_memberships = ActiveMembershipManager()
member = models.ForeignKey(
User,
'members.Member',
on_delete=models.CASCADE,
verbose_name=_('Member'),
)
......@@ -348,7 +348,7 @@ class CommitteeMembership(models.Model, metaclass=ModelTranslateMeta):
class Mentorship(models.Model):
member = models.ForeignKey(
User,
'members.Member',
on_delete=models.CASCADE,
verbose_name=_('Member'),
)
......
......@@ -34,13 +34,13 @@
<ul class="row" id="commissieleden">
{% for member in members %}
<li class="post member-item span3 has-overlay">
<a href="{{ member.member.get_absolute_url }}">
<a href="{{ member.get_absolute_url }}">
<div class="post-inner">
<div class="inner-img">
{% if not member.member.photo %}
<img alt="{{ member.member.display_name }}" src="{% static 'members/images/default-avatar.jpg' %}" height="220" width="220" />
{% if not member.profile.photo %}
<img alt="{{ member.profile.display_name }}" src="{% static 'members/images/default-avatar.jpg' %}" height="220" width="220" />
{% else %}
<img alt="{{ member.member.display_name }}" src="{% thumbnail member.member.photo '220x220' %}" width="220" height="220" />
<img alt="{{ member.profile.display_name }}" src="{% thumbnail member.profile.photo '220x220' %}" width="220" height="220" />
{% endif %}
</div>
{% if member.chair %}
......@@ -52,12 +52,12 @@
{% endif %}
<div class="post-overlay">
<div class="post-overlay-meta">
<h2>{{ member.member.display_name }}</h2>
<h2>{{ member.profile.display_name }}</h2>
<p>{{ member.role }}</p>
</div>
</div>
<div class="post-body avatar-subtitle">
{{ member.member.display_name }}
{{ member.profile.display_name }}
</div>
</div>
</a>
......
......@@ -30,13 +30,13 @@
<ul class="row" id="commissieleden">
{% for member in members %}
<li class="post member-item span3 has-overlay">
<a href="{{ member.member.get_absolute_url }}">
<a href="{{ member.get_absolute_url }}">
<div class="post-inner">
<div class="inner-img">
{% if not member.member.photo %}
<img alt="{{ member.member.display_name }}" src="{% static 'members/images/default-avatar.jpg' %}" height="220" width="220" />
{% if not member.profile.photo %}
<img alt="{{ member.profile.display_name }}" src="{% static 'members/images/default-avatar.jpg' %}" height="220" width="220" />
{% else %}
<img alt="{{ member.member.display_name }}" src="{% thumbnail member.member.photo '220x220' %}" width="220" height="220" />
<img alt="{{ member.profile.display_name }}" src="{% thumbnail member.profile.photo '220x220' %}" width="220" height="220" />
{% endif %}
</div>
{% if member.chair %}
......@@ -48,7 +48,7 @@
{% endif %}
<div class="post-overlay">
<div class="post-overlay-meta">
<h2>{{ member.member.display_name }}</h2>
<h2>{{ member.profile.display_name }}</h2>
<p>
{% if member.committee_since.year == 1970 %}
{% blocktrans %}Committee member since: ?{% endblocktrans %}
......@@ -59,7 +59,7 @@
</div>
</div>
<div class="post-body avatar-subtitle">
{{ member.member.display_name }}
{{ member.profile.display_name }}
</div>
</div>
</a>
......
from django.contrib.auth import get_user_model
from django.contrib.auth.models import User
from django.core.exceptions import ValidationError
from django.db.utils import IntegrityError
......@@ -7,6 +6,7 @@ from django.utils import timezone
from activemembers.models import Committee, CommitteeMembership, Board
from mailinglists.models import MailingList
from members.models import Member
class CommitteeMembersTest(TestCase):
......@@ -15,7 +15,7 @@ class CommitteeMembersTest(TestCase):
@classmethod
def setUpTestData(cls):
cls.testcie = Committee.objects.get(pk=1)
cls.testuser = User.objects.get(pk=1)
cls.testuser = Member.objects.get(pk=1)
cls.m = CommitteeMembership.objects.create(
committee=cls.testcie,
member=cls.testuser,
......@@ -35,7 +35,7 @@ class CommitteeMembersTest(TestCase):
photo="")
def test_join(self):
testuser2 = User.objects.get(pk=2)
testuser2 = Member.objects.get(pk=2)
m = CommitteeMembership(committee=self.testcie,
member=testuser2)
m.full_clean()
......@@ -95,8 +95,8 @@ class CommitteeMembersChairTest(TestCase):
@classmethod
def setUpTestData(cls):
cls.testcie = Committee.objects.get(pk=1)
cls.testuser = User.objects.get(pk=1)
cls.testuser2 = User.objects.get(pk=2)
cls.testuser = Member.objects.get(pk=1)
cls.testuser2 = Member.objects.get(pk=2)
def setUp(self):
self.m1 = CommitteeMembership(committee=self.testcie,
......@@ -134,11 +134,11 @@ class PermissionsBackendTest(TestCase):
@classmethod
def setUpTestData(cls):
cls.u1 = User.objects.get(pk=1)
cls.u1 = Member.objects.get(pk=1)
cls.u1.is_superuser = False
cls.u1.save()
cls.u2 = User.objects.get(pk=2)
cls.u3 = User.objects.get(pk=3)
cls.u2 = Member.objects.get(pk=2)
cls.u3 = Member.objects.get(pk=3)
cls.c1 = Committee.objects.get(pk=1)
cls.c2 = Committee.objects.get(pk=2)
cls.m1 = CommitteeMembership.objects.create(committee=cls.c1,
......@@ -152,7 +152,7 @@ class PermissionsBackendTest(TestCase):
self.assertEqual(set(), self.u3.get_all_permissions())
def test_nonmember_user(self):
u = get_user_model().objects.create(username='foo')
u = User.objects.create(username='foo')
self.assertEqual(set(), u.get_all_permissions())
......
# -*- coding: utf-8 -*-
# Generated by Django 1.11.6 on 2017-10-13 13:35
from __future__ import unicode_literals
from django.db import migrations, models
import django.db.models.deletion
class Migration(migrations.Migration):
dependencies = [
('members', '0018_create_proxy_member'),
('education', '0005_auto_20170906_2109'),
]
operations = [
migrations.AlterField(
model_name='exam',
name='uploader',
field=models.ForeignKey(on_delete=django.db.models.deletion.CASCADE, to='members.Member', verbose_name='uploader'),
),
migrations.AlterField(
model_name='summary',
name='uploader',
field=models.ForeignKey(on_delete=django.db.models.deletion.CASCADE, to='members.Member', verbose_name='uploader'),
),
]
from django.conf import settings
from django.db import models
from django.urls import reverse
from django.utils import timezone
from django.utils.translation import ugettext_lazy as _
from members.models import Member
from utils.snippets import datetime_to_lectureyear
from utils.translation import ModelTranslateMeta, MultilingualField
......@@ -103,7 +103,7 @@ class Exam(models.Model, metaclass=ModelTranslateMeta):
)
uploader = models.ForeignKey(
settings.AUTH_USER_MODEL,
Member,
verbose_name=_('uploader'),
on_delete=models.CASCADE,
)
......@@ -159,7 +159,7 @@ class Summary(models.Model, metaclass=ModelTranslateMeta):
)
uploader = models.ForeignKey(
settings.AUTH_USER_MODEL,
Member,
verbose_name=_('uploader'),
on_delete=models.CASCADE,
)
......
......@@ -76,7 +76,7 @@ def submit_exam(request, id=None):
if form.is_valid():
saved = True
obj = form.save(commit=False)
obj.uploader = request.user
obj.uploader = request.member
obj.uploader_date = datetime.now()
obj.save()
......@@ -101,18 +101,18 @@ def submit_summary(request, id=None):
if form.is_valid():
saved = True
obj = form.save(commit=False)
obj.uploader = request.user
obj.uploader = request.member
obj.uploader_date = datetime.now()
obj.save()
obj = Summary()
obj.author = request.user.get_full_name()
obj.author = request.member.get_full_name()
form = AddSummaryForm(instance=obj)
else:
obj = Summary()
if id is not None:
obj.course = Course.objects.get(id=id)
obj.author = request.user.get_full_name()
obj.author = request.member.get_full_name()
form = AddSummaryForm(instance=obj)
return render(request, 'education/add_summary.html',
......
# -*- coding: utf-8 -*-
from django.contrib import admin
from django.contrib.auth.models import User
from django.http import HttpResponseRedirect
from django.template.defaultfilters import date as _date
from django.urls import reverse
......@@ -74,7 +73,7 @@ class EventAdmin(DoNextModelAdmin):
def has_change_permission(self, request, event=None):
if (event is not None and
not services.is_organiser(request.user, event)):
not services.is_organiser(request.member, event)):
return False
return super().has_change_permission(request, event)
......@@ -111,13 +110,10 @@ class EventAdmin(DoNextModelAdmin):
@staticmethod
def _change_published(request, queryset, published):
try:
if not request.user.is_superuser:
queryset = queryset.filter(
organiser__in=request.user.member.get_committees())
queryset.update(published=published)
except Member.DoesNotExist:
pass
if not request.user.is_superuser:
queryset = queryset.filter(
organiser__in=request.member.get_committees())
queryset.update(published=published)
def save_formset(self, request, form, formset, change):
"""Save formsets with their order"""
......@@ -144,13 +140,9 @@ class EventAdmin(DoNextModelAdmin):
if db_field.name == 'organiser':
# Use custom queryset for organiser field
# Only get the current active committees the user is a member of
try:
if not (request.user.is_superuser or
request.user.has_perm('events.override_organiser')):
kwargs['queryset'] = request.user.member.get_committees()
except Member.DoesNotExist:
pass
if not (request.user.is_superuser or
request.user.has_perm('events.override_organiser')):
kwargs['queryset'] = request.member.get_committees()
return super().formfield_for_foreignkey(db_field, request, **kwargs)
def get_actions(self, request):
......@@ -179,6 +171,5 @@ class RegistrationAdmin(DoNextModelAdmin):
kwargs['queryset'] = models.Event.objects.filter(
pk=int(request.GET['event_pk']))
elif db_field.name == 'member':
# TODO: Member.active_members.all()
kwargs['queryset'] = User.objects.all()
kwargs['queryset'] = Member.active_members.all()
return super().formfield_for_foreignkey(db_field, request, **kwargs)
......@@ -95,7 +95,7 @@ def export(request, event_id):
_('Date'): timezone.localtime(
registration.date).strftime("%Y-%m-%d %H:%m"),
_('Present'): _('Yes') if registration.present else '',
_('Phone number'): (registration.member.member.phone_number
_('Phone number'): (registration.member.profile.phone_number
if registration.member
else ''),
_('Email'): (registration.member.email
......
......@@ -77,7 +77,8 @@ class EventCalenderJSSerializer(CalenderJSSerializer):
def _registered(self, instance):
try:
return services.is_user_registered(instance, self.context['user'])
return services.is_user_registered(instance,
self.context['member'])
except AttributeError:
return None
......@@ -155,16 +156,15 @@ class EventRetrieveSerializer(serializers.ModelSerializer):
def _user_registration(self, instance):
try:
reg = instance.registration_set.get(
member=self.context['request'].user)
member=self.context['request'].member)
return RegistrationListSerializer(reg, context=self.context).data
except Registration.DoesNotExist:
return None
def _registration_allowed(self, instance):
user = self.context['request'].user
return (user.member is not None and
user.member.current_membership is not None and
user.member.can_attend_events)
member = self.context['request'].member
return (member.has_active_membership and
member.can_attend_events)
def _has_fields(self, instance):
return instance.has_fields()
......@@ -228,13 +228,13 @@ class RegistrationListSerializer(serializers.ModelSerializer):
def _name(self, instance):
if instance.member:
return instance.member.member.display_name()
return instance.member.profile.display_name()
return instance.name
def _photo(self, instance):
if instance.member and instance.member.member.photo:
if instance.member and instance.member.profile.photo:
return self.context['request'].build_absolute_uri(
'%s%s' % (settings.MEDIA_URL, instance.member.member.photo))
'%s%s' % (settings.MEDIA_URL, instance.member.profile.photo))
else:
return self.context['request'].build_absolute_uri(
static('members/images/default-avatar.jpg'))
......@@ -278,13 +278,13 @@ class RegistrationSerializer(serializers.ModelSerializer):
def _name(self, instance):
if instance.member:
return instance.member.member.display_name()
return instance.member.profile.display_name()
return instance.name
def _photo(self, instance):
if instance.member and instance.member.member.photo:
if instance.member and instance.member.profile.photo:
return self.context['request'].build_absolute_uri(
'%s%s' % (settings.MEDIA_URL, instance.member.photo))
'%s%s' % (settings.MEDIA_URL, instance.profile.photo))
else:
return self.context['request'].build_absolute_uri(
static('members/images/default-avatar.jpg'))
......
......@@ -63,7 +63,7 @@ class EventViewset(viewsets.ReadOnlyModelViewSet):
if request.method.lower() == 'post':
try:
registration = services.create_registration(
request.user, event)
request.member, event)
serializer = RegistrationSerializer(
instance=registration,
context={'request': request}
......@@ -76,7 +76,7 @@ class EventViewset(viewsets.ReadOnlyModelViewSet):
# Make sure you can only access other registrations when you have
# the permissions to do so
if not services.is_organiser(request.user, event):
if not services.is_organiser(request.member, event):
status = 'registered'
queryset = Registration.objects.filter(event=pk)
......@@ -106,8 +106,8 @@ class EventViewset(viewsets.ReadOnlyModelViewSet):
published=True
)
serializer = EventCalenderJSSerializer(queryset, many=True,
context={'user': request.user})
serializer = EventCalenderJSSerializer(
queryset, many=True, context={'member': request.member})
return Response(serializer.data)
@list_route(permission_classes=(IsAdminUser, UnpublishedEventPermissions,))
......@@ -120,8 +120,8 @@ class EventViewset(viewsets.ReadOnlyModelViewSet):
published=False
)
serializer = UnpublishedEventSerializer(queryset, many=True,
context={'user': request.user})
serializer = UnpublishedEventSerializer(
queryset, many=True, context={'member': request.member})
return Response(serializer.data)
......@@ -138,8 +138,8 @@ class RegistrationViewSet(GenericViewSet, RetrieveModelMixin,
def get_object(self):
instance = super().get_object()
if (instance.member.pk != self.request.user.pk and
not services.is_organiser(self.request.user,
if (instance.member.pk != self.request.member.pk and
not services.is_organiser(self.request.member,
instance.event)):
raise NotFound()
......
......@@ -21,7 +21,7 @@ class OrganiserOnly(object):
except Event.DoesNotExist:
pass
if event and services.is_organiser(request.user, event):
if event and services.is_organiser(request.member, event):
return self.view_function(request, *args, **kwargs)
raise PermissionDenied
......@@ -4,7 +4,7 @@ from django.utils import translation
from django.utils.translation import ugettext_lazy as _
from events.models import Registration
from members.models import Member
from members.models import Profile
from thaliawebsite.templatetags import baseurl
......@@ -21,10 +21,10 @@ def notify_first_waiting(request, event):
text_template = get_template('events/member_email.txt')
if first_waiting_member.member:
if first_waiting_member.profile:
language = first_waiting_member.member.language
else:
language = Member._meta.get_field('language').default
language = Profile._meta.get_field('language').default
with translation.override(language):
subject = _("[THALIA] Notification about your "
......
# -*- coding: utf-8 -*-
# Generated by Django 1.11.6 on 2017-10-13 12:19
from __future__ import unicode_literals
from django.db import migrations, models
import django.db.models.deletion
class Migration(migrations.Migration):
dependencies = [
('members', '0018_create_proxy_member'),
('events', '0020_4_user_foreign_keys'),
]
operations = [
migrations.AlterField(
model_name='registration',
name='member',
field=models.ForeignKey(blank=True, null=True, on_delete=django.db.models.deletion.CASCADE, to='members.Member'),
),
]
from django.contrib.auth.models import User
from django.core import validators
from django.core.exceptions import ValidationError
from django.db import models
......@@ -274,7 +273,7 @@ class Registration(models.Model):
event = models.ForeignKey(Event, models.CASCADE)
member = models.ForeignKey(
User, models.CASCADE,
'members.Member', models.CASCADE,
blank=True,
null=True,
limit_choices_to=(Q(membership__until__isnull=True) |
......
......@@ -6,27 +6,27 @@ from events.exceptions import RegistrationError
from events.models import Registration, RegistrationInformationField
def is_user_registered(event, user):
def is_user_registered(event, member):
if not event.registration_required:
return None
return event.registrations.filter(
member=user,
member=member,
date_cancelled=None).count() > 0
def event_permissions(user, event):
def event_permissions(member, event):
perms = {
"create_registration": False,
"cancel_registration": False,
"update_registration": False,
}
if user.is_authenticated and user.member.can_attend_events:
if member.is_authenticated and member.can_attend_events:
registration = None
try:
registration = Registration.objects.get(
event=event,
member=user
member=member
)
except Registration.DoesNotExist:
pass
......@@ -46,27 +46,27 @@ def event_permissions(user, event):
return perms
def is_organiser(user, event):
if user.is_superuser or user.has_perm("events.override_organiser"):
def is_organiser(member, event):
if member.is_superuser or member.has_perm("events.override_organiser"):
return True
if event and user.has_perm('events.change_event'):
if event and member.has_perm('events.change_event'):
committees = 0
if event is not None:
committees = user.member.get_committees().filter(
committees = member.get_committees().filter(
pk=event.organiser.pk).count()
return committees != 0
return False
def create_registration(user, event):
if event_permissions(user, event)["create_registration"]:
def create_registration(member, event):
if event_permissions(member, event)["create_registration"]:
registration = None
try:
registration = Registration.objects.get(
event=event,
member=user
member=member
)
except Registration.DoesNotExist:
pass
......@@ -74,7 +74,7 @@ def create_registration(user, event):
if registration is None:
return Registration.objects.create(
event=event,
member=user
member=member
)
elif registration.date_cancelled is not None:
if registration.is_late_cancellation():
......@@ -87,23 +87,24 @@ def create_registration(user, event):
registration.save()
return registration
elif event_permissions(user, event)["cancel_registration"]:
elif event_permissions(member, event)["cancel_registration"]:
raise RegistrationError(_("You were already registered."))
else:
raise RegistrationError(_("You may not register."))
def cancel_registration(request, user, event):
def cancel_registration(request, member, event):
registration = None
try:
registration = Registration.objects.get(
event=event,
member=user
member=member
)