diff --git a/allianceauth/locale/es/LC_MESSAGES/django.po b/allianceauth/locale/es/LC_MESSAGES/django.po index a6787958..3d7fec13 100644 --- a/allianceauth/locale/es/LC_MESSAGES/django.po +++ b/allianceauth/locale/es/LC_MESSAGES/django.po @@ -1443,56 +1443,6 @@ msgstr "Ping Enviado" msgid "Broadcast" msgstr "" -#: allianceauth/services/modules/seat/views.py:40 -#, python-format -msgid "Successfully activated your %(service)s account." -msgstr "Se activo con exito el %(service)s en tu cuenta." - -#: allianceauth/services/modules/seat/views.py:49 -#, python-format -msgid "" -"Failed to activate your %(service)s account, please contact your " -"administrator." -msgstr "Fallo al activar el %(service)s en tu cuenta, por favor contacta a tu administrador." - -#: allianceauth/services/modules/seat/views.py:62 -#, python-format -msgid "Successfully deactivated your %(service)s account." -msgstr "Se desactivo el servicio %(service)s con exito." - -#: allianceauth/services/modules/seat/views.py:68 -#, python-format -msgid "" -"Failed to deactivate your %(service)s account, please contact your " -"administrator." -msgstr "Fallo al desactivar el servicio %(service)s, por favor contacta a tu administrador." - -#: allianceauth/services/modules/seat/views.py:87 -#, python-format -msgid "Successfully reset your %(service)s password." -msgstr "Se restablecio con exito tu contraseña del servicio %(service)s." - -#: allianceauth/services/modules/seat/views.py:93 -#, python-format -msgid "" -"Failed to reset your %(service)s password, please contact your administrator." -msgstr "Fallo al restablecer tu contraseña en el servicio %(service)s, por favor contacta a tu adminsitrador." - -#: allianceauth/services/modules/seat/views.py:114 -#, python-format -msgid "Successfully set your %(service)s password." -msgstr "Se cambio con exito tu contraseña en el servicio %(service)s" - -#: allianceauth/services/modules/seat/views.py:119 -#, python-format -msgid "" -"Failed to set your %(service)s password, please contact your administrator." -msgstr "Fallo al cambiar tu contraseña en %(service)s, por favor contacta a tu administrador." - -#: allianceauth/services/modules/seat/views.py:123 -msgid "Invalid password." -msgstr "Contraseña invalida." - #: allianceauth/services/modules/teamspeak3/forms.py:14 #, python-format msgid "Unable to locate user %s on server" diff --git a/allianceauth/services/modules/market/__init__.py b/allianceauth/services/modules/market/__init__.py deleted file mode 100644 index 35e7d1ed..00000000 --- a/allianceauth/services/modules/market/__init__.py +++ /dev/null @@ -1 +0,0 @@ -default_app_config = 'allianceauth.services.modules.market.apps.MarketServiceConfig' diff --git a/allianceauth/services/modules/market/admin.py b/allianceauth/services/modules/market/admin.py deleted file mode 100644 index 75e0a9e9..00000000 --- a/allianceauth/services/modules/market/admin.py +++ /dev/null @@ -1,9 +0,0 @@ -from django.contrib import admin -from .models import MarketUser - - -class MarketUserAdmin(admin.ModelAdmin): - list_display = ('user', 'username') - search_fields = ('user__username', 'username') - -admin.site.register(MarketUser, MarketUserAdmin) diff --git a/allianceauth/services/modules/market/apps.py b/allianceauth/services/modules/market/apps.py deleted file mode 100644 index 13a77d38..00000000 --- a/allianceauth/services/modules/market/apps.py +++ /dev/null @@ -1,6 +0,0 @@ -from django.apps import AppConfig - - -class MarketServiceConfig(AppConfig): - name = 'allianceauth.services.modules.market' - label = 'market' diff --git a/allianceauth/services/modules/market/auth_hooks.py b/allianceauth/services/modules/market/auth_hooks.py deleted file mode 100644 index 472f8574..00000000 --- a/allianceauth/services/modules/market/auth_hooks.py +++ /dev/null @@ -1,54 +0,0 @@ -import logging - -from django.conf import settings -from django.template.loader import render_to_string - -from allianceauth import hooks -from allianceauth.services.hooks import ServicesHook -from .tasks import MarketTasks -from .urls import urlpatterns - -logger = logging.getLogger(__name__) - - -class MarketService(ServicesHook): - def __init__(self): - ServicesHook.__init__(self) - self.name = 'market' - self.urlpatterns = urlpatterns - self.service_url = settings.MARKET_URL - self.access_perm = 'market.access_market' - - @property - def title(self): - return "Alliance Market" - - def delete_user(self, user, notify_user=False): - logger.debug('Deleting user %s %s account' % (user, self.name)) - return MarketTasks.delete_user(user, notify_user=notify_user) - - def validate_user(self, user): - logger.debug('Validating user %s %s account' % (user, self.name)) - if MarketTasks.has_account(user) and not self.service_active_for_user(user): - self.delete_user(user) - - def service_active_for_user(self, user): - return user.has_perm(self.access_perm) - - def render_services_ctrl(self, request): - urls = self.Urls() - urls.auth_activate = 'evernusmarket:activate' - urls.auth_deactivate = 'evernusmarket:deactivate' - urls.auth_reset_password = 'evernusmarket:reset_password' - urls.auth_set_password = 'evernusmarket:set_password' - return render_to_string(self.service_ctrl_template, { - 'service_name': self.title, - 'urls': urls, - 'service_url': self.service_url, - 'username': request.user.market.username if MarketTasks.has_account(request.user) else '' - }, request=request) - - -@hooks.register('services_hook') -def register_service(): - return MarketService() diff --git a/allianceauth/services/modules/market/manager.py b/allianceauth/services/modules/market/manager.py deleted file mode 100644 index 0953de3d..00000000 --- a/allianceauth/services/modules/market/manager.py +++ /dev/null @@ -1,152 +0,0 @@ -import logging -import random -import string -import re - -from django.db import connections -from passlib.hash import bcrypt -from django.conf import settings - -# requires yum install libffi-devel and pip install bcrypt - -logger = logging.getLogger(__name__) - - -TABLE_PREFIX = getattr(settings, 'MARKET_TABLE_PREFIX', 'fos_') - - -class MarketManager: - def __init__(self): - pass - - SQL_ADD_USER = r"INSERT INTO %suser (username, username_canonical, email, email_canonical, enabled, salt," \ - r"password, locked, expired, roles, credentials_expired, characterid, characterName)" \ - r"VALUES (%%s, %%s, %%s, %%s, 1,%%s, %%s, 0, 0, 'a:0:{}', 0, %%s, %%s) " % TABLE_PREFIX - SQL_GET_USER_ID = r"SELECT id FROM %suser WHERE username = %%s" % TABLE_PREFIX - SQL_DISABLE_USER = r"UPDATE %suser SET enabled = '0' WHERE username = %%s" % TABLE_PREFIX - SQL_ENABLE_USER = r"UPDATE %suser SET enabled = '1' WHERE username = %%s" % TABLE_PREFIX - SQL_UPDATE_PASSWORD = r"UPDATE %suser SET password = %%s, salt = %%s WHERE username = %%s" % TABLE_PREFIX - SQL_CHECK_EMAIL = r"SELECT email FROM %suser WHERE email = %%s" % TABLE_PREFIX - SQL_CHECK_USERNAME = r"SELECT username FROM %suser WHERE username = %%s" % TABLE_PREFIX - SQL_UPDATE_USER = r"UPDATE %suser SET password = %%s, salt = %%s, enabled = '1' WHERE username = %%s" % TABLE_PREFIX - - @staticmethod - def __santatize_username(username): - sanatized = username.replace(" ", "_") - return sanatized.lower() - - @staticmethod - def __generate_random_pass(): - return ''.join([random.choice(string.ascii_letters + string.digits) for n in range(16)]) - - @staticmethod - def _gen_pwhash(password): - return bcrypt.using(ident='2y').encrypt(password.encode('utf-8'), rounds=13) - - @staticmethod - def _get_salt(pw_hash): - search = re.compile(r"^\$2[a-z]?\$([0-9]+)\$(.{22})(.{31})$") - match = re.match(search, pw_hash) - return match.group(2) - - @classmethod - def check_username(cls, username): - logger.debug("Checking alliance market username %s" % username) - cursor = connections['market'].cursor() - cursor.execute(cls.SQL_CHECK_USERNAME, [cls.__santatize_username(username)]) - row = cursor.fetchone() - if row: - logger.debug("Found user %s on alliance market" % username) - return True - logger.debug("User %s not found on alliance market" % username) - return False - - @classmethod - def check_user_email(cls, username, email): - logger.debug("Checking if alliance market email exists for user %s" % username) - cursor = connections['market'].cursor() - cursor.execute(cls.SQL_CHECK_EMAIL, [email]) - row = cursor.fetchone() - if row: - logger.debug("Found user %s email address on alliance market" % username) - return True - logger.debug("User %s email address not found on alliance market" % username) - return False - - @classmethod - def add_user(cls, username, email, characterid, charactername): - logger.debug("Adding new market user %s" % username) - plain_password = cls.__generate_random_pass() - hash = cls._gen_pwhash(plain_password) - salt = cls._get_salt(hash) - username_clean = cls.__santatize_username(username) - if not cls.check_username(username): - if not cls.check_user_email(username, email): - try: - logger.debug("Adding user %s to alliance market" % username) - cursor = connections['market'].cursor() - cursor.execute(cls.SQL_ADD_USER, [username_clean, username_clean, email, email, salt, - hash, characterid, charactername]) - return username_clean, plain_password - except: - logger.debug("Unsuccessful attempt to add market user %s" % username) - return "", "" - else: - logger.debug("Alliance market email %s already exists Updating instead" % email) - username_clean, password = cls.update_user_info(username) - return username_clean, password - else: - logger.debug("Alliance market username %s already exists Updating instead" % username) - username_clean, password = cls.update_user_info(username) - return username_clean, password - - @classmethod - def disable_user(cls, username): - logger.debug("Disabling alliance market user %s " % username) - cursor = connections['market'].cursor() - cursor.execute(cls.SQL_DISABLE_USER, [username]) - return True - - @classmethod - def update_custom_password(cls, username, plain_password): - logger.debug("Updating alliance market user %s password" % username) - if cls.check_username(username): - username_clean = cls.__santatize_username(username) - hash = cls._gen_pwhash(plain_password) - salt = cls._get_salt(hash) - cursor = connections['market'].cursor() - cursor.execute(cls.SQL_UPDATE_PASSWORD, [hash, salt, username_clean]) - return plain_password - else: - logger.error("Unable to update alliance market user %s password" % username) - return "" - - @classmethod - def update_user_password(cls, username): - logger.debug("Updating alliance market user %s password" % username) - if cls.check_username(username): - username_clean = cls.__santatize_username(username) - plain_password = cls.__generate_random_pass() - hash = cls._gen_pwhash(plain_password) - salt = cls._get_salt(hash) - cursor = connections['market'].cursor() - cursor.execute(cls.SQL_UPDATE_PASSWORD, [hash, salt, username_clean]) - return plain_password - else: - logger.error("Unable to update alliance market user %s password" % username) - return "" - - @classmethod - def update_user_info(cls, username): - logger.debug("Updating alliance market user %s" % username) - try: - username_clean = cls.__santatize_username(username) - plain_password = cls.__generate_random_pass() - hash = cls._gen_pwhash(plain_password) - salt = cls._get_salt(hash) - cursor = connections['market'].cursor() - cursor.execute(cls.SQL_UPDATE_USER, [hash, salt, username_clean]) - return username_clean, plain_password - except: - logger.debug("Alliance market update user failed for %s" % username) - return "", "" diff --git a/allianceauth/services/modules/market/migrations/0001_initial.py b/allianceauth/services/modules/market/migrations/0001_initial.py deleted file mode 100644 index 1e306c9f..00000000 --- a/allianceauth/services/modules/market/migrations/0001_initial.py +++ /dev/null @@ -1,26 +0,0 @@ -# -*- coding: utf-8 -*- -# Generated by Django 1.10.2 on 2016-12-12 03:27 -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): - - initial = True - - dependencies = [ - ('auth', '0008_alter_user_username_max_length'), - ] - - operations = [ - migrations.CreateModel( - name='MarketUser', - fields=[ - ('user', models.OneToOneField(on_delete=django.db.models.deletion.CASCADE, primary_key=True, related_name='market', serialize=False, to=settings.AUTH_USER_MODEL)), - ('username', models.CharField(max_length=254)), - ], - ), - ] diff --git a/allianceauth/services/modules/market/migrations/0002_service_permissions.py b/allianceauth/services/modules/market/migrations/0002_service_permissions.py deleted file mode 100644 index 76861713..00000000 --- a/allianceauth/services/modules/market/migrations/0002_service_permissions.py +++ /dev/null @@ -1,61 +0,0 @@ -# -*- coding: utf-8 -*- -# Generated by Django 1.10.5 on 2017-02-02 05:59 -from __future__ import unicode_literals - -from django.db import migrations -from django.conf import settings -from django.core.exceptions import ObjectDoesNotExist -from django.contrib.auth.management import create_permissions - -import logging - -logger = logging.getLogger(__name__) - - -def migrate_service_enabled(apps, schema_editor): - for app_config in apps.get_app_configs(): - app_config.models_module = True - create_permissions(app_config, apps=apps, verbosity=0) - app_config.models_module = None - - Group = apps.get_model("auth", "Group") - Permission = apps.get_model("auth", "Permission") - MarketUser = apps.get_model("market", "MarketUser") - - perm = Permission.objects.get(codename='access_market') - - member_group_name = getattr(settings, str('DEFAULT_AUTH_GROUP'), 'Member') - blue_group_name = getattr(settings, str('DEFAULT_BLUE_GROUP'), 'Blue') - - # Migrate members - if MarketUser.objects.filter(user__groups__name=member_group_name).exists() or \ - getattr(settings, str('ENABLE_AUTH_MARKET'), False): - try: - group = Group.objects.get(name=member_group_name) - group.permissions.add(perm) - except ObjectDoesNotExist: - logger.warning('Failed to migrate ENABLE_AUTH_MARKET setting') - - # Migrate blues - if MarketUser.objects.filter(user__groups__name=blue_group_name).exists() or \ - getattr(settings, str('ENABLE_BLUE_MARKET'), False): - try: - group = Group.objects.get(name=blue_group_name) - group.permissions.add(perm) - except ObjectDoesNotExist: - logger.warning('Failed to migrate ENABLE_BLUE_MARKET setting') - - -class Migration(migrations.Migration): - - dependencies = [ - ('market', '0001_initial'), - ] - - operations = [ - migrations.AlterModelOptions( - name='marketuser', - options={'permissions': (('access_market', 'Can access the Evernus Market service'),)}, - ), - migrations.RunPython(migrate_service_enabled, migrations.RunPython.noop), - ] diff --git a/allianceauth/services/modules/market/migrations/__init__.py b/allianceauth/services/modules/market/migrations/__init__.py deleted file mode 100644 index e69de29b..00000000 diff --git a/allianceauth/services/modules/market/models.py b/allianceauth/services/modules/market/models.py deleted file mode 100644 index a76157e9..00000000 --- a/allianceauth/services/modules/market/models.py +++ /dev/null @@ -1,18 +0,0 @@ -from django.contrib.auth.models import User -from django.db import models - - -class MarketUser(models.Model): - user = models.OneToOneField(User, - primary_key=True, - on_delete=models.CASCADE, - related_name='market') - username = models.CharField(max_length=254) - - def __str__(self): - return self.username - - class Meta: - permissions = ( - ("access_market", u"Can access the Evernus Market service"), - ) diff --git a/allianceauth/services/modules/market/tasks.py b/allianceauth/services/modules/market/tasks.py deleted file mode 100644 index 597d4a07..00000000 --- a/allianceauth/services/modules/market/tasks.py +++ /dev/null @@ -1,36 +0,0 @@ -import logging - -from django.core.exceptions import ObjectDoesNotExist - -from allianceauth.notifications import notify -from .manager import MarketManager -from .models import MarketUser - -logger = logging.getLogger(__name__) - - -class MarketTasks: - def __init__(self): - pass - - @classmethod - def delete_user(cls, user, notify_user=False): - if cls.has_account(user): - logger.debug("User %s has a Market account %s. Deleting." % (user, user.market.username)) - if MarketManager.disable_user(user.market.username): - user.market.delete() - if notify_user: - notify(user, 'Alliance Market Account Disabled', level='danger') - return True - return False - - @staticmethod - def has_account(user): - try: - return user.market.username != '' - except ObjectDoesNotExist: - return False - - @staticmethod - def disable(): - MarketUser.objects.all().delete() diff --git a/allianceauth/services/modules/market/tests.py b/allianceauth/services/modules/market/tests.py deleted file mode 100644 index 71674fe9..00000000 --- a/allianceauth/services/modules/market/tests.py +++ /dev/null @@ -1,183 +0,0 @@ -from unittest import mock - -from django.test import TestCase, RequestFactory -from django import urls -from django.contrib.auth.models import User, Group, Permission -from django.core.exceptions import ObjectDoesNotExist - -from allianceauth.tests.auth_utils import AuthUtils - -from .auth_hooks import MarketService -from .models import MarketUser -from .tasks import MarketTasks - -MODULE_PATH = 'allianceauth.services.modules.market' -DEFAULT_AUTH_GROUP = 'Member' - - -def add_permissions(): - permission = Permission.objects.get(codename='access_market') - members = Group.objects.get_or_create(name=DEFAULT_AUTH_GROUP)[0] - AuthUtils.add_permissions_to_groups([permission], [members]) - - -class MarketHooksTestCase(TestCase): - def setUp(self): - self.member = 'member_user' - member = AuthUtils.create_member(self.member) - MarketUser.objects.create(user=member, username=self.member) - self.none_user = 'none_user' - none_user = AuthUtils.create_user(self.none_user) - self.service = MarketService - add_permissions() - - def test_has_account(self): - member = User.objects.get(username=self.member) - none_user = User.objects.get(username=self.none_user) - self.assertTrue(MarketTasks.has_account(member)) - self.assertFalse(MarketTasks.has_account(none_user)) - - def test_service_enabled(self): - service = self.service() - member = User.objects.get(username=self.member) - none_user = User.objects.get(username=self.none_user) - - self.assertTrue(service.service_active_for_user(member)) - self.assertFalse(service.service_active_for_user(none_user)) - - @mock.patch(MODULE_PATH + '.tasks.MarketManager') - def test_delete_user(self, manager): - member = User.objects.get(username=self.member) - - service = self.service() - result = service.delete_user(member) - - self.assertTrue(result) - self.assertTrue(manager.disable_user.called) - with self.assertRaises(ObjectDoesNotExist): - market_user = User.objects.get(username=self.member).market - - @mock.patch(MODULE_PATH + '.tasks.MarketManager') - def test_validate_user(self, manager): - service = self.service() - # Test member is not deleted - member = User.objects.get(username=self.member) - service.validate_user(member) - self.assertTrue(User.objects.get(username=self.member).market) - - # Test none user is deleted - none_user = User.objects.get(username=self.none_user) - MarketUser.objects.create(user=none_user, username='abc123') - service.validate_user(none_user) - self.assertTrue(manager.disable_user.called) - with self.assertRaises(ObjectDoesNotExist): - none_svc = User.objects.get(username=self.none_user).market - - def test_render_services_ctrl(self): - service = self.service() - member = User.objects.get(username=self.member) - request = RequestFactory().get('/services/') - request.user = member - - response = service.render_services_ctrl(request) - self.assertTemplateUsed(service.service_ctrl_template) - self.assertIn(urls.reverse('evernusmarket:set_password'), response) - self.assertIn(urls.reverse('evernusmarket:reset_password'), response) - self.assertIn(urls.reverse('evernusmarket:deactivate'), response) - - # Test register becomes available - member.market.delete() - member = User.objects.get(username=self.member) - request.user = member - response = service.render_services_ctrl(request) - self.assertIn(urls.reverse('evernusmarket:activate'), response) - - -class MarketViewsTestCase(TestCase): - def setUp(self): - self.member = AuthUtils.create_member('auth_member') - self.member.email = 'auth_member@example.com' - self.member.save() - AuthUtils.add_main_character(self.member, 'auth_member', '12345', corp_id='111', corp_name='Test Corporation') - add_permissions() - - def login(self): - self.client.force_login(self.member) - - @mock.patch(MODULE_PATH + '.views.MarketManager') - def test_activate(self, manager): - self.login() - expected_username = 'auth_member' - expected_password = 'password' - expected_id = '1234' - - manager.add_user.return_value = (expected_username, expected_password, expected_id) - - response = self.client.get(urls.reverse('evernusmarket:activate'), follow=False) - - self.assertTrue(manager.add_user.called) - args, kwargs = manager.add_user.call_args - self.assertEqual(args[0], expected_username) - self.assertEqual(args[1], self.member.email) - - self.assertTemplateUsed(response, 'services/service_credentials.html') - self.assertContains(response, expected_username) - self.assertContains(response, expected_password) - - @mock.patch(MODULE_PATH + '.tasks.MarketManager') - def test_deactivate(self, manager): - self.login() - MarketUser.objects.create(user=self.member, username='12345') - manager.disable_user.return_value = True - - response = self.client.get(urls.reverse('evernusmarket:deactivate')) - - self.assertTrue(manager.disable_user.called) - self.assertRedirects(response, expected_url=urls.reverse('services:services'), target_status_code=200) - with self.assertRaises(ObjectDoesNotExist): - market_user = User.objects.get(pk=self.member.pk).market - - @mock.patch(MODULE_PATH + '.views.MarketManager') - def test_set_password(self, manager): - self.login() - MarketUser.objects.create(user=self.member, username='12345') - expected_password = 'password' - manager.update_user_password.return_value = expected_password - - response = self.client.post(urls.reverse('evernusmarket:set_password'), data={'password': expected_password}) - - self.assertTrue(manager.update_custom_password.called) - args, kwargs = manager.update_custom_password.call_args - self.assertEqual(args[1], expected_password) - self.assertRedirects(response, expected_url=urls.reverse('services:services'), target_status_code=200) - - @mock.patch(MODULE_PATH + '.views.MarketManager') - def test_reset_password(self, manager): - self.login() - MarketUser.objects.create(user=self.member, username='12345') - - response = self.client.get(urls.reverse('evernusmarket:reset_password')) - - self.assertTrue(manager.update_user_password.called) - self.assertTemplateUsed(response, 'services/service_credentials.html') - - -class MarketManagerTestCase(TestCase): - def setUp(self): - from .manager import MarketManager - self.manager = MarketManager - - def test_generate_random_password(self): - password = self.manager._MarketManager__generate_random_pass() - - self.assertEqual(len(password), 16) - self.assertIsInstance(password, type('')) - - def test_gen_pwhash(self): - pwhash = self.manager._gen_pwhash('test') - salt = self.manager._get_salt(pwhash) - - self.assertIsInstance(pwhash, str) - self.assertGreaterEqual(len(pwhash), 59) - self.assertIsInstance(salt, str) - self.assertEqual(len(salt), 22) diff --git a/allianceauth/services/modules/market/urls.py b/allianceauth/services/modules/market/urls.py deleted file mode 100644 index 3381ec29..00000000 --- a/allianceauth/services/modules/market/urls.py +++ /dev/null @@ -1,17 +0,0 @@ -from django.conf.urls import url, include - -from . import views - -app_name = 'evernusmarket' - -module_urls = [ - # Alliance Market Control - url(r'^activate/$', views.activate_market, name='activate'), - url(r'^deactivate/$', views.deactivate_market, name='deactivate'), - url(r'^reset_password/$', views.reset_market_password, name='reset_password'), - url(r'^set_password/$', views.set_market_password, name='set_password'), -] - -urlpatterns = [ - url(r'^evernus-market/', include((module_urls, app_name), namespace=app_name)) -] diff --git a/allianceauth/services/modules/market/views.py b/allianceauth/services/modules/market/views.py deleted file mode 100644 index e15c5890..00000000 --- a/allianceauth/services/modules/market/views.py +++ /dev/null @@ -1,104 +0,0 @@ -import logging - -from django.contrib import messages -from django.contrib.auth.decorators import login_required, permission_required -from django.shortcuts import render, redirect - -from allianceauth.services.forms import ServicePasswordForm -from .manager import MarketManager -from .models import MarketUser -from .tasks import MarketTasks - -logger = logging.getLogger(__name__) - -ACCESS_PERM = 'market.access_market' - - -@login_required -@permission_required(ACCESS_PERM) -def activate_market(request): - logger.debug("activate_market called by user %s" % request.user) - character = request.user.profile.main_character - if character is not None: - logger.debug("Adding market user for user %s with main character %s" % (request.user, character)) - result = MarketManager.add_user(character.character_name, request.user.email, character.character_id, - character.character_name) - # if empty we failed - if result[0] != "": - MarketUser.objects.create(user=request.user, username=result[0]) - logger.debug("Updated authserviceinfo for user %s with market credentials." % request.user) - logger.info("Successfully activated market for user %s" % request.user) - messages.success(request, 'Activated Alliance Market account.') - credentials = { - 'username': result[0], - 'password': result[1], - } - return render(request, 'services/service_credentials.html', - context={'credentials': credentials, 'service': 'Alliance Market'}) - logger.error("Unsuccessful attempt to activate market for user %s" % request.user) - messages.error(request, 'An error occurred while processing your Alliance Market account.') - return redirect("services:services") - - -@login_required -@permission_required(ACCESS_PERM) -def deactivate_market(request): - logger.debug("deactivate_market called by user %s" % request.user) - # false we failed - if MarketTasks.delete_user(request.user): - logger.info("Successfully deactivated market for user %s" % request.user) - messages.success(request, 'Deactivated Alliance Market account.') - else: - logger.error("Unsuccessful attempt to activate market for user %s" % request.user) - messages.error(request, 'An error occurred while processing your Alliance Market account.') - return redirect("services:services") - - -@login_required -@permission_required(ACCESS_PERM) -def reset_market_password(request): - logger.debug("reset_market_password called by user %s" % request.user) - if MarketTasks.has_account(request.user): - result = MarketManager.update_user_password(request.user.market.username) - # false we failed - if result != "": - logger.info("Successfully reset market password for user %s" % request.user) - messages.success(request, 'Reset Alliance Market password.') - credentials = { - 'username': request.user.market.username, - 'password': result, - } - return render(request, 'services/service_credentials.html', - context={'credentials': credentials, 'service': 'Alliance Market'}) - - logger.error("Unsuccessful attempt to reset market password for user %s" % request.user) - messages.error(request, 'An error occurred while processing your Alliance Market account.') - return redirect("services:services") - - -@login_required -@permission_required(ACCESS_PERM) -def set_market_password(request): - logger.debug("set_market_password called by user %s" % request.user) - if request.method == 'POST': - logger.debug("Received POST request with form.") - form = ServicePasswordForm(request.POST) - logger.debug("Form is valid: %s" % form.is_valid()) - if form.is_valid() and MarketTasks.has_account(request.user): - password = form.cleaned_data['password'] - logger.debug("Form contains password of length %s" % len(password)) - result = MarketManager.update_custom_password(request.user.market.username, password) - if result != "": - logger.info("Successfully reset market password for user %s" % request.user) - messages.success(request, 'Set Alliance Market password.') - else: - logger.error("Failed to install custom market password for user %s" % request.user) - messages.error(request, 'An error occurred while processing your Alliance Market account.') - return redirect("services:services") - else: - logger.debug("Request is not type POST - providing empty form.") - form = ServicePasswordForm() - - logger.debug("Rendering form for user %s" % request.user) - context = {'form': form, 'service': 'Market'} - return render(request, 'services/service_password.html', context=context) diff --git a/allianceauth/services/modules/seat/__init__.py b/allianceauth/services/modules/seat/__init__.py deleted file mode 100644 index eec64742..00000000 --- a/allianceauth/services/modules/seat/__init__.py +++ /dev/null @@ -1 +0,0 @@ -default_app_config = 'allianceauth.services.modules.seat.apps.SeatServiceConfig' diff --git a/allianceauth/services/modules/seat/admin.py b/allianceauth/services/modules/seat/admin.py deleted file mode 100644 index 14640c9c..00000000 --- a/allianceauth/services/modules/seat/admin.py +++ /dev/null @@ -1,9 +0,0 @@ -from django.contrib import admin -from .models import SeatUser - - -class SeatUserAdmin(admin.ModelAdmin): - list_display = ('user', 'username') - search_fields = ('user__username', 'username') - -admin.site.register(SeatUser, SeatUserAdmin) diff --git a/allianceauth/services/modules/seat/apps.py b/allianceauth/services/modules/seat/apps.py deleted file mode 100644 index ad213736..00000000 --- a/allianceauth/services/modules/seat/apps.py +++ /dev/null @@ -1,6 +0,0 @@ -from django.apps import AppConfig - - -class SeatServiceConfig(AppConfig): - name = 'allianceauth.services.modules.seat' - label = 'seat' diff --git a/allianceauth/services/modules/seat/auth_hooks.py b/allianceauth/services/modules/seat/auth_hooks.py deleted file mode 100644 index bad00873..00000000 --- a/allianceauth/services/modules/seat/auth_hooks.py +++ /dev/null @@ -1,64 +0,0 @@ -import logging - -from django.conf import settings -from django.template.loader import render_to_string - -from allianceauth import hooks -from allianceauth.services.hooks import ServicesHook -from .tasks import SeatTasks -from .urls import urlpatterns - -logger = logging.getLogger(__name__) - - -class SeatService(ServicesHook): - def __init__(self): - ServicesHook.__init__(self) - self.urlpatterns = urlpatterns - self.name = 'seat' - self.service_url = settings.SEAT_URL - self.access_perm = 'seat.access_seat' - self.name_format = '{character_name}' - - @property - def title(self): - return "SeAT" - - def delete_user(self, user, notify_user=False): - logger.debug('Deleting user %s %s account' % (user, self.name)) - return SeatTasks.delete_user(user, notify_user=notify_user) - - def validate_user(self, user): - logger.debug('Validating user %s %s account' % (user, self.name)) - if SeatTasks.has_account(user) and not self.service_active_for_user(user): - self.delete_user(user) - - def update_groups(self, user): - logger.debug("Updating %s groups for %s" % (self.name, user)) - if SeatTasks.has_account(user): - SeatTasks.update_roles.delay(user.pk) - - def update_all_groups(self): - logger.debug('Update all %s groups called' % self.name) - SeatTasks.update_all_roles.delay() - - def service_active_for_user(self, user): - return user.has_perm(self.access_perm) - - def render_services_ctrl(self, request): - urls = self.Urls() - urls.auth_activate = 'seat:activate' - urls.auth_deactivate = 'seat:deactivate' - urls.auth_reset_password = 'seat:reset_password' - urls.auth_set_password = 'seat:set_password' - return render_to_string(self.service_ctrl_template, { - 'service_name': self.title, - 'urls': urls, - 'service_url': self.service_url, - 'username': request.user.seat.username if SeatTasks.has_account(request.user) else '' - }, request=request) - - -@hooks.register('services_hook') -def register_service(): - return SeatService() diff --git a/allianceauth/services/modules/seat/manager.py b/allianceauth/services/modules/seat/manager.py deleted file mode 100644 index 2f77042f..00000000 --- a/allianceauth/services/modules/seat/manager.py +++ /dev/null @@ -1,204 +0,0 @@ -import hashlib -import logging -import random -import string - -import requests -from django.conf import settings - -logger = logging.getLogger(__name__) - - -class SeatManager: - def __init__(self): - pass - - RESPONSE_OK = 'ok' - - @staticmethod - def __sanitize_username(username): - sanatized = username.replace(" ", "_") - return sanatized.lower() - - @staticmethod - def __generate_random_pass(): - return ''.join([random.choice(string.ascii_letters + string.digits) for n in range(16)]) - - @classmethod - def _response_ok(cls, response): - return cls.RESPONSE_OK in response - - @staticmethod - def exec_request(endpoint, func, raise_for_status=False, **kwargs): - """ Send an https api request """ - try: - endpoint = '{0}/api/v1/{1}'.format(settings.SEAT_URL, endpoint) - headers = {'X-Token': settings.SEAT_XTOKEN, 'Accept': 'application/json'} - logger.debug(headers) - logger.debug(endpoint) - ret = getattr(requests, func)(endpoint, headers=headers, data=kwargs) - ret.raise_for_status() - return ret.json() - except requests.HTTPError as e: - if raise_for_status: - raise e - logger.exception("Error encountered while performing API request to SeAT with url {}".format(endpoint)) - return {} - - @classmethod - def add_user(cls, username, email): - """ Add user to service """ - sanitized = str(cls.__sanitize_username(username)) - logger.debug("Adding user to SeAT with username %s" % sanitized) - password = cls.__generate_random_pass() - ret = cls.exec_request('user', 'post', username=sanitized, email=str(email), password=password) - logger.debug(ret) - if cls._response_ok(ret): - logger.info("Added SeAT user with username %s" % sanitized) - return sanitized, password - logger.info("Failed to add SeAT user with username %s" % sanitized) - return None, None - - @classmethod - def delete_user(cls, username): - """ Delete user """ - ret = cls.exec_request('user/{}'.format(username), 'delete') - logger.debug(ret) - if cls._response_ok(ret): - logger.info("Deleted SeAT user with username %s" % username) - return username - return None - - @classmethod - def enable_user(cls, username): - """ Enable user """ - ret = cls.exec_request('user/{}'.format(username), 'put', account_status=1) - logger.debug(ret) - if cls._response_ok(ret): - logger.info("Enabled SeAT user with username %s" % username) - return username - logger.info("Failed to enabled SeAT user with username %s" % username) - return None - - @classmethod - def disable_user(cls, username): - """ Disable user """ - cls.update_roles(username, []) - ret = cls.exec_request('user/{}'.format(username), 'put', account_status=0) - logger.debug(ret) - if cls._response_ok(ret): - logger.info("Disabled SeAT user with username %s" % username) - return username - logger.info("Failed to disable SeAT user with username %s" % username) - return None - - @classmethod - def _check_email_changed(cls, username, email): - """Compares email to one set on SeAT""" - ret = cls.exec_request('user/{}'.format(username), 'get', raise_for_status=True) - return ret['email'] != email - - @classmethod - def update_user(cls, username, email, password): - """ Edit user info """ - if cls._check_email_changed(username, email): - # if we try to set the email to whatever it is already on SeAT, we get a HTTP422 error - logger.debug("Updating SeAT username %s with email %s and password" % (username, email)) - ret = cls.exec_request('user/{}'.format(username), 'put', email=email) - logger.debug(ret) - if not cls._response_ok(ret): - logger.warn("Failed to update email for username {}".format(username)) - ret = cls.exec_request('user/{}'.format(username), 'put', password=password) - logger.debug(ret) - if not cls._response_ok(ret): - logger.warn("Failed to update password for username {}".format(username)) - return None - logger.info("Updated SeAT user with username %s" % username) - return username - - @classmethod - def update_user_password(cls, username, email, plain_password=None): - logger.debug("Settings new SeAT password for user %s" % username) - if not plain_password: - plain_password = cls.__generate_random_pass() - if cls.update_user(username, email, plain_password): - return plain_password - - @classmethod - def check_user_status(cls, username): - sanitized = str(cls.__sanitize_username(username)) - logger.debug("Checking SeAT status for user %s" % sanitized) - ret = cls.exec_request('user/{}'.format(sanitized), 'get') - logger.debug(ret) - return ret - - @classmethod - def get_all_seat_eveapis(cls): - seat_all_keys = cls.exec_request('key', 'get') - seat_keys = {} - for key in seat_all_keys: - try: - seat_keys[key["key_id"]] = key["user_id"] - except KeyError: - seat_keys[key["key_id"]] = None - return seat_keys - - @classmethod - def get_all_roles(cls): - groups = {} - ret = cls.exec_request('role', 'get') - logger.debug(ret) - for group in ret: - groups[group["title"]] = group["id"] - logger.debug("Retrieved role list from SeAT: %s" % str(groups)) - return groups - - @classmethod - def add_role(cls, role): - ret = cls.exec_request('role/new', 'post', name=role) - logger.debug(ret) - logger.info("Added Seat group %s" % role) - role_info = cls.exec_request('role/detail/{}'.format(role), 'get') - logger.debug(role_info) - return role_info["id"] - - @classmethod - def add_role_to_user(cls, user_id, role_id): - ret = cls.exec_request('role/grant-user-role/{}/{}'.format(user_id, role_id), 'get') - logger.info("Added role %s to user %s" % (role_id, user_id)) - return ret - - @classmethod - def revoke_role_from_user(cls, user_id, role_id): - ret = cls.exec_request('role/revoke-user-role/{}/{}'.format(user_id, role_id), 'get') - logger.info("Revoked role %s from user %s" % (role_id, user_id)) - return ret - - @classmethod - def update_roles(cls, seat_user, roles): - logger.debug("Updating SeAT user %s with roles %s" % (seat_user, roles)) - user_info = cls.check_user_status(seat_user) - user_roles = {} - if type(user_info["roles"]) is list: - for role in user_info["roles"]: - user_roles[role["title"]] = role["id"] - logger.debug("Got user %s SeAT roles %s" % (seat_user, user_roles)) - seat_roles = cls.get_all_roles() - addroles = set(roles) - set(user_roles.keys()) - remroles = set(user_roles.keys()) - set(roles) - - logger.info("Updating SeAT roles for user %s - adding %s, removing %s" % (seat_user, addroles, remroles)) - for r in addroles: - if r not in seat_roles: - seat_roles[r] = cls.add_role(r) - logger.debug("Adding role %s to SeAT user %s" % (r, seat_user)) - cls.add_role_to_user(user_info["id"], seat_roles[r]) - for r in remroles: - logger.debug("Removing role %s from user %s" % (r, seat_user)) - cls.revoke_role_from_user(user_info["id"], seat_roles[r]) - - @staticmethod - def username_hash(username): - m = hashlib.sha1() - m.update(username.encode('utf-8')) - return m.hexdigest() diff --git a/allianceauth/services/modules/seat/migrations/0001_initial.py b/allianceauth/services/modules/seat/migrations/0001_initial.py deleted file mode 100644 index 3e8359cb..00000000 --- a/allianceauth/services/modules/seat/migrations/0001_initial.py +++ /dev/null @@ -1,26 +0,0 @@ -# -*- coding: utf-8 -*- -# Generated by Django 1.10.4 on 2017-01-15 07:06 -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): - - initial = True - - dependencies = [ - ('auth', '0008_alter_user_username_max_length'), - ] - - operations = [ - migrations.CreateModel( - name='SeatUser', - fields=[ - ('user', models.OneToOneField(on_delete=django.db.models.deletion.CASCADE, primary_key=True, related_name='seat', serialize=False, to=settings.AUTH_USER_MODEL)), - ('username', models.CharField(max_length=254)), - ], - ), - ] diff --git a/allianceauth/services/modules/seat/migrations/0002_service_permissions.py b/allianceauth/services/modules/seat/migrations/0002_service_permissions.py deleted file mode 100644 index 3f777994..00000000 --- a/allianceauth/services/modules/seat/migrations/0002_service_permissions.py +++ /dev/null @@ -1,19 +0,0 @@ -# -*- coding: utf-8 -*- -# Generated by Django 1.10.5 on 2017-02-02 10:49 -from __future__ import unicode_literals - -from django.db import migrations - - -class Migration(migrations.Migration): - - dependencies = [ - ('seat', '0001_initial'), - ] - - operations = [ - migrations.AlterModelOptions( - name='seatuser', - options={'permissions': (('access_seat', 'Can access the SeAT service'),)}, - ), - ] diff --git a/allianceauth/services/modules/seat/migrations/__init__.py b/allianceauth/services/modules/seat/migrations/__init__.py deleted file mode 100644 index e69de29b..00000000 diff --git a/allianceauth/services/modules/seat/models.py b/allianceauth/services/modules/seat/models.py deleted file mode 100644 index 54174e0f..00000000 --- a/allianceauth/services/modules/seat/models.py +++ /dev/null @@ -1,18 +0,0 @@ -from django.contrib.auth.models import User -from django.db import models - - -class SeatUser(models.Model): - user = models.OneToOneField(User, - primary_key=True, - on_delete=models.CASCADE, - related_name='seat') - username = models.CharField(max_length=254) - - def __str__(self): - return self.username - - class Meta: - permissions = ( - ("access_seat", u"Can access the SeAT service"), - ) diff --git a/allianceauth/services/modules/seat/tasks.py b/allianceauth/services/modules/seat/tasks.py deleted file mode 100644 index e0f61186..00000000 --- a/allianceauth/services/modules/seat/tasks.py +++ /dev/null @@ -1,69 +0,0 @@ -import logging - -from django.contrib.auth.models import User -from django.core.exceptions import ObjectDoesNotExist -from celery import shared_task -from allianceauth.services.tasks import QueueOnce -from allianceauth.notifications import notify -from allianceauth.services.hooks import NameFormatter -from .manager import SeatManager -from .models import SeatUser - -logger = logging.getLogger(__name__) - - -class SeatTasks: - def __init__(self): - pass - - @staticmethod - def has_account(user): - try: - return user.seat.username != '' - except ObjectDoesNotExist: - return False - - @classmethod - def delete_user(cls, user, notify_user=False): - if cls.has_account(user) and SeatManager.disable_user(user.seat.username): - user.seat.delete() - logger.info("Successfully deactivated SeAT for user %s" % user) - if notify_user: - notify(user, 'SeAT Account Disabled', level='danger') - return True - return False - - @staticmethod - @shared_task(bind=True, name='seat.update_roles', base=QueueOnce) - def update_roles(self, pk): - user = User.objects.get(pk=pk) - logger.debug("Updating SeAT roles for user %s" % user) - if SeatTasks.has_account(user): - groups = [user.profile.state.name] - for group in user.groups.all(): - groups.append(str(group.name)) - logger.debug("Updating user %s SeAT roles to %s" % (user, groups)) - try: - SeatManager.update_roles(user.seat.username, groups) - except: - logger.warn("SeAT group sync failed for %s, retrying in 10 mins" % user, exc_info=True) - raise self.retry(countdown=60 * 10) - logger.debug("Updated user %s SeAT roles." % user) - else: - logger.debug("User %s does not have a SeAT account") - - @staticmethod - @shared_task - def update_all_roles(): - logger.debug("Updating ALL SeAT roles") - for user in SeatUser.objects.all(): - SeatTasks.update_roles.delay(user.user_id) - - @staticmethod - def deactivate(): - SeatUser.objects.all().delete() - - @staticmethod - def get_username(user): - from .auth_hooks import SeatService - return NameFormatter(SeatService(), user).format_name() diff --git a/allianceauth/services/modules/seat/tests.py b/allianceauth/services/modules/seat/tests.py deleted file mode 100644 index 5de5d5d0..00000000 --- a/allianceauth/services/modules/seat/tests.py +++ /dev/null @@ -1,204 +0,0 @@ -from unittest import mock - -from django.test import TestCase, RequestFactory -from django import urls -from django.contrib.auth.models import User, Group, Permission -from django.core.exceptions import ObjectDoesNotExist - -from allianceauth.tests.auth_utils import AuthUtils - -from .auth_hooks import SeatService -from .models import SeatUser -from .tasks import SeatTasks - -MODULE_PATH = 'allianceauth.services.modules.seat' -DEFAULT_AUTH_GROUP = 'Member' - - -def add_permissions(): - permission = Permission.objects.get(codename='access_seat') - members = Group.objects.get_or_create(name=DEFAULT_AUTH_GROUP)[0] - AuthUtils.add_permissions_to_groups([permission], [members]) - - -class SeatHooksTestCase(TestCase): - def setUp(self): - self.member = 'member_user' - member = AuthUtils.create_member(self.member) - SeatUser.objects.create(user=member, username=self.member) - self.none_user = 'none_user' - none_user = AuthUtils.create_user(self.none_user, disconnect_signals=True) - self.service = SeatService - add_permissions() - - def test_has_account(self): - member = User.objects.get(username=self.member) - none_user = User.objects.get(username=self.none_user) - self.assertTrue(SeatTasks.has_account(member)) - self.assertFalse(SeatTasks.has_account(none_user)) - - def test_service_enabled(self): - service = self.service() - member = User.objects.get(username=self.member) - none_user = User.objects.get(username=self.none_user) - - self.assertTrue(service.service_active_for_user(member)) - self.assertFalse(service.service_active_for_user(none_user)) - - @mock.patch(MODULE_PATH + '.tasks.SeatManager') - def test_update_all_groups(self, manager): - service = self.service() - service.update_all_groups() - # Check member and blue user have groups updated - self.assertTrue(manager.update_roles.called) - self.assertEqual(manager.update_roles.call_count, 1) - - def test_update_groups(self): - # Check member has Member group updated - with mock.patch(MODULE_PATH + '.tasks.SeatManager') as manager: - service = self.service() - member = User.objects.get(username=self.member) - service.update_groups(member) - self.assertTrue(manager.update_roles.called) - args, kwargs = manager.update_roles.call_args - user_id, groups = args - self.assertIn(DEFAULT_AUTH_GROUP, groups) - self.assertEqual(user_id, member.seat.username) - - # Check none user does not have groups updated - with mock.patch(MODULE_PATH + '.tasks.SeatManager') as manager: - service = self.service() - none_user = User.objects.get(username=self.none_user) - service.update_groups(none_user) - self.assertFalse(manager.update_roles.called) - - @mock.patch(MODULE_PATH + '.tasks.SeatManager') - def test_validate_user(self, manager): - service = self.service() - # Test member is not deleted - member = User.objects.get(username=self.member) - # Pre assertion - self.assertTrue(member.has_perm('seat.access_seat')) - - service.validate_user(member) - self.assertTrue(User.objects.get(username=self.member).seat) - - # Test none user is deleted - none_user = User.objects.get(username=self.none_user) - manager.disable_user.return_value = 'abc123' - SeatUser.objects.create(user=none_user, username='abc123') - service.validate_user(none_user) - self.assertTrue(manager.disable_user.called) - with self.assertRaises(ObjectDoesNotExist): - none_seat = User.objects.get(username=self.none_user).seat - - @mock.patch(MODULE_PATH + '.tasks.SeatManager') - def test_delete_user(self, manager): - member = User.objects.get(username=self.member) - - service = self.service() - result = service.delete_user(member) - - self.assertTrue(result) - self.assertTrue(manager.disable_user.called) - with self.assertRaises(ObjectDoesNotExist): - seat_user = User.objects.get(username=self.member).seat - - def test_render_services_ctrl(self): - service = self.service() - member = User.objects.get(username=self.member) - request = RequestFactory().get('/services/') - request.user = member - - response = service.render_services_ctrl(request) - self.assertTemplateUsed(service.service_ctrl_template) - self.assertIn(urls.reverse('seat:deactivate'), response) - self.assertIn(urls.reverse('seat:reset_password'), response) - self.assertIn(urls.reverse('seat:set_password'), response) - - # Test register becomes available - member.seat.delete() - member = User.objects.get(username=self.member) - request.user = member - response = service.render_services_ctrl(request) - self.assertIn(urls.reverse('seat:activate'), response) - - -class SeatViewsTestCase(TestCase): - def setUp(self): - self.member = AuthUtils.create_member('auth_member') - self.member.email = 'auth_member@example.com' - self.member.save() - AuthUtils.add_main_character(self.member, 'auth_member', '12345', corp_id='111', corp_name='Test Corporation') - add_permissions() - - def login(self): - self.client.force_login(self.member) - - @mock.patch(MODULE_PATH + '.tasks.SeatManager') - @mock.patch(MODULE_PATH + '.views.SeatManager') - def test_activate(self, manager, tasks_manager): - self.login() - expected_username = 'auth_member' - manager.check_user_status.return_value = {} - manager.add_user.return_value = (expected_username, 'abc123') - - response = self.client.get(urls.reverse('seat:activate')) - - self.assertTrue(manager.add_user.called) - self.assertTrue(tasks_manager.update_roles.called) - self.assertEqual(response.status_code, 200) - self.assertTemplateUsed('services/service_credentials.html') - self.assertContains(response, expected_username) - seat_user = SeatUser.objects.get(user=self.member) - self.assertEqual(seat_user.username, expected_username) - - @mock.patch(MODULE_PATH + '.tasks.SeatManager') - def test_deactivate(self, manager): - self.login() - SeatUser.objects.create(user=self.member, username='some member') - - response = self.client.get(urls.reverse('seat:deactivate')) - - self.assertTrue(manager.disable_user.called) - self.assertRedirects(response, expected_url=urls.reverse('services:services'), target_status_code=200) - - with self.assertRaises(ObjectDoesNotExist): - seat_user = User.objects.get(pk=self.member.pk).seat - - @mock.patch(MODULE_PATH + '.views.SeatManager') - def test_set_password(self, manager): - self.login() - SeatUser.objects.create(user=self.member, username='some member') - - response = self.client.post(urls.reverse('seat:set_password'), data={'password': '1234asdf'}) - - self.assertTrue(manager.update_user_password.called) - args, kwargs = manager.update_user_password.call_args - self.assertEqual(kwargs['plain_password'], '1234asdf') - self.assertRedirects(response, expected_url=urls.reverse('services:services'), target_status_code=200) - - @mock.patch(MODULE_PATH + '.views.SeatManager') - def test_reset_password(self, manager): - self.login() - SeatUser.objects.create(user=self.member, username='some member') - - manager.update_user_password.return_value = 'hunter2' - - response = self.client.get(urls.reverse('seat:reset_password')) - - self.assertTemplateUsed(response, 'services/service_credentials.html') - self.assertContains(response, 'some member') - self.assertContains(response, 'hunter2') - - -class SeatManagerTestCase(TestCase): - def setUp(self): - from .manager import SeatManager - self.manager = SeatManager - - def test_generate_random_password(self): - password = self.manager._SeatManager__generate_random_pass() - - self.assertEqual(len(password), 16) - self.assertIsInstance(password, type('')) diff --git a/allianceauth/services/modules/seat/urls.py b/allianceauth/services/modules/seat/urls.py deleted file mode 100644 index c374681c..00000000 --- a/allianceauth/services/modules/seat/urls.py +++ /dev/null @@ -1,17 +0,0 @@ -from django.conf.urls import url, include - -from . import views - -app_name='seat' - -module_urls = [ - # SeAT Service Control - url(r'^activate/$', views.activate_seat, name='activate'), - url(r'^deactivate/$', views.deactivate_seat, name='deactivate'), - url(r'^reset_password/$', views.reset_seat_password, name='reset_password'), - url(r'^set_password/$', views.set_seat_password, name='set_password'), -] - -urlpatterns = [ - url(r'^seat/', include((module_urls, app_name), namespace=app_name)), -] diff --git a/allianceauth/services/modules/seat/views.py b/allianceauth/services/modules/seat/views.py deleted file mode 100644 index 73383851..00000000 --- a/allianceauth/services/modules/seat/views.py +++ /dev/null @@ -1,130 +0,0 @@ -import logging - -from django.contrib import messages -from django.contrib.auth.decorators import login_required, permission_required -from django.shortcuts import render, redirect -from django.utils.translation import ugettext_lazy as _ - -from allianceauth.services.forms import ServicePasswordForm -from .manager import SeatManager -from .models import SeatUser -from .tasks import SeatTasks - -logger = logging.getLogger(__name__) - -ACCESS_PERM = 'seat.access_seat' -SERVICE_NAME = {'service': 'SeAT'} - - -@login_required -@permission_required(ACCESS_PERM) -def activate_seat(request): - logger.debug("activate_seat called by user %s" % request.user) - character = request.user.profile.main_character - logger.debug("Checking SeAT for inactive users with the same username") - stat = SeatManager.check_user_status(character.character_name) - if stat == {}: - logger.debug("User not found, adding SeAT user for user %s with main character %s" % (request.user, character)) - result = SeatManager.add_user(SeatTasks.get_username(request.user), request.user.email) - else: - logger.debug("User found, resetting password") - username = SeatManager.enable_user(stat["name"]) - password = SeatManager.update_user_password(username, request.user.email) - result = [username, password] - # if empty we failed - if result[0] and result[1]: - SeatUser.objects.update_or_create(user=request.user, defaults={'username': result[0]}) - logger.debug("Updated SeatUser for user %s with SeAT credentials. Adding eve-apis..." % request.user) - SeatTasks.update_roles.delay(request.user.pk) - logger.info("Successfully activated SeAT for user %s" % request.user) - messages.add_message(request, messages.SUCCESS, _('Successfully activated your %(service)s account.') % - SERVICE_NAME) - credentials = { - 'username': request.user.seat.username, - 'password': result[1], - } - return render(request, 'services/service_credentials.html', - context={'credentials': credentials, 'service': 'SeAT'}) - messages.add_message(request, messages.ERROR, - _('Failed to activate your %(service)s account, please contact your administrator.') % - SERVICE_NAME) - logger.error("Unsuccessful attempt to activate seat for user %s" % request.user) - return redirect("services:services") - - -@login_required -@permission_required(ACCESS_PERM) -def deactivate_seat(request): - logger.debug("deactivate_seat called by user %s" % request.user) - # false we failed - if SeatTasks.delete_user(request.user): - messages.add_message(request, messages.SUCCESS, - _('Successfully deactivated your %(service)s account.') % SERVICE_NAME) - logger.info("Successfully deactivated SeAT for user %s" % request.user) - return redirect("services:services") - else: - logging.error("User does not have a SeAT account") - messages.add_message(request, messages.ERROR, - _('Failed to deactivate your %(service)s account, please contact your administrator.') % - SERVICE_NAME) - logger.error("Unsuccessful attempt to activate SeAT for user %s" % request.user) - return redirect("services:services") - - -@login_required -@permission_required(ACCESS_PERM) -def reset_seat_password(request): - logger.debug("reset_seat_password called by user %s" % request.user) - if SeatTasks.has_account(request.user): - result = SeatManager.update_user_password(request.user.seat.username, request.user.email) - # false we failed - if result: - credentials = { - 'username': request.user.seat.username, - 'password': result, - } - messages.add_message(request, messages.SUCCESS, - _('Successfully reset your %(service)s password.') % {'service': 'SeAT'}) - logger.info("Succesfully reset SeAT password for user %s" % request.user) - return render(request, 'services/service_credentials.html', - context={'credentials': credentials, 'service': 'SeAT'}) - logger.error("Unsuccessful attempt to reset SeAT password for user %s" % request.user) - messages.add_message(request, messages.ERROR, - _('Failed to reset your %(service)s password, please contact your administrator.') % - {'service': 'SeAT'}) - return redirect("services:services") - - -@login_required -@permission_required(ACCESS_PERM) -def set_seat_password(request): - logger.debug("set_seat_password called by user %s" % request.user) - if request.method == 'POST': - logger.debug("Received POST request with form.") - form = ServicePasswordForm(request.POST) - logger.debug("Form is valid: %s" % form.is_valid()) - if form.is_valid() and SeatTasks.has_account(request.user): - password = form.cleaned_data['password'] - logger.debug("Form contains password of length %s" % len(password)) - result = SeatManager.update_user_password(request.user.seat.username, - request.user.email, - plain_password=password) - if result: - messages.add_message(request, messages.SUCCESS, - _('Successfully set your %(service)s password.') % SERVICE_NAME) - logger.info("Succesfully reset SeAT password for user %s" % request.user) - return redirect("services:services") - else: - messages.add_message(request, messages.ERROR, - _('Failed to set your %(service)s password, please contact your administrator.') % - SERVICE_NAME) - logger.error("Failed to install custom SeAT password for user %s" % request.user) - else: - messages.add_message(request, messages.ERROR, _('Invalid password.')) - logger.error("Invalid SeAT password provided") - else: - logger.debug("Request is not type POST - providing empty form.") - form = ServicePasswordForm() - logger.debug("Rendering form for user %s" % request.user) - context = {'form': form, 'service': 'SeAT'} - return render(request, 'services/service_password.html', context) diff --git a/docs/features/nameformats.md b/docs/features/nameformats.md index ed466d93..437d33f6 100644 --- a/docs/features/nameformats.md +++ b/docs/features/nameformats.md @@ -25,8 +25,6 @@ Currently the following services support custom name formats: +-------------+-----------+-------------------------------------+ | phpBB3 | Username | ``{character_name}`` | +-------------+-----------+-------------------------------------+ -| SeAT | Username | ``{character_name}`` | -+-------------+-----------+-------------------------------------+ | SMF | Username | ``{character_name}`` | +-------------+-----------+-------------------------------------+ | Teamspeak 3 | Nickname | ``[{corp_ticker}]{character_name}`` | diff --git a/docs/installation/services/index.md b/docs/installation/services/index.md index 922fc063..90fc6fc4 100644 --- a/docs/installation/services/index.md +++ b/docs/installation/services/index.md @@ -4,7 +4,6 @@ .. toctree:: permissions - market discord discourse mumble diff --git a/docs/installation/services/market.md b/docs/installation/services/market.md deleted file mode 100644 index 3f990953..00000000 --- a/docs/installation/services/market.md +++ /dev/null @@ -1,7 +0,0 @@ -# Alliance Market - -## Deprecation - -Alliance Market relies on the now non-functional XML API. - -Please remove this service data with `python manage.py migrate appname zero` and then remove from your `INSTALLED_APPS` list. diff --git a/docs/installation/services/smf.md b/docs/installation/services/smf.md index 72d222b5..8ad27b53 100644 --- a/docs/installation/services/smf.md +++ b/docs/installation/services/smf.md @@ -62,7 +62,7 @@ SMF needs a database. Create one: Enter the database information into the `DATABASES['smf']` section of your auth project's settings file. ### Web Server Configuration -Your web server needs to be configured to serve Alliance Market. +Your web server needs to be configured to serve SMF. A minimal Apache config might look like: diff --git a/tests/settings.py b/tests/settings.py index 2eb84521..045f1089 100644 --- a/tests/settings.py +++ b/tests/settings.py @@ -29,9 +29,7 @@ INSTALLED_APPS += [ 'allianceauth.services.modules.discord', 'allianceauth.services.modules.discourse', 'allianceauth.services.modules.ips4', - 'allianceauth.services.modules.market', 'allianceauth.services.modules.openfire', - 'allianceauth.services.modules.seat', 'allianceauth.services.modules.smf', 'allianceauth.services.modules.phpbb3', 'allianceauth.services.modules.xenforo', @@ -43,11 +41,6 @@ ROOT_URLCONF = 'tests.urls' CACHES['default'] = {'BACKEND': 'django.core.cache.backends.db.DatabaseCache'} -##################### -# Alliance Market -##################### -MARKET_URL = 'http://yourdomain.com/market' - ##################### # HR Configuration ##################### @@ -159,15 +152,6 @@ DISCOURSE_SSO_SECRET = 'd836444a9e4084d5b224a60c208dce14' IPS4_URL = 'http://example.com/ips4' IPS4_API_KEY = '' -##################################### -# SEAT Configuration -##################################### -# SEAT_URL - base url of the seat install (no trailing slash) -# SEAT_XTOKEN - API key X-Token provided by SeAT -##################################### -SEAT_URL = 'http://example.com/seat' -SEAT_XTOKEN = 'tokentokentoken' - ###################################### # SMF Configuration ######################################