2017-12-19 12:58:28 +01:00
|
|
|
|
import string
|
2017-12-08 17:08:33 +01:00
|
|
|
|
from functools import wraps
|
|
|
|
|
|
2017-12-08 18:41:48 +01:00
|
|
|
|
from django.contrib import messages
|
2017-12-08 17:08:33 +01:00
|
|
|
|
from django.contrib.auth.decorators import login_required
|
2017-12-08 17:42:32 +01:00
|
|
|
|
from django.contrib.auth.models import User
|
2017-12-08 17:08:33 +01:00
|
|
|
|
from django.core.exceptions import PermissionDenied
|
2017-12-08 17:42:32 +01:00
|
|
|
|
from django.core.paginator import Paginator
|
2017-12-10 03:49:21 +01:00
|
|
|
|
from django.db import transaction
|
2017-12-08 21:31:53 +01:00
|
|
|
|
from django.db.models import Prefetch
|
2017-12-08 18:41:48 +01:00
|
|
|
|
from django.shortcuts import get_object_or_404, redirect, render
|
2017-12-10 03:49:21 +01:00
|
|
|
|
from django.urls import reverse
|
2017-12-19 12:58:28 +01:00
|
|
|
|
from django.utils.crypto import get_random_string
|
2017-12-08 18:41:48 +01:00
|
|
|
|
from django.utils.translation import ugettext_lazy as _
|
|
|
|
|
|
2017-12-10 15:23:53 +01:00
|
|
|
|
from c3nav.control.forms import AccessPermissionForm, AnnouncementForm, UserPermissionsForm
|
2017-12-08 18:41:48 +01:00
|
|
|
|
from c3nav.control.models import UserPermissions
|
2017-12-10 03:49:21 +01:00
|
|
|
|
from c3nav.mapdata.models.access import AccessPermission, AccessPermissionToken
|
2017-12-10 15:23:53 +01:00
|
|
|
|
from c3nav.site.models import Announcement
|
2017-12-08 15:21:33 +01:00
|
|
|
|
|
|
|
|
|
|
2017-12-08 17:08:33 +01:00
|
|
|
|
def control_panel_view(func):
|
|
|
|
|
@wraps(func)
|
2017-12-08 17:42:32 +01:00
|
|
|
|
def wrapped_func(request, *args, **kwargs):
|
2017-12-08 17:08:33 +01:00
|
|
|
|
if not request.user_permissions.control_panel:
|
|
|
|
|
raise PermissionDenied
|
2017-12-08 17:42:32 +01:00
|
|
|
|
return func(request, *args, **kwargs)
|
2017-12-08 17:08:33 +01:00
|
|
|
|
return login_required(login_url='site.login')(wrapped_func)
|
|
|
|
|
|
|
|
|
|
|
2017-12-18 21:01:55 +01:00
|
|
|
|
@login_required(login_url='site.login')
|
2017-12-08 17:08:33 +01:00
|
|
|
|
@control_panel_view
|
2017-12-08 15:21:33 +01:00
|
|
|
|
def main_index(request):
|
|
|
|
|
return render(request, 'control/index.html', {})
|
2017-12-08 17:42:32 +01:00
|
|
|
|
|
|
|
|
|
|
2017-12-18 21:01:55 +01:00
|
|
|
|
@login_required(login_url='site.login')
|
2017-12-08 17:42:32 +01:00
|
|
|
|
@control_panel_view
|
|
|
|
|
def user_list(request):
|
|
|
|
|
search = request.GET.get('s')
|
|
|
|
|
page = request.GET.get('page', 1)
|
|
|
|
|
|
|
|
|
|
queryset = User.objects.order_by('id')
|
|
|
|
|
if search:
|
|
|
|
|
queryset = queryset.filter(username__icontains=search.strip())
|
|
|
|
|
|
|
|
|
|
paginator = Paginator(queryset, 20)
|
|
|
|
|
users = paginator.page(page)
|
|
|
|
|
|
|
|
|
|
return render(request, 'control/users.html', {
|
|
|
|
|
'users': users,
|
|
|
|
|
})
|
2017-12-08 18:41:48 +01:00
|
|
|
|
|
|
|
|
|
|
2017-12-18 21:01:55 +01:00
|
|
|
|
@login_required(login_url='site.login')
|
2017-12-08 18:41:48 +01:00
|
|
|
|
@control_panel_view
|
|
|
|
|
def user_detail(request, user):
|
2017-12-08 21:31:53 +01:00
|
|
|
|
qs = User.objects.select_related(
|
|
|
|
|
'permissions',
|
|
|
|
|
).prefetch_related(
|
2017-12-19 12:17:48 +01:00
|
|
|
|
Prefetch('accesspermissions', AccessPermission.objects.select_related('access_restriction', 'author'))
|
2017-12-08 21:31:53 +01:00
|
|
|
|
)
|
2017-12-08 18:41:48 +01:00
|
|
|
|
user = get_object_or_404(qs, pk=user)
|
|
|
|
|
|
2017-12-08 22:18:05 +01:00
|
|
|
|
if request.method == 'POST':
|
|
|
|
|
delete_access_permission = request.POST.get('delete_access_permission')
|
|
|
|
|
if delete_access_permission:
|
2017-12-19 12:17:48 +01:00
|
|
|
|
with transaction.atomic():
|
|
|
|
|
try:
|
|
|
|
|
permission = AccessPermission.objects.select_for_update().get(pk=delete_access_permission)
|
|
|
|
|
except AccessPermission.DoesNotExist:
|
|
|
|
|
messages.error(request, _('Unknown access permission.'))
|
|
|
|
|
else:
|
2017-12-19 12:29:50 +01:00
|
|
|
|
if request.user_permissions.grant_all_access or permission.author_id == request.user.pk:
|
2017-12-19 12:17:48 +01:00
|
|
|
|
permission.delete()
|
|
|
|
|
messages.success(request, _('Access Permission successfully deleted.'))
|
|
|
|
|
else:
|
|
|
|
|
messages.error(request, _('You cannot delete this Access Permission.'))
|
|
|
|
|
return redirect(request.path_info)
|
2017-12-08 22:18:05 +01:00
|
|
|
|
|
2017-12-19 12:58:28 +01:00
|
|
|
|
api_secret_action = request.POST.get('api_secret')
|
|
|
|
|
if (api_secret_action and (request.user_permissions.grant_permissions or
|
|
|
|
|
request.user == user and user.permissions.api_secret)):
|
|
|
|
|
|
|
|
|
|
permissions = user.permissions
|
|
|
|
|
|
|
|
|
|
if api_secret_action == 'generate' and permissions.api_secret:
|
|
|
|
|
messages.error(request, _('This user already has an API secret.'))
|
|
|
|
|
return redirect(request.path_info)
|
|
|
|
|
|
|
|
|
|
if api_secret_action in ('delete', 'regenerate') and not permissions.api_secret:
|
|
|
|
|
messages.error(request, _('This user does not have an API secret.'))
|
|
|
|
|
return redirect(request.path_info)
|
|
|
|
|
|
|
|
|
|
with transaction.atomic():
|
|
|
|
|
if api_secret_action in ('generate', 'regenerate'):
|
|
|
|
|
api_secret = get_random_string(64, string.ascii_letters+string.digits)
|
|
|
|
|
permissions.api_secret = api_secret
|
|
|
|
|
permissions.save()
|
|
|
|
|
|
|
|
|
|
messages.success(request, _('The new API secret is: %s – '
|
|
|
|
|
'be sure to note it down now, it won\'t be shown again.') % api_secret)
|
|
|
|
|
|
|
|
|
|
elif api_secret_action == 'delete':
|
|
|
|
|
permissions.api_secret = None
|
|
|
|
|
permissions.save()
|
|
|
|
|
|
|
|
|
|
messages.success(request, _('API secret successfully deleted!'))
|
|
|
|
|
|
|
|
|
|
return redirect(request.path_info)
|
|
|
|
|
|
2017-12-08 18:41:48 +01:00
|
|
|
|
ctx = {
|
|
|
|
|
'user': user,
|
|
|
|
|
}
|
|
|
|
|
|
|
|
|
|
# user permissions
|
|
|
|
|
try:
|
|
|
|
|
permissions = user.permissions
|
|
|
|
|
except AttributeError:
|
|
|
|
|
permissions = UserPermissions(user=user)
|
|
|
|
|
ctx.update({
|
|
|
|
|
'user_permissions': tuple(
|
|
|
|
|
field.verbose_name for field in UserPermissions._meta.get_fields()
|
|
|
|
|
if not field.one_to_one and getattr(permissions, field.attname)
|
|
|
|
|
)
|
|
|
|
|
})
|
|
|
|
|
if request.user_permissions.grant_permissions:
|
|
|
|
|
if request.method == 'POST' and request.POST.get('submit_user_permissions'):
|
|
|
|
|
form = UserPermissionsForm(instance=permissions, data=request.POST)
|
|
|
|
|
if form.is_valid():
|
|
|
|
|
form.save()
|
|
|
|
|
messages.success(request, _('General permissions successfully updated.'))
|
|
|
|
|
return redirect(request.path_info)
|
|
|
|
|
else:
|
|
|
|
|
form = UserPermissionsForm(instance=permissions)
|
|
|
|
|
ctx.update({
|
|
|
|
|
'user_permissions_form': form
|
|
|
|
|
})
|
|
|
|
|
|
2017-12-08 21:31:53 +01:00
|
|
|
|
# access permissions
|
|
|
|
|
if request.method == 'POST' and request.POST.get('submit_access_permissions'):
|
|
|
|
|
form = AccessPermissionForm(request=request, data=request.POST)
|
|
|
|
|
if form.is_valid():
|
2017-12-10 03:16:07 +01:00
|
|
|
|
form.get_token().redeem(user)
|
|
|
|
|
messages.success(request, _('Access permissions successfully granted.'))
|
2017-12-08 21:31:53 +01:00
|
|
|
|
return redirect(request.path_info)
|
|
|
|
|
else:
|
|
|
|
|
form = AccessPermissionForm(request=request)
|
|
|
|
|
|
|
|
|
|
ctx.update({
|
2017-12-08 21:46:24 +01:00
|
|
|
|
'access_permission_form': form
|
2017-12-08 21:31:53 +01:00
|
|
|
|
})
|
|
|
|
|
|
2017-12-08 18:41:48 +01:00
|
|
|
|
return render(request, 'control/user.html', ctx)
|
2017-12-10 03:49:21 +01:00
|
|
|
|
|
|
|
|
|
|
2017-12-18 21:01:55 +01:00
|
|
|
|
@login_required(login_url='site.login')
|
2017-12-10 03:49:21 +01:00
|
|
|
|
@control_panel_view
|
|
|
|
|
def grant_access(request):
|
|
|
|
|
if request.method == 'POST' and request.POST.get('submit_access_permissions'):
|
|
|
|
|
form = AccessPermissionForm(request=request, data=request.POST)
|
|
|
|
|
if form.is_valid():
|
|
|
|
|
token = form.get_token()
|
|
|
|
|
token.save()
|
2017-12-18 14:57:57 +01:00
|
|
|
|
return redirect(reverse('control.access.qr', kwargs={'token': token.token}))
|
2017-12-10 03:49:21 +01:00
|
|
|
|
else:
|
|
|
|
|
form = AccessPermissionForm(request=request)
|
|
|
|
|
|
|
|
|
|
ctx = {
|
|
|
|
|
'access_permission_form': form
|
|
|
|
|
}
|
|
|
|
|
|
|
|
|
|
return render(request, 'control/access.html', ctx)
|
|
|
|
|
|
|
|
|
|
|
2017-12-18 21:01:55 +01:00
|
|
|
|
@login_required(login_url='site.login')
|
2017-12-10 03:49:21 +01:00
|
|
|
|
@control_panel_view
|
|
|
|
|
def grant_access_qr(request, token):
|
|
|
|
|
with transaction.atomic():
|
2017-12-18 14:54:45 +01:00
|
|
|
|
token = AccessPermissionToken.objects.select_for_update().get(token=token, author=request.user)
|
2017-12-10 03:49:21 +01:00
|
|
|
|
if token.redeemed:
|
2017-12-10 14:20:11 +01:00
|
|
|
|
messages.success(request, _('Access successfully granted.'))
|
2017-12-10 03:49:21 +01:00
|
|
|
|
token = None
|
2017-12-10 14:20:11 +01:00
|
|
|
|
elif request.method == 'POST' and request.POST.get('revoke'):
|
|
|
|
|
token.delete()
|
|
|
|
|
messages.success(request, _('Token successfully revoked.'))
|
|
|
|
|
return redirect('control.access')
|
2017-12-10 03:49:21 +01:00
|
|
|
|
elif not token.unlimited:
|
|
|
|
|
try:
|
|
|
|
|
latest = AccessPermissionToken.objects.filter(author=request.user).latest('valid_until')
|
|
|
|
|
except AccessPermissionToken.DoesNotExist:
|
|
|
|
|
token = None
|
|
|
|
|
else:
|
|
|
|
|
if latest.id != token.id:
|
|
|
|
|
token = None
|
|
|
|
|
if token is None:
|
2017-12-10 12:40:59 +01:00
|
|
|
|
messages.error(request, _('You can only display your most recently created token.'))
|
2017-12-10 03:49:21 +01:00
|
|
|
|
|
|
|
|
|
if token is None:
|
2017-12-10 14:13:20 +01:00
|
|
|
|
return redirect('control.access')
|
2017-12-10 03:49:21 +01:00
|
|
|
|
|
|
|
|
|
token.bump()
|
|
|
|
|
token.save()
|
|
|
|
|
|
2017-12-18 14:54:45 +01:00
|
|
|
|
url = reverse('site.access.redeem', kwargs={'token': str(token.token)})
|
2017-12-10 03:49:21 +01:00
|
|
|
|
return render(request, 'control/access_qr.html', {
|
2017-12-10 14:13:20 +01:00
|
|
|
|
'url': url,
|
|
|
|
|
'url_qr': reverse('site.qr', kwargs={'path': url}),
|
|
|
|
|
'url_absolute': request.build_absolute_uri(url),
|
2017-12-10 03:49:21 +01:00
|
|
|
|
})
|
2017-12-10 15:23:53 +01:00
|
|
|
|
|
|
|
|
|
|
2017-12-18 21:01:55 +01:00
|
|
|
|
@login_required(login_url='site.login')
|
2017-12-10 15:23:53 +01:00
|
|
|
|
@control_panel_view
|
|
|
|
|
def announcement_list(request):
|
|
|
|
|
if not request.user_permissions.manage_announcements:
|
|
|
|
|
raise PermissionDenied
|
|
|
|
|
|
2017-12-10 15:25:03 +01:00
|
|
|
|
announcements = Announcement.objects.order_by('-created')
|
2017-12-10 15:23:53 +01:00
|
|
|
|
|
|
|
|
|
if request.method == 'POST':
|
|
|
|
|
form = AnnouncementForm(data=request.POST)
|
|
|
|
|
if form.is_valid():
|
|
|
|
|
announcement = form.instance
|
|
|
|
|
announcement = request.user
|
|
|
|
|
announcement.save()
|
|
|
|
|
return redirect('control.announcements')
|
|
|
|
|
else:
|
|
|
|
|
form = AnnouncementForm()
|
|
|
|
|
|
|
|
|
|
return render(request, 'control/announcements.html', {
|
|
|
|
|
'form': form,
|
|
|
|
|
'announcements': announcements,
|
|
|
|
|
})
|
|
|
|
|
|
|
|
|
|
|
2017-12-18 21:01:55 +01:00
|
|
|
|
@login_required(login_url='site.login')
|
2017-12-10 15:23:53 +01:00
|
|
|
|
@control_panel_view
|
|
|
|
|
def announcement_detail(request, announcement):
|
|
|
|
|
if not request.user_permissions.manage_announcements:
|
|
|
|
|
raise PermissionDenied
|
|
|
|
|
|
|
|
|
|
announcement = get_object_or_404(Announcement, pk=announcement)
|
|
|
|
|
|
|
|
|
|
if request.method == 'POST':
|
|
|
|
|
form = AnnouncementForm(instance=announcement, data=request.POST)
|
|
|
|
|
if form.is_valid():
|
|
|
|
|
form.save()
|
|
|
|
|
return redirect('control.announcements')
|
|
|
|
|
else:
|
|
|
|
|
form = AnnouncementForm(instance=announcement)
|
|
|
|
|
|
|
|
|
|
return render(request, 'control/announcement.html', {
|
|
|
|
|
'form': form,
|
|
|
|
|
'announcement': announcement,
|
|
|
|
|
})
|