202 lines
6.7 KiB
Python
202 lines
6.7 KiB
Python
"""
|
|
The functions in this file are used to check *user* permissions.
|
|
|
|
There are two kinds of permission systems in use. One of them is defined in this
|
|
file, the other is the Django permission system (accessed by `User.has_perm`).
|
|
The system in this file describe the permissions for the user of the website and
|
|
thus we call this one the *user* permission system. And the Django permission
|
|
system is used to describe the permissions of the admins/staff/moderators and
|
|
thus we call this system the *admin* permission system.
|
|
|
|
The reason for this distinction is that the Django permission system is used by
|
|
the admin interface and consequently is designed for global permissions like
|
|
"This user can update Events", and not per se for granular permissions of the
|
|
form "This user can update Events that he/she owns". To have the best of both
|
|
worlds we basically extend the Django permission system with more granular
|
|
fallbacks.
|
|
|
|
So per *user* permissions we define a function in this file. If there is a
|
|
relevant permission in the Django/admin permission system we check that first,
|
|
and failing that defer to more granular logic.
|
|
"""
|
|
from django.contrib.auth.models import User
|
|
|
|
from conference_main.models import Edition, Event, FestivalEntry, Profile, FestivalEntryFinalVotes
|
|
import tickets.queries
|
|
|
|
|
|
def can_view_event(event: Event, user: User) -> bool:
|
|
if user.has_perm('can_view_event'):
|
|
# User has Model-level permission
|
|
return True
|
|
elif event.user == user:
|
|
# User is the submitter of the event
|
|
return True
|
|
elif event.status in ('accepted', 'cancelled') and event.edition.speakers_viewable:
|
|
# The event is 'public' and the speaker list is 'public'
|
|
return True
|
|
else:
|
|
return False
|
|
|
|
|
|
def can_add_event(edition: Edition, user: User) -> bool:
|
|
if user.has_perm('can_add_event'):
|
|
return True
|
|
else:
|
|
# NOTE: We ignore `edition.presentation_submissions_open` because from past experience we
|
|
# know that being able to send users who were too late with submissions a link to the
|
|
# submission form is really handy.
|
|
return not edition.is_archived
|
|
|
|
|
|
def can_change_event(event: Event, user: User) -> bool:
|
|
if user.has_perm('can_change_event'):
|
|
return True
|
|
elif event.user == user:
|
|
return not event.edition.is_archived
|
|
else:
|
|
return False
|
|
|
|
|
|
def can_view_messages_on_event(event: Event, user: User) -> bool:
|
|
if user.has_perm('can_view_message'):
|
|
return True
|
|
elif event.user == user:
|
|
return True
|
|
else:
|
|
return False
|
|
|
|
|
|
def can_add_message_to_event(event: Event, user: User) -> bool:
|
|
if user.has_perm('can_add_message'):
|
|
return True
|
|
elif event.user == user:
|
|
return not event.edition.is_archived
|
|
else:
|
|
return False
|
|
|
|
|
|
def can_view_festival_entry(event: FestivalEntry, user: User) -> bool:
|
|
if user.has_perm('can_view_festival_entry'):
|
|
return True
|
|
elif event.user == user:
|
|
return True
|
|
elif event.status in ('accepted', 'winner'):
|
|
return True
|
|
else:
|
|
return False
|
|
|
|
|
|
def can_add_festival_entry(edition: Edition, user: User) -> bool:
|
|
if user.has_perm('can_add_festival_entry'):
|
|
return True
|
|
else:
|
|
# NOTE: We ignore `edition.presentation_submissions_open` because from past experience we
|
|
# know that being able to send users who were too late with submissions a link to the
|
|
# submission form is really handy.
|
|
return not edition.is_archived
|
|
|
|
|
|
def can_change_festival_entry(festival_entry: FestivalEntry, user: User) -> bool:
|
|
if user.has_perm('can_change_festival_entry'):
|
|
return True
|
|
elif festival_entry.user == user:
|
|
return not festival_entry.edition.is_archived
|
|
else:
|
|
return False
|
|
|
|
|
|
def can_view_messages_on_festival_entry(festival_entry: FestivalEntry, user: User) -> bool:
|
|
if user.has_perm('can_view_message'):
|
|
return True
|
|
elif festival_entry.user == user:
|
|
return True
|
|
else:
|
|
return False
|
|
|
|
|
|
def can_add_message_to_festival_entry(festival_entry: FestivalEntry, user: User) -> bool:
|
|
if user.has_perm('can_add_message'):
|
|
return True
|
|
elif festival_entry.user == user:
|
|
return not festival_entry.edition.is_archived
|
|
else:
|
|
return False
|
|
|
|
|
|
def can_vote_on_festival_entry(festival_entry: FestivalEntry, user: User) -> bool:
|
|
if user.has_perm('can_add_festival_entry_votes'):
|
|
return True
|
|
elif festival_entry.user.is_anonymous:
|
|
# Users need to be logged in to be able to vote.
|
|
return False
|
|
elif festival_entry.user == user:
|
|
# Users cannot vote on their own entry.
|
|
return False
|
|
elif festival_entry.status not in ('accepted', 'winner'):
|
|
# Users cannot vote on non-accepted entries.
|
|
return False
|
|
else:
|
|
return (
|
|
not festival_entry.edition.is_archived and festival_entry.edition.festival_voting_open
|
|
)
|
|
|
|
|
|
def can_vote_on_festival_entry_final(festival_entry: FestivalEntry, user: User) -> bool:
|
|
if not can_vote_on_festival_entry(festival_entry, user):
|
|
return False
|
|
if festival_entry.status not in {'nominated'}:
|
|
# Users cannot vote on entries which weren't nominated for finals.
|
|
return False
|
|
# Cannot vote if already voted for this edition
|
|
if FestivalEntryFinalVotes.objects.filter(
|
|
user=user, festival__edition_id=festival_entry.edition_id
|
|
).exists():
|
|
return False
|
|
return True
|
|
|
|
|
|
def can_view_schedule(edition: Edition, user: User) -> bool:
|
|
if user.is_superuser:
|
|
return True
|
|
else:
|
|
return edition.schedule_status in (Edition.SCHEDULE_PROPOSED, Edition.SCHEDULE_FINAL)
|
|
|
|
|
|
def can_view_speakers(edition: Edition, user: User) -> bool:
|
|
if user.is_superuser:
|
|
return True
|
|
else:
|
|
return edition.speakers_viewable
|
|
|
|
|
|
def can_view_attendees(edition: Edition, user: User) -> bool:
|
|
"""Allow attendees and admins view attendees list."""
|
|
if user.is_superuser:
|
|
return True
|
|
if tickets.queries.is_attending_edition(user, edition) and edition.attendees_viewable:
|
|
return True
|
|
return False
|
|
|
|
|
|
def can_view_profile(profile: Profile, user: User) -> bool:
|
|
if user.is_superuser:
|
|
return True
|
|
elif profile.user == user:
|
|
return True
|
|
else:
|
|
return profile.events.filter(status='accepted', edition__speakers_viewable=True).exists()
|
|
|
|
|
|
def can_add_flatfile(user: User) -> bool:
|
|
return user.has_perm('can_add_flatfile')
|
|
|
|
|
|
def can_upload_photos(album, user: User) -> bool:
|
|
"""Allow attendees and admins upload new photos."""
|
|
if user.is_superuser:
|
|
return True
|
|
if album.is_upload_open and tickets.queries.is_attending_edition(user, album.edition):
|
|
return True
|
|
return False
|