Alliance Auth app for managing and synchronizing EVE Online standings.
Project description
AA Standings Manager
Alliance Auth app for managing and synchronizing EVE Online standings across characters.
Version 0.0.1 - Initial release. Complete architectural rewrite with persistent standings database, request/approval workflow, and character-level synchronization.
Overview
AA Standings Manager is a comprehensive standings management system for Alliance Auth that enables organizations to:
- Manage a persistent database of approved standings (characters, corporations, alliances)
- Implement a request/approval workflow for new standings
- Automatically synchronize standings to member characters via ESI
- Track and audit all standings changes
- Support flexible organizational structures (alliances, coalitions, corporations)
This is a complete refactor that combines and improves upon features from:
- aa-standingssync by Erik Kalkoken
- aa-standingsrequests by colcrunch
Key Features
Persistent Standings Database
- Centralized Management: Single source of truth for all approved standings
- Entity Types: Support for characters, corporations, and alliances
- Flexible Standing Values: Configurable standing values (-10 to +10)
- Audit Trail: Complete history of all standings changes
Request/Approval Workflow
- User Requests: Users can request standings for their characters or corporations
- Approver Queue: Designated approvers review and process requests
- Validation: Automatic validation of ESI scopes and token coverage
- Revocations: Support for removing standings with approval workflow
Automated Synchronization
- Character-Level Sync: Each user's characters sync independently
- ESI Integration: Direct integration with EVE Online ESI API
- Contact Labels: Uses configurable contact labels for organization
- Automatic Updates: Periodic synchronization keeps contacts current
- Error Handling: Robust retry logic with exponential backoff
Flexible Configuration
- State-Based Scopes: Different ESI scope requirements per Auth state
- Configurable Labels: Set your organization's contact label name
- Sync Intervals: Control how often syncs occur
- Auto-Validation: Automatic removal of ineligible characters
Security & Permissions
- Three Permission Levels: Basic users, approvers, and administrators
- Token Validation: Ensures users own all characters in corporation requests
- Eligibility Checking: Automatic deactivation when users lose access
- Comprehensive Auditing: All actions logged with user attribution
How It Works
Architecture Overview
┌─────────────────────────────────────────────────────────────┐
│ Persistent Standings DB │
│ (Characters, Corporations, Alliances with Standing Values) │
└─────────────────────┬───────────────────────────────────────┘
│
▼
┌─────────────────────────────────────────────────────────────┐
│ Request/Approval Workflow │
│ User Requests → Approver Reviews → Standing Added/Removed │
└─────────────────────┬───────────────────────────────────────┘
│
▼
┌─────────────────────────────────────────────────────────────┐
│ Character Synchronization │
│ Each User's Characters Sync Standings to ESI Contacts │
└─────────────────────────────────────────────────────────────┘
Workflow Example
-
User Requests Standing
- User navigates to "Request Standings" page
- Selects their character or corporation
- System validates ESI scopes and ownership
- Request created in PENDING state
-
Approver Reviews Request
- Approver sees request in "Manage Requests" queue
- Reviews requester information and affiliations
- Approves or rejects the request
- On approval: Standing entry created in database
-
Automatic Synchronization
- All synced characters receive the update
- ESI API updates contact lists
- Contacts marked with organization label
- Users see updated standings in-game
-
Ongoing Management
- Users can request removal of standings (revocation)
- System automatically removes ineligible characters
- Audit log tracks all changes
- Periodic sync keeps everything current
Requirements
- Alliance Auth: v4.0.0 or higher
- Python: 3.11, 3.12, or 3.13
- ESI Scopes Required:
esi-characters.read_contacts.v1(read character contacts)esi-characters.write_contacts.v1(manage character contacts)- Additional scopes configurable per Auth state
Installation
1. Install the Package
pip install aa-standingsmanager
2. Add to Django Settings
Edit your Alliance Auth local.py settings file:
INSTALLED_APPS = [
# ... other apps ...
'standingsmanager',
]
3. Run Migrations
python manage.py migrate standingsmanager
4. Restart Services
# Restart Gunicorn/UWSGI
systemctl restart allianceauth
# Restart Celery workers
systemctl restart allianceauth-worker
systemctl restart allianceauth-beat
5. Configure Celery Beat (if not using systemd timers)
Add to your local.py:
# Standings Manager scheduled tasks
CELERYBEAT_SCHEDULE['standingsmanager_sync_all'] = {
'task': 'standingsmanager.tasks.run_regular_sync',
'schedule': crontab(minute='*/30'), # Every 30 minutes
}
CELERYBEAT_SCHEDULE['standingsmanager_validate_all'] = {
'task': 'standingsmanager.tasks.run_regular_validation',
'schedule': crontab(hour='*/6'), # Every 6 hours
}
6. Load Static Files
python manage.py collectstatic --noinput
Configuration
Required Settings
# Organization's contact label name (users create this in-game)
STANDINGS_LABEL_NAME = "MY_ORG" # Change to your org name
Optional Settings
# Sync interval in minutes (default: 30)
STANDINGS_SYNC_INTERVAL = 30
# Sync timeout in minutes (default: 180)
STANDINGS_SYNC_TIMEOUT = 180
# Default standing value for new standings (default: 5.0)
STANDINGS_DEFAULT_STANDING = 5.0
# Auto-validation interval in minutes (default: 360)
STANDINGS_AUTO_VALIDATE_INTERVAL = 360
# ESI scope requirements per Auth state (default: {})
STANDINGS_SCOPE_REQUIREMENTS = {
"Member": [], # No additional scopes for members
"Blue": ["esi-killmails.read_killmails.v1"], # Example: Blues need killmail access
}
Settings Validation
The app validates all settings on startup and will raise errors for invalid configurations:
STANDINGS_LABEL_NAMEmust be a non-empty stringSTANDINGS_SYNC_INTERVALmust be greater than 0STANDINGS_DEFAULT_STANDINGmust be between -10 and +10STANDINGS_SCOPE_REQUIREMENTSmust be a dictionary
Permissions
The app uses three permission levels:
| Permission | Code Name | Description |
|---|---|---|
| Basic User | standingsmanager.add_syncedcharacter |
Request standings, manage own synced characters |
| Approver | standingsmanager.approve_standings |
Approve/reject standing requests and revocations |
| Administrator | standingsmanager.manage_standings |
Full access to standings database via Django admin |
| Auditor | standingsmanager.view_auditlog |
View audit log (read-only) |
Granting Permissions
Via Django Admin:
- Go to Admin → Authentication and Authorization → Groups
- Select or create a group
- Add desired permissions
- Assign users to the group
Recommended Setup:
- All members:
add_syncedcharacter(basic access) - Directors/Leadership:
approve_standings(approval queue) - IT/Admin:
manage_standings(database management) - Compliance:
view_auditlog(audit access)
User Guide
Requesting Standings
-
Navigate to Standings Menu
- Click "Standings Sync" in Alliance Auth menu
- Select "Request Standings"
-
Select Character or Corporation
- Character requests: Click "Request Standing" next to your character
- Corporation requests: Ensure you have tokens for ALL characters in corp
-
Wait for Approval
- Your request appears in the approver queue
- You'll receive a notification when processed
-
Add Character to Sync
- Navigate to "My Synced Characters"
- Click "Add to Sync" for characters you want to sync
- Important: Create the contact label in-game first!
Creating Contact Label In-Game
CRITICAL STEP: Before adding characters to sync, create the contact label in EVE:
- Open your in-game "People & Places" window (Alt+E)
- Click the "Contacts" tab
- Right-click in the labels section → "Add Label"
- Enter the exact label name from settings (e.g., "MY_ORG")
- Click "OK"
Now you can add the character to sync in Alliance Auth.
Managing Your Standings
View Status:
- Green checkmark: Sync working correctly
- Orange warning: Needs attention (stale sync, missing label)
- Red X: Error (check error message)
Remove Standing:
- Go to "Request Standings"
- Click "Remove Standing" next to approved character/corp
- Approver must approve the revocation
Troubleshooting Sync:
- Verify contact label exists in-game (exact name match)
- Check ESI token is valid (re-add character if needed)
- Check "My Synced Characters" for error messages
- Contact your administrator if issues persist
Admin Guide
Approver Workflow
Managing Requests:
- Navigate to "Manage Requests"
- Review pending requests
- Check requester information
- Verify affiliations and scopes
- Review request age
- Click "Approve" or "Reject"
- System automatically triggers sync for all characters
Managing Revocations:
- Navigate to "Manage Revocations"
- Review pending revocation requests
- Approve to remove standing, Reject to keep it
- System syncs removal to all characters
Best Practices:
- Review requests promptly (check daily)
- Verify requester identity for high-value standings
- Use rejection notes to explain decisions
- Monitor auto-revocations (system-initiated)
Django Admin Functions
Standings Entry Management:
- View all approved standings
- Filter by entity type, standing value, date
- Manually add/edit/delete standings
- Bulk actions available
Request/Revocation Management:
- View all requests (pending, approved, rejected)
- Bulk approve/reject actions
- Read-only (use UI or actions for changes)
Synced Character Management:
- View all synced characters
- Check sync status (fresh, stale, errors)
- Force manual sync for troubleshooting
- Validate eligibility (removes ineligible)
Audit Log:
- View all actions (approvals, rejections, removals)
- Filter by action type, date, user
- Export to CSV for compliance
- Read-only (immutable log)
Troubleshooting
Common Issues
"Contact label not found"
- Cause: Character doesn't have the configured label in-game
- Fix: Create the label in EVE (see "Creating Contact Label In-Game" above)
"Missing required ESI scopes"
- Cause: Character token doesn't have required scopes
- Fix: Re-add character in Alliance Auth to grant scopes
"Token is invalid or expired"
- Cause: ESI token expired or revoked
- Fix: Re-authenticate character in Alliance Auth
"Sync is stale"
- Cause: Sync hasn't run recently (could be ESI issues)
- Fix: Check Celery workers are running, check ESI status
"Corporation request failed - missing tokens"
- Cause: Don't have tokens for all characters in corporation
- Fix: Add all your corp characters to Alliance Auth with required scopes
Checking System Health
Verify Celery is Running:
systemctl status allianceauth-worker
systemctl status allianceauth-beat
Check Task Logs:
# View Celery worker logs
journalctl -u allianceauth-worker -f
# Check for sync errors
grep "ERROR" /var/log/allianceauth/allianceauth.log | grep standingsmanager
Force Manual Sync (Admin):
- Go to Django Admin → Synced Characters
- Select character(s)
- Choose "Force sync selected characters"
- Click "Go"
Check ESI Status:
- Visit EVE Online ESI Status
- Check for ongoing outages or issues
FAQ
Q: What happened to alliance contact sync and war targets? A: Version 2.0 uses a persistent standings database instead of cloning alliance contacts. War targets feature has been removed. Each organization manages their own standings list.
Q: Can I migrate from version 1.x? A: Version 2.0 is a complete rewrite with a new database schema. See MIGRATION_GUIDE.md for migration instructions.
Q: Do all my characters need to be in the same alliance? A: No! This system works for any organizational structure. Characters just need appropriate permissions and ESI scopes.
Q: How often do contacts sync?
A: By default every 30 minutes. Configurable via STANDINGS_SYNC_INTERVAL setting.
Q: What happens if I lose alliance membership? A: The system automatically detects permission loss and removes your characters from sync. Your in-game contacts remain until manually deleted.
Q: Can I have personal contacts and org contacts? A: Yes! The system only manages contacts with your organization's label. Other contacts are untouched.
Q: How do I add a corporation standing? A: Request a corporation standing from the UI. You must have valid tokens for ALL characters in that corp you own in Alliance Auth.
Q: What standing value is used for synced contacts? A: The value in the standings database (default: +5.0, configurable per entry).
Q: Can I see who approved a standing?
A: Yes! Check the Audit Log (requires view_auditlog permission) or view standing details in admin.
Credits
Original Projects
AA-StandingsSync
- Author: Erik Kalkoken
- Repository: https://gitlab.com/ErikKalkoken/aa-standingssync
- Features Adapted:
- SyncedCharacter model concept
- ESI contact synchronization logic
- Contact label management
- Background task architecture
AA-StandingsRequests
- Repository: https://gitlab.com/colcrunch/standingsrequests
- Features Adapted:
- Request/approval workflow
- StandingRequest and StandingRevocation models
- Approver permission system
- Scope requirements per Auth state
- Audit logging
Key Innovations in Version 2.0
- Persistent Standings Database: Central standings management vs. cloning alliance contacts
- Character-Level Sync: Each user's characters sync independently vs. alliance manager approach
- Combined Workflows: Integrated request + sync in one application
- Configurable Labels: Support any organizational structure
- Enhanced Validation: Comprehensive scope and token validation
- Improved Error Handling: Retry logic with exponential backoff
Maintainer
- Current Maintainer: guarzo
- Repository: https://github.com/guarzo/aa-standingsmanager
Support
Getting Help
- Documentation: See docs in this repository
- Issues: Report bugs at https://github.com/guarzo/aa-standingsmanager/issues
- Discussions: Community discussions on GitHub
Contributing
Contributions welcome! Please:
- Fork the repository
- Create a feature branch
- Write tests for new features
- Submit a pull request
Security Issues
For security vulnerabilities, please email the maintainer directly rather than opening a public issue.
License
This project is licensed under the MIT License - see the LICENSE file for details.
Changelog
See CHANGELOG.md for version history and release notes.
Version: 0.0.1 Last Updated: 2025-11-16 Status: Initial Release
Project details
Release history Release notifications | RSS feed
Download files
Download the file for your platform. If you're not sure which to choose, learn more about installing packages.
Source Distribution
Built Distribution
Filter files by name, interpreter, ABI, and platform.
If you're not sure about the file name format, learn more about wheel file names.
Copy a direct link to the current filters
File details
Details for the file aa_standingsmanager-0.0.16.tar.gz.
File metadata
- Download URL: aa_standingsmanager-0.0.16.tar.gz
- Upload date:
- Size: 76.1 kB
- Tags: Source
- Uploaded using Trusted Publishing? Yes
- Uploaded via: twine/6.1.0 CPython/3.13.7
File hashes
| Algorithm | Hash digest | |
|---|---|---|
| SHA256 |
2c2fffa738bb69fa8f7f2fc817db6fa48b81b3d6ebfac975e02b6bf6f80cf091
|
|
| MD5 |
a5890c5cd22208d4b01608a63db3dc2e
|
|
| BLAKE2b-256 |
dd3abcd4ed615f8efe86c124b9a8130b6d80734e48e208540e3cfe73695fe4bf
|
Provenance
The following attestation bundles were made for aa_standingsmanager-0.0.16.tar.gz:
Publisher:
publish.yml on guarzo/aa-standingsmanager
-
Statement:
-
Statement type:
https://in-toto.io/Statement/v1 -
Predicate type:
https://docs.pypi.org/attestations/publish/v1 -
Subject name:
aa_standingsmanager-0.0.16.tar.gz -
Subject digest:
2c2fffa738bb69fa8f7f2fc817db6fa48b81b3d6ebfac975e02b6bf6f80cf091 - Sigstore transparency entry: 724374713
- Sigstore integration time:
-
Permalink:
guarzo/aa-standingsmanager@02bfd87e3b527397d41b79f1fd22d6dac6a6af12 -
Branch / Tag:
refs/heads/main - Owner: https://github.com/guarzo
-
Access:
public
-
Token Issuer:
https://token.actions.githubusercontent.com -
Runner Environment:
github-hosted -
Publication workflow:
publish.yml@02bfd87e3b527397d41b79f1fd22d6dac6a6af12 -
Trigger Event:
workflow_dispatch
-
Statement type:
File details
Details for the file aa_standingsmanager-0.0.16-py3-none-any.whl.
File metadata
- Download URL: aa_standingsmanager-0.0.16-py3-none-any.whl
- Upload date:
- Size: 80.5 kB
- Tags: Python 3
- Uploaded using Trusted Publishing? Yes
- Uploaded via: twine/6.1.0 CPython/3.13.7
File hashes
| Algorithm | Hash digest | |
|---|---|---|
| SHA256 |
81e902eeaf9e03d1b9adc1f73886a0f43636f19b7cbd1e1f2b33ee02c7dc4de4
|
|
| MD5 |
c29e840f128c915da514d59d833ec5c7
|
|
| BLAKE2b-256 |
eb4a141b03ee49cb36aa86ea3c2d8afe42bbcb9877d30c24c247ae5b03ed8a74
|
Provenance
The following attestation bundles were made for aa_standingsmanager-0.0.16-py3-none-any.whl:
Publisher:
publish.yml on guarzo/aa-standingsmanager
-
Statement:
-
Statement type:
https://in-toto.io/Statement/v1 -
Predicate type:
https://docs.pypi.org/attestations/publish/v1 -
Subject name:
aa_standingsmanager-0.0.16-py3-none-any.whl -
Subject digest:
81e902eeaf9e03d1b9adc1f73886a0f43636f19b7cbd1e1f2b33ee02c7dc4de4 - Sigstore transparency entry: 724374716
- Sigstore integration time:
-
Permalink:
guarzo/aa-standingsmanager@02bfd87e3b527397d41b79f1fd22d6dac6a6af12 -
Branch / Tag:
refs/heads/main - Owner: https://github.com/guarzo
-
Access:
public
-
Token Issuer:
https://token.actions.githubusercontent.com -
Runner Environment:
github-hosted -
Publication workflow:
publish.yml@02bfd87e3b527397d41b79f1fd22d6dac6a6af12 -
Trigger Event:
workflow_dispatch
-
Statement type: