Compare commits

...

119 Commits

Author SHA1 Message Date
Ariel Rin
6b932b1188 Version Bump 3.4.0 2023-04-25 20:57:26 +10:00
Ariel Rin
f62153c746 Bump grafana minor for new installs 2023-04-25 20:38:48 +10:00
Ariel Rin
88216c3f81 Merge branch 'improve-dependency-bounds' into 'master'
Reduce upper bound version constraints

See merge request allianceauth/allianceauth!1498
2023-04-25 10:07:06 +00:00
Erik Kalkoken
dc983c31e3 Reduce upper bound version constraints 2023-04-25 10:07:06 +00:00
Ariel Rin
4204c44bde Merge branch 'transifex' into 'master'
Update from Transifex

See merge request allianceauth/allianceauth!1497
2023-04-25 10:05:38 +00:00
Ariel Rin
8da0122d17 Update from Transifex 2023-04-25 10:05:38 +00:00
Ariel Rin
c9fcf6e6bf Merge branch 'dev-team-update' into 'master'
[Change] Dev Team updated in readme

See merge request allianceauth/allianceauth!1499
2023-04-25 10:05:23 +00:00
Peter Pfeufer
36866cc59b [ADDED] snipere4agle1 to the list of active developers 2023-04-24 09:56:40 +02:00
Peter Pfeufer
298bdd98ed [Change] Dev Team updated in readme 2023-04-24 09:50:47 +02:00
Ariel Rin
819018748d Merge branch 'fix-dev-docs-mysql' into 'master'
Fix mysql Django config for developers

See merge request allianceauth/allianceauth!1483
2023-04-12 03:40:50 +00:00
Erik Kalkoken
32e8e0fdd0 Fix mysql Django config for developers 2023-04-12 03:40:50 +00:00
Ariel Rin
7625060a12 Merge branch 'improve-installation-docs' into 'master'
Improve installation guide database section for Ubuntu

See merge request allianceauth/allianceauth!1494
2023-04-12 01:52:54 +00:00
Erik Kalkoken
672cb13bfe Improve installation guide database section for Ubuntu 2023-04-12 01:52:54 +00:00
Ariel Rin
7170f75b89 Merge branch 'add-docs-copy-button' into 'master'
Add copy button to  bash snippets in docs

See merge request allianceauth/allianceauth!1493
2023-04-12 01:47:43 +00:00
Erik Kalkoken
8f60c7a00a Add copy button to bash snippets in docs 2023-04-12 01:47:43 +00:00
Ariel Rin
34ae6e402c Merge branch 'tsTests' into 'master'
Fix TS Tests when testing against a real MySQL backend

See merge request allianceauth/allianceauth!1495
2023-04-12 01:42:48 +00:00
Aaron Kable
0905e48994 Merge remote-tracking branch 'origin/master' into tsTests 2023-04-10 19:49:33 +08:00
Aaron Kable
02fcf7d500 fix TS Tests with mySql 2023-04-10 19:45:28 +08:00
Ariel Rin
8d8da50946 Merge branch '1481-alt' into 'master'
!1481 - Alternate

See merge request allianceauth/allianceauth!1489
2023-04-04 01:47:27 +00:00
Ariel Rin
c1499d173f !1481 - Alternate 2023-04-04 01:47:26 +00:00
Ariel Rin
b149baa4e5 Merge branch 'combine-imports' into 'master'
Combining imports

See merge request allianceauth/allianceauth!1478
2023-02-13 03:21:24 +00:00
Ariel Rin
4807c69b5e Merge branch 'isort' into 'master'
Standardise isort

See merge request allianceauth/allianceauth!1485
2023-02-13 03:11:32 +00:00
Ariel Rin
ebefa0e307 Standardise isort 2023-02-13 03:11:32 +00:00
Ariel Rin
468e7433f9 Merge branch 'py3.11' into 'master'
Add Python 3.11 Support

See merge request allianceauth/allianceauth!1487
2023-02-13 03:06:03 +00:00
Ariel Rin
3ca313f907 Add Python 3.11 Support 2023-02-13 03:06:03 +00:00
Ariel Rin
820065fc04 Merge branch 'update-install-docu' into 'master'
Improve installation guide

See merge request allianceauth/allianceauth!1488
2023-02-13 03:05:41 +00:00
Erik Kalkoken
3eddeefe28 Improve installation guide 2023-02-13 03:05:41 +00:00
Ariel Rin
82d7d7e3bf Merge branch 'arielcode' into 'master'
Extra < in bundle

See merge request allianceauth/allianceauth!1486
2023-02-02 03:27:34 +00:00
Ariel Rin
93194b4f2d pesky < 2023-01-25 16:17:29 +10:00
Ariel Rin
fa335253d3 Merge branch 'pypy' into 'master'
Add pypy testing

See merge request allianceauth/allianceauth!1474
2023-01-25 05:00:16 +00:00
Ariel Rin
d1af9416b3 Add pypy testing 2023-01-25 05:00:16 +00:00
Ariel Rin
f4ac2ea400 Merge branch 'faster-commands' into 'master'
Faster management commands

See merge request allianceauth/allianceauth!1484
2023-01-25 03:25:47 +00:00
Erik Kalkoken
31c1f8bb7d Faster management commands 2023-01-25 03:25:47 +00:00
Ariel Rin
57f7178f1e Merge branch 'docker_docs' into 'master'
Update Docker Docs and fix custom.dockerfile

See merge request allianceauth/allianceauth!1477
2022-12-31 09:37:54 +00:00
Ariel Rin
17d4a4c415 Merge branch 'change-packaging-dependency' into 'master'
Don't limit `packaging` to versions below 22.0

See merge request allianceauth/allianceauth!1479
2022-12-20 10:01:50 +00:00
Peter Pfeufer
18ce433fa0 Don't limit packaging to versions below 22.0 2022-12-20 10:01:50 +00:00
Ariel Rin
1eadb1d934 Merge branch 'fix-tox-4-issue' into 'master'
Adopt docs section to work with tox 4

See merge request allianceauth/allianceauth!1480
2022-12-20 08:38:59 +00:00
Erik Kalkoken
59a8f8a967 Adopt docs section to work with tox 4 2022-12-20 08:38:59 +00:00
Peter Pfeufer
2dc07b5519 Combining imports 2022-12-09 23:48:17 +01:00
Aaron Kable
3454520dfe update docker docs and fix custom.dockerfile 2022-11-24 21:56:33 +08:00
Ariel Rin
7a195d4158 Merge branch 'docs' into 'master'
Tuning Docs - Redis Compression

See merge request allianceauth/allianceauth!1475
2022-11-03 10:33:25 +00:00
Ariel Rin
b73072dec0 Tuning Docs - Redis Compression 2022-11-03 10:33:24 +00:00
Ariel Rin
1ca5e38bd9 Merge branch 'fix-docker-tag' into 'master'
fix missing v in tag

See merge request allianceauth/allianceauth!1476
2022-11-03 10:32:29 +00:00
Matteo Ghia
ecb737c6a5 fix missing v in tag 2022-11-01 13:45:44 +01:00
Ariel Rin
7063f53cdf Merge branch 'coverage' into 'master'
Adding Coverage % to MRs

See merge request allianceauth/allianceauth!1473
2022-10-25 10:10:33 +00:00
Ariel Rin
017424b9d4 Adding Coverage % to MRs 2022-10-25 10:10:33 +00:00
Ariel Rin
f6c26cf2ec Merge branch 'py3.11' into 'master'
Python 3.11 Stable Tests

See merge request allianceauth/allianceauth!1471
2022-10-25 02:51:12 +00:00
Ariel Rin
9a422bd4ca Python 3.11 Stable Tests 2022-10-25 02:51:12 +00:00
Ariel Rin
47fec23f2e cap django for docs 2022-10-23 16:42:16 +10:00
Ariel Rin
399ef1917d Version Bump 3.3.0 2022-10-14 21:46:28 +10:00
Ariel Rin
9db443ba54 Merge branch 'tokens-and-alts' into 'master'
CCP SSO Issues, Mitigations

See merge request allianceauth/allianceauth!1472
2022-10-14 11:44:18 +00:00
Ariel Rin
0f2f5ea0ba nowrap to stop buttons moving around 2022-10-14 20:21:07 +10:00
Ariel Rin
1f781c5037 datatables statesave 2022-10-12 20:52:59 +10:00
Ariel Rin
36dedfcbd2 add disclaimer 2022-10-12 20:51:36 +10:00
Ariel Rin
13a05606fb Scopes Typo 2022-10-12 20:29:42 +10:00
Ariel Rin
90ad7790e1 rename revoke to delete to be clearer 2022-10-12 20:22:20 +10:00
Ariel Rin
6b8341ab5a Add FA icon to user dropdown 2022-10-12 20:21:27 +10:00
Ariel Rin
d15f42b3fd Merge branch 'tokens-and-alts' of https://gitlab.com/aaronkable/allianceauth into tokens-and-alts 2022-10-12 20:07:49 +10:00
Aaron Kable
cc60b26f5a add token management link to user dropdown 2022-10-12 17:57:12 +08:00
Aaron Kable
36ff0af993 Add token management and restrict logins to mains only 2022-10-12 17:50:41 +08:00
Aaron Kable
f17c94a9e1 Add token management and restrict logins to mains only 2022-10-12 17:49:28 +08:00
Ariel Rin
7e3ba476f3 Merge branch 'docs' into 'master'
Discord Credential Clarification

See merge request allianceauth/allianceauth!1470
2022-10-12 08:07:02 +00:00
Ariel Rin
dd1313a2a9 Merge branch 'remove-unnecessary-lambda-statement' into 'master'
[REMOVED] Unnecessary `lambda` statement

See merge request allianceauth/allianceauth!1465
2022-10-09 08:17:46 +00:00
Ariel Rin
763003bd7d Clarify new discord developers layout 2022-10-09 17:41:41 +10:00
Ariel Rin
f3217443dd Merge branch 'remove-celery-backend-from-docker' into 'master'
[REMOVED] Celery backend from docker config

See merge request allianceauth/allianceauth!1466
2022-10-09 07:16:04 +00:00
Ariel Rin
a713ae1914 Merge branch 'fix-default-perms-for-static-files' into 'master'
[FIX] Default permissions for static files

See merge request allianceauth/allianceauth!1469
2022-10-09 06:15:18 +00:00
Peter Pfeufer
5815bac0df [FIX] Default permissions for static files
A little fallacy on my end in the docs.

655 is enough for files in those directories, but the directories themselves need to be traversal, so 755 for the directories ...
2022-09-22 19:54:58 +02:00
Ariel Rin
6154d2c2e7 Merge branch 'better-exclude-regex' into 'master'
[CHANGE] Better regex for exclusion in pre-commit

See merge request allianceauth/allianceauth!1468
2022-09-18 08:26:22 +00:00
Peter Pfeufer
b34661b35d [CHANGE] Better regex for exclusion in pre-commit 2022-09-18 08:26:22 +00:00
Ariel Rin
a9a7e03b80 Merge branch 'capntack-master-patch-07678' into 'master'
Update switch_to_non_root.md

See merge request allianceauth/allianceauth!1467
2022-09-16 14:48:08 +00:00
Tack
23c797ef64 Update switch_to_non_root.md
chmod requires "-R" to be Recursive, not "-r"
2022-09-14 16:51:10 +00:00
Ariel Rin
da102618a0 Version Bump 3.2.0 2022-09-14 23:26:02 +10:00
Ariel Rin
51ee281b14 Update from Transifex 2022-09-14 23:20:08 +10:00
Peter Pfeufer
9133232c20 [REMOVED] Celery backend from docker config 2022-09-14 13:06:30 +02:00
Peter Pfeufer
9cbabee126 [CHANGE] Language names always start with a capital letter 2022-09-13 21:00:31 +02:00
Peter Pfeufer
4026523a2e [REMOVED] Unnecessary lambda statement
The `lambda` statement in `base.py` is unnecessary and has no effect.

```py
ugettext = lambda s: s
LANGUAGES = (
    ("en", ugettext("English")),
    ("de", ugettext("German")),
    ("es", ugettext("Spanish")),
    ("zh-hans", ugettext("Chinese Simplified")),
    ("ru", ugettext("Russian")),
    ("ko", ugettext("Korean")),
    ("fr", ugettext("French")),
    ("ja", ugettext("Japanese")),
    ("it", ugettext("Italian")),
)
```

In this case `ugettext = lambda s: s` is pretty much the same as:
```py
def ugettext(s):
    return s
```
And would simply return the string the function receives as parameter.

So we can omit this completely and simplify the `LANGUAGES` list to:

```py
LANGUAGES = (
    ("en", "English"),
    ("de", "German"),
    ("es", "Spanish"),
    ("zh-hans", "Chinese Simplified"),
    ("ru", "Russian"),
    ("ko", "Korean"),
    ("fr", "French"),
    ("ja", "Japanese"),
    ("it", "Italian"),
)
```
2022-09-13 20:59:14 +02:00
Ariel Rin
7fbf96623b Update from Transifex 2022-09-12 11:41:08 +10:00
Ariel Rin
273bda173e Merge branch '1088-qol-improve-name-handling-for-smf' into 'master'
Displayed names for SMF

Closes #1088

See merge request allianceauth/allianceauth!1459
2022-09-11 13:53:25 +00:00
Ariel Rin
7bd5838ea1 Merge branch 'master' into 'master'
minor fixes to dev environment setup

See merge request allianceauth/allianceauth!1458
2022-09-11 13:51:42 +00:00
Ariel Rin
b232d9ab17 Merge branch 'use-SITE_URL-in-templates' into 'master'
[ADDED] `SITE_URL` usage in templates

See merge request allianceauth/allianceauth!1456
2022-09-11 13:51:21 +00:00
Ariel Rin
a11b870664 Merge branch 'switch-to-non-root' into 'master'
Add docs for switching to a non-root installation

See merge request allianceauth/allianceauth!1463
2022-09-11 13:48:44 +00:00
Erik Kalkoken
a27aae5d1c Add docs for switching to a non-root installation 2022-09-11 13:48:43 +00:00
Ariel Rin
117ef63d90 Merge branch 'trailing-slash-it' into 'master'
[ADDED] Missing trailing slashes to URLs

See merge request allianceauth/allianceauth!1457
2022-09-11 13:45:50 +00:00
Ariel Rin
1bde3d5672 Merge branch 'esi-related-links-on-login' into 'master'
[ADDED] ESI related links in login box

See merge request allianceauth/allianceauth!1455
2022-09-11 13:44:55 +00:00
Ariel Rin
d2355b1ec8 Merge branch 'none-is-not-an-alliance' into 'master'
[CHANGE] None is not an alliance name, so don't show `None`

See merge request allianceauth/allianceauth!1460
2022-09-11 13:44:34 +00:00
Ariel Rin
191d474a8e Merge branch 'task-queue-top-margin-fix' into 'master'
[FIX] Top margin on celery task percentage bar

See merge request allianceauth/allianceauth!1461
2022-09-11 13:44:11 +00:00
Peter Pfeufer
ec9a9733be [FIX] Top margin on celery task percentage bar 2022-09-11 13:44:11 +00:00
Ariel Rin
cf7a8cedf1 Merge branch 'dont-fight-against-bootstrap' into 'master'
[FIX] Use proper markup instead of fighting against Bootstrap

See merge request allianceauth/allianceauth!1462
2022-09-11 13:43:38 +00:00
Peter Pfeufer
18cbb994d5 [FIX] Use proper markup instead of fighting against Bootstrap 2022-09-08 11:22:40 +02:00
Peter Pfeufer
663388a0c2 [CHANGE] None is not an alliance name, so don't show None 2022-09-08 00:19:41 +02:00
Peter Pfeufer
7a943591ec [ADDED] Migration to update existing user's displayed names 2022-09-07 23:01:38 +02:00
Peter Pfeufer
cd189927fe [ADDED] Update displayed name when main is changed 2022-09-07 23:01:07 +02:00
Peter Pfeufer
8772349309 [ADDED] Main character name as displayed name on SMF service activation 2022-09-07 21:14:18 +02:00
Arc Tiru
cf20100cb5 minor fixes to dev environment setup 2022-09-07 11:00:38 -07:00
Peter Pfeufer
9b9c2ddc04 [ADDED] SITE_URLto test settings 2022-09-07 15:31:22 +02:00
Peter Pfeufer
34839e8344 [ADDED] Trailing slahes to URLs
URLs in AA usually use a trailing slash, so this was added to the ones that were missing it.
2022-09-07 15:18:06 +02:00
Peter Pfeufer
89ef4f4cbc [ADDED] SITE_URL usage in templates
Instead of {{ request.scheme }}://{{request.get_host}}`
2022-09-07 15:04:25 +02:00
Peter Pfeufer
2cc7f46aae [ADDED] ESI related links in login box 2022-09-07 14:45:04 +02:00
Ariel Rin
8d255fb720 Merge branch '834-check-if-character-is-online' into 'master'
[FIX] Check if character is online before accepting FAT click

Closes #834

See merge request allianceauth/allianceauth!1451
2022-09-07 06:29:19 +00:00
Ariel Rin
67cf68ad87 Merge branch 'no_unique_names' into 'master'
Corp and Alliance names are not unique

Closes #1317

See merge request allianceauth/allianceauth!1452
2022-09-07 06:28:01 +00:00
colcrunch
db1971d4c2 Corp and Alliance names are not unique 2022-09-07 06:28:01 +00:00
Ariel Rin
63c1521cba Merge branch 'add-missing-doctype' into 'master'
[FIX] Missing DOCTYPE and padding

See merge request allianceauth/allianceauth!1449
2022-09-07 06:25:45 +00:00
Ariel Rin
ba7ef11505 Merge branch 'fix-deprecated-translation-tags' into 'master'
[FIX] Deprecated `{% blocktrans %}` tags to `{% blocktranslate %}`

See merge request allianceauth/allianceauth!1454
2022-09-07 06:22:55 +00:00
Ariel Rin
d2e494b9be Merge branch 'modernize-css' into 'master'
CSS modernized

See merge request allianceauth/allianceauth!1448
2022-09-07 06:21:15 +00:00
Ariel Rin
98bab0b180 Merge branch 'bundle-all-the-things' into 'master'
Bundle the remaining static files

See merge request allianceauth/allianceauth!1447
2022-09-07 06:20:41 +00:00
Ariel Rin
c4efb2a11f Merge branch 'aa3-docker-fixes' into 'master'
[CHANGE] Docker updates for AA3

Closes #1352

See merge request allianceauth/allianceauth!1453
2022-09-07 06:19:47 +00:00
Ariel Rin
94e4895f29 Merge branch 'clarify-url-format' into 'master'
[MISC] Clarify URL format

See merge request allianceauth/allianceauth!1450
2022-09-07 06:18:43 +00:00
Peter Pfeufer
70eb1b5b50 [CHANGE] Deprecated {% blocktrans %} tags to {% blocktranslate %} 2022-09-06 23:48:36 +02:00
Peter Pfeufer
e247a94db3 [CHANGE] Updates for AA3
- SITE_URL introduced
- Redis cache fixed (#1352)
- Using the same type of quotes, not wildly mixing them
2022-09-06 22:50:49 +02:00
Peter Pfeufer
714431c932 [FIX] Check if character is online before accepting FAT click
Fixes #834
2022-08-07 12:08:57 +02:00
Peter Pfeufer
b026277ab0 [MISC] Clarify URL format
Seems his is causing confusion, so add a note that the URL should be without a trailing slash
2022-08-07 02:01:26 +02:00
Peter Pfeufer
11855f0b54 [FIX] Missing DOCTYPE and padding 2022-08-05 19:51:50 +02:00
Ariel Rin
635fbfe2c8 Version Bump v3.1.1 2022-08-05 21:35:51 +10:00
Ariel Rin
b10233daf0 Merge branch 'transifex' of https://gitlab.com/allianceauth/allianceauth 2022-08-05 21:23:58 +10:00
Ariel Rin
1aa3187491 Cap Django to 4.0.x 2022-08-05 21:23:40 +10:00
Ariel Rin
59f17a88f0 Update from Transifex 2022-08-05 21:20:32 +10:00
Peter Pfeufer
75db3195d4 CSS modernized 2022-08-02 23:56:47 +02:00
Peter Pfeufer
afe3fea757 Bundle the remaining static files
They are used in some template overrides. To prevent missing JS or CSS in the future in those template overrides, it's a good idea to provide HTML templates for these static files.
2022-08-01 14:15:55 +02:00
Ariel Rin
74651dd30a Update from Transifex 2022-07-30 18:21:20 +10:00
103 changed files with 9581 additions and 6100 deletions

4
.gitignore vendored
View File

@@ -69,11 +69,7 @@ celerybeat-schedule
#gitlab configs
.gitlab/
#transifex
.tx/
#other
.flake8
.pylintrc
Makefile
.isort.cfg

View File

@@ -89,7 +89,7 @@ test-3.10-core:
test-3.11-core:
<<: *only-default
image: python:3.11-rc-bullseye
image: python:3.11-bullseye
script:
- tox -e py311-core
artifacts:
@@ -98,6 +98,18 @@ test-3.11-core:
coverage_report:
coverage_format: cobertura
path: coverage.xml
test-pvpy-core:
<<: *only-default
image: pypy:3.9-bullseye
script:
- tox -e pypy-all
artifacts:
when: always
reports:
coverage_report:
coverage_format: cobertura
path: coverage.xml
allow_failure: true
test-3.8-all:
@@ -138,7 +150,7 @@ test-3.10-all:
test-3.11-all:
<<: *only-default
image: python:3.11-rc-bullseye
image: python:3.11-bullseye
script:
- tox -e py311-all
artifacts:
@@ -147,6 +159,19 @@ test-3.11-all:
coverage_report:
coverage_format: cobertura
path: coverage.xml
coverage: '/(?i)total.*? (100(?:\.0+)?\%|[1-9]?\d(?:\.\d+)?\%)$/'
test-pvpy-all:
<<: *only-default
image: pypy:3.9-bullseye
script:
- tox -e pypy-all
artifacts:
when: always
reports:
coverage_report:
coverage_format: cobertura
path: coverage.xml
allow_failure: true
build-test:

6
.isort.cfg Normal file
View File

@@ -0,0 +1,6 @@
[settings]
profile=django
sections=FUTURE,STDLIB,THIRDPARTY,DJANGO,ESI,FIRSTPARTY,LOCALFOLDER
known_esi=esi
known_django=django
skip_gitignore=true

View File

@@ -5,7 +5,7 @@
repos:
- repo: https://github.com/pre-commit/pre-commit-hooks
rev: v4.3.0
rev: v4.4.0
hooks:
- id: check-case-conflict
- id: check-json
@@ -13,27 +13,49 @@ repos:
- id: check-yaml
- id: fix-byte-order-marker
- id: trailing-whitespace
exclude: (\.min\.css|\.min\.js|\.mo|\.po|swagger\.json)$
exclude: |
(?x)(
\.min\.css|
\.min\.js|
\.po|
\.mo|
swagger\.json
)
- id: end-of-file-fixer
exclude: (\.min\.css|\.min\.js|\.mo|\.po|swagger\.json)$
exclude: |
(?x)(
\.min\.css|
\.min\.js|
\.po|
\.mo|
swagger\.json
)
- id: mixed-line-ending
args: [ '--fix=lf' ]
- id: fix-encoding-pragma
args: [ '--remove' ]
- repo: https://github.com/editorconfig-checker/editorconfig-checker.python
rev: 2.4.0
rev: 2.7.1
hooks:
- id: editorconfig-checker
exclude: ^(LICENSE|allianceauth\/static\/allianceauth\/css\/themes\/bootstrap-locals.less|allianceauth\/eveonline\/swagger.json|(.*.po)|(.*.mo))
exclude: |
(?x)(
LICENSE|
allianceauth\/static\/allianceauth\/css\/themes\/bootstrap-locals.less|
\.po|
\.mo|
swagger\.json
)
- repo: https://github.com/asottile/pyupgrade
rev: v2.34.0
rev: v3.3.1
hooks:
- id: pyupgrade
args: [ --py38-plus ]
- repo: https://github.com/asottile/setup-cfg-fmt
rev: v1.20.1
rev: v2.2.0
hooks:
- id: setup-cfg-fmt
args: [ --include-version-classifiers ]

10
.tx/config Normal file
View File

@@ -0,0 +1,10 @@
[main]
host = https://www.transifex.com
lang_map = zh-Hans: zh_Hans
[o:alliance-auth:p:alliance-auth:r:django-po]
file_filter = allianceauth/locale/<lang>/LC_MESSAGES/django.po
source_file = allianceauth/locale/en/LC_MESSAGES/django.po
source_lang = en
type = PO
minimum_perc = 0

10
.tx/config_20230406134150.bak Executable file
View File

@@ -0,0 +1,10 @@
[main]
host = https://www.transifex.com
lang_map = zh-Hans:zh_Hans
[alliance-auth.django-po]
file_filter = allianceauth/locale/<lang>/LC_MESSAGES/django.po
minimum_perc = 0
source_file = allianceauth/locale/en/LC_MESSAGES/django.po
source_lang = en
type = PO

View File

@@ -36,7 +36,7 @@ Main features:
- Can be easily extended with additional services and apps. Many are provided by the community and can be found here: [Community Creations](https://gitlab.com/allianceauth/community-creations)
- English :flag_gb:, Chinese :flag_cn:, German :flag_de:, Spanish :flag_es:, Korean :flag_kr: and Russian :flag_ru: localization
- English :flag_gb:, Chinese :flag_cn:, German :flag_de:, Spanish :flag_es:, Korean :flag_kr:, Russian :flag_ru:, Italian :flag_it:, French :flag_fr:, Japanese :flag_jp: and Ukrainian :flag_ua: Localization
For further details about AA - including an installation guide and a full list of included services and plugin apps - please see the [official documentation](http://allianceauth.rtfd.io).
@@ -56,13 +56,15 @@ Here is an example of the Alliance Auth web site with some plug-ins apps and ser
- [Aaron Kable](https://gitlab.com/aaronkable/)
- [Ariel Rin](https://gitlab.com/soratidus999/)
- [Basraah](https://gitlab.com/basraah/)
- [Col Crunch](https://gitlab.com/colcrunch/)
- [Erik Kalkoken](https://gitlab.com/ErikKalkoken/)
- [Rounon Dax](https://gitlab.com/ppfeufer)
- [snipereagle1](https://gitlab.com/mckernanin)
### Former Developers
- [Adarnof](https://gitlab.com/adarnof/)
- [Basraah](https://gitlab.com/basraah/)
### Beta Testers / Bug Fixers

View File

@@ -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__ = '3.1.0'
__version__ = '3.4.0'
__title__ = 'Alliance Auth'
__url__ = 'https://gitlab.com/allianceauth/allianceauth'
NAME = f'{__title__} v{__version__}'

View File

@@ -8,13 +8,13 @@ from uuid import uuid4
class AnalyticsIdentifier(models.Model):
identifier = models.UUIDField(default=uuid4,
editable=False)
editable=False)
def save(self, *args, **kwargs):
if not self.pk and AnalyticsIdentifier.objects.exists():
# Force a single object
raise ValidationError('There is can be only one \
AnalyticsIdentifier instance')
AnalyticsIdentifier instance')
self.pk = self.id = 1 # If this happens to be deleted and recreated, force it to be 1
return super().save(*args, **kwargs)

View File

@@ -2,6 +2,7 @@ import logging
from django.contrib.auth.backends import ModelBackend
from django.contrib.auth.models import User, Permission
from django.contrib import messages
from .models import UserProfile, CharacterOwnership, OwnershipRecord
@@ -37,7 +38,13 @@ class StateBackend(ModelBackend):
ownership = CharacterOwnership.objects.get(character__character_id=token.character_id)
if ownership.owner_hash == token.character_owner_hash:
logger.debug(f'Authenticating {ownership.user} by ownership of character {token.character_name}')
return ownership.user
if ownership.user.profile.main_character:
if ownership.user.profile.main_character.character_id == token.character_id:
return ownership.user
else: ## this is an alt, enforce main only.
if request:
messages.error("Unable to authenticate with this Character, Please log in with the main character associated with this account.")
return None
else:
logger.debug(f'{token.character_name} has changed ownership. Creating new user account.')
ownership.delete()
@@ -57,13 +64,20 @@ class StateBackend(ModelBackend):
if records.exists():
# we've seen this character owner before. Re-attach to their old user account
user = records[0].user
if user.profile.main_character:
if ownership.user.profile.main_character.character_id != token.character_id:
## this is an alt, enforce main only due to trust issues in SSO.
if request:
messages.error("Unable to authenticate with this Character, Please log in with the main character associated with this account. Then add this character from the dashboard.")
return None
token.user = user
co = CharacterOwnership.objects.create_by_token(token)
logger.debug(f'Authenticating {user} by matching owner hash record of character {co.character}')
if not user.profile.main_character:
# set this as their main by default if they have none
user.profile.main_character = co.character
user.profile.save()
# set this as their main by default as they have none
user.profile.main_character = co.character
user.profile.save()
return user
logger.debug(f'Unable to authenticate character {token.character_name}. Creating new user.')
return self.create_user(token)

View File

@@ -18,13 +18,13 @@ class State(models.Model):
priority = models.IntegerField(unique=True, help_text="Users get assigned the state with the highest priority available to them.")
member_characters = models.ManyToManyField(EveCharacter, blank=True,
help_text="Characters to which this state is available.")
help_text="Characters to which this state is available.")
member_corporations = models.ManyToManyField(EveCorporationInfo, blank=True,
help_text="Corporations to whose members this state is available.")
help_text="Corporations to whose members this state is available.")
member_alliances = models.ManyToManyField(EveAllianceInfo, blank=True,
help_text="Alliances to whose members this state is available.")
help_text="Alliances to whose members this state is available.")
member_factions = models.ManyToManyField(EveFactionInfo, blank=True,
help_text="Factions to whose members this state is available.")
help_text="Factions to whose members this state is available.")
public = models.BooleanField(default=False, help_text="Make this state available to any character.")
objects = StateManager()

View File

@@ -6,24 +6,26 @@ CSS for allianceauth admin site
.img-circle {
border-radius: 50%;
}
.column-user_profile_pic {
width: 1px;
white-space: nowrap;
width: 1px;
}
/* tooltip */
.tooltip {
position: relative ;
position: relative;
}
.tooltip:hover::after {
content: attr(data-tooltip) ;
position: absolute ;
top: 1.1em ;
left: 1em ;
min-width: 200px ;
border: 1px #808080 solid ;
padding: 8px ;
color: black ;
background-color: rgb(255, 255, 204) ;
z-index: 1 ;
background-color: rgb(255 255 204);
border: 1px rgb(128 128 128) solid;
color: rgb(0 0 0);
content: attr(data-tooltip);
left: 1em;
min-width: 200px;
padding: 8px;
position: absolute;
top: 1.1em;
z-index: 1;
}

View File

@@ -14,9 +14,9 @@
<div class="panel panel-primary" style="height:100%">
<div class="panel-heading">
<h3 class="panel-title">
{% blocktrans with state=request.user.profile.state %}
{% blocktranslate with state=request.user.profile.state %}
Main Character (State: {{ state }})
{% endblocktrans %}
{% endblocktranslate %}
</h3>
</div>
<div class="panel-body">
@@ -103,13 +103,17 @@
{% endif %}
<div class="clearfix"></div>
<div class="row">
<div class="col-sm-6 button-wrapper">
<a href="{% url 'authentication:add_character' %}" class="btn btn-block btn-info"
title="Add Character">{% translate 'Add Character' %}</a>
<div class="col-sm-6">
<p>
<a href="{% url 'authentication:add_character' %}" class="btn btn-block btn-info"
title="Add Character">{% translate 'Add Character' %}</a>
</p>
</div>
<div class="col-sm-6 button-wrapper">
<a href="{% url 'authentication:change_main_character' %}" class="btn btn-block btn-info"
title="Change Main Character">{% translate "Change Main" %}</a>
<div class="col-sm-6">
<p>
<a href="{% url 'authentication:change_main_character' %}" class="btn btn-block btn-info"
title="Change Main Character">{% translate "Change Main" %}</a>
</p>
</div>
</div>
</div>
@@ -159,7 +163,7 @@
</td>
<td class="text-center">{{ char.character_name }}</td>
<td class="text-center">{{ char.corporation_name }}</td>
<td class="text-center">{{ char.alliance_name }}</td>
<td class="text-center">{{ char.alliance_name|default:"" }}</td>
</tr>
{% endfor %}
</tbody>

View File

@@ -0,0 +1,62 @@
{% extends "allianceauth/base.html" %}
{% load i18n %}
{% block page_title %}{% translate "Dashboard" %}{% endblock %}
{% block content %}
<h1 class="page-header text-center">{% translate "Token Management" %}</h1>
<div class="col-sm-12">
<table class="table table-aa" id="table_tokens" style="width:100%">
<thead>
<tr>
<th>{% translate "Scopes" %}</th>
<th class="text-right">{% translate "Actions" %}</th>
<th>{% translate "Character" %}</th>
</tr>
</thead>
<tbody>
{% for t in tokens %}
<tr>
<td styl="white-space:initial;">{% for s in t.scopes.all %}<span class="label label-default">{{s.name}}</span> {% endfor %}</td>
<td nowrap class="text-right"><a href="{% url 'authentication:token_delete' t.id %}" class="btn btn-danger"><i class="fas fa-trash"></i></a> <a href="{% url 'authentication:token_refresh' t.id %}" class="btn btn-success"><i class="fas fa-sync-alt"></i></a></td>
<td>{{t.character_name}}</td>
</tr>
{% endfor %}
</tbody>
</table>
{% translate "This page is a best attempt, but backups or database logs can still contain your tokens. Always revoke tokens on https://community.eveonline.com/support/third-party-applications/ where possible."|urlize %}
</div>
{% endblock %}
{% block extra_javascript %}
{% include 'bundles/datatables-js.html' %}
{% endblock %}
{% block extra_css %}
{% include 'bundles/datatables-css.html' %}
{% endblock %}
{% block extra_script %}
$(document).ready(function(){
let grp = 2;
var table = $('#table_tokens').DataTable({
"columnDefs": [{ orderable: false, targets: [0,1] },{ "visible": false, "targets": grp }],
"order": [[grp, 'asc']],
"drawCallback": function (settings) {
var api = this.api();
var rows = api.rows({ page: 'current' }).nodes();
var last = null;
api.column(grp, { page: 'current' })
.data()
.each(function (group, i) {
if (last !== group) {
$(rows).eq(i).before('<tr class="info"><td colspan="3">' + group + '</td></tr>');
last = group;
}
});
},
"stateSave": true,
});
});
{% endblock %}

View File

@@ -1,4 +1,5 @@
{% load static %}
<!DOCTYPE html>
<html lang="en">
<head>
<meta charset="utf-8">
@@ -7,7 +8,7 @@
<meta name="description" content="">
<meta name="author" content="">
<meta property="og:title" content="{{ SITE_NAME }}">
<meta property="og:image" content="{{ request.scheme }}://{{ request.get_host }}{% static 'allianceauth/icons/apple-touch-icon.png' %}">
<meta property="og:image" content="{{ SITE_URL }}{% static 'allianceauth/icons/apple-touch-icon.png' %}">
<meta property="og:description" content="Alliance Auth - An auth system for EVE Online to help in-game organizations manage online service access.">
{% include 'allianceauth/icons.html' %}
@@ -31,6 +32,7 @@
.panel-transparent {
background: rgba(48, 48, 48, 0.7);
color: #ffffff;
padding-bottom: 21px;
}
.panel-body {

View File

@@ -6,7 +6,7 @@
{% get_language_info_list for LANGUAGES as languages %}
{% for language in languages %}
<option value="{{ language.code }}"{% if language.code == LANGUAGE_CODE %} selected="selected"{% endif %}>
{{ language.name_local }} ({{ language.code }})
{{ language.name_local|capfirst }} ({{ language.code }})
</option>
{% endfor %}
</select>

View File

@@ -1,4 +1,7 @@
{% extends 'public/base.html' %}
{% load i18n %}
{% block content %}
<div class="col-md-4 col-md-offset-4">
{% if messages %}
@@ -6,6 +9,7 @@
<div class="alert alert-{{ message.level_tag}}">{{ message }}</div>
{% endfor %}
{% endif %}
<div class="panel panel-default panel-transparent">
<div class="panel-body">
<div class="col-md-12">
@@ -13,10 +17,25 @@
{% endblock %}
</div>
</div>
{% include 'public/lang_select.html' %}
<p class="text-center" style="margin-top: 2rem;">
{% translate "For information on SSO, ESI and security read the CCP Dev Blog" %}<br>
<a href="https://www.eveonline.com/article/introducing-esi" target="_blank" rel="noopener noreferrer">
{% translate "Introducing ESI - A New API For Eve Online" %}
</a>
</p>
<p class="text-center">
<a href="https://community.eveonline.com/support/third-party-applications/" target="_blank" rel="noopener noreferrer">
{% translate "Manage ESI Applications" %}
</a>
</p>
</div>
</div>
{% endblock %}
{% block extra_include %}
{% include 'bundles/bootstrap-js.html' %}
{% endblock %}

View File

@@ -116,10 +116,17 @@ class TestAuthenticate(TestCase):
user = StateBackend().authenticate(token=t)
self.assertEqual(user, self.user)
""" Alt Login disabled
def test_authenticate_alt_character(self):
t = Token(character_id=self.alt_character.character_id, character_owner_hash='2')
user = StateBackend().authenticate(token=t)
self.assertEqual(user, self.user)
"""
def test_authenticate_alt_character_fail(self):
t = Token(character_id=self.alt_character.character_id, character_owner_hash='2')
user = StateBackend().authenticate(token=t)
self.assertEqual(user, None)
def test_authenticate_unclaimed_character(self):
t = Token(character_id=self.unclaimed_character.character_id, character_name=self.unclaimed_character.character_name, character_owner_hash='3')
@@ -128,6 +135,7 @@ class TestAuthenticate(TestCase):
self.assertEqual(user.username, 'Unclaimed_Character')
self.assertEqual(user.profile.main_character, self.unclaimed_character)
""" Alt Login disabled
def test_authenticate_character_record(self):
t = Token(character_id=self.unclaimed_character.character_id, character_name=self.unclaimed_character.character_name, character_owner_hash='4')
OwnershipRecord.objects.create(user=self.old_user, character=self.unclaimed_character, owner_hash='4')
@@ -135,6 +143,15 @@ class TestAuthenticate(TestCase):
self.assertEqual(user, self.old_user)
self.assertTrue(CharacterOwnership.objects.filter(owner_hash='4', user=self.old_user).exists())
self.assertTrue(user.profile.main_character)
"""
def test_authenticate_character_record_fails(self):
t = Token(character_id=self.unclaimed_character.character_id, character_name=self.unclaimed_character.character_name, character_owner_hash='4')
OwnershipRecord.objects.create(user=self.old_user, character=self.unclaimed_character, owner_hash='4')
user = StateBackend().authenticate(token=t)
self.assertEqual(user, self.old_user)
self.assertTrue(CharacterOwnership.objects.filter(owner_hash='4', user=self.old_user).exists())
self.assertTrue(user.profile.main_character)
def test_iterate_username(self):
t = Token(character_id=self.unclaimed_character.character_id,

View File

@@ -22,5 +22,20 @@ urlpatterns = [
views.add_character,
name='add_character'
),
path(
'account/tokens/manage/',
views.token_management,
name='token_management'
),
path(
'account/tokens/delete/<int:token_id>',
views.token_delete,
name='token_delete'
),
path(
'account/tokens/refresh/<int:token_id>',
views.token_refresh,
name='token_refresh'
),
path('dashboard/', views.dashboard, name='dashboard'),
]

View File

@@ -61,6 +61,44 @@ def dashboard(request):
}
return render(request, 'authentication/dashboard.html', context)
@login_required
def token_management(request):
tokens = request.user.token_set.all()
context = {
'tokens': tokens
}
return render(request, 'authentication/tokens.html', context)
@login_required
def token_delete(request, token_id=None):
try:
token = Token.objects.get(id=token_id)
if request.user == token.user:
token.delete()
messages.success(request, "Token Deleted.")
else:
messages.error(request, "This token does not belong to you.")
except Token.DoesNotExist:
messages.warning(request, "Token does not exist")
return redirect('authentication:token_management')
@login_required
def token_refresh(request, token_id=None):
try:
token = Token.objects.get(id=token_id)
if request.user == token.user:
try:
token.refresh()
messages.success(request, "Token refreshed.")
except Exception as e:
messages.warning(request, f"Failed to refresh token. {e}")
else:
messages.error(request, "This token does not belong to you.")
except Token.DoesNotExist:
messages.warning(request, "Token does not exist")
return redirect('authentication:token_management')
@login_required
@token_required(scopes=settings.LOGIN_TOKEN_SCOPES)

View File

@@ -5,5 +5,6 @@ from .views import NightModeRedirectView
def auth_settings(request):
return {
'SITE_NAME': settings.SITE_NAME,
'SITE_URL': settings.SITE_URL,
'NIGHT_MODE': NightModeRedirectView.night_mode_state(request),
}

View File

@@ -0,0 +1,23 @@
# Generated by Django 4.0.7 on 2022-08-14 16:23
from django.db import migrations, models
class Migration(migrations.Migration):
dependencies = [
('eveonline', '0016_character_names_are_not_unique'),
]
operations = [
migrations.AlterField(
model_name='eveallianceinfo',
name='alliance_name',
field=models.CharField(max_length=254, db_index=True),
),
migrations.AlterField(
model_name='evecorporationinfo',
name='corporation_name',
field=models.CharField(max_length=254, db_index=True),
),
]

View File

@@ -71,7 +71,7 @@ class EveAllianceInfo(models.Model):
"""An alliance in Eve Online."""
alliance_id = models.PositiveIntegerField(unique=True)
alliance_name = models.CharField(max_length=254, unique=True)
alliance_name = models.CharField(max_length=254, db_index=True)
alliance_ticker = models.CharField(max_length=254)
executor_corp_id = models.PositiveIntegerField()
@@ -139,7 +139,7 @@ class EveCorporationInfo(models.Model):
"""A corporation in Eve Online."""
corporation_id = models.PositiveIntegerField(unique=True)
corporation_name = models.CharField(max_length=254, unique=True)
corporation_name = models.CharField(max_length=254, db_index=True)
corporation_ticker = models.CharField(max_length=254)
member_count = models.IntegerField()
ceo_id = models.PositiveIntegerField(blank=True, null=True, default=None)

View File

@@ -8,6 +8,7 @@ from django.conf import settings
from esi.clients import esi_client_factory
from allianceauth import __version__
from allianceauth.utils.django import StartupCommand
SWAGGER_SPEC_PATH = os.path.join(os.path.dirname(
@@ -175,15 +176,16 @@ class EveProvider:
class EveSwaggerProvider(EveProvider):
def __init__(self, token=None, adapter=None):
if settings.DEBUG:
if settings.DEBUG or StartupCommand().is_management_command:
self._client = None
logger.info(
'DEBUG mode detected: ESI client will be loaded on-demand.'
)
logger.info('ESI client will be loaded on-demand')
else:
logger.info('Loading ESI client')
try:
self._client = esi_client_factory(
token=token, spec_file=SWAGGER_SPEC_PATH, app_info_text=("allianceauth v" + __version__)
token=token,
spec_file=SWAGGER_SPEC_PATH,
app_info_text=f"allianceauth v{__version__}"
)
except (HTTPError, RefResolutionError):
logger.exception(

View File

@@ -30,7 +30,7 @@
<td class="text-center">{{ fat.user }}</td>
<td class="text-center">{{ fat.character.character_name }}</td>
{% if fat.station != "No Station" %}
<td class="text-center">{% blocktrans %}Docked in {% endblocktrans %}{{ fat.system }}</td>
<td class="text-center">{% blocktranslate %}Docked in {% endblocktranslate %}{{ fat.system }}</td>
{% else %}
<td class="text-center">{{ fat.system }}</td>
{% endif %}

View File

@@ -5,7 +5,7 @@
{% block content %}
<div class="col-lg-12">
<h1 class="page-header text-center">{% blocktrans %}Participation data statistics for {{ month }}, {{ year }}{% endblocktrans %}
<h1 class="page-header text-center">{% blocktranslate %}Participation data statistics for {{ month }}, {{ year }}{% endblocktranslate %}
{% if char_id %}
<div class="text-right">
<a href="{% url 'fatlink:user_statistics_month' char_id previous_month|date:'Y' previous_month|date:'m' %}" class="btn btn-info">{% translate "Previous month" %}</a>
@@ -14,11 +14,11 @@
{% endif %}
</h1>
<h2>
{% blocktrans count links=n_fats trimmed %}
{% blocktranslate count links=n_fats trimmed %}
{{ user }} has collected one link this month.
{% plural %}
{{ user }} has collected {{ links }} links this month.
{% endblocktrans %}
{% endblocktranslate %}
</h2>
<table class="table table-responsive">
<tr>
@@ -34,11 +34,11 @@
</table>
{% if created_fats %}
<h2>
{% blocktrans count links=n_created_fats trimmed %}
{% blocktranslate count links=n_created_fats trimmed %}
{{ user }} has created one link this month.
{% plural %}
{{ user }} has created {{ links }} links this month.
{% endblocktrans %}
{% endblocktranslate %}
</h2>
{% if created_fats %}
<table class="table">

View File

@@ -5,7 +5,7 @@
{% block content %}
<div class="col-lg-12">
<h1 class="page-header text-center">{% blocktrans %}Participation data statistics for {{ year }}{% endblocktrans %}
<h1 class="page-header text-center">{% blocktranslate %}Participation data statistics for {{ year }}{% endblocktranslate %}
<div class="text-right">
<a href="{% url 'fatlink:personal_statistics_year' previous_year %}" class="btn btn-info">{% translate "Previous year" %}</a>
{% if next_year %}

View File

@@ -5,7 +5,7 @@
{% block content %}
<div class="col-lg-12">
<h1 class="page-header text-center">{% blocktrans %}Participation data statistics for {{ month }}, {{ year }}{% endblocktrans %}
<h1 class="page-header text-center">{% blocktranslate %}Participation data statistics for {{ month }}, {{ year }}{% endblocktranslate %}
<div class="text-right">
<a href="{% url 'fatlink:statistics_corp_month' corpid previous_month|date:"Y" previous_month|date:"m" %}" class="btn btn-info">{% translate "Previous month" %}</a>
{% if next_month %}

View File

@@ -5,7 +5,7 @@
{% block content %}
<div class="col-lg-12">
<h1 class="page-header text-center">{% blocktrans %}Participation data statistics for {{ month }}, {{ year }}{% endblocktrans %}
<h1 class="page-header text-center">{% blocktranslate %}Participation data statistics for {{ month }}, {{ year }}{% endblocktranslate %}
<div class="text-right">
<a href="{% url 'fatlink:statistics_month' previous_month|date:"Y" previous_month|date:"m" %}" class="btn btn-info">{% translate "Previous month" %}</a>
{% if next_month %}

View File

@@ -33,7 +33,7 @@
<td class="text-center">{{ fat.fatlink.fleet }}</td>
<td class="text-center">{{ fat.character.character_name }}</td>
{% if fat.station != "No Station" %}
<td class="text-center">{% blocktrans %}Docked in {% endblocktrans %}{{ fat.system }}</td>
<td class="text-center">{% blocktranslate %}Docked in {% endblocktranslate %}{{ fat.system }}</td>
{% else %}
<td class="text-center">{{ fat.system }}</td>
{% endif %}

View File

@@ -248,59 +248,82 @@ def fatlink_monthly_personal_statistics_view(request, year, month, char_id=None)
@login_required
@token_required(
scopes=['esi-location.read_location.v1', 'esi-location.read_ship_type.v1', 'esi-universe.read_structures.v1'])
scopes=[
'esi-location.read_location.v1',
'esi-location.read_ship_type.v1',
'esi-universe.read_structures.v1',
'esi-location.read_online.v1',
]
)
def click_fatlink_view(request, token, fat_hash=None):
fatlink = get_object_or_404(Fatlink, hash=fat_hash)
c = token.get_esi_client(spec_file=SWAGGER_SPEC_PATH)
character = EveCharacter.objects.get_character_by_id(token.character_id)
character_online = c.Location.get_characters_character_id_online(
character_id=token.character_id
).result()
if (timezone.now() - fatlink.fatdatetime) < datetime.timedelta(seconds=(fatlink.duration * 60)):
if character_online["online"] is True:
fatlink = get_object_or_404(Fatlink, hash=fat_hash)
character = EveCharacter.objects.get_character_by_id(token.character_id)
if (timezone.now() - fatlink.fatdatetime) < datetime.timedelta(seconds=(fatlink.duration * 60)):
if character:
# get data
location = c.Location.get_characters_character_id_location(character_id=token.character_id).result()
ship = c.Location.get_characters_character_id_ship(character_id=token.character_id).result()
location['solar_system_name'] = \
c.Universe.get_universe_systems_system_id(system_id=location['solar_system_id']).result()['name']
if character:
# get data
c = token.get_esi_client(spec_file=SWAGGER_SPEC_PATH)
location = c.Location.get_characters_character_id_location(character_id=token.character_id).result()
ship = c.Location.get_characters_character_id_ship(character_id=token.character_id).result()
location['solar_system_name'] = \
c.Universe.get_universe_systems_system_id(system_id=location['solar_system_id']).result()['name']
if location['station_id']:
location['station_name'] = \
c.Universe.get_universe_stations_station_id(station_id=location['station_id']).result()['name']
elif location['structure_id']:
location['station_name'] = \
c.Universe.get_universe_structures_structure_id(structure_id=location['structure_id']).result()[
'name']
if location['station_id']:
location['station_name'] = \
c.Universe.get_universe_stations_station_id(station_id=location['station_id']).result()['name']
elif location['structure_id']:
location['station_name'] = \
c.Universe.get_universe_structures_structure_id(structure_id=location['structure_id']).result()[
'name']
else:
location['station_name'] = "No Station"
ship['ship_type_name'] = provider.get_itemtype(ship['ship_type_id']).name
fat = Fat()
fat.system = location['solar_system_name']
fat.station = location['station_name']
fat.shiptype = ship['ship_type_name']
fat.fatlink = fatlink
fat.character = character
fat.user = request.user
try:
fat.full_clean()
fat.save()
messages.success(request, _('Fleet participation registered.'))
except ValidationError as e:
err_messages = []
for errorname, message in e.message_dict.items():
err_messages.append(message[0])
messages.error(request, ' '.join(err_messages))
else:
location['station_name'] = "No Station"
ship['ship_type_name'] = provider.get_itemtype(ship['ship_type_id']).name
context = {
'character_id': token.character_id,
'character_name': token.character_name,
'character_portrait_url': EveCharacter.generic_portrait_url(
token.character_id, 128
),
}
fat = Fat()
fat.system = location['solar_system_name']
fat.station = location['station_name']
fat.shiptype = ship['ship_type_name']
fat.fatlink = fatlink
fat.character = character
fat.user = request.user
try:
fat.full_clean()
fat.save()
messages.success(request, _('Fleet participation registered.'))
except ValidationError as e:
err_messages = []
for errorname, message in e.message_dict.items():
err_messages.append(message[0])
messages.error(request, ' '.join(err_messages))
return render(request, 'fleetactivitytracking/characternotexisting.html', context=context)
else:
context = {
'character_id': token.character_id,
'character_name': token.character_name,
'character_portrait_url': EveCharacter.generic_portrait_url(
token.character_id, 128
),
}
return render(request, 'fleetactivitytracking/characternotexisting.html', context=context)
messages.error(request, _('FAT link has expired.'))
else:
messages.error(request, _('FAT link has expired.'))
messages.warning(
request,
_(
f"Cannot register the fleet participation for {character.character_name}. The character needs to be online."
),
)
return redirect('fatlink:view')

View File

@@ -1,5 +1,4 @@
{% extends "allianceauth/base.html" %}
{% load static %}
{% load i18n %}
{% block page_title %}{{ group }} {% translate "Audit Log" %}{% endblock page_title %}

View File

@@ -60,7 +60,7 @@
<i class="glyphicon glyphicon-list-alt"></i>
</a>
<a id="clipboard-copy" data-clipboard-text="{{ request.scheme }}://{{request.get_host}}{% url 'groupmanagement:request_add' group.id %}" class="btn btn-warning" title="{% translate "Copy Direct Join Link" %}">
<a id="clipboard-copy" data-clipboard-text="{{ SITE_URL }}{% url 'groupmanagement:request_add' group.id %}" class="btn btn-warning" title="{% translate "Copy Direct Join Link" %}">
<i class="glyphicon glyphicon-copy"></i>
</a>
</td>

View File

@@ -5,7 +5,7 @@ app_name = "groupmanagement"
urlpatterns = [
# groups
path("groups", views.groups_view, name="groups"),
path("groups/", views.groups_view, name="groups"),
path("group/request/join/<int:group_id>/", views.group_request_add, name="request_add"),
path(
"group/request/leave/<int:group_id>/", views.group_request_leave, name="request_leave"

File diff suppressed because it is too large Load Diff

File diff suppressed because it is too large Load Diff

File diff suppressed because it is too large Load Diff

File diff suppressed because it is too large Load Diff

File diff suppressed because it is too large Load Diff

File diff suppressed because it is too large Load Diff

File diff suppressed because it is too large Load Diff

File diff suppressed because it is too large Load Diff

Binary file not shown.

File diff suppressed because it is too large Load Diff

File diff suppressed because it is too large Load Diff

View File

@@ -34,7 +34,7 @@ class OpTimer(models.Model):
fc = models.CharField(max_length=254, default="")
post_time = models.DateTimeField(default=timezone.now)
eve_character = models.ForeignKey(EveCharacter, null=True,
on_delete=models.SET_NULL)
on_delete=models.SET_NULL)
description = models.TextField(blank=True, default="")
type = models.ForeignKey(OpTimerType, null=True, on_delete=models.SET_NULL)

View File

@@ -8,10 +8,10 @@
<h1 class="page-header">{% translate "Permissions Overview" %}</h1>
<p>
{% if request.GET.all != 'yes' %}
{% blocktrans %}Showing only applied permissions{% endblocktrans %}
{% blocktranslate %}Showing only applied permissions{% endblocktranslate %}
<a href="{% url 'permissions_tool:overview' %}?all=yes" class="btn btn-primary">{% translate "Show All" %}</a>
{% else %}
{% blocktrans %}Showing all permissions{% endblocktrans %}
{% blocktranslate %}Showing all permissions{% endblocktranslate %}
<a href="{% url 'permissions_tool:overview' %}?all=no" class="btn btn-primary">{% translate "Show Applied" %}</a>
{% endif %}
</p>

View File

@@ -84,17 +84,17 @@ LOCALE_PATHS = (
os.path.join(BASE_DIR, 'locale/'),
)
ugettext = lambda s: s
LANGUAGES = (
('en', ugettext('English')),
('de', ugettext('German')),
('es', ugettext('Spanish')),
('zh-hans', ugettext('Chinese Simplified')),
('ru', ugettext('Russian')),
('ko', ugettext('Korean')),
('fr', ugettext('French')),
('ja', ugettext('Japanese')),
('it', ugettext('Italian')),
("en", "English"),
("de", "German"),
("es", "Spanish"),
("zh-hans", "Chinese Simplified"),
("ru", "Russian"),
("ko", "Korean"),
("fr", "French"),
("ja", "Japanese"),
("it", "Italian"),
("uk", "Ukrainian"),
)
TEMPLATES = [

View File

@@ -14,6 +14,7 @@ STATIC_ROOT = "/var/www/{{ project_name }}/static/"
SITE_NAME = '{{ project_name }}'
# This is your websites URL, set it accordingly
# Make sure this URL is WITHOUT a trailing slash
SITE_URL = "https://example.com"
# Django security

View File

@@ -1,13 +1,16 @@
<tr>
<td class="text-center">{{ service_name }}</td>
<td class="text-center">{{ username }}</td>
<td class="text-center"><a href="mumble://{{ service_url }}">{{ service_url }}</a></td>
<td class="text-center">
{% if username == "" %}
<td class="text-center">{{ service_url }}</td>
<td class="text-center">
<a href="{% url 'mumble:activate' %}" title="Activate" class="btn btn-warning">
<span class="glyphicon glyphicon-ok"></span>
</a>
</td>
{% else %}
<td class="text-center"><a href="mumble://{{ connect_url }}">{{ service_url }}</a></td>
<td class="text-center">
<a href="{% url 'mumble:set_password' %}" title="Set Password" class="btn btn-warning">
<span class="glyphicon glyphicon-pencil"></span>
</a>
@@ -17,9 +20,9 @@
<a href="{% url 'mumble:deactivate' %}" title="Deactivate" class="btn btn-danger">
<span class="glyphicon glyphicon-remove"></span>
</a>
<a href="mumble://{{ connect_url }}" class="btn btn-success" title="Connect">
<a href="mumble://{{ connect_url }}" class="btn btn-success" title="Connect">
<span class="glyphicon glyphicon-arrow-right"></span>
</a>
</td>
{% endif %}
</td>
</tr>

View File

@@ -38,6 +38,12 @@ class SmfService(ServicesHook):
if SmfTasks.has_account(user):
SmfTasks.update_groups.delay(user.pk)
def sync_nickname(self, user):
logger.debug(f"Updating {self.name} displayed name for {user}")
if SmfTasks.has_account(user):
SmfTasks.update_display_name.apply_async(args=[user.pk], countdown=5) # cooldown on this task to ensure DB clean when syncing
def update_all_groups(self):
logger.debug('Update all %s groups called' % self.name)
SmfTasks.update_all_groups.delay()

View File

@@ -5,11 +5,14 @@ from datetime import datetime
import hashlib
import logging
import re
from typing import Tuple
from packaging import version
from django.db import connections
from django.conf import settings
from django.contrib.auth.models import User
from allianceauth.eveonline.models import EveCharacter
logger = logging.getLogger(__name__)
@@ -37,6 +40,10 @@ class SmfManager:
SQL_DEL_USER = r"DELETE FROM %smembers where member_name = %%s" % TABLE_PREFIX
SQL_UPD_USER = r"UPDATE %smembers SET email_address = %%s, passwd = %%s, real_name = %%s WHERE member_name = %%s" % TABLE_PREFIX
SQL_UPD_DISPLAY_NAME = r"UPDATE %smembers SET real_name = %%s WHERE member_name = %%s" % TABLE_PREFIX
SQL_DIS_USER = r"UPDATE %smembers SET email_address = %%s, passwd = %%s WHERE member_name = %%s" % TABLE_PREFIX
SQL_USER_ID_FROM_USERNAME = r"SELECT id_member from %smembers WHERE member_name = %%s" % TABLE_PREFIX
@@ -174,50 +181,75 @@ class SmfManager:
return out
@classmethod
def add_user(cls, username, email_address, groups, characterid):
def add_user(cls, username, email_address, groups, main_character: EveCharacter) -> Tuple:
"""
Add a user to SMF
:param username:
:param email_address:
:param groups:
:param main_character:
:return:
"""
main_character_id = main_character.character_id
main_character_name = main_character.character_name
logger.debug(
f"Adding smf user with member_name {username}, "
f"email_address {email_address}, "
f"characterid {characterid}"
f"Adding smf user with member_name: {username}, "
f"email_address: {email_address}, "
f"characterid: {main_character_id}, "
f"main character: {main_character_name}"
)
cursor = connections['smf'].cursor()
username_clean = cls.santatize_username(username)
passwd = cls.generate_random_pass()
pwhash = cls.gen_hash(username_clean, passwd)
logger.debug(f"Proceeding to add smf user {username} and pwhash starting with {pwhash[0:5]}")
register_date = cls.get_current_utc_date()
logger.debug(f"Proceeding to add smf user {username} and pwhash starting with {pwhash[0:5]}")
# check if the username was simply revoked
if cls.check_user(username) is True:
logger.warning(f"Unable to add smf user with username {username} - already exists. Updating user instead.")
cls.__update_user_info(username_clean, email_address, pwhash)
logger.warning(
f"Unable to add smf user with username {username} - "
f"already exists. Updating user instead."
)
cls.__update_user_info(
username_clean, email_address, pwhash, main_character_name
)
else:
try:
smf_version = cls._get_current_smf_version()
sql_add_user_arguments = [
username_clean,
pwhash,
email_address,
register_date,
main_character_name,
]
if version.parse(smf_version) < version.parse("2.1"):
logger.debug("SMF compatibility: < 2.1")
cursor.execute(
cls.SQL_ADD_USER_SMF_20,
[username_clean, pwhash, email_address, register_date, username_clean]
)
cursor.execute(cls.SQL_ADD_USER_SMF_20, sql_add_user_arguments)
else:
logger.debug("SMF compatibility: >= 2.1")
cursor.execute(
cls.SQL_ADD_USER_SMF_21,
[username_clean, pwhash, email_address, register_date, username_clean]
)
cls.add_avatar(username_clean, characterid)
cursor.execute(cls.SQL_ADD_USER_SMF_21, sql_add_user_arguments)
cls.add_avatar(username_clean, main_character_id)
logger.info(f"Added smf member_name {username_clean}")
cls.update_groups(username_clean, groups)
except Exception as e:
logger.warning(f"Unable to add smf user {username_clean}: {e}")
pass
return username_clean, passwd
@classmethod
def __update_user_info(cls, username, email_address, passwd):
def __update_user_info(cls, username, email_address, passwd, main_character_name):
logger.debug(
f"Updating smf user {username} info: "
f"username {email_address} "
@@ -225,7 +257,9 @@ class SmfManager:
)
cursor = connections['smf'].cursor()
try:
cursor.execute(cls.SQL_DIS_USER, [email_address, passwd, username])
cursor.execute(
cls.SQL_UPD_USER, [email_address, passwd, main_character_name, username]
)
logger.info(f"Updated smf user {username} info")
except Exception as e:
logger.exception(f"Unable to update smf user {username} info. ({e})")
@@ -243,6 +277,27 @@ class SmfManager:
logger.error(f"Unable to delete smf user {username} - user not found on smf.")
return False
@classmethod
def update_display_name(cls, user: User):
logger.debug(f"Updating SMF displayed name for user {user}")
cursor = connections['smf'].cursor()
smf_username = user.smf.username
try:
display_name = user.profile.main_character.character_name
except Exception as exc:
logger.exception(
f"Unable to find a main character name for {user}, skipping... ({exc})"
)
display_name = smf_username
if cls.check_user(smf_username):
cursor.execute(cls.SQL_UPD_DISPLAY_NAME, [display_name, smf_username])
logger.info(f"Updated displayed name for smf user {smf_username}")
return True
logger.error(f"Unable to update smf user {smf_username} - user not found on smf.")
return False
@classmethod
def update_groups(cls, username, groups):
userid = cls.get_user_id(username)

View File

@@ -0,0 +1,29 @@
from django.db import migrations
from ..manager import SmfManager
def on_migrate(apps, schema_editor):
SmfUser = apps.get_model("smf", "SmfUser")
db_alias = schema_editor.connection.alias
all_smf_users = SmfUser.objects.using(db_alias).all()
for smf_user in all_smf_users:
try:
auth_user = smf_user.user
except:
pass
else:
SmfManager.update_display_name(auth_user)
def on_migrate_zero(apps, schema_editor):
pass
class Migration(migrations.Migration):
dependencies = [
('smf', '0002_service_permissions'),
]
operations = [
migrations.RunPython(on_migrate, on_migrate_zero),
]

View File

@@ -57,6 +57,40 @@ class SmfTasks:
else:
logger.debug("User does not have an smf account")
@staticmethod
@shared_task(bind=True, name="smf.update_display_name", base=QueueOnce)
def update_display_name(self, pk):
user = User.objects.get(pk=pk)
logger.debug(f"Updating SMF displayed name user {user}")
if SmfTasks.has_account(user):
try:
if not SmfManager.update_display_name(user):
raise Exception("SMF Displayed Name Sync failed")
logger.debug(f"Updated user {user} SMF displayed name.")
return True
except SmfUser.DoesNotExist:
logger.info(
f"SMF displayed name sync failed for {user}, "
"user does not have a SMF account"
)
except:
logger.exception(
f"SMF displayed name sync failed for {user}, retrying in 10 mins"
)
raise self.retry(countdown=60 * 10)
else:
logger.debug(f"User {user} does not have a SMF account, skipping")
return False
@staticmethod
@shared_task(name="smf.update_all_display_names")
def update_all_display_names():
logger.debug("Updating ALL SMF display names")
for smf_user in SmfUser.objects.exclude(username__exact=''):
SmfTasks.update_display_name.delay(smf_user)
@staticmethod
@shared_task(name="smf.update_all_groups")
def update_all_groups():

View File

@@ -19,26 +19,51 @@ ACCESS_PERM = 'smf.access_smf'
@login_required
@permission_required(ACCESS_PERM)
def activate_smf(request):
logger.debug("activate_smf called by user %s" % request.user)
logger.debug(f"activate_smf called by user {request.user}")
# Valid now we get the main characters
character = request.user.profile.main_character
logger.debug(f"Adding smf user for user {request.user} with main character {character}")
result = SmfManager.add_user(SmfTasks.get_username(request.user), request.user.email, ['Member'], character.character_id)
main_character = request.user.profile.main_character
logger.debug(
f"Adding smf user for user {request.user} with main character {main_character}"
)
result = SmfManager.add_user(
SmfTasks.get_username(request.user),
request.user.email,
['Member'],
main_character,
)
# if empty we failed
if result[0] != "":
SmfUser.objects.update_or_create(user=request.user, defaults={'username': result[0]})
logger.debug("Updated authserviceinfo for user %s with smf credentials. Updating groups." % request.user)
SmfUser.objects.update_or_create(
user=request.user, defaults={'username': result[0]}
)
logger.debug(
f"Updated authserviceinfo for user {request.user} "
f"with smf credentials. Updating groups."
)
SmfTasks.update_groups.delay(request.user.pk)
logger.info("Successfully activated smf for user %s" % request.user)
logger.info(f"Successfully activated smf for user {request.user}")
messages.success(request, _('Activated SMF account.'))
credentials = {
'username': result[0],
'password': result[1],
}
return render(request, 'services/service_credentials.html', context={'credentials': credentials, 'service': 'SMF'})
else:
logger.error("Unsuccessful attempt to activate smf for user %s" % request.user)
messages.error(request, _('An error occurred while processing your SMF account.'))
return render(
request,
'services/service_credentials.html',
context={'credentials': credentials, 'service': 'SMF'},
)
logger.error(f"Unsuccessful attempt to activate smf for user {request.user}")
messages.error(request, _('An error occurred while processing your SMF account.'))
return redirect("services:services")

View File

@@ -457,7 +457,7 @@ class Teamspeak3AdminTestCase(TestCase):
cls.site = AdminSite()
cls.admin = AuthTSgroupAdmin(AuthTS, cls.site)
cls.group = Group.objects.create(name='test')
cls.ts_group = TSgroup.objects.create(ts_group_name='test')
cls.ts_group = TSgroup.objects.create(ts_group_id=1, ts_group_name='test')
def test_field_queryset_no_reserved_names(self):
"""Ensure all groups are listed when no reserved names"""

View File

@@ -2,5 +2,10 @@
CSS for allianceauth admin site
*/
.img-circle { border-radius: 50%; }
.column-user_profile_pic { width: 50px; }
.img-circle {
border-radius: 50%;
}
.column-user_profile_pic {
width: 50px;
}

View File

@@ -3,13 +3,13 @@
{% block page_title %}
{% blocktrans with service_name=view.service_name|title %}Delete {{ service_name }} Account?{% endblocktrans %}
{% blocktranslate with service_name=view.service_name|title %}Delete {{ service_name }} Account?{% endblocktranslate %}
{% endblock page_title %}
{% block content %}
<div class="col-lg-12">
<h1 class="page-header text-center">
{% blocktrans with service_name=view.service_name|title %}Delete {{ service_name }} Account?{% endblocktrans %}
{% blocktranslate with service_name=view.service_name|title %}Delete {{ service_name }} Account?{% endblocktranslate %}
</h1>
<div class="container-fluid">
<div class="col-md-2 col-md-offset-5">
@@ -17,9 +17,9 @@
<form action="" method="post">
{% csrf_token %}
<p>
{% blocktrans trimmed with service_name=view.service_name|title %}
{% blocktranslate trimmed with service_name=view.service_name|title %}
Are you sure you want to delete your {{ service_name }} account {{ object }}?
{% endblocktrans %}
{% endblocktranslate %}
</p>
<input class="btn btn-danger btn-block" type="submit" value="Confirm">
</form>

View File

@@ -1,11 +1,11 @@
{% extends "allianceauth/base.html" %}
{% load i18n %}
{% block page_title %}{% blocktrans with service_name=view.service_name|title %}{{ service_name }} Credentials{% endblocktrans %}{% endblock page_title %}
{% block page_title %}{% blocktranslate with service_name=view.service_name|title %}{{ service_name }} Credentials{% endblocktranslate %}{% endblock page_title %}
{% block content %}
<div class="col-lg-12">
<h1 class="page-header text-center">{% blocktrans with service_name=view.service_name|title %}{{ service_name }} Credentials{% endblocktrans %}</h1>
<h1 class="page-header text-center">{% blocktranslate with service_name=view.service_name|title %}{{ service_name }} Credentials{% endblocktranslate %}</h1>
<div class="container-fluid">
<div class="col-lg-4 col-lg-offset-4">
<form class="form-signin">

View File

@@ -2,11 +2,11 @@
{% load bootstrap %}
{% load i18n %}
{% block page_title %}{% blocktrans with service_name=view.service_name|title %}{{ service_name }} Password Change{% endblocktrans %}{% endblock page_title %}
{% block page_title %}{% blocktranslate with service_name=view.service_name|title %}{{ service_name }} Password Change{% endblocktranslate %}{% endblock page_title %}
{% block content %}
<div class="col-lg-12">
<h1 class="page-header text-center">{% blocktrans with service_name=view.service_name|title %}Set {{service_name}} Password{% endblocktrans %}</h1>
<h1 class="page-header text-center">{% blocktranslate with service_name=view.service_name|title %}Set {{service_name}} Password{% endblocktranslate %}</h1>
<div class="container-fluid">
<div class="col-md-4 col-md-offset-4">
<div class="row">

View File

@@ -23,9 +23,10 @@
<button class="btn btn-lg btn-primary btn-block" type="submit">{% translate "Create SRP Fleet" %}</button>
</form>
{% else %}
<div class="alert alert-info" role="alert">{% blocktrans %}Give this link to the line members{% endblocktrans %}.</div>
<div class="alert alert-info" role="alert">{% blocktranslate %}Give this link to the line members{% endblocktranslate %}.</div>
<div class="alert alert-info" role="alert">
{{ request.scheme }}://{{ request.get_host }}{% url 'srp:request' completed_srp_code %}</div>
{{ SITE_URL }}{% url 'srp:request' completed_srp_code %}
</div>
<div class="text-center">
<a href="{% url 'srp:management' %}" class="btn btn-primary btn-lg">{% translate "Continue" %}</a>
</div>

View File

@@ -1,5 +1,4 @@
{% extends "allianceauth/base.html" %}
{% load static %}
{% load i18n %}
{% load humanize %}
@@ -7,7 +6,7 @@
{% block extra_css %}
{% include 'bundles/datatables-css.html' %}
{% include 'bundles/x-editable.css.html' %}
<link href="{% static 'allianceauth/css/checkbox.css' %}" rel="stylesheet">
{% include 'bundles/checkbox-css.html' %}
<style>
.copy-text-fa-icon:hover {
cursor: pointer;
@@ -93,9 +92,9 @@
<th class="text-center">{% translate "Ship Type" %}</th>
<th class="text-center">{% translate "Killboard Loss Amt" %}</th>
<th class="text-center">{% translate "SRP ISK Cost" %}
<i class="glyphicon glyphicon-question-sign" rel="tooltip" title="{% blocktrans trimmed %}Click value to edit
<i class="glyphicon glyphicon-question-sign" rel="tooltip" title="{% blocktranslate trimmed %}Click value to edit
Enter to save & next
ESC to cancel{% endblocktrans %}" id="blah"></i></th>
ESC to cancel{% endblocktranslate %}" id="blah"></i></th>
<th class="text-center">{% translate "Post Time" %}</th>
<th class="text-center">{% translate "Status" %}</th>
{% if perms.auth.srp_management %}

View File

@@ -11,7 +11,7 @@ urlpatterns = [
path('<int:fleet_id>/view/', views.srp_fleet_view, name='fleet'),
path('add/', views.srp_fleet_add_view, name='add'),
path('<int:fleet_id>/edit/', views.srp_fleet_edit_view, name='edit'),
path('<str:fleet_srp>/request', views.srp_request_view, name='request'),
path('<str:fleet_srp>/request/', views.srp_request_view, name='request'),
# SRP URLS
path('<int:fleet_id>/remove/', views.srp_fleet_remove, name='remove'),
@@ -27,6 +27,6 @@ urlpatterns = [
name='request_approve'),
path('request/reject/', views.srp_request_reject,
name='request_reject'),
path('request/<int:fleet_srp_request_id>/update', views.srp_request_update_amount,
path('request/<int:fleet_srp_request_id>/update/', views.srp_request_update_amount,
name="request_update_amount"),
]

View File

@@ -2,17 +2,9 @@ body {
margin-bottom: 32px;
}
.gray-icon-color .fa {
color: #505050;
}
.notification-bell-color {
color: #a88f1e;
}
.navbar-brand {
height: 58px;
padding: 19px 19px;
padding: 19px;
}
.auth-navbar-top {
@@ -48,36 +40,36 @@ ul.list-group.list-group-horizontal > li.list-group-item {
}
@media all {
/* style nav tabs in dark mode*/
/* style nav tabs in dark mode */
.template-dark-mode .nav-tabs > li.active > a {
background-color: rgb(70, 69, 69) !important;
color: rgb(255, 255, 255) !important;
background-color: rgb(70 69 69) !important;
color: rgb(255 255 255) !important;
}
.panel-tabs-aa {
border-top: none;
border-top-left-radius: 0%;
border-top-right-radius: 0%;
border-top-left-radius: 0;
border-top-right-radius: 0;
}
/* style group headers within a table */
.template-light-mode .tr-group {
background-color: #e6e6e6 !important;
background-color: rgb(230 230 230) !important;
font-weight: bold;
}
.template-dark-mode .tr-group {
background-color: rgb(105, 105, 105) !important;
background-color: rgb(105 105 105) !important;
font-weight: bold;
}
/* default style for tables */
.template-light-mode .table-aa > thead > tr > th {
border-bottom: 1px solid #f2f2f2;
border-bottom: 1px solid rgb(242 242 242);
}
.template-dark-mode .table-aa > thead > tr > th {
border-bottom: 1px solid rgb(70, 69, 69);
border-bottom: 1px solid rgb(70 69 69);
}
.table-aa > thead > tr > th {
@@ -85,11 +77,11 @@ ul.list-group.list-group-horizontal > li.list-group-item {
}
.template-light-mode .table-aa > tbody > tr > td {
border-bottom: 1px solid #f2f2f2;
border-bottom: 1px solid rgb(242 242 242);
}
.template-dark-mode .table-aa > tbody > tr > td {
border-bottom: 1px solid rgb(70, 69, 69);
border-bottom: 1px solid rgb(70 69 69);
}
.table-aa > tbody > tr > td {
@@ -100,9 +92,9 @@ ul.list-group.list-group-horizontal > li.list-group-item {
border-bottom: none;
}
.task-status-progress-bar {
font-size: 15px!important;
line-height: normal!important;
.progress .progress-bar {
font-size: 13px;
line-height: 21px;
}
}
@@ -110,11 +102,11 @@ ul.list-group.list-group-horizontal > li.list-group-item {
------------------------------------------------------------------------------------- */
@media all {
.template-light-mode .nav-pills > li > a.active {
background-color: rgb(236, 240, 241);
background-color: rgb(236 240 241);
}
.template-dark-mode .nav-pills > li > a.active {
background-color: rgb(48, 48, 48);
background-color: rgb(48 48 48);
}
}
@@ -136,45 +128,41 @@ ul.list-group.list-group-horizontal > li.list-group-item {
.dropdown-menu > li > a {
clear: both;
color: rgb(123, 138, 139);
color: rgb(123 138 139);
display: block;
font-weight: 400;
line-height: 1.42857143;
line-height: 1.42857;
padding: 3px 20px;
white-space: nowrap;
}
.top-user-menu {
color: rgb(255, 255, 255);
color: rgb(255 255 255);
}
.top-menu-bar-language-select form {
border-bottom: 1px solid transparent;
border-top: 1px solid transparent;
-webkit-box-shadow: inset 0 1px 0 rgb(255 255 255), 0 1px 0 rgb(255 255 255);
box-shadow: inset 0 1px 0 rgb(255 255 255), 0 1px 0 rgb(255 255 255);
margin-bottom: 7.5px;
margin-left: 5px;
margin-right: 5px;
margin-top: 7.5px;
margin: 7.5px 5px;
padding: 10px 15px;
}
}
@media all and (max-width: 768px) {
.navbar-nav .open .dropdown-menu .dropdown-header, .navbar-nav .open .dropdown-menu > li > a {
.navbar-nav .open .dropdown-menu .dropdown-header,
.navbar-nav .open .dropdown-menu > li > a {
padding: 5px 15px 5px 25px;
}
}
@media all and (min-width: 768px) {
.top-user-menu {
color: rgb(123, 138, 139);
color: rgb(123 138 139);
}
.top-menu-bar-language-select form {
border: 0;
-webkit-box-shadow: none;
box-shadow: none;
margin-left: 0;
margin-right: 0;
@@ -188,7 +176,7 @@ ul.list-group.list-group-horizontal > li.list-group-item {
------------------------------------------------------------------------------------- */
@media all {
.nav-item-eve-time .eve-time-wrapper {
color: rgb(255, 255, 255);
color: rgb(255 255 255);
display: block;
line-height: 21px;
padding: 10px 15px;
@@ -203,26 +191,17 @@ ul.list-group.list-group-horizontal > li.list-group-item {
}
}
/* Small devices (tablets, 768px and up) */
/* Small devices (tablets, 768px and up)
------------------------------------------------------------------------------------- */
@media (min-width: 768px) {
/* class for vertically aligning columns in a bootstrap row */
.row.vertical-flexbox-row2 {
display: -webkit-box;
display: -webkit-flex;
display: -ms-flexbox;
display: flex;
flex-wrap: wrap;
}
.row.vertical-flexbox-row2 > [class*='col-'] {
.row.vertical-flexbox-row2 > [class*="col-"] {
display: flex;
flex-direction: column;
}
}
/* Extra Small devices (Phones, <768px) */
@media (max-width: 767px) {
.button-wrapper .btn {
margin-bottom: 5px;
}
}

View File

@@ -1,20 +1,20 @@
.checkbox label:after,
.radio label:after {
content: '';
display: table;
.checkbox label::after,
.radio label::after {
clear: both;
content: "";
display: table;
}
.checkbox .cr,
.radio .cr {
position: relative;
border: 1px solid rgb(169 169 169);
border-radius: 0.25em;
display: inline-block;
border: 1px solid #a9a9a9;
border-radius: .25em;
width: 1.3em;
height: 1.3em;
float: left;
margin-right: .5em;
height: 1.3em;
margin-right: 0.5em;
position: relative;
width: 1.3em;
}
.radio .cr {
@@ -23,11 +23,11 @@
.checkbox .cr .cr-icon,
.radio .cr .cr-icon {
position: absolute;
font-size: .8em;
line-height: 0;
top: 50%;
font-size: 0.8em;
left: 20%;
line-height: 0;
position: absolute;
top: 50%;
}
.radio .cr .cr-icon {
@@ -41,18 +41,18 @@
.checkbox label input[type="checkbox"] + .cr > .cr-icon,
.radio label input[type="radio"] + .cr > .cr-icon {
transform: scale(3) rotateZ(-20deg);
opacity: 0;
transition: all .3s ease-in;
transform: scale(3) rotateZ(-20deg);
transition: all 0.3s ease-in;
}
.checkbox label input[type="checkbox"]:checked + .cr > .cr-icon,
.radio label input[type="radio"]:checked + .cr > .cr-icon {
transform: scale(1) rotateZ(0deg);
opacity: 1;
transform: scale(1) rotateZ(0deg);
}
.checkbox label input[type="checkbox"]:disabled + .cr,
.radio label input[type="radio"]:disabled + .cr {
opacity: .5;
opacity: 0.5;
}

View File

@@ -7,6 +7,7 @@
aria-valuenow="{% decimal_widthratio tasks_count tasks_total 100 %}"
aria-valuemin="0"
aria-valuemax="100"
style="width: {% decimal_widthratio tasks_count tasks_total 100 %}%;">
<p style="margin-top:5px;">{% widthratio tasks_count tasks_total 100 %}%</p>
style="width: {% decimal_widthratio tasks_count tasks_total 100 %}%;"
>
<span>{% widthratio tasks_count tasks_total 100 %}%</span>
</div>

View File

@@ -1,4 +1,3 @@
{% load static %}
{% load i18n %}
{% load navactive %}
{% load auth_notifications %}
@@ -16,8 +15,7 @@
{% include 'bundles/bootstrap-css.html' %}
{% include 'bundles/fontawesome.html' %}
<link href="{% static 'allianceauth/css/auth-base.css' %}" rel="stylesheet">
{% include 'bundles/auth-base-css.html' %}
{% block extra_css %}{% endblock extra_css %}
</head>

View File

@@ -53,6 +53,14 @@
<!-- logout / login -->
<li role="separator" class="divider"></li>
{% if user.is_authenticated %}
<li>
<a href="{% url 'authentication:token_management' %}">
<i class="fas fa-user-lock"></i>
{% translate "Token Management" %}
</a>
</li>
<li role="separator" class="divider"></li>
<li><a href="{% url 'logout' %}">{% translate "Logout" %}</a></li>
{% else %}
<li><a href="{% url 'authentication:login' %}">{% translate "Login" %}</a></li>

View File

@@ -0,0 +1,3 @@
{% load static %}
<link href="{% static 'allianceauth/css/auth-base.css' %}" rel="stylesheet">

View File

@@ -0,0 +1,3 @@
{% load static %}
<link href="{% static 'allianceauth/css/checkbox.css' %}" rel="stylesheet">

View File

@@ -1,3 +1,3 @@
<!-- Start X-editable JS from cdnjs -->
<<script src="https://cdnjs.cloudflare.com/ajax/libs/x-editable/1.5.1/bootstrap3-editable/js/bootstrap-editable.min.js" integrity="sha512-Mvqhe3YIUElH6VT0CFmUeRgYMrLvCGd2mvYCnJOf2nL9FvRBK74qRgTn7u0zSqA5cHiGxy83bwuhl1ASbS9M/w==" crossorigin="anonymous" referrerpolicy="no-referrer"></script>
<script src="https://cdnjs.cloudflare.com/ajax/libs/x-editable/1.5.1/bootstrap3-editable/js/bootstrap-editable.min.js" integrity="sha512-Mvqhe3YIUElH6VT0CFmUeRgYMrLvCGd2mvYCnJOf2nL9FvRBK74qRgTn7u0zSqA5cHiGxy83bwuhl1ASbS9M/w==" crossorigin="anonymous" referrerpolicy="no-referrer"></script>
<!-- End X-editable JS from cdnjs -->

View File

@@ -4,8 +4,7 @@ from typing import Optional
import amqp.exceptions
import requests
from celery.app import app_or_default
from packaging.version import InvalidVersion
from packaging.version import Version as Pep440Version
from packaging.version import InvalidVersion, Version as Pep440Version
from django import template
from django.conf import settings

View File

@@ -16,7 +16,7 @@
<div class="row">
<form action="" method="post">
{% csrf_token %}
<p>{% blocktrans %}Are you sure you want to delete timer "{{ object }}"?{% endblocktrans %}</p>
<p>{% blocktranslate %}Are you sure you want to delete timer "{{ object }}"?{% endblocktranslate %}</p>
<input class="btn btn-danger btn-block" type="submit" value="Confirm">
</form>
</div>

View File

@@ -1,5 +1,4 @@
{% extends "allianceauth/base.html" %}
{% load static %}
{% load i18n %}
{% get_current_language as LANGUAGE_CODE %}
{% load evelinks %}

View File

@@ -0,0 +1,25 @@
import sys
from copy import copy
from pathlib import Path
class StartupCommand:
"""Information about the command this Django instance was started with."""
def __init__(self) -> None:
self._argv = copy(sys.argv)
@property
def argv(self) -> list:
"""Return raw list of command line arguments."""
return self._argv
@property
def script_name(self) -> str:
"""Return the base script name."""
path = Path(self._argv[0])
return path.name
@property
def is_management_command(self) -> bool:
return self.script_name == "manage.py"

View File

@@ -0,0 +1,25 @@
from unittest.mock import patch
from django.test import TestCase
from allianceauth.utils.django import StartupCommand
MODULE_PATH = "allianceauth.utils.django"
class TestStartupCommand(TestCase):
def test_should_detect_management_command(self):
# when
with patch(MODULE_PATH + ".sys") as m:
m.argv = ["manage.py", "check"]
info = StartupCommand()
# then
self.assertTrue(info.is_management_command)
def test_should_detect_not_a_management_command(self):
# when
with patch(MODULE_PATH + ".sys") as m:
m.argv = ['/home/python/allianceauth-dev/venv/bin/gunicorn', 'myauth.wsgi']
info = StartupCommand()
# then
self.assertFalse(info.is_management_command)

View File

@@ -1,7 +1,7 @@
PROTOCOL=https://
AUTH_SUBDOMAIN=%AUTH_SUBDOMAIN%
DOMAIN=%DOMAIN%
AA_DOCKER_TAG=registry.gitlab.com/allianceauth/allianceauth/auth:v3.1.0
AA_DOCKER_TAG=registry.gitlab.com/allianceauth/allianceauth/auth:v3.4.0
# Nginx Proxy Manager
PROXY_HTTP_PORT=80

View File

@@ -1,5 +1,5 @@
FROM python:3.9-slim
ARG AUTH_VERSION=v3.1.0
ARG AUTH_VERSION=v3.4.0
ARG AUTH_PACKAGE=allianceauth==${AUTH_VERSION}
ENV VIRTUAL_ENV=/opt/venv
ENV AUTH_USER=allianceauth

View File

@@ -49,7 +49,11 @@ Using a custom docker image is the preferred approach, as it gives you the stabi
1. Add each additional package that you want to install to a single line in `conf/requirements.txt`. It is recommended, but not required, that you include a version number as well. This will keep your packages from magically updating. You can lookup packages on https://package.wiki, and copy everything after `pip install` from the top of the page to use the most recent version. It should look something like `allianceauth-signal-pings==0.0.7`. Every entry in this file should be on a separate line
1. In `docker-compose.yml`, comment out the `image` line under `allianceauth` (line 36... ish) and uncomment the `build` section
1. Now run `docker-compose --env-file=.env up -d`, your custom container will be built, and auth will have your new packages. Make sure to follow the package's instructions on config values that go in `local.py`
1. run `docker-compose --env-file=.env up -d`, your custom container will be built, and auth will have your new packages. Make sure to follow the package's instructions on config values that go in `local.py`
1. run `docker-compose exec allianceauth bash` to open up a terminal inside your auth container
1. run `allianceauth update myauth`
1. run `auth migrate`
1. run `auth collectstatic`
_NOTE: It is recommended that you put any secret values (API keys, database credentials, etc) in an environment variable instead of hardcoding them into `local.py`. This gives you the ability to track your config in git without committing passwords. To do this, just add it to your `.env` file, and then reference in `local.py` with `os.environ.get("SECRET_NAME")`_
@@ -58,8 +62,12 @@ _NOTE: It is recommended that you put any secret values (API keys, database cred
### Base Image
Whether you're using a custom image or not, the version of auth is dictated by $AA_DOCKER_TAG in your `.env` file.
1. To update to a new version of auth, update the version number at the end (or replace the whole value with the tag in the release notes).
1. Next, run `docker-compose pull`
1. Finally, run `docker-compose --env-file=.env up -d`
1. run `docker-compose pull`
1. run `docker-compose --env-file=.env up -d`
1. run `docker-compose exec allianceauth bash` to open up a terminal inside your auth container
1. run `allianceauth update myauth`
1. run `auth migrate`
1. run `auth collectstatic`
_NOTE: If you specify a version of allianceauth in your `requirements.txt` in a custom image it will override the version from the base image. Not recommended unless you know what you're doing_

View File

@@ -3,14 +3,20 @@ from .base import *
SECRET_KEY = os.environ.get("AA_SECRET_KEY")
SITE_NAME = os.environ.get("AA_SITENAME")
SITE_URL = (
f"{os.environ.get('PROTOCOL')}"
f"{os.environ.get('AUTH_SUBDOMAIN')}."
f"{os.environ.get('DOMAIN')}"
)
CSRF_TRUSTED_ORIGINS = [SITE_URL]
DEBUG = os.environ.get("AA_DEBUG", False)
DATABASES['default'] = {
'ENGINE': 'django.db.backends.mysql',
'NAME': os.environ.get("AA_DB_NAME"),
'USER': os.environ.get("AA_DB_USER"),
'PASSWORD': os.environ.get("AA_DB_PASSWORD"),
'HOST': os.environ.get("AA_DB_HOST"),
'PORT': os.environ.get("AA_DB_PORT", "3306"),
DATABASES["default"] = {
"ENGINE": "django.db.backends.mysql",
"NAME": os.environ.get("AA_DB_NAME"),
"USER": os.environ.get("AA_DB_USER"),
"PASSWORD": os.environ.get("AA_DB_PASSWORD"),
"HOST": os.environ.get("AA_DB_HOST"),
"PORT": os.environ.get("AA_DB_PORT", "3306"),
}
# Register an application at https://developers.eveonline.com for Authentication
@@ -21,10 +27,10 @@ DATABASES['default'] = {
ESI_SSO_CLIENT_ID = os.environ.get("ESI_SSO_CLIENT_ID")
ESI_SSO_CLIENT_SECRET = os.environ.get("ESI_SSO_CLIENT_SECRET")
ESI_SSO_CALLBACK_URL = (f"{os.environ.get('PROTOCOL')}"
f"{os.environ.get('AUTH_SUBDOMAIN')}."
f"{os.environ.get('DOMAIN')}/sso/callback")
ESI_USER_CONTACT_EMAIL = os.environ.get("ESI_USER_CONTACT_EMAIL") # A server maintainer that CCP can contact in case of issues.
ESI_SSO_CALLBACK_URL = f"{SITE_URL}/sso/callback"
ESI_USER_CONTACT_EMAIL = os.environ.get(
"ESI_USER_CONTACT_EMAIL"
) # A server maintainer that CCP can contact in case of issues.
# By default emails are validated before new users can log in.
# It's recommended to use a free service like SparkPost or Elastic Email to send email.
@@ -40,40 +46,40 @@ EMAIL_HOST_PASSWORD = os.environ.get("AA_EMAIL_HOST_PASSWORD", "")
EMAIL_USE_TLS = os.environ.get("AA_EMAIL_USE_TLS", True)
DEFAULT_FROM_EMAIL = os.environ.get("AA_DEFAULT_FROM_EMAIL", "")
ROOT_URLCONF = 'myauth.urls'
WSGI_APPLICATION = 'myauth.wsgi.application'
ROOT_URLCONF = "myauth.urls"
WSGI_APPLICATION = "myauth.wsgi.application"
STATIC_ROOT = "/var/www/myauth/static/"
BROKER_URL = F"redis://{os.environ.get('AA_REDIS', 'redis:6379')}/0"
CELERY_RESULT_BACKEND = F"redis://{os.environ.get('AA_REDIS', 'redis:6379')}/0"
BROKER_URL = f"redis://{os.environ.get('AA_REDIS', 'redis:6379')}/0"
CACHES = {
"default": {
"BACKEND": "redis_cache.RedisCache",
"LOCATION": os.environ.get('AA_REDIS', 'redis:6379'),
"OPTIONS": {
"DB": 1,
}
"BACKEND": "django_redis.cache.RedisCache",
"LOCATION": f"redis://{os.environ.get('AA_REDIS', 'redis:6379')}/1", # change the 1 here to change the database used
}
}
# Add any additional apps to this list.
INSTALLED_APPS += [
# https://allianceauth.readthedocs.io/en/latest/features/apps/index.html
# 'allianceauth.corputils',
# 'allianceauth.fleetactivitytracking',
# 'allianceauth.optimer',
# 'allianceauth.permissions_tool',
# 'allianceauth.srp',
# 'allianceauth.timerboard',
# https://allianceauth.readthedocs.io/en/latest/features/apps/index.html
# 'allianceauth.corputils',
# 'allianceauth.fleetactivitytracking',
# 'allianceauth.optimer',
# 'allianceauth.permissions_tool',
# 'allianceauth.srp',
# 'allianceauth.timerboard',
# https://allianceauth.readthedocs.io/en/latest/features/services/index.html
# 'allianceauth.services.modules.discord',
# 'allianceauth.services.modules.discourse',
# 'allianceauth.services.modules.ips4',
# 'allianceauth.services.modules.openfire',
# 'allianceauth.services.modules.phpbb3',
# 'allianceauth.services.modules.smf',
# 'allianceauth.services.modules.teamspeak3',
# 'allianceauth.services.modules.xenforo',
# https://allianceauth.readthedocs.io/en/latest/features/services/index.html
# 'allianceauth.services.modules.discord',
# 'allianceauth.services.modules.discourse',
# 'allianceauth.services.modules.ips4',
# 'allianceauth.services.modules.openfire',
# 'allianceauth.services.modules.mumble',
# An example of running mumble with authenticator in docker can be found here
# https://github.com/Solar-Helix-Independent-Transport/allianceauth-docker-mumble
# 'allianceauth.services.modules.phpbb3',
# 'allianceauth.services.modules.smf',
# 'allianceauth.services.modules.teamspeak3',
# 'allianceauth.services.modules.xenforo',
]
#######################################

View File

@@ -4,5 +4,3 @@ FROM $AA_DOCKER_TAG
RUN cd /home/allianceauth
COPY /conf/requirements.txt requirements.txt
RUN pip install -r requirements.txt
RUN python $AUTH_HOME/myauth/manage.py collectstatic --noinput
RUN allianceauth update myauth

View File

@@ -52,7 +52,7 @@ services:
- auth_mysql
grafana:
image: grafana/grafana-oss:8.3.2
image: grafana/grafana-oss:8.5.22
restart: always
depends_on:
- auth_mysql

View File

@@ -46,6 +46,7 @@ extensions = [
'recommonmark',
'sphinxcontrib_django2',
'sphinx.ext.viewcode',
'sphinx_copybutton'
]
# Add any paths that contain templates here, relative to this directory.

View File

@@ -16,14 +16,14 @@ In addition all tools described in this guide are open source or free software.
The development environment consists of the following components:
- Visual Studio Code with Remote WSL and Python extension
- WSL with Ubuntu 18.04. LTS
- Python 3.7 environment on WSL
- WSL with Ubuntu (18.04. LTS or higher)
- Python environment on WSL (3.8 or higher)
- MySQL server on WSL
- Redis on WSL
- Alliance Auth on WSL
- Celery on WSL
We will use the build-in Django development webserver, so we don't need to setup a WSGI server or a web server.
We will use the build-in Django development web server, so we don't need to setup a WSGI server or a web server.
```eval_rst
.. note::
@@ -34,13 +34,13 @@ We will use the build-in Django development webserver, so we don't need to setup
The only requirement is a PC with Windows 10 and Internet connection in order to download the additional software components.
## Windows installation
## Installing Windows apps
### Windows Subsystem for Linux
- Install from here: [Microsoft docs](https://docs.microsoft.com/en-us/windows/wsl/install-win10)
- Choose Ubuntu 18.04. LTS
- Choose Ubuntu 18.04. LTS or higher
### Visual Studio Code
@@ -54,7 +54,7 @@ The only requirement is a PC with Windows 10 and Internet connection in order to
- Once connected to WSL install the Python extension on the WSL side
## WSL Installation
## Setting up WSL / Linux
Open a WSL bash and update all software packets:
@@ -71,7 +71,7 @@ sudo apt-get install gettext
### Install Python
For AA we want to develop with Python 3.7, because that provides the maximum compatibility with today's AA installations.
Next we need to install Python and related development tools.
```eval_rst
.. hint::
@@ -80,7 +80,7 @@ For AA we want to develop with Python 3.7, because that provides the maximum com
```eval_rst
.. note::
Should your Ubuntu come with a newer version of Python we recommend to still setup your dev environment with the oldest Python 3 version supported by AA, e.g Python 3.7
Should your Ubuntu come with a newer version of Python we recommend to still setup your dev environment with the oldest Python 3 version currently supported by AA (e.g Python 3.8 at this time of writing) to ensure your apps are compatible with all current AA installations
You an check out this `page <https://askubuntu.com/questions/682869/how-do-i-install-a-different-python-version-using-apt-get/1195153>`_ on how to install additional Python versions on Ubuntu.
```
@@ -90,7 +90,19 @@ Use the following command to install Python 3 with all required libraries with t
sudo apt-get install python3 python3-dev python3-venv python3-setuptools python3-pip python-pip
```
### Installing the DBMS
### Install redis and other tools
```bash
sudo apt-get install unzip git redis-server curl libssl-dev libbz2-dev libffi-dev
```
Start redis
```bash
sudo redis-server --daemonize yes
```
## Installing the DBMS
Install MySQL and required libraries with the following command:
@@ -122,35 +134,22 @@ sudo mysql -u root
```
```sql
CREATE USER 'aa_dev'@'localhost' IDENTIFIED BY 'PASSWORD';
CREATE DATABASE aa_dev CHARACTER SET utf8mb4;
GRANT ALL PRIVILEGES ON aa_dev . * TO 'aa_dev'@'localhost';
CREATE DATABASE test_aa_dev CHARACTER SET utf8mb4;
GRANT ALL PRIVILEGES ON test_aa_dev . * TO 'aa_dev'@'localhost';
CREATE USER 'admin'@'localhost' IDENTIFIED BY 'YOUR-PASSWORD';
GRANT ALL PRIVILEGES ON * . * TO 'admin'@'localhost';
FLUSH PRIVILEGES;
exit;
```
Add timezone info to mysql
Add timezone info to mysql:
```bash
sudo mysql_tzinfo_to_sql /usr/share/zoneinfo | sudo mysql -u root mysql
```
### Install redis and other tools
```bash
sudo apt-get install unzip git redis-server curl libssl-dev libbz2-dev libffi-dev
```
Start redis
```bash
sudo redis-server --daemonize yes
```
```eval_rst
.. note::
WSL does not have an init.d service, so it will not automatically start your services such as MySQL and Redis when you boot your Windows machine. For convenience we recommend putting the commands for starting these services in a bash script. Here is an example:
If your WSL does not have an init.d service, it will not automatically start your services such as MySQL and Redis when you boot your Windows machine and you have to manually start them. For convenience we recommend putting these commands in a bash script. Here is an example:
::
@@ -159,7 +158,6 @@ sudo redis-server --daemonize yes
sudo service mysql start
sudo redis-server --daemonize yes
In addition it is possible to configure Windows to automatically start WSL services, but that procedure goes beyond the scopes of this guide.
```
### Setup dev folder on WSL
@@ -179,9 +177,14 @@ A good location for setting up this folder structure is your home folder or a su
Following this approach you can also setup additional AA projects, e.g. aa-dev-2, aa-dev-3 if needed.
Create the root folder aa-dev.
Create the root folder `aa-dev`.
### setup virtual Python environment for aa-dev
```eval_rst
.. hint::
The folders `venv` and `myauth` will be created automatically in later steps. Please do not create them manually as this would lead to errors.
```
### Setup virtual Python environment for aa-dev
Create the virtual environment. Run this in your aa-dev folder:
@@ -195,16 +198,15 @@ And activate your venv:
source venv/bin/activate
```
### install Python packages
### Install and update basic Python packages
```bash
pip install --upgrade pip
pip install wheel
pip install -U pip setuptools wheel
```
## Alliance Auth installation
## Installing Alliance Auth
## Install and create AA instance
### Install and create AA instance
```bash
pip install allianceauth
@@ -226,44 +228,55 @@ First you want to make sure exclude the venv folder from VSC as follows:
Open settings and go to Files:Exclude
Add pattern: `**/venv`
### Update settings
### Create EVE Online SSO App
Open the settings file with VSC. Its under `myauth/myauth/settings/local.py`
For the Eve Online related setup you need to create a SSO app on the developer site:
Make sure to have the settings of your Eve Online app ready.
- Create your Eve Online SSO App on the [Eve Online developer site](https://developers.eveonline.com/)
- Add all ESI scopes
- Set callback URL to: `http://127.0.0.1:8000/sso/callback`
Turn on DEBUG mode to ensure your static files get served by Django:
### Update Django settings
Open your local Django settings with VSC. The file is under `myauth/myauth/settings/local.py`
```eval_rst
.. hint::
There are two Django settings files: ``base.py`` and ``local.py``. The base settings file is controlled by the AA project and may change at any time. It is therefore recommended to only change the local settings file.
```
```python
DEBUG = True
```
Define URL and name of your site:
```python
SITE_URL = "http://127.0.0.1:8000"
...
SITE_NAME = "AA Dev"
```
Update name, user and password of your DATABASE configuration.
```python
DATABASES['default'] = {
'ENGINE': 'django.db.backends.mysql',
'NAME': 'aa_dev',
'USER': 'aa_dev',
'PASSWORD': 'PASSWORD',
'USER': 'admin',
'PASSWORD': 'YOUR-PASSWORD',
'HOST': '127.0.0.1',
'PORT': '3306',
'OPTIONS': {'charset': 'utf8mb4'},
"TEST": {"CHARSET": "utf8mb4"},
}
```
For the Eve Online related setup you need to create a SSO app on the developer site:
- Create your Eve Online SSO App on the [Eve Online developer site](https://developers.eveonline.com/)
- Add all ESI scopes
- Set callback URL to: `http://localhost:8000/sso/callback`
Then update local.py with your settings:
Add the credentials for your Eve Online SSO app as defined above:
```python
ESI_SSO_CLIENT_ID = 'YOUR-ID'
ESI_SSO_CLIENT_SECRET = 'YOUR_SECRET'
ESI_SSO_CALLBACK_URL = 'http://localhost:8000/sso/callback'
```
Disable email registration:
@@ -284,7 +297,7 @@ python manage.py migrate
We also need to create a superuser for our AA installation:
```bash
python /home/allianceserver/myauth/manage.py createsuperuser
python manage.py createsuperuser
```
## Running Alliance Auth
@@ -319,7 +332,7 @@ In addition you can start a celery worker instance for myauth. For development p
This can be done from the command line with the following command in the myauth folder (where manage.py is located):
```bash
celery -E -A myauth worker -l info -P solo
celery -A myauth worker -l info -P solo
```
Same as AA itself you can start Celery from any terminal session, from a terminal window within VSC or as a debug config in VSC (see chapter about debugging for details). For convenience we recommend starting Celery as debug config.
@@ -340,17 +353,19 @@ In VSC click on Debug / Add Configuration and choose "Django". Should Django not
The result should look something like this:
```python
```json
{
"name": "Python: Django",
"type": "python",
"request": "launch",
"program": "${workspaceFolder}/myauth/manage.py",
"cwd": "${workspaceFolder}/myauth",
"args": [
"runserver",
"--noreload"
],
"django": true
"django": true,
"justMyCode": true,
}
```
@@ -360,7 +375,7 @@ For celery we need another debug config, so that we can run it in parallel to ou
Here is an example debug config for Celery:
```javascript
```json
{
"name": "Python: Celery",
"type": "python",
@@ -386,16 +401,16 @@ Here is an example debug config for Celery:
Finally it makes sense to have a dedicated debug config for running unit tests. Here is an example config for running all tests of the app `example`.
```javascript
```json
{
"name": "Python: myauth unit tests",
"type": "python",
"request": "launch",
"program": "${workspaceFolder}/myauth/manage.py",
"cwd": "${workspaceFolder}/myauth",
"args": [
"test",
"--keepdb",
"--debug-mode",
"--failfast",
"example",
],
@@ -410,7 +425,7 @@ You can also specify to run just a part of your test suite down to a test method
Finally you may also want to have a debug config to debug a non-Django Python script:
```javascript
```json
{
"name": "Python: Current File",
"type": "python",
@@ -424,37 +439,31 @@ Finally you may also want to have a debug config to debug a non-Django Python sc
The following additional tools are very helpful when developing for AA with VS Code:
### Pylance
### VS Code extensions
Pylance is an extension that works alongside Python in Visual Studio Code to provide performant language support: [Pylance](https://marketplace.visualstudio.com/items?itemName=ms-python.vscode-pylance)
### Code Spell Checker
Typos in your user facing comments can be quite embarrassing. This spell checker helps you avoid them: [Code Spell Checker](https://marketplace.visualstudio.com/items?itemName=streetsidesoftware.code-spell-checker)
### markdownlint
Extension for Visual Studio Code - Markdown linting and style checking for Visual Studio Code: [markdownlint](https://marketplace.visualstudio.com/items?itemName=DavidAnson.vscode-markdownlint)
### GitLens
Extension for Visual Studio Code - Supercharge the Git capabilities built into Visual Studio Code: [GitLens](https://marketplace.visualstudio.com/items?itemName=eamodio.gitlens)
### RST preview
A VS Code extension to preview restructured text and provide syntax highlighting: [RST Preview](https://marketplace.visualstudio.com/items?itemName=tht13.rst-vscode)
### Django Template
#### Django Template
This extension adds language colorization support and user snippets for the Django template language to VS Code: [Django Template](https://marketplace.visualstudio.com/items?itemName=bibhasdn.django-html)
### DBeaver
#### Code Spell Checker
DBeaver is a free universal database tool and works with many different kinds of databases include MySQL. It can be installed on Windows 10 and will be able to help manage your MySQL databases running on WSL.
Typos in your user facing comments can be quite embarrassing. This spell checker helps you avoid them: [Code Spell Checker](https://marketplace.visualstudio.com/items?itemName=streetsidesoftware.code-spell-checker)
Install from here. [DBeaver](https://dbeaver.io/)
#### Git History
### django-extensions
Very helpful to visualize the change history and compare different branches. [Git History](https://marketplace.visualstudio.com/items?itemName=donjayamanne.githistory)
#### markdownlint
Extension for Visual Studio Code - Markdown linting and style checking for Visual Studio Code: [markdownlint](https://marketplace.visualstudio.com/items?itemName=DavidAnson.vscode-markdownlint)
#### Live Server
Live Server allows you to start a mini webserver for any file quickly. This can e.g. be useful for looking at changes to to Sphinx docs.: [Live Server](https://marketplace.visualstudio.com/items?itemName=ritwickdey.LiveServer)
### Django apps
#### Django Extensions
[django-extensions](https://django-extensions.readthedocs.io/en/latest/) is a swiss army knife for django developers with adds a lot of very useful features to your Django site. Here are a few highlights:
@@ -462,6 +471,20 @@ Install from here. [DBeaver](https://dbeaver.io/)
- graph_models - Creates a dependency graph of Django models. Visualizing a model dependency structure can be very useful for trying to understand how an existing Django app works, or e.g. how all the AA models work together.
- runserver_plus - The standard runserver stuff but with the Werkzeug debugger baked in. This is a must have for any serious debugging.
#### Django Debug Toolbar
The [Django Debug Toolbar](https://github.com/jazzband/django-debug-toolbar) is a configurable set of panels that display various debug information about the current request/response and when clicked, display more details about the panel's content.
E.g. this tool is invaluable to debug and fix performance issues with Django queries.
### Windows applications
#### DBeaver
DBeaver is a free universal database tool and works with many different kinds of databases include MySQL. It can be installed on Windows 10 and will be able to help manage your MySQL databases running on WSL.
Install from here. [DBeaver](https://dbeaver.io/)
## Adding apps for development
The idea behind the particular folder structure of aa-dev is to have each and every app in its own folder and git repo. To integrate them with the AA instance they need to be installed once using the -e option that enabled editing of the package. And then added to the INSTALLED_APPS settings.

View File

@@ -65,9 +65,9 @@ On the application summary page, press Create a Bot User.
Update your auth project's settings file with these pieces of information from the summary page:
- From the App Details panel, `DISCORD_APP_ID` is the Client/Application ID
- From the App Details panel, `DISCORD_APP_SECRET` is the Secret
- From the App Bot Users panel, `DISCORD_BOT_TOKEN` is the Token
- From the General Information panel, `DISCORD_APP_ID` is the Client/Application ID
- From the OAuth2 > General panel, `DISCORD_APP_SECRET` is the Client Secret
- From the Bot panel, `DISCORD_BOT_TOKEN` is the Token
### Preparing Auth

View File

@@ -26,9 +26,10 @@ To install on your favorite flavour of Linux, identify and install equivalent pa
### OS Maintenance
It is reccommended to ensure your OS is fully up to date before proceeding. We may also add Package Repositories here, used later in the documentation.
It is recommended to ensure your OS is fully up to date before proceeding. We may also add Package Repositories here, used later in the documentation.
Ubuntu 1804, 2004, 2204:
```bash
sudo apt-get update
```
@@ -41,7 +42,7 @@ sudo apt-get upgrade
sudo do-dist-upgrade
```
CentOS 7
CentOS 7:
```bash
yum install epel-release
@@ -51,7 +52,7 @@ yum install epel-release
sudo yum upgrade
```
CentOS Stream 8
CentOS Stream 8:
```bash
sudo dnf config-manager --set-enabled powertools
@@ -65,7 +66,7 @@ sudo dnf install epel-release epel-next-release
sudo yum upgrade
```
CentOS Stream 9
CentOS Stream 9:
```bash
sudo dnf config-manager --set-enabled crb
@@ -78,15 +79,12 @@ dnf install epel-release epel-next-release
```bash
sudo yum upgrade
```
### Python
Alliance Auth requires Python 3.8 or higher. Ensure it is installed on your server before proceeding.
Install Python 3.10 and related tools on your system.
Ubuntu 1804, 2004:
```eval_rst
.. note::
Ubuntu 2204 ships with Python 3.10 already
```
```bash
sudo add-apt-repository ppa:deadsnakes/ppa
@@ -100,13 +98,25 @@ sudo apt-get update
sudo apt-get install python3.10 python3.10-dev python3.10-venv
```
Ubuntu 2204:
```eval_rst
.. note::
Ubuntu 2204 ships with Python 3.10 already, but some important tools are missing in the default installation.
```
```bash
sudo apt-get install python3.10-dev python3.10-venv
```
CentOS 7:
We need to build Python from source
Centos Stream 8/9:
```eval_rst
.. note::
A Python 3.9 Package is available for Stream 8 and 9. You _may_ use this instead of building your own package. But our documentation will assume Python3.10 and you may need to substitute as neccessary
A Python 3.9 Package is available for Stream 8 and 9. You _may_ use this instead of building your own package. But our documentation will assume Python3.10 and you may need to substitute as necessary
sudo dnf install python39 python39-devel
```
@@ -137,29 +147,34 @@ cd Python-3.10.5/
```bash
sudo make altinstall
```
### Database
It's recommended to use a database service instead of SQLite. Many options are available, but this guide will use MariaDB.
```eval_rst
.. note::
Many Ubuntu distributions come with an older version of Maria DB, which is not compatible with **Alliance Auth**. You need Maria DB 10.3 or higher!
Ubuntu distributions prior to 20.04 come with an older version of Maria DB, which is not compatible with **Alliance Auth**. You need Maria DB 10.3 or higher!
For 20.04 we still recommend to install Maria DB from the link below in order to get the newest stable version.
For 22.04 we recommend installing from the default Ubuntu distro, since it comes with the newest stable version.
```
Ubuntu 1804, 2004, 2204:
Ubuntu 1804, 2004:
```eval_rst
.. warning::
Please follow these steps to update MariaDB
https://mariadb.org/download/?t=repo-config&d=20.04+%22focal%22&v=10.6&r_m=osuosl
```
Ubuntu 1804, 2004, 2204
```bash
apt-get install mariadb-server mariadb-client libmysqlclient-dev
sudo apt-get install mariadb-server mariadb-client libmysqlclient-dev
```
CentOS 7
CentOS 7:
```eval_rst
.. warning::
Please follow these steps to update MariaDB
@@ -170,11 +185,11 @@ CentOS 7
sudo yum install MariaDB-server MariaDB-client MariaDB-devel MariaDB-shared
```
CentOS Stream 8/9
CentOS Stream 8/9:
```eval_rst
.. note::
We reccomend using the built in AppStream, as they are maintained by CentOS. Currently an AppStream is not available for 10.6
We recommend using the built in AppStream, as they are maintained by CentOS. Currently an AppStream is not available for 10.6
```
```bash
@@ -188,6 +203,7 @@ sudo dnf install mariadb mariadb-server mariadb-devel
```bash
sudo systemctl enable mariadb
```
```bash
sudo systemctl start mariadb
```
@@ -202,11 +218,13 @@ sudo systemctl start mariadb
A few extra utilities are also required for installation of packages.
Ubuntu 1804, 2004, 2204:
```bash
sudo apt-get install unzip git redis-server curl libssl-dev libbz2-dev libffi-dev build-essential
```
CentOS 7:
```bash
sudo yum install gcc gcc-c++ unzip git redis curl bzip2-devel openssl-devel libffi-devel wget
```
@@ -220,6 +238,7 @@ sudo systemctl start redis.service
```
CentOS Stream 8, Stream 9:
```bash
sudo dnf install gcc gcc-c++ unzip git redis curl bzip2-devel openssl-devel libffi-devel wget
```
@@ -231,6 +250,7 @@ sudo systemctl enable redis.service
```bash
sudo systemctl start redis.service
```
## Database Setup
Alliance Auth needs a MySQL user account and database. Open an SQL shell with
@@ -277,11 +297,13 @@ mysql_secure_installation
For security and permissions, its highly recommended you create a separate user to install auth under. Do not log in as this account.
Ubuntu 1804, 2004, 2204:
```bash
adduser --disabled-login allianceserver
sudo adduser --disabled-login allianceserver
```
CentOS 7, Stream 8, Stream 9:
```bash
sudo useradd -s /bin/bash allianceserver
```
@@ -289,6 +311,7 @@ sudo useradd -s /bin/bash allianceserver
```bash
sudo passwd -l allianceserver
```
### Prepare Directories
```bash
@@ -308,6 +331,23 @@ sudo chown -R allianceserver:allianceserver /var/www/myauth/static/
### Virtual Environment
Switch to the allianceserver user.
```bash
sudo su allianceserver
```
And switch to it's home directory:
```bash
cd
```
```eval_rst
.. note::
In general using the allianceserver user will greatly simplify permission management, when installing and performing maintenance on Alliance Auth.
```
Create a Python virtual environment and put it somewhere convenient (e.g. `/home/allianceserver/venv/auth/`)
```eval_rst
@@ -346,16 +386,17 @@ As **callback URL** you want to define the URL of your Alliance Auth site plus t
### Alliance Auth Project
Update Pip before installing python packages:
```bash
pip install -U pip setuptools
```eval_rst
.. warning::
Before installing any Python packages please double-check that you have activated in the virtual environment. This is usually indicated by your command line in the terminal starting with: `(auth)`.
```
Ensure wheel is available before continuing:
#### Install Python packages
Update & install basic tools before installing further Python packages:
```bash
pip install wheel
pip install -U pip setuptools wheel
```
You can install **Alliance Auth** with the following command. This will install AA and all its Python dependencies.
@@ -370,7 +411,9 @@ You should also install Gunicorn now unless you want to use another WSGI server
pip install gunicorn
```
Now you need to create the application that will run the **Alliance Auth** install. Ensure you are in the allianceserver home directory by issuing:
#### Create Alliance Auth project
Now you need to create the Django project that will run **Alliance Auth**. Ensure you are in the allianceserver home directory by issuing:
```bash
cd /home/allianceserver
@@ -382,16 +425,25 @@ The following command bootstraps a Django project which will run your **Alliance
allianceauth start myauth
```
The settings file needs configuring, edit the template at `myauth/myauth/settings/local.py`.
#### Update settings
Your settings file needs configuring:
```bash
nano myauth/myauth/settings/local.py
```
**Be sure to configure:**
* Your site URL as `SITE_URL`
* The Database account setup earlier in **Database Setup**
* `ESI_SSO_CLIENT_ID`, `ESI_SSO_CLIENT_SECRET` from the EVE Online Developers Portal earlier in **Eve Online Settings**
* `ESI_USER_CONTACT_EMAIL` to an email address to ensure that CCP has reliable contact information for you
* Valid Email server settings.
Django needs to install models to the database before it can start.
- Your site URL as `SITE_URL`
- The database user account setup from earlier in [Database Setup](#database-setup)
- `ESI_SSO_CLIENT_ID`, `ESI_SSO_CLIENT_SECRET` from the EVE Online Developers Portal from earlier in [Eve Online SSO](#eve-online-sso)
- `ESI_USER_CONTACT_EMAIL` to an email address to ensure that CCP has reliable contact information for you
- Valid email server settings
#### Install database & static files
Django needs to setup the database before it can start.
```bash
python /home/allianceserver/myauth/manage.py migrate
@@ -400,7 +452,7 @@ python /home/allianceserver/myauth/manage.py migrate
Now we need to round up all the static files required to render templates. Make a directory to serve them from and populate it.
```bash
python /home/allianceserver/myauth/manage.py collectstatic
python /home/allianceserver/myauth/manage.py collectstatic --noinput
```
Check to ensure your settings are valid.
@@ -409,7 +461,6 @@ Check to ensure your settings are valid.
python /home/allianceserver/myauth/manage.py check
```
```eval_rst
.. hint::
If you are using root, ensure the allianceserver user has read/write permissions to this directory before proceeding::
@@ -417,17 +468,7 @@ python /home/allianceserver/myauth/manage.py check
chown -R allianceserver:allianceserver /home/allianceserver/myauth
```
## Services
Alliance Auth needs some additional services to run, which we will set up and configure next.
### Gunicorn
To run the **Alliance Auth** website a [WSGI Server](https://www.fullstackpython.com/wsgi-servers.html) is required. For this [Gunicorn](http://gunicorn.org/) is highly recommended for its ease of configuring. It can be manually run from within your `myauth` base directory with `gunicorn --bind 0.0.0.0 myauth.wsgi` or automatically run using Supervisor.
The default configuration is good enough for most installations. Additional information is available in the [gunicorn](gunicorn.md) doc.
## Superuser
#### Setup superuser
Before using your auth site, it is essential to create a superuser account. This account will have all permissions in Alliance Auth. It's OK to use this as your personal auth account.
@@ -439,6 +480,16 @@ Once your install is complete, the superuser account is accessed by logging in v
If you intend to use this account as your personal auth account you need to add a main character. Navigate to the normal user dashboard (at `https://example.com`) after logging in via the admin site and select `Change Main`. Once a main character has been added, it is possible to use SSO to login to this account.
## Services
Alliance Auth needs some additional services to run, which we will set up and configure next.
### Gunicorn
To run the **Alliance Auth** website a [WSGI Server](https://www.fullstackpython.com/wsgi-servers.html) is required. For this [Gunicorn](http://gunicorn.org/) is highly recommended for its ease of configuring. It can be manually run from within your `myauth` base directory with `gunicorn --bind 0.0.0.0 myauth.wsgi` or automatically run using Supervisor.
The default configuration is good enough for most installations. Additional information is available in the [gunicorn](gunicorn.md) doc.
### Supervisor
[Supervisor](http://supervisord.org/) is a process watchdog service: it makes sure other processes are started automatically and kept running. It can be used to automatically start the WSGI server and Celery workers for background tasks.
@@ -461,9 +512,11 @@ CentOS 7:
```bash
sudo dnf install supervisor
```
```bash
sudo systemctl enable supervisord.service
```
```bash
sudo systemctl start supervisord.service
```
@@ -473,9 +526,11 @@ CentOS Stream 8, Stream 9:
```bash
sudo dnf install supervisor
```
```bash
sudo systemctl enable supervisord.service
```
```bash
sudo systemctl start supervisord.service
```
@@ -491,21 +546,21 @@ ln -s /home/allianceserver/myauth/supervisor.conf /etc/supervisor/conf.d/myauth.
CentOS:
```bash
ln -s /home/allianceserver/myauth/supervisor.conf /etc/supervisord.d/myauth.ini
sudo ln -s /home/allianceserver/myauth/supervisor.conf /etc/supervisord.d/myauth.ini
```
Activate it with `supervisorctl reload`.
Activate it with `sudo 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.
You can check the status of the processes with `sudo supervisorctl status`. Logs from these processes are available in `/home/allianceserver/myauth/log` named by process.
```eval_rst
.. note::
Any time the code or your settings change you'll need to restart Gunicorn and Celery. ::
supervisorctl restart myauth:
sudo supervisorctl restart myauth:
```
## Webserver
## Web server
Once installed, decide on whether you're going to use [NGINX](nginx.md) or [Apache](apache.md) and follow the respective guide.
@@ -530,7 +585,7 @@ source /home/allianceserver/venv/auth/bin/activate
and update with:
```bash
pip install --upgrade allianceauth
pip install -U allianceauth
```
Some releases come with changes to the base settings. Update your project's settings with:
@@ -548,7 +603,7 @@ python /home/allianceserver/myauth/manage.py migrate
Finally, some releases come with new or changed static files. Run the following command to update your static files folder:
```bash
python /home/allianceserver/myauth/manage.py collectstatic
python /home/allianceserver/myauth/manage.py collectstatic --noinput
```
Always restart AA, Celery and Gunicorn after updating:

View File

@@ -13,4 +13,5 @@ In addition to main guide for installation Alliance Auth you also find guides fo
apache
gunicorn
upgrade_python
switch_to_non_root
```

View File

@@ -0,0 +1,68 @@
# Switch to non-root
If you followed the official installation guide for Alliance Auth (AA) pre AA 3.x you usually ended up with a "root installation". A root installation means that you have installed AA with the root user and now need to log in as root every time to perform maintenance for AA, e.g. updating existing apps.
Since working as root is [generally not recommended](https://askubuntu.com/questions/16178/why-is-it-bad-to-log-in-as-root), this guide explains how you can easily migrate your existing "root installation" to a "non-root installation".
## How to switch to non-root
We will change the setup so that you can use your `allianceserver` user to perform most maintenance operations. In addition, you also need a sudo user for invoking root privileges, e.g. when restarting the AA services.
The migration itself is rather straightforward. The main idea is to change ownership for all relevant directories and files to `allianceserver`.
First, log in as your sudo user and run the following commands in order:
```shell
# Set the right owner
sudo chown -R allianceserver: /home/allianceserver
sudo chown -R allianceserver: /var/www/myauth
# Remove static files, they will be re-added later
sudo rm -rf /var/www/mayauth/static/*
# Fix directory permissions
sudo chmod -R 755 /var/www/myauth
```
That's it. Your AA installation is now configured to be maintained with the `allianceserver` user.
## How to do maintenance with a non-root user
Here is how you can maintain your AA installation in the future:
First, log in with your sudo user.
Then, switch to the `allianceserver` user:
```shell
sudo su allianceserver
```
Go to your home folder and activate your venv:
```shell
cd ~
source venv/auth/bin/activate
```
Finally, switch to the main AA folder, from where you can run most commands directly:
```shell
cd myauth
```
Now it's time to re-add the static files with the right permissions. To do so simply
run:
```shell
python manage.py collectstatic
```
When you want to restart myauth, you need to switch back to your sudo user, because `allianceserver` does not have sudo privileges:
```shell
exit
sudo supervisorctl restart myauth:
```
Alternatively, you can open another terminal with your sudo user for restarting myauth. That has the added advantage that you can now continue working with both your allianceauth user and your sudo user for restarts at the same time.

View File

@@ -13,4 +13,5 @@ The official installation guide will install a stable version of Alliance Auth t
gunicorn
celery
redis
```

View File

@@ -0,0 +1,22 @@
# Redis
## Compression
Cache compression can help tame the memory usage of specialised installation configurations and Community Apps that heavily utilize Redis.
Various compression algorithms are supported, with various strengths. Our testing has shown that lzma works best with our use cases. You can read more at [Django-Redis Compression Support](https://github.com/jazzband/django-redis#compression-support)
Add the following lines to `local.py`
```python
import lzma
CACHES = {
"default": {
# ...
"OPTIONS": {
"COMPRESSOR": "django_redis.compressors.lzma.LzmaCompressor",
}
}
}
```

View File

@@ -5,11 +5,12 @@ recommonmark==0.7.1
Jinja2<3.1
docutils==0.16
sphinxcontrib-django2
sphinx-copybutton
# Autodoc dependencies
celery>=5.2.0,<6.0.0
celery_once>=3.0.1
django>=4.0.5,<5.0.0
django>=4.0.6,<4.1.0
django-bootstrap-form
django-celery-beat>=2.3.0
django-esi>=4.0.1

View File

@@ -17,9 +17,11 @@ classifiers =
Operating System :: POSIX :: Linux
Programming Language :: Python
Programming Language :: Python :: 3
Programming Language :: Python :: 3 :: Only
Programming Language :: Python :: 3.8
Programming Language :: Python :: 3.9
Programming Language :: Python :: 3.10
Programming Language :: Python :: 3.11
Topic :: Internet :: WWW/HTTP
Topic :: Internet :: WWW/HTTP :: Dynamic Content
home_page = https://gitlab.com/allianceauth/allianceauth
@@ -35,28 +37,28 @@ packages = find_namespace:
install_requires =
bcrypt
beautifulsoup4
celery>=5.2.0,<6.0.0
celery>=5.2.0,<6
celery-once>=3.0.1
django>=4.0.6,<5.0.0
django>=4.0.9,<4.1.0
django-bootstrap-form
django-celery-beat>=2.3.0
django-esi>=4.0.1
django-redis>=5.2.0,<6.0.0
django-redis>=5.2.0
django-registration>=3.3
django-sortedm2m
dnspython
mysqlclient>=2.1.0
openfire-restapi
packaging>=21.0,<22
packaging>=21.0
passlib
pydiscourse
python-slugify>=1.2
redis>=4.0.0,<5.0.0
requests>=2.9.1,<3.0.0
redis>=4.0.0
requests>=2.9.1
requests-oauthlib
semantic-version
slixmpp
python_requires = ~=3.8
python_requires = >=3.8
include_package_data = True
zip_safe = False

Some files were not shown because too many files have changed in this diff Show More