mirror of
https://gitlab.com/allianceauth/allianceauth.git
synced 2026-02-04 06:06:19 +01:00
Compare commits
29 Commits
| Author | SHA1 | Date | |
|---|---|---|---|
|
|
f70987de09 | ||
|
|
9d02b1530c | ||
|
|
3d532dae01 | ||
|
|
02247b067f | ||
|
|
63c2668171 | ||
|
|
5575039126 | ||
|
|
f97c8f2ce4 | ||
|
|
6baab1d006 | ||
|
|
17adf04860 | ||
|
|
f871ecb425 | ||
|
|
4a425cde78 | ||
|
|
f56252b0cc | ||
|
|
7ae6c66beb | ||
|
|
be90fb96ea | ||
|
|
dd3350b169 | ||
|
|
cdd1ba1fe3 | ||
|
|
10ea12c867 | ||
|
|
e6358d948a | ||
|
|
1101572f78 | ||
|
|
0cf8836832 | ||
|
|
6e4562b0e6 | ||
|
|
856f1e176a | ||
|
|
1653a57e7b | ||
|
|
5f03e580c2 | ||
|
|
d370ae48a2 | ||
|
|
38baeba254 | ||
|
|
478f9b9390 | ||
|
|
82ad3821c4 | ||
|
|
07afaf12d5 |
@@ -24,6 +24,7 @@ Active Developers:
|
||||
Beta Testers / Bug Fixers:
|
||||
|
||||
- [ghoti](https://github.com/ghoti)
|
||||
- [mmolitor87](https://github.com/mmolitor87)
|
||||
|
||||
|
||||
Past Beta Testers / Bug Fixers:
|
||||
|
||||
@@ -1,7 +1,7 @@
|
||||
# This will make sure the app is always imported when
|
||||
# Django starts so that shared_task will use this app.
|
||||
|
||||
__version__ = '2.0-dev'
|
||||
__version__ = '2.0b2'
|
||||
NAME = 'Alliance Auth v%s' % __version__
|
||||
default_app_config = 'allianceauth.apps.AllianceAuthConfig'
|
||||
|
||||
|
||||
@@ -39,6 +39,7 @@ class StateBackend(ModelBackend):
|
||||
# insecure legacy main check for pre-sso registration auth installs
|
||||
profile = UserProfile.objects.get(main_character__character_id=token.character_id)
|
||||
# attach an ownership
|
||||
token.user = profile.user
|
||||
CharacterOwnership.objects.create_by_token(token)
|
||||
return profile.user
|
||||
except UserProfile.DoesNotExist:
|
||||
|
||||
@@ -103,16 +103,16 @@ def populate_ownerships(apps, schema_editor):
|
||||
|
||||
unique_character_owners = [t['character_id'] for t in
|
||||
Token.objects.all().values('character_id').annotate(n=models.Count('user')) if
|
||||
t['n'] == 1 and EveCharacter.objects.filter(character_id=t['character_id'].exists())]
|
||||
t['n'] == 1 and EveCharacter.objects.filter(character_id=t['character_id']).exists()]
|
||||
|
||||
tokens = Token.objects.filter(character_id__in=unique_character_owners)
|
||||
for c_id in unique_character_owners:
|
||||
ts = tokens.filter(character_id=c_id).order_by('created')
|
||||
for t in ts:
|
||||
if t.can_refresh:
|
||||
# find newest refreshable token and use it as basis for CharacterOwnership
|
||||
CharacterOwnership.objecs.create_by_token(t)
|
||||
break
|
||||
# find newest refreshable token and use it as basis for CharacterOwnership
|
||||
ts = tokens.filter(character_id=c_id).exclude(refresh_token__isnull=True).order_by('created')
|
||||
if ts.exists():
|
||||
token = ts[0]
|
||||
char = EveCharacter.objects.get(character_id=token.character_id)
|
||||
CharacterOwnership.objects.create(user_id=token.user_id, character_id=char.id, owner_hash=token.character_owner_hash)
|
||||
|
||||
|
||||
def create_profiles(apps, schema_editor):
|
||||
|
||||
@@ -4,3 +4,6 @@ from django.apps import AppConfig
|
||||
class EveAutogroupsConfig(AppConfig):
|
||||
name = 'allianceauth.eveonline.autogroups'
|
||||
label = 'eve_autogroups'
|
||||
|
||||
def ready(self):
|
||||
import allianceauth.eveonline.autogroups.signals
|
||||
|
||||
@@ -1,5 +1,5 @@
|
||||
# -*- coding: utf-8 -*-
|
||||
# Generated by Django 1.11.5 on 2017-09-29 14:44
|
||||
# Generated by Django 1.11.6 on 2017-12-23 04:30
|
||||
from __future__ import unicode_literals
|
||||
|
||||
from django.db import migrations, models
|
||||
@@ -29,40 +29,31 @@ class Migration(migrations.Migration):
|
||||
('alliance_name_source', models.CharField(choices=[('ticker', 'Ticker'), ('name', 'Full name')], default='name', max_length=20)),
|
||||
('replace_spaces', models.BooleanField(default=False)),
|
||||
('replace_spaces_with', models.CharField(blank=True, default='', help_text='Any spaces in the group name will be replaced with this.', max_length=10)),
|
||||
('states', models.ManyToManyField(related_name='autogroups', to='authentication.State')),
|
||||
],
|
||||
),
|
||||
migrations.CreateModel(
|
||||
name='ManagedGroup',
|
||||
fields=[
|
||||
('id', models.AutoField(auto_created=True, primary_key=True, serialize=False, verbose_name='ID')),
|
||||
],
|
||||
),
|
||||
migrations.CreateModel(
|
||||
name='ManagedAllianceGroup',
|
||||
fields=[
|
||||
('managedgroup_ptr', models.OneToOneField(auto_created=True, on_delete=django.db.models.deletion.CASCADE, parent_link=True, primary_key=True, serialize=False, to='eve_autogroups.ManagedGroup')),
|
||||
('id', models.AutoField(auto_created=True, primary_key=True, serialize=False, verbose_name='ID')),
|
||||
('alliance', models.ForeignKey(on_delete=django.db.models.deletion.CASCADE, to='eveonline.EveAllianceInfo')),
|
||||
('config', models.ForeignKey(on_delete=django.db.models.deletion.CASCADE, to='eve_autogroups.AutogroupsConfig')),
|
||||
('group', models.ForeignKey(on_delete=django.db.models.deletion.CASCADE, to='auth.Group')),
|
||||
],
|
||||
bases=('eve_autogroups.managedgroup',),
|
||||
options={
|
||||
'abstract': False,
|
||||
},
|
||||
),
|
||||
migrations.CreateModel(
|
||||
name='ManagedCorpGroup',
|
||||
fields=[
|
||||
('managedgroup_ptr', models.OneToOneField(auto_created=True, on_delete=django.db.models.deletion.CASCADE, parent_link=True, primary_key=True, serialize=False, to='eve_autogroups.ManagedGroup')),
|
||||
('id', models.AutoField(auto_created=True, primary_key=True, serialize=False, verbose_name='ID')),
|
||||
('config', models.ForeignKey(on_delete=django.db.models.deletion.CASCADE, to='eve_autogroups.AutogroupsConfig')),
|
||||
('corp', models.ForeignKey(on_delete=django.db.models.deletion.CASCADE, to='eveonline.EveCorporationInfo')),
|
||||
('group', models.ForeignKey(on_delete=django.db.models.deletion.CASCADE, to='auth.Group')),
|
||||
],
|
||||
bases=('eve_autogroups.managedgroup',),
|
||||
),
|
||||
migrations.AddField(
|
||||
model_name='managedgroup',
|
||||
name='config',
|
||||
field=models.ForeignKey(on_delete=django.db.models.deletion.CASCADE, to='eve_autogroups.AutogroupsConfig'),
|
||||
),
|
||||
migrations.AddField(
|
||||
model_name='managedgroup',
|
||||
name='group',
|
||||
field=models.ForeignKey(on_delete=django.db.models.deletion.CASCADE, to='auth.Group'),
|
||||
options={
|
||||
'abstract': False,
|
||||
},
|
||||
),
|
||||
migrations.AddField(
|
||||
model_name='autogroupsconfig',
|
||||
@@ -74,4 +65,9 @@ class Migration(migrations.Migration):
|
||||
name='corp_managed_groups',
|
||||
field=models.ManyToManyField(help_text="A list of corporation groups created and maintained by this AutogroupConfig. You should not edit this list unless you know what you're doing.", related_name='corp_managed_config', through='eve_autogroups.ManagedCorpGroup', to='auth.Group'),
|
||||
),
|
||||
migrations.AddField(
|
||||
model_name='autogroupsconfig',
|
||||
name='states',
|
||||
field=models.ManyToManyField(related_name='autogroups', to='authentication.State'),
|
||||
),
|
||||
]
|
||||
|
||||
@@ -110,11 +110,12 @@ class AutogroupsConfig(models.Model):
|
||||
group = None
|
||||
try:
|
||||
if not self.alliance_groups or not self.user_entitled_to_groups(user):
|
||||
logger.debug('User {} does not have required state'.format(user))
|
||||
logger.debug('User {} does not have required state for alliance group membership'.format(user))
|
||||
return
|
||||
else:
|
||||
alliance = user.profile.main_character.alliance
|
||||
if alliance is None:
|
||||
logger.debug('User {} alliance is None, cannot update group membership'.format(user))
|
||||
return
|
||||
group = self.get_alliance_group(alliance)
|
||||
except EveAllianceInfo.DoesNotExist:
|
||||
@@ -123,8 +124,9 @@ class AutogroupsConfig(models.Model):
|
||||
except AttributeError:
|
||||
logger.warning('User {} does not have a main character. Group membership not updated'.format(user))
|
||||
finally:
|
||||
self.remove_user_from_corp_groups(user, except_group=group)
|
||||
self.remove_user_from_alliance_groups(user, except_group=group)
|
||||
if group is not None:
|
||||
logger.debug('Adding user {} to alliance group {}'.format(user, group))
|
||||
user.groups.add(group)
|
||||
|
||||
@transaction.atomic
|
||||
@@ -132,7 +134,7 @@ class AutogroupsConfig(models.Model):
|
||||
group = None
|
||||
try:
|
||||
if not self.corp_groups or not self.user_entitled_to_groups(user):
|
||||
logger.debug('User {} does not have required state'.format(user))
|
||||
logger.debug('User {} does not have required state for corp group membership'.format(user))
|
||||
else:
|
||||
corp = user.profile.main_character.corporation
|
||||
group = self.get_corp_group(corp)
|
||||
@@ -144,6 +146,7 @@ class AutogroupsConfig(models.Model):
|
||||
finally:
|
||||
self.remove_user_from_corp_groups(user, except_group=group)
|
||||
if group is not None:
|
||||
logger.debug('Adding user {} to corp group {}'.format(user, group))
|
||||
user.groups.add(group)
|
||||
|
||||
@transaction.atomic
|
||||
@@ -184,13 +187,15 @@ class AutogroupsConfig(models.Model):
|
||||
"""
|
||||
Deletes ALL managed alliance groups
|
||||
"""
|
||||
self.alliance_managed_groups.all().delete()
|
||||
for g in self.alliance_managed_groups.all():
|
||||
g.delete()
|
||||
|
||||
def delete_corp_managed_groups(self):
|
||||
"""
|
||||
Deletes ALL managed corp groups
|
||||
"""
|
||||
self.corp_managed_groups.all().delete()
|
||||
for g in self.corp_managed_groups.all():
|
||||
g.delete()
|
||||
|
||||
def get_alliance_group_name(self, alliance: EveAllianceInfo) -> str:
|
||||
if self.alliance_name_source == self.OPT_TICKER:
|
||||
@@ -225,6 +230,9 @@ class ManagedGroup(models.Model):
|
||||
group = models.ForeignKey(Group, on_delete=models.CASCADE)
|
||||
config = models.ForeignKey(AutogroupsConfig, on_delete=models.CASCADE)
|
||||
|
||||
class Meta:
|
||||
abstract = True
|
||||
|
||||
|
||||
class ManagedCorpGroup(ManagedGroup):
|
||||
corp = models.ForeignKey(EveCorporationInfo, on_delete=models.CASCADE)
|
||||
|
||||
@@ -82,6 +82,7 @@ class AutogroupsConfigTestCase(TestCase):
|
||||
|
||||
# Act
|
||||
obj.update_alliance_group_membership(self.member)
|
||||
obj.update_corp_group_membership(self.member) # check for no side effects
|
||||
|
||||
group = obj.create_alliance_group(self.alliance)
|
||||
group_qs = Group.objects.filter(pk=group.pk)
|
||||
|
||||
@@ -4,8 +4,6 @@ from django.db import models
|
||||
from django.db.models.signals import post_save
|
||||
from django.dispatch import receiver
|
||||
|
||||
from allianceauth.eveonline.models import EveCharacter
|
||||
|
||||
|
||||
class GroupRequest(models.Model):
|
||||
status = models.CharField(max_length=254)
|
||||
|
||||
@@ -303,7 +303,6 @@ def group_request_add(request, group_id):
|
||||
grouprequest.status = _('Pending')
|
||||
grouprequest.group = group
|
||||
grouprequest.user = request.user
|
||||
grouprequest.main_char = request.user.profile.main_character
|
||||
grouprequest.leave_request = False
|
||||
grouprequest.save()
|
||||
logger.info("Created group request for user %s to group %s" % (request.user, Group.objects.get(id=group_id)))
|
||||
@@ -333,7 +332,6 @@ def group_request_leave(request, group_id):
|
||||
grouprequest.status = _('Pending')
|
||||
grouprequest.group = group
|
||||
grouprequest.user = request.user
|
||||
grouprequest.main_char = request.user.profile.main_character
|
||||
grouprequest.leave_request = True
|
||||
grouprequest.save()
|
||||
logger.info("Created group leave request for user %s to group %s" % (request.user, Group.objects.get(id=group_id)))
|
||||
|
||||
@@ -0,0 +1 @@
|
||||
from .celery import app as celery_app
|
||||
|
||||
@@ -10,7 +10,7 @@ app = Celery('{{ project_name }}')
|
||||
|
||||
# Using a string here means the worker don't have to serialize
|
||||
# the configuration object to child processes.
|
||||
app.config_from_object('django.conf:settings')
|
||||
app.config_from_object('django.conf:settings', namespace='CELERY')
|
||||
|
||||
# Load task modules from all registered Django app configs.
|
||||
app.autodiscover_tasks(lambda: settings.INSTALLED_APPS)
|
||||
|
||||
@@ -39,7 +39,7 @@ INSTALLED_APPS = [
|
||||
]
|
||||
|
||||
# Celery configuration
|
||||
BROKER_URL = 'redis://localhost:6379/0'
|
||||
CELERY_BROKER_URL = 'redis://localhost:6379/0'
|
||||
CELERYBEAT_SCHEDULER = "django_celery_beat.schedulers.DatabaseScheduler"
|
||||
CELERYBEAT_SCHEDULE = {
|
||||
'esi_cleanup_callbackredirect': {
|
||||
|
||||
@@ -10,12 +10,33 @@ STATIC_ROOT = "/var/www/{{ project_name }}/static/"
|
||||
TEMPLATES[0]['DIRS'] += [os.path.join(PROJECT_DIR, 'templates')]
|
||||
SECRET_KEY = '{{ secret_key }}'
|
||||
|
||||
# Change this to change the name of the auth site
|
||||
#######################################
|
||||
# Site Name #
|
||||
#######################################
|
||||
# Change this to change the name of the
|
||||
# auth site displayed in page titles
|
||||
# and the site header.
|
||||
#######################################
|
||||
SITE_NAME = '{{ project_name }}'
|
||||
|
||||
# Change this to enable/disable debug mode
|
||||
#######################################
|
||||
# Debug Mode #
|
||||
#######################################
|
||||
# Change this to enable/disable debug
|
||||
# mode, which displays useful error
|
||||
# messages but can leak sensitive data.
|
||||
#######################################
|
||||
DEBUG = False
|
||||
|
||||
#######################################
|
||||
# Additional Applications #
|
||||
#######################################
|
||||
# Add any additional apps to this list.
|
||||
#######################################
|
||||
INSTALLED_APPS += [
|
||||
|
||||
]
|
||||
|
||||
#######################################
|
||||
# Database Settings #
|
||||
#######################################
|
||||
@@ -27,42 +48,45 @@ DEBUG = False
|
||||
DATABASES['default'] = {
|
||||
'ENGINE': 'django.db.backends.mysql',
|
||||
'NAME': 'alliance_auth',
|
||||
'USER': os.environ.get('AA_DB_DEFAULT_USER', ''),
|
||||
'PASSWORD': os.environ.get('AA_DB_DEFAULT_PASSWORD', ''),
|
||||
'HOST': os.environ.get('AA_DB_DEFAULT_HOST', '127.0.0.1'),
|
||||
'PORT': os.environ.get('AA_DB_DEFAULT_PORT', '3306'),
|
||||
'USER': '',
|
||||
'PASSWORD': '',
|
||||
'HOST': '127.0.0.1',
|
||||
'PORT': '3306',
|
||||
}
|
||||
"""
|
||||
|
||||
######################################
|
||||
# SSO Settings #
|
||||
######################################
|
||||
#######################################
|
||||
# SSO Settings #
|
||||
#######################################
|
||||
# Register an application at
|
||||
# https://developers.eveonline.com
|
||||
# and fill out these settings.
|
||||
# Be sure to set the callback URL to
|
||||
# https://example.com/sso/callback
|
||||
# substituting your domain for example.com
|
||||
######################################
|
||||
#######################################
|
||||
ESI_SSO_CLIENT_ID = ''
|
||||
ESI_SSO_CLIENT_SECRET = ''
|
||||
ESI_SSO_CALLBACK_URL = ''
|
||||
|
||||
######################################
|
||||
# Email Settings #
|
||||
######################################
|
||||
#######################################
|
||||
# Email Settings #
|
||||
#######################################
|
||||
# Alliance Auth validates emails before
|
||||
# new users can log in.
|
||||
# It's recommended to use a free service
|
||||
# like SparkPost or Mailgun to send email.
|
||||
# https://www.sparkpost.com/docs/integrations/django/
|
||||
#################
|
||||
# Set the default from email to something
|
||||
# like 'noreply@example.com'
|
||||
#######################################
|
||||
EMAIL_HOST = ''
|
||||
EMAIL_PORT = 587
|
||||
EMAIL_HOST_USER = ''
|
||||
EMAIL_HOST_PASSWORD = ''
|
||||
EMAIL_USE_TLS = True
|
||||
DEFAULT_FROM_EMAIL = ''
|
||||
|
||||
######################################
|
||||
# Add any custom settings below here #
|
||||
######################################
|
||||
#######################################
|
||||
# Add any custom settings below here. #
|
||||
#######################################
|
||||
|
||||
@@ -9,7 +9,9 @@ class NameFormatConfigForm(forms.ModelForm):
|
||||
super(NameFormatConfigForm, self).__init__(*args, **kwargs)
|
||||
SERVICE_CHOICES = [(s.name, s.name) for h in hooks.get_hooks('services_hook') for s in [h()]]
|
||||
if self.instance.id:
|
||||
SERVICE_CHOICES.append((self.instance.field, self.instance.field))
|
||||
current_choice = (self.instance.service_name, self.instance.service_name)
|
||||
if current_choice not in SERVICE_CHOICES:
|
||||
SERVICE_CHOICES.append(current_choice)
|
||||
self.fields['service_name'] = forms.ChoiceField(choices=SERVICE_CHOICES)
|
||||
|
||||
|
||||
|
||||
@@ -6,4 +6,4 @@ class ServicesConfig(AppConfig):
|
||||
label = 'services'
|
||||
|
||||
def ready(self):
|
||||
pass
|
||||
from . import signals
|
||||
|
||||
@@ -244,10 +244,10 @@ class Teamspeak3Manager:
|
||||
|
||||
return False
|
||||
|
||||
def generate_new_permissionkey(self, uid, username, corpticker):
|
||||
def generate_new_permissionkey(self, uid, username):
|
||||
logger.debug("Re-issuing permission key for user id %s" % uid)
|
||||
self.delete_user(uid)
|
||||
return self.add_user(username, corpticker)
|
||||
return self.add_user(username)
|
||||
|
||||
def update_groups(self, uid, ts_groups):
|
||||
logger.debug("Updating uid %s TS3 groups %s" % (uid, ts_groups))
|
||||
|
||||
@@ -85,8 +85,7 @@ def reset_teamspeak3_perm(request):
|
||||
ts3man.delete_user(request.user.teamspeak3.uid)
|
||||
|
||||
logger.debug("Generating new permission key for user %s with main character %s" % (request.user, character))
|
||||
result = ts3man.generate_new_permissionkey(request.user.teamspeak3.uid, character.character_name,
|
||||
character.corporation_ticker)
|
||||
result = ts3man.generate_new_permissionkey(request.user.teamspeak3.uid, character.character_name)
|
||||
|
||||
# if blank we failed
|
||||
if result[0] != "":
|
||||
|
||||
@@ -1,5 +1,6 @@
|
||||
import requests
|
||||
import logging
|
||||
import amqp.exceptions
|
||||
import semantic_version as semver
|
||||
from django import template
|
||||
from django.conf import settings
|
||||
@@ -54,6 +55,9 @@ def get_celery_queue_length():
|
||||
with app.connection_or_acquire() as conn:
|
||||
return conn.default_channel.queue_declare(
|
||||
queue=getattr(settings, 'CELERY_DEFAULT_QUEUE', 'celery'), passive=True).message_count
|
||||
except amqp.exceptions.ChannelError:
|
||||
# Queue doesn't exist, probably empty
|
||||
return 0
|
||||
except Exception:
|
||||
logger.exception("Failed to get celery queue length")
|
||||
return -1
|
||||
@@ -82,7 +86,7 @@ def get_version_info():
|
||||
}
|
||||
try:
|
||||
tags = cache.get_or_set('github_release_tags', get_github_tags, TAG_CACHE_TIME)
|
||||
current_ver = semver.Version(__version__, partial=True)
|
||||
current_ver = semver.Version.coerce(__version__)
|
||||
|
||||
# Set them all to the current version to start
|
||||
# If the server has only earlier or the same version
|
||||
@@ -102,7 +106,10 @@ def get_version_info():
|
||||
if tag_name[0] == 'v':
|
||||
# Strip 'v' off front of verison if it exists
|
||||
tag_name = tag_name[1:]
|
||||
tag_ver = semver.Version(tag_name, partial=True)
|
||||
try:
|
||||
tag_ver = semver.Version.coerce(tag_name)
|
||||
except ValueError:
|
||||
tag_ver = semver.Version('0.0.0', partial=True)
|
||||
if tag_ver > current_ver:
|
||||
if latest_major is None or tag_ver > latest_major:
|
||||
latest_major = tag_ver
|
||||
|
||||
@@ -1,33 +1,9 @@
|
||||
# Groups
|
||||
Group Management is one of the core tasks of Alliance Auth. Many of Alliance Auth's services allow for synchronising of group membership, allowing you to grant permissions or roles in services to access certain aspects of them.
|
||||
|
||||
## Automatic Groups
|
||||
When a member registers in Alliance Auth and selects a main character, Auth will assign them some groups automatically based on some factors.
|
||||
|
||||
```eval_rst
|
||||
.. important::
|
||||
The ``Corp_`` and ``Alliance_`` group name prefixes are reserved for Alliance Auth internal group management. If you prefix a group with these you will find Alliance Auth automatically removes users from the group.
|
||||
```
|
||||
|
||||
```eval_rst
|
||||
+------------------------------+-----------------------------------------------------------------------------------+
|
||||
| Group | Condition |
|
||||
+------------------------------+-----------------------------------------------------------------------------------+
|
||||
| ``Corp_<corp_name>`` | Users Main Character belongs to the Corporation |
|
||||
+------------------------------+-----------------------------------------------------------------------------------+
|
||||
| ``Alliance_<alliance_name>`` | Users Main Character belongs to the Alliance |
|
||||
+------------------------------+-----------------------------------------------------------------------------------+
|
||||
| ``Member`` | User is a member of one of the tenant Corps or Alliances |
|
||||
+------------------------------+-----------------------------------------------------------------------------------+
|
||||
| ``Blue`` | User is a member of a blue Corp or Alliance, be it via standings or static config |
|
||||
+------------------------------+-----------------------------------------------------------------------------------+
|
||||
```
|
||||
|
||||
When the user no longer has the condition required to be a member of that group they are automatically removed by Auth.
|
||||
|
||||
## User Organised Groups
|
||||
|
||||
Along with the automated groups, administrators can create custom groups for users to join. Examples might be groups like `Leadership`, `CEO` or `Scouts`.
|
||||
Administrators can create custom groups for users to join. Examples might be groups like `Leadership`, `CEO` or `Scouts`.
|
||||
|
||||
When you create a Django `Group`, Auth automatically creates a corresponding `AuthGroup` model. The admin page looks like this:
|
||||
|
||||
|
||||
@@ -2,7 +2,7 @@
|
||||
|
||||
```eval_rst
|
||||
.. tip::
|
||||
Installation is easiest as the root user. Log in as root or a user with sudo powers.
|
||||
If you are uncomfortable with linux permissions follow the steps below as the root user. Some commands do not behave the same when run with sudo.
|
||||
```
|
||||
|
||||
## Dependencies
|
||||
@@ -91,6 +91,11 @@ Create a Python virtual environment and put it somewhere convenient (e.g. `/home
|
||||
|
||||
python3 -m venv /home/allianceserver/venv/auth/
|
||||
|
||||
```eval_rst
|
||||
.. warning::
|
||||
The python3 command may not be available on all installations. Try a specific version such as python3.6 if this is the case.
|
||||
```
|
||||
|
||||
```eval_rst
|
||||
.. tip::
|
||||
A virtual environment provides support for creating a lightweight "copy" of Python with their own site directories. Each virtual environment has its own Python binary (allowing creation of environments with various Python versions) and can have its own independent set of installed Python packages in its site directories. You can read more about virtual environments on the Python_ docs.
|
||||
@@ -106,18 +111,11 @@ Activate the virtualenv using `source /home/allianceserver/venv/auth/bin/activat
|
||||
|
||||
### Alliance Auth Project
|
||||
|
||||
You can install the library using `pip install allianceauth`. This will install Alliance Auth and all its python dependencies.
|
||||
You can install the library using `pip install allianceauth`. This will install Alliance Auth and all its python dependencies. You should also install gunicorn with `pip install gunicorn` before proceeding.
|
||||
|
||||
Now you need to create the application that will run the Alliance Auth install. Ensure you are in the allianceserver home directory by issuing `cd /home/allianceserver`.
|
||||
|
||||
The `allianceauth start myauth` command will bootstrap a Django project which will run Alliance Auth. You can rename it from `myauth` to anything you'd like: this name is shown by default as the site name but that can be changed later.
|
||||
|
||||
```eval_rst
|
||||
.. tip::
|
||||
If you plan to use gunicorn as your WSGI server (recommended), ensure it is installed before starting your auth project to have an entry automatically created in the project's supervisor config file. ::
|
||||
|
||||
pip install gunicorn
|
||||
```
|
||||
The `allianceauth start myauth` command bootstraps a Django project which will run Alliance Auth. You can rename it from `myauth` to anything you'd like: this name is shown by default as the site name but that can be changed later.
|
||||
|
||||
The settings file needs configuring. Edit the template at `myauth/myauth/settings/local.py`. Be sure to configure the EVE SSO and Email settings.
|
||||
|
||||
@@ -143,9 +141,9 @@ And finally ensure the allianceserver user has read/write permissions to this di
|
||||
|
||||
### Gunicorn
|
||||
|
||||
To run the auth website a [WSGI Server](https://www.fullstackpython.com/wsgi-servers.html) is required. [Gunicorn](http://gunicorn.org/) is highly recommended for its ease of configuring. Installation is simple: `pip install gunicorn`. It can be manually called with `gunicorn myauth.wsgi` or automatically run using supervisor.
|
||||
To run the auth website a [WSGI Server](https://www.fullstackpython.com/wsgi-servers.html) is required. [Gunicorn](http://gunicorn.org/) is highly recommended for its ease of configuring. It can be manually run with `gunicorn myauth.wsgi` or automatically run using supervisor.
|
||||
|
||||
Additional information is available in the [gunicorn](gunicorn.md) doc.
|
||||
The default configuration is good enough for most installations. Additional information is available in the [gunicorn](gunicorn.md) doc.
|
||||
|
||||
### Supervisor
|
||||
|
||||
@@ -163,8 +161,15 @@ CentOS:
|
||||
|
||||
Once installed it needs a configuration file to know which processes to watch. Your Alliance Auth project comes with a ready-to-use template which will ensure the celery workers, celery task scheduler and gunicorn are all running.
|
||||
|
||||
Ubuntu:
|
||||
|
||||
ln /home/allianceserver/myauth/supervisor.conf /etc/supervisor/conf.d/myauth.conf
|
||||
supervisorctl reload
|
||||
|
||||
CentOS:
|
||||
|
||||
ln /home/allianceserver/myauth/supervisor.conf /etc/supervisord.d/myauth.ini
|
||||
|
||||
And activate it with `supervisorctl reload`.
|
||||
|
||||
You can check the status of the processes with `supervisorctl status`. Logs from these processes are available in `/home/allianceserver/myauth/log` named by process.
|
||||
|
||||
|
||||
@@ -1,108 +1,69 @@
|
||||
# Apache Setup
|
||||
### Overview
|
||||
|
||||
AllianceAuth gets served using a Web Server Gateway Interface (WSGI) script. This script passes web requests to AllianceAuth which generates the content to be displayed and returns it. This means very little has to be configured in Apache to host AllianceAuth.
|
||||
## Overview
|
||||
|
||||
In the interest of ~~laziness~~ time-efficiency, scroll down for example configs. Use these, changing the ServerName to your domain name.
|
||||
Alliance Auth gets served using a Web Server Gateway Interface (WSGI) script. This script passes web requests to Alliance Auth which generates the content to be displayed and returns it. This means very little has to be configured in Apache to host Alliance Auth.
|
||||
|
||||
If you're using a small VPS to host services with very limited memory resources, consider using NGINX with [Gunicorn](gunicorn.md). Even if you would like to use Apache, Gunicorn may give you lower memory usage over mod_wsgi.
|
||||
If you're using a small VPS to host services with very limited memory, consider using [NGINX](nginx.md).
|
||||
|
||||
### Required Parameters for AllianceAuth Core
|
||||
## Installation
|
||||
|
||||
The AllianceAuth core requires the following parameters to be set:
|
||||
Ubuntu:
|
||||
|
||||
WSGIDaemonProcess
|
||||
WSGIProcessGroup
|
||||
WSGIScriptAlias
|
||||
apt-get install apache2
|
||||
|
||||
The following aliases are required:
|
||||
CentOS:
|
||||
|
||||
Alias /static/ to point at the static folder
|
||||
Alias /templates/ to point at the templates folder
|
||||
yum install httpd
|
||||
systemctl enable httpd
|
||||
systemctl start httpd
|
||||
|
||||
## Description of Parameters
|
||||
## Configuration
|
||||
|
||||
- `WSGIDaemonProcess` is the name of the process/application. It also needs to be passed the python-path parameter directing python to search the AllianceAuth directory for modules to load.
|
||||
- `WSGIProcessGroup` is the group to run the process under. Typically the same as the name of the process/application.
|
||||
- `WSGIScriptAlias` points to the WSGI script.
|
||||
Apache serves sites through defined virtual hosts. These are located in `/etc/apache2/sites-available/` on Ubuntu and `/etc/httpd/conf.d/httpd.conf` on CentOS.
|
||||
|
||||
## Additional Parameters for Full Setup
|
||||
A virtual host for auth need only proxy requests to your WSGI server (gunicorn if you followed the install guide) and serve static files. Examples can be found below. Create your config in its own file eg `myauth.conf`.
|
||||
|
||||
To pass additional services the following aliases and directories are required:
|
||||
### Ubuntu
|
||||
|
||||
- `Alias /forums` to point at the forums folder
|
||||
- `Alias /killboard` to point at the killboard
|
||||
To proxy and modify headers a few mods need to be enabled.
|
||||
|
||||
Each of these require directory permissions allowing all connections.
|
||||
a2enmod proxy
|
||||
a2enmod proxy_http
|
||||
a2enmod headers
|
||||
|
||||
For Apache 2.4 or greater:
|
||||
Create a new config file for auth eg `/etc/apache2/sites-available/myauth.conf` and fill out the virtual host configuration. To enable your config use `a2ensite myauth.conf` and then reload apache with `service apache2 reload`.
|
||||
|
||||
<Directory "/path/to/alias/folder">
|
||||
Require all granted
|
||||
</Directory>
|
||||
### CentOS
|
||||
|
||||
For Apache 2.3 or older:
|
||||
Place your virtual host configuration in the appropriate section within `/etc/httpd/conf.d/httpd.conf` and restart the httpd service with `systemctl restart httpd`.
|
||||
|
||||
<Directory "/path/to/alias/folder">
|
||||
Order Deny,Allow
|
||||
Allow from all
|
||||
</Directory>
|
||||
|
||||
## SSL
|
||||
|
||||
You can supply your own SSL certificates if you so desire. The alternative is running behind cloudflare for free SSL.
|
||||
|
||||
## Sample Config Files
|
||||
|
||||
### Minimally functional config
|
||||
## Sample Config File
|
||||
|
||||
```
|
||||
<VirtualHost *:80>
|
||||
ServerName example.com
|
||||
ServerAdmin webmaster@localhost
|
||||
|
||||
DocumentRoot /var/www
|
||||
|
||||
WSGIDaemonProcess allianceauth python-path=/home/allianceserver/allianceauth
|
||||
WSGIProcessGroup allianceauth
|
||||
WSGIScriptAlias / /home/allianceserver/allianceauth/alliance_auth/wsgi.py
|
||||
|
||||
Alias /static/ /home/allianceserver/allianceauth/static/
|
||||
|
||||
<Directory /home/allianceserver/allianceauth/>
|
||||
Require all granted
|
||||
ServerName auth.example.com
|
||||
|
||||
ProxyPassMatch ^/static !
|
||||
ProxyPass / http://127.0.0.1:8000/
|
||||
ProxyPassReverse / http://127.0.0.1:8000/
|
||||
ProxyPreserveHost On
|
||||
|
||||
Alias "/static" "/var/www/myauth/static"
|
||||
<Directory "/var/www/myauth/static">
|
||||
Require all granted
|
||||
</Directory>
|
||||
|
||||
<Directory /var/www/>
|
||||
Require all granted
|
||||
</Directory>
|
||||
</VirtualHost>
|
||||
```
|
||||
|
||||
### Own SSL Cert
|
||||
- Apache 2.4 or newer:
|
||||
- [000-default.conf](http://pastebin.com/3LLzyNmV)
|
||||
- [default-ssl.conf](http://pastebin.com/HUPPEp0R)
|
||||
- Apache 2.3 or older:
|
||||
- [000-default](http://pastebin.com/HfyKpQNu)
|
||||
- [default-ssl](http://pastebin.com/2WCS5jnb)
|
||||
If you use SSL, add the following lines inside the `VirtualHost` block:
|
||||
|
||||
### No SSL Cloudflare, or LetsEncrypt
|
||||
- Apache 2.4 or newer:
|
||||
- [000-default.conf](http://pastebin.com/j1Ps3ZK6)
|
||||
- Apache 2.3 or older:
|
||||
- [000-default](http://pastebin.com/BHQzf2pj)
|
||||
```
|
||||
RequestHeader set X-FORWARDED-PROTOCOL https
|
||||
RequestHeader set X-FORWARDED-SSL On
|
||||
```
|
||||
|
||||
To have LetsEncrypt automatically install SSL certs, comment out the three lines starting with `WSGI`, install certificates, then uncomment them in `000-default-ls-ssl.conf`
|
||||
## SSL
|
||||
|
||||
## Enabling and Disabling Sites
|
||||
|
||||
To instruct apache to serve traffic from a virtual host, enable it:
|
||||
|
||||
sudo a2ensite NAME
|
||||
where NAME is the name of the configuration file (eg 000-default.conf)
|
||||
|
||||
To disable traffic from a site, disable the virtual host:
|
||||
|
||||
sudo a2dissite NAME
|
||||
where NAME is the name of the configuration file (eg 000-default.conf)
|
||||
It's 2018 - there's no reason to run a site without SSL. The EFF provides free, renewable SSL certificates with an automated installer. Visit their [website](https://certbot.eff.org/) for information.
|
||||
@@ -47,7 +47,7 @@ server {
|
||||
location = /favicon.ico { access_log off; log_not_found off; }
|
||||
|
||||
location /static/ {
|
||||
alias /home/allianceserver/allianceauth/static/;
|
||||
alias /var/www/myauth/static;
|
||||
autoindex off;
|
||||
}
|
||||
|
||||
|
||||
@@ -10,7 +10,7 @@ app = Celery('devauth')
|
||||
|
||||
# Using a string here means the worker don't have to serialize
|
||||
# the configuration object to child processes.
|
||||
app.config_from_object('django.conf:settings')
|
||||
app.config_from_object('django.conf:settings', namespace='CELERY')
|
||||
|
||||
# Load task modules from all registered Django app configs.
|
||||
app.autodiscover_tasks(lambda: settings.INSTALLED_APPS)
|
||||
|
||||
@@ -14,7 +14,7 @@ NOSE_ARGS = [
|
||||
]
|
||||
|
||||
# Celery configuration
|
||||
CELERY_ALWAYS_EAGER = True # Forces celery to run locally for testing
|
||||
CELERY_TASK_ALWAYS_EAGER = True # Forces celery to run locally for testing
|
||||
|
||||
INSTALLED_APPS += [
|
||||
'allianceauth.eveonline.autogroups',
|
||||
|
||||
Reference in New Issue
Block a user