Compare commits

...

20 Commits

Author SHA1 Message Date
Basraah
3de7a2ccd2 Version bump to v2.0.5 2018-07-10 02:27:32 +00:00
Basraah
9cc278df31 Merge branch 'corp_stat_fix' into 'master'
Corp Stats update to fix removal of character name endpoints

See merge request allianceauth/allianceauth!1092
2018-07-10 02:01:26 +00:00
Mike
1de3c989d7 fix tests with new endpoints (i think) 2018-06-24 17:41:27 -04:00
Mike
2e547945e2 Corp Stats update to fix removal of character name endpoints 2018-06-24 17:23:08 -04:00
Basraah
5b41d0995f Update README.md badges 2018-06-06 07:12:10 +00:00
Basraah
a7a2ffd16b Add .gitlab-ci.yml 2018-06-06 05:46:35 +00:00
Basraah
dbeda324e0 Update tox.ini for GitLab CI 2018-06-06 05:45:23 +00:00
Adarnof
ee9ed13a66 Remove reference to depreciated bad_gateway model.
Addresses #1078

I too enjoy breaking changes with no warning. Round two.
2018-05-28 17:16:58 -04:00
Stephen Shirley
490ce286ff Add missing <tr> tags for discourse service template 2018-05-26 13:21:39 -04:00
Adarnof
099c2c0a21 Remove reference to depreciated x-user-agent header.
Addresses #1073

I too enjoy breaking changes with no warning.
2018-05-23 22:58:41 -04:00
Peter Pfeufer
46e15f7fa1 German translation corrected
At least the most obvious mistakes ...
2018-05-16 11:20:29 -04:00
Adarnof
6677e63e08 Correct resetting of permission key.
Thanks @Alf-Life
2018-05-11 10:55:56 -04:00
Adarnof
6d6a3a3d6b Allow viewing corpstats added by the user.
Order corpstats by corp name.
2018-05-10 14:25:57 -04:00
colcrunch
5006246cf1 Build TS perm key using State Information (#1044)
Build permkey with state group id
Pass user object to add_user instead of just username

Fixes #1043
2018-05-09 20:39:14 -04:00
Basraah
6187fb9b86 Timer JS fixes (#1054)
Add months to duration output
Update momentjs
Move EVE time generation function to shared source

Fixes timerboard showing EVE time as local time.
Changed to show 24 hour time.
2018-05-09 20:31:02 -04:00
Adarnof
86f57ccd56 Allow reversing service migrations.
This is probably the wrong way as we should really take care of removing the permission we added, but I don't see a reason anyone would need to migrate back that far as auth wouldn't work anymore without XML api (and even so newer installs don't have the settings referenced so permissions are not automagically added by the migration). So noop is bad but acceptable to me.

Thanks @mmolitor87
2018-05-08 10:06:58 -04:00
colcrunch
854096bac7 fix alliancelogo on corp stats page 2018-05-07 23:26:37 -04:00
Adarnof
9d2b3bb157 Include compiled messages.
It doesn't work without these if DEBUG is False. And users can't compile them outside the allianceauth source directory.

When editing translations, compile with: django-admin compilemessages --settings=allianceauth.project_template.project_name.settings.base
2018-05-02 21:42:26 -04:00
Adarnof
22bda62e59 Spanish translations courtesy of @frank1210
Fixed a few problems with translating the menu links - they had leading spaces.
2018-05-02 20:49:21 -04:00
Adarnof
7212a7a328 Example supervisor config for authenticator. Ensure ICE is active in config. 2018-05-01 16:40:37 -04:00
44 changed files with 2503 additions and 508 deletions

1
.gitignore vendored
View File

@@ -42,7 +42,6 @@ nosetests.xml
coverage.xml coverage.xml
# Translations # Translations
*.mo
*.pot *.pot
# Django stuff: # Django stuff:

41
.gitlab-ci.yml Normal file
View File

@@ -0,0 +1,41 @@
# Official language image. Look for the different tagged releases at:
# https://hub.docker.com/r/library/python/tags/
.job_template: &job_definition
# Change pip's cache directory to be inside the project directory since we can
# only cache local items.
variables:
PIP_CACHE_DIR: "$CI_PROJECT_DIR/.cache"
# Pip's cache doesn't store the python packages
# https://pip.pypa.io/en/stable/reference/pip_install/#caching
#
# If you want to also cache the installed packages, you have to install
# them in a virtualenv and cache it as well.
cache:
paths:
- .cache/pip
- venv/
before_script:
- python -V # Print out python version for debugging
- pip install virtualenv tox
- virtualenv venv
- source venv/bin/activate
coverage: '/TOTAL.+ ([0-9]{1,3}%)/'
py36-dj111:
<<: *job_definition
image: python:3.6-stretch
script:
- export TOXENV=py36-dj111
- tox
py36-dj20:
<<: *job_definition
image: python:3.6-stretch
script:
- export TOXENV=py36-dj20
- tox

View File

@@ -3,8 +3,9 @@ Alliance Auth
[![Join the chat at https://gitter.im/R4stl1n/allianceauth](https://badges.gitter.im/R4stl1n/allianceauth.svg)](https://gitter.im/R4stl1n/allianceauth?utm_source=badge&utm_medium=badge&utm_campaign=pr-badge&utm_content=badge) [![Join the chat at https://gitter.im/R4stl1n/allianceauth](https://badges.gitter.im/R4stl1n/allianceauth.svg)](https://gitter.im/R4stl1n/allianceauth?utm_source=badge&utm_medium=badge&utm_campaign=pr-badge&utm_content=badge)
[![Documentation Status](https://readthedocs.org/projects/allianceauth/badge/?version=latest)](http://allianceauth.readthedocs.io/?badge=latest) [![Documentation Status](https://readthedocs.org/projects/allianceauth/badge/?version=latest)](http://allianceauth.readthedocs.io/?badge=latest)
[![Build Status](https://travis-ci.org/allianceauth/allianceauth.svg?branch=master)](https://travis-ci.org/allianceauth/allianceauth) [![pipeline status](https://gitlab.com/allianceauth/allianceauth/badges/master/pipeline.svg)](https://gitlab.com/allianceauth/allianceauth/commits/master)
[![Coverage Status](https://coveralls.io/repos/github/allianceauth/allianceauth/badge.svg?branch=master)](https://coveralls.io/github/allianceauth/allianceauth?branch=master) [![coverage report](https://gitlab.com/allianceauth/allianceauth/badges/master/coverage.svg)](https://gitlab.com/allianceauth/allianceauth/commits/master)
An auth system for EVE Online to help in-game organizations manage online service access. An auth system for EVE Online to help in-game organizations manage online service access.

View File

@@ -1,7 +1,6 @@
# This will make sure the app is always imported when # This will make sure the app is always imported when
# Django starts so that shared_task will use this app. # Django starts so that shared_task will use this app.
__version__ = '2.0.1' __version__ = '2.0.5'
NAME = 'Alliance Auth v%s' % __version__ NAME = 'Alliance Auth v%s' % __version__
default_app_config = 'allianceauth.apps.AllianceAuthConfig' default_app_config = 'allianceauth.apps.AllianceAuthConfig'

View File

@@ -1,5 +1,5 @@
from allianceauth.services.hooks import MenuItemHook, UrlHook from allianceauth.services.hooks import MenuItemHook, UrlHook
from django.utils.translation import ugettext_lazy as _
from allianceauth import hooks from allianceauth import hooks
from allianceauth.corputils import urls from allianceauth.corputils import urls
@@ -7,7 +7,7 @@ from allianceauth.corputils import urls
class CorpStats(MenuItemHook): class CorpStats(MenuItemHook):
def __init__(self): def __init__(self):
MenuItemHook.__init__(self, MenuItemHook.__init__(self,
'Corporation Stats', _('Corporation Stats'),
'fa fa-share-alt fa-fw', 'fa fa-share-alt fa-fw',
'corputils:view', 'corputils:view',
navactive=['corputils:']) navactive=['corputils:'])

View File

@@ -12,6 +12,16 @@ from allianceauth.notifications import notify
from allianceauth.corputils.managers import CorpStatsManager from allianceauth.corputils.managers import CorpStatsManager
SWAGGER_SPEC_PATH = os.path.join(os.path.dirname(os.path.abspath(__file__)), 'swagger.json') SWAGGER_SPEC_PATH = os.path.join(os.path.dirname(os.path.abspath(__file__)), 'swagger.json')
"""
Swagger spec operations:
Character
get_characters_character_id
get_corporations_corporation_id_members
Universe
post_universe_names
"""
logger = logging.getLogger(__name__) logger = logging.getLogger(__name__)
@@ -47,11 +57,11 @@ class CorpStats(models.Model):
# the swagger spec doesn't have a maxItems count # the swagger spec doesn't have a maxItems count
# manual testing says we can do over 350, but let's not risk it # manual testing says we can do over 350, but let's not risk it
member_id_chunks = [member_ids[i:i + 255] for i in range(0, len(member_ids), 255)] member_id_chunks = [member_ids[i:i + 255] for i in range(0, len(member_ids), 255)]
member_name_chunks = [c.Character.get_characters_names(character_ids=id_chunk).result() for id_chunk in member_name_chunks = [c.Universe.post_universe_names(ids=id_chunk).result() for id_chunk in
member_id_chunks] member_id_chunks]
member_list = {} member_list = {}
for name_chunk in member_name_chunks: for name_chunk in member_name_chunks:
member_list.update({m['character_id']: m['character_name'] for m in name_chunk}) member_list.update({m['id']: m['name'] for m in name_chunk})
# bulk create new member models # bulk create new member models
missing_members = [m_id for m_id in member_ids if missing_members = [m_id for m_id in member_ids if

File diff suppressed because one or more lines are too long

View File

@@ -11,7 +11,7 @@
{% if corpstats.corp.alliance %}{% else %}col-lg-offset-3{% endif %}"><img {% if corpstats.corp.alliance %}{% else %}col-lg-offset-3{% endif %}"><img
class="ra-avatar" src="{{ corpstats.corp.logo_url_128 }}"></td> class="ra-avatar" src="{{ corpstats.corp.logo_url_128 }}"></td>
{% if corpstats.corp.alliance %} {% if corpstats.corp.alliance %}
<td class="text-center col-lg-6"><img class="ra-avatar" src="{{ corpstats.alliance.logo_url_128 }}"> <td class="text-center col-lg-6"><img class="ra-avatar" src="{{ corpstats.corp.alliance.logo_url_128 }}">
</td> </td>
{% endif %} {% endif %}
</tr> </tr>
@@ -202,4 +202,4 @@
}); });
}); });
{% endblock %} {% endblock %}

View File

@@ -86,7 +86,7 @@ class CorpStatsUpdateTestCase(TestCase):
def test_update_add_member(self, SwaggerClient): def test_update_add_member(self, SwaggerClient):
SwaggerClient.from_spec.return_value.Character.get_characters_character_id.return_value.result.return_value = {'corporation_id': 2} SwaggerClient.from_spec.return_value.Character.get_characters_character_id.return_value.result.return_value = {'corporation_id': 2}
SwaggerClient.from_spec.return_value.Corporation.get_corporations_corporation_id_members.return_value.result.return_value = [1] SwaggerClient.from_spec.return_value.Corporation.get_corporations_corporation_id_members.return_value.result.return_value = [1]
SwaggerClient.from_spec.return_value.Character.get_characters_names.return_value.result.return_value = [{'character_id': 1, 'character_name': 'test character'}] SwaggerClient.from_spec.return_value.Universe.post_universe_names.return_value.result.return_value = [{'id': 1, 'name': 'test character'}]
self.corpstats.update() self.corpstats.update()
self.assertTrue(CorpMember.objects.filter(character_id='1', character_name='test character', corpstats=self.corpstats).exists()) self.assertTrue(CorpMember.objects.filter(character_id='1', character_name='test character', corpstats=self.corpstats).exists())
@@ -95,7 +95,7 @@ class CorpStatsUpdateTestCase(TestCase):
CorpMember.objects.create(character_id='2', character_name='old test character', corpstats=self.corpstats) CorpMember.objects.create(character_id='2', character_name='old test character', corpstats=self.corpstats)
SwaggerClient.from_spec.return_value.Character.get_characters_character_id.return_value.result.return_value = {'corporation_id': 2} SwaggerClient.from_spec.return_value.Character.get_characters_character_id.return_value.result.return_value = {'corporation_id': 2}
SwaggerClient.from_spec.return_value.Corporation.get_corporations_corporation_id_members.return_value.result.return_value = [1] SwaggerClient.from_spec.return_value.Corporation.get_corporations_corporation_id_members.return_value.result.return_value = [1]
SwaggerClient.from_spec.return_value.Character.get_characters_names.return_value.result.return_value = [{'character_id': 1, 'character_name': 'test character'}] SwaggerClient.from_spec.return_value.Universe.post_universe_names.return_value.result.return_value = [{'id': 1, 'name': 'test character'}]
self.corpstats.update() self.corpstats.update()
self.assertFalse(CorpMember.objects.filter(character_id='2', corpstats=self.corpstats).exists()) self.assertFalse(CorpMember.objects.filter(character_id='2', corpstats=self.corpstats).exists())

View File

@@ -13,11 +13,17 @@ from allianceauth.eveonline.models import EveCharacter, EveCorporationInfo
from .models import CorpStats from .models import CorpStats
SWAGGER_SPEC_PATH = os.path.join(os.path.dirname(os.path.abspath(__file__)), 'swagger.json') SWAGGER_SPEC_PATH = os.path.join(os.path.dirname(os.path.abspath(__file__)), 'swagger.json')
"""
Swagger spec operations:
get_characters_character_id
"""
def access_corpstats_test(user): def access_corpstats_test(user):
return user.has_perm('corputils.view_corp_corpstats') or user.has_perm( return user.has_perm('corputils.view_corp_corpstats') or user.has_perm(
'corputils.view_alliance_corpstats') or user.has_perm('corputils.view_state_corpstats') 'corputils.view_alliance_corpstats') or user.has_perm('corputils.view_state_corpstats') or user.has_perm(
'corputils.add_corpstats')
@login_required @login_required
@@ -62,7 +68,7 @@ def corpstats_view(request, corp_id=None):
corpstats = get_object_or_404(CorpStats, corp=corp) corpstats = get_object_or_404(CorpStats, corp=corp)
# get available models # get available models
available = CorpStats.objects.visible_to(request.user) available = CorpStats.objects.visible_to(request.user).order_by('corp__corporation_name')
# ensure we can see the requested model # ensure we can see the requested model
if corpstats and corpstats not in available: if corpstats and corpstats not in available:

View File

@@ -4,6 +4,16 @@ import logging
import os import os
SWAGGER_SPEC_PATH = os.path.join(os.path.dirname(os.path.abspath(__file__)), 'swagger.json') SWAGGER_SPEC_PATH = os.path.join(os.path.dirname(os.path.abspath(__file__)), 'swagger.json')
"""
Swagger spec operations:
get_alliances_alliance_id
get_alliances_alliance_id_corporations
get_corporations_corporation_id
get_characters_character_id
get_universe_types_type_id
"""
logger = logging.getLogger(__name__) logger = logging.getLogger(__name__)

File diff suppressed because one or more lines are too long

View File

@@ -1,12 +1,12 @@
from . import urls from . import urls
from django.utils.translation import ugettext_lazy as _
from allianceauth import hooks from allianceauth import hooks
from allianceauth.services.hooks import MenuItemHook, UrlHook from allianceauth.services.hooks import MenuItemHook, UrlHook
@hooks.register('menu_item_hook') @hooks.register('menu_item_hook')
def register_menu(): def register_menu():
return MenuItemHook('Fleet Activity Tracking', 'fa fa-users fa-lightbulb-o fa-fw', 'fatlink:view', return MenuItemHook(_('Fleet Activity Tracking'), 'fa fa-users fa-lightbulb-o fa-fw', 'fatlink:view',
navactive=['fatlink:']) navactive=['fatlink:'])

File diff suppressed because one or more lines are too long

View File

@@ -22,6 +22,16 @@ from allianceauth.eveonline.models import EveCharacter
from allianceauth.eveonline.models import EveCorporationInfo from allianceauth.eveonline.models import EveCorporationInfo
SWAGGER_SPEC_PATH = os.path.join(os.path.dirname(os.path.abspath(__file__)), 'swagger.json') SWAGGER_SPEC_PATH = os.path.join(os.path.dirname(os.path.abspath(__file__)), 'swagger.json')
"""
Swagger spec operations:
get_characters_character_id_location
get_characters_character_id_ship
get_universe_systems_system_id
get_universe_stations_station_id
get_universe_structures_structure_id
"""
logger = logging.getLogger(__name__) logger = logging.getLogger(__name__)

View File

@@ -1,5 +1,5 @@
from allianceauth.services.hooks import MenuItemHook, UrlHook from allianceauth.services.hooks import MenuItemHook, UrlHook
from django.utils.translation import ugettext_lazy as _
from allianceauth import hooks from allianceauth import hooks
from allianceauth.hrapplications import urls from allianceauth.hrapplications import urls
@@ -7,7 +7,7 @@ from allianceauth.hrapplications import urls
class ApplicationsMenu(MenuItemHook): class ApplicationsMenu(MenuItemHook):
def __init__(self): def __init__(self):
MenuItemHook.__init__(self, MenuItemHook.__init__(self,
'Applications', _('Applications'),
'fa fa-file-o fa-fw', 'fa fa-file-o fa-fw',
'hrapplications:index', 'hrapplications:index',
navactive=['hrapplications:']) navactive=['hrapplications:'])

Binary file not shown.

File diff suppressed because it is too large Load Diff

Binary file not shown.

File diff suppressed because it is too large Load Diff

View File

@@ -1,12 +1,12 @@
from allianceauth.services.hooks import MenuItemHook, UrlHook from allianceauth.services.hooks import MenuItemHook, UrlHook
from django.utils.translation import ugettext_lazy as _
from allianceauth import hooks from allianceauth import hooks
from . import urls from . import urls
class OpTimerboardMenu(MenuItemHook): class OpTimerboardMenu(MenuItemHook):
def __init__(self): def __init__(self):
MenuItemHook.__init__(self, 'Fleet Operations', MenuItemHook.__init__(self, _('Fleet Operations'),
'fa fa-exclamation fa-fw', 'fa fa-exclamation fa-fw',
'optimer:view', 'optimer:view',
navactive=['optimer:']) navactive=['optimer:'])

View File

@@ -19,7 +19,8 @@
<div class="col-lg-12 text-center row"> <div class="col-lg-12 text-center row">
<div class="label label-info text-left"> <div class="label label-info text-left">
<b>{% trans "Current Eve Time:" %} </b> <b>{% trans "Current Eve Time:" %} </b>
</div><div class="label label-info text-left" id="current-time"></div> </div>
<strong class="label label-info text-left" id="current-time"></strong>
<br /> <br />
</div> </div>
@@ -111,7 +112,7 @@
} }
function updateClock() { function updateClock() {
document.getElementById("current-time").innerHTML = "<b>" + moment.utc().format('LLLL') + "</b>"; document.getElementById("current-time").innerHTML = getCurrentEveTimeString();
} }
</script> </script>
{% endblock content %} {% endblock content %}

View File

@@ -82,6 +82,7 @@ ugettext = lambda s: s
LANGUAGES = ( LANGUAGES = (
('en', ugettext('English')), ('en', ugettext('English')),
('de', ugettext('German')), ('de', ugettext('German')),
('es', ugettext('Spanish')),
) )
TEMPLATES = [ TEMPLATES = [
@@ -193,6 +194,8 @@ LOGIN_TOKEN_SCOPES = ['publicData']
# number of days email verification links are valid for # number of days email verification links are valid for
ACCOUNT_ACTIVATION_DAYS = 1 ACCOUNT_ACTIVATION_DAYS = 1
ESI_API_URL = 'https://esi.evetech.net/'
LOGGING = { LOGGING = {
'version': 1, 'version': 1,
'disable_existing_loggers': False, 'disable_existing_loggers': False,

View File

@@ -57,5 +57,5 @@ class Migration(migrations.Migration):
name='discorduser', name='discorduser',
options={'permissions': (('access_discord', 'Can access the Discord service'),)}, options={'permissions': (('access_discord', 'Can access the Discord service'),)},
), ),
migrations.RunPython(migrate_service_enabled), migrations.RunPython(migrate_service_enabled, migrations.RunPython.noop),
] ]

View File

@@ -58,5 +58,5 @@ class Migration(migrations.Migration):
name='discourseuser', name='discourseuser',
options={'permissions': (('access_discourse', 'Can access the Discourse service'),)}, options={'permissions': (('access_discourse', 'Can access the Discourse service'),)},
), ),
migrations.RunPython(migrate_service_enabled), migrations.RunPython(migrate_service_enabled, migrations.RunPython.noop),
] ]

View File

@@ -1,8 +1,10 @@
{% load i18n %} {% load i18n %}
<td class="text-center">Discourse</td> <tr>
<td class="text-center">{{ char.character_name }}</td> <td class="text-center">Discourse</td>
<td class="text-center"><a href="{{ DISCOURSE_URL }}">{{ DISCOURSE_URL }}</a></td> <td class="text-center">{{ char.character_name }}</td>
<td class="text-center"> <td class="text-center"><a href="{{ DISCOURSE_URL }}">{{ DISCOURSE_URL }}</a></td>
<a title="Go To Forums" class="btn btn-success" href="{{ DISCOURSE_URL }}"><span class="glyphicon glyphicon-arrow-right"></span></a> <td class="text-center">
</td> <a title="Go To Forums" class="btn btn-success" href="{{ DISCOURSE_URL }}"><span class="glyphicon glyphicon-arrow-right"></span></a>
</td>
</tr>

View File

@@ -57,5 +57,5 @@ class Migration(migrations.Migration):
name='ips4user', name='ips4user',
options={'permissions': (('access_ips4', 'Can access the IPS4 service'),)}, options={'permissions': (('access_ips4', 'Can access the IPS4 service'),)},
), ),
migrations.RunPython(migrate_service_enabled), migrations.RunPython(migrate_service_enabled, migrations.RunPython.noop),
] ]

View File

@@ -57,5 +57,5 @@ class Migration(migrations.Migration):
name='marketuser', name='marketuser',
options={'permissions': (('access_market', 'Can access the Evernus Market service'),)}, options={'permissions': (('access_market', 'Can access the Evernus Market service'),)},
), ),
migrations.RunPython(migrate_service_enabled), migrations.RunPython(migrate_service_enabled, migrations.RunPython.noop),
] ]

View File

@@ -57,5 +57,5 @@ class Migration(migrations.Migration):
name='mumbleuser', name='mumbleuser',
options={'permissions': (('access_mumble', 'Can access the Mumble service'),)}, options={'permissions': (('access_mumble', 'Can access the Mumble service'),)},
), ),
migrations.RunPython(migrate_service_enabled), migrations.RunPython(migrate_service_enabled, migrations.RunPython.noop),
] ]

View File

@@ -57,5 +57,5 @@ class Migration(migrations.Migration):
name='openfireuser', name='openfireuser',
options={'permissions': (('access_openfire', 'Can access the Openfire service'),)}, options={'permissions': (('access_openfire', 'Can access the Openfire service'),)},
), ),
migrations.RunPython(migrate_service_enabled), migrations.RunPython(migrate_service_enabled, migrations.RunPython.noop),
] ]

View File

@@ -57,5 +57,5 @@ class Migration(migrations.Migration):
name='phpbb3user', name='phpbb3user',
options={'permissions': (('access_phpbb3', 'Can access the phpBB3 service'),)}, options={'permissions': (('access_phpbb3', 'Can access the phpBB3 service'),)},
), ),
migrations.RunPython(migrate_service_enabled), migrations.RunPython(migrate_service_enabled, migrations.RunPython.noop),
] ]

View File

@@ -57,5 +57,5 @@ class Migration(migrations.Migration):
name='smfuser', name='smfuser',
options={'permissions': (('access_smf', 'Can access the SMF service'),)}, options={'permissions': (('access_smf', 'Can access the SMF service'),)},
), ),
migrations.RunPython(migrate_service_enabled), migrations.RunPython(migrate_service_enabled, migrations.RunPython.noop),
] ]

View File

@@ -179,18 +179,19 @@ class Teamspeak3Manager:
except: except:
logger.exception("An unhandled exception has occured while syncing TS groups.") logger.exception("An unhandled exception has occured while syncing TS groups.")
def add_user(self, username): def add_user(self, user, fmt_name):
username_clean = self.__santatize_username(username[:30]) username_clean = self.__santatize_username(fmt_name[:30])
logger.debug("Adding user to TS3 server with cleaned username %s" % username_clean) logger.debug("Adding user to TS3 server with cleaned username %s" % username_clean)
server_groups = self._group_list() server_groups = self._group_list()
if 'Member' not in server_groups: state = user.profile.state.name
self._create_group('Member') if state not in server_groups:
self._create_group(state)
alliance_group_id = self._group_id_by_name('Member') state_group_id = self._group_id_by_name(state)
try: try:
ret = self.server.send_command('tokenadd', {'tokentype': 0, 'tokenid1': alliance_group_id, 'tokenid2': 0, ret = self.server.send_command('tokenadd', {'tokentype': 0, 'tokenid1': state_group_id, 'tokenid2': 0,
'tokendescription': username_clean, 'tokendescription': username_clean,
'tokencustomset': "ident=sso_uid value=%s" % username_clean}) 'tokencustomset': "ident=sso_uid value=%s" % username_clean})
except TeamspeakError as e: except TeamspeakError as e:
@@ -244,10 +245,10 @@ class Teamspeak3Manager:
return False return False
def generate_new_permissionkey(self, uid, username): def generate_new_permissionkey(self, uid, user, username):
logger.debug("Re-issuing permission key for user id %s" % uid) logger.debug("Re-issuing permission key for user id %s" % uid)
self.delete_user(uid) self.delete_user(uid)
return self.add_user(username) return self.add_user(user, username)
def update_groups(self, uid, ts_groups): def update_groups(self, uid, ts_groups):
logger.debug("Updating uid %s TS3 groups %s" % (uid, ts_groups)) logger.debug("Updating uid %s TS3 groups %s" % (uid, ts_groups))

View File

@@ -57,5 +57,5 @@ class Migration(migrations.Migration):
name='teamspeak3user', name='teamspeak3user',
options={'permissions': (('access_teamspeak3', 'Can access the Teamspeak3 service'),)}, options={'permissions': (('access_teamspeak3', 'Can access the Teamspeak3 service'),)},
), ),
migrations.RunPython(migrate_service_enabled), migrations.RunPython(migrate_service_enabled, migrations.RunPython.noop),
] ]

View File

@@ -22,7 +22,7 @@ def activate_teamspeak3(request):
character = request.user.profile.main_character character = request.user.profile.main_character
with Teamspeak3Manager() as ts3man: with Teamspeak3Manager() as ts3man:
logger.debug("Adding TS3 user for user %s with main character %s" % (request.user, character)) logger.debug("Adding TS3 user for user %s with main character %s" % (request.user, character))
result = ts3man.add_user(Teamspeak3Tasks.get_username(request.user)) result = ts3man.add_user(request.user, Teamspeak3Tasks.get_username(request.user))
# if its empty we failed # if its empty we failed
if result[0] is not "": if result[0] is not "":
@@ -79,13 +79,12 @@ def reset_teamspeak3_perm(request):
logger.debug("reset_teamspeak3_perm called by user %s" % request.user) logger.debug("reset_teamspeak3_perm called by user %s" % request.user)
if not Teamspeak3Tasks.has_account(request.user): if not Teamspeak3Tasks.has_account(request.user):
return redirect("services:services") return redirect("services:services")
character = request.user.profile.main_character
logger.debug("Deleting TS3 user for user %s" % request.user) logger.debug("Deleting TS3 user for user %s" % request.user)
with Teamspeak3Manager() as ts3man: with Teamspeak3Manager() as ts3man:
ts3man.delete_user(request.user.teamspeak3.uid) ts3man.delete_user(request.user.teamspeak3.uid)
logger.debug("Generating new permission key for user %s with main character %s" % (request.user, character)) logger.debug("Generating new permission key for user %s" % request.user)
result = ts3man.generate_new_permissionkey(request.user.teamspeak3.uid, character.character_name) result = ts3man.generate_new_permissionkey(request.user.teamspeak3.uid, request.user, Teamspeak3Tasks.get_username(request.user))
# if blank we failed # if blank we failed
if result[0] != "": if result[0] != "":

View File

@@ -57,5 +57,5 @@ class Migration(migrations.Migration):
name='xenforouser', name='xenforouser',
options={'permissions': (('access_xenforo', 'Can access the XenForo service'),)}, options={'permissions': (('access_xenforo', 'Can access the XenForo service'),)},
), ),
migrations.RunPython(migrate_service_enabled), migrations.RunPython(migrate_service_enabled, migrations.RunPython.noop),
] ]

View File

@@ -1,12 +1,12 @@
from allianceauth.services.hooks import MenuItemHook, UrlHook from allianceauth.services.hooks import MenuItemHook, UrlHook
from django.utils.translation import ugettext_lazy as _
from allianceauth import hooks from allianceauth import hooks
from . import urls from . import urls
class SrpMenu(MenuItemHook): class SrpMenu(MenuItemHook):
def __init__(self): def __init__(self):
MenuItemHook.__init__(self, 'Ship Replacement', MenuItemHook.__init__(self, _('Ship Replacement'),
'fa fa-money fa-fw', 'fa fa-money fa-fw',
'srp:management', 'srp:management',
navactive=['srp:']) navactive=['srp:'])

View File

@@ -8,8 +8,16 @@ function getDurationString(duration) {
if (duration.years()) { if (duration.years()) {
out += duration.years() + 'y '; out += duration.years() + 'y ';
} }
if (duration.months()) {
out += duration.months() + 'm ';
}
if (duration.days()) { if (duration.days()) {
out += duration.days() + 'd '; out += duration.days() + 'd ';
} }
return out + duration.hours() + "h " + duration.minutes() + "m " + duration.seconds() + "s"; return out + duration.hours() + "h " + duration.minutes() + "m " + duration.seconds() + "s";
} }
function getCurrentEveTimeString() {
return moment().utc().format('dddd LL HH:mm:ss')
}

View File

@@ -1,11 +1,12 @@
{% extends "allianceauth/base.html" %} {% extends "allianceauth/base.html" %}
{% load i18n %}
{% block page_title %}Help{% endblock page_title %} {% block page_title %}{% trans "Help" %}{% endblock page_title %}
{% block content %} {% block content %}
<div class="col-lg-12"> <div class="col-lg-12">
<h1 class="page-header text-center">Help</h1> <h1 class="page-header text-center">{% trans "Help" %}</h1>
<div class="container-fluid"> <div class="container-fluid">
<div class="embed-responsive embed-responsive-16by9"> <div class="embed-responsive embed-responsive-16by9">

View File

@@ -7,12 +7,12 @@
<li> <li>
<a class="{% navactive request 'authentication:dashboard' %}" <a class="{% navactive request 'authentication:dashboard' %}"
href="{% url 'authentication:dashboard' %}"> href="{% url 'authentication:dashboard' %}">
<i class="fa fa-dashboard fa-fw"></i>{% trans " Dashboard" %} <i class="fa fa-dashboard fa-fw"></i> {% trans "Dashboard" %}
</a> </a>
</li> </li>
<li> <li>
<a class="{% navactive request 'groupmanagement:groups' %}" href="{% url 'groupmanagement:groups' %}"> <a class="{% navactive request 'groupmanagement:groups' %}" href="{% url 'groupmanagement:groups' %}">
<i class="fa fa-cogs fa-fw fa-sitemap"></i>{% trans " Groups" %} <i class="fa fa-cogs fa-fw fa-sitemap"></i> {% trans "Groups" %}
</a> </a>
</li> </li>
@@ -20,7 +20,7 @@
<li> <li>
<a class="{% navactive request 'groupmanagement:management groupmanagement:membership groupmanagement:membership_list' %}" <a class="{% navactive request 'groupmanagement:management groupmanagement:membership groupmanagement:membership_list' %}"
href="{% url 'groupmanagement:management' %}"> href="{% url 'groupmanagement:management' %}">
<i class="fa fa-lock fa-sitemap fa-fw"></i>{% trans " Group Management" %} <i class="fa fa-lock fa-sitemap fa-fw"></i> {% trans "Group Management" %}
</a> </a>
</li> </li>
{% endif %} {% endif %}
@@ -30,7 +30,7 @@
<li> <li>
<a class="{% navactive request 'authentication:help' %}" <a class="{% navactive request 'authentication:help' %}"
href="{% url 'authentication:help' %}"> href="{% url 'authentication:help' %}">
<i class="fa fa-question fa-fw"></i>{% trans " Help" %} <i class="fa fa-question fa-fw"></i> {% trans "Help" %}
</a> </a>
</li> </li>
</ul> </ul>

View File

@@ -1,4 +1,4 @@
<script src="https://cdnjs.cloudflare.com/ajax/libs/moment.js/2.17.1/moment.min.js"></script> <script src="https://cdnjs.cloudflare.com/ajax/libs/moment.js/2.22.1/moment.min.js"></script>
{% if locale and LANGUAGE_CODE != 'en' %} {% if locale and LANGUAGE_CODE != 'en' %}
<script src="https://cdnjs.cloudflare.com/ajax/libs/moment.js/2.17.1/locale/{{ LANGUAGE_CODE }}.js"></script> <script src="https://cdnjs.cloudflare.com/ajax/libs/moment.js/2.22.1/locale/{{ LANGUAGE_CODE }}.js"></script>
{% endif %} {% endif %}

View File

@@ -18,7 +18,8 @@
<div class="col-lg-12 text-center"> <div class="col-lg-12 text-center">
<div class="label label-info text-left"> <div class="label label-info text-left">
<b>{% trans "Current Eve Time:" %} </b> <b>{% trans "Current Eve Time:" %} </b>
</div><div class="label label-info text-left" id="current-time"></div> </div>
<strong class="label label-info text-left" id="current-time"></strong>
</div> </div>
{% if corp_timers %} {% if corp_timers %}
<h4><b>{% trans "Corp Timers" %}</b></h4> <h4><b>{% trans "Corp Timers" %}</b></h4>
@@ -555,7 +556,7 @@
} }
function updateClock() { function updateClock() {
document.getElementById("current-time").innerHTML = "<b>" + moment().format('LLLL') + "</b>"; document.getElementById("current-time").innerHTML = getCurrentEveTimeString();
} }
</script> </script>
{% endblock content %} {% endblock content %}

View File

@@ -34,6 +34,7 @@ Mumble ships with a configuration file that needs customization. By default it
REQUIRED: To enable the ICE authenticator, edit the following: REQUIRED: To enable the ICE authenticator, edit the following:
- `icesecretwrite=MY_CLEVER_PASSWORD`, obviously choosing a secure password - `icesecretwrite=MY_CLEVER_PASSWORD`, obviously choosing a secure password
- ensure the line containing `Ice="tcp -h 127.0.0.1 -p 6502"` is uncommented
By default mumble operates on SQLite which is fine, but slower than a dedicated MySQL server. To customize the database, edit the following: By default mumble operates on SQLite which is fine, but slower than a dedicated MySQL server. To customize the database, edit the following:
@@ -46,7 +47,7 @@ By default mumble operates on SQLite which is fine, but slower than a dedicated
To name your root channel, uncomment and set `registerName=` to whatever cool name you want To name your root channel, uncomment and set `registerName=` to whatever cool name you want
Save and close the file (control + O, control + X). Save and close the file.
To get Mumble superuser account credentials, run the following: To get Mumble superuser account credentials, run the following:
@@ -80,7 +81,21 @@ Test your configuration by starting it: `python authenticator.py`
## Running the Authenticator ## Running the Authenticator
The authenticator needs to be running 24/7 to validate users on Mumble. You should check the [supervisor docs](../auth/supervisor.md) on how to achieve this. The authenticator needs to be running 24/7 to validate users on Mumble. This can be achieved by adding a section to your auth project's supervisor config file like the following example:
```
[program:authenticator]
command=/path/to/venv/bin/python authenticator.py
directory=/path/to/authenticator/directory/
user=allianceserver
stdout_logfile=/path/to/authenticator/directory/authenticator.log
stderr_logfile=/path/to/authenticator/directory/authenticator.log
autostart=true
autorestart=true
startsecs=10
priority=998
```
Note that groups will only be created on Mumble automatically when a user joins who is in the group. Note that groups will only be created on Mumble automatically when a user joins who is in the group.

View File

@@ -17,4 +17,6 @@ deps=
py37: https://github.com/yaml/pyyaml/zipball/master#egg=pyyaml py37: https://github.com/yaml/pyyaml/zipball/master#egg=pyyaml
py37: https://github.com/celery/kombu/zipball/master#egg=kombu py37: https://github.com/celery/kombu/zipball/master#egg=kombu
install_command = pip install -e ".[testing]" -U {opts} {packages} install_command = pip install -e ".[testing]" -U {opts} {packages}
commands=coverage run runtests.py -v 2 commands =
coverage run runtests.py -v 2
coverage report -m