mirror of
https://gitlab.com/allianceauth/allianceauth.git
synced 2026-02-08 16:16:18 +01:00
API SSO, Beautification of Tables, and more. (#562)
# One Thousandth Commit 🎉 🎈 🎆 🍾 * Allow requiring API ownership validation by SSO. Closes #163 * Add Discourse group name length restrictions. * Redirect after api addition/deletion of main character * Correct admin searching for removed discourse_username field in AuthServicesInfo * Correct admin function to sync user Discourse groups * Beautify tables by removing borders and hiding when empty. *Add buttons on dead-end pages to return to originating view.
This commit is contained in:
@@ -4,6 +4,7 @@ from django.conf import settings
|
||||
|
||||
from services.managers.eve_api_manager import EveApiManager
|
||||
from eveonline.managers import EveManager
|
||||
from eveonline.models import EveApiKeyPair
|
||||
import evelink
|
||||
|
||||
import logging
|
||||
@@ -31,7 +32,9 @@ class UpdateKeyForm(forms.Form):
|
||||
|
||||
if EveManager.check_if_api_key_pair_exist(self.cleaned_data['api_id']):
|
||||
logger.debug("UpdateKeyForm failed cleaning as API id %s already exists." % self.cleaned_data['api_id'])
|
||||
raise forms.ValidationError('API key already exist')
|
||||
if EveApiKeyPair.objects.get(api_id=self.cleaned_data['api_id']).user:
|
||||
# allow orphaned APIs to proceed to SSO validation upon re-entry
|
||||
raise forms.ValidationError('API key already exist')
|
||||
if settings.REJECT_OLD_APIS and not EveManager.check_if_api_key_pair_is_new(
|
||||
self.cleaned_data['api_id'],
|
||||
settings.REJECT_OLD_APIS_MARGIN):
|
||||
|
||||
27
eveonline/migrations/0003_auto_20161026_0149.py
Normal file
27
eveonline/migrations/0003_auto_20161026_0149.py
Normal file
@@ -0,0 +1,27 @@
|
||||
# -*- coding: utf-8 -*-
|
||||
# Generated by Django 1.10.2 on 2016-10-26 01:49
|
||||
from __future__ import unicode_literals
|
||||
|
||||
from django.conf import settings
|
||||
from django.db import migrations, models
|
||||
import django.db.models.deletion
|
||||
|
||||
|
||||
class Migration(migrations.Migration):
|
||||
|
||||
dependencies = [
|
||||
('eveonline', '0002_remove_eveapikeypair_error_count'),
|
||||
]
|
||||
|
||||
operations = [
|
||||
migrations.AlterField(
|
||||
model_name='eveapikeypair',
|
||||
name='user',
|
||||
field=models.ForeignKey(blank=True, null=True, on_delete=django.db.models.deletion.CASCADE, to=settings.AUTH_USER_MODEL),
|
||||
),
|
||||
migrations.AlterField(
|
||||
model_name='evecharacter',
|
||||
name='user',
|
||||
field=models.ForeignKey(blank=True, null=True, on_delete=django.db.models.deletion.CASCADE, to=settings.AUTH_USER_MODEL),
|
||||
),
|
||||
]
|
||||
@@ -14,7 +14,7 @@ class EveCharacter(models.Model):
|
||||
alliance_id = models.CharField(max_length=254)
|
||||
alliance_name = models.CharField(max_length=254)
|
||||
api_id = models.CharField(max_length=254)
|
||||
user = models.ForeignKey(User)
|
||||
user = models.ForeignKey(User, blank=True, null=True)
|
||||
|
||||
def __str__(self):
|
||||
return self.character_name
|
||||
@@ -24,10 +24,10 @@ class EveCharacter(models.Model):
|
||||
class EveApiKeyPair(models.Model):
|
||||
api_id = models.CharField(max_length=254)
|
||||
api_key = models.CharField(max_length=254)
|
||||
user = models.ForeignKey(User)
|
||||
user = models.ForeignKey(User, blank=True, null=True)
|
||||
|
||||
def __str__(self):
|
||||
return self.user.username + " - ApiKeyPair"
|
||||
return self.api_id
|
||||
|
||||
|
||||
@python_2_unicode_compatible
|
||||
|
||||
@@ -1,5 +1,5 @@
|
||||
from __future__ import unicode_literals
|
||||
from django.shortcuts import render, redirect
|
||||
from django.shortcuts import render, redirect, get_object_or_404
|
||||
from django.contrib.auth.decorators import login_required
|
||||
from django.contrib import messages
|
||||
|
||||
@@ -7,11 +7,13 @@ from eveonline.forms import UpdateKeyForm
|
||||
from eveonline.managers import EveManager
|
||||
from authentication.managers import AuthServicesInfoManager
|
||||
from services.managers.eve_api_manager import EveApiManager
|
||||
from eveonline.models import EveApiKeyPair
|
||||
from eveonline.models import EveApiKeyPair, EveCharacter
|
||||
from authentication.models import AuthServicesInfo
|
||||
from authentication.tasks import set_state
|
||||
from eveonline.tasks import refresh_api
|
||||
|
||||
from eve_sso.decorators import token_required
|
||||
from django.conf import settings
|
||||
import logging
|
||||
|
||||
logger = logging.getLogger(__name__)
|
||||
@@ -24,20 +26,39 @@ def add_api_key(request):
|
||||
form = UpdateKeyForm(request.user, request.POST)
|
||||
logger.debug("Request type POST with form valid: %s" % form.is_valid())
|
||||
if form.is_valid():
|
||||
EveManager.create_api_keypair(form.cleaned_data['api_id'],
|
||||
form.cleaned_data['api_key'],
|
||||
request.user)
|
||||
|
||||
if EveApiKeyPair.objects.filter(api_id=form.cleaned_data['api_id'],
|
||||
api_key=form.cleaned_data['api_key']).exists():
|
||||
# allow orphaned keys to proceed to SSO validation upon re-entry
|
||||
api_key = EveApiKeyPair.objects.get(api_id=form.cleaned_data['api_id'],
|
||||
api_key=form.cleaned_data['api_key'])
|
||||
elif EveApiKeyPair.objects.filter(api_id=form.cleaned_data['api_id']).exists():
|
||||
logger.warn('API %s re-added with different vcode.' % form.cleaned_data['api_id'])
|
||||
EveApiKeyPair.objects.filter(api_id=form.cleaned_data['api_id']).delete()
|
||||
api_key = EveApiKeyPair.objects.create(api_id=form.cleaned_data['api_id'],
|
||||
api_key=form.cleaned_data['api_key'])
|
||||
else:
|
||||
api_key = EveApiKeyPair.objects.create(api_id=form.cleaned_data['api_id'],
|
||||
api_key=form.cleaned_data['api_key'])
|
||||
owner = None
|
||||
if not settings.API_SSO_VALIDATION:
|
||||
# set API and character owners if SSO validation not requested
|
||||
api_key.user = request.user
|
||||
api_key.save()
|
||||
owner = request.user
|
||||
# Grab characters associated with the key pair
|
||||
characters = EveApiManager.get_characters_from_api(form.cleaned_data['api_id'],
|
||||
form.cleaned_data['api_key'])
|
||||
EveManager.create_characters_from_list(characters, request.user, form.cleaned_data['api_id'])
|
||||
EveManager.create_characters_from_list(characters, owner, form.cleaned_data['api_id'])
|
||||
logger.info("Successfully processed api add form for user %s" % request.user)
|
||||
messages.success(request, 'Added API key %s to your account.' % form.cleaned_data['api_id'])
|
||||
auth = AuthServicesInfo.objects.get_or_create(user=request.user)[0]
|
||||
if not auth.main_char_id:
|
||||
messages.warning(request, 'Please select a main character.')
|
||||
return redirect("/api_key_management/")
|
||||
if not settings.API_SSO_VALIDATION:
|
||||
messages.success(request, 'Added API key %s to your account.' % form.cleaned_data['api_id'])
|
||||
auth = AuthServicesInfo.objects.get_or_create(user=request.user)[0]
|
||||
if not auth.main_char_id:
|
||||
return redirect('auth_characters')
|
||||
return redirect("/api_key_management/")
|
||||
else:
|
||||
logger.debug('Requesting SSO validation of API %s by user %s' % (api_key.api_id, request.user))
|
||||
return render(request, 'registered/apisso.html', context={'api':api_key})
|
||||
else:
|
||||
logger.debug("Form invalid: returning to form.")
|
||||
else:
|
||||
@@ -47,6 +68,32 @@ def add_api_key(request):
|
||||
return render(request, 'registered/addapikey.html', context=context)
|
||||
|
||||
|
||||
@login_required
|
||||
@token_required(new=True)
|
||||
def api_sso_validate(request, tokens, api_id):
|
||||
logger.debug('api_sso_validate called by user %s for api %s' % (request.user, api_id))
|
||||
api = get_object_or_404(EveApiKeyPair, api_id=api_id)
|
||||
if api.user:
|
||||
logger.warning('User %s attempting to take ownership of api %s from %s' % (request.user, api_id, api.user))
|
||||
messages.warning(request, 'API %s already claimed by user %s' % (api_id, api.user))
|
||||
return redirect('auth_api_key_management')
|
||||
token = tokens[0]
|
||||
logger.debug('API %s has no owner. Checking if token for %s matches.' % (api_id, token.character_name))
|
||||
characters = EveApiManager.get_characters_from_api(api.api_id, api.api_key).result
|
||||
if token.character_id in characters:
|
||||
api.user = request.user
|
||||
api.save()
|
||||
EveCharacter.objects.filter(character_id__in=characters).update(user=request.user, api_id=api_id)
|
||||
messages.success(request, 'Confirmed ownership of API %s' % api.api_id)
|
||||
auth, c = AuthServicesInfo.objects.get_or_create(user=request.user)
|
||||
if not auth.main_char_id:
|
||||
return redirect('auth_characters')
|
||||
return redirect('auth_api_key_management')
|
||||
else:
|
||||
messages.warning(request, '%s not found on API %s. Please SSO as a character on the API.' % (token.character_name, api.api_id))
|
||||
return render(request, 'registered/apisso.html', context={'api':api})
|
||||
|
||||
|
||||
@login_required
|
||||
def api_key_management_view(request):
|
||||
logger.debug("api_key_management_view called by user %s" % request.user)
|
||||
@@ -59,21 +106,17 @@ def api_key_management_view(request):
|
||||
def api_key_removal(request, api_id):
|
||||
logger.debug("api_key_removal called by user %s for api id %s" % (request.user, api_id))
|
||||
authinfo = AuthServicesInfo.objects.get_or_create(user=request.user)[0]
|
||||
# Check if our users main id is in the to be deleted characters
|
||||
characters = EveManager.get_characters_by_owner_id(request.user.id)
|
||||
if characters is not None:
|
||||
for character in characters:
|
||||
if character.character_id == authinfo.main_char_id:
|
||||
if character.api_id == api_id:
|
||||
messages.warning(request,
|
||||
'You have deleted your main character. Please select a new main character.')
|
||||
set_state(request.user)
|
||||
|
||||
EveManager.delete_api_key_pair(api_id, request.user.id)
|
||||
EveManager.delete_characters_by_api_id(api_id, request.user.id)
|
||||
messages.success(request, 'Deleted API key %s' % api_id)
|
||||
logger.info("Succesfully processed api delete request by user %s for api %s" % (request.user, api_id))
|
||||
return redirect("auth_api_key_management")
|
||||
if EveCharacter.objects.filter(character_id=authinfo.main_char_id).exists():
|
||||
return redirect("auth_api_key_management")
|
||||
else:
|
||||
authinfo.main_char_id = None
|
||||
authinfo.save()
|
||||
set_state(request.user)
|
||||
return redirect("auth_characters")
|
||||
|
||||
|
||||
@login_required
|
||||
@@ -89,8 +132,8 @@ def main_character_change(request, char_id):
|
||||
logger.debug("main_character_change called by user %s for character id %s" % (request.user, char_id))
|
||||
if EveManager.check_if_character_owned_by_user(char_id, request.user):
|
||||
AuthServicesInfoManager.update_main_char_id(char_id, request.user)
|
||||
set_state(request.user)
|
||||
messages.success(request, 'Changed main character ID to %s' % char_id)
|
||||
set_state(request.user)
|
||||
return redirect("auth_characters")
|
||||
messages.error(request, 'Failed to change main character - selected character is not owned by your account.')
|
||||
return redirect("auth_characters")
|
||||
|
||||
Reference in New Issue
Block a user