diff --git a/alliance_auth/settings.py.example b/alliance_auth/settings.py.example index 42b55319..271eace0 100644 --- a/alliance_auth/settings.py.example +++ b/alliance_auth/settings.py.example @@ -344,6 +344,8 @@ ALLIANCE_NAME = os.environ.get('AA_ALLIANCE_NAME', '') # BLUE_API_ACCOUNT - Require API to be for Account and not character restricted # REJECT_OLD_APIS - Require each submitted API be newer than the latest submitted API # REJECT_OLD_APIS_MARGIN - Margin from latest submitted API ID within which a newly submitted API is still accepted +# API_SSO_VALIDATION - Require users to prove ownership of newly entered API keys via SSO +# Requires SSO to be configured. ####################### MEMBER_API_MASK = os.environ.get('AA_MEMBER_API_MASK', 268435455) MEMBER_API_ACCOUNT = 'True' == os.environ.get('AA_MEMBER_API_ACCOUNT', 'True') @@ -351,6 +353,7 @@ BLUE_API_MASK = os.environ.get('AA_BLUE_API_MASK', 8388608) BLUE_API_ACCOUNT = 'True' == os.environ.get('AA_BLUE_API_ACCOUNT', 'False') REJECT_OLD_APIS = 'True' == os.environ.get('AA_REJECT_OLD_APIS', 'False') REJECT_OLD_APIS_MARGIN = os.environ.get('AA_REJECT_OLD_APIS_MARGIN', 50) +API_SSO_VALIDATION = 'True' == os.environ.get('AA_API_SSO_VALIDATION', 'False') ##################### # Alliance Market diff --git a/alliance_auth/urls.py b/alliance_auth/urls.py index 26d204ea..29613fc5 100755 --- a/alliance_auth/urls.py +++ b/alliance_auth/urls.py @@ -39,6 +39,7 @@ urlpatterns = [ # Eve Online url(r'^main_character_change/(\w+)/$', eveonline.views.main_character_change, name='auth_main_character_change'), + url(r'^api_verify_owner/(\w+)/$', eveonline.views.api_sso_validate, name='auth_api_sso'), # Forum Service Control url(r'^activate_forum/$', services.views.activate_forum, name='auth_activate_forum'), diff --git a/authentication/admin.py b/authentication/admin.py index dc41e4f8..a700af4e 100644 --- a/authentication/admin.py +++ b/authentication/admin.py @@ -99,7 +99,7 @@ class AuthServicesInfoManager(admin.ModelAdmin): def sync_discourse(self, request, queryset): count = 0 for a in queryset: - if a.discourse_username != "": + if a.discourse_enabled: update_discourse_groups.delay(a.user.pk) count += 1 self.message_user(request, "%s discourse accounts queued for group sync." % count) @@ -137,7 +137,6 @@ class AuthServicesInfoManager(admin.ModelAdmin): 'mumble_username', 'teamspeak3_uid', 'discord_uid', - 'discourse_username', 'ips4_username', 'smf_username', 'market_username', diff --git a/eveonline/forms.py b/eveonline/forms.py index 7588fdbc..9572f478 100644 --- a/eveonline/forms.py +++ b/eveonline/forms.py @@ -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): diff --git a/eveonline/migrations/0003_auto_20161026_0149.py b/eveonline/migrations/0003_auto_20161026_0149.py new file mode 100644 index 00000000..beffba20 --- /dev/null +++ b/eveonline/migrations/0003_auto_20161026_0149.py @@ -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), + ), + ] diff --git a/eveonline/models.py b/eveonline/models.py index f3926a6f..77684100 100644 --- a/eveonline/models.py +++ b/eveonline/models.py @@ -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 diff --git a/eveonline/views.py b/eveonline/views.py index d224d3c1..1e8cd63d 100755 --- a/eveonline/views.py +++ b/eveonline/views.py @@ -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") diff --git a/services/managers/discourse_manager.py b/services/managers/discourse_manager.py index 830fbaf9..1953bf57 100644 --- a/services/managers/discourse_manager.py +++ b/services/managers/discourse_manager.py @@ -343,7 +343,10 @@ class DiscourseManager: @staticmethod def _sanitize_groupname(name): name = name.strip(' _') - return re.sub('[^\w]', '', name) + name = re.sub('[^\w]', '', name) + if len(name) < 3: + name = name + "".join('_' for i in range(3-len(name))) + return name[:20] @staticmethod def update_groups(user): diff --git a/stock/templates/registered/apikeymanagment.html b/stock/templates/registered/apikeymanagment.html index 6e7c963d..c6de2c29 100644 --- a/stock/templates/registered/apikeymanagment.html +++ b/stock/templates/registered/apikeymanagment.html @@ -9,38 +9,36 @@ {% block extra_css %}{% endblock extra_css %} {% block content %} -
+
- {% if apikeypairs %} - {% else %} - - {% endif %}

{% trans "API Key Management" %}

- - - - - - - {% for pair in apikeypairs %} + {% if apikeypairs %} +
{% trans "API ID" %}{% trans "API Key" %}{% trans "Action" %}
- - - + + - {% endfor %} -
{{ pair.api_id }}{{ pair.api_key }} - - - - - - - {% trans "API ID" %}{% trans "Action" %}
+ {% for pair in apikeypairs %} + + {{ pair.api_id }} + + + + + + + + + + {% endfor %} + + {% else %} + + {% endif %}
diff --git a/stock/templates/registered/apisso.html b/stock/templates/registered/apisso.html new file mode 100644 index 00000000..e9bb4291 --- /dev/null +++ b/stock/templates/registered/apisso.html @@ -0,0 +1,21 @@ +{% extends 'public/base.html' %} +{% load staticfiles %} +{% block title %}Verify API Ownership{% endblock %} +{% block page_title%}Verify API Ownership{% endblock %} +{% block content %} +
+

Verify API Ownership

+
+
Please authenticate as a character on API {{ api.api_id }} to prove ownership.
+
+
+ + + +
+
+
+
+ +{% endblock %} diff --git a/stock/templates/registered/fatlinkpersonalmonthlystatisticsview.html b/stock/templates/registered/fatlinkpersonalmonthlystatisticsview.html index fac9a02c..c73da6de 100644 --- a/stock/templates/registered/fatlinkpersonalmonthlystatisticsview.html +++ b/stock/templates/registered/fatlinkpersonalmonthlystatisticsview.html @@ -17,7 +17,7 @@ {% endif %}

{% blocktrans %}{{ user }} has collected {{ n_fats }} links this month.{% endblocktrans %}

- +
@@ -31,7 +31,8 @@
{% trans "Ship" %} {% trans "Times used" %}
{% if created_fats %}

{% blocktrans %}{{ user }} has created {{ n_created_fats }} links this month.{% endblocktrans %}

- + {% if created_fats %} +
@@ -58,6 +59,7 @@
{% trans "Name" %} {% trans "Creator" %}
{% endif %} + {% endif %} diff --git a/stock/templates/registered/fatlinkpersonalstatisticsview.html b/stock/templates/registered/fatlinkpersonalstatisticsview.html index 53bae5b9..a85b5f2b 100644 --- a/stock/templates/registered/fatlinkpersonalstatisticsview.html +++ b/stock/templates/registered/fatlinkpersonalstatisticsview.html @@ -16,7 +16,8 @@ {% endif %} - +
+
@@ -32,6 +33,7 @@ {% endfor %}
{% trans "Month" %} {% trans "Fats" %}
+ diff --git a/stock/templates/registered/fatlinkstatisticsview.html b/stock/templates/registered/fatlinkstatisticsview.html index 9fe2349d..bb1aa7cc 100644 --- a/stock/templates/registered/fatlinkstatisticsview.html +++ b/stock/templates/registered/fatlinkstatisticsview.html @@ -16,7 +16,8 @@ {% endif %} - + {% if fatStats %} +
@@ -38,6 +39,7 @@ {% endfor %}
{% trans "Ticker" %}
+ {% endif %} diff --git a/stock/templates/registered/fatlinkview.html b/stock/templates/registered/fatlinkview.html index bd201cc0..69e75f0f 100644 --- a/stock/templates/registered/fatlinkview.html +++ b/stock/templates/registered/fatlinkview.html @@ -22,7 +22,8 @@ - + {% if fats %} +
@@ -44,6 +45,9 @@ {% endfor %}
{% trans "fatname" %} {% trans "Character" %}
+ {% else %} +
No fleet activity on record.
+ {% endif %} {% if perms.auth.fleetactivitytracking%} @@ -64,7 +68,8 @@
- + {% if fatlinks %} +
@@ -89,6 +94,9 @@ {% endfor %}
{% trans "Name" %} {% trans "Creator" %}
+ {% else %} +
No created fatlinks on record.
+ {% endif %} {% endif %} diff --git a/stock/templates/registered/groupmanagement.html b/stock/templates/registered/groupmanagement.html index c2b3ebd5..9f48722d 100644 --- a/stock/templates/registered/groupmanagement.html +++ b/stock/templates/registered/groupmanagement.html @@ -10,59 +10,73 @@ {% block content %}
- - - - - - - - - - - {% for acceptrequest in acceptrequests %} - - - - - - - {% endfor %} -
{% trans "RequestID" %}{% trans "CharacterName" %}{% trans "GroupName" %}{% trans "Action" %}
{{ acceptrequest.id }}{{ acceptrequest.main_char.character_name }}{{ acceptrequest.group.name }} - - {% trans "Accept" %} - - - - {% trans "Reject" %} - -
- - - - - - - - - - {% for leaverequest in leaverequests %} - - - - - - - {% endfor %} -
{% trans "RequestID" %}{% trans "CharacterName" %}{% trans "GroupName" %}{% trans "Action" %}
{{ leaverequest.id }}{{ leaverequest.main_char.character_name }}{{ leaverequest.group.name }} - - {% trans "Accept" %} - - - - {% trans "Reject" %} - -
+ +
+
+
+ {% if acceptrequests %} + + + + + + + + {% for acceptrequest in acceptrequests %} + + + + + + + {% endfor %} +
{% trans "RequestID" %}{% trans "CharacterName" %}{% trans "GroupName" %}{% trans "Action" %}
{{ acceptrequest.id }}{{ acceptrequest.main_char.character_name }}{{ acceptrequest.group.name }} + + {% trans "Accept" %} + + + {% trans "Reject" %} + +
+ {% else %} +
No group add requests.
+ {% endif %} +
+
+
+
+ {% if leaverequests %} + + + + + + + + {% for leaverequest in leaverequests %} + + + + + + + {% endfor %} +
{% trans "RequestID" %}{% trans "CharacterName" %}{% trans "GroupName" %}{% trans "Action" %}
{{ leaverequest.id }}{{ leaverequest.main_char.character_name }}{{ leaverequest.group.name }} + + {% trans "Accept" %} + + + {% trans "Reject" %} + +
+ {% else %} +
No group leave requests.
+ {% endif %} +
+
+
- {% endblock content %} diff --git a/stock/templates/registered/groups.html b/stock/templates/registered/groups.html index ca5ec16e..2581544a 100644 --- a/stock/templates/registered/groups.html +++ b/stock/templates/registered/groups.html @@ -11,9 +11,9 @@

{% trans "Available Groups" %}

{% if STATE == MEMBER_STATE or user.is_superuser %} - + {% if pairs %} +
- @@ -21,7 +21,6 @@ {% for pair in pairs %} - {% endfor %}
{% trans "GroupID" %} {% trans "GroupName" %} {% trans "GroupDesc" %} {% trans "Action" %}
{{ pair.0.id }} {{ pair.0.name }} {{ pair.1.description }} @@ -48,6 +47,9 @@
+ {% else %} +
No groups available.
+ {% endif %} {% else %} {% if IS_CORP %} diff --git a/stock/templates/registered/hrapplicationmanagement.html b/stock/templates/registered/hrapplicationmanagement.html index 660b12eb..f3967698 100755 --- a/stock/templates/registered/hrapplicationmanagement.html +++ b/stock/templates/registered/hrapplicationmanagement.html @@ -10,7 +10,7 @@ {% block content %}
- {% if not STATE == MEMBER_STATE and not user.is_superuser %} + {% if not STATE == MEMBER_STATE %}

{% trans "Personal Applications" %}
{% if create %} @@ -20,7 +20,8 @@ {% endif %}

- + {% if personal_apps %} +
{% endfor %}
{% trans "Username" %} {% trans "Corporation" %} @@ -54,6 +55,7 @@
+ {% endif %} {% endif %} {% if perms.auth.human_resources %}

{% trans "Application Management" %} @@ -71,6 +73,7 @@
+ {% if applications %} @@ -107,10 +110,14 @@ {% endfor %}
{% trans "Date" %}
+ {% else %} +
No pending applications.
+ {% endif %}
+ {% if finished_applications %} @@ -147,6 +154,9 @@ {% endfor %}
{% trans "Date" %}
+ {% else %} +
No reviewed applications.
+ {% endif %}
diff --git a/stock/templates/registered/hrapplicationview.html b/stock/templates/registered/hrapplicationview.html index c07edcf7..88d0e927 100644 --- a/stock/templates/registered/hrapplicationview.html +++ b/stock/templates/registered/hrapplicationview.html @@ -11,17 +11,17 @@

{% trans "View Application" %}

-
+
{% if app.approved %} -
{% trans "Approved" %}
+
{% trans "Approved" %}
{% elif app.approved == False %} -
{% trans "Denied" %}
+
{% trans "Denied" %}
{% else %} -
{% trans "Pending" %}
+
{% trans "Pending" %}
{% endif %} {% if app.reviewer_str %} -
{% trans "Reviewer:" %} {{ app.reviewer_str }}
+
{% trans "Reviewer:" %} {{ app.reviewer_str }}
{% endif %}
diff --git a/stock/templates/registered/notification_list.html b/stock/templates/registered/notification_list.html index 30fa8e0f..d7ea7f5b 100644 --- a/stock/templates/registered/notification_list.html +++ b/stock/templates/registered/notification_list.html @@ -22,6 +22,7 @@
+ {% if unread %} @@ -43,12 +44,16 @@ {% endfor %}
{% trans "Timestamp" %}
+ {% else %} +
No unread notifications.
+ {% endif %}
+ {% if read %} @@ -70,6 +75,9 @@ {% endfor %}
{% trans "Timestamp" %}
+ {% else %} +
No read notifications.
+ {% endif %}
diff --git a/stock/templates/registered/notification_view.html b/stock/templates/registered/notification_view.html index 67b9e92f..872e5ec8 100644 --- a/stock/templates/registered/notification_view.html +++ b/stock/templates/registered/notification_view.html @@ -8,7 +8,14 @@ {% block content %}
-

{% trans "View Notification" %}

+

+ {% trans "View Notification" %} +
+ + + +
+

diff --git a/stock/templates/registered/operationmanagement.html b/stock/templates/registered/operationmanagement.html index f74e539b..34d677a9 100644 --- a/stock/templates/registered/operationmanagement.html +++ b/stock/templates/registered/operationmanagement.html @@ -17,13 +17,14 @@ {% endif %}

-
+
{% trans "Current Eve Time:" %}
-
+
- + {% if optimer %} +
@@ -70,7 +71,9 @@ {% endfor %}
{% trans "Operation Name" %} {% trans "Doctrine" %}
- + {% else %} +
No fleet operations found.
+ {% endif %}
diff --git a/stock/templates/registered/srpfleetadd.html b/stock/templates/registered/srpfleetadd.html index 03795a29..71f4bc2b 100755 --- a/stock/templates/registered/srpfleetadd.html +++ b/stock/templates/registered/srpfleetadd.html @@ -28,6 +28,9 @@ + {% endif %}
diff --git a/stock/templates/registered/srpfleetdata.html b/stock/templates/registered/srpfleetdata.html index ba89d962..aa1ac88a 100755 --- a/stock/templates/registered/srpfleetdata.html +++ b/stock/templates/registered/srpfleetdata.html @@ -34,7 +34,8 @@ {% trans "Total ISK Cost:" %} {{ totalcost | intcomma }} - + {% if srpfleetrequests %} +
@@ -120,6 +121,9 @@ {% endfor %}
{% trans "Pilot Name" %} {% trans "Killboard Link" %}
+ {% else %} +
No SRP requests for this fleet.
+ {% endif %} diff --git a/stock/templates/registered/srpfleetrequest.html b/stock/templates/registered/srpfleetrequest.html index c2824d68..8cc91f18 100755 --- a/stock/templates/registered/srpfleetrequest.html +++ b/stock/templates/registered/srpfleetrequest.html @@ -30,6 +30,9 @@ {% else %} +
+ {% trans 'Continue' %} +
{% endif %} {% endif %} diff --git a/stock/templates/registered/srpmanagement.html b/stock/templates/registered/srpmanagement.html index 288e8d40..7eb7ae4d 100755 --- a/stock/templates/registered/srpmanagement.html +++ b/stock/templates/registered/srpmanagement.html @@ -29,7 +29,8 @@ {% trans "Total ISK Cost:" %} {{ totalcost | intcomma }} - + {% if srpfleets %} +
@@ -117,6 +118,9 @@ {% endfor %}
{% trans "Fleet Name" %} {% trans "Fleet Time" %}
+ {% else %} +
No SRP fleets created.
+ {% endif %} diff --git a/stock/templates/registered/timermanagement.html b/stock/templates/registered/timermanagement.html index 863a602a..de68535d 100755 --- a/stock/templates/registered/timermanagement.html +++ b/stock/templates/registered/timermanagement.html @@ -24,7 +24,7 @@ {% if corp_timers %}

{% trans "Corp Timers" %}

- +
@@ -124,7 +124,8 @@
{% trans "Details" %} {% trans "Objective" %}
{% endif %}

{% trans "Next Timers" %}

- + {% if future_timers %} +
@@ -221,8 +222,12 @@ {% endfor %}
{% trans "Details" %} {% trans "Objective" %}
+ {% else %} +
No upcoming timers.
+ {% endif %}

{% trans "Past Timers" %}

- + {% if past_timers %} +
@@ -320,6 +325,9 @@ {% endfor %}
{% trans "Details" %} {% trans "Objective" %}
+ {% else %} +
No past timers.
+ {% endif %}