Merge branch 'v2-dev' of https://github.com/allianceauth/allianceauth into sso_registration

This commit is contained in:
Adarnof 2017-10-04 23:43:57 -04:00
commit f121ed4062
12 changed files with 124 additions and 145 deletions

View File

@ -5,14 +5,12 @@ import random
import string import string
from allianceauth.authentication.models import CharacterOwnership from allianceauth.authentication.models import CharacterOwnership
from django.conf import settings
from django.contrib import messages from django.contrib import messages
from django.contrib.auth.decorators import login_required from django.contrib.auth.decorators import login_required
from django.contrib.auth.decorators import permission_required from django.contrib.auth.decorators import permission_required
from django.contrib.auth.models import User from django.contrib.auth.models import User
from django.core.exceptions import ValidationError, ObjectDoesNotExist from django.core.exceptions import ValidationError, ObjectDoesNotExist
from django.core.paginator import Paginator, EmptyPage, PageNotAnInteger from django.shortcuts import render, redirect, get_object_or_404, Http404
from django.shortcuts import render, redirect, get_object_or_404
from django.utils import timezone from django.utils import timezone
from django.utils.translation import ugettext_lazy as _ from django.utils.translation import ugettext_lazy as _
from esi.decorators import token_required from esi.decorators import token_required
@ -83,9 +81,9 @@ def fatlink_view(request):
user = request.user user = request.user
logger.debug("fatlink_view called by user %s" % request.user) logger.debug("fatlink_view called by user %s" % request.user)
latest_fats = Fat.objects.filter(user=user).order_by('-id')[:5] latest_fats = Fat.objects.select_related('character', 'fatlink').filter(user=user).order_by('-id')[:5]
if user.has_perm('auth.fleetactivitytracking'): if user.has_perm('auth.fleetactivitytracking'):
latest_links = Fatlink.objects.all().order_by('-id')[:5] latest_links = Fatlink.objects.select_related('creator').all().order_by('-id')[:5]
context = {'user': user, 'fats': latest_fats, 'fatlinks': latest_links} context = {'user': user, 'fats': latest_fats, 'fatlinks': latest_links}
else: else:
@ -173,7 +171,7 @@ def fatlink_personal_statistics_view(request, year=datetime.date.today().year):
user = request.user user = request.user
logger.debug("fatlink_personal_statistics_view called by user %s" % request.user) logger.debug("fatlink_personal_statistics_view called by user %s" % request.user)
personal_fats = Fat.objects.filter(user=user).order_by('id') personal_fats = Fat.objects.select_related('fatlink').filter(user=user).order_by('id')
monthlystats = [0 for month in range(1, 13)] monthlystats = [0 for month in range(1, 13)]
@ -207,8 +205,8 @@ def fatlink_monthly_personal_statistics_view(request, year, month, char_id=None)
user = request.user user = request.user
logger.debug("Personal monthly statistics view for user %s called by %s" % (user, request.user)) logger.debug("Personal monthly statistics view for user %s called by %s" % (user, request.user))
personal_fats = Fat.objects.filter(user=user).filter(fatlink__fatdatetime__gte=start_of_month).filter( personal_fats = Fat.objects.filter(user=user)\
fatlink__fatdatetime__lt=start_of_next_month) .filter(fatlink__fatdatetime__gte=start_of_month).filter(fatlink__fatdatetime__lt=start_of_next_month)
ship_statistics = dict() ship_statistics = dict()
n_fats = 0 n_fats = 0
@ -330,7 +328,10 @@ def modify_fatlink_view(request, hash=""):
if not hash: if not hash:
return redirect('fatlink:view') return redirect('fatlink:view')
fatlink = Fatlink.objects.filter(hash=hash)[0] try:
fatlink = Fatlink.objects.get(hash=hash)
except Fatlink.DoesNotExist:
raise Http404
if request.GET.get('removechar', None): if request.GET.get('removechar', None):
character_id = request.GET.get('removechar') character_id = request.GET.get('removechar')
@ -344,7 +345,8 @@ def modify_fatlink_view(request, hash=""):
fatlink.delete() fatlink.delete()
return redirect('fatlink:view') return redirect('fatlink:view')
registered_fats = Fat.objects.filter(fatlink=fatlink).order_by('character__character_name') registered_fats = Fat.objects.select_related('character', 'fatlink', 'user')\
.filter(fatlink=fatlink).order_by('character__character_name')
context = {'fatlink': fatlink, 'registered_fats': registered_fats} context = {'fatlink': fatlink, 'registered_fats': registered_fats}

View File

@ -7,11 +7,11 @@ class GroupManager:
@staticmethod @staticmethod
def get_joinable_groups(): def get_joinable_groups():
return Group.objects.exclude(authgroup__internal=True) return Group.objects.select_related('authgroup').exclude(authgroup__internal=True)
@staticmethod @staticmethod
def get_group_leaders_groups(user): def get_group_leaders_groups(user):
return Group.objects.filter(authgroup__group_leaders__in=[user]) return Group.objects.select_related('authgroup').filter(authgroup__group_leaders__in=[user])
@staticmethod @staticmethod
def joinable_group(group): def joinable_group(group):

View File

@ -24,12 +24,13 @@ def group_management(request):
acceptrequests = [] acceptrequests = []
leaverequests = [] leaverequests = []
base_group_query = GroupRequest.objects.select_related('user', 'group')
if GroupManager.has_management_permission(request.user): if GroupManager.has_management_permission(request.user):
# Full access # Full access
group_requests = GroupRequest.objects.all() group_requests = base_group_query.all()
else: else:
# Group specific leader # Group specific leader
group_requests = GroupRequest.objects.filter(group__authgroup__group_leaders__in=[request.user]) group_requests = base_group_query.filter(group__authgroup__group_leaders__in=[request.user])
for grouprequest in group_requests: for grouprequest in group_requests:
if grouprequest.leave_request: if grouprequest.leave_request:
@ -83,7 +84,7 @@ def group_membership_list(request, group_id):
members = list() members = list()
for member in group.user_set.all().order_by('username'): for member in group.user_set.select_related('profile').all().order_by('username'):
members.append({ members.append({
'user': member, 'user': member,

View File

@ -2,7 +2,6 @@
{% load staticfiles %} {% load staticfiles %}
{% load bootstrap %} {% load bootstrap %}
{% load i18n %} {% load i18n %}
{% load eveonline_extras %}
{% block title %}Alliance Auth - {% trans "View Application" %}{% endblock %} {% block title %}Alliance Auth - {% trans "View Application" %}{% endblock %}
{% block page_title %}{% trans "View Application" %}{% endblock page_title %} {% block page_title %}{% trans "View Application" %}{% endblock page_title %}

View File

@ -3,7 +3,8 @@ import logging
from django.contrib.auth.decorators import login_required from django.contrib.auth.decorators import login_required
from django.contrib.auth.decorators import permission_required from django.contrib.auth.decorators import permission_required
from django.contrib.auth.decorators import user_passes_test from django.contrib.auth.decorators import user_passes_test
from django.shortcuts import render, get_object_or_404, redirect from django.shortcuts import render, get_object_or_404, redirect, Http404
from django.db.models import Q
from .models import Application from .models import Application
from .models import ApplicationComment from .models import ApplicationComment
from .models import ApplicationForm from .models import ApplicationForm
@ -26,14 +27,16 @@ def hr_application_management_view(request):
corp_applications = [] corp_applications = []
finished_corp_applications = [] finished_corp_applications = []
main_char = request.user.profile.main_character main_char = request.user.profile.main_character
base_app_query = Application.objects.select_related('user', 'form', 'form__corp')
if request.user.is_superuser: if request.user.is_superuser:
corp_applications = Application.objects.filter(approved=None) corp_applications = base_app_query.filter(approved=None)
finished_corp_applications = Application.objects.exclude(approved=None) finished_corp_applications = base_app_query.exclude(approved=None)
elif request.user.has_perm('auth.human_resources') and main_char: elif request.user.has_perm('auth.human_resources') and main_char:
if ApplicationForm.objects.filter(corp__corporation_id=main_char.corporation_id).exists(): if ApplicationForm.objects.filter(corp__corporation_id=main_char.corporation_id).exists():
app_form = ApplicationForm.objects.get(corp__corporation_id=main_char.corporation_id) app_form = ApplicationForm.objects.get(corp__corporation_id=main_char.corporation_id)
corp_applications = Application.objects.filter(form=app_form).filter(approved=None) corp_applications = base_app_query.filter(form=app_form).filter(approved=None)
finished_corp_applications = Application.objects.filter(form=app_form).filter(approved__in=[True, False]) finished_corp_applications = base_app_query.filter(form=app_form).filter(approved__in=[True, False])
logger.debug("Retrieved %s personal, %s corp applications for %s" % ( logger.debug("Retrieved %s personal, %s corp applications for %s" % (
len(request.user.applications.all()), len(corp_applications), request.user)) len(request.user.applications.all()), len(corp_applications), request.user))
context = { context = {
@ -63,7 +66,7 @@ def hr_application_create_view(request, form_id=None):
"Failed to retrieve answer provided by applicant.") "Failed to retrieve answer provided by applicant.")
response.save() response.save()
logger.info("%s created %s" % (request.user, application)) logger.info("%s created %s" % (request.user, application))
return redirect('auth_hrapplications_view') return redirect('hrapplications:view')
else: else:
questions = app_form.questions.all() questions = app_form.questions.all()
return render(request, 'hrapplications/create.html', return render(request, 'hrapplications/create.html',
@ -91,7 +94,7 @@ def hr_application_personal_view(request, app_id):
return render(request, 'hrapplications/view.html', context=context) return render(request, 'hrapplications/view.html', context=context)
else: else:
logger.warn("User %s not authorized to view %s" % (request.user, app)) logger.warn("User %s not authorized to view %s" % (request.user, app))
return redirect('auth_hrapplications_view') return redirect('hrapplications:view')
@login_required @login_required
@ -106,14 +109,17 @@ def hr_application_personal_removal(request, app_id):
logger.warn("User %s attempting to delete reviewed app %s" % (request.user, app)) logger.warn("User %s attempting to delete reviewed app %s" % (request.user, app))
else: else:
logger.warn("User %s not authorized to delete %s" % (request.user, app)) logger.warn("User %s not authorized to delete %s" % (request.user, app))
return redirect('auth_hrapplications_view') return redirect('hrapplications:view')
@login_required @login_required
@permission_required('auth.human_resources') @permission_required('auth.human_resources')
def hr_application_view(request, app_id): def hr_application_view(request, app_id):
logger.debug("hr_application_view called by user %s for app id %s" % (request.user, app_id)) logger.debug("hr_application_view called by user %s for app id %s" % (request.user, app_id))
app = get_object_or_404(Application, pk=app_id) try:
app = Application.objects.prefetch_related('responses', 'comments', 'comments__user').get(pk=app_id)
except Application.DoesNotExist:
raise Http404
if request.method == 'POST': if request.method == 'POST':
if request.user.has_perm('hrapplications.add_applicationcomment'): if request.user.has_perm('hrapplications.add_applicationcomment'):
form = HRApplicationCommentForm(request.POST) form = HRApplicationCommentForm(request.POST)
@ -125,18 +131,18 @@ def hr_application_view(request, app_id):
comment.text = form.cleaned_data['comment'] comment.text = form.cleaned_data['comment']
comment.save() comment.save()
logger.info("Saved comment by user %s to %s" % (request.user, app)) logger.info("Saved comment by user %s to %s" % (request.user, app))
return redirect(hr_application_view, app_id) return redirect('hrapplications:view', app_id)
else: else:
logger.warn("User %s does not have permission to add ApplicationComments" % request.user) logger.warn("User %s does not have permission to add ApplicationComments" % request.user)
return redirect(hr_application_view, app_id) return redirect('hrapplications:view', app_id)
else: else:
logger.debug("Returning blank HRApplication comment form.") logger.debug("Returning blank HRApplication comment form.")
form = HRApplicationCommentForm() form = HRApplicationCommentForm()
context = { context = {
'app': app, 'app': app,
'responses': ApplicationResponse.objects.filter(application=app), 'responses': app.responses.all(),
'buttons': True, 'buttons': True,
'comments': ApplicationComment.objects.filter(application=app), 'comments': app.comments.all(),
'comment_form': form, 'comment_form': form,
} }
return render(request, 'hrapplications/view.html', context=context) return render(request, 'hrapplications/view.html', context=context)
@ -151,7 +157,7 @@ def hr_application_remove(request, app_id):
logger.info("User %s deleting %s" % (request.user, app)) logger.info("User %s deleting %s" % (request.user, app))
app.delete() app.delete()
notify(app.user, "Application Deleted", message="Your application to %s was deleted." % app.form.corp) notify(app.user, "Application Deleted", message="Your application to %s was deleted." % app.form.corp)
return redirect('auth_hrapplications_view') return redirect('hrapplications:view')
@login_required @login_required
@ -168,7 +174,7 @@ def hr_application_approve(request, app_id):
level="success") level="success")
else: else:
logger.warn("User %s not authorized to approve %s" % (request.user, app)) logger.warn("User %s not authorized to approve %s" % (request.user, app))
return redirect('auth_hrapplications_view') return redirect('hrapplications:view')
@login_required @login_required
@ -185,7 +191,7 @@ def hr_application_reject(request, app_id):
level="danger") level="danger")
else: else:
logger.warn("User %s not authorized to reject %s" % (request.user, app)) logger.warn("User %s not authorized to reject %s" % (request.user, app))
return redirect('auth_hrapplications_view') return redirect('hrapplications:view')
@login_required @login_required
@ -199,35 +205,24 @@ def hr_application_search(request):
searchstring = form.cleaned_data['search_string'].lower() searchstring = form.cleaned_data['search_string'].lower()
applications = set([]) applications = set([])
logger.debug("Searching for application with character name %s for user %s" % (searchstring, request.user)) logger.debug("Searching for application with character name %s for user %s" % (searchstring, request.user))
app_list = [] app_list = Application.objects.all()
if request.user.is_superuser: if not request.user.is_superuser:
app_list = Application.objects.all()
else:
try: try:
app_list = Application.objects.filter(form__corp__corporation_id=request.user.profile.main_character.corporation_id) app_list = app_list.filter(
form__corp__corporation_id=request.user.profile.main_character.corporation_id)
except AttributeError: except AttributeError:
logger.warn( logger.warn(
"User %s missing main character model: unable to filter applications to search" % request.user) "User %s missing main character model: unable to filter applications to search" % request.user)
for application in app_list:
if application.main_character: applications = app_list.filter(
if searchstring in application.main_character.character_name.lower(): Q(user__profile__main_character__character_name__icontains=searchstring) |
applications.add(application) Q(user__profile__main_character__corporation_name__icontains=searchstring) |
if searchstring in application.main_character.corporation_name.lower(): Q(user__profile__main_character__alliance_name__icontains=searchstring) |
applications.add(application) Q(user__character_ownerships__character__character_name__icontains=searchstring) |
if application.main_character.alliance_name \ Q(user__character_ownerships__character__corporation_name__icontains=searchstring) |
and searchstring in application.main_character.alliance_name.lower(): Q(user__character_ownerships__character__alliance_name__icontains=searchstring) |
applications.add(application) Q(user__username__icontains=searchstring)
for character in application.characters: )
if searchstring in character.character_name.lower():
applications.add(application)
if searchstring in character.corporation_name.lower():
applications.add(application)
if character.alliance_name and searchstring in character.alliance_name.lower():
applications.add(application)
if searchstring in application.user.username.lower():
applications.add(application)
logger.info("Found %s Applications for user %s matching search string %s" % (
len(applications), request.user, searchstring))
context = {'applications': applications, 'search_form': HRApplicationSearchForm()} context = {'applications': applications, 'search_form': HRApplicationSearchForm()}
@ -239,7 +234,7 @@ def hr_application_search(request):
else: else:
logger.debug("Returning empty search form for user %s" % request.user) logger.debug("Returning empty search form for user %s" % request.user)
return redirect("auth_hrapplications_view") return redirect("hrapplications:view")
@login_required @login_required

View File

@ -18,10 +18,11 @@ logger = logging.getLogger(__name__)
@permission_required('auth.optimer_view') @permission_required('auth.optimer_view')
def optimer_view(request): def optimer_view(request):
logger.debug("optimer_view called by user %s" % request.user) logger.debug("optimer_view called by user %s" % request.user)
render_items = {'optimer': OpTimer.objects.all(), base_query = OpTimer.objects.select_related('eve_character')
'future_timers': OpTimer.objects.all().filter( render_items = {'optimer': base_query.all(),
'future_timers': base_query.filter(
start__gte=timezone.now()), start__gte=timezone.now()),
'past_timers': OpTimer.objects.all().filter( 'past_timers': base_query.filter(
start__lt=timezone.now()).order_by('-start')} start__lt=timezone.now()).order_by('-start')}
return render(request, 'optimer/management.html', context=render_items) return render(request, 'optimer/management.html', context=render_items)

View File

@ -1,13 +1,11 @@
from unittest import mock from django_webtest import WebTest
from django.test import TestCase
from django import urls from django import urls
from django.contrib.auth.models import Group, Permission from django.contrib.auth.models import Group, Permission
from allianceauth.tests.auth_utils import AuthUtils from allianceauth.tests.auth_utils import AuthUtils
class PermissionsToolViewsTestCase(TestCase): class PermissionsToolViewsTestCase(WebTest):
def setUp(self): def setUp(self):
self.member = AuthUtils.create_member('auth_member') self.member = AuthUtils.create_member('auth_member')
self.member.email = 'auth_member@example.com' self.member.email = 'auth_member@example.com'
@ -36,8 +34,8 @@ class PermissionsToolViewsTestCase(TestCase):
AuthUtils.connect_signals() AuthUtils.connect_signals()
def test_menu_item(self): def test_menu_item(self):
self.client.force_login(self.member) self.app.set_user(self.member)
response = self.client.get(urls.reverse('permissions_tool:overview')) response = self.app.get(urls.reverse('permissions_tool:overview'))
response_content = response.content.decode('utf-8') response_content = response.content.decode('utf-8')
@ -45,9 +43,9 @@ class PermissionsToolViewsTestCase(TestCase):
'<i class="fa fa-key fa-id-card"></i> Permissions Audit</a></li>', response_content) '<i class="fa fa-key fa-id-card"></i> Permissions Audit</a></li>', response_content)
def test_permissions_overview(self): def test_permissions_overview(self):
self.client.force_login(self.member) self.app.set_user(self.member)
response = self.client.get(urls.reverse('permissions_tool:overview')) response = self.app.get(urls.reverse('permissions_tool:overview'))
self.assertEqual(response.status_code, 200) self.assertEqual(response.status_code, 200)
self.assertTemplateUsed('permissions_tool/overview.html') self.assertTemplateUsed('permissions_tool/overview.html')
@ -71,9 +69,9 @@ class PermissionsToolViewsTestCase(TestCase):
def test_permissions_overview_perms(self): def test_permissions_overview_perms(self):
# Ensure permission effectively denys access # Ensure permission effectively denys access
self.client.force_login(self.no_perm_user) self.app.set_user(self.no_perm_user)
response = self.client.get(urls.reverse('permissions_tool:overview')) response = self.app.get(urls.reverse('permissions_tool:overview'))
self.assertEqual(response.status_code, 302) self.assertEqual(response.status_code, 302)
@ -99,9 +97,9 @@ class PermissionsToolViewsTestCase(TestCase):
def test_permissions_audit_perms(self): def test_permissions_audit_perms(self):
# Ensure permission effectively denys access # Ensure permission effectively denys access
self.client.force_login(self.no_perm_user) self.app.set_user(self.no_perm_user)
response = self.client.get(urls.reverse('permissions_tool:audit', response = self.app.get(urls.reverse('permissions_tool:audit',
kwargs={ kwargs={
'app_label': self.permission.content_type.app_label, 'app_label': self.permission.content_type.app_label,
'model': self.permission.content_type.model, 'model': self.permission.content_type.model,

View File

@ -3,9 +3,8 @@ import logging
from django.contrib.auth.decorators import login_required, permission_required from django.contrib.auth.decorators import login_required, permission_required
from django.contrib.auth.models import Permission, User from django.contrib.auth.models import Permission, User
from django.db.models import Count from django.db.models import Count
from django.shortcuts import render, get_object_or_404 from django.shortcuts import render, Http404
from allianceauth.authentication.models import UserProfile
logger = logging.getLogger(__name__) logger = logging.getLogger(__name__)
@ -14,25 +13,28 @@ logger = logging.getLogger(__name__)
@permission_required('permissions_tool.audit_permissions') @permission_required('permissions_tool.audit_permissions')
def permissions_overview(request): def permissions_overview(request):
logger.debug("permissions_overview called by user %s" % request.user) logger.debug("permissions_overview called by user %s" % request.user)
perms = Permission.objects.all() perms = Permission.objects.select_related('content_type').all()\
.annotate(Count('user', distinct=True))\
.annotate(Count('group', distinct=True)) \
.annotate(Count('group__user', distinct=True)) \
.annotate(Count('state', distinct=True))\
.annotate(Count('state__userprofile', distinct=True))
get_all = True if request.GET.get('all', 'no') == 'yes' else False get_all = True if request.GET.get('all', 'no') == 'yes' else False
context = {'permissions': []} context = {'permissions': []}
for perm in perms: for perm in perms:
this_perm = { this_perm = {
'users': perm.user_set.all().count(), 'users': perm.user__count,
'groups': perm.group_set.all().count(), 'groups': perm.group__count,
'states': perm.state_set.all().count(), 'group_users': perm.group__user__count,
'permission': perm 'states': perm.state__count,
'state_users': perm.state__userprofile__count,
'permission': perm,
} }
if get_all or this_perm['users'] > 0 or this_perm['groups'] > 0 or this_perm['states'] > 0: if get_all or sum([this_perm['users'], this_perm['groups'], this_perm['states']]) > 0:
# Only add if we're getting everything or one of the objects has this permission # Only add if we're getting everything or one of the objects has this permission
# Add group_users separately to improve performance
this_perm['group_users'] = sum(group.user_count for group in
perm.group_set.annotate(user_count=Count('user')))
this_perm['state_users'] = UserProfile.objects.filter(state__in=perm.state_set.all()).count()
context['permissions'].append(this_perm) context['permissions'].append(this_perm)
return render(request, 'permissions_tool/overview.html', context=context) return render(request, 'permissions_tool/overview.html', context=context)
@ -42,10 +44,13 @@ def permissions_overview(request):
@permission_required('permissions_tool.audit_permissions') @permission_required('permissions_tool.audit_permissions')
def permissions_audit(request, app_label, model, codename): def permissions_audit(request, app_label, model, codename):
logger.debug("permissions_audit called by user {} on {}:{}:{}".format(request.user, app_label, model, codename)) logger.debug("permissions_audit called by user {} on {}:{}:{}".format(request.user, app_label, model, codename))
perm = get_object_or_404(Permission, try:
content_type__app_label=app_label, perm = Permission.objects\
content_type__model=model, .prefetch_related('group_set', 'user_set', 'state_set',
codename=codename) 'state_set__userprofile_set', 'group_set__user_set', 'state_set__userprofile_set__user')\
.get(content_type__app_label=app_label, content_type__model=model, codename=codename)
except Permission.DoesNotExist:
raise Http404
context = {'permission': { context = {'permission': {
'permission': perm, 'permission': perm,
@ -53,7 +58,7 @@ def permissions_audit(request, app_label, model, codename):
'groups': perm.group_set.all(), 'groups': perm.group_set.all(),
'states': perm.state_set.all(), 'states': perm.state_set.all(),
'group_users': [group.user_set.all() for group in perm.group_set.all()], 'group_users': [group.user_set.all() for group in perm.group_set.all()],
'state_users': User.objects.filter(profile__state__in=perm.state_set.all()), 'state_users': [state.userprofile_set.all() for state in perm.state_set.all()],
} }
} }

View File

@ -1,3 +1,8 @@
import json
import urllib
import datetime
import requests_mock
from django_webtest import WebTest
from unittest import mock from unittest import mock
from django.test import TestCase, RequestFactory from django.test import TestCase, RequestFactory
@ -10,9 +15,8 @@ from .auth_hooks import DiscordService
from .models import DiscordUser from .models import DiscordUser
from .tasks import DiscordTasks from .tasks import DiscordTasks
from .manager import DiscordOAuthManager from .manager import DiscordOAuthManager
from . import manager
import requests_mock
import datetime
MODULE_PATH = 'allianceauth.services.modules.discord' MODULE_PATH = 'allianceauth.services.modules.discord'
DEFAULT_AUTH_GROUP = 'Member' DEFAULT_AUTH_GROUP = 'Member'
@ -138,26 +142,26 @@ class DiscordHooksTestCase(TestCase):
# TODO: Test update nicknames # TODO: Test update nicknames
class DiscordViewsTestCase(TestCase): class DiscordViewsTestCase(WebTest):
def setUp(self): def setUp(self):
self.member = AuthUtils.create_member('auth_member') self.member = AuthUtils.create_member('auth_member')
add_permissions() add_permissions()
def login(self): def login(self):
self.client.force_login(self.member) self.app.set_user(self.member)
@mock.patch(MODULE_PATH + '.views.DiscordOAuthManager') @mock.patch(MODULE_PATH + '.views.DiscordOAuthManager')
def test_activate(self, manager): def test_activate(self, manager):
self.login() self.login()
manager.generate_oauth_redirect_url.return_value = '/example.com/oauth/' manager.generate_oauth_redirect_url.return_value = '/example.com/oauth/'
response = self.client.get('/discord/activate/', follow=False) response = self.app.get('/discord/activate/', auto_follow=False)
self.assertRedirects(response, expected_url='/example.com/oauth/', target_status_code=404) self.assertRedirects(response, expected_url='/example.com/oauth/', target_status_code=404)
@mock.patch(MODULE_PATH + '.tasks.DiscordOAuthManager') @mock.patch(MODULE_PATH + '.tasks.DiscordOAuthManager')
def test_callback(self, manager): def test_callback(self, manager):
self.login() self.login()
manager.add_user.return_value = '1234' manager.add_user.return_value = '1234'
response = self.client.get('/discord/callback/', data={'code': '1234'}) response = self.app.get('/discord/callback/', params={'code': '1234'})
self.member = User.objects.get(pk=self.member.pk) self.member = User.objects.get(pk=self.member.pk)
@ -172,7 +176,7 @@ class DiscordViewsTestCase(TestCase):
DiscordUser.objects.create(user=self.member, uid='12345') DiscordUser.objects.create(user=self.member, uid='12345')
manager.delete_user.return_value = True manager.delete_user.return_value = True
response = self.client.get('/discord/reset/') response = self.app.get('/discord/reset/')
self.assertRedirects(response, expected_url='/discord/activate/', target_status_code=302) self.assertRedirects(response, expected_url='/discord/activate/', target_status_code=302)
@ -182,7 +186,7 @@ class DiscordViewsTestCase(TestCase):
DiscordUser.objects.create(user=self.member, uid='12345') DiscordUser.objects.create(user=self.member, uid='12345')
manager.delete_user.return_value = True manager.delete_user.return_value = True
response = self.client.get('/discord/deactivate/') response = self.app.get('/discord/deactivate/')
self.assertTrue(manager.delete_user.called) self.assertTrue(manager.delete_user.called)
self.assertRedirects(response, expected_url='/services/', target_status_code=200) self.assertRedirects(response, expected_url='/services/', target_status_code=200)
@ -201,7 +205,6 @@ class DiscordManagerTestCase(TestCase):
self.assertEqual(group_name, 'GroupName_Test') self.assertEqual(group_name, 'GroupName_Test')
def test_generate_Bot_add_url(self): def test_generate_Bot_add_url(self):
from . import manager
bot_add_url = DiscordOAuthManager.generate_bot_add_url() bot_add_url = DiscordOAuthManager.generate_bot_add_url()
auth_url = manager.AUTH_URL auth_url = manager.AUTH_URL
@ -209,23 +212,15 @@ class DiscordManagerTestCase(TestCase):
self.assertEqual(bot_add_url, real_bot_add_url) self.assertEqual(bot_add_url, real_bot_add_url)
def test_generate_oauth_redirect_url(self): def test_generate_oauth_redirect_url(self):
from . import manager
import urllib
import sys
oauth_url = DiscordOAuthManager.generate_oauth_redirect_url() oauth_url = DiscordOAuthManager.generate_oauth_redirect_url()
self.assertIn(manager.AUTH_URL, oauth_url) self.assertIn(manager.AUTH_URL, oauth_url)
self.assertIn('+'.join(manager.SCOPES), oauth_url) self.assertIn('+'.join(manager.SCOPES), oauth_url)
self.assertIn(settings.DISCORD_APP_ID, oauth_url) self.assertIn(settings.DISCORD_APP_ID, oauth_url)
if sys.version_info[0] < 3: self.assertIn(urllib.parse.quote_plus(settings.DISCORD_CALLBACK_URL), oauth_url)
# Py2
self.assertIn(urllib.quote_plus(settings.DISCORD_CALLBACK_URL), oauth_url)
else: # Py3
self.assertIn(urllib.parse.quote_plus(settings.DISCORD_CALLBACK_URL), oauth_url)
@mock.patch(MODULE_PATH + '.manager.OAuth2Session') @mock.patch(MODULE_PATH + '.manager.OAuth2Session')
def test__process_callback_code(self, oauth): def test__process_callback_code(self, oauth):
from . import manager
instance = oauth.return_value instance = oauth.return_value
instance.fetch_token.return_value = {'access_token': 'mywonderfultoken'} instance.fetch_token.return_value = {'access_token': 'mywonderfultoken'}
@ -245,9 +240,6 @@ class DiscordManagerTestCase(TestCase):
@mock.patch(MODULE_PATH + '.manager.DiscordOAuthManager._process_callback_code') @mock.patch(MODULE_PATH + '.manager.DiscordOAuthManager._process_callback_code')
@requests_mock.Mocker() @requests_mock.Mocker()
def test_add_user(self, oauth_token, m): def test_add_user(self, oauth_token, m):
from . import manager
import json
# Arrange # Arrange
oauth_token.return_value = {'access_token': 'accesstoken'} oauth_token.return_value = {'access_token': 'accesstoken'}
@ -272,9 +264,6 @@ class DiscordManagerTestCase(TestCase):
@requests_mock.Mocker() @requests_mock.Mocker()
def test_delete_user(self, m): def test_delete_user(self, m):
from . import manager
import json
# Arrange # Arrange
headers = {'accept': 'application/json', 'authorization': 'Bot ' + settings.DISCORD_BOT_TOKEN} headers = {'accept': 'application/json', 'authorization': 'Bot ' + settings.DISCORD_BOT_TOKEN}
@ -321,7 +310,6 @@ class DiscordManagerTestCase(TestCase):
@requests_mock.Mocker() @requests_mock.Mocker()
def test_update_nickname(self, m): def test_update_nickname(self, m):
from . import manager
# Arrange # Arrange
headers = {'content-type': 'application/json', 'authorization': 'Bot ' + settings.DISCORD_BOT_TOKEN} headers = {'content-type': 'application/json', 'authorization': 'Bot ' + settings.DISCORD_BOT_TOKEN}
@ -339,9 +327,6 @@ class DiscordManagerTestCase(TestCase):
@mock.patch(MODULE_PATH + '.manager.DiscordOAuthManager._get_groups') @mock.patch(MODULE_PATH + '.manager.DiscordOAuthManager._get_groups')
@requests_mock.Mocker() @requests_mock.Mocker()
def test_update_groups(self, group_cache, m): def test_update_groups(self, group_cache, m):
from . import manager
import json
# Arrange # Arrange
groups = ['Member', 'Blue', 'Special Group'] groups = ['Member', 'Blue', 'Special Group']
@ -373,8 +358,6 @@ class DiscordManagerTestCase(TestCase):
@mock.patch(MODULE_PATH + '.manager.DiscordOAuthManager._get_groups') @mock.patch(MODULE_PATH + '.manager.DiscordOAuthManager._get_groups')
@requests_mock.Mocker() @requests_mock.Mocker()
def test_update_groups_backoff(self, group_cache, djcache, m): def test_update_groups_backoff(self, group_cache, djcache, m):
from . import manager
# Arrange # Arrange
groups = ['Member'] groups = ['Member']
group_cache.return_value = [{'id': 111, 'name': 'Member'}] group_cache.return_value = [{'id': 111, 'name': 'Member'}]
@ -408,8 +391,6 @@ class DiscordManagerTestCase(TestCase):
@mock.patch(MODULE_PATH + '.manager.DiscordOAuthManager._get_groups') @mock.patch(MODULE_PATH + '.manager.DiscordOAuthManager._get_groups')
@requests_mock.Mocker() @requests_mock.Mocker()
def test_update_groups_global_backoff(self, group_cache, djcache, m): def test_update_groups_global_backoff(self, group_cache, djcache, m):
from . import manager
# Arrange # Arrange
groups = ['Member'] groups = ['Member']
group_cache.return_value = [{'id': 111, 'name': 'Member'}] group_cache.return_value = [{'id': 111, 'name': 'Member'}]

View File

@ -7,7 +7,7 @@ app_name = 'srp'
urlpatterns = [ urlpatterns = [
# SRP URLS # SRP URLS
url(r'^$', views.srp_management, name='management'), url(r'^$', views.srp_management, name='management'),
url(r'^all/$', views.srp_management_all, name='all'), url(r'^all/$', views.srp_management, {'all': True}, name='all'),
url(r'^(\w+)/view$', views.srp_fleet_view, name='fleet'), url(r'^(\w+)/view$', views.srp_fleet_view, name='fleet'),
url(r'^add/$', views.srp_fleet_add_view, name='add'), url(r'^add/$', views.srp_fleet_add_view, name='add'),
url(r'^(\w+)/edit$', views.srp_fleet_edit_view, name='edit'), url(r'^(\w+)/edit$', views.srp_fleet_edit_view, name='edit'),

View File

@ -5,10 +5,11 @@ from django.contrib import messages
from django.contrib.auth.decorators import login_required from django.contrib.auth.decorators import login_required
from django.contrib.auth.decorators import permission_required from django.contrib.auth.decorators import permission_required
from django.contrib.humanize.templatetags.humanize import intcomma from django.contrib.humanize.templatetags.humanize import intcomma
from django.http import JsonResponse from django.http import JsonResponse, Http404
from django.shortcuts import render, redirect, get_object_or_404 from django.shortcuts import render, redirect, get_object_or_404
from django.utils import timezone from django.utils import timezone
from django.utils.translation import ugettext_lazy as _ from django.utils.translation import ugettext_lazy as _
from django.db.models import Sum
from allianceauth.eveonline.providers import provider from allianceauth.eveonline.providers import provider
from allianceauth.notifications import notify from allianceauth.notifications import notify
from .form import SrpFleetMainForm from .form import SrpFleetMainForm
@ -31,31 +32,27 @@ def random_string(string_length=10):
@login_required @login_required
@permission_required('srp.access_srp') @permission_required('srp.access_srp')
def srp_management(request): def srp_management(request, all=False):
logger.debug("srp_management called by user %s" % request.user) logger.debug("srp_management called by user %s" % request.user)
fleets = SrpFleetMain.objects.filter(fleet_srp_status="") fleets = SrpFleetMain.objects.select_related('fleet_commander').prefetch_related('srpuserrequest_set').all()
totalcost = sum([int(fleet.total_cost) for fleet in fleets]) if not all:
fleets = fleets.filter(fleet_srp_status="")
else:
logger.debug("Returning all SRP requests")
totalcost = fleets.aggregate(total_cost=Sum('srpuserrequest__srp_total_amount')).get('total_cost', 0)
context = {"srpfleets": fleets, "totalcost": totalcost} context = {"srpfleets": fleets, "totalcost": totalcost}
return render(request, 'srp/management.html', context=context) return render(request, 'srp/management.html', context=context)
@login_required
@permission_required('srp.access_srp')
def srp_management_all(request):
logger.debug("srp_management_all called by user %s" % request.user)
fleets = SrpFleetMain.objects.all()
totalcost = sum([int(fleet.total_cost) for fleet in fleets])
context = {"srpfleets": SrpFleetMain.objects.all(), "totalcost": totalcost}
return render(request, 'srp/management.html', context=context)
@login_required @login_required
@permission_required('srp.access_srp') @permission_required('srp.access_srp')
def srp_fleet_view(request, fleet_id): def srp_fleet_view(request, fleet_id):
logger.debug("srp_fleet_view called by user %s for fleet id %s" % (request.user, fleet_id)) logger.debug("srp_fleet_view called by user %s for fleet id %s" % (request.user, fleet_id))
fleet_main = get_object_or_404(SrpFleetMain, id=fleet_id) try:
fleet_main = SrpFleetMain.objects.get(id=fleet_id)
except SrpFleetMain.DoesNotExist:
raise Http404
context = {"fleet_id": fleet_id, "fleet_status": fleet_main.fleet_srp_status, context = {"fleet_id": fleet_id, "fleet_status": fleet_main.fleet_srp_status,
"srpfleetrequests": fleet_main.srpuserrequest_set.order_by('srp_ship_name'), "srpfleetrequests": fleet_main.srpuserrequest_set.select_related('character').order_by('srp_ship_name'),
"totalcost": fleet_main.total_cost} "totalcost": fleet_main.total_cost}
return render(request, 'srp/data.html', context=context) return render(request, 'srp/data.html', context=context)

View File

@ -32,12 +32,12 @@ class TimerView(BaseTimerView):
corp = char.corporation corp = char.corporation
else: else:
corp = None corp = None
base_query = Timer.objects.select_related('eve_character')
render_items = { render_items = {
'timers': Timer.objects.filter(corp_timer=False), 'timers': base_query.filter(corp_timer=False),
'corp_timers': Timer.objects.filter(corp_timer=True, eve_corp=corp), 'corp_timers': base_query.filter(corp_timer=True, eve_corp=corp),
'future_timers': Timer.objects.filter(corp_timer=False, eve_time__gte=timezone.now()), 'future_timers': base_query.filter(corp_timer=False, eve_time__gte=timezone.now()),
'past_timers': Timer.objects.filter(corp_timer=False, eve_time__lt=timezone.now()), 'past_timers': base_query.filter(corp_timer=False, eve_time__lt=timezone.now()),
} }
return render(request, self.template_name, context=render_items) return render(request, self.template_name, context=render_items)