mirror of
https://gitlab.com/allianceauth/allianceauth.git
synced 2025-07-27 05:02:27 +02:00
Compare commits
6 Commits
757c6fa491
...
5e836c4285
Author | SHA1 | Date | |
---|---|---|---|
|
5e836c4285 | ||
|
dc0c1a2818 | ||
|
eaba01ad97 | ||
|
f4c024d199 | ||
|
8f4daea14f | ||
|
b95f393a4c |
@ -5,20 +5,20 @@
|
||||
|
||||
repos:
|
||||
- repo: https://github.com/astral-sh/ruff-pre-commit
|
||||
rev: v0.6.4
|
||||
rev: v0.8.1
|
||||
hooks:
|
||||
# Run the linter, and only the linter
|
||||
- id: ruff
|
||||
|
||||
- repo: https://github.com/adamchainz/django-upgrade
|
||||
rev: 1.21.0
|
||||
rev: 1.22.2
|
||||
hooks:
|
||||
- id: django-upgrade
|
||||
args: [--target-version=4.2]
|
||||
|
||||
# Formatting
|
||||
- repo: https://github.com/pre-commit/pre-commit-hooks
|
||||
rev: v4.6.0
|
||||
rev: v5.0.0
|
||||
hooks:
|
||||
# Identify invalid files
|
||||
- id: check-ast
|
||||
@ -75,14 +75,14 @@ repos:
|
||||
swagger\.json
|
||||
)
|
||||
- repo: https://github.com/igorshubovych/markdownlint-cli
|
||||
rev: v0.41.0
|
||||
rev: v0.43.0
|
||||
hooks:
|
||||
- id: markdownlint
|
||||
args:
|
||||
- --disable=MD013
|
||||
# Infrastructure
|
||||
- repo: https://github.com/tox-dev/pyproject-fmt
|
||||
rev: 2.2.3
|
||||
rev: v2.5.0
|
||||
hooks:
|
||||
- id: pyproject-fmt
|
||||
name: pyproject.toml formatter
|
||||
@ -92,7 +92,7 @@ repos:
|
||||
additional_dependencies:
|
||||
- tox==4.18.1 # https://github.com/tox-dev/tox/releases/latest
|
||||
- repo: https://github.com/abravalheri/validate-pyproject
|
||||
rev: v0.19
|
||||
rev: v0.23
|
||||
hooks:
|
||||
- id: validate-pyproject
|
||||
name: Validate pyproject.toml
|
||||
|
@ -43,11 +43,12 @@ def system_package_redis(app_configs, **kwargs) -> list[CheckMessage]:
|
||||
except InvalidVersion:
|
||||
errors.append(Warning("Unable to confirm Redis Version"))
|
||||
return errors
|
||||
|
||||
if redis_version.major == 7 and redis_version.minor == 2 and timezone.now() > timezone.datetime(year=2025, month=8, day=31, tzinfo=datetime.timezone.utc):
|
||||
if redis_version.major == 7 and redis_version.minor == 4 and timezone.now() > timezone.datetime(year=2025, month=8, day=31, tzinfo=datetime.timezone.utc):
|
||||
errors.append(Error(f"Redis {redis_version.public} in Security Support only, Updating Suggested", hint="https://allianceauth.readthedocs.io/en/latest/installation/allianceauth.html#redis-and-other-tools", id="allianceauth.checks.A001"))
|
||||
elif redis_version.major == 7 and redis_version.minor == 2:
|
||||
errors.append(Error(f"Redis {redis_version.public} in Security Support only, Updating Suggested", hint="https://allianceauth.readthedocs.io/en/latest/installation/allianceauth.html#redis-and-other-tools", id="allianceauth.checks.A019"))
|
||||
elif redis_version.major == 7 and redis_version.minor == 0:
|
||||
errors.append(Warning(f"Redis {redis_version.public} in Security Support only, Updating Suggested", hint="https://allianceauth.readthedocs.io/en/latest/installation/allianceauth.html#redis-and-other-tools", id="allianceauth.checks.A002"))
|
||||
errors.append(Error(f"Redis {redis_version.public} EOL", hint="https://allianceauth.readthedocs.io/en/latest/installation/allianceauth.html#redis-and-other-tools", id="allianceauth.checks.A019"))
|
||||
elif redis_version.major == 6 and redis_version.minor == 2:
|
||||
errors.append(Warning(f"Redis {redis_version.public} in Security Support only, Updating Suggested", hint="https://allianceauth.readthedocs.io/en/latest/installation/allianceauth.html#redis-and-other-tools", id="allianceauth.checks.A018"))
|
||||
elif redis_version.major in [6, 5]:
|
||||
@ -71,11 +72,7 @@ def system_package_mysql(app_configs, **kwargs) -> list[CheckMessage]:
|
||||
# MySQL 8
|
||||
if mysql_version.major == 8 and mysql_version.minor == 4 and timezone.now() > timezone.datetime(year=2032, month=4, day=30, tzinfo=datetime.timezone.utc):
|
||||
errors.append(Error(f"MySQL {mysql_version.public} EOL", hint="https://dev.mysql.com/doc/mysql-apt-repo-quick-guide/en/", id="allianceauth.checks.A004"))
|
||||
elif mysql_version.major == 8 and mysql_version.minor == 3:
|
||||
errors.append(Warning(f"MySQL {mysql_version.public} Non LTS", hint="https://dev.mysql.com/doc/mysql-apt-repo-quick-guide/en/", id="allianceauth.checks.A005"))
|
||||
elif mysql_version.major == 8 and mysql_version.minor == 2:
|
||||
errors.append(Warning(f"MySQL {mysql_version.public} Non LTS", hint="https://dev.mysql.com/doc/mysql-apt-repo-quick-guide/en/", id="allianceauth.checks.A006"))
|
||||
elif mysql_version.major == 8 and mysql_version.minor == 1:
|
||||
elif mysql_version.major == 8 and mysql_version.minor in [1, 2, 3]:
|
||||
errors.append(Error(f"MySQL {mysql_version.public} EOL", hint="https://dev.mysql.com/doc/mysql-apt-repo-quick-guide/en/", id="allianceauth.checks.A007"))
|
||||
elif mysql_version.major == 8 and mysql_version.minor == 0 and timezone.now() > timezone.datetime(year=2026, month=4, day=30, tzinfo=datetime.timezone.utc):
|
||||
errors.append(Error(f"MySQL {mysql_version.public} EOL", hint="https://dev.mysql.com/doc/mysql-apt-repo-quick-guide/en/", id="allianceauth.checks.A008"))
|
||||
@ -99,14 +96,7 @@ def system_package_mariadb(app_configs, **kwargs) -> list[CheckMessage]:
|
||||
# MariaDB 11
|
||||
if mariadb_version.major == 11 and mariadb_version.minor == 4 and timezone.now() > timezone.datetime(year=2029, month=5, day=19, tzinfo=datetime.timezone.utc):
|
||||
errors.append(Error(f"MariaDB {mariadb_version.public} EOL", hint="https://mariadb.org/download/?t=repo-config", id="allianceauth.checks.A010"))
|
||||
elif mariadb_version.major == 11 and mariadb_version.minor == 2:
|
||||
errors.append(Warning(f"MariaDB {mariadb_version.public} Non LTS", hint="https://mariadb.org/download/?t=repo-config", id="allianceauth.checks.A018"))
|
||||
if timezone.now() > timezone.datetime(year=2024, month=11, day=21, tzinfo=datetime.timezone.utc):
|
||||
errors.append(Error(f"MariaDB {mariadb_version.public} EOL", hint="https://mariadb.org/download/?t=repo-config", id="allianceauth.checks.A011"))
|
||||
elif mariadb_version.major == 11 and mariadb_version.minor == 1:
|
||||
errors.append(Warning(f"MariaDB {mariadb_version.public} Non LTS", hint="https://mariadb.org/download/?t=repo-config", id="allianceauth.checks.A019"))
|
||||
errors.append(Error(f"MariaDB {mariadb_version.public} EOL", hint="https://mariadb.org/download/?t=repo-config", id="allianceauth.checks.A012"))
|
||||
elif mariadb_version.major == 11 and mariadb_version.minor in [0, 3]: # Demote versions down here once EOL
|
||||
elif mariadb_version.major == 11 and mariadb_version.minor in [0, 1, 2, 3, 5]: # Demote versions down here once EOL
|
||||
errors.append(Error(f"MariaDB {mariadb_version.public} EOL", hint="https://mariadb.org/download/?t=repo-config.", id="allianceauth.checks.A013"))
|
||||
|
||||
# MariaDB 10
|
||||
|
@ -70,7 +70,7 @@ def forward(apps, schema_editor):
|
||||
perm.delete()
|
||||
|
||||
|
||||
def reverse(apps, schema_editor):
|
||||
def reverse(apps, schema_editor): # noqa: C901
|
||||
perm_dict = user_permissions_dict(apps)
|
||||
|
||||
corp_users = users_with_permission(apps, perm_dict['corpstats']['view_corp_corpstats'])
|
||||
|
@ -62,7 +62,7 @@ def corpstats_add(request, token):
|
||||
|
||||
@login_required
|
||||
@user_passes_test(access_corpstats_test)
|
||||
def corpstats_view(request, corp_id=None):
|
||||
def corpstats_view(request, corp_id=None): # noqa: C901
|
||||
corpstats = None
|
||||
|
||||
# get requested model
|
||||
|
@ -49,8 +49,8 @@ class EveFactionForm(EveEntityForm):
|
||||
def clean_id(self):
|
||||
try:
|
||||
assert self.Meta.model.provider.get_faction(self.cleaned_data['id'])
|
||||
except (AssertionError, ObjectNotFound):
|
||||
raise EveEntityNotFoundError('faction', self.cleaned_data['id'])
|
||||
except (AssertionError, ObjectNotFound) as e:
|
||||
raise EveEntityNotFoundError('faction', self.cleaned_data['id']) from e
|
||||
if self.Meta.model.objects.filter(faction_id=self.cleaned_data['id']).exists():
|
||||
raise EveEntityExistsError('faction', self.cleaned_data['id'])
|
||||
return self.cleaned_data['id']
|
||||
@ -70,8 +70,8 @@ class EveCharacterForm(EveEntityForm):
|
||||
def clean_id(self):
|
||||
try:
|
||||
assert self.Meta.model.provider.get_character(self.cleaned_data['id'])
|
||||
except (AssertionError, ObjectNotFound):
|
||||
raise EveEntityNotFoundError(self.entity_type_name, self.cleaned_data['id'])
|
||||
except (AssertionError, ObjectNotFound) as e:
|
||||
raise EveEntityNotFoundError(self.entity_type_name, self.cleaned_data['id']) from e
|
||||
if self.Meta.model.objects.filter(character_id=self.cleaned_data['id']).exists():
|
||||
raise EveEntityExistsError(self.entity_type_name, self.cleaned_data['id'])
|
||||
return self.cleaned_data['id']
|
||||
@ -90,8 +90,8 @@ class EveCorporationForm(EveEntityForm):
|
||||
def clean_id(self):
|
||||
try:
|
||||
assert self.Meta.model.provider.get_corporation(self.cleaned_data['id'])
|
||||
except (AssertionError, ObjectNotFound):
|
||||
raise EveEntityNotFoundError(self.entity_type_name, self.cleaned_data['id'])
|
||||
except (AssertionError, ObjectNotFound) as e:
|
||||
raise EveEntityNotFoundError(self.entity_type_name, self.cleaned_data['id']) from e
|
||||
if self.Meta.model.objects.filter(corporation_id=self.cleaned_data['id']).exists():
|
||||
raise EveEntityExistsError(self.entity_type_name, self.cleaned_data['id'])
|
||||
return self.cleaned_data['id']
|
||||
@ -110,8 +110,8 @@ class EveAllianceForm(EveEntityForm):
|
||||
def clean_id(self):
|
||||
try:
|
||||
assert self.Meta.model.provider.get_alliance(self.cleaned_data['id'])
|
||||
except (AssertionError, ObjectNotFound):
|
||||
raise EveEntityNotFoundError(self.entity_type_name, self.cleaned_data['id'])
|
||||
except (AssertionError, ObjectNotFound) as e:
|
||||
raise EveEntityNotFoundError(self.entity_type_name, self.cleaned_data['id']) from e
|
||||
if self.Meta.model.objects.filter(alliance_id=self.cleaned_data['id']).exists():
|
||||
raise EveEntityExistsError(self.entity_type_name, self.cleaned_data['id'])
|
||||
return self.cleaned_data['id']
|
||||
|
@ -223,8 +223,8 @@ class EveSwaggerProvider(EveProvider):
|
||||
faction_id=data['faction_id'] if 'faction_id' in data else None,
|
||||
)
|
||||
return model
|
||||
except HTTPNotFound:
|
||||
raise ObjectNotFound(alliance_id, 'alliance')
|
||||
except HTTPNotFound as e:
|
||||
raise ObjectNotFound(alliance_id, 'alliance') from e
|
||||
|
||||
def get_corp(self, corp_id: int) -> Corporation:
|
||||
"""Fetch corporation from ESI."""
|
||||
@ -240,8 +240,8 @@ class EveSwaggerProvider(EveProvider):
|
||||
faction_id=data['faction_id'] if 'faction_id' in data else None,
|
||||
)
|
||||
return model
|
||||
except HTTPNotFound:
|
||||
raise ObjectNotFound(corp_id, 'corporation')
|
||||
except HTTPNotFound as e:
|
||||
raise ObjectNotFound(corp_id, 'corporation') from e
|
||||
|
||||
def get_character(self, character_id: int) -> Character:
|
||||
"""Fetch character from ESI."""
|
||||
@ -256,8 +256,8 @@ class EveSwaggerProvider(EveProvider):
|
||||
faction_id=affiliation['faction_id'] if 'faction_id' in affiliation else None,
|
||||
)
|
||||
return model
|
||||
except (HTTPNotFound, HTTPUnprocessableEntity, ObjectNotFound):
|
||||
raise ObjectNotFound(character_id, 'character')
|
||||
except (HTTPNotFound, HTTPUnprocessableEntity, ObjectNotFound) as e:
|
||||
raise ObjectNotFound(character_id, 'character') from e
|
||||
|
||||
def _fetch_character_name(self, character_id: int) -> str:
|
||||
"""Fetch character name from ESI."""
|
||||
@ -288,16 +288,16 @@ class EveSwaggerProvider(EveProvider):
|
||||
return Entity(id=f['faction_id'], name=f['name'])
|
||||
else:
|
||||
raise KeyError()
|
||||
except (HTTPNotFound, HTTPUnprocessableEntity, KeyError):
|
||||
raise ObjectNotFound(faction_id, 'faction')
|
||||
except (HTTPNotFound, HTTPUnprocessableEntity, KeyError) as e:
|
||||
raise ObjectNotFound(faction_id, 'faction') from e
|
||||
|
||||
def get_itemtype(self, type_id: int) -> ItemType:
|
||||
"""Fetch inventory item from ESI."""
|
||||
try:
|
||||
data = self.client.Universe.get_universe_types_type_id(type_id=type_id).result()
|
||||
return ItemType(id=type_id, name=data['name'])
|
||||
except (HTTPNotFound, HTTPUnprocessableEntity):
|
||||
raise ObjectNotFound(type_id, 'type')
|
||||
except (HTTPNotFound, HTTPUnprocessableEntity) as e:
|
||||
raise ObjectNotFound(type_id, 'type') from e
|
||||
|
||||
|
||||
provider = EveSwaggerProvider()
|
||||
|
@ -57,11 +57,11 @@ class EsiClientStub:
|
||||
}
|
||||
try:
|
||||
return BravadoOperationStub(data[int(alliance_id)])
|
||||
except KeyError:
|
||||
except KeyError as e:
|
||||
response = BravadoResponseStub(
|
||||
404, f"Alliance with ID {alliance_id} not found"
|
||||
)
|
||||
raise HTTPNotFound(response)
|
||||
raise HTTPNotFound(response) from e
|
||||
|
||||
@staticmethod
|
||||
def get_alliances_alliance_id_corporations(alliance_id):
|
||||
@ -87,11 +87,11 @@ class EsiClientStub:
|
||||
}
|
||||
try:
|
||||
return BravadoOperationStub(data[int(character_id)])
|
||||
except KeyError:
|
||||
except KeyError as e:
|
||||
response = BravadoResponseStub(
|
||||
404, f"Character with ID {character_id} not found"
|
||||
)
|
||||
raise HTTPNotFound(response)
|
||||
raise HTTPNotFound(response) from e
|
||||
|
||||
@staticmethod
|
||||
def post_characters_affiliation(characters: list):
|
||||
@ -147,11 +147,11 @@ class EsiClientStub:
|
||||
}
|
||||
try:
|
||||
return BravadoOperationStub(data[int(corporation_id)])
|
||||
except KeyError:
|
||||
except KeyError as e:
|
||||
response = BravadoResponseStub(
|
||||
404, f"Corporation with ID {corporation_id} not found"
|
||||
)
|
||||
raise HTTPNotFound(response)
|
||||
raise HTTPNotFound(response) from e
|
||||
|
||||
class Universe:
|
||||
@staticmethod
|
||||
|
@ -143,7 +143,12 @@ def fatlink_statistics_corp_view(request, corpid, year=None, month=None):
|
||||
|
||||
@login_required
|
||||
@permission_required('auth.fleetactivitytracking_statistics')
|
||||
def fatlink_statistics_view(request, year=datetime.date.today().year, month=datetime.date.today().month):
|
||||
def fatlink_statistics_view(request, year=None, month=None):
|
||||
if year is None:
|
||||
year = datetime.date.today().year
|
||||
if month is None:
|
||||
month = datetime.date.today().month
|
||||
|
||||
year = int(year)
|
||||
month = int(month)
|
||||
start_of_month = datetime.datetime(year, month, 1)
|
||||
@ -176,9 +181,12 @@ def fatlink_statistics_view(request, year=datetime.date.today().year, month=date
|
||||
|
||||
|
||||
@login_required
|
||||
def fatlink_personal_statistics_view(request, year=datetime.date.today().year):
|
||||
def fatlink_personal_statistics_view(request, year=None):
|
||||
if year is None:
|
||||
year = datetime.date.today().year
|
||||
|
||||
year = int(year)
|
||||
logger.debug("Personal statistics view for year %i called by %s" % (year, request.user))
|
||||
logger.debug(f"Personal statistics view for year {year} called by {request.user}")
|
||||
|
||||
user = request.user
|
||||
logger.debug(f"fatlink_personal_statistics_view called by user {request.user}")
|
||||
|
@ -87,8 +87,8 @@ def group_membership_audit(request, group_id):
|
||||
logger.warning(f"User {request.user} attempted to view the membership of group {group_id} but permission was denied")
|
||||
raise PermissionDenied
|
||||
|
||||
except ObjectDoesNotExist:
|
||||
raise Http404("Group does not exist")
|
||||
except ObjectDoesNotExist as e:
|
||||
raise Http404("Group does not exist") from e
|
||||
render_items = {'group': group}
|
||||
entries = RequestLog.objects.filter(group=group).order_by('-date')
|
||||
render_items['entries'] = entries
|
||||
@ -117,8 +117,8 @@ def group_membership_list(request, group_id):
|
||||
)
|
||||
raise PermissionDenied
|
||||
|
||||
except ObjectDoesNotExist:
|
||||
raise Http404("Group does not exist")
|
||||
except ObjectDoesNotExist as e:
|
||||
raise Http404("Group does not exist") from e
|
||||
|
||||
group_leaders = group.authgroup.group_leaders.all()
|
||||
members = []
|
||||
|
@ -111,8 +111,8 @@ def hr_application_view(request, app_id):
|
||||
logger.debug(f"hr_application_view called by user {request.user} for app id {app_id}")
|
||||
try:
|
||||
app = Application.objects.prefetch_related('responses', 'comments', 'comments__user').get(pk=app_id)
|
||||
except Application.DoesNotExist:
|
||||
raise Http404
|
||||
except Application.DoesNotExist as e:
|
||||
raise Http404 from e
|
||||
if request.method == 'POST':
|
||||
if request.user.has_perm('hrapplications.add_applicationcomment'):
|
||||
form = HRApplicationCommentForm(request.POST)
|
||||
|
@ -47,7 +47,7 @@ class MenuItem(models.Model):
|
||||
)
|
||||
|
||||
# app related properties
|
||||
hook_hash = models.CharField(
|
||||
hook_hash = models.CharField( # noqa: DJ001
|
||||
max_length=64,
|
||||
default=None,
|
||||
null=True,
|
||||
|
@ -77,7 +77,7 @@ class RenderedMenuItem:
|
||||
self.html_id = hook_obj.html_id
|
||||
|
||||
|
||||
def render_menu(request: HttpRequest) -> list[RenderedMenuItem]:
|
||||
def render_menu(request: HttpRequest) -> list[RenderedMenuItem]: # noqa: C901
|
||||
"""Return the rendered side menu for including in a template.
|
||||
|
||||
This function is creating BS5 style menus.
|
||||
|
@ -48,8 +48,8 @@ def permissions_audit(request, app_label, model, codename):
|
||||
.prefetch_related('group_set', 'user_set', 'state_set',
|
||||
'state_set__userprofile_set', 'group_set__user_set', 'state_set__userprofile_set__user')\
|
||||
.get(content_type__app_label=app_label, content_type__model=model, codename=codename)
|
||||
except Permission.DoesNotExist:
|
||||
raise Http404
|
||||
except Permission.DoesNotExist as e:
|
||||
raise Http404 from e
|
||||
|
||||
context = {'permission': {
|
||||
'permission': perm,
|
||||
|
@ -33,7 +33,6 @@ class AbstractServiceModel(models.Model):
|
||||
related_name='%(app_label)s'
|
||||
)
|
||||
|
||||
|
||||
class Meta:
|
||||
abstract = True
|
||||
|
||||
@ -85,8 +84,8 @@ class ServicesCRUDMixin(SingleObjectMixin):
|
||||
|
||||
try:
|
||||
return queryset.get(user__pk=self.request.user.pk)
|
||||
except ObjectDoesNotExist:
|
||||
raise Http404
|
||||
except ObjectDoesNotExist as e:
|
||||
raise Http404 from e
|
||||
|
||||
|
||||
class BaseDeactivateServiceAccountView(ServicesCRUDMixin, BaseServiceView, DeleteView):
|
||||
|
@ -44,26 +44,24 @@ MAX_JITTER_PER_RUN_SECS = 1.0
|
||||
|
||||
def worker(num: int):
|
||||
"""worker function"""
|
||||
worker_info = 'worker %d' % num
|
||||
logger.info('%s: started', worker_info)
|
||||
worker_info = f'worker {num}'
|
||||
logger.info(f'{worker_info}: started')
|
||||
client = DiscordClient(DISCORD_BOT_TOKEN)
|
||||
try:
|
||||
runs = 0
|
||||
while runs < NUMBER_OF_RUNS:
|
||||
run_info = '%s: run %d' % (worker_info, runs + 1)
|
||||
run_info = f'{worker_info}: run {runs + 1}'
|
||||
my_jitter_secs = random() * MAX_JITTER_PER_RUN_SECS
|
||||
logger.info('%s - waiting %s secs', run_info, f'{my_jitter_secs:.3f}')
|
||||
logger.info(f'{run_info} - waiting {my_jitter_secs:.3f} secs')
|
||||
sleep(my_jitter_secs)
|
||||
logger.info('%s - started', run_info)
|
||||
logger.info(f'{run_info} - started')
|
||||
try:
|
||||
client.modify_guild_member(
|
||||
DISCORD_GUILD_ID, DISCORD_USER_ID, nick=NICK
|
||||
)
|
||||
runs += 1
|
||||
except DiscordApiBackoff as bo:
|
||||
message = '%s - waiting out API backoff for %d ms' % (
|
||||
run_info, bo.retry_after
|
||||
)
|
||||
message = f'{run_info} - waiting out API backoff for {bo.retry_after} ms'
|
||||
logger.info(message)
|
||||
print()
|
||||
print(message)
|
||||
|
@ -89,12 +89,12 @@ def _task_perform_user_action(self, user_pk: int, method: str, **kwargs) -> None
|
||||
bo,
|
||||
bo.retry_after_seconds
|
||||
)
|
||||
raise self.retry(countdown=bo.retry_after_seconds)
|
||||
raise self.retry(exc=bo, countdown=bo.retry_after_seconds) from bo
|
||||
|
||||
except AttributeError:
|
||||
raise ValueError(f'{method} not a valid method for DiscordUser')
|
||||
except AttributeError as e:
|
||||
raise ValueError(f'{method} not a valid method for DiscordUser') from e
|
||||
|
||||
except (HTTPError, ConnectionError):
|
||||
except (HTTPError, ConnectionError) as e:
|
||||
logger.warning(
|
||||
'%s failed for user %s, retrying in %d secs',
|
||||
method,
|
||||
@ -103,7 +103,7 @@ def _task_perform_user_action(self, user_pk: int, method: str, **kwargs) -> None
|
||||
exc_info=True
|
||||
)
|
||||
if self.request.retries < DISCORD_TASKS_MAX_RETRIES:
|
||||
raise self.retry(countdown=DISCORD_TASKS_RETRY_PAUSE)
|
||||
raise self.retry(exc=e, countdown=DISCORD_TASKS_RETRY_PAUSE) from e
|
||||
else:
|
||||
logger.error(
|
||||
'%s failed for user %s after max retries',
|
||||
@ -192,8 +192,8 @@ def _task_perform_users_action(self, method: str, **kwargs) -> Any:
|
||||
try:
|
||||
result = getattr(DiscordUser.objects, method)(**kwargs)
|
||||
|
||||
except AttributeError:
|
||||
raise ValueError(f'{method} not a valid method for DiscordUser.objects')
|
||||
except AttributeError as e:
|
||||
raise ValueError(f'{method} not a valid method for DiscordUser.objects') from e
|
||||
|
||||
except DiscordApiBackoff as bo:
|
||||
logger.info(
|
||||
@ -202,9 +202,9 @@ def _task_perform_users_action(self, method: str, **kwargs) -> Any:
|
||||
bo,
|
||||
bo.retry_after_seconds
|
||||
)
|
||||
raise self.retry(countdown=bo.retry_after_seconds)
|
||||
raise self.retry(exc=bo, countdown=bo.retry_after_seconds) from bo
|
||||
|
||||
except (HTTPError, ConnectionError):
|
||||
except (HTTPError, ConnectionError)as e:
|
||||
logger.warning(
|
||||
'%s failed, retrying in %d secs',
|
||||
method,
|
||||
@ -212,7 +212,7 @@ def _task_perform_users_action(self, method: str, **kwargs) -> Any:
|
||||
exc_info=True
|
||||
)
|
||||
if self.request.retries < DISCORD_TASKS_MAX_RETRIES:
|
||||
raise self.retry(countdown=DISCORD_TASKS_RETRY_PAUSE)
|
||||
raise self.retry(exc=e, countdown=DISCORD_TASKS_RETRY_PAUSE) from e
|
||||
else:
|
||||
logger.error('%s failed after max retries', method, exc_info=True)
|
||||
|
||||
|
@ -52,7 +52,7 @@ class DiscourseTasks:
|
||||
except Exception as e:
|
||||
logger.exception(e)
|
||||
logger.warning(f"Discourse group sync failed for {user}, retrying in 10 mins")
|
||||
raise self.retry(countdown=60 * 10)
|
||||
raise self.retry(exc=e, countdown=60 * 10) from e
|
||||
logger.debug(f"Updated user {user} discourse groups.")
|
||||
|
||||
@staticmethod
|
||||
|
@ -41,9 +41,9 @@ class MumbleTasks:
|
||||
return True
|
||||
except MumbleUser.DoesNotExist:
|
||||
logger.info(f"Mumble group sync failed for {user}, user does not have a mumble account")
|
||||
except Exception:
|
||||
except Exception as e:
|
||||
logger.exception(f"Mumble group sync failed for {user}, retrying in 10 mins")
|
||||
raise self.retry(countdown=60 * 10)
|
||||
raise self.retry(exc=e, countdown=60 * 10) from e
|
||||
else:
|
||||
logger.debug(f"User {user} does not have a mumble account, skipping")
|
||||
return False
|
||||
@ -61,9 +61,9 @@ class MumbleTasks:
|
||||
return True
|
||||
except MumbleUser.DoesNotExist:
|
||||
logger.info(f"Mumble display name sync failed for {user}, user does not have a mumble account")
|
||||
except Exception:
|
||||
except Exception as e:
|
||||
logger.exception(f"Mumble display name sync failed for {user}, retrying in 10 mins")
|
||||
raise self.retry(countdown=60 * 10)
|
||||
raise self.retry(exc=e, countdown=60 * 10) from e
|
||||
else:
|
||||
logger.debug(f"User {user} does not have a mumble account, skipping")
|
||||
return False
|
||||
|
@ -54,9 +54,9 @@ class OpenfireTasks:
|
||||
logger.debug(f"Updating user {user} jabber groups to {groups}")
|
||||
try:
|
||||
OpenfireManager.update_user_groups(user.openfire.username, groups)
|
||||
except Exception:
|
||||
except Exception as e:
|
||||
logger.exception(f"Jabber group sync failed for {user}, retrying in 10 mins")
|
||||
raise self.retry(countdown=60 * 10)
|
||||
raise self.retry(exc=e, countdown=60 * 10) from e
|
||||
logger.debug(f"Updated user {user} jabber groups.")
|
||||
else:
|
||||
logger.debug("User does not have an openfire account")
|
||||
|
@ -8,10 +8,10 @@ class Phpbb3User(models.Model):
|
||||
related_name='phpbb3')
|
||||
username = models.CharField(max_length=254)
|
||||
|
||||
def __str__(self):
|
||||
return self.username
|
||||
|
||||
class Meta:
|
||||
permissions = (
|
||||
("access_phpbb3", "Can access the phpBB3 service"),
|
||||
)
|
||||
|
||||
def __str__(self) -> str:
|
||||
return self.username
|
||||
|
@ -49,9 +49,9 @@ class Phpbb3Tasks:
|
||||
logger.debug(f"Updating user {user} phpbb3 groups to {groups}")
|
||||
try:
|
||||
Phpbb3Manager.update_groups(user.phpbb3.username, groups)
|
||||
except Exception:
|
||||
except Exception as e:
|
||||
logger.exception(f"Phpbb group sync failed for {user}, retrying in 10 mins")
|
||||
raise self.retry(countdown=60 * 10)
|
||||
raise self.retry(exc=e, countdown=60 * 10) from e
|
||||
logger.debug(f"Updated user {user} phpbb3 groups.")
|
||||
else:
|
||||
logger.debug("User does not have a Phpbb3 account")
|
||||
|
@ -53,9 +53,9 @@ class SmfTasks:
|
||||
logger.debug(f"Updating user {user} smf groups to {groups}")
|
||||
try:
|
||||
SmfManager.update_groups(user.smf.username, groups)
|
||||
except Exception:
|
||||
except Exception as e:
|
||||
logger.exception(f"smf group sync failed for {user}, retrying in 10 mins")
|
||||
raise self.retry(countdown=60 * 10)
|
||||
raise self.retry(exc=e, countdown=60 * 10) from e
|
||||
logger.debug(f"Updated user {user} smf groups.")
|
||||
else:
|
||||
logger.debug("User does not have an smf account")
|
||||
@ -77,11 +77,11 @@ class SmfTasks:
|
||||
f"SMF displayed name sync failed for {user}, "
|
||||
"user does not have a SMF account"
|
||||
)
|
||||
except Exception:
|
||||
except Exception as e:
|
||||
logger.exception(
|
||||
f"SMF displayed name sync failed for {user}, retrying in 10 mins"
|
||||
)
|
||||
raise self.retry(countdown=60 * 10)
|
||||
raise self.retry(exc=e, countdown=60 * 10) from e
|
||||
else:
|
||||
logger.debug(f"User {user} does not have a SMF account, skipping")
|
||||
|
||||
|
@ -81,7 +81,7 @@ class Teamspeak3Tasks:
|
||||
logger.debug(f"Updated user {user} teamspeak3 groups.")
|
||||
except TeamspeakError as e:
|
||||
logger.error(f"Error occured while syncing TS groups for {user}: {str(e)}")
|
||||
raise self.retry(countdown=60*10)
|
||||
raise self.retry(exc=e, countdown=60 * 10) from e
|
||||
else:
|
||||
logger.debug("User does not have a teamspeak3 account")
|
||||
|
||||
|
@ -182,7 +182,7 @@ class TS3Proto:
|
||||
"""
|
||||
|
||||
if isinstance(value, int):
|
||||
return "%d" % value
|
||||
return f"{value}"
|
||||
value = value.replace("\\", r'\\')
|
||||
for i, j in ts3_escape.items():
|
||||
value = value.replace(i, j)
|
||||
@ -197,7 +197,7 @@ class TS3Proto:
|
||||
"""
|
||||
|
||||
if isinstance(value, int):
|
||||
return "%d" % value
|
||||
return f"{value}"
|
||||
value = value.replace(r"\\", "\\")
|
||||
for i, j in ts3_escape.items():
|
||||
value = value.replace(j, i)
|
||||
|
@ -68,8 +68,8 @@ def m2m_changed_group_permissions(sender, instance, action, pk_set, *args, **kwa
|
||||
logger.debug(f"Received m2m_changed from group {instance} permissions with action {action}")
|
||||
if instance.pk and (action == "post_remove" or action == "post_clear"):
|
||||
logger.debug(f"Checking if service permission changed for group {instance}")
|
||||
# As validating an entire groups service could lead to many thousands of permission checks
|
||||
# first we check that one of the permissions changed is, in fact, a service permission.
|
||||
# As validating an entire group's service could lead to many thousands of permission checks,
|
||||
# first, we check that one of the permissions changed is, in fact, a service permission.
|
||||
perms = Permission.objects.filter(pk__in=pk_set)
|
||||
got_change = False
|
||||
service_perms = [svc.access_perm for svc in ServicesHook.get_services()]
|
||||
@ -81,18 +81,19 @@ def m2m_changed_group_permissions(sender, instance, action, pk_set, *args, **kwa
|
||||
continue
|
||||
for svc in ServicesHook.get_services():
|
||||
if svc.access_perm == path_perm:
|
||||
logger.debug(f"Permissions changed for group {instance} on service {svc}, re-validating services for groups users")
|
||||
logger.debug(f"Permissions changed for group {instance} on service {svc}, re-validating services for group users")
|
||||
|
||||
def validate_all_groups_users_for_service():
|
||||
logger.debug(f"Performing validation for service {svc}")
|
||||
def validate_all_groups_users_for_service(service):
|
||||
logger.debug(f"Performing validation for service {service}")
|
||||
for user in instance.user_set.all():
|
||||
svc.validate_user(user)
|
||||
service.validate_user(user)
|
||||
|
||||
transaction.on_commit(validate_all_groups_users_for_service)
|
||||
transaction.on_commit(lambda service=svc: validate_all_groups_users_for_service(service))
|
||||
got_change = True
|
||||
break # Found service, break out of services iteration and go back to permission iteration
|
||||
if not got_change:
|
||||
logger.debug(f"Permission change for group {instance} was not service permission, ignoring")
|
||||
logger.debug(f"Permission change for group {instance} was not a service permission, ignoring")
|
||||
|
||||
|
||||
|
||||
@receiver(m2m_changed, sender=State.permissions.through)
|
||||
@ -115,12 +116,12 @@ def m2m_changed_state_permissions(sender, instance, action, pk_set, *args, **kwa
|
||||
if svc.access_perm == path_perm:
|
||||
logger.debug(f"Permissions changed for state {instance} on service {svc}, re-validating services for state users")
|
||||
|
||||
def validate_all_state_users_for_service():
|
||||
logger.debug(f"Performing validation for service {svc}")
|
||||
def validate_all_state_users_for_service(service):
|
||||
logger.debug(f"Performing validation for service {service}")
|
||||
for profile in instance.userprofile_set.all():
|
||||
svc.validate_user(profile.user)
|
||||
service.validate_user(profile.user)
|
||||
|
||||
transaction.on_commit(validate_all_state_users_for_service)
|
||||
transaction.on_commit(lambda service=svc: validate_all_state_users_for_service(service))
|
||||
got_change = True
|
||||
break # Found service, break out of services iteration and go back to permission iteration
|
||||
if not got_change:
|
||||
|
@ -28,11 +28,7 @@ x-allianceauth-base: &allianceauth-base
|
||||
|
||||
x-allianceauth-health-check: &allianceauth-health-checks
|
||||
healthcheck:
|
||||
test: [
|
||||
"CMD",
|
||||
"/memory_check.sh",
|
||||
"500000000"
|
||||
]
|
||||
test: ["CMD", "/memory_check.sh", "500000000"]
|
||||
interval: 60s
|
||||
timeout: 10s
|
||||
retries: 3
|
||||
@ -89,47 +85,25 @@ services:
|
||||
max-file: "5"
|
||||
|
||||
allianceauth_gunicorn:
|
||||
ports:
|
||||
- 8000:8000
|
||||
container_name: allianceauth_gunicorn
|
||||
<<: [*allianceauth-base]
|
||||
entrypoint: [
|
||||
"gunicorn",
|
||||
"myauth.wsgi",
|
||||
"--bind=0.0.0.0:8000",
|
||||
"--workers=3",
|
||||
"--timeout=120",
|
||||
"--max-requests=500",
|
||||
"--max-requests-jitter=50"
|
||||
]
|
||||
entrypoint: ["gunicorn", "myauth.wsgi", "--bind=0.0.0.0:8000", "--workers=3", "--timeout=120", "--max-requests=500", "--max-requests-jitter=50"]
|
||||
ports:
|
||||
- 8000:8000
|
||||
|
||||
allianceauth_beat:
|
||||
container_name: allianceauth_worker_beat
|
||||
<<: [*allianceauth-base]
|
||||
entrypoint: [
|
||||
"celery",
|
||||
"-A",
|
||||
"myauth",
|
||||
"beat"
|
||||
]
|
||||
entrypoint: ["celery", "-A", "myauth", "beat"]
|
||||
|
||||
allianceauth_worker:
|
||||
<<: [*allianceauth-base, *allianceauth-health-checks]
|
||||
entrypoint: [
|
||||
"celery",
|
||||
"-A",
|
||||
"myauth",
|
||||
"worker",
|
||||
"--pool=threads",
|
||||
"--concurrency=5",
|
||||
"-n",
|
||||
"worker_%n"
|
||||
]
|
||||
entrypoint: ["celery", "-A", "myauth", "worker", "--pool=threads", "--concurrency=5", "-n", "worker_%n"]
|
||||
deploy:
|
||||
replicas: 2
|
||||
|
||||
grafana:
|
||||
image: grafana/grafana-oss:11.2.0
|
||||
image: grafana/grafana-oss:latest
|
||||
restart: always
|
||||
depends_on:
|
||||
- auth_mysql
|
||||
@ -156,13 +130,6 @@ services:
|
||||
- ${PROXY_HTTP_PORT:-80}:80
|
||||
- ${PROXY_DASH_PORT:-81}:81
|
||||
- ${PROXY_HTTPS_PORT:-443}:443
|
||||
# Uncomment this section to use a dedicated database for Nginx Proxy Manager
|
||||
# environment:
|
||||
# DB_MYSQL_HOST: "proxy-db"
|
||||
# DB_MYSQL_PORT: 3306
|
||||
# DB_MYSQL_USER: "npm"
|
||||
# DB_MYSQL_PASSWORD: "${PROXY_MYSQL_PASS?err}"
|
||||
# DB_MYSQL_NAME: "npm"
|
||||
volumes:
|
||||
- proxy-data:/data
|
||||
- proxy-le:/etc/letsencrypt
|
||||
@ -174,25 +141,6 @@ services:
|
||||
max-size: "10Mb"
|
||||
max-file: "5"
|
||||
|
||||
# Uncomment this section to use a dedicated database for Nginx Proxy Manager
|
||||
# proxy-db:
|
||||
# image: 'jc21/mariadb-aria:latest'
|
||||
# restart: always
|
||||
# environment:
|
||||
# MYSQL_ROOT_PASSWORD: "${PROXY_MYSQL_PASS_ROOT?err}"
|
||||
# MYSQL_DATABASE: 'npm'
|
||||
# MYSQL_USER: 'npm'
|
||||
# MYSQL_PASSWORD: "${PROXY_MYSQL_PASS?err}"
|
||||
# ports:
|
||||
# - 3306
|
||||
# volumes:
|
||||
# - proxy-db:/var/lib/mysql
|
||||
# logging:
|
||||
# driver: "json-file"
|
||||
# options:
|
||||
# max-size: "1Mb"
|
||||
# max-file: "5"
|
||||
|
||||
volumes:
|
||||
redis-data:
|
||||
static-volume:
|
||||
|
@ -1,7 +1,7 @@
|
||||
[build-system]
|
||||
build-backend = "flit_core.buildapi"
|
||||
requires = [
|
||||
"flit-core<4,>=3.2",
|
||||
"flit-core>=3.2,<4",
|
||||
]
|
||||
|
||||
[project]
|
||||
@ -29,6 +29,7 @@ classifiers = [
|
||||
"Programming Language :: Python :: 3.10",
|
||||
"Programming Language :: Python :: 3.11",
|
||||
"Programming Language :: Python :: 3.12",
|
||||
"Programming Language :: Python :: 3.13",
|
||||
"Topic :: Internet :: WWW/HTTP",
|
||||
"Topic :: Internet :: WWW/HTTP :: Dynamic Content",
|
||||
]
|
||||
@ -39,15 +40,15 @@ dynamic = [
|
||||
dependencies = [
|
||||
"bcrypt",
|
||||
"beautifulsoup4",
|
||||
"celery<6,>=5.4",
|
||||
"celery>=5.4,<6",
|
||||
"celery-once>=3.0.1",
|
||||
"django<5.2,>=5.1",
|
||||
"django>=5.1,<5.2",
|
||||
"django-bootstrap-form",
|
||||
"django-bootstrap5>=23.3",
|
||||
"django-celery-beat>=2.7",
|
||||
"django-esi>=5",
|
||||
"django-redis>=5.4",
|
||||
"django-registration<4,>=3.3",
|
||||
"django-registration>=5.1,<6",
|
||||
"django-solo",
|
||||
"django-sortedm2m",
|
||||
"dnspython",
|
||||
@ -67,7 +68,7 @@ optional-dependencies.docs = [
|
||||
"myst-parser>=4",
|
||||
"sphinx>=8",
|
||||
"sphinx-copybutton",
|
||||
"sphinx-rtd-theme<4,>=3.0.0rc1",
|
||||
"sphinx-rtd-theme>=3,<4",
|
||||
"sphinx-tabs",
|
||||
"sphinxcontrib-django",
|
||||
]
|
||||
|
Loading…
x
Reference in New Issue
Block a user