
Alliance Auth के Discord एकीकरण के लिए समाधान लेखापरीक्षा: गिल्ड सदस्यों को ढूंढता है जो AA द्वारा प्रबंधित भूमिकाएँ धारण कर रहे हैं जो Auth ने कभी प्रदान नहीं कीं, और उन्हें एक ऑपरेटर-नियंत्रित नीति के तहत हटा देता है या निकाल देता है। स्टैंडअलोन सामुदायिक Django ऐप।
Alliance Auth के Discord एकीकरण के लिए सामंजस्य ऑडिट। कॉन्फ़िगर किए गए Discord गिल्ड में वास्तविक भूमिका असाइनमेंट की तुलना Alliance Auth (प्रति उपयोगकर्ता समूह + स्थिति) में व्यक्त स्थिति से करता है और उस अंतर को बंद करता है जिसके माध्यम से मॉडरेटर AA-नामित भूमिकाओं को उन उपयोगकर्ताओं को मैन्युअल रूप से असाइन कर सकते हैं जिनके बारे में AA को जानकारी नहीं है।
स्थिति: अल्फा (
0.1.x)। सार्वजनिक API और सेटिंग्स1.0से पहले बदल सकती हैं।
ऑडिट डिफ़ॉल्ट रूप से सुरक्षित है:
InitialAuditAcknowledgement (केवल व्यवस्थापक या शेल) की आवश्यकता होती है।report है — विनाशकारी क्रियाएं ऑप्ट-इन होती हैं।AuditRun, AuditFinding, AuditInvocation, ConfigChangeLog) प्रबंधक और इंस्टेंस स्तरों पर केवल-जोड़ हैं; बल्क update() / bulk_update() अवरुद्ध हैं।प्रत्येक गिल्ड सदस्य को एक श्रेणी में वर्गीकृत किया जाता है:
| श्रेणी | अर्थ |
|---|---|
unknown_guest | Discord सदस्य जिसके बारे में AA कुछ नहीं जानता |
linked_no_perm | पहचान AA को ज्ञात है लेकिन उसके पास discord.access_discord का अभाव है |
bot_filtered | कॉन्फ़िगर किया गया बॉट खाता — कभी कार्रवाई नहीं की जाती |
ऑपरेटर प्रत्येक श्रेणी को एक क्रिया से मैप करता है:
| क्रिया | व्यवहार |
|---|---|
report | निष्कर्ष रिकॉर्ड करें; Discord पक्ष में कोई बदलाव नहीं |
strip | AA-प्रबंधित भूमिकाएँ हटाएं |
strip_kick | AA-प्रबंधित भूमिकाएँ हटाएं, फिर गिल्ड से किक करें |
मैपिंग AA_DISCORD_AUDIT_POLICY सेटिंग है; प्रति-समूह और प्रति-स्थिति ओवरराइड प्रत्येक श्रेणी के अंदर स्थित होते हैं।
allianceauth.services.modules.discord) स्थापित और कॉन्फ़िगर किया गया (बॉट टोकन + गिल्ड)pip install aa-discord-audit
अपने Auth `local.py` में:```python
# `aa_discord_audit` must appear AFTER
# `allianceauth.services.modules.discord` so the discord module's
# models load first; `apps.ready()` raises `ImproperlyConfigured`
# otherwise.
INSTALLED_APPS += ["aa_discord_audit"]
MIDDLEWARE += [
"aa_discord_audit.current_user.CurrentUserMiddleware",
]
फिर माइग्रेशन चलाएँ:```sh python manage.py migrate aa_discord_audit
`CurrentUserMiddleware` अनिवार्य है — `apps.ready()` यदि यह गायब है तो `ImproperlyConfigured` उठाता है। यही है जो `ConfigChangeLog` सिग्नल हैंडलर को एडमिन संपादनों को एक वास्तविक उपयोगकर्ता को गुण देने की अनुमति देता है, न कि `<system>` को।
## त्वरित आरंभ
1. `aa_discord_audit.run_audit` को ऑडिट चलाने वाले ऑपरेटर भूमिका को प्रदान करें।
2. एक dry-run ऑडिट चलाएँ: ```sh
python manage.py audit_discord_roles --action report
InitialAuditAcknowledgement पंक्ति बनाएं, या
python manage.py audit_acknowledge_initial चलाएं। दोनों के लिए
aa_discord_audit.run_audit और
aa_discord_audit.acknowledge_initial_audit आवश्यक है।manage_* कोडनेम को विस्फोट त्रिज्या के अनुसार विभाजित किया गया है ताकि
manage_bot_account_uid वाला एक जूनियर ManagedRoleException को संपादित करके
ऑडिट को निष्क्रिय न कर सके।
सभी सेटिंग्स वैकल्पिक हैं। डिफ़ॉल्ट सुरक्षित हैं।```python
AA_DISCORD_AUDIT_POLICY = { "unknown_guest": "report", "linked_no_perm": "report", # "linked_no_perm": { # "default": "strip", # "by_state": {"Guest": "report"}, # "by_group": {"Directors": "report"}, # }, }
AA_DISCORD_AUDIT_NOTIFY_ADMINS = True
AA_DISCORD_AUDIT_WEBHOOK_URL = None
AA_DISCORD_AUDIT_BOT_UIDS = []
AA_DISCORD_AUDIT_AUTO_DISCOVER_BY_NICKNAME = False
AA_DISCORD_AUDIT_RUN_RETENTION_DAYS = 180 AA_DISCORD_AUDIT_RETENTION_OPT_OUT_ACKNOWLEDGED = False
AA_DISCORD_AUDIT_IDEMPOTENCY_KEY_TTL_DAYS = 0
AA_DISCORD_AUDIT_RUN_DEADLINE_MINUTES = 60
AA_DISCORD_AUDIT_RUN_RATE_LIMIT_PER_DAY = 5 AA_DISCORD_AUDIT_RUN_RATE_LIMIT_DISABLED = False
AA_DISCORD_AUDIT_WEBHOOK_TIMEOUT = 10 AA_DISCORD_AUDIT_WEBHOOK_MAX_RETRIES = 3
AA_DISCORD_AUDIT_USE_BULK_ROLE_STRIP = False
AA_DISCORD_AUDIT_BEAT_ALLOW_DESTRUCTIVE = False
AA_DISCORD_AUDIT_BEAT_MIN_INTERVAL_MINUTES = 0
AA_DISCORD_AUDIT_CLI_ACTOR = None
AA_DISCORD_AUDIT_PRESENCE_ENABLED = True
AA_DISCORD_AUDIT_PRESENCE_SAMPLE_INTERVAL_MINUTES = 10
AA_DISCORD_AUDIT_METRICS_MEMBERS_BY_GROUP = True
AA_DISCORD_AUDIT_METRICS_MEMBERS_BY_ROLE = False
## प्रबंधन कमांड्स
| कमांड | उद्देश्य |
|--------------------------|------------------------------------------------------------------|
| `audit_discord_roles` | प्राथमिक प्रवेश बिंदु। `--action {report,strip,strip_kick}`. |
| `audit_discord_roles --resume <run_id>` | किसी मौजूदा रन के PENDING निष्कर्षों को फिर से चलाएं। |
| `audit_discord_roles --abandon <run_id>` | फंसे हुए रन को ABANDONED के रूप में चिह्नित करें। |
| `audit_discord_roles --diff <run_id>` | वर्तमान स्थिति की तुलना किसी पुराने रन से करें। |
| `audit_discord_roles --explain <member_id>` | प्रति-सदस्य वर्गीकरण (केवल पढ़ने के लिए). |
| `audit_discord_roles --policy-preview <json>` | काल्पनिक नीति का अनुमान लगाएं. |
| `audit_discord_roles --from-fixture <path>` | JSON स्नैपशॉट के विरुद्ध पुनः चलाएं। |
| `audit_acknowledge_initial` | कंसोल से पहली रन ड्राई-रन लॉक को जारी करें। |
| `audit_benchmark` | कृत्रिम-लोड आकार निर्धारण बेंचमार्क (देखें [`docs/performance.md`](https://gitlab.com/eveo7/aa-discord-audit/-/blob/main/docs/performance.md)). |
| `prune_audit_runs` | प्रतिधारण छंटाई. |
| `audit_abandon_stuck_runs` | क्रैश हुए वर्कर द्वारा लीक किए गए फंसे हुए PENDING रनों को समेटें — उन्हें ABANDONED में फ्लिप करता है (रनबुक देखें; एक फंसा हुआ RUNNING रन `audit_discord_roles --abandon` का उपयोग करता है). |
एक लंबे समय तक चलने वाला ``audit_discord_roles`` ``SIGTERM`` और ``SIGINT`` पर साफ-सुथरा प्रतिक्रिया करता है: रन को ``INTERRUPTED`` में बदल दिया जाता है और एप्लाई लूप अगली फाइंडिंग सीमा पर बाहर निकल जाता है ताकि आंशिक कार्य ऑडिट ट्रेल में स्थायी रहे। ``audit_discord_roles --resume <run_id>`` बचे हुए ``PENDING`` निष्कर्षों से रन को उठाता है।
## आवधिक ऑडिट (Celery beat)
`audit_orphan_members` उसी बिल्ड + एप्लाई पाइपलाइन को एक शेड्यूल पर चलाता है जिसे आप Celery beat में वायर करते हैं (यह डिफ़ॉल्ट रूप से शेड्यूल नहीं है)। बिना पर्यवेक्षण वाला पथ सुरक्षा के लिए गेटेड है:
- **केवल-रिपोर्ट जब तक सशस्त्र न हो।** एक बीट रन को नीति के बावजूद `report` में बदलने के लिए मजबूर किया जाता है, जब तक कि `AA_DISCORD_AUDIT_BEAT_ALLOW_DESTRUCTIVE` सेट न हो — मैन्युअल CLI रन के लिए एक-शॉट पहली-रन लॉक को जारी करना बीट को सशस्त्र नहीं करता है। बूट-टाइम चेतावनी तब फायर होती है जब नीति विनाशकारी होती है लेकिन बीट ऑप्ट-इन नहीं है।
- **जिम्मेदारी।** प्रत्येक बीट रन एक स्वीकृत सिस्टम-एक्टर `AuditInvocation` (`triggered_by=BEAT`) लिखता है, ताकि ऑडिट-द-ऑडिटर ट्रेल बिना पर्यवेक्षण वाले रनों को भी कवर करे।
- **स्व-उपचार।** सॉफ्ट-टाइम-लिमिट हिट या वर्कर क्रैश द्वारा फंसा हुआ एक रन अगले टिक पर पुनः प्रारंभ करने योग्य `INTERRUPTED` स्थिति में समेट दिया जाता है। `AA_DISCORD_AUDIT_BEAT_MIN_INTERVAL_MINUTES` एक गलत कॉन्फ़िगर की गई तेज़ शेड्यूल के खिलाफ एक मोटा फ़्लोर है।
## Celery कार्य
पैकेज `aa_discord_audit.*` नाम उपसर्ग के अंतर्गत पाँच कार्य पंजीकृत करता है। केवल बीट कार्यों को एक शेड्यूल की आवश्यकता होती है; बाकी इवेंट-ड्रिवन या ऑन-डिमांड चलते हैं। आपके लिए कोई भी शेड्यूल नहीं है।
| कार्य | यह कैसे चलता है | यह क्या करता है |
|------|-------------|--------------|
| `aa_discord_audit.audit_orphan_members` | Celery beat — आप इसे शेड्यूल करते हैं | ऊपर वर्णित बिना पर्यवेक्षण वाला build + apply ऑडिट। जब तक सशस्त्र न हो तब तक केवल-रिपोर्ट; AA के `update_groups` के साथ `discord.user_actions.<uid>` लॉक साझा करता है। |
| `aa_discord_audit.retry_pending_kicks` | Celery beat — आप इसे शेड्यूल करते हैं | एक सीमित स्वीप जो एक क्षणिक Discord विफलता द्वारा स्थगित किक को पुनः भेजता है, प्रति-पंक्ति कूलडाउन का सम्मान करता है ताकि एक कठिन-विफल सदस्य को बार-बार न मारा जाए। |
| `aa_discord_audit.process_pending_run` | इवेंट-ड्रिवन — एक वेब लॉन्च द्वारा एनक्यू किया गया | `PENDING` रन को उठाता है जो एक वेब लॉन्च ने बनाया, इसे `RUNNING` में बदलता है, और रन के जमे हुए कन्फर्मेशन फ्लैग के विरुद्ध पाइपलाइन चलाता है। |
| `aa_discord_audit.prune_audit_runs` | Celery beat / cron — आप इसे शेड्यूल करते हैं (एक प्रबंधन कमांड भी) | प्रतिधारण: आइडेम्पोटेंसी-की समाप्ति फिर पंक्ति हटाना (देखें **प्रबंधन कमांड्स** और रनबुक). |
| `aa_discord_audit.sample_guild_presence` | Celery beat — आप इसे शेड्यूल करते हैं | हल्का, केवल-REST नमूना जो गिल्ड सदस्य/ऑनलाइन/बूस्ट गणनाओं को Prometheus उपस्थिति गेज के लिए नवीनतम-केवल उपस्थिति स्नैपशॉट में डालता है। `AA_DISCORD_AUDIT_PRESENCE_ENABLED` पर गेटेड; एक स्किप-गार्ड गलत कॉन्फ़िगर की गई तेज़ शेड्यूल को बाउंड करता है (फ़्लोर `AA_DISCORD_AUDIT_PRESENCE_SAMPLE_INTERVAL_MINUTES`, डिफ़ॉल्ट 10)। तब तक निष्क्रिय जब तक `[metrics]` एक्स्ट्रा और एक बीट एंट्री दोनों मौजूद न हों (देखें [`docs/METRICS.md`](https://gitlab.com/eveo7/aa-discord-audit/-/blob/main/docs/METRICS.md)). |
बीट कार्यों को शेड्यूल करने के लिए, अपने `local.py` में `CELERYBEAT_SCHEDULE` में उन्हें जोड़ें, उदाहरण के लिए:```python
CELERYBEAT_SCHEDULE["aa_discord_audit_sample_guild_presence"] = {
"task": "aa_discord_audit.sample_guild_presence",
"schedule": 600, # seconds; honoured no finer than the sampler floor
}
Auth मुख्य नेविगेशन में Discord Audit के रूप में माउंट किया गया है। केवल-पढ़ने वाले दृश्य; प्रत्येक सूची में एक सर्वर-साइड खोज बॉक्स होता है जो हर पंक्ति में मिलान करता है — न केवल दृश्य में पृष्ठ — इसके ड्रॉपडाउन फ़िल्टर के साथ:
ProtectedDiscordMember, पहली-रन लॉक) ने परिणाम तय किया।aa_discord_audit.run_audit अनुमति वाले ऑपरेटर ऑडिट रन पृष्ठ पर लॉन्च ऑडिट बटन देखते हैं। इसे क्लिक करने से एक Bootstrap मोडल खुलता है जो कॉन्फ़िगर की गई नीति मोड (रिपोर्ट-ओनली या विनाशकारी), प्रारंभिक-स्वीकृति स्थिति, और एक कन्फर्म लॉन्च बटन को सतह पर लाता है। सबमिट करना /run-launch/ पर POST करता है, जो एक PENDING AuditRun बनाता है, Celery के माध्यम से process_pending_run को कतारबद्ध करता है, और रन-डिटेल पृष्ठ पर रीडायरेक्ट करता है।
वेब पथ CLI के सुरक्षा द्वार को दर्शाता है:
audit_acknowledge_initial चलाया नहीं गया है, मोडल एक अस्वीकृति ब्लॉक (कोई सबमिट बटन नहीं) दिखाता है कन्फर्म लॉन्च क्रिया के बजाय। एक POST जो मोडल को बायपास करता है (जैसे curl) सर्वर-साइड पर अस्वीकार कर दिया जाता है, अस्वीकृति AuditInvocation में दर्ज की जाती है, और ऑपरेटर को एक फ्लैश संदेश के साथ रीडायरेक्ट किया जाता है।was_confirmation_bypassed = user.has_perm(run_audit_destructive) and policy_has_destructive(policy)। UI में कोई टॉगल नहीं है — विनाशकारी अनुमति अकेले इरादा निर्धारित करती है। एक run_audit-केवल ऑपरेटर जो एक विनाशकारी नीति के खिलाफ एक लॉन्च ट्रिगर करता है, उसे एक मौन REPORT-केवल रन मिलता है (वही जबरदस्ती CLI बिना --yes के लागू करती है)।जब कोई रन गैर-टर्मिनल स्थिति (PENDING, RUNNING, या INTERRUPTED) में होता है, रन-डिटेल पृष्ठ हर पांच सेकंड में /runs/<pk>/state.json को पोल करता है और स्टेट कार्ड को अपडेट करता है। पोलिंग छिपे हुए टैब पर रुकती है और रन के टर्मिनल स्थिति तक पहुंचते ही बंद हो जाती है।
[metrics] एक्सट्रा के पीछे वैकल्पिक Prometheus इंस्ट्रूमेंटेशन — अनुपस्थित होने पर, प्रत्येक मीट्रिक कॉल लगभग-शून्य लागत पर एक नो-ऑप स्टब में हल हो जाती है। मॉड्यूल एक सहयोग-निर्भर-न-करें परत प्रदान करता है: जब django-prometheus स्थापित होता है तो ऑडिट के काउंटर और हिस्टोग्राम डिफ़ॉल्ट prometheus_client.REGISTRY में पंजीकृत हो जाते हैं और django-prometheus' /metrics दृश्य उन्हें अपनी श्रृंखला के साथ निर्यात करता है।```sh
pip install aa-discord-audit[metrics]
स्नैपशॉट गेज — गिल्ड उपस्थिति और प्रति-समूह / प्रति-भूमिका सदस्यता समुच्चय — एक दूसरा पथ लेते हैं: वे एक समर्पित रजिस्ट्री में रहते हैं जो मॉड्यूल के स्वयं के `/audit/discord/metrics` एंडपॉइंट द्वारा निर्यात की जाती है। django-prometheus का मल्टीप्रोसेस कलेक्टर केवल mmap फ़ाइलें पढ़ता है और कस्टम कलेक्टरों को छोड़ देता है, इसलिए इन गेजों को अपने स्वयं के स्क्रेप टार्गेट की आवश्यकता होती है। किसी भी `/metrics` टार्गेट की तरह यह अप्रमाणित है — इसे रिवर्स-प्रॉक्सी या नेटवर्क लेयर पर प्रतिबंधित करें। `[metrics]` एक्स्ट्रा के बिना दोनों सतहें निष्क्रिय रहती हैं।
मीट्रिक कैटलॉग, लेबल शब्दावली, और Grafana रेसिपीज़ यहाँ मौजूद हैं:
[`docs/METRICS.md`](https://gitlab.com/eveo7/aa-discord-audit/-/blob/main/docs/METRICS.md)
(रूसी अनुवाद:
[`docs/METRICS.ru.md`](https://gitlab.com/eveo7/aa-discord-audit/-/blob/main/docs/METRICS.ru.md))।
## सीमाएँ
- **एकल गिल्ड।** ऑडिट एक Discord गिल्ड के साथ मेल खाता है जिसके विरुद्ध AA कॉन्फ़िगर किया गया है; यह कई गिल्डों में विस्तारित नहीं होता।
- **केवल AA-प्रबंधित भूमिकाएँ।** Strip/kick केवल AA-नामित भूमिकाओं और गिल्ड सदस्यता पर कार्य करते हैं; AA जिन भूमिकाओं का प्रबंधन नहीं करता, उन्हें कभी नहीं छुआ जाता।
- **कोई उपनाम स्वतः-खोज नहीं।** बॉट खातों को केवल स्पष्ट `BotAccountUid` तालिका / `AA_DISCORD_AUDIT_BOT_UIDS` के माध्यम से पहचाना जाता है — `AA_DISCORD_AUDIT_AUTO_DISCOVER_BY_NICKNAME` v2 के लिए आरक्षित है और लागू नहीं किया गया है।
- **अल्फा सतह।** सेटिंग्स के नाम और सार्वजनिक API `1.0` से पहले बदल सकते हैं।
## दस्तावेज़ीकरण
- [`docs/runbook.md`](https://gitlab.com/eveo7/aa-discord-audit/-/blob/main/docs/runbook.md) — ऑपरेटर रनबुक: बॉट Discord अनुमतियाँ, प्री-फ़्लाइट चेकलिस्ट, फ़र्स्ट-रन लॉक जारी करना, घटना प्लेबुक, डायग्नोस्टिक टॉगल।
- [`docs/performance.md`](https://gitlab.com/eveo7/aa-discord-audit/-/blob/main/docs/performance.md) — `audit_benchmark` संदर्भ संख्याएँ और आकार निहितार्थ।
- [`docs/METRICS.md`](https://gitlab.com/eveo7/aa-discord-audit/-/blob/main/docs/METRICS.md) / [`docs/METRICS.ru.md`](https://gitlab.com/eveo7/aa-discord-audit/-/blob/main/docs/METRICS.ru.md) — Prometheus मीट्रिक कैटलॉग, लेबल शब्दावली, Grafana रेसिपीज़।
- स्रोत कोड: <https://gitlab.com/eveo7/aa-discord-audit>
- मुद्दा ट्रैकर: <https://gitlab.com/eveo7/aa-discord-audit/-/issues>
- परिवर्तन लॉग:
[`CHANGELOG.md`](https://gitlab.com/eveo7/aa-discord-audit/-/blob/main/CHANGELOG.md)
## विकास```sh
make dev # uv sync --all-groups + pre-commit install
make tests # uv run nox -s tests
make lint # uv run nox -s lint
make typecheck # mypy + basedpyright
make coverage # term + html + xml report
make package # uv build
Toolchain uv-ही है। लाइन की लंबाई 79 (Python) / 120 (Markdown) है।
MIT — LICENSE देखें।
| कोडनेम | गेट्स |
|---|
aa_discord_audit.run_audit | प्रबंधन कमांड, बीट कार्य, डिलीट चलाएं |
aa_discord_audit.run_audit_destructive | strip / strip_kick के लिए वेब-लॉन्च गेट (run_audit से अलग) |
aa_discord_audit.acknowledge_initial_audit | पहली बार चलने वाले ड्राई-रन ताले (lock) को हटाएं |
aa_discord_audit.manage_discord_identity | DiscordIdentity व्यवस्थापक |
aa_discord_audit.manage_role_exception | ManagedRoleException व्यवस्थापक |
aa_discord_audit.manage_protected_member | ProtectedDiscordMember व्यवस्थापक |
aa_discord_audit.manage_bot_account_uid | BotAccountUid व्यवस्थापक |
aa_discord_audit.manage_finding_override | FindingActionOverride व्यवस्थापक |
aa_discord_audit.view_auditrun (and friends) | Auth डैशबोर्ड में केवल-पढ़ने योग्य ऑडिट-ट्रेल |