mirror of
https://gitlab.com/allianceauth/allianceauth.git
synced 2025-07-09 20:40:17 +02:00
Bulk of the profile work is done.
This commit is contained in:
parent
bb87fdd958
commit
e15d79b834
@ -35,7 +35,7 @@ BASE_DIR = os.path.dirname(os.path.dirname(os.path.abspath(__file__)))
|
|||||||
SECRET_KEY = ''
|
SECRET_KEY = ''
|
||||||
|
|
||||||
# SECURITY WARNING: don't run with debug turned on in production!
|
# SECURITY WARNING: don't run with debug turned on in production!
|
||||||
DEBUG = 'True' == os.environ.get('AA_DEBUG','True')
|
DEBUG = True
|
||||||
|
|
||||||
ALLOWED_HOSTS = []
|
ALLOWED_HOSTS = []
|
||||||
|
|
||||||
@ -144,22 +144,13 @@ DATABASES = {
|
|||||||
'default': {
|
'default': {
|
||||||
'ENGINE': 'django.db.backends.mysql',
|
'ENGINE': 'django.db.backends.mysql',
|
||||||
'NAME': 'alliance_auth',
|
'NAME': 'alliance_auth',
|
||||||
'USER': os.environ.get('AA_DB_DEFAULT_USER', 'allianceserver'),
|
'USER': 'allianceserver',
|
||||||
'PASSWORD': os.environ.get('AA_DB_DEFAULT_PASSWORD', 'password'),
|
'PASSWORD': '',
|
||||||
'HOST': os.environ.get('AA_DB_DEFAULT_HOST', '127.0.0.1'),
|
'HOST': '127.0.0.1',
|
||||||
'PORT': os.environ.get('AA_DB_DEFAULT_PORT', '3306'),
|
'PORT': '3306',
|
||||||
},
|
},
|
||||||
}
|
}
|
||||||
|
|
||||||
# If you have run the authentication.0013_service_modules migration
|
|
||||||
# you will need to set this to True in order to install service modules
|
|
||||||
# which were involved in that migration after it has been run.
|
|
||||||
# If you are on a fresh install with no existing database you can safely
|
|
||||||
# set this to True
|
|
||||||
# If you have not run the authentication.0013_service_modules migration
|
|
||||||
# leave this set to False.
|
|
||||||
SERVICES_MIGRATED = False
|
|
||||||
|
|
||||||
# Password validation
|
# Password validation
|
||||||
# https://docs.djangoproject.com/en/1.10/ref/settings/#auth-password-validators
|
# https://docs.djangoproject.com/en/1.10/ref/settings/#auth-password-validators
|
||||||
|
|
||||||
@ -178,16 +169,15 @@ AUTH_PASSWORD_VALIDATORS = [
|
|||||||
},
|
},
|
||||||
]
|
]
|
||||||
|
|
||||||
|
AUTHENTICATION_BACKENDS = ['authentication.backends.StateBackend', 'authentication.backends.ModelBackend']
|
||||||
LOGIN_URL = 'auth_login_user'
|
LOGIN_URL = 'auth_login_user'
|
||||||
|
|
||||||
SUPERUSER_STATE_BYPASS = 'True' == os.environ.get('AA_SUPERUSER_STATE_BYPASS', 'True')
|
|
||||||
|
|
||||||
# Internationalization
|
# Internationalization
|
||||||
# https://docs.djangoproject.com/en/1.10/topics/i18n/
|
# https://docs.djangoproject.com/en/1.10/topics/i18n/
|
||||||
|
|
||||||
LANGUAGE_CODE = os.environ.get('AA_LANGUAGE_CODE', 'en-us')
|
LANGUAGE_CODE = 'en-us'
|
||||||
|
|
||||||
TIME_ZONE = os.environ.get('AA_TIME_ZONE', 'UTC')
|
TIME_ZONE = 'UTC'
|
||||||
|
|
||||||
USE_I18N = True
|
USE_I18N = True
|
||||||
|
|
||||||
@ -227,35 +217,27 @@ CACHES = {
|
|||||||
##
|
##
|
||||||
#####################################################
|
#####################################################
|
||||||
|
|
||||||
|
####################
|
||||||
|
# SITE_NAME - Name of the auth site.
|
||||||
|
####################
|
||||||
|
SITE_NAME = 'Alliance Auth'
|
||||||
|
|
||||||
#################
|
#################
|
||||||
# EMAIL SETTINGS
|
# EMAIL SETTINGS
|
||||||
#################
|
#################
|
||||||
# DOMAIN - The alliance auth domain_url
|
# DOMAIN - The Alliance Auth domain (or subdomain) address, starting with http://
|
||||||
# EMAIL_HOST - SMTP Server URL
|
# EMAIL_HOST - SMTP Server URL
|
||||||
# EMAIL_PORT - SMTP Server PORT
|
# EMAIL_PORT - SMTP Server PORT
|
||||||
# EMAIL_HOST_USER - Email Username (for gmail, the entire address)
|
# EMAIL_HOST_USER - Email Username (for gmail, the entire address)
|
||||||
# EMAIL_HOST_PASSWORD - Email Password
|
# EMAIL_HOST_PASSWORD - Email Password
|
||||||
# EMAIL_USE_TLS - Set to use TLS encryption
|
# EMAIL_USE_TLS - Set to use TLS encryption
|
||||||
#################
|
#################
|
||||||
DOMAIN = os.environ.get('AA_DOMAIN', 'https://example.com')
|
DOMAIN = 'https://example.com'
|
||||||
EMAIL_HOST = os.environ.get('AA_EMAIL_HOST', 'smtp.gmail.com')
|
EMAIL_HOST = 'smtp.gmail.com'
|
||||||
EMAIL_PORT = int(os.environ.get('AA_EMAIL_PORT', '587'))
|
EMAIL_PORT = 587
|
||||||
EMAIL_HOST_USER = os.environ.get('AA_EMAIL_HOST_USER', '')
|
EMAIL_HOST_USER = ''
|
||||||
EMAIL_HOST_PASSWORD = os.environ.get('AA_EMAIL_HOST_PASSWORD', '')
|
EMAIL_HOST_PASSWORD = ''
|
||||||
EMAIL_USE_TLS = 'True' == os.environ.get('AA_EMAIL_USE_TLS', 'True')
|
EMAIL_USE_TLS = True
|
||||||
|
|
||||||
####################
|
|
||||||
# Front Page Links
|
|
||||||
####################
|
|
||||||
# KILLBOARD_URL - URL for your killboard. Blank to hide link
|
|
||||||
# MEDIA_URL - URL for your media page (youtube etc). Blank to hide link
|
|
||||||
# FORUM_URL - URL for your forums. Blank to hide link
|
|
||||||
# SITE_NAME - Name of the auth site.
|
|
||||||
####################
|
|
||||||
KILLBOARD_URL = os.environ.get('AA_KILLBOARD_URL', '')
|
|
||||||
EXTERNAL_MEDIA_URL = os.environ.get('AA_EXTERNAL_MEDIA_URL', '')
|
|
||||||
FORUM_URL = os.environ.get('AA_FORUM_URL', '')
|
|
||||||
SITE_NAME = os.environ.get('AA_SITE_NAME', 'Alliance Auth')
|
|
||||||
|
|
||||||
###################
|
###################
|
||||||
# SSO Settings
|
# SSO Settings
|
||||||
@ -264,174 +246,100 @@ SITE_NAME = os.environ.get('AA_SITE_NAME', 'Alliance Auth')
|
|||||||
# https://developers.eveonline.com/
|
# https://developers.eveonline.com/
|
||||||
# Callback URL should be https://example.com/sso/callback
|
# Callback URL should be https://example.com/sso/callback
|
||||||
###################
|
###################
|
||||||
ESI_SSO_CLIENT_ID = os.environ.get('AA_ESI_SSO_CLIENT_ID', '')
|
ESI_SSO_CLIENT_ID = ''
|
||||||
ESI_SSO_CLIENT_SECRET = os.environ.get('AA_ESI_SSO_CLIENT_SECRET', '')
|
ESI_SSO_CLIENT_SECRET = ''
|
||||||
ESI_SSO_CALLBACK_URL = os.environ.get('AA_ESI_SSO_CALLBACK_URL', '')
|
ESI_SSO_CALLBACK_URL = ''
|
||||||
|
|
||||||
#########################
|
#################
|
||||||
# Default Group Settings
|
# Login Settings
|
||||||
#########################
|
#################
|
||||||
# DEFAULT_AUTH_GROUP - Default group members are put in
|
# Both of these redirects accept values as per the django redirect shortcut
|
||||||
# DEFAULT_BLUE_GROUP - Default group for blue members
|
# https://docs.djangoproject.com/en/1.10/topics/http/shortcuts/#redirect
|
||||||
# MEMBER_CORP_GROUPS - Assign members to a group representing their main corp
|
# - url names eg 'authentication:dashboard'
|
||||||
# BLUE_CORP_GROUPS - Assign blues to a group representing their main corp
|
# - relative urls eg '/dashboard'
|
||||||
#########################
|
# - absolute urls eg 'http://example.com/dashboard'
|
||||||
DEFAULT_AUTH_GROUP = os.environ.get('AA_DEFAULT_ALLIANCE_GROUP', 'Member')
|
# LOGIN_REDIRECT_URL - default destination when logging in if no redirect specified
|
||||||
DEFAULT_BLUE_GROUP = os.environ.get('AA_DEFAULT_BLUE_GROUP', 'Blue')
|
# LOGOUT_REDIRECT_URL - destination after logging out
|
||||||
MEMBER_CORP_GROUPS = 'True' == os.environ.get('AA_MEMBER_CORP_GROUPS', 'True')
|
# LOGIN_TOKEN_SCOPES - scopes required on new tokens when logging in. Cannot be blank.
|
||||||
MEMBER_ALLIANCE_GROUPS = 'True' == os.environ.get('AA_MEMBER_ALLIANCE_GROUPS', 'False')
|
##################
|
||||||
BLUE_CORP_GROUPS = 'True' == os.environ.get('AA_BLUE_CORP_GROUPS', 'False')
|
LOGIN_REDIRECT_URL = 'authentication:dashboard'
|
||||||
BLUE_ALLIANCE_GROUPS = 'True' == os.environ.get('AA_BLUE_ALLIANCE_GROUPS', 'False')
|
LOGOUT_REDIRECT_URL = 'authentication:dashboard'
|
||||||
|
LOGIN_TOKEN_SCOPES = ['esi-characters.read_opportunities.v1']
|
||||||
#########################
|
|
||||||
# Tenant Configuration
|
|
||||||
#########################
|
|
||||||
# CORP_IDS - A list of corporation IDs to treat as members.
|
|
||||||
# ALLIANCE_IDS - A list of alliance IDs to treat as members.
|
|
||||||
# Any corps in a specified alliance will be treated as members, so do not include them in CORP_IDS
|
|
||||||
#########################
|
|
||||||
CORP_IDS = []
|
|
||||||
ALLIANCE_IDS = []
|
|
||||||
|
|
||||||
#########################
|
|
||||||
# Standings Configuration
|
|
||||||
#########################
|
|
||||||
# Add a corp API key to add blue standings to grant access.
|
|
||||||
# CORP_API_ID - Set this to the api id for the corp API key
|
|
||||||
# CORP_API_VCODE - Set this to the api vcode for the corp API key
|
|
||||||
# BLUE_STANDING - The lowest standings value to consider blue
|
|
||||||
# STANDING_LEVEL - The level of standings to query. Accepted values are 'corp' and 'alliance'.
|
|
||||||
# BLUE_CORP_IDS - A list of corps to remain blue regardless of in-game standings
|
|
||||||
# BLUE_ALLIANCE_IDS - A list of alliances to remain blue regardless of in-game standings
|
|
||||||
########################
|
|
||||||
CORP_API_ID = os.environ.get('AA_CORP_API_ID', '')
|
|
||||||
CORP_API_VCODE = os.environ.get('AA_CORP_API_VCODE', '')
|
|
||||||
BLUE_STANDING = float(os.environ.get('AA_BLUE_STANDING', '5.0'))
|
|
||||||
STANDING_LEVEL = os.environ.get('AA_STANDING_LEVEL', 'corp')
|
|
||||||
BLUE_CORP_IDS = []
|
|
||||||
BLUE_ALLIANCE_IDS = []
|
|
||||||
|
|
||||||
########################
|
|
||||||
# API Configuration
|
|
||||||
########################
|
|
||||||
# MEMBER_API_MASK - Numeric value of minimum API mask required for members
|
|
||||||
# MEMBER_API_ACCOUNT - Require API to be for Account and not character restricted
|
|
||||||
# BLUE_API_MASK - Numeric value of minimum API mask required for blues
|
|
||||||
# BLUE_API_ACCOUNT - Require API to be for Account and not character restricted
|
|
||||||
# REJECT_OLD_APIS - Require each submitted API be newer than the latest submitted API
|
|
||||||
# REJECT_OLD_APIS_MARGIN - Margin from latest submitted API ID within which a newly submitted API is still accepted
|
|
||||||
# API_SSO_VALIDATION - Require users to prove ownership of newly entered API keys via SSO
|
|
||||||
# Requires SSO to be configured.
|
|
||||||
#######################
|
|
||||||
MEMBER_API_MASK = os.environ.get('AA_MEMBER_API_MASK', 268435455)
|
|
||||||
MEMBER_API_ACCOUNT = 'True' == os.environ.get('AA_MEMBER_API_ACCOUNT', 'True')
|
|
||||||
BLUE_API_MASK = os.environ.get('AA_BLUE_API_MASK', 8388608)
|
|
||||||
BLUE_API_ACCOUNT = 'True' == os.environ.get('AA_BLUE_API_ACCOUNT', 'False')
|
|
||||||
REJECT_OLD_APIS = 'True' == os.environ.get('AA_REJECT_OLD_APIS', 'False')
|
|
||||||
REJECT_OLD_APIS_MARGIN = os.environ.get('AA_REJECT_OLD_APIS_MARGIN', 50)
|
|
||||||
API_SSO_VALIDATION = 'True' == os.environ.get('AA_API_SSO_VALIDATION', 'False')
|
|
||||||
|
|
||||||
#######################
|
|
||||||
# EVE Provider Settings
|
|
||||||
#######################
|
|
||||||
# EVEONLINE_CHARACTER_PROVIDER - Name of default data source for getting eve character data
|
|
||||||
# EVEONLINE_CORP_PROVIDER - Name of default data source for getting eve corporation data
|
|
||||||
# EVEONLINE_ALLIANCE_PROVIDER - Name of default data source for getting eve alliance data
|
|
||||||
# EVEONLINE_ITEMTYPE_PROVIDER - Name of default data source for getting eve item type data
|
|
||||||
#
|
|
||||||
# Available sources are 'esi' and 'xml'. Leaving blank results in the default 'esi' being used.
|
|
||||||
#######################
|
|
||||||
EVEONLINE_CHARACTER_PROVIDER = os.environ.get('AA_EVEONLINE_CHARACTER_PROVIDER', '')
|
|
||||||
EVEONLINE_CORP_PROVIDER = os.environ.get('AA_EVEONLINE_CORP_PROVIDER', '')
|
|
||||||
EVEONLINE_ALLIANCE_PROVIDER = os.environ.get('AA_EVEONLINE_ALLIANCE_PROVIDER', '')
|
|
||||||
EVEONLINE_ITEMTYPE_PROVIDER = os.environ.get('AA_EVEONLINE_ITEMTYPE_PROVIDER', '')
|
|
||||||
|
|
||||||
#####################
|
#####################
|
||||||
# Alliance Market
|
# Alliance Market
|
||||||
#####################
|
#####################
|
||||||
MARKET_URL = os.environ.get('AA_MARKET_URL', 'http://example.com/market')
|
MARKET_URL = 'http://example.com/market'
|
||||||
MARKET_DB = {
|
MARKET_DB = {
|
||||||
'ENGINE': 'django.db.backends.mysql',
|
'ENGINE': 'django.db.backends.mysql',
|
||||||
'NAME': 'alliance_market',
|
'NAME': 'alliance_market',
|
||||||
'USER': os.environ.get('AA_DB_MARKET_USER', 'allianceserver-market'),
|
'USER': 'allianceserver-market',
|
||||||
'PASSWORD': os.environ.get('AA_DB_MARKET_PASSWORD', 'password'),
|
'PASSWORD': '',
|
||||||
'HOST': os.environ.get('AA_DB_MARKET_HOST', '127.0.0.1'),
|
'HOST': '127.0.0.1',
|
||||||
'PORT': os.environ.get('AA_DB_MARKET_PORT', '3306'),
|
'PORT': '3306',
|
||||||
}
|
}
|
||||||
|
|
||||||
#####################
|
#####################
|
||||||
# HR Configuration
|
# IPBoard3 Configuration
|
||||||
#####################
|
|
||||||
# API_KEY_AUDIT_URL - URL for viewing API keys.
|
|
||||||
# Other URLs are supported. Use string formatting notation {} with parameter names api_id, vcode, pk
|
|
||||||
# Example URL formats are shown below:
|
|
||||||
# Old Jacknife: 'https://example.com/jacknife/eveapi/audit.php?usid={api_id}&apik={vcode}'
|
|
||||||
# New Jacknife: 'https://example.com/jacknife/?usid={api_id}&apik={vcode}'
|
|
||||||
# SeAT: 'https://seat.example.com/api-key/detail/{api_id}'
|
|
||||||
# Django Admin: '/admin/eveonline/eveapikeypair/{pk}/change'
|
|
||||||
# Leave blank for the verification code to be shown in a popup on click.
|
|
||||||
#####################
|
|
||||||
API_KEY_AUDIT_URL = os.environ.get('AA_API_KEY_AUDIT_URL', '')
|
|
||||||
|
|
||||||
#####################
|
|
||||||
# Forum Configuration
|
|
||||||
#####################
|
#####################
|
||||||
# IPBOARD_ENDPOINT - Api endpoint if using ipboard
|
# IPBOARD_ENDPOINT - Api endpoint if using ipboard
|
||||||
# IPBOARD_APIKEY - Api key to interact with ipboard
|
# IPBOARD_APIKEY - Api key to interact with ipboard
|
||||||
# IPBOARD_APIMODULE - Module for alliance auth *leave alone*
|
# IPBOARD_APIMODULE - Module for alliance auth *leave alone*
|
||||||
#####################
|
#####################
|
||||||
IPBOARD_ENDPOINT = os.environ.get('AA_IPBOARD_ENDPOINT', 'example.com/interface/board/index.php')
|
IPBOARD_ENDPOINT = 'example.com/interface/board/index.php'
|
||||||
IPBOARD_APIKEY = os.environ.get('AA_IPBOARD_APIKEY', 'somekeyhere')
|
IPBOARD_APIKEY = ''
|
||||||
IPBOARD_APIMODULE = 'aa'
|
IPBOARD_APIMODULE = 'aa'
|
||||||
|
|
||||||
########################
|
########################
|
||||||
# XenForo Configuration
|
# XenForo Configuration
|
||||||
########################
|
########################
|
||||||
XENFORO_ENDPOINT = os.environ.get('AA_XENFORO_ENDPOINT', 'example.com/api.php')
|
XENFORO_ENDPOINT = 'example.com/api.php'
|
||||||
XENFORO_DEFAULT_GROUP = os.environ.get('AA_XENFORO_DEFAULT_GROUP', 0)
|
XENFORO_DEFAULT_GROUP = 0
|
||||||
XENFORO_APIKEY = os.environ.get('AA_XENFORO_APIKEY', 'yourapikey')
|
XENFORO_APIKEY = ''
|
||||||
#####################
|
#####################
|
||||||
|
|
||||||
######################
|
######################
|
||||||
# Jabber Configuration
|
# Jabber Configuration
|
||||||
######################
|
######################
|
||||||
# JABBER_URL - Jabber address url
|
# JABBER_URL - Jabber address url, no leading http://
|
||||||
# JABBER_PORT - Jabber service portal
|
# JABBER_PORT - Jabber service portal
|
||||||
# JABBER_SERVER - Jabber server url
|
# JABBER_SERVER - Jabber server url (server name, eg 'example.com'), no leading http://
|
||||||
# OPENFIRE_ADDRESS - Address of the openfire admin console including port
|
# OPENFIRE_ADDRESS - Address of the openfire admin console including port
|
||||||
# Please use http with 9090 or https with 9091
|
# Please use http:// with 9090 or https:// with 9091
|
||||||
|
# eg 'http://example.com:9090' or 'https://example.com:9091'
|
||||||
# OPENFIRE_SECRET_KEY - Openfire REST API secret key
|
# OPENFIRE_SECRET_KEY - Openfire REST API secret key
|
||||||
# BROADCAST_USER - Broadcast user JID
|
# BROADCAST_USER - Broadcast user username (before @ sign)
|
||||||
# BROADCAST_USER_PASSWORD - Broadcast user password
|
# BROADCAST_USER_PASSWORD - Broadcast user password
|
||||||
|
# BROADCAST_SERVICE_NAME - Name of the Openfire service to broadcast to, usually "broadcast"
|
||||||
######################
|
######################
|
||||||
JABBER_URL = os.environ.get('AA_JABBER_URL', "example.com")
|
JABBER_URL = ''
|
||||||
JABBER_PORT = int(os.environ.get('AA_JABBER_PORT', '5223'))
|
JABBER_PORT = 5223
|
||||||
JABBER_SERVER = os.environ.get('AA_JABBER_SERVER', "example.com")
|
JABBER_SERVER = ''
|
||||||
OPENFIRE_ADDRESS = os.environ.get('AA_OPENFIRE_ADDRESS', "http://example.com:9090")
|
OPENFIRE_ADDRESS = ''
|
||||||
OPENFIRE_SECRET_KEY = os.environ.get('AA_OPENFIRE_SECRET_KEY', "somekey")
|
OPENFIRE_SECRET_KEY = ''
|
||||||
BROADCAST_USER = os.environ.get('AA_BROADCAST_USER', "broadcast@") + JABBER_URL
|
BROADCAST_USER = "broadcast" + "@" + JABBER_URL
|
||||||
BROADCAST_USER_PASSWORD = os.environ.get('AA_BROADCAST_USER_PASSWORD', "somepassword")
|
BROADCAST_USER_PASSWORD = ''
|
||||||
BROADCAST_SERVICE_NAME = os.environ.get('AA_BROADCAST_SERVICE_NAME', "broadcast")
|
BROADCAST_SERVICE_NAME = "broadcast"
|
||||||
|
|
||||||
######################################
|
######################################
|
||||||
# Mumble Configuration
|
# Mumble Configuration
|
||||||
######################################
|
######################################
|
||||||
# MUMBLE_URL - Mumble server url
|
# MUMBLE_URL - Mumble server url, tolerates leading http://, mumble://, or none
|
||||||
# MUMBLE_SERVER_ID - Mumble server id
|
# eg 'http://example.com', 'mumble://example.com', or 'example.com'
|
||||||
######################################
|
######################################
|
||||||
MUMBLE_URL = os.environ.get('AA_MUMBLE_URL', "https://example.com")
|
MUMBLE_URL = ''
|
||||||
MUMBLE_SERVER_ID = int(os.environ.get('AA_MUMBLE_SERVER_ID', '1'))
|
|
||||||
|
|
||||||
######################################
|
######################################
|
||||||
# PHPBB3 Configuration
|
# PHPBB3 Configuration
|
||||||
######################################
|
######################################
|
||||||
|
PHPBB3_URL = 'http://example.com/phpbb/'
|
||||||
PHPBB3_DB = {
|
PHPBB3_DB = {
|
||||||
'ENGINE': 'django.db.backends.mysql',
|
'ENGINE': 'django.db.backends.mysql',
|
||||||
'NAME': 'alliance_forum',
|
'NAME': 'alliance_forum',
|
||||||
'USER': os.environ.get('AA_DB_PHPBB3_USER', 'allianceserver-phpbb3'),
|
'USER': 'allianceserver-phpbb3',
|
||||||
'PASSWORD': os.environ.get('AA_DB_PHPBB3_PASSWORD', 'password'),
|
'PASSWORD': '',
|
||||||
'HOST': os.environ.get('AA_DB_PHPBB3_HOST', '127.0.0.1'),
|
'HOST': '127.0.0.1',
|
||||||
'PORT': os.environ.get('AA_DB_PHPBB3_PORT', '3306'),
|
'PORT': '3306',
|
||||||
}
|
}
|
||||||
|
|
||||||
######################################
|
######################################
|
||||||
@ -445,82 +353,86 @@ PHPBB3_DB = {
|
|||||||
# TEAMSPEAK3_AUTHED_GROUP_ID - Default authed group id
|
# TEAMSPEAK3_AUTHED_GROUP_ID - Default authed group id
|
||||||
# TEAMSPEAK3_PUBLIC_URL - teamspeak3 public url used for link creation
|
# TEAMSPEAK3_PUBLIC_URL - teamspeak3 public url used for link creation
|
||||||
######################################
|
######################################
|
||||||
TEAMSPEAK3_SERVER_IP = os.environ.get('AA_TEAMSPEAK3_SERVER_IP', '127.0.0.1')
|
TEAMSPEAK3_SERVER_IP = '127.0.0.1'
|
||||||
TEAMSPEAK3_SERVER_PORT = int(os.environ.get('AA_TEAMSPEAK3_SERVER_PORT', '10011'))
|
TEAMSPEAK3_SERVER_PORT = 10011
|
||||||
TEAMSPEAK3_SERVERQUERY_USER = os.environ.get('AA_TEAMSPEAK3_SERVERQUERY_USER', 'serveradmin')
|
TEAMSPEAK3_SERVERQUERY_USER = 'serveradmin'
|
||||||
TEAMSPEAK3_SERVERQUERY_PASSWORD = os.environ.get('AA_TEAMSPEAK3_SERVERQUERY_PASSWORD', 'passwordhere')
|
TEAMSPEAK3_SERVERQUERY_PASSWORD = ''
|
||||||
TEAMSPEAK3_VIRTUAL_SERVER = int(os.environ.get('AA_TEAMSPEAK3_VIRTUAL_SERVER', '1'))
|
TEAMSPEAK3_VIRTUAL_SERVER = 1
|
||||||
TEAMSPEAK3_PUBLIC_URL = os.environ.get('AA_TEAMSPEAK3_PUBLIC_URL', 'example.com')
|
TEAMSPEAK3_PUBLIC_URL = ''
|
||||||
|
|
||||||
######################################
|
######################################
|
||||||
# Discord Configuration
|
# Discord Configuration
|
||||||
######################################
|
######################################
|
||||||
# DISCORD_GUILD_ID - ID of the guild to manage
|
# DISCORD_GUILD_ID - ID of the guild to manage
|
||||||
# DISCORD_BOT_TOKEN - oauth token of the app bot user
|
# DISCORD_BOT_TOKEN - OAuth token of the app bot user
|
||||||
# DISCORD_INVITE_CODE - invite code to the server
|
# DISCORD_INVITE_CODE - Alphanumeric string invite code to the server
|
||||||
# DISCORD_APP_ID - oauth app client ID
|
# Do not include the leading http://discord.gg/
|
||||||
# DISCORD_APP_SECRET - oauth app secret
|
# DISCORD_APP_ID - OAuth app client ID
|
||||||
# DISCORD_CALLBACK_URL - oauth callback url
|
# DISCORD_APP_SECRET - OAuth app secret
|
||||||
# DISCORD_SYNC_NAMES - enable to force discord nicknames to be set to eve char name (bot needs Manage Nicknames permission)
|
# DISCORD_CALLBACK_URL - OAuth callback url
|
||||||
|
# Should be of the form 'http://example.com/discord/callback'
|
||||||
|
# DISCORD_SYNC_NAMES - Force discord nicknames to be set to eve char name
|
||||||
######################################
|
######################################
|
||||||
DISCORD_GUILD_ID = os.environ.get('AA_DISCORD_GUILD_ID', '')
|
DISCORD_GUILD_ID = ''
|
||||||
DISCORD_BOT_TOKEN = os.environ.get('AA_DISCORD_BOT_TOKEN', '')
|
DISCORD_BOT_TOKEN = ''
|
||||||
DISCORD_INVITE_CODE = os.environ.get('AA_DISCORD_INVITE_CODE', '')
|
DISCORD_INVITE_CODE = ''
|
||||||
DISCORD_APP_ID = os.environ.get('AA_DISCORD_APP_ID', '')
|
DISCORD_APP_ID = ''
|
||||||
DISCORD_APP_SECRET = os.environ.get('AA_DISCORD_APP_SECRET', '')
|
DISCORD_APP_SECRET = ''
|
||||||
DISCORD_CALLBACK_URL = os.environ.get('AA_DISCORD_CALLBACK_URL', 'http://example.com/discord/callback')
|
DISCORD_CALLBACK_URL = ''
|
||||||
DISCORD_SYNC_NAMES = 'True' == os.environ.get('AA_DISCORD_SYNC_NAMES', 'False')
|
DISCORD_SYNC_NAMES = False
|
||||||
|
|
||||||
######################################
|
######################################
|
||||||
# Discourse Configuration
|
# Discourse Configuration
|
||||||
######################################
|
######################################
|
||||||
# DISCOURSE_URL - Web address of the forums (no trailing slash)
|
# DISCOURSE_URL - Web address of the forums (no trailing slash). Include http://
|
||||||
# DISCOURSE_API_USERNAME - API account username
|
# DISCOURSE_API_USERNAME - API account username
|
||||||
# DISCOURSE_API_KEY - API Key
|
# DISCOURSE_API_KEY - API Key
|
||||||
# DISCOURSE_SSO_SECRET - SSO secret key
|
# DISCOURSE_SSO_SECRET - SSO secret key
|
||||||
######################################
|
######################################
|
||||||
DISCOURSE_URL = os.environ.get('AA_DISCOURSE_URL', '')
|
DISCOURSE_URL = ''
|
||||||
DISCOURSE_API_USERNAME = os.environ.get('AA_DISCOURSE_API_USERNAME', '')
|
DISCOURSE_API_USERNAME = ''
|
||||||
DISCOURSE_API_KEY = os.environ.get('AA_DISCOURSE_API_KEY', '')
|
DISCOURSE_API_KEY = ''
|
||||||
DISCOURSE_SSO_SECRET = os.environ.get('AA_DISCOURSE_SSO_SECRET', '')
|
DISCOURSE_SSO_SECRET = ''
|
||||||
|
|
||||||
#####################################
|
#####################################
|
||||||
# IPS4 Configuration
|
# IPS4 Configuration
|
||||||
#####################################
|
#####################################
|
||||||
# IPS4_URL - base url of the IPS4 install (no trailing slash)
|
# IPS4_URL - Base URL of the IPS4 install (no trailing slash). Include http://
|
||||||
# IPS4_API_KEY - API key provided by IPS4
|
# IPS4_API_KEY - API key provided by IPS4
|
||||||
#####################################
|
#####################################
|
||||||
IPS4_URL = os.environ.get('AA_IPS4_URL', 'http://example.com/ips4')
|
IPS4_URL = ''
|
||||||
IPS4_API_KEY = os.environ.get('AA_IPS4_API_KEY', '')
|
IPS4_API_KEY = ''
|
||||||
IPS4_DB = {
|
IPS4_DB = {
|
||||||
'ENGINE': 'django.db.backends.mysql',
|
'ENGINE': 'django.db.backends.mysql',
|
||||||
'NAME': 'alliance_ips4',
|
'NAME': 'alliance_ips4',
|
||||||
'USER': os.environ.get('AA_DB_IPS4_USER', 'allianceserver-ips4'),
|
'USER': 'allianceserver-ips4',
|
||||||
'PASSWORD': os.environ.get('AA_DB_IPS4_PASSWORD', 'password'),
|
'PASSWORD': '',
|
||||||
'HOST': os.environ.get('AA_DB_IPS4_HOST', '127.0.0.1'),
|
'HOST': '127.0.0.1',
|
||||||
'PORT': os.environ.get('AA_DB_IPS4_PORT', '3306'),
|
'PORT': '3306',
|
||||||
}
|
}
|
||||||
|
|
||||||
#####################################
|
#####################################
|
||||||
# SEAT Configuration
|
# SEAT Configuration
|
||||||
#####################################
|
#####################################
|
||||||
# SEAT_URL - base url of the seat install (no trailing slash)
|
# SEAT_URL - Base URL of the seat install (no trailing slash). Include http://
|
||||||
# SEAT_XTOKEN - API key X-Token provided by SeAT
|
# SEAT_XTOKEN - API key X-Token provided by SeAT
|
||||||
#####################################
|
#####################################
|
||||||
SEAT_URL = os.environ.get('AA_SEAT_URL', 'http://example.com/seat')
|
SEAT_URL = ''
|
||||||
SEAT_XTOKEN = os.environ.get('AA_SEAT_XTOKEN', '')
|
SEAT_XTOKEN = ''
|
||||||
|
|
||||||
######################################
|
######################################
|
||||||
# SMF Configuration
|
# SMF Configuration
|
||||||
######################################
|
######################################
|
||||||
SMF_URL = os.environ.get('AA_SMF_URL', 'https://example.com')
|
# SMF_URL - Web address of the forums. Include leading http://
|
||||||
|
######################################
|
||||||
|
SMF_URL = ''
|
||||||
SMF_DB = {
|
SMF_DB = {
|
||||||
'ENGINE': 'django.db.backends.mysql',
|
'ENGINE': 'django.db.backends.mysql',
|
||||||
'NAME': 'alliance_smf',
|
'NAME': 'alliance_smf',
|
||||||
'USER': os.environ.get('AA_DB_SMF_USER', 'allianceserver-smf'),
|
'USER': 'allianceserver-smf',
|
||||||
'PASSWORD': os.environ.get('AA_DB_SMF_PASSWORD', 'password'),
|
'PASSWORD': '',
|
||||||
'HOST': os.environ.get('AA_DB_SMF_HOST', '127.0.0.1'),
|
'HOST': '127.0.0.1',
|
||||||
'PORT': os.environ.get('AA_DB_SMF_PORT', '3306'),
|
'PORT': '3306',
|
||||||
}
|
}
|
||||||
|
|
||||||
######################################
|
######################################
|
||||||
@ -531,10 +443,10 @@ SMF_DB = {
|
|||||||
# FLEETUP_API_ID - The API id from http://fleet-up.com/Api/MyKeys
|
# FLEETUP_API_ID - The API id from http://fleet-up.com/Api/MyKeys
|
||||||
# FLEETUP_GROUP_ID - The id of the group you want to pull data from, see http://fleet-up.com/Api/Endpoints#groups_mygroupmemberships
|
# FLEETUP_GROUP_ID - The id of the group you want to pull data from, see http://fleet-up.com/Api/Endpoints#groups_mygroupmemberships
|
||||||
######################################
|
######################################
|
||||||
FLEETUP_APP_KEY = os.environ.get('AA_FLEETUP_APP_KEY', '')
|
FLEETUP_APP_KEY = ''
|
||||||
FLEETUP_USER_ID = os.environ.get('AA_FLEETUP_USER_ID', '')
|
FLEETUP_USER_ID = ''
|
||||||
FLEETUP_API_ID = os.environ.get('AA_FLEETUP_API_ID', '')
|
FLEETUP_API_ID = ''
|
||||||
FLEETUP_GROUP_ID = os.environ.get('AA_FLEETUP_GROUP_ID', '')
|
FLEETUP_GROUP_ID = ''
|
||||||
|
|
||||||
#####################################
|
#####################################
|
||||||
# Logging Configuration
|
# Logging Configuration
|
||||||
@ -659,11 +571,6 @@ if 'services.modules.market' in INSTALLED_APPS:
|
|||||||
if 'services.modules.ips4' in INSTALLED_APPS:
|
if 'services.modules.ips4' in INSTALLED_APPS:
|
||||||
DATABASES['ips4'] = IPS4_DB
|
DATABASES['ips4'] = IPS4_DB
|
||||||
|
|
||||||
# Ensure corp/alliance IDs are expected types
|
|
||||||
STR_CORP_IDS = [str(id) for id in CORP_IDS]
|
|
||||||
STR_ALLIANCE_IDS = [str(id) for id in ALLIANCE_IDS]
|
|
||||||
STR_BLUE_CORP_IDS = [str(id) for id in BLUE_CORP_IDS]
|
|
||||||
STR_BLUE_ALLIANCE_IDS = [str(id) for id in BLUE_ALLIANCE_IDS]
|
|
||||||
|
|
||||||
# Conditionally add periodic tasks for services if installed
|
# Conditionally add periodic tasks for services if installed
|
||||||
if 'services.modules.teamspeak3' in INSTALLED_APPS:
|
if 'services.modules.teamspeak3' in INSTALLED_APPS:
|
||||||
|
@ -1,15 +1,11 @@
|
|||||||
from __future__ import unicode_literals
|
from __future__ import unicode_literals
|
||||||
|
|
||||||
from django.db.models.signals import m2m_changed, pre_save
|
from django.db.models.signals import m2m_changed, pre_save
|
||||||
from django.contrib.auth.models import User, Group, Permission
|
from django.contrib.auth.models import User, Group
|
||||||
|
|
||||||
from services.signals import m2m_changed_user_groups, pre_save_user
|
from services.signals import m2m_changed_user_groups, pre_save_user
|
||||||
from services.signals import m2m_changed_group_permissions, m2m_changed_user_permissions
|
from services.signals import m2m_changed_group_permissions, m2m_changed_user_permissions
|
||||||
from authentication.signals import pre_save_auth_state
|
from authentication.signals import pre_save_auth_state
|
||||||
|
from authentication.models import UserProfile
|
||||||
from authentication.tasks import make_member, make_blue
|
|
||||||
from authentication.models import AuthServicesInfo
|
|
||||||
from authentication.states import MEMBER_STATE, BLUE_STATE, NONE_STATE
|
|
||||||
|
|
||||||
from eveonline.models import EveCharacter
|
from eveonline.models import EveCharacter
|
||||||
|
|
||||||
@ -72,7 +68,7 @@ class AuthUtils:
|
|||||||
@classmethod
|
@classmethod
|
||||||
def add_main_character(cls, user, name, character_id, corp_id='', corp_name='', corp_ticker='', alliance_id='',
|
def add_main_character(cls, user, name, character_id, corp_id='', corp_name='', corp_ticker='', alliance_id='',
|
||||||
alliance_name=''):
|
alliance_name=''):
|
||||||
EveCharacter.objects.create(
|
char = EveCharacter.objects.create(
|
||||||
character_id=character_id,
|
character_id=character_id,
|
||||||
character_name=name,
|
character_name=name,
|
||||||
corporation_id=corp_id,
|
corporation_id=corp_id,
|
||||||
@ -83,7 +79,7 @@ class AuthUtils:
|
|||||||
api_id='1234',
|
api_id='1234',
|
||||||
user=user
|
user=user
|
||||||
)
|
)
|
||||||
AuthServicesInfo.objects.update_or_create(user=user, defaults={'main_char_id': character_id})
|
UserProfile.objects.update_or_create(user=user, defaults={'main_character': char})
|
||||||
|
|
||||||
@classmethod
|
@classmethod
|
||||||
def add_permissions_to_groups(cls, perms, groups, disconnect_signals=True):
|
def add_permissions_to_groups(cls, perms, groups, disconnect_signals=True):
|
||||||
|
@ -3,9 +3,8 @@ from django.conf.urls import include, url
|
|||||||
from django.conf.urls.i18n import i18n_patterns
|
from django.conf.urls.i18n import i18n_patterns
|
||||||
from django.utils.translation import ugettext_lazy as _
|
from django.utils.translation import ugettext_lazy as _
|
||||||
from django.contrib import admin
|
from django.contrib import admin
|
||||||
import django.contrib.auth.views
|
import authentication.urls
|
||||||
import authentication.views
|
import authentication.views
|
||||||
import eveonline.views
|
|
||||||
import services.views
|
import services.views
|
||||||
import groupmanagement.views
|
import groupmanagement.views
|
||||||
import optimer.views
|
import optimer.views
|
||||||
@ -19,16 +18,19 @@ import corputils.urls
|
|||||||
import esi.urls
|
import esi.urls
|
||||||
import permissions_tool.urls
|
import permissions_tool.urls
|
||||||
from alliance_auth import NAME
|
from alliance_auth import NAME
|
||||||
|
from alliance_auth.hooks import get_hooks
|
||||||
|
|
||||||
admin.site.site_header = NAME
|
admin.site.site_header = NAME
|
||||||
|
|
||||||
from alliance_auth.hooks import get_hooks
|
|
||||||
|
|
||||||
# Functional/Untranslated URL's
|
# Functional/Untranslated URL's
|
||||||
urlpatterns = [
|
urlpatterns = [
|
||||||
# Locale
|
# Locale
|
||||||
url(r'^i18n/', include('django.conf.urls.i18n')),
|
url(r'^i18n/', include('django.conf.urls.i18n')),
|
||||||
|
|
||||||
|
# Authentication
|
||||||
|
url(r'', include(authentication.urls, namespace='authentication')),
|
||||||
|
|
||||||
# Admin urls
|
# Admin urls
|
||||||
url(r'^admin/', include(admin.site.urls)),
|
url(r'^admin/', include(admin.site.urls)),
|
||||||
|
|
||||||
@ -36,17 +38,6 @@ urlpatterns = [
|
|||||||
url(r'^sso/', include(esi.urls, namespace='esi')),
|
url(r'^sso/', include(esi.urls, namespace='esi')),
|
||||||
url(r'^sso/login$', authentication.views.sso_login, name='auth_sso_login'),
|
url(r'^sso/login$', authentication.views.sso_login, name='auth_sso_login'),
|
||||||
|
|
||||||
# Index
|
|
||||||
url(_(r'^$'), authentication.views.index_view, name='auth_index'),
|
|
||||||
|
|
||||||
# Authentication
|
|
||||||
url(r'^logout_user/', authentication.views.logout_user, name='auth_logout_user'),
|
|
||||||
|
|
||||||
# Eve Online
|
|
||||||
url(r'^main_character_change/(\w+)/$', eveonline.views.main_character_change,
|
|
||||||
name='auth_main_character_change'),
|
|
||||||
url(r'^api_verify_owner/(\w+)/$', eveonline.views.api_sso_validate, name='auth_api_sso'),
|
|
||||||
|
|
||||||
# SRP URLS
|
# SRP URLS
|
||||||
url(r'^srp_fleet_remove/(\w+)$', srp.views.srp_fleet_remove, name='auth_srp_fleet_remove'),
|
url(r'^srp_fleet_remove/(\w+)$', srp.views.srp_fleet_remove, name='auth_srp_fleet_remove'),
|
||||||
url(r'^srp_fleet_disable/(\w+)$', srp.views.srp_fleet_disable, name='auth_srp_fleet_disable'),
|
url(r'^srp_fleet_disable/(\w+)$', srp.views.srp_fleet_disable, name='auth_srp_fleet_disable'),
|
||||||
@ -79,32 +70,6 @@ urlpatterns += i18n_patterns(
|
|||||||
url(r'^fleetup/characters/$', fleetup.views.fleetup_characters, name='auth_fleetup_characters'),
|
url(r'^fleetup/characters/$', fleetup.views.fleetup_characters, name='auth_fleetup_characters'),
|
||||||
url(r'^fleetup/doctrines/(?P<doctrinenumber>[0-9]+)/$', fleetup.views.fleetup_doctrine, name='auth_fleetup_doctrine'),
|
url(r'^fleetup/doctrines/(?P<doctrinenumber>[0-9]+)/$', fleetup.views.fleetup_doctrine, name='auth_fleetup_doctrine'),
|
||||||
|
|
||||||
# Authentication
|
|
||||||
url(_(r'^login_user/'), authentication.views.login_user, name='auth_login_user'),
|
|
||||||
url(_(r'^register_user/'), authentication.views.register_user_view, name='auth_register_user'),
|
|
||||||
|
|
||||||
url(_(r'^user/password/$'), django.contrib.auth.views.password_change, name='password_change'),
|
|
||||||
url(_(r'^user/password/done/$'), django.contrib.auth.views.password_change_done,
|
|
||||||
name='password_change_done'),
|
|
||||||
url(_(r'^user/password/reset/$'), django.contrib.auth.views.password_reset,
|
|
||||||
name='password_reset'),
|
|
||||||
url(_(r'^user/password/password/reset/done/$'), django.contrib.auth.views.password_reset_done,
|
|
||||||
name='password_reset_done'),
|
|
||||||
url(_(r'^user/password/reset/complete/$'), django.contrib.auth.views.password_reset_complete,
|
|
||||||
name='password_reset_complete'),
|
|
||||||
url(_(r'^user/password/reset/confirm/(?P<uidb64>[0-9A-Za-z_\-]+)/(?P<token>.+)/$'),
|
|
||||||
django.contrib.auth.views.password_reset_confirm, name='password_reset_confirm'),
|
|
||||||
|
|
||||||
# Portal Urls
|
|
||||||
url(_(r'^dashboard/$'), eveonline.views.dashboard_view, name='auth_dashboard'),
|
|
||||||
url(_(r'^help/$'), authentication.views.help_view, name='auth_help'),
|
|
||||||
|
|
||||||
# Eveonline Urls
|
|
||||||
url(_(r'^add_api_key/'), eveonline.views.add_api_key, name='auth_add_api_key'),
|
|
||||||
url(_(r'^refresh_api_pair/([0-9]+)/$'), eveonline.views.user_refresh_api, name='auth_user_refresh_api'),
|
|
||||||
url(_(r'^delete_api_pair/(\w+)/$'), eveonline.views.api_key_removal, name='auth_api_key_removal'),
|
|
||||||
url(_(r'^characters/'), eveonline.views.characters_view, name='auth_characters'),
|
|
||||||
|
|
||||||
# Corputils
|
# Corputils
|
||||||
url(_(r'^corpstats/'), include(corputils.urls, namespace='corputils')),
|
url(_(r'^corpstats/'), include(corputils.urls, namespace='corputils')),
|
||||||
|
|
||||||
|
@ -5,39 +5,11 @@ from django.contrib.auth.admin import UserAdmin as BaseUserAdmin
|
|||||||
from django.contrib.auth.models import User
|
from django.contrib.auth.models import User
|
||||||
from django.utils.text import slugify
|
from django.utils.text import slugify
|
||||||
from django import forms
|
from django import forms
|
||||||
from authentication.models import AuthServicesInfo, State, get_none_state
|
from authentication.models import State, get_guest_state
|
||||||
from eveonline.models import EveCharacter
|
|
||||||
from alliance_auth.hooks import get_hooks
|
from alliance_auth.hooks import get_hooks
|
||||||
from services.hooks import ServicesHook
|
from services.hooks import ServicesHook
|
||||||
|
|
||||||
|
|
||||||
@admin.register(AuthServicesInfo)
|
|
||||||
class AuthServicesInfoManager(admin.ModelAdmin):
|
|
||||||
|
|
||||||
@staticmethod
|
|
||||||
def main_character(obj):
|
|
||||||
if obj.main_char_id:
|
|
||||||
try:
|
|
||||||
return EveCharacter.objects.get(character_id=obj.main_char_id)
|
|
||||||
except EveCharacter.DoesNotExist:
|
|
||||||
pass
|
|
||||||
return None
|
|
||||||
|
|
||||||
@staticmethod
|
|
||||||
def has_delete_permission(request, obj=None):
|
|
||||||
return False
|
|
||||||
|
|
||||||
@staticmethod
|
|
||||||
def has_add_permission(request, obj=None):
|
|
||||||
return False
|
|
||||||
|
|
||||||
search_fields = [
|
|
||||||
'user__username',
|
|
||||||
'main_char_id',
|
|
||||||
]
|
|
||||||
list_display = ('user', 'main_character')
|
|
||||||
|
|
||||||
|
|
||||||
def make_service_hooks_update_groups_action(service):
|
def make_service_hooks_update_groups_action(service):
|
||||||
"""
|
"""
|
||||||
Make a admin action for the given service
|
Make a admin action for the given service
|
||||||
@ -103,16 +75,16 @@ class StateForm(forms.ModelForm):
|
|||||||
def _is_none_state(self):
|
def _is_none_state(self):
|
||||||
instance = getattr(self, 'instance', None)
|
instance = getattr(self, 'instance', None)
|
||||||
if instance and instance.pk:
|
if instance and instance.pk:
|
||||||
return instance == get_none_state()
|
return instance == get_guest_state()
|
||||||
|
|
||||||
def __init__(self, *args, **kwargs):
|
def __init__(self, *args, **kwargs):
|
||||||
super(StateForm, self).__init__(*args, **kwargs)
|
super(StateForm, self).__init__(*args, **kwargs)
|
||||||
if _is_none_state():
|
if self._is_none_state():
|
||||||
self.fields['name'].widget.attrs['readonly'] = True
|
self.fields['name'].widget.attrs['readonly'] = True
|
||||||
|
|
||||||
def clean_name(self):
|
def clean_name(self):
|
||||||
if self._is_none_state():
|
if self._is_none_state():
|
||||||
return instance.name
|
return self.instance.name
|
||||||
return self.cleaned_data['name']
|
return self.cleaned_data['name']
|
||||||
|
|
||||||
|
|
||||||
@ -122,6 +94,6 @@ class StateAdmin(admin.ModelAdmin):
|
|||||||
|
|
||||||
@staticmethod
|
@staticmethod
|
||||||
def has_delete_permission(request, obj=None):
|
def has_delete_permission(request, obj=None):
|
||||||
if obj == get_none_state():
|
if obj == get_guest_state():
|
||||||
return False
|
return False
|
||||||
|
|
||||||
|
@ -1,10 +1,14 @@
|
|||||||
from __future__ import unicode_literals
|
from __future__ import unicode_literals
|
||||||
|
|
||||||
from django.apps import AppConfig
|
from django.apps import AppConfig
|
||||||
|
from django.core.checks import register, Tags
|
||||||
|
|
||||||
|
|
||||||
class AuthenticationConfig(AppConfig):
|
class AuthenticationConfig(AppConfig):
|
||||||
name = 'authentication'
|
name = 'authentication'
|
||||||
|
|
||||||
def ready(self):
|
def ready(self):
|
||||||
|
super(AuthenticationConfig, self).ready()
|
||||||
import authentication.signals
|
import authentication.signals
|
||||||
|
from authentication import checks
|
||||||
|
register(Tags.security)(checks.check_login_scopes_setting)
|
||||||
|
@ -1,6 +1,7 @@
|
|||||||
from django.contrib.auth.backends import ModelBackend
|
from django.contrib.auth.backends import ModelBackend
|
||||||
from django.contrib.auth.models import Permission
|
from django.contrib.auth.models import Permission
|
||||||
from authentication.models import UserProfile
|
from authentication.models import UserProfile, CharacterOwnership
|
||||||
|
from django.contrib.auth.models import User
|
||||||
|
|
||||||
|
|
||||||
class StateBackend(ModelBackend):
|
class StateBackend(ModelBackend):
|
||||||
@ -10,7 +11,7 @@ class StateBackend(ModelBackend):
|
|||||||
user_state_query = 'state__%s__user' % profile_state_field.related_query_name()
|
user_state_query = 'state__%s__user' % profile_state_field.related_query_name()
|
||||||
return Permission.objects.filter(**{user_state_query: user_obj})
|
return Permission.objects.filter(**{user_state_query: user_obj})
|
||||||
|
|
||||||
def get_state_permission(self, user_obj, obj=None):
|
def get_state_permissions(self, user_obj, obj=None):
|
||||||
return self._get_permissions(user_obj, obj, 'state')
|
return self._get_permissions(user_obj, obj, 'state')
|
||||||
|
|
||||||
def get_all_permissions(self, user_obj, obj=None):
|
def get_all_permissions(self, user_obj, obj=None):
|
||||||
@ -21,3 +22,49 @@ class StateBackend(ModelBackend):
|
|||||||
user_obj._perm_cache.update(self.get_group_permissions(user_obj))
|
user_obj._perm_cache.update(self.get_group_permissions(user_obj))
|
||||||
user_obj._perm_cache.update(self.get_state_permissions(user_obj))
|
user_obj._perm_cache.update(self.get_state_permissions(user_obj))
|
||||||
return user_obj._perm_cache
|
return user_obj._perm_cache
|
||||||
|
|
||||||
|
def authenticate(self, token=None):
|
||||||
|
if not token:
|
||||||
|
return None
|
||||||
|
try:
|
||||||
|
ownership = CharacterOwnership.objects.get(character__character_id=token.character_id)
|
||||||
|
if ownership.owner_hash == token.character_owner_hash:
|
||||||
|
return ownership.user
|
||||||
|
else:
|
||||||
|
ownership.delete()
|
||||||
|
return self.create_user(token)
|
||||||
|
except CharacterOwnership.DoesNotExist:
|
||||||
|
try:
|
||||||
|
# insecure legacy main check for pre-sso registration auth installs
|
||||||
|
profile = UserProfile.objects.get(main_character__character_id=token.character_id)
|
||||||
|
# attach an ownership
|
||||||
|
CharacterOwnership.objects.create_by_token(token)
|
||||||
|
return profile.user
|
||||||
|
except UserProfile.DoesNotExist:
|
||||||
|
pass
|
||||||
|
return self.create_user(token)
|
||||||
|
|
||||||
|
def create_user(self, token):
|
||||||
|
username = self.iterate_username(token.charater_name) # build unique username off character name
|
||||||
|
user = User.objects.create_user(username)
|
||||||
|
user.set_unusable_password() # prevent login via password
|
||||||
|
user.is_active = False # prevent login until email set
|
||||||
|
user.save()
|
||||||
|
token.user = user
|
||||||
|
co = CharacterOwnership.objects.create_by_token(token) # assign ownership to this user
|
||||||
|
user.profile.main_character = co.character # assign main character as token character
|
||||||
|
user.profile.save()
|
||||||
|
return user
|
||||||
|
|
||||||
|
@staticmethod
|
||||||
|
def iterate_username(name):
|
||||||
|
if User.objects.filter(username__startswith=name).exists():
|
||||||
|
u = User.objects.filter(username__startswith=name)
|
||||||
|
num = len(u)
|
||||||
|
username = "%s_%s" % (name, num)
|
||||||
|
while u.filter(username=username).exists():
|
||||||
|
num += 1
|
||||||
|
username = "%s_%s" % (name, num)
|
||||||
|
else:
|
||||||
|
username = name
|
||||||
|
return username
|
||||||
|
13
authentication/checks.py
Normal file
13
authentication/checks.py
Normal file
@ -0,0 +1,13 @@
|
|||||||
|
from __future__ import unicode_literals
|
||||||
|
from django.core.checks import Error
|
||||||
|
from django.conf import settings
|
||||||
|
|
||||||
|
|
||||||
|
def check_login_scopes_setting(*args, **kwargs):
|
||||||
|
errors = []
|
||||||
|
try:
|
||||||
|
assert settings.LOGIN_TOKEN_SCOPES
|
||||||
|
except (AssertionError, AttributeError):
|
||||||
|
errors.append(Error('LOGIN_TOKEN_SCOPES setting cannot be blank.',
|
||||||
|
hint='SSO tokens used for logging in must require scopes to be refreshable.'))
|
||||||
|
return errors
|
@ -1,17 +0,0 @@
|
|||||||
from __future__ import unicode_literals
|
|
||||||
from authentication.states import NONE_STATE, BLUE_STATE, MEMBER_STATE
|
|
||||||
from authentication.managers import UserState
|
|
||||||
from django.conf import settings
|
|
||||||
|
|
||||||
|
|
||||||
def membership_state(request):
|
|
||||||
return UserState.get_membership_state(request)
|
|
||||||
|
|
||||||
|
|
||||||
def states(request):
|
|
||||||
return {
|
|
||||||
'BLUE_STATE': BLUE_STATE,
|
|
||||||
'MEMBER_STATE': MEMBER_STATE,
|
|
||||||
'NONE_STATE': NONE_STATE,
|
|
||||||
'MEMBER_BLUE_STATE': [MEMBER_STATE, BLUE_STATE],
|
|
||||||
}
|
|
@ -1,23 +0,0 @@
|
|||||||
from __future__ import unicode_literals
|
|
||||||
from django.contrib.auth.decorators import user_passes_test
|
|
||||||
from authentication.managers import UserState
|
|
||||||
|
|
||||||
|
|
||||||
def _state_required(state_test, *args, **kwargs):
|
|
||||||
return user_passes_test(state_test, *args, **kwargs)
|
|
||||||
|
|
||||||
|
|
||||||
def members(*args, **kwargs):
|
|
||||||
return _state_required(UserState.member_state, *args, **kwargs)
|
|
||||||
|
|
||||||
|
|
||||||
def blues(*args, **kwargs):
|
|
||||||
return _state_required(UserState.blue_state, *args, **kwargs)
|
|
||||||
|
|
||||||
|
|
||||||
def members_and_blues(*args, **kwargs):
|
|
||||||
return _state_required(UserState.member_or_blue_state, *args, **kwargs)
|
|
||||||
|
|
||||||
|
|
||||||
def none_state(*args, **kwargs):
|
|
||||||
return _state_required(UserState.none_state, *args, **kwargs)
|
|
@ -1,42 +1,7 @@
|
|||||||
from __future__ import unicode_literals
|
from __future__ import unicode_literals
|
||||||
from django import forms
|
from django import forms
|
||||||
from django.utils.translation import ugettext_lazy as _
|
from django.utils.translation import ugettext_lazy as _
|
||||||
from django.contrib.auth.models import User
|
|
||||||
import re
|
|
||||||
|
|
||||||
|
|
||||||
class LoginForm(forms.Form):
|
|
||||||
username = forms.CharField(label=_('Username'), max_length=32, required=True)
|
|
||||||
password = forms.CharField(label=_('Password'), widget=forms.PasswordInput())
|
|
||||||
|
|
||||||
|
|
||||||
class RegistrationForm(forms.Form):
|
class RegistrationForm(forms.Form):
|
||||||
username = forms.CharField(label=_('Username'), max_length=30, required=True)
|
email = forms.EmailField(label=_('Email'), max_length=254, required=True)
|
||||||
password = forms.CharField(label=_('Password'), widget=forms.PasswordInput(), required=True)
|
|
||||||
password_again = forms.CharField(label=_('Password Again'), widget=forms.PasswordInput(), required=True)
|
|
||||||
email = forms.CharField(label=_('Email'), max_length=254, required=True)
|
|
||||||
email_again = forms.CharField(label=_('Email Again'), max_length=254, required=True)
|
|
||||||
|
|
||||||
def clean(self):
|
|
||||||
if ' ' in self.cleaned_data['username']:
|
|
||||||
raise forms.ValidationError('Username cannot contain a space')
|
|
||||||
|
|
||||||
# We attempt to get the user object if we succeed we know email as been used
|
|
||||||
try:
|
|
||||||
User.objects.get(email=self.cleaned_data['email'])
|
|
||||||
raise forms.ValidationError('Email as already been used')
|
|
||||||
except User.DoesNotExist:
|
|
||||||
pass
|
|
||||||
|
|
||||||
if not re.match("^\w+$", self.cleaned_data['username']):
|
|
||||||
raise forms.ValidationError('Username contains illegal characters')
|
|
||||||
|
|
||||||
if 'password' in self.cleaned_data and 'password_again' in self.cleaned_data:
|
|
||||||
if self.cleaned_data['password'] != self.cleaned_data['password_again']:
|
|
||||||
raise forms.ValidationError('Passwords do not match')
|
|
||||||
|
|
||||||
if 'email' in self.cleaned_data and 'email_again' in self.cleaned_data:
|
|
||||||
if self.cleaned_data['email'] != self.cleaned_data['email_again']:
|
|
||||||
raise forms.ValidationError('Emails do not match')
|
|
||||||
|
|
||||||
return self.cleaned_data
|
|
||||||
|
@ -1,75 +1,57 @@
|
|||||||
from __future__ import unicode_literals
|
from __future__ import unicode_literals
|
||||||
from django.contrib.auth.models import User
|
from django.db.models import Manager, QuerySet, Q
|
||||||
from django.conf import settings
|
from eveonline.managers import EveManager
|
||||||
from authentication.states import NONE_STATE, BLUE_STATE, MEMBER_STATE
|
from eveonline.models import EveCharacter
|
||||||
from authentication.models import AuthServicesInfo
|
|
||||||
|
|
||||||
import logging
|
import logging
|
||||||
|
|
||||||
logger = logging.getLogger(__name__)
|
logger = logging.getLogger(__name__)
|
||||||
|
|
||||||
|
|
||||||
class AuthServicesInfoManager:
|
class CharacterOwnershipManager(Manager):
|
||||||
def __init__(self):
|
def create_by_token(self, token):
|
||||||
pass
|
if not EveCharacter.objects.filter(character_id=token.character_id).exists():
|
||||||
|
EveManager.create_character(token.character_id)
|
||||||
|
return self.create(character=EveCharacter.objects.get(characte_id=token.character_id), user=token.user,
|
||||||
|
owner_hash=token.character_owner_hash)
|
||||||
|
|
||||||
@staticmethod
|
|
||||||
def update_main_char_id(char_id, user):
|
class StateQuerySet(QuerySet):
|
||||||
if User.objects.filter(username=user.username).exists():
|
def available_to_character(self, character):
|
||||||
logger.debug("Updating user %s main character to id %s" % (user, char_id))
|
query = Q(member_characters__character_id=character.character_id)
|
||||||
authserviceinfo = AuthServicesInfo.objects.get(user=user)
|
query |= Q(member_corporations__corporation_id=character.corporation_id)
|
||||||
authserviceinfo.main_char_id = char_id
|
query |= Q(member_alliances__alliance_id=character.alliance_id)
|
||||||
authserviceinfo.save(update_fields=['main_char_id'])
|
query |= Q(public=True)
|
||||||
logger.info("Updated user %s main character to id %s" % (user, char_id))
|
return self.filter(query)
|
||||||
|
|
||||||
|
def available_to_user(self, user):
|
||||||
|
if user.profile.main_character:
|
||||||
|
return self.available_to_character(user.profile.main_character)
|
||||||
else:
|
else:
|
||||||
logger.error("Failed to update user %s main character id to %s: user does not exist." % (user, char_id))
|
return self.none()
|
||||||
|
|
||||||
@staticmethod
|
|
||||||
def update_is_blue(is_blue, user):
|
|
||||||
if User.objects.filter(username=user.username).exists():
|
|
||||||
logger.debug("Updating user %s blue status: %s" % (user, is_blue))
|
|
||||||
authserviceinfo = AuthServicesInfo.objects.get(user=user)
|
|
||||||
authserviceinfo.is_blue = is_blue
|
|
||||||
authserviceinfo.save(update_fields=['is_blue'])
|
|
||||||
logger.info("Updated user %s blue status to %s in authservicesinfo model." % (user, is_blue))
|
|
||||||
|
|
||||||
|
|
||||||
class UserState:
|
class StateManager(Manager):
|
||||||
def __init__(self):
|
def get_queryset(self):
|
||||||
pass
|
return StateQuerySet(self.model, using=self._db)
|
||||||
|
|
||||||
MEMBER_STATE = MEMBER_STATE
|
def available_to_character(self, character):
|
||||||
BLUE_STATE = BLUE_STATE
|
return self.get_queryset().available_to_character(character)
|
||||||
NONE_STATE = NONE_STATE
|
|
||||||
|
|
||||||
@classmethod
|
def available_to_user(self, user):
|
||||||
def member_state(cls, user):
|
return self.get_queryset().available_to_user(user)
|
||||||
return cls.state_required(user, [cls.MEMBER_STATE])
|
|
||||||
|
|
||||||
@classmethod
|
def get_for_character(self, character):
|
||||||
def member_or_blue_state(cls, user):
|
states = self.get_queryset().available_to_character(character).order_by('priority')
|
||||||
return cls.state_required(user, [cls.MEMBER_STATE, cls.BLUE_STATE])
|
if states.exists():
|
||||||
|
return states[0]
|
||||||
|
else:
|
||||||
|
from authentication.models import get_guest_state
|
||||||
|
return get_guest_state()
|
||||||
|
|
||||||
@classmethod
|
def get_for_user(self, user):
|
||||||
def blue_state(cls, user):
|
states = self.get_queryset().available_to_user(user)
|
||||||
return cls.state_required(user, [cls.BLUE_STATE])
|
if states.exists():
|
||||||
|
return states[0]
|
||||||
@classmethod
|
else:
|
||||||
def none_state(cls, user):
|
from authentication.models import get_guest_state
|
||||||
return cls.state_required(user, [cls.NONE_STATE])
|
return get_guest_state()
|
||||||
|
|
||||||
@classmethod
|
|
||||||
def get_membership_state(cls, request):
|
|
||||||
if request.user.is_authenticated:
|
|
||||||
auth = AuthServicesInfo.objects.get(user=request.user)
|
|
||||||
return {'STATE': auth.state}
|
|
||||||
return {'STATE': cls.NONE_STATE}
|
|
||||||
|
|
||||||
@staticmethod
|
|
||||||
def state_required(user, states):
|
|
||||||
if user.is_superuser and settings.SUPERUSER_STATE_BYPASS:
|
|
||||||
return True
|
|
||||||
if user.is_authenticated:
|
|
||||||
auth = AuthServicesInfo.objects.get(user=user)
|
|
||||||
return auth.state in states
|
|
||||||
return False
|
|
@ -4,52 +4,6 @@ from __future__ import unicode_literals
|
|||||||
|
|
||||||
from django.db import migrations
|
from django.db import migrations
|
||||||
|
|
||||||
from authentication.states import MEMBER_STATE, BLUE_STATE, NONE_STATE
|
|
||||||
from django.conf import settings
|
|
||||||
|
|
||||||
def determine_membership_by_character(char, apps):
|
|
||||||
if str(char.corporation_id) in settings.STR_CORP_IDS:
|
|
||||||
return MEMBER_STATE
|
|
||||||
elif str(char.alliance_id) in settings.STR_ALLIANCE_IDS:
|
|
||||||
return MEMBER_STATE
|
|
||||||
EveCorporationInfo = apps.get_model('eveonline', 'EveCorporationInfo')
|
|
||||||
if EveCorporationInfo.objects.filter(corporation_id=char.corporation_id).exists() is False:
|
|
||||||
return NONE_STATE
|
|
||||||
else:
|
|
||||||
corp = EveCorporationInfo.objects.get(corporation_id=char.corporation_id)
|
|
||||||
if corp.is_blue:
|
|
||||||
return BLUE_STATE
|
|
||||||
else:
|
|
||||||
return NONE_STATE
|
|
||||||
|
|
||||||
def determine_membership_by_user(user, apps):
|
|
||||||
AuthServicesInfo = apps.get_model('authentication', 'AuthServicesInfo')
|
|
||||||
auth = AuthServicesInfo.objects.get(user=user)
|
|
||||||
if auth.main_char_id:
|
|
||||||
EveCharacter = apps.get_model('eveonline', 'EveCharacter')
|
|
||||||
if EveCharacter.objects.filter(character_id=auth.main_char_id).exists():
|
|
||||||
char = EveCharacter.objects.get(character_id=auth.main_char_id)
|
|
||||||
return determine_membership_by_character(char, apps)
|
|
||||||
else:
|
|
||||||
return NONE_STATE
|
|
||||||
else:
|
|
||||||
return NONE_STATE
|
|
||||||
|
|
||||||
def set_state(user, apps):
|
|
||||||
if user.is_active:
|
|
||||||
state = determine_membership_by_user(user, apps)
|
|
||||||
else:
|
|
||||||
state = NONE_STATE
|
|
||||||
AuthServicesInfo = apps.get_model('authentication', 'AuthServicesInfo')
|
|
||||||
auth = AuthServicesInfo.objects.get(user=user)
|
|
||||||
if auth.state != state:
|
|
||||||
auth.state = state
|
|
||||||
auth.save()
|
|
||||||
|
|
||||||
def set_initial_state(apps, schema_editor):
|
|
||||||
User = apps.get_model('auth', 'User')
|
|
||||||
for u in User.objects.all():
|
|
||||||
set_state(u, apps)
|
|
||||||
|
|
||||||
class Migration(migrations.Migration):
|
class Migration(migrations.Migration):
|
||||||
|
|
||||||
@ -60,5 +14,4 @@ class Migration(migrations.Migration):
|
|||||||
]
|
]
|
||||||
|
|
||||||
operations = [
|
operations = [
|
||||||
migrations.RunPython(set_initial_state, migrations.RunPython.noop)
|
|
||||||
]
|
]
|
||||||
|
24
authentication/migrations/0014_fleetup_permission.py
Normal file
24
authentication/migrations/0014_fleetup_permission.py
Normal file
@ -0,0 +1,24 @@
|
|||||||
|
# -*- coding: utf-8 -*-
|
||||||
|
# Generated by Django 1.10.1 on 2016-09-09 23:19
|
||||||
|
from __future__ import unicode_literals
|
||||||
|
|
||||||
|
from django.db import migrations
|
||||||
|
|
||||||
|
|
||||||
|
def create_permission(apps, schema_editor):
|
||||||
|
User = apps.get_model('auth', 'User')
|
||||||
|
ContentType = apps.get_model('contenttypes', 'ContentType')
|
||||||
|
Permission = apps.get_model('auth', 'Permission')
|
||||||
|
ct = ContentType.objects.get_for_model(User)
|
||||||
|
Permission.objects.get_or_create(codename="view_fleetup", content_type=ct, name="view_fleetup")
|
||||||
|
|
||||||
|
|
||||||
|
class Migration(migrations.Migration):
|
||||||
|
|
||||||
|
dependencies = [
|
||||||
|
('authentication', '0013_service_modules'),
|
||||||
|
]
|
||||||
|
|
||||||
|
operations = [
|
||||||
|
migrations.RunPython(create_permission, migrations.RunPython.noop)
|
||||||
|
]
|
227
authentication/migrations/0015_user_profiles.py
Normal file
227
authentication/migrations/0015_user_profiles.py
Normal file
@ -0,0 +1,227 @@
|
|||||||
|
# -*- coding: utf-8 -*-
|
||||||
|
# Generated by Django 1.10.5 on 2017-03-22 23:09
|
||||||
|
from __future__ import unicode_literals
|
||||||
|
|
||||||
|
import authentication.models
|
||||||
|
from django.conf import settings
|
||||||
|
from django.db import migrations, models
|
||||||
|
import django.db.models.deletion
|
||||||
|
|
||||||
|
|
||||||
|
def create_guest_state(apps, schema_editor):
|
||||||
|
State = apps.get_model('authentication', 'State')
|
||||||
|
State.objects.update_or_create(name='Guest', defaults={'priority': 0, 'public': True})
|
||||||
|
|
||||||
|
|
||||||
|
def create_member_state(apps, schema_editor):
|
||||||
|
Group = apps.get_model('auth', 'Group')
|
||||||
|
State = apps.get_model('authentication', 'State')
|
||||||
|
EveAllianceInfo = apps.get_model('eveonline', 'EveAllianceInfo')
|
||||||
|
EveCorporationInfo = apps.get_model('eveonline', 'EveCorporationInfo')
|
||||||
|
|
||||||
|
member_state_name = getattr(settings, 'DEFAULT_AUTH_GROUP', 'Member')
|
||||||
|
s = State.objects.update_or_create(name=member_state_name, defaults={'priority': 100, 'public': False})[0]
|
||||||
|
try:
|
||||||
|
# move group permissions to state
|
||||||
|
g = Group.objects.get(name=member_state_name)
|
||||||
|
s.permissions.add(g.permissions.all())
|
||||||
|
g.delete()
|
||||||
|
except Group.DoesNotExist:
|
||||||
|
pass
|
||||||
|
|
||||||
|
# auto-populate member IDs
|
||||||
|
CORP_IDS = getattr(settings, 'CORP_IDS', [])
|
||||||
|
ALLIANCE_IDS = getattr(settings, 'ALLIANCE_IDS', [])
|
||||||
|
s.member_corporations.add(EveCorporationInfo.objects.filter(corporation_id__in=CORP_IDS))
|
||||||
|
s.member_alliances.add(EveAllianceInfo.objects.filter(alliance_id__in=ALLIANCE_IDS))
|
||||||
|
|
||||||
|
|
||||||
|
def create_member_group(apps, schema_editor):
|
||||||
|
Group = apps.get_model('auth', 'Group')
|
||||||
|
State = apps.get_model('authentication', 'State')
|
||||||
|
member_state_name = getattr(settings, 'DEFAULT_AUTH_GROUP', 'Member')
|
||||||
|
|
||||||
|
g = Group.objects.get_or_create(name=member_state_name)[0]
|
||||||
|
try:
|
||||||
|
# move permissions back
|
||||||
|
state = State.objects.get(name=member_state_name)
|
||||||
|
g.permissions.add(state.permissions.all())
|
||||||
|
|
||||||
|
# move users back
|
||||||
|
for profile in state.userprofile_set.all().select_related('user'):
|
||||||
|
profile.user.groups.add(g)
|
||||||
|
except State.DoesNotExist:
|
||||||
|
pass
|
||||||
|
|
||||||
|
|
||||||
|
def create_blue_state(apps, schema_editor):
|
||||||
|
Group = apps.get_model('auth', 'Group')
|
||||||
|
State = apps.get_model('authentication', 'State')
|
||||||
|
EveAllianceInfo = apps.get_model('eveonline', 'EveAllianceInfo')
|
||||||
|
EveCorporationInfo = apps.get_model('eveonline', 'EveCorporationInfo')
|
||||||
|
blue_state_name = getattr(settings, 'DEFAULT_BLUE_GROUP', 'Blue')
|
||||||
|
|
||||||
|
s = State.objects.update_or_create(name=blue_state_name, defaults={'priority': 50, 'public': False})[0]
|
||||||
|
try:
|
||||||
|
# move group permissions to state
|
||||||
|
g = Group.objects.get(name=blue_state_name)
|
||||||
|
s.permissions.add(g.permissions.all())
|
||||||
|
g.permissions.clear()
|
||||||
|
except Group.DoesNotExist:
|
||||||
|
pass
|
||||||
|
|
||||||
|
# auto-populate blue member IDs
|
||||||
|
BLUE_CORP_IDS = getattr(settings, 'BLUE_CORP_IDS', [])
|
||||||
|
BLUE_ALLIANCE_IDS = getattr(settings, 'BLUE_ALLIANCE_IDS', [])
|
||||||
|
s.member_corporations.add(EveCorporationInfo.objects.filter(corporation_id__in=BLUE_CORP_IDS))
|
||||||
|
s.member_alliances.add(EveAllianceInfo.objects.filter(alliance_id__in=BLUE_ALLIANCE_IDS))
|
||||||
|
|
||||||
|
|
||||||
|
def create_blue_group(apps, schema_editor):
|
||||||
|
Group = apps.get_model('auth', 'Group')
|
||||||
|
State = apps.get_model('authentication', 'State')
|
||||||
|
blue_state_name = getattr(settings, 'DEFAULT_BLUE_GROUP', 'Blue')
|
||||||
|
|
||||||
|
g = Group.objects.get_or_create(name=blue_state_name)[0]
|
||||||
|
try:
|
||||||
|
# move permissions back
|
||||||
|
state = State.objects.get(name=blue_state_name)
|
||||||
|
g.permissions.add(state.permissions.all())
|
||||||
|
|
||||||
|
# move users back
|
||||||
|
for profile in state.userprofile_set.all().select_related('user'):
|
||||||
|
profile.user.groups.add(g)
|
||||||
|
except State.DoesNotExist:
|
||||||
|
pass
|
||||||
|
|
||||||
|
|
||||||
|
def populate_ownerships(apps, schema_editor):
|
||||||
|
Token = apps.get_model('esi', 'Token')
|
||||||
|
CharacterOwnership = apps.get_model('authentication', 'CharacterOwnership')
|
||||||
|
EveCharacter = apps.get_model('eveonline', 'EveCharacter')
|
||||||
|
|
||||||
|
unique_character_owners = [t['character_id'] for t in
|
||||||
|
Token.objects.all().values('character_id').annotate(n=models.Count('user')) if
|
||||||
|
t['n'] == 1 and EveCharacter.objects.filter(character_id=t['character_id'].exists())]
|
||||||
|
|
||||||
|
tokens = Token.objects.filter(character_id__in=unique_character_owners)
|
||||||
|
for c_id in unique_character_owners:
|
||||||
|
ts = tokens.filter(character_id=c_id).order_by('created')
|
||||||
|
for t in ts:
|
||||||
|
if t.can_refresh:
|
||||||
|
# find newest refreshable token and use it as basis for CharacterOwnership
|
||||||
|
CharacterOwnership.objecs.create_by_token(t)
|
||||||
|
break
|
||||||
|
|
||||||
|
|
||||||
|
def create_profiles(apps, schema_editor):
|
||||||
|
AuthServicesInfo = apps.get_model('authentication', 'AuthServicesInfo')
|
||||||
|
State = apps.get_model('authentication', 'State')
|
||||||
|
UserProfile = apps.get_model('authentication', 'UserProfile')
|
||||||
|
EveCharacter = apps.get_model('eveonline', 'EveCharacter')
|
||||||
|
|
||||||
|
# grab AuthServicesInfo if they have a unique main_char_id and the EveCharacter exists
|
||||||
|
unique_mains = [auth['main_char_id'] for auth in
|
||||||
|
AuthServicesInfo.objects.exclude(main_char_id='').values('main_char_id').annotate(
|
||||||
|
n=models.Count('main_char_id')) if
|
||||||
|
auth['n'] == 1 and EveCharacter.objects.filter(character_id=auth['main_char_id'].exists())]
|
||||||
|
|
||||||
|
auths = AuthServicesInfo.objects.filter(main_char_id__in=unique_mains).select_related('user')
|
||||||
|
for auth in auths:
|
||||||
|
# carry states and mains forward
|
||||||
|
profile = UserProfile.objects.get_or_create(user=auth.user.pk)
|
||||||
|
state = State.objects.get(name=auth.state if auth.state else 'Guest')
|
||||||
|
profile.state = state
|
||||||
|
char = EveCharacter.objects.get(character_id=auth.main_char_id)
|
||||||
|
profile.main_character = char
|
||||||
|
profile.save()
|
||||||
|
|
||||||
|
|
||||||
|
def recreate_authservicesinfo(apps, schema_editor):
|
||||||
|
AuthServicesInfo = apps.get_model('authentication', 'AuthServicesInfo')
|
||||||
|
UserProfile = apps.get_model('authentication', 'UserProfile')
|
||||||
|
User = apps.get_model('auth', 'User')
|
||||||
|
|
||||||
|
# recreate all missing AuthServicesInfo models
|
||||||
|
AuthServicesInfo.objects.bulk_create([AuthServicesInfo(user=u.pk) for u in User.objects.all()])
|
||||||
|
|
||||||
|
# repopulate main characters
|
||||||
|
for profile in UserProfile.objects.exclude(main_character__isnull=True).select_related('user', 'main_character'):
|
||||||
|
AuthServicesInfo.objects.update_or_create(user=profile.user, defaults={'main_char_id': profile.main_character.character_id})
|
||||||
|
|
||||||
|
# repopulate states we understand
|
||||||
|
for profile in UserProfile.objects.exclude(state__name='Guest').filter(state__name__in=['Member', 'Blue']).select_related('user', 'state'):
|
||||||
|
AuthServicesInfo.objects.update_or_create(user=profile.user, defaults={'state': profile.state.name})
|
||||||
|
|
||||||
|
|
||||||
|
class Migration(migrations.Migration):
|
||||||
|
dependencies = [
|
||||||
|
('auth', '0008_alter_user_username_max_length'),
|
||||||
|
migrations.swappable_dependency(settings.AUTH_USER_MODEL),
|
||||||
|
('eveonline', '0008_remove_apikeys'),
|
||||||
|
('authentication', '0014_fleetup_permission'),
|
||||||
|
('esi', '0001_initial'),
|
||||||
|
]
|
||||||
|
|
||||||
|
operations = [
|
||||||
|
migrations.CreateModel(
|
||||||
|
name='CharacterOwnership',
|
||||||
|
fields=[
|
||||||
|
('id', models.AutoField(auto_created=True, primary_key=True, serialize=False, verbose_name='ID')),
|
||||||
|
('owner_hash', models.CharField(max_length=28, unique=True)),
|
||||||
|
('character',
|
||||||
|
models.OneToOneField(on_delete=django.db.models.deletion.CASCADE, related_name='character_ownership',
|
||||||
|
to='eveonline.EveCharacter')),
|
||||||
|
('user',
|
||||||
|
models.ForeignKey(on_delete=django.db.models.deletion.CASCADE, related_name='character_ownerships',
|
||||||
|
to=settings.AUTH_USER_MODEL)),
|
||||||
|
],
|
||||||
|
options={
|
||||||
|
'default_permissions': ('change', 'delete'),
|
||||||
|
},
|
||||||
|
),
|
||||||
|
migrations.CreateModel(
|
||||||
|
name='State',
|
||||||
|
fields=[
|
||||||
|
('id', models.AutoField(auto_created=True, primary_key=True, serialize=False, verbose_name='ID')),
|
||||||
|
('name', models.CharField(max_length=20, unique=True)),
|
||||||
|
('priority', models.IntegerField(unique=True)),
|
||||||
|
('public', models.BooleanField(default=False)),
|
||||||
|
('member_alliances', models.ManyToManyField(to='eveonline.EveAllianceInfo')),
|
||||||
|
('member_characters', models.ManyToManyField(to='eveonline.EveCharacter')),
|
||||||
|
('member_corporations', models.ManyToManyField(to='eveonline.EveCorporationInfo')),
|
||||||
|
('permissions', models.ManyToManyField(blank=True, to='auth.Permission')),
|
||||||
|
],
|
||||||
|
options={
|
||||||
|
'ordering': ['priority'],
|
||||||
|
},
|
||||||
|
),
|
||||||
|
migrations.CreateModel(
|
||||||
|
name='UserProfile',
|
||||||
|
fields=[
|
||||||
|
('id', models.AutoField(auto_created=True, primary_key=True, serialize=False, verbose_name='ID')),
|
||||||
|
('main_character',
|
||||||
|
models.OneToOneField(blank=True, null=True, on_delete=django.db.models.deletion.SET_NULL,
|
||||||
|
to='eveonline.EveCharacter')),
|
||||||
|
('state', models.ForeignKey(on_delete=models.SET(authentication.models.get_guest_state),
|
||||||
|
to='authentication.State')),
|
||||||
|
('user', models.OneToOneField(on_delete=django.db.models.deletion.CASCADE, related_name='profile',
|
||||||
|
to=settings.AUTH_USER_MODEL)),
|
||||||
|
],
|
||||||
|
options={
|
||||||
|
'default_permissions': ('change',),
|
||||||
|
},
|
||||||
|
),
|
||||||
|
migrations.RunPython(create_guest_state, migrations.RunPython.noop),
|
||||||
|
migrations.RunPython(create_member_state, create_member_group),
|
||||||
|
migrations.RunPython(create_blue_state, create_blue_group),
|
||||||
|
migrations.RunPython(populate_ownerships, migrations.RunPython.noop),
|
||||||
|
migrations.RunPython(create_profiles, recreate_authservicesinfo),
|
||||||
|
migrations.RemoveField(
|
||||||
|
model_name='authservicesinfo',
|
||||||
|
name='user',
|
||||||
|
),
|
||||||
|
migrations.DeleteModel(
|
||||||
|
name='AuthServicesInfo',
|
||||||
|
),
|
||||||
|
]
|
@ -1,40 +1,24 @@
|
|||||||
from __future__ import unicode_literals
|
from __future__ import unicode_literals
|
||||||
from django.utils.encoding import python_2_unicode_compatible
|
from django.utils.encoding import python_2_unicode_compatible
|
||||||
from django.db import models
|
from django.db import models
|
||||||
from django.contrib.auth.models import User
|
from django.contrib.auth.models import User, Permission
|
||||||
from authentication.states import MEMBER_STATE, BLUE_STATE, NONE_STATE
|
from authentication.managers import CharacterOwnershipManager, StateManager
|
||||||
from eveonline.models import EveCharacter
|
from eveonline.models import EveCharacter, EveCorporationInfo, EveAllianceInfo
|
||||||
|
|
||||||
|
|
||||||
@python_2_unicode_compatible
|
|
||||||
class AuthServicesInfo(models.Model):
|
|
||||||
class Meta:
|
|
||||||
default_permissions = ('change',)
|
|
||||||
|
|
||||||
STATE_CHOICES = (
|
|
||||||
(NONE_STATE, 'None'),
|
|
||||||
(BLUE_STATE, 'Blue'),
|
|
||||||
(MEMBER_STATE, 'Member'),
|
|
||||||
)
|
|
||||||
|
|
||||||
main_char_id = models.CharField(max_length=64, blank=True, default="")
|
|
||||||
user = models.OneToOneField(User)
|
|
||||||
state = models.CharField(blank=True, null=True, choices=STATE_CHOICES, default=NONE_STATE, max_length=10)
|
|
||||||
|
|
||||||
def __str__(self):
|
|
||||||
return self.user.username + ' - AuthInfo'
|
|
||||||
|
|
||||||
|
|
||||||
@python_2_unicode_compatible
|
@python_2_unicode_compatible
|
||||||
class State(models.Model):
|
class State(models.Model):
|
||||||
name = models.CharField(_('name'), max_length=20, unique=True)
|
name = models.CharField(max_length=20, unique=True)
|
||||||
permissions = models.ManyToManyField(
|
permissions = models.ManyToManyField(Permission, blank=True)
|
||||||
Permission,
|
|
||||||
verbose_name=_('permissions'),
|
|
||||||
blank=True,
|
|
||||||
)
|
|
||||||
priority = models.IntegerField(unique=True)
|
priority = models.IntegerField(unique=True)
|
||||||
|
|
||||||
|
member_characters = models.ManyToManyField(EveCharacter)
|
||||||
|
member_corporations = models.ManyToManyField(EveCorporationInfo)
|
||||||
|
member_alliances = models.ManyToManyField(EveAllianceInfo)
|
||||||
|
public = models.BooleanField(default=False)
|
||||||
|
|
||||||
|
objects = StateManager()
|
||||||
|
|
||||||
class Meta:
|
class Meta:
|
||||||
ordering = ['priority']
|
ordering = ['priority']
|
||||||
|
|
||||||
@ -42,8 +26,8 @@ class State(models.Model):
|
|||||||
return self.name
|
return self.name
|
||||||
|
|
||||||
|
|
||||||
def get_none_state():
|
def get_guest_state():
|
||||||
return State.objects.get_or_create(name='None')[0]
|
return State.objects.update_or_create(name='Guest', defaults={'priority': 0, 'public': True})[0]
|
||||||
|
|
||||||
|
|
||||||
@python_2_unicode_compatible
|
@python_2_unicode_compatible
|
||||||
@ -52,7 +36,28 @@ class UserProfile(models.Model):
|
|||||||
default_permissions = ('change',)
|
default_permissions = ('change',)
|
||||||
|
|
||||||
user = models.OneToOneField(User, related_name='profile', on_delete=models.CASCADE)
|
user = models.OneToOneField(User, related_name='profile', on_delete=models.CASCADE)
|
||||||
main_character = models.ForeignKey(EveCharacter, on_delete=models.CASCADE)
|
main_character = models.OneToOneField(EveCharacter, blank=True, null=True, on_delete=models.SET_NULL)
|
||||||
state = models.ForeignKey(State, on_delete=models.SET(get_none_state))
|
state = models.ForeignKey(State, on_delete=models.SET(get_guest_state))
|
||||||
|
|
||||||
|
def assign_state(self, commit=True):
|
||||||
|
self.state = State.objects.get_for_user(self.user)
|
||||||
|
if commit:
|
||||||
|
self.save(update_fields=['state'])
|
||||||
|
|
||||||
|
def __str__(self):
|
||||||
|
return "%s Profile" % self.user
|
||||||
|
|
||||||
|
|
||||||
|
@python_2_unicode_compatible
|
||||||
|
class CharacterOwnership(models.Model):
|
||||||
|
class Meta:
|
||||||
|
default_permissions = ('change', 'delete')
|
||||||
|
|
||||||
|
character = models.OneToOneField(EveCharacter, on_delete=models.CASCADE, related_name='character_ownership')
|
||||||
owner_hash = models.CharField(max_length=28, unique=True)
|
owner_hash = models.CharField(max_length=28, unique=True)
|
||||||
owner_token = models.ForeignKey(Token, on_delete=models.SET_NULL)
|
user = models.ForeignKey(User, on_delete=models.CASCADE, related_name='character_ownerships')
|
||||||
|
|
||||||
|
objects = CharacterOwnershipManager()
|
||||||
|
|
||||||
|
def __str__(self):
|
||||||
|
return "%s: %s" % (self.user, self.character)
|
||||||
|
@ -1,34 +1,70 @@
|
|||||||
from __future__ import unicode_literals
|
from __future__ import unicode_literals
|
||||||
from django.db.models.signals import pre_save, post_save
|
from django.db.models.signals import post_save, pre_delete
|
||||||
from django.dispatch import receiver
|
from django.dispatch import receiver
|
||||||
from django.contrib.auth.models import User
|
from django.contrib.auth.models import User
|
||||||
from authentication.models import AuthServicesInfo
|
from authentication.models import CharacterOwnership, UserProfile, get_guest_state
|
||||||
from authentication.states import MEMBER_STATE, BLUE_STATE
|
|
||||||
from authentication.tasks import make_member, make_blue, disable_member
|
|
||||||
from services.tasks import validate_services
|
from services.tasks import validate_services
|
||||||
|
from esi.models import Token
|
||||||
|
from eveonline.managers import EveManager
|
||||||
|
from eveonline.models import EveCharacter
|
||||||
import logging
|
import logging
|
||||||
|
|
||||||
logger = logging.getLogger(__name__)
|
logger = logging.getLogger(__name__)
|
||||||
|
|
||||||
|
|
||||||
@receiver(pre_save, sender=AuthServicesInfo)
|
# Is there a smarter way to intercept pre_save with a diff main_character or state?
|
||||||
def pre_save_auth_state(sender, instance, *args, **kwargs):
|
@receiver(post_save, sender=UserProfile)
|
||||||
if instance.pk:
|
def reassess_on_profile_save(sender, instance, created, *args, **kwargs):
|
||||||
old_instance = AuthServicesInfo.objects.get(pk=instance.pk)
|
# catches post_save from profiles to trigger necessary service and state checks
|
||||||
if old_instance.state != instance.state:
|
if not created:
|
||||||
logger.debug('Detected state change for %s' % instance.user)
|
update_fields = kwargs.pop('update_fields', [])
|
||||||
if instance.state == MEMBER_STATE:
|
if 'state' not in update_fields:
|
||||||
make_member(instance)
|
instance.assign_state()
|
||||||
elif instance.state == BLUE_STATE:
|
# TODO: how do we prevent running this twice on profile state change?
|
||||||
make_blue(instance)
|
validate_services(instance.user)
|
||||||
else:
|
|
||||||
disable_member(instance.user)
|
|
||||||
validate_services.apply(args=(instance.user,))
|
|
||||||
|
|
||||||
|
|
||||||
@receiver(post_save, sender=User)
|
@receiver(post_save, sender=User)
|
||||||
def post_save_user(sender, instance, created, *args, **kwargs):
|
def create_required_models(sender, instance, created, *args, **kwargs):
|
||||||
# ensure all users have a model
|
# ensure all users have a model
|
||||||
if created:
|
if created:
|
||||||
AuthServicesInfo.objects.get_or_create(user=instance)
|
UserProfile.objects.get_or_create(user=instance)
|
||||||
|
|
||||||
|
|
||||||
|
@receiver(post_save, sender=Token)
|
||||||
|
def record_character_ownership(sender, instance, created, *args, **kwargs):
|
||||||
|
if created:
|
||||||
|
# purge ownership records if the hash or auth user account has changed
|
||||||
|
CharacterOwnership.objects.filter(character__character_id=instance.character_id).exclude(
|
||||||
|
owner_hash=instance.owner_hash).exclude(user=instance.user).delete()
|
||||||
|
# create character if needed
|
||||||
|
if EveCharacter.objects.filter(character_id=instance.character_id).exists() is False:
|
||||||
|
EveManager.create_character(instance.character_id)
|
||||||
|
char = EveCharacter.objects.get(character_id=instance.character_id)
|
||||||
|
CharacterOwnership.objects.update_or_create(character=char,
|
||||||
|
defaults={'owner_hash': instance.owner_hash, 'user': instance.user})
|
||||||
|
|
||||||
|
|
||||||
|
@receiver(pre_delete, sender=CharacterOwnership)
|
||||||
|
def validate_main_character(sender, instance, *args, **kwargs):
|
||||||
|
if instance.user.profile.main_character == instance.character:
|
||||||
|
# clear main character as user no longer owns them
|
||||||
|
instance.user.profile.main_character = None
|
||||||
|
instance.user.profile.save()
|
||||||
|
|
||||||
|
|
||||||
|
@receiver(pre_delete, sender=Token)
|
||||||
|
def validate_main_character_token(sender, instance, *args, **kwargs):
|
||||||
|
if UserProfile.objects.filter(main_character__character_id=instance.character_id):
|
||||||
|
if not Token.objects.filter(character_id=instance.character_id).filter(user=instance.user).exists():
|
||||||
|
# clear main character as we can no longer verify ownership
|
||||||
|
instance.user.profile.main_character = None
|
||||||
|
instance.user.profile.save()
|
||||||
|
|
||||||
|
|
||||||
|
@receiver(post_save, sender=User)
|
||||||
|
def assign_state_on_reactivate(sender, instance, *args, **kwargs):
|
||||||
|
# There's no easy way to trigger an action upon saving from pre_save signal
|
||||||
|
# If we're saving a user and that user is in the Guest state, assume is_active was just set to True and assign state
|
||||||
|
if instance.is_active and instance.profile.state == get_guest_state():
|
||||||
|
instance.profile.assign_state()
|
||||||
|
@ -1,4 +0,0 @@
|
|||||||
from __future__ import unicode_literals
|
|
||||||
MEMBER_STATE = 'Member'
|
|
||||||
BLUE_STATE = 'Blue'
|
|
||||||
NONE_STATE = None
|
|
@ -1,189 +0,0 @@
|
|||||||
from __future__ import unicode_literals
|
|
||||||
from services.tasks import validate_services
|
|
||||||
from django.contrib.auth.models import Group
|
|
||||||
from authentication.models import AuthServicesInfo
|
|
||||||
from authentication.states import MEMBER_STATE, BLUE_STATE, NONE_STATE
|
|
||||||
from eveonline.models import EveCharacter, EveCorporationInfo
|
|
||||||
from notifications import notify
|
|
||||||
from django.conf import settings
|
|
||||||
import logging
|
|
||||||
|
|
||||||
logger = logging.getLogger(__name__)
|
|
||||||
|
|
||||||
|
|
||||||
def generate_corp_group_name(corpname):
|
|
||||||
return 'Corp_' + corpname.replace(' ', '_')
|
|
||||||
|
|
||||||
|
|
||||||
def generate_alliance_group_name(alliancename):
|
|
||||||
return 'Alliance_' + alliancename.replace(' ', '_')
|
|
||||||
|
|
||||||
|
|
||||||
def disable_member(user):
|
|
||||||
"""
|
|
||||||
Disable a member who is transitioning to a NONE state.
|
|
||||||
:param user: django.contrib.auth.models.User to disable
|
|
||||||
:return:
|
|
||||||
"""
|
|
||||||
logger.debug("Disabling member %s" % user)
|
|
||||||
if user.user_permissions.all().exists():
|
|
||||||
logger.info("Clearning user %s permission to deactivate user." % user)
|
|
||||||
user.user_permissions.clear()
|
|
||||||
if user.groups.all().exists():
|
|
||||||
logger.info("Clearing all non-public user %s groups to disable member." % user)
|
|
||||||
user.groups.remove(*user.groups.filter(authgroup__public=False))
|
|
||||||
validate_services.apply(args=(user,))
|
|
||||||
|
|
||||||
|
|
||||||
def disable_user(user):
|
|
||||||
"""
|
|
||||||
Disable a user who is being set inactive or deleted
|
|
||||||
:param user: django.contrib.auth.models.User to disable
|
|
||||||
:return:
|
|
||||||
"""
|
|
||||||
logger.debug("Disabling user %s" % user)
|
|
||||||
if user.user_permissions.all().exists():
|
|
||||||
logger.info("Clearning user %s permission to deactivate user." % user)
|
|
||||||
user.user_permissions.clear()
|
|
||||||
if user.groups.all().exists():
|
|
||||||
logger.info("Clearing user %s groups to deactivate user." % user)
|
|
||||||
user.groups.clear()
|
|
||||||
validate_services.apply(args=(user,))
|
|
||||||
|
|
||||||
|
|
||||||
def make_member(auth):
|
|
||||||
logger.debug("Ensuring user %s has member permissions and groups." % auth.user)
|
|
||||||
# ensure member is not blue right now
|
|
||||||
blue_group, c = Group.objects.get_or_create(name=settings.DEFAULT_BLUE_GROUP)
|
|
||||||
if blue_group in auth.user.groups.all():
|
|
||||||
logger.info("Removing user %s blue group" % auth.user)
|
|
||||||
auth.user.groups.remove(blue_group)
|
|
||||||
# make member
|
|
||||||
member_group, c = Group.objects.get_or_create(name=settings.DEFAULT_AUTH_GROUP)
|
|
||||||
if member_group not in auth.user.groups.all():
|
|
||||||
logger.info("Adding user %s to member group" % auth.user)
|
|
||||||
auth.user.groups.add(member_group)
|
|
||||||
assign_corp_group(auth)
|
|
||||||
assign_alliance_group(auth)
|
|
||||||
|
|
||||||
|
|
||||||
def make_blue(auth):
|
|
||||||
logger.debug("Ensuring user %s has blue permissions and groups." % auth.user)
|
|
||||||
# ensure user is not a member
|
|
||||||
member_group, c = Group.objects.get_or_create(name=settings.DEFAULT_AUTH_GROUP)
|
|
||||||
if member_group in auth.user.groups.all():
|
|
||||||
logger.info("Removing user %s member group" % auth.user)
|
|
||||||
auth.user.groups.remove(member_group)
|
|
||||||
# make blue
|
|
||||||
blue_group, c = Group.objects.get_or_create(name=settings.DEFAULT_BLUE_GROUP)
|
|
||||||
if blue_group not in auth.user.groups.all():
|
|
||||||
logger.info("Adding user %s to blue group" % auth.user)
|
|
||||||
auth.user.groups.add(blue_group)
|
|
||||||
assign_corp_group(auth)
|
|
||||||
assign_alliance_group(auth)
|
|
||||||
|
|
||||||
|
|
||||||
def determine_membership_by_character(char):
|
|
||||||
if str(char.corporation_id) in settings.STR_CORP_IDS:
|
|
||||||
logger.debug("Character %s in member corp id %s" % (char, char.corporation_id))
|
|
||||||
return MEMBER_STATE
|
|
||||||
elif str(char.alliance_id) in settings.STR_ALLIANCE_IDS:
|
|
||||||
logger.debug("Character %s in member alliance id %s" % (char, char.alliance_id))
|
|
||||||
return MEMBER_STATE
|
|
||||||
elif not EveCorporationInfo.objects.filter(corporation_id=char.corporation_id).exists():
|
|
||||||
logger.debug("No corp model for character %s corp id %s. Unable to check standings. Non-member." % (
|
|
||||||
char, char.corporation_id))
|
|
||||||
return NONE_STATE
|
|
||||||
else:
|
|
||||||
corp = EveCorporationInfo.objects.get(corporation_id=char.corporation_id)
|
|
||||||
if corp.is_blue:
|
|
||||||
logger.debug("Character %s member of blue corp %s" % (char, corp))
|
|
||||||
return BLUE_STATE
|
|
||||||
else:
|
|
||||||
logger.debug("Character %s member of non-blue corp %s. Non-member." % (char, corp))
|
|
||||||
return NONE_STATE
|
|
||||||
|
|
||||||
|
|
||||||
def determine_membership_by_user(user):
|
|
||||||
logger.debug("Determining membership of user %s" % user)
|
|
||||||
auth = AuthServicesInfo.objects.get(user=user)
|
|
||||||
if auth.main_char_id:
|
|
||||||
if EveCharacter.objects.filter(character_id=auth.main_char_id).exists():
|
|
||||||
char = EveCharacter.objects.get(character_id=auth.main_char_id)
|
|
||||||
return determine_membership_by_character(char)
|
|
||||||
else:
|
|
||||||
logger.debug("Character model matching user %s main character id %s does not exist. Non-member." % (
|
|
||||||
user, auth.main_char_id))
|
|
||||||
return NONE_STATE
|
|
||||||
else:
|
|
||||||
logger.debug("User %s has no main character set. Non-member." % user)
|
|
||||||
return NONE_STATE
|
|
||||||
|
|
||||||
|
|
||||||
def set_state(user):
|
|
||||||
if user.is_active:
|
|
||||||
state = determine_membership_by_user(user)
|
|
||||||
else:
|
|
||||||
state = NONE_STATE
|
|
||||||
logger.debug("Assigning user %s to state %s" % (user, state))
|
|
||||||
auth = AuthServicesInfo.objects.get(user=user)
|
|
||||||
if auth.state != state:
|
|
||||||
auth.state = state
|
|
||||||
auth.save()
|
|
||||||
notify(user, "Membership State Change", message="You membership state has been changed to %s" % state)
|
|
||||||
assign_corp_group(auth)
|
|
||||||
assign_alliance_group(auth)
|
|
||||||
|
|
||||||
|
|
||||||
def assign_corp_group(auth):
|
|
||||||
corp_group = None
|
|
||||||
if auth.main_char_id:
|
|
||||||
if EveCharacter.objects.filter(character_id=auth.main_char_id).exists():
|
|
||||||
char = EveCharacter.objects.get(character_id=auth.main_char_id)
|
|
||||||
corpname = generate_corp_group_name(char.corporation_name)
|
|
||||||
if auth.state == BLUE_STATE and settings.BLUE_CORP_GROUPS:
|
|
||||||
logger.debug("Validating blue user %s has corp group assigned." % auth.user)
|
|
||||||
corp_group, c = Group.objects.get_or_create(name=corpname)
|
|
||||||
elif auth.state == MEMBER_STATE and settings.MEMBER_CORP_GROUPS:
|
|
||||||
logger.debug("Validating member %s has corp group assigned." % auth.user)
|
|
||||||
corp_group, c = Group.objects.get_or_create(name=corpname)
|
|
||||||
else:
|
|
||||||
logger.debug("Ensuring %s has no corp groups assigned." % auth.user)
|
|
||||||
if corp_group:
|
|
||||||
if corp_group not in auth.user.groups.all():
|
|
||||||
logger.info("Adding user %s to corp group %s" % (auth.user, corp_group))
|
|
||||||
auth.user.groups.add(corp_group)
|
|
||||||
for g in auth.user.groups.all():
|
|
||||||
if str.startswith(str(g.name), "Corp_"):
|
|
||||||
if g != corp_group:
|
|
||||||
logger.info("Removing user %s from old corpgroup %s" % (auth.user, g))
|
|
||||||
auth.user.groups.remove(g)
|
|
||||||
|
|
||||||
|
|
||||||
def assign_alliance_group(auth):
|
|
||||||
alliance_group = None
|
|
||||||
if auth.main_char_id:
|
|
||||||
if EveCharacter.objects.filter(character_id=auth.main_char_id).exists():
|
|
||||||
char = EveCharacter.objects.get(character_id=auth.main_char_id)
|
|
||||||
if char.alliance_name:
|
|
||||||
alliancename = generate_alliance_group_name(char.alliance_name)
|
|
||||||
if auth.state == BLUE_STATE and settings.BLUE_ALLIANCE_GROUPS:
|
|
||||||
logger.debug("Validating blue user %s has alliance group assigned." % auth.user)
|
|
||||||
alliance_group, c = Group.objects.get_or_create(name=alliancename)
|
|
||||||
elif auth.state == MEMBER_STATE and settings.MEMBER_ALLIANCE_GROUPS:
|
|
||||||
logger.debug("Validating member %s has alliance group assigned." % auth.user)
|
|
||||||
alliance_group, c = Group.objects.get_or_create(name=alliancename)
|
|
||||||
else:
|
|
||||||
logger.debug("Ensuring %s has no alliance groups assigned." % auth.user)
|
|
||||||
else:
|
|
||||||
logger.debug("User %s main character %s not in an alliance. Ensuring no alliance group assigned." % (
|
|
||||||
auth.user, char))
|
|
||||||
if alliance_group:
|
|
||||||
if alliance_group not in auth.user.groups.all():
|
|
||||||
logger.info("Adding user %s to alliance group %s" % (auth.user, alliance_group))
|
|
||||||
auth.user.groups.add(alliance_group)
|
|
||||||
for g in auth.user.groups.all():
|
|
||||||
if str.startswith(str(g.name), "Alliance_"):
|
|
||||||
if g != alliance_group:
|
|
||||||
logger.info("Removing user %s from old alliance group %s" % (auth.user, g))
|
|
||||||
auth.user.groups.remove(g)
|
|
94
authentication/templates/authentication/dashboard.html
Normal file
94
authentication/templates/authentication/dashboard.html
Normal file
@ -0,0 +1,94 @@
|
|||||||
|
{% extends "registered/base.html" %}
|
||||||
|
{% load staticfiles %}
|
||||||
|
{% load i18n %}
|
||||||
|
|
||||||
|
{% block title %}{% trans "Dashboard" %}{% endblock %}
|
||||||
|
|
||||||
|
{% block content %}
|
||||||
|
<div class="col-lg-12">
|
||||||
|
<h1 class="page-header text-center">{% trans "Dashboard" %}</h1>
|
||||||
|
<div class="col-lg-12 container">
|
||||||
|
<div class="row">
|
||||||
|
<div class="col-lg-6 text-center">
|
||||||
|
<div class="panel panel-primary">
|
||||||
|
<div class="panel-heading">{% trans "Main Character" %}</div>
|
||||||
|
<div class="panel-body">
|
||||||
|
{% if request.user.profile.main_character %}
|
||||||
|
{% with request.user.profile.main_character as main %}
|
||||||
|
<div class="col-lg-4 col-sm-2">
|
||||||
|
<table class="table">
|
||||||
|
<tr><td class="text-center"><img class="ra-avatar" src="https://image.eveonline.com/Character/{{ main.character_id }}_128.jpg"></td></tr>
|
||||||
|
<tr><td class="text-center">{{ main.character_name }}</td></tr>
|
||||||
|
</table>
|
||||||
|
</div>
|
||||||
|
<div class="col-lg-4 col-sm-2">
|
||||||
|
<table class="table">
|
||||||
|
<tr><td class="text-center"><img class="ra-avatar" src="https://image.eveonline.com/Corporation/{{ main.corporation_id }}_128.png"></td></tr>
|
||||||
|
<tr><td class="text-center">{{ main.corporation_name }}</td></tr>
|
||||||
|
</table>
|
||||||
|
</div>
|
||||||
|
<div class="col-lg-4 col-sm-2">
|
||||||
|
{% if main.alliance_id %}
|
||||||
|
<table class="table">
|
||||||
|
<tr><td class="text-center"><img class="ra-avatar" src="https://image.eveonline.com/Alliance/{{ main.alliance_id }}_128.png"></td></tr>
|
||||||
|
<tr><td class="text-center">{{ main.alliance_name }}</td><tr>
|
||||||
|
</table>
|
||||||
|
{% endif %}
|
||||||
|
</div>
|
||||||
|
{% endwith %}
|
||||||
|
{% else %}
|
||||||
|
<div class="alert alert-danger" role="alert">{% trans "Missing main character model." %}</div>
|
||||||
|
{% endif %}
|
||||||
|
<div class="clearfix"></div>
|
||||||
|
<div class="col-xs-6">
|
||||||
|
<a href="{% url 'authentication:add_character' %}" class="btn btn-block btn-info" title="Add Character">{% trans 'Add Character' %}</a>
|
||||||
|
</div>
|
||||||
|
<div class="col-xs-6">
|
||||||
|
<a href="{% url 'authentication:change_main_character' %}" class="btn btn-block btn-info" title="Change Main Character">{% trans "Change Main" %}</a>
|
||||||
|
</div>
|
||||||
|
</div>
|
||||||
|
</div>
|
||||||
|
</div>
|
||||||
|
</div>
|
||||||
|
<div class="col-lg-6 text-center">
|
||||||
|
<div class="panel panel-success">
|
||||||
|
<div class="panel-heading">{% trans "Groups" %}</div>
|
||||||
|
<div class="panel-body">
|
||||||
|
<div style="height: 236px;overflow:-moz-scrollbars-vertical;overflow-y:auto;">
|
||||||
|
<table class="table table-striped">
|
||||||
|
{% for group in user.groups.all %}
|
||||||
|
<tr>
|
||||||
|
<td>{{ group.name }}</td>
|
||||||
|
</tr>
|
||||||
|
{% endfor %}
|
||||||
|
</table>
|
||||||
|
</div>
|
||||||
|
</div>
|
||||||
|
</div>
|
||||||
|
</div>
|
||||||
|
</div>
|
||||||
|
<div class="clearfix"></div>
|
||||||
|
<div class="panel panel-default">
|
||||||
|
<div class="panel-heading" style="display:flex;">{% trans 'Characters' %}</div>
|
||||||
|
<div class="panel-body">
|
||||||
|
<table class="table table-hover">
|
||||||
|
<tr>
|
||||||
|
<th class="text-center"></th>
|
||||||
|
<th class="text-center">{% trans 'Name' %}</th>
|
||||||
|
<th class="text-center">{% trans 'Corp' %}</th>
|
||||||
|
<th class="text-center">{% trans 'Alliance' %}</th>
|
||||||
|
</tr>
|
||||||
|
{% for ownership in request.user.character_ownerships.all %}
|
||||||
|
{% with ownership.character as char %}
|
||||||
|
<tr>
|
||||||
|
<td class="text-center">{{ char.character_name }}</td>
|
||||||
|
<td class="text-center">{{ char.corporation_name }}</td>
|
||||||
|
<td class="text-center">{{ char.alliance_name }}</td>
|
||||||
|
</tr>
|
||||||
|
{% endwith %}
|
||||||
|
{% endfor %}
|
||||||
|
</table>
|
||||||
|
</div>
|
||||||
|
</div>
|
||||||
|
</div>
|
||||||
|
{% endblock %}
|
49
authentication/templates/public/base.html
Normal file
49
authentication/templates/public/base.html
Normal file
@ -0,0 +1,49 @@
|
|||||||
|
<html lang="en">
|
||||||
|
<head>
|
||||||
|
<meta charset="utf-8">
|
||||||
|
<meta http-equiv="X-UA-Compatible" content="IE=edge">
|
||||||
|
<meta name="viewport" content="width=device-width, initial-scale=1">
|
||||||
|
<meta name="description" content="">
|
||||||
|
<meta name="author" content="">
|
||||||
|
|
||||||
|
<title>{% block title %}{{ SITE_NAME }}{% endblock %}</title>
|
||||||
|
|
||||||
|
{% include 'bundles/bootstrap-css.html' %}
|
||||||
|
{% include 'bundles/fontawesome.html' %}
|
||||||
|
{% block extra_include %}
|
||||||
|
{% endblock %}
|
||||||
|
|
||||||
|
<style>
|
||||||
|
body {
|
||||||
|
background: url('{% static 'img/index_images/index_blank_bg.jpg' %}') no-repeat scroll;
|
||||||
|
-webkit-background-size: cover;
|
||||||
|
-moz-background-size: cover;
|
||||||
|
-o-background-size: cover;
|
||||||
|
background-size: cover;
|
||||||
|
}
|
||||||
|
|
||||||
|
.panel-transparent {
|
||||||
|
background: rgba(48, 48, 48, 0.7);
|
||||||
|
color: #ffffff;
|
||||||
|
}
|
||||||
|
|
||||||
|
.panel-body {
|
||||||
|
|
||||||
|
}
|
||||||
|
|
||||||
|
#lang_select {
|
||||||
|
width: 40%;
|
||||||
|
margin-left: auto;
|
||||||
|
margin-right: auto;
|
||||||
|
}
|
||||||
|
{% block extra_style %}
|
||||||
|
{% endblock %}
|
||||||
|
</style>
|
||||||
|
</head>
|
||||||
|
<body>
|
||||||
|
<div class="container" style="margin-top:150px">
|
||||||
|
{% block content %}
|
||||||
|
{% endblock %}
|
||||||
|
</div>
|
||||||
|
</body>
|
||||||
|
</html>
|
15
authentication/templates/public/lang_select.html
Normal file
15
authentication/templates/public/lang_select.html
Normal file
@ -0,0 +1,15 @@
|
|||||||
|
{% load i18n %}
|
||||||
|
<div class="dropdown">
|
||||||
|
<form action="{% url 'set_language' %}" method="post">
|
||||||
|
{% csrf_token %}
|
||||||
|
<input name="next" type="hidden" value="{{ request.get_full_path|slice:'3:' }}" />
|
||||||
|
<select onchange="this.form.submit()" class="form-control" id="lang_select" name="language">
|
||||||
|
{% 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 }})
|
||||||
|
</option>
|
||||||
|
{% endfor %}
|
||||||
|
</select>
|
||||||
|
</form>
|
||||||
|
</div>
|
27
authentication/templates/public/login.html
Normal file
27
authentication/templates/public/login.html
Normal file
@ -0,0 +1,27 @@
|
|||||||
|
{% extends 'public/base.html' %}
|
||||||
|
{% block title %}Login{% endblock %}
|
||||||
|
{% block content %}
|
||||||
|
<div class="col-md-4 col-md-offset-4">
|
||||||
|
{% if messages %}
|
||||||
|
{% for message in messages %}
|
||||||
|
<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">
|
||||||
|
<p style="text-align:center">
|
||||||
|
<a href="{% url 'auth_sso_login' %}">
|
||||||
|
<img src="{% static 'img/sso/EVE_SSO_Login_Buttons_Large_Black.png' %}" border=0>
|
||||||
|
</a>
|
||||||
|
</p>
|
||||||
|
</div>
|
||||||
|
</div>
|
||||||
|
</div>
|
||||||
|
{% include 'public/lang_select.html' %}
|
||||||
|
</div>
|
||||||
|
{% endblock %}
|
||||||
|
{% block extra_include %}
|
||||||
|
{% include 'bundles/bootstrap-js.html' %}
|
||||||
|
{% endblock %}
|
||||||
|
|
24
authentication/templates/public/register.html
Normal file
24
authentication/templates/public/register.html
Normal file
@ -0,0 +1,24 @@
|
|||||||
|
{% load staticfiles %}
|
||||||
|
{% load bootstrap %}
|
||||||
|
{% load i18n %}
|
||||||
|
{% extends 'public/base.html' %}
|
||||||
|
{% block title %}Registration{% endblock %}
|
||||||
|
{% block extra_include %}
|
||||||
|
{% include 'bundles/bootstrap-css.html' %}
|
||||||
|
{% include 'bundles/fontawesome.html' %}
|
||||||
|
{% include 'bundles/bootstrap-js.html' %}
|
||||||
|
{% endblock %}
|
||||||
|
{% block content %}
|
||||||
|
<div class="col-md-4 col-md-offset-4">
|
||||||
|
<div class="panel panel-default panel-transparent">
|
||||||
|
<div class="panel-body">
|
||||||
|
<form method="POST">
|
||||||
|
{% csrf_token %}
|
||||||
|
{{ form|bootstrap }}
|
||||||
|
<button class="btn btn-lg btn-primary btn-block" type="submit">{% trans "Register" %}</button>
|
||||||
|
</form>
|
||||||
|
</div>
|
||||||
|
</div>
|
||||||
|
{% include 'public/lang_select.html' %}
|
||||||
|
</div>
|
||||||
|
{% endblock %}
|
62
stock/templates/public/base.html → authentication/templates/registered/base.html
Executable file → Normal file
62
stock/templates/public/base.html → authentication/templates/registered/base.html
Executable file → Normal file
@ -104,20 +104,19 @@
|
|||||||
<li class="text-center divider-horizontal">
|
<li class="text-center divider-horizontal">
|
||||||
<h5>{% trans "Aux Navigation" %}</h5>
|
<h5>{% trans "Aux Navigation" %}</h5>
|
||||||
</li>
|
</li>
|
||||||
|
|
||||||
<li>
|
<li>
|
||||||
<a class="{% navactive request 'auth_services' %}" href="{% url 'auth_services' %}">
|
<a class="{% navactive request 'auth_services' %}" href="{% url 'auth_services' %}">
|
||||||
<i class="fa fa-cogs fa-fw grayiconecolor"></i>{% trans " Services" %}
|
<i class="fa fa-cogs fa-fw grayiconecolor"></i>{% trans " Services" %}
|
||||||
</a>
|
</a>
|
||||||
</li>
|
</li>
|
||||||
|
|
||||||
{% if not STATE == MEMBER_STATE or perms.auth.human_resources %}
|
<li>
|
||||||
<li>
|
<a class="{% navactive request 'auth_hrapplications_view auth_hrapplication_create_view auth_hrapplication_personal_view auth_hrapplication_search auth_hrapplication_view' %}"
|
||||||
<a class="{% navactive request 'auth_hrapplications_view auth_hrapplication_create_view auth_hrapplication_personal_view auth_hrapplication_search auth_hrapplication_view' %}"
|
href="{% url 'auth_hrapplications_view' %}">
|
||||||
href="{% url 'auth_hrapplications_view' %}">
|
<i class="fa fa-file-o fa-fw grayiconecolor"></i>{% trans " Applications" %}
|
||||||
<i class="fa fa-file-o fa-fw grayiconecolor"></i>{% trans " Applications" %}
|
</a>
|
||||||
</a>
|
</li>
|
||||||
</li>
|
|
||||||
{% endif %}
|
|
||||||
|
|
||||||
{% if perms.corputils.view_corp_corpstats or perms.corputils.view_alliance_corpstats or perms.corputils.view_blue_corpstats %}
|
{% if perms.corputils.view_corp_corpstats or perms.corputils.view_alliance_corpstats or perms.corputils.view_blue_corpstats %}
|
||||||
<li>
|
<li>
|
||||||
@ -135,54 +134,47 @@
|
|||||||
</li>
|
</li>
|
||||||
{% endif %}
|
{% endif %}
|
||||||
|
|
||||||
{% if STATE in MEMBER_BLUE_STATE or user.is_superuser %}
|
{% if perms.auth.view_fleetup %}
|
||||||
<li>
|
<li>
|
||||||
<a class="{% navactive request 'auth_fleetup_view auth_fleetup_fittings auth_fleetup_fitting auth_fleetup_doctrines auth_fleetup_doctrine auth_fleetup_characters' %}" href="{% url 'auth_fleetup_view' %}">
|
<a class="{% navactive request 'auth_fleetup_view auth_fleetup_fittings auth_fleetup_fitting auth_fleetup_doctrines auth_fleetup_doctrine auth_fleetup_characters' %}" href="{% url 'auth_fleetup_view' %}">
|
||||||
<i class="fa fa-clock-o fa-fw grayiconecolor"></i> Fleet-Up
|
<i class="fa fa-clock-o fa-fw grayiconecolor"></i> Fleet-Up
|
||||||
</a>
|
</a>
|
||||||
</li>
|
</li>
|
||||||
|
{% endif %}
|
||||||
|
|
||||||
{% endif %}
|
{% if perms.auth.optimer_view %}
|
||||||
|
|
||||||
{% if STATE in MEMBER_BLUE_STATE or user.is_superuser %}
|
|
||||||
{% if perms.auth.optimer_view %}
|
|
||||||
<li>
|
<li>
|
||||||
<a class="{% navactive request 'auth_optimer_view auth_add_optimer_view auth_edit_optimer' %}" href="{% url 'auth_optimer_view' %}">
|
<a class="{% navactive request 'auth_optimer_view auth_add_optimer_view auth_edit_optimer' %}" href="{% url 'auth_optimer_view' %}">
|
||||||
<i class="fa fa-exclamation fa-fw grayiconecolor"></i>{% trans " Fleet Operations" %}
|
<i class="fa fa-exclamation fa-fw grayiconecolor"></i>{% trans " Fleet Operations" %}
|
||||||
</a>
|
</a>
|
||||||
</li>
|
</li>
|
||||||
{% endif %}
|
{% endif %}
|
||||||
{% if perms.auth.timer_view %}
|
|
||||||
<li>
|
|
||||||
<a class="{% navactive request 'auth_timer_view auth_add_timer_view auth_edit_timer' %}" href="{% url 'auth_timer_view' %}">
|
|
||||||
<i class="fa fa-clock-o fa-fw grayiconecolor"></i>{% trans " Structure Timers" %}
|
|
||||||
</a>
|
|
||||||
</li>
|
|
||||||
{% endif %}
|
|
||||||
|
|
||||||
|
{% if perms.auth.timer_view %}
|
||||||
<li>
|
<li>
|
||||||
<a class="{% navactive request 'auth_fatlink_view auth_fatlink_view_statistics auth_fatlink_view_statistics_month auth_fatlink_view_personal_statistics auth_fatlink_view_personal_statistics_year auth_fatlink_view_personal_statistics_month auth_fatlink_view_user_statistics_month auth_create_fatlink_view auth_modify_fatlink_view auth_click_fatlink_view' %}" href="{% url 'auth_fatlink_view' %}">
|
<a class="{% navactive request 'auth_timer_view auth_add_timer_view auth_edit_timer' %}" href="{% url 'auth_timer_view' %}">
|
||||||
<i class="fa fa-users fa-lightbulb-o fa-fw grayiconecolor"></i>{% trans " Fleet Activity Tracking" %}
|
<i class="fa fa-clock-o fa-fw grayiconecolor"></i>{% trans " Structure Timers" %}
|
||||||
</a>
|
|
||||||
</li>
|
|
||||||
|
|
||||||
<li>
|
|
||||||
<a class="{% navactive request 'auth_srp_management_view auth_srp_management_all_view auth_srp_fleet_view auth_srp_fleet_add_view auth_srp_fleet_edit_view auth_srp_request_view auth_srp_request_update_amount_view' %}" href="{% url 'auth_srp_management_view' %}">
|
|
||||||
<i class="fa fa-money fa-fw grayiconecolor"></i>{% trans " Ship Replacement" %}
|
|
||||||
</a>
|
</a>
|
||||||
</li>
|
</li>
|
||||||
{% endif %}
|
{% endif %}
|
||||||
|
|
||||||
|
<li>
|
||||||
|
<a class="{% navactive request 'auth_fatlink_view auth_fatlink_view_statistics auth_fatlink_view_statistics_month auth_fatlink_view_personal_statistics auth_fatlink_view_personal_statistics_year auth_fatlink_view_personal_statistics_month auth_fatlink_view_user_statistics_month auth_create_fatlink_view auth_modify_fatlink_view auth_click_fatlink_view' %}" href="{% url 'auth_fatlink_view' %}">
|
||||||
|
<i class="fa fa-users fa-lightbulb-o fa-fw grayiconecolor"></i>{% trans " Fleet Activity Tracking" %}
|
||||||
|
</a>
|
||||||
|
</li>
|
||||||
|
|
||||||
|
<li>
|
||||||
|
<a class="{% navactive request 'auth_srp_management_view auth_srp_management_all_view auth_srp_fleet_view auth_srp_fleet_add_view auth_srp_fleet_edit_view auth_srp_request_view auth_srp_request_update_amount_view' %}" href="{% url 'auth_srp_management_view' %}">
|
||||||
|
<i class="fa fa-money fa-fw grayiconecolor"></i>{% trans " Ship Replacement" %}
|
||||||
|
</a>
|
||||||
|
</li>
|
||||||
{% menu_aux %}
|
{% menu_aux %}
|
||||||
<li class="text-center divider-horizontal">
|
<li class="text-center divider-horizontal">
|
||||||
<h5>{% trans "Util" %}</h5>
|
<h5>{% trans "Util" %}</h5>
|
||||||
</li>
|
</li>
|
||||||
<li>
|
|
||||||
<a class="{% navactive request 'password_change password_change_done' %}" href="{% url 'password_change' %}">
|
|
||||||
<i class="fa fa-lock fa-fw grayiconecolor"></i>{% trans "Change Password" %}
|
|
||||||
</a>
|
|
||||||
</li>
|
|
||||||
|
|
||||||
{% if STATE in MEMBER_BLUE_STATE or user.is_superuser %}
|
{% if perms.auth.jabber_broadcast or perms.auth.jabber_broadcast_all or user.is_superuser %}
|
||||||
<li>
|
<li>
|
||||||
<a class="{% navactive request 'auth_fleet_format_tool_view' %}" href="{% url 'auth_fleet_format_tool_view' %}">
|
<a class="{% navactive request 'auth_fleet_format_tool_view' %}" href="{% url 'auth_fleet_format_tool_view' %}">
|
||||||
<i class="fa fa-space-shuttle fa-fw grayiconecolor"></i>{% trans " Fleet Broadcast Formatter" %}
|
<i class="fa fa-space-shuttle fa-fw grayiconecolor"></i>{% trans " Fleet Broadcast Formatter" %}
|
@ -1,4 +1,4 @@
|
|||||||
{% extends "public/base.html" %}
|
{% extends "registered/base.html" %}
|
||||||
{% load bootstrap %}
|
{% load bootstrap %}
|
||||||
{% load i18n static %}
|
{% load i18n static %}
|
||||||
|
|
@ -1,4 +1,4 @@
|
|||||||
{% extends "public/base.html" %}
|
{% extends "registered/base.html" %}
|
||||||
{% load bootstrap %}
|
{% load bootstrap %}
|
||||||
{% load i18n static %}
|
{% load i18n static %}
|
||||||
|
|
@ -1,84 +0,0 @@
|
|||||||
from __future__ import unicode_literals
|
|
||||||
|
|
||||||
try:
|
|
||||||
# Py3
|
|
||||||
from unittest import mock
|
|
||||||
except ImportError:
|
|
||||||
# Py2
|
|
||||||
import mock
|
|
||||||
|
|
||||||
from django.test import TestCase
|
|
||||||
from django.contrib.auth.models import Group, Permission
|
|
||||||
|
|
||||||
from alliance_auth.tests.auth_utils import AuthUtils
|
|
||||||
|
|
||||||
from authentication.tasks import disable_member, disable_user
|
|
||||||
|
|
||||||
|
|
||||||
class AuthenticationTasksTestCase(TestCase):
|
|
||||||
def setUp(self):
|
|
||||||
self.member = AuthUtils.create_member('auth_member')
|
|
||||||
self.none_user = AuthUtils.create_user('none_user', disconnect_signals=True)
|
|
||||||
|
|
||||||
@mock.patch('services.signals.transaction')
|
|
||||||
def test_disable_member(self, transaction):
|
|
||||||
# Inert signals action
|
|
||||||
transaction.on_commit.side_effect = lambda fn: fn()
|
|
||||||
|
|
||||||
# Add permission
|
|
||||||
perm = Permission.objects.create(codename='test_perm', name='test perm', content_type_id=1)
|
|
||||||
|
|
||||||
# Add public group
|
|
||||||
pub_group = Group.objects.create(name="A Public group")
|
|
||||||
pub_group.authgroup.internal = False
|
|
||||||
pub_group.authgroup.public = True
|
|
||||||
pub_group.save()
|
|
||||||
|
|
||||||
# Setup member
|
|
||||||
self.member.user_permissions.add(perm)
|
|
||||||
self.member.groups.add(pub_group)
|
|
||||||
|
|
||||||
# Pre assertion
|
|
||||||
self.assertIn(pub_group, self.member.groups.all())
|
|
||||||
self.assertGreater(len(self.member.groups.all()), 1)
|
|
||||||
|
|
||||||
# Act
|
|
||||||
disable_member(self.member)
|
|
||||||
|
|
||||||
# Assert
|
|
||||||
self.assertIn(pub_group, self.member.groups.all())
|
|
||||||
# Everything but the single public group wiped
|
|
||||||
self.assertEqual(len(self.member.groups.all()), 1)
|
|
||||||
# All permissions wiped
|
|
||||||
self.assertEqual(len(self.member.user_permissions.all()), 0)
|
|
||||||
|
|
||||||
@mock.patch('services.signals.transaction')
|
|
||||||
def test_disable_user(self, transaction):
|
|
||||||
# Inert signals action
|
|
||||||
transaction.on_commit.side_effect = lambda fn: fn()
|
|
||||||
|
|
||||||
# Add permission
|
|
||||||
perm = Permission.objects.create(codename='test_perm', name='test perm', content_type_id=1)
|
|
||||||
|
|
||||||
# Add public group
|
|
||||||
pub_group = Group.objects.create(name="A Public group")
|
|
||||||
pub_group.authgroup.internal = False
|
|
||||||
pub_group.authgroup.public = True
|
|
||||||
pub_group.save()
|
|
||||||
|
|
||||||
# Setup member
|
|
||||||
self.member.user_permissions.add(perm)
|
|
||||||
self.member.groups.add(pub_group)
|
|
||||||
|
|
||||||
# Pre assertion
|
|
||||||
self.assertIn(pub_group, self.member.groups.all())
|
|
||||||
self.assertGreater(len(self.member.groups.all()), 1)
|
|
||||||
|
|
||||||
# Act
|
|
||||||
disable_user(self.member)
|
|
||||||
|
|
||||||
# Assert
|
|
||||||
# All groups wiped
|
|
||||||
self.assertEqual(len(self.member.groups.all()), 0)
|
|
||||||
# All permissions wiped
|
|
||||||
self.assertEqual(len(self.member.user_permissions.all()), 0)
|
|
21
authentication/urls.py
Normal file
21
authentication/urls.py
Normal file
@ -0,0 +1,21 @@
|
|||||||
|
from django.conf.urls import url, include
|
||||||
|
from django.contrib.auth.decorators import login_required
|
||||||
|
from django.views.generic.base import TemplateView
|
||||||
|
from authentication import views
|
||||||
|
from registration.backends.hmac import urls
|
||||||
|
|
||||||
|
# inject our custom view classes into the HMAC scheme but use their urlpatterns because :efficiency:
|
||||||
|
urls.views = views
|
||||||
|
|
||||||
|
app_name = 'authentication'
|
||||||
|
|
||||||
|
urlpatterns = [
|
||||||
|
url(r'^$', TemplateView.as_view(template_name='public/login.html'), name='login'),
|
||||||
|
url(r'^account/login/$', TemplateView.as_view(template_name='public/login.html')),
|
||||||
|
url(r'^account/characters/main/$', views.main_character_change, name='change_main_character'),
|
||||||
|
url(r'^account/characters/add/$', views.add_character, name='add_character'),
|
||||||
|
url(r'^account/', include(urls, namespace='registration')),
|
||||||
|
url(r'^help/$', login_required(TemplateView.as_view(template_name='public/help.html')), name='help'),
|
||||||
|
url(r'^dashboard/$',
|
||||||
|
login_required(TemplateView.as_view(template_name='authentication/dashboard.html')), name='dashboard'),
|
||||||
|
]
|
@ -1,116 +1,123 @@
|
|||||||
from __future__ import unicode_literals
|
from __future__ import unicode_literals
|
||||||
from django.contrib.auth import login
|
from django.contrib.auth import login, authenticate
|
||||||
from django.contrib.auth import logout
|
from django.shortcuts import redirect
|
||||||
from django.contrib.auth import authenticate
|
|
||||||
from django.shortcuts import render, redirect
|
|
||||||
from django.contrib.auth.decorators import login_required
|
from django.contrib.auth.decorators import login_required
|
||||||
from django.utils.translation import ugettext_lazy as _
|
from django.utils.translation import ugettext_lazy as _
|
||||||
from eveonline.managers import EveManager
|
from authentication.forms import RegistrationForm
|
||||||
from eveonline.models import EveCharacter
|
from authentication.models import CharacterOwnership
|
||||||
from authentication.models import AuthServicesInfo
|
|
||||||
from authentication.forms import LoginForm, RegistrationForm
|
|
||||||
from django.contrib.auth.models import User
|
|
||||||
from django.contrib import messages
|
from django.contrib import messages
|
||||||
|
from django.contrib.auth.models import User
|
||||||
|
from django.conf import settings
|
||||||
|
from django.core import signing
|
||||||
from esi.decorators import token_required
|
from esi.decorators import token_required
|
||||||
|
from registration.backends.hmac.views import RegistrationView as BaseRegistrationView, \
|
||||||
|
ActivationView as BaseActivationView, REGISTRATION_SALT
|
||||||
|
from registration.signals import user_registered
|
||||||
import logging
|
import logging
|
||||||
|
|
||||||
logger = logging.getLogger(__name__)
|
logger = logging.getLogger(__name__)
|
||||||
|
|
||||||
|
|
||||||
def login_user(request):
|
|
||||||
logger.debug("login_user called by user %s" % request.user)
|
|
||||||
if request.method == 'POST':
|
|
||||||
form = LoginForm(request.POST)
|
|
||||||
logger.debug("Request of type POST, received form, valid: %s" % form.is_valid())
|
|
||||||
if form.is_valid():
|
|
||||||
user = authenticate(username=form.cleaned_data['username'], password=form.cleaned_data['password'])
|
|
||||||
logger.debug("Authentication attempt with supplied credentials. Received user %s" % user)
|
|
||||||
if user is not None:
|
|
||||||
if user.is_active:
|
|
||||||
logger.info("Successful login attempt from user %s" % user)
|
|
||||||
login(request, user)
|
|
||||||
redirect_to = request.POST.get('next', request.GET.get('next', ''))
|
|
||||||
if not redirect_to:
|
|
||||||
redirect_to = 'auth_dashboard'
|
|
||||||
return redirect(redirect_to)
|
|
||||||
else:
|
|
||||||
logger.info("Login attempt failed for user %s: user marked inactive." % user)
|
|
||||||
messages.warning(request, _('Your account has been disabled.'))
|
|
||||||
else:
|
|
||||||
logger.info("Failed login attempt: provided username %s" % form.cleaned_data['username'])
|
|
||||||
messages.error(request, _('Username/password invalid.'))
|
|
||||||
return render(request, 'public/login.html', context={'form': form})
|
|
||||||
else:
|
|
||||||
logger.debug("Providing new login form.")
|
|
||||||
form = LoginForm()
|
|
||||||
|
|
||||||
return render(request, 'public/login.html', context={'form': form})
|
|
||||||
|
|
||||||
|
|
||||||
def logout_user(request):
|
|
||||||
logger.debug("logout_user called by user %s" % request.user)
|
|
||||||
temp_user = request.user
|
|
||||||
logout(request)
|
|
||||||
logger.info("Successful logout for user %s" % temp_user)
|
|
||||||
return redirect("auth_index")
|
|
||||||
|
|
||||||
|
|
||||||
def register_user_view(request):
|
|
||||||
logger.debug("register_user_view called by user %s" % request.user)
|
|
||||||
if request.method == 'POST':
|
|
||||||
form = RegistrationForm(request.POST)
|
|
||||||
logger.debug("Request type POST contains form valid: %s" % form.is_valid())
|
|
||||||
if form.is_valid():
|
|
||||||
|
|
||||||
if not User.objects.filter(username=form.cleaned_data['username']).exists():
|
|
||||||
user = User.objects.create_user(form.cleaned_data['username'],
|
|
||||||
form.cleaned_data['email'], form.cleaned_data['password'])
|
|
||||||
|
|
||||||
user.save()
|
|
||||||
logger.info("Created new user %s" % user)
|
|
||||||
login(request, user)
|
|
||||||
messages.warning(request, _('Add an API key to set up your account.'))
|
|
||||||
return redirect("auth_dashboard")
|
|
||||||
|
|
||||||
else:
|
|
||||||
logger.error("Unable to register new user: username %s already exists." % form.cleaned_data['username'])
|
|
||||||
return render(request, 'public/register.html', context={'form': form, 'error': True})
|
|
||||||
else:
|
|
||||||
logger.debug("Registration form invalid. Returning for user %s to make corrections." % request.user)
|
|
||||||
|
|
||||||
else:
|
|
||||||
logger.debug("Returning blank registration form.")
|
|
||||||
form = RegistrationForm()
|
|
||||||
|
|
||||||
return render(request, 'public/register.html', context={'form': form})
|
|
||||||
|
|
||||||
|
|
||||||
def index_view(request):
|
|
||||||
logger.debug("index_view called by user %s" % request.user)
|
|
||||||
return render(request, 'public/index.html')
|
|
||||||
|
|
||||||
|
|
||||||
@login_required
|
@login_required
|
||||||
def help_view(request):
|
@token_required(scopes=settings.LOGIN_TOKEN_SCOPES)
|
||||||
logger.debug("help_view called by user %s" % request.user)
|
def main_character_change(request, token):
|
||||||
return render(request, 'registered/help.html')
|
logger.debug("main_character_change called by user %s for character %s" % (request.user, token.character_name))
|
||||||
|
|
||||||
|
|
||||||
@token_required(new=True)
|
|
||||||
def sso_login(request, token):
|
|
||||||
try:
|
try:
|
||||||
char = EveCharacter.objects.get(character_id=token.character_id)
|
co = CharacterOwnership.objects.get(character__character_id=token.character_id)
|
||||||
if char.user:
|
except CharacterOwnership.DoesNotExist:
|
||||||
if char.user.is_active:
|
co = CharacterOwnership.objects.create_by_token(token)
|
||||||
login(request, char.user)
|
request.user.profile.main_character = co.character
|
||||||
token.user = char.user
|
request.user.profile.save(update_fields=['main_character'])
|
||||||
token.save()
|
messages.success(request, _('Changed main character to %(char)s') % {"char": co.character})
|
||||||
return redirect('auth_dashboard')
|
return redirect("auth_dashboard")
|
||||||
else:
|
|
||||||
messages.error(request, _('Your account has been disabled.'))
|
|
||||||
else:
|
@token_required(new=True, scopes=settings.LOGIN_TOKEN_SCOPES)
|
||||||
messages.warning(request,
|
def add_character(request, token):
|
||||||
_('Authenticated character has no owning account. Please log in with username and password.'))
|
if CharacterOwnership.objects.filter(character__character_id=token.character_id).filter(
|
||||||
except EveCharacter.DoesNotExist:
|
owner_hash=token.character_owner_hash).filter(user=request.user).exists():
|
||||||
messages.error(request, _('No account exists with the authenticated character. Please create an account first.'))
|
messages.success(request, _('Added %(name)s to your account.'% ({'name': token.character_name})))
|
||||||
return redirect(login_user)
|
else:
|
||||||
|
messages.error(request, _('Failed to add %(name)s to your account.' % ({'name': token.charater_name})))
|
||||||
|
return redirect('authentication:dashboard')
|
||||||
|
|
||||||
|
|
||||||
|
"""
|
||||||
|
Override the HMAC two-step registration view to accommodate the three-step registration required.
|
||||||
|
Step 1: OAuth token to create user and profile.
|
||||||
|
Step 2: Get email and send activation link (but do not save email).
|
||||||
|
Step 3: Get link, save email and activate.
|
||||||
|
|
||||||
|
Step 1 is necessary to automatically assign character ownership and a main character, both of which require a saved User
|
||||||
|
model - this means the ensuing registration form cannot create the user because it already exists.
|
||||||
|
|
||||||
|
Email is not saved to the user model in Step 2 as a way of differentiating users who have not yet completed registration
|
||||||
|
(is_active=False) and users who have been disabled by an admin (is_active=False, email present).
|
||||||
|
|
||||||
|
Because of this, the email address needs to be assigned in Step 3 after clicking the link, which means the link must
|
||||||
|
have the email address embedded much like the username. Key creation and decoding is overridden to support this action.
|
||||||
|
"""
|
||||||
|
|
||||||
|
|
||||||
|
# Step 1
|
||||||
|
@token_required(new=True, scopes=settings.LOGIN_TOKEN_SCOPES)
|
||||||
|
def sso_login(request, token):
|
||||||
|
user = authenticate(token=token)
|
||||||
|
if user and user.is_active:
|
||||||
|
login(request, user)
|
||||||
|
return redirect(request.POST.get('next', request.GET.get('next', 'auth_dashboard')))
|
||||||
|
elif user and not user.email:
|
||||||
|
# Store the new user PK in the session to enable us to identify the registering user in Step 2
|
||||||
|
request.session['registration_uid'] = user.pk
|
||||||
|
# Go to Step 2
|
||||||
|
return redirect('authentication:register')
|
||||||
|
else:
|
||||||
|
messages.error(request, _('Unable to authenticate as the selected character.'))
|
||||||
|
return redirect(settings.LOGIN_URL)
|
||||||
|
|
||||||
|
|
||||||
|
# Step 2
|
||||||
|
class RegistrationView(BaseRegistrationView):
|
||||||
|
form_class = RegistrationForm
|
||||||
|
success_url = 'authentication:dashboard'
|
||||||
|
|
||||||
|
def dispatch(self, *args, **kwargs):
|
||||||
|
# We're storing a key in the session to pass user information from OAuth response. Make sure it's there.
|
||||||
|
if not self.request.session.get('registration_uid', None) or not User.objects.filter(
|
||||||
|
pk=self.request.session.get('registration_uid')).exists():
|
||||||
|
messages.error(self.request, _('Registration token has expired.'))
|
||||||
|
return redirect(settings.LOGIN_URL)
|
||||||
|
return super(RegistrationView, self).dispatch(*args, **kwargs)
|
||||||
|
|
||||||
|
def register(self, form):
|
||||||
|
user = User.objects.get(pk=self.request.session.get('registration_uid'))
|
||||||
|
user.email = form.cleaned_data['email']
|
||||||
|
user_registered.send(self.__class__, user=user, request=self.request)
|
||||||
|
# Go to Step 3
|
||||||
|
self.send_activation_email(user)
|
||||||
|
return user
|
||||||
|
|
||||||
|
def get_activation_key(self, user):
|
||||||
|
return signing.dumps(obj=[getattr(user, User.USERNAME_FIELD), user.email], salt=REGISTRATION_SALT)
|
||||||
|
|
||||||
|
|
||||||
|
# Step 3
|
||||||
|
class ActivationView(BaseActivationView):
|
||||||
|
def validate_key(self, activation_key):
|
||||||
|
try:
|
||||||
|
dump = signing.loads(activation_key, salt=REGISTRATION_SALT,
|
||||||
|
max_age=settings.ACCOUNT_ACTIVATION_DAYS * 86400)
|
||||||
|
return dump
|
||||||
|
except signing.BadSignature:
|
||||||
|
return None
|
||||||
|
|
||||||
|
def activate(self, *args, **kwargs):
|
||||||
|
dump = self.validate_key(kwargs.get('activation_key'))
|
||||||
|
if dump:
|
||||||
|
user = self.get_user(dump[0])
|
||||||
|
if user:
|
||||||
|
user.email = dump[1]
|
||||||
|
user.is_active = True
|
||||||
|
user.save()
|
||||||
|
return user
|
||||||
|
return False
|
||||||
|
@ -1,6 +1,4 @@
|
|||||||
from django.db import models
|
from django.db import models
|
||||||
from authentication.models import AuthServicesInfo
|
|
||||||
from eveonline.models import EveCharacter
|
|
||||||
|
|
||||||
|
|
||||||
class CorpStatsQuerySet(models.QuerySet):
|
class CorpStatsQuerySet(models.QuerySet):
|
||||||
@ -9,9 +7,9 @@ class CorpStatsQuerySet(models.QuerySet):
|
|||||||
if user.is_superuser:
|
if user.is_superuser:
|
||||||
return self
|
return self
|
||||||
|
|
||||||
auth = AuthServicesInfo.objects.get(user=user)
|
|
||||||
try:
|
try:
|
||||||
char = EveCharacter.objects.get(character_id=auth.main_char_id)
|
assert user.profile.main_character
|
||||||
|
char = user.profile.main_character
|
||||||
# build all accepted queries
|
# build all accepted queries
|
||||||
queries = []
|
queries = []
|
||||||
if user.has_perm('corputils.view_corp_corpstats'):
|
if user.has_perm('corputils.view_corp_corpstats'):
|
||||||
@ -30,7 +28,7 @@ class CorpStatsQuerySet(models.QuerySet):
|
|||||||
else:
|
else:
|
||||||
# not allowed to see any
|
# not allowed to see any
|
||||||
return self.none()
|
return self.none()
|
||||||
except EveCharacter.DoesNotExist:
|
except AssertionError:
|
||||||
return self.none()
|
return self.none()
|
||||||
|
|
||||||
|
|
||||||
|
19
corputils/migrations/0003_auto_20170322_2335.py
Normal file
19
corputils/migrations/0003_auto_20170322_2335.py
Normal file
@ -0,0 +1,19 @@
|
|||||||
|
# -*- coding: utf-8 -*-
|
||||||
|
# Generated by Django 1.10.5 on 2017-03-22 23:35
|
||||||
|
from __future__ import unicode_literals
|
||||||
|
|
||||||
|
from django.db import migrations
|
||||||
|
|
||||||
|
|
||||||
|
class Migration(migrations.Migration):
|
||||||
|
|
||||||
|
dependencies = [
|
||||||
|
('corputils', '0002_migrate_permissions'),
|
||||||
|
]
|
||||||
|
|
||||||
|
operations = [
|
||||||
|
migrations.AlterModelOptions(
|
||||||
|
name='corpstats',
|
||||||
|
options={'permissions': (('corp_apis', 'Can view API keys of members of their corporation.'), ('alliance_apis', 'Can view API keys of members of their alliance.'), ('blue_apis', 'Can view API keys of members of blue corporations.'), ('view_corp_corpstats', 'Can view corp stats of their corporation.'), ('view_alliance_corpstats', 'Can view corp stats of members of their alliance.'), ('view_blue_corpstats', 'Can view corp stats of blue corporations.')), 'verbose_name': 'corp stats', 'verbose_name_plural': 'corp stats'},
|
||||||
|
),
|
||||||
|
]
|
@ -1,11 +1,11 @@
|
|||||||
from __future__ import unicode_literals
|
from __future__ import unicode_literals
|
||||||
from django.utils.encoding import python_2_unicode_compatible
|
from django.utils.encoding import python_2_unicode_compatible
|
||||||
from django.db import models
|
from django.db import models
|
||||||
from eveonline.models import EveCorporationInfo, EveCharacter, EveApiKeyPair
|
from eveonline.models import EveCorporationInfo, EveCharacter
|
||||||
from esi.models import Token
|
from esi.models import Token
|
||||||
from esi.errors import TokenError
|
from esi.errors import TokenError
|
||||||
from notifications import notify
|
from notifications import notify
|
||||||
from authentication.models import AuthServicesInfo
|
from authentication.models import CharacterOwnership, UserProfile
|
||||||
from bravado.exception import HTTPForbidden
|
from bravado.exception import HTTPForbidden
|
||||||
from corputils.managers import CorpStatsManager
|
from corputils.managers import CorpStatsManager
|
||||||
from operator import attrgetter
|
from operator import attrgetter
|
||||||
@ -97,62 +97,32 @@ class CorpStats(models.Model):
|
|||||||
def member_names(self):
|
def member_names(self):
|
||||||
return [name for id, name in self.members.items()]
|
return [name for id, name in self.members.items()]
|
||||||
|
|
||||||
def show_apis(self, user):
|
|
||||||
auth = AuthServicesInfo.objects.get(user=user)
|
|
||||||
if auth.main_char_id:
|
|
||||||
try:
|
|
||||||
char = EveCharacter.objects.get(character_id=auth.main_char_id)
|
|
||||||
if char.corporation_id == self.corp.corporation_id and user.has_perm('corputils.corp_apis'):
|
|
||||||
return True
|
|
||||||
if self.corp.alliance and char.alliance_id == self.corp.alliance.alliance_id and user.has_perm(
|
|
||||||
'corputils.alliance_apis'):
|
|
||||||
return True
|
|
||||||
if user.has_perm('corputils.blue_apis') and self.corp.is_blue:
|
|
||||||
return True
|
|
||||||
except EveCharacter.DoesNotExist:
|
|
||||||
pass
|
|
||||||
return user.is_superuser
|
|
||||||
|
|
||||||
def entered_apis(self):
|
|
||||||
return EveCharacter.objects.filter(character_id__in=self.member_ids).exclude(api_id__isnull=True).count()
|
|
||||||
|
|
||||||
def member_count(self):
|
def member_count(self):
|
||||||
return len(self.members)
|
return len(self.members)
|
||||||
|
|
||||||
def user_count(self, members):
|
@staticmethod
|
||||||
|
def user_count(members):
|
||||||
mainchars = []
|
mainchars = []
|
||||||
for member in members:
|
for member in members:
|
||||||
if hasattr(member.main, 'character_name'):
|
if hasattr(member.main, 'character_name'):
|
||||||
mainchars.append(member.main.character_name)
|
mainchars.append(member.main.character_name)
|
||||||
return len(set(mainchars))
|
return len(set(mainchars))
|
||||||
|
|
||||||
|
def registered_characters(self):
|
||||||
|
return len(CharacterOwnership.objects.filter(character__character_id__in=self.member_ids))
|
||||||
|
|
||||||
@python_2_unicode_compatible
|
@python_2_unicode_compatible
|
||||||
class MemberObject(object):
|
class MemberObject(object):
|
||||||
def __init__(self, character_id, character_name, show_apis=False):
|
def __init__(self, character_id, character_name):
|
||||||
self.character_id = character_id
|
self.character_id = character_id
|
||||||
self.character_name = character_name
|
self.character_name = character_name
|
||||||
try:
|
try:
|
||||||
char = EveCharacter.objects.get(character_id=character_id)
|
char = EveCharacter.objects.get(character_id=character_id)
|
||||||
auth = AuthServicesInfo.objects.get(user=char.user)
|
self.main_user = char.character_ownership.user
|
||||||
try:
|
self.main = self.main_user.profile.main_character
|
||||||
self.main = EveCharacter.objects.get(character_id=auth.main_char_id)
|
|
||||||
self.main_user = self.main.character_name
|
|
||||||
except EveCharacter.DoesNotExist:
|
|
||||||
self.main = None
|
|
||||||
self.main_user = ''
|
|
||||||
api = EveApiKeyPair.objects.get(api_id=char.api_id)
|
|
||||||
self.registered = True
|
self.registered = True
|
||||||
if show_apis:
|
except (EveCharacter.DoesNotExist, CharacterOwnership.DoesNotExist, UserProfile.DoesNotExist, AttributeError):
|
||||||
self.api = api
|
|
||||||
else:
|
|
||||||
self.api = None
|
|
||||||
except (EveCharacter.DoesNotExist, AuthServicesInfo.DoesNotExist):
|
|
||||||
self.main = None
|
self.main = None
|
||||||
self.api = None
|
|
||||||
self.registered = False
|
|
||||||
self.main_user = ''
|
|
||||||
except EveApiKeyPair.DoesNotExist:
|
|
||||||
self.api = None
|
|
||||||
self.registered = False
|
self.registered = False
|
||||||
self.main_user = ''
|
self.main_user = ''
|
||||||
|
|
||||||
@ -162,9 +132,8 @@ class CorpStats(models.Model):
|
|||||||
def portrait_url(self, size=32):
|
def portrait_url(self, size=32):
|
||||||
return "https://image.eveonline.com/Character/%s_%s.jpg" % (self.character_id, size)
|
return "https://image.eveonline.com/Character/%s_%s.jpg" % (self.character_id, size)
|
||||||
|
|
||||||
def get_member_objects(self, user):
|
def get_member_objects(self):
|
||||||
show_apis = self.show_apis(user)
|
member_list = [CorpStats.MemberObject(id, name) for id, name in self.members.items()]
|
||||||
member_list = [CorpStats.MemberObject(id, name, show_apis=show_apis) for id, name in self.members.items()]
|
|
||||||
outlist = sorted([m for m in member_list if m.main_user], key=attrgetter('main_user', 'character_name'))
|
outlist = sorted([m for m in member_list if m.main_user], key=attrgetter('main_user', 'character_name'))
|
||||||
outlist = outlist + sorted([m for m in member_list if not m.main_user], key=attrgetter('character_name'))
|
outlist = outlist + sorted([m for m in member_list if not m.main_user], key=attrgetter('character_name'))
|
||||||
return outlist
|
return outlist
|
||||||
@ -180,8 +149,7 @@ class CorpStats(models.Model):
|
|||||||
self.can_update = corpstats.can_update(user)
|
self.can_update = corpstats.can_update(user)
|
||||||
self.total_members = len(self.members)
|
self.total_members = len(self.members)
|
||||||
self.total_users = corpstats.user_count(self.members)
|
self.total_users = corpstats.user_count(self.members)
|
||||||
self.registered_members = corpstats.entered_apis()
|
self.registered_members = corpstats.registered_characters()
|
||||||
self.show_apis = corpstats.show_apis(user)
|
|
||||||
self.last_updated = corpstats.last_update
|
self.last_updated = corpstats.last_update
|
||||||
|
|
||||||
def __str__(self):
|
def __str__(self):
|
||||||
|
@ -1,4 +1,4 @@
|
|||||||
{% extends 'public/base.html' %}
|
{% extends 'registered/base.html' %}
|
||||||
{% load i18n %}
|
{% load i18n %}
|
||||||
{% block title %}{% trans "Corporation Member Data" %}{% endblock %}
|
{% block title %}{% trans "Corporation Member Data" %}{% endblock %}
|
||||||
{% block page_title %}{% trans "Corporation Member Data" %}{% endblock %}
|
{% block page_title %}{% trans "Corporation Member Data" %}{% endblock %}
|
||||||
|
@ -58,9 +58,6 @@
|
|||||||
<tr>
|
<tr>
|
||||||
<th></th>
|
<th></th>
|
||||||
<th class="text-center">{% trans "Character" %}</th>
|
<th class="text-center">{% trans "Character" %}</th>
|
||||||
{% if corpstats.show_apis %}
|
|
||||||
<th class="text-center">API</th>
|
|
||||||
{% endif %}
|
|
||||||
<th class="text-center">{% trans "zKillboard" %}</th>
|
<th class="text-center">{% trans "zKillboard" %}</th>
|
||||||
<th class="text-center">{% trans "Main Character" %}</th>
|
<th class="text-center">{% trans "Main Character" %}</th>
|
||||||
<th class="text-center">{% trans "Main Corporation" %}</th>
|
<th class="text-center">{% trans "Main Corporation" %}</th>
|
||||||
@ -70,13 +67,6 @@
|
|||||||
<tr {% if not member.registered %}class="danger"{% endif %}>
|
<tr {% if not member.registered %}class="danger"{% endif %}>
|
||||||
<td><img src="{{ member.portrait_url }}" class="img-circle"></td>
|
<td><img src="{{ member.portrait_url }}" class="img-circle"></td>
|
||||||
<td class="text-center">{{ member.character_name }}</td>
|
<td class="text-center">{{ member.character_name }}</td>
|
||||||
{% if corpstats.show_apis %}
|
|
||||||
{% if member.api %}
|
|
||||||
<td class="text-center">{{ member.api|api_link:'label label-primary' }}</td>
|
|
||||||
{% else %}
|
|
||||||
<td></td>
|
|
||||||
{% endif %}
|
|
||||||
{% endif %}
|
|
||||||
<td class="text-center"><a href="https://zkillboard.com/character/{{ member.character_id }}/" class="label label-danger" target="_blank">{% trans "Killboard" %}</a></td>
|
<td class="text-center"><a href="https://zkillboard.com/character/{{ member.character_id }}/" class="label label-danger" target="_blank">{% trans "Killboard" %}</a></td>
|
||||||
<td class="text-center">{{ member.main.character_name }}</td>
|
<td class="text-center">{{ member.main.character_name }}</td>
|
||||||
<td class="text-center">{{ member.main.corporation_name }}</td>
|
<td class="text-center">{{ member.main.corporation_name }}</td>
|
||||||
|
@ -16,7 +16,6 @@
|
|||||||
<th class="text-center"></th>
|
<th class="text-center"></th>
|
||||||
<th class="text-center">{% trans "Character" %}</th>
|
<th class="text-center">{% trans "Character" %}</th>
|
||||||
<th class="text-center">{% trans "Corporation" %}</th>
|
<th class="text-center">{% trans "Corporation" %}</th>
|
||||||
<th class="text-center">{% trans "API" %}</th>
|
|
||||||
<th class="text-center">{% trans "zKillboard" %}</th>
|
<th class="text-center">{% trans "zKillboard" %}</th>
|
||||||
<th class="text-center">{% trans "Main Character" %}</th>
|
<th class="text-center">{% trans "Main Character" %}</th>
|
||||||
<th class="text-center">{% trans "Main Corporation" %}</th>
|
<th class="text-center">{% trans "Main Corporation" %}</th>
|
||||||
@ -27,11 +26,6 @@
|
|||||||
<td class="text-center"><img src="{{ result.1.portrait_url }}" class="img-circle"></td>
|
<td class="text-center"><img src="{{ result.1.portrait_url }}" class="img-circle"></td>
|
||||||
<td class="text-center">{{ result.1.character_name }}</td>
|
<td class="text-center">{{ result.1.character_name }}</td>
|
||||||
<td class="text-center">{{ result.0.corp.corporation_name }}</td>
|
<td class="text-center">{{ result.0.corp.corporation_name }}</td>
|
||||||
{% if result.1.api %}
|
|
||||||
<td class="text-center">{{ result.1.api|api_link:"label label-primary" }}</td>
|
|
||||||
{% else %}
|
|
||||||
<td></td>
|
|
||||||
{% endif %}
|
|
||||||
<td class="text-center"><a href="https://zkillboard.com/character/{{ result.1.character_id }}/" class="label label-danger" target="_blank">{% trans "Killboard" %}</a></td>
|
<td class="text-center"><a href="https://zkillboard.com/character/{{ result.1.character_id }}/" class="label label-danger" target="_blank">{% trans "Killboard" %}</a></td>
|
||||||
<td class="text-center">{{ result.1.main.character_name }}</td>
|
<td class="text-center">{{ result.1.main.character_name }}</td>
|
||||||
<td class="text-center">{{ result.1.main.corporation_name }}</td>
|
<td class="text-center">{{ result.1.main.corporation_name }}</td>
|
||||||
|
@ -1,5 +1,4 @@
|
|||||||
from __future__ import unicode_literals
|
from __future__ import unicode_literals
|
||||||
from django.conf import settings
|
|
||||||
from django.contrib.auth.decorators import login_required, permission_required, user_passes_test
|
from django.contrib.auth.decorators import login_required, permission_required, user_passes_test
|
||||||
from django.shortcuts import render, redirect, get_object_or_404
|
from django.shortcuts import render, redirect, get_object_or_404
|
||||||
from django.contrib import messages
|
from django.contrib import messages
|
||||||
@ -133,7 +132,7 @@ def corpstats_search(request):
|
|||||||
search_string.lower() in corpstats.members[member_id].lower()]
|
search_string.lower() in corpstats.members[member_id].lower()]
|
||||||
for s in similar:
|
for s in similar:
|
||||||
results.append(
|
results.append(
|
||||||
(corpstats, CorpStats.MemberObject(s[0], s[1], show_apis=corpstats.show_apis(request.user))))
|
(corpstats, CorpStats.MemberObject(s[0], s[1])))
|
||||||
page = request.GET.get('page', 1)
|
page = request.GET.get('page', 1)
|
||||||
results = sorted(results, key=lambda x: x[1].character_name)
|
results = sorted(results, key=lambda x: x[1].character_name)
|
||||||
results_page = get_page(results, page)
|
results_page = get_page(results, page)
|
||||||
|
@ -1,46 +1,31 @@
|
|||||||
from __future__ import unicode_literals
|
from __future__ import unicode_literals
|
||||||
from django.contrib import admin
|
from django.contrib import admin
|
||||||
|
from django.core.exceptions import ObjectDoesNotExist
|
||||||
from eveonline.models import EveCharacter
|
from eveonline.models import EveCharacter
|
||||||
from eveonline.models import EveApiKeyPair
|
|
||||||
from eveonline.models import EveAllianceInfo
|
from eveonline.models import EveAllianceInfo
|
||||||
from eveonline.models import EveCorporationInfo
|
from eveonline.models import EveCorporationInfo
|
||||||
from authentication.models import AuthServicesInfo
|
|
||||||
|
|
||||||
admin.site.register(EveAllianceInfo)
|
admin.site.register(EveAllianceInfo)
|
||||||
admin.site.register(EveCorporationInfo)
|
admin.site.register(EveCorporationInfo)
|
||||||
|
|
||||||
|
|
||||||
class EveApiKeyPairAdmin(admin.ModelAdmin):
|
|
||||||
search_fields = ['api_id', 'user__username']
|
|
||||||
list_display = ['api_id', 'user', 'characters']
|
|
||||||
|
|
||||||
@staticmethod
|
|
||||||
def characters(obj):
|
|
||||||
return ', '.join(sorted([c.character_name for c in EveCharacter.objects.filter(api_id=obj.api_id)]))
|
|
||||||
|
|
||||||
def get_search_results(self, request, queryset, search_term):
|
|
||||||
queryset, use_distinct = super(EveApiKeyPairAdmin, self).get_search_results(request, queryset, search_term)
|
|
||||||
chars = EveCharacter.objects.filter(character_name__icontains=search_term)
|
|
||||||
queryset |= EveApiKeyPair.objects.filter(api_id__in=[char.api_id for char in chars if bool(char.api_id)])
|
|
||||||
return queryset, use_distinct
|
|
||||||
|
|
||||||
|
|
||||||
class EveCharacterAdmin(admin.ModelAdmin):
|
class EveCharacterAdmin(admin.ModelAdmin):
|
||||||
search_fields = ['character_name', 'corporation_name', 'alliance_name', 'user__username', 'api_id']
|
search_fields = ['character_name', 'corporation_name', 'alliance_name', 'character_ownership__user__username']
|
||||||
list_display = ('character_name', 'corporation_name', 'alliance_name', 'user', 'main_character')
|
list_display = ('character_name', 'corporation_name', 'alliance_name', 'user', 'main_character')
|
||||||
|
|
||||||
|
@staticmethod
|
||||||
|
def user(obj):
|
||||||
|
try:
|
||||||
|
return obj.character_ownership.user
|
||||||
|
except (AttributeError, ObjectDoesNotExist):
|
||||||
|
return None
|
||||||
|
|
||||||
@staticmethod
|
@staticmethod
|
||||||
def main_character(obj):
|
def main_character(obj):
|
||||||
if obj.user:
|
try:
|
||||||
auth = AuthServicesInfo.objects.get(user=obj.user)
|
return obj.character_ownership.user.profile.main_character
|
||||||
if auth and auth.main_char_id:
|
except (AttributeError, ObjectDoesNotExist):
|
||||||
try:
|
return None
|
||||||
return EveCharacter.objects.get(character_id=auth.main_char_id)
|
|
||||||
except EveCharacter.DoesNotExist:
|
|
||||||
pass
|
|
||||||
return None
|
|
||||||
|
|
||||||
|
|
||||||
admin.site.register(EveCharacter, EveCharacterAdmin)
|
admin.site.register(EveCharacter, EveCharacterAdmin)
|
||||||
admin.site.register(EveApiKeyPair, EveApiKeyPairAdmin)
|
|
||||||
|
@ -1,52 +0,0 @@
|
|||||||
from __future__ import unicode_literals
|
|
||||||
from django import forms
|
|
||||||
from django.conf import settings
|
|
||||||
|
|
||||||
from services.managers.eve_api_manager import EveApiManager
|
|
||||||
from eveonline.managers import EveManager
|
|
||||||
from eveonline.models import EveApiKeyPair
|
|
||||||
import evelink
|
|
||||||
|
|
||||||
import logging
|
|
||||||
|
|
||||||
logger = logging.getLogger(__name__)
|
|
||||||
|
|
||||||
|
|
||||||
class UpdateKeyForm(forms.Form):
|
|
||||||
api_id = forms.CharField(max_length=254, required=True, label="Key ID")
|
|
||||||
api_key = forms.CharField(max_length=254, required=True, label="Verification Code")
|
|
||||||
|
|
||||||
def __init__(self, user, *args, **kwargs):
|
|
||||||
super(UpdateKeyForm, self).__init__(*args, **kwargs)
|
|
||||||
self.user = user
|
|
||||||
|
|
||||||
def clean_api_id(self):
|
|
||||||
try:
|
|
||||||
api_id = int(self.cleaned_data['api_id'])
|
|
||||||
return api_id
|
|
||||||
except:
|
|
||||||
raise forms.ValidationError("API ID must be a number")
|
|
||||||
|
|
||||||
def clean(self):
|
|
||||||
if 'api_id' not in self.cleaned_data or 'api_key' not in self.cleaned_data:
|
|
||||||
# need to check if api_id and vcode in cleaned_data because
|
|
||||||
# if they fail, they get removed from the dict but this method still happens
|
|
||||||
return self.cleaned_data
|
|
||||||
|
|
||||||
if EveManager.check_if_api_key_pair_exist(self.cleaned_data['api_id']):
|
|
||||||
logger.debug("UpdateKeyForm failed cleaning as API id %s already exists." % self.cleaned_data['api_id'])
|
|
||||||
if EveApiKeyPair.objects.get(api_id=self.cleaned_data['api_id']).user:
|
|
||||||
# allow orphaned APIs to proceed to SSO validation upon re-entry
|
|
||||||
raise forms.ValidationError('API key already exist')
|
|
||||||
if settings.REJECT_OLD_APIS and not EveManager.check_if_api_key_pair_is_new(
|
|
||||||
self.cleaned_data['api_id'],
|
|
||||||
settings.REJECT_OLD_APIS_MARGIN):
|
|
||||||
raise forms.ValidationError('API key is too old. Please create a new key')
|
|
||||||
try:
|
|
||||||
EveApiManager.validate_api(self.cleaned_data['api_id'], self.cleaned_data['api_key'], self.user)
|
|
||||||
return self.cleaned_data
|
|
||||||
except EveApiManager.ApiValidationError as e:
|
|
||||||
raise forms.ValidationError(str(e))
|
|
||||||
except evelink.api.APIError as e:
|
|
||||||
logger.debug("Got error code %s while validating API %s" % (e.code, self.cleaned_data['api_id']))
|
|
||||||
raise forms.ValidationError('Error while checking API key (%s)' % e.code)
|
|
@ -1,11 +1,8 @@
|
|||||||
from __future__ import unicode_literals
|
from __future__ import unicode_literals
|
||||||
from eveonline.models import EveCharacter
|
from eveonline.models import EveCharacter
|
||||||
from eveonline.models import EveApiKeyPair
|
|
||||||
from eveonline.models import EveAllianceInfo
|
from eveonline.models import EveAllianceInfo
|
||||||
from eveonline.models import EveCorporationInfo
|
from eveonline.models import EveCorporationInfo
|
||||||
from authentication.models import AuthServicesInfo
|
from eveonline.providers import eve_adapter_factory
|
||||||
from eveonline.providers import eve_adapter_factory, EveXmlProvider
|
|
||||||
from services.managers.eve_api_manager import EveApiManager
|
|
||||||
import logging
|
import logging
|
||||||
|
|
||||||
logger = logging.getLogger(__name__)
|
logger = logging.getLogger(__name__)
|
||||||
@ -25,11 +22,11 @@ class EveManager(object):
|
|||||||
return cls.get_adapter().get_character(character_id)
|
return cls.get_adapter().get_character(character_id)
|
||||||
|
|
||||||
@staticmethod
|
@staticmethod
|
||||||
def create_character(id, user, api_id):
|
def create_character(id):
|
||||||
return EveManager.create_character_obj(EveManager.get_character(id), user, api_id)
|
return EveManager.create_character_obj(EveManager.get_character(id))
|
||||||
|
|
||||||
@staticmethod
|
@staticmethod
|
||||||
def create_character_obj(character, user, api_id):
|
def create_character_obj(character,):
|
||||||
return EveCharacter.objects.create(
|
return EveCharacter.objects.create(
|
||||||
character_id=character.id,
|
character_id=character.id,
|
||||||
character_name=character.name,
|
character_name=character.name,
|
||||||
@ -38,8 +35,6 @@ class EveManager(object):
|
|||||||
corporation_ticker=character.corp.ticker,
|
corporation_ticker=character.corp.ticker,
|
||||||
alliance_id=character.alliance.id,
|
alliance_id=character.alliance.id,
|
||||||
alliance_name=character.alliance.name,
|
alliance_name=character.alliance.name,
|
||||||
user=user,
|
|
||||||
api_id=api_id,
|
|
||||||
)
|
)
|
||||||
|
|
||||||
@staticmethod
|
@staticmethod
|
||||||
@ -58,19 +53,6 @@ class EveManager(object):
|
|||||||
model.save()
|
model.save()
|
||||||
return model
|
return model
|
||||||
|
|
||||||
@staticmethod
|
|
||||||
def create_api_keypair(api_id, api_key, user_id):
|
|
||||||
logger.debug("Creating api keypair id %s for user_id %s" % (api_id, user_id))
|
|
||||||
if not EveApiKeyPair.objects.filter(api_id=api_id).exists():
|
|
||||||
api_pair = EveApiKeyPair()
|
|
||||||
api_pair.api_id = api_id
|
|
||||||
api_pair.api_key = api_key
|
|
||||||
api_pair.user = user_id
|
|
||||||
api_pair.save()
|
|
||||||
logger.info("Created api keypair id %s for user %s" % (api_id, user_id))
|
|
||||||
else:
|
|
||||||
logger.warn("Attempting to create existing api keypair with id %s" % api_id)
|
|
||||||
|
|
||||||
@classmethod
|
@classmethod
|
||||||
def get_alliance(cls, alliance_id):
|
def get_alliance(cls, alliance_id):
|
||||||
return cls.get_adapter().get_alliance(alliance_id)
|
return cls.get_adapter().get_alliance(alliance_id)
|
||||||
@ -157,82 +139,6 @@ class EveManager(object):
|
|||||||
def get_itemtype(cls, type_id):
|
def get_itemtype(cls, type_id):
|
||||||
return cls.get_adapter().get_itemtype(type_id)
|
return cls.get_adapter().get_itemtype(type_id)
|
||||||
|
|
||||||
@staticmethod
|
|
||||||
def get_characters_from_api(api):
|
|
||||||
char_result = EveApiManager.get_characters_from_api(api.api_id, api.api_key).result
|
|
||||||
provider = EveXmlProvider(adapter=EveManager.get_adapter())
|
|
||||||
return [provider._build_character(result) for id, result in char_result.items()]
|
|
||||||
|
|
||||||
@staticmethod
|
|
||||||
def get_api_key_pairs(user):
|
|
||||||
if EveApiKeyPair.objects.filter(user=user).exists():
|
|
||||||
logger.debug("Returning api keypairs for user %s" % user)
|
|
||||||
return EveApiKeyPair.objects.filter(user=user)
|
|
||||||
else:
|
|
||||||
logger.debug("No api keypairs found for user %s" % user)
|
|
||||||
|
|
||||||
@staticmethod
|
|
||||||
def get_all_api_key_pairs():
|
|
||||||
if EveApiKeyPair.objects.exists():
|
|
||||||
logger.debug("Returning all api keypairs.")
|
|
||||||
return EveApiKeyPair.objects.all()
|
|
||||||
else:
|
|
||||||
logger.debug("No api keypairs found.")
|
|
||||||
|
|
||||||
@staticmethod
|
|
||||||
def check_if_api_key_pair_exist(api_id):
|
|
||||||
if EveApiKeyPair.objects.filter(api_id=api_id).exists():
|
|
||||||
logger.debug("Determined api id %s exists." % api_id)
|
|
||||||
return True
|
|
||||||
else:
|
|
||||||
logger.debug("Determined api id %s does not exist." % api_id)
|
|
||||||
return False
|
|
||||||
|
|
||||||
@staticmethod
|
|
||||||
def check_if_api_key_pair_is_new(api_id, fudge_factor):
|
|
||||||
if EveApiKeyPair.objects.count() == 0:
|
|
||||||
return True
|
|
||||||
latest_api_id = int(EveApiKeyPair.objects.order_by('-api_id')[0].api_id) - fudge_factor
|
|
||||||
if latest_api_id >= api_id:
|
|
||||||
logger.debug("api key (%d) is older than latest API key (%d). Rejecting" % (api_id, latest_api_id))
|
|
||||||
return False
|
|
||||||
else:
|
|
||||||
logger.debug("api key (%d) is new. Accepting" % api_id)
|
|
||||||
return True
|
|
||||||
|
|
||||||
@staticmethod
|
|
||||||
def delete_api_key_pair(api_id, user_id):
|
|
||||||
logger.debug("Deleting api id %s" % api_id)
|
|
||||||
if EveApiKeyPair.objects.filter(api_id=api_id).exists():
|
|
||||||
# Check that its owned by our user_id
|
|
||||||
apikeypair = EveApiKeyPair.objects.get(api_id=api_id)
|
|
||||||
if apikeypair.user.id == user_id:
|
|
||||||
logger.info("Deleted user %s api key id %s" % (user_id, api_id))
|
|
||||||
apikeypair.delete()
|
|
||||||
else:
|
|
||||||
logger.error(
|
|
||||||
"Unable to delete api: user mismatch: key id %s owned by user id %s, not deleting user id %s" % (
|
|
||||||
api_id, apikeypair.user.id, user_id))
|
|
||||||
else:
|
|
||||||
logger.warn("Unable to locate api id %s - cannot delete." % api_id)
|
|
||||||
|
|
||||||
@staticmethod
|
|
||||||
def delete_characters_by_api_id(api_id, user_id):
|
|
||||||
logger.debug("Deleting all characters associated with api id %s" % api_id)
|
|
||||||
if EveCharacter.objects.filter(api_id=api_id).exists():
|
|
||||||
# Check that its owned by our user_id
|
|
||||||
characters = EveCharacter.objects.filter(api_id=api_id)
|
|
||||||
logger.debug("Got user %s characters %s from api %s" % (user_id, characters, api_id))
|
|
||||||
for char in characters:
|
|
||||||
if char.user.id == user_id:
|
|
||||||
logger.info("Deleting user %s character %s from api %s" % (user_id, char, api_id))
|
|
||||||
char.delete()
|
|
||||||
else:
|
|
||||||
logger.error(
|
|
||||||
"Unable to delete character %s by api %s: user mismatch: character owned by user id %s, "
|
|
||||||
"not deleting user id %s" % (
|
|
||||||
char, api_id, char.user.id, user_id))
|
|
||||||
|
|
||||||
@staticmethod
|
@staticmethod
|
||||||
def check_if_character_exist(char_name):
|
def check_if_character_exist(char_name):
|
||||||
return EveCharacter.objects.filter(character_name=char_name).exists()
|
return EveCharacter.objects.filter(character_name=char_name).exists()
|
||||||
@ -256,16 +162,6 @@ class EveManager(object):
|
|||||||
|
|
||||||
return None
|
return None
|
||||||
|
|
||||||
@staticmethod
|
|
||||||
def get_main_character(user):
|
|
||||||
"""
|
|
||||||
Get a characters main
|
|
||||||
:param user: django.contrib.auth.models.User
|
|
||||||
:return: EveCharacter
|
|
||||||
"""
|
|
||||||
authserviceinfo = AuthServicesInfo.objects.get(user=user)
|
|
||||||
return EveManager.get_character_by_id(authserviceinfo.main_char_id)
|
|
||||||
|
|
||||||
@staticmethod
|
@staticmethod
|
||||||
def get_characters_by_api_id(api_id):
|
def get_characters_by_api_id(api_id):
|
||||||
return EveCharacter.objects.filter(api_id=api_id)
|
return EveCharacter.objects.filter(api_id=api_id)
|
||||||
|
38
eveonline/migrations/0008_remove_apikeys.py
Normal file
38
eveonline/migrations/0008_remove_apikeys.py
Normal file
@ -0,0 +1,38 @@
|
|||||||
|
# -*- coding: utf-8 -*-
|
||||||
|
# Generated by Django 1.10.5 on 2017-03-22 23:09
|
||||||
|
from __future__ import unicode_literals
|
||||||
|
|
||||||
|
from django.db import migrations
|
||||||
|
|
||||||
|
|
||||||
|
class Migration(migrations.Migration):
|
||||||
|
|
||||||
|
dependencies = [
|
||||||
|
('eveonline', '0007_unique_id_name'),
|
||||||
|
]
|
||||||
|
|
||||||
|
operations = [
|
||||||
|
migrations.RemoveField(
|
||||||
|
model_name='eveapikeypair',
|
||||||
|
name='user',
|
||||||
|
),
|
||||||
|
migrations.RemoveField(
|
||||||
|
model_name='eveallianceinfo',
|
||||||
|
name='is_blue',
|
||||||
|
),
|
||||||
|
migrations.RemoveField(
|
||||||
|
model_name='evecharacter',
|
||||||
|
name='api_id',
|
||||||
|
),
|
||||||
|
migrations.RemoveField(
|
||||||
|
model_name='evecharacter',
|
||||||
|
name='user',
|
||||||
|
),
|
||||||
|
migrations.RemoveField(
|
||||||
|
model_name='evecorporationinfo',
|
||||||
|
name='is_blue',
|
||||||
|
),
|
||||||
|
migrations.DeleteModel(
|
||||||
|
name='EveApiKeyPair',
|
||||||
|
),
|
||||||
|
]
|
@ -1,7 +1,6 @@
|
|||||||
from __future__ import unicode_literals
|
from __future__ import unicode_literals
|
||||||
from django.utils.encoding import python_2_unicode_compatible
|
from django.utils.encoding import python_2_unicode_compatible
|
||||||
from django.db import models
|
from django.db import models
|
||||||
from django.contrib.auth.models import User
|
|
||||||
|
|
||||||
|
|
||||||
@python_2_unicode_compatible
|
@python_2_unicode_compatible
|
||||||
@ -13,31 +12,17 @@ class EveCharacter(models.Model):
|
|||||||
corporation_ticker = models.CharField(max_length=254)
|
corporation_ticker = models.CharField(max_length=254)
|
||||||
alliance_id = models.CharField(max_length=254, blank=True, null=True, default='')
|
alliance_id = models.CharField(max_length=254, blank=True, null=True, default='')
|
||||||
alliance_name = models.CharField(max_length=254, blank=True, null=True, default='')
|
alliance_name = models.CharField(max_length=254, blank=True, null=True, default='')
|
||||||
api_id = models.CharField(max_length=254)
|
|
||||||
user = models.ForeignKey(User, blank=True, null=True)
|
|
||||||
|
|
||||||
def __str__(self):
|
def __str__(self):
|
||||||
return self.character_name
|
return self.character_name
|
||||||
|
|
||||||
|
|
||||||
@python_2_unicode_compatible
|
|
||||||
class EveApiKeyPair(models.Model):
|
|
||||||
api_id = models.CharField(max_length=254, unique=True)
|
|
||||||
api_key = models.CharField(max_length=254)
|
|
||||||
user = models.ForeignKey(User, blank=True, null=True)
|
|
||||||
sso_verified = models.BooleanField(default=False)
|
|
||||||
|
|
||||||
def __str__(self):
|
|
||||||
return self.api_id
|
|
||||||
|
|
||||||
|
|
||||||
@python_2_unicode_compatible
|
@python_2_unicode_compatible
|
||||||
class EveAllianceInfo(models.Model):
|
class EveAllianceInfo(models.Model):
|
||||||
alliance_id = models.CharField(max_length=254, unique=True)
|
alliance_id = models.CharField(max_length=254, unique=True)
|
||||||
alliance_name = models.CharField(max_length=254, unique=True)
|
alliance_name = models.CharField(max_length=254, unique=True)
|
||||||
alliance_ticker = models.CharField(max_length=254)
|
alliance_ticker = models.CharField(max_length=254)
|
||||||
executor_corp_id = models.CharField(max_length=254)
|
executor_corp_id = models.CharField(max_length=254)
|
||||||
is_blue = models.BooleanField(default=False)
|
|
||||||
|
|
||||||
def __str__(self):
|
def __str__(self):
|
||||||
return self.alliance_name
|
return self.alliance_name
|
||||||
@ -49,7 +34,6 @@ class EveCorporationInfo(models.Model):
|
|||||||
corporation_name = models.CharField(max_length=254, unique=True)
|
corporation_name = models.CharField(max_length=254, unique=True)
|
||||||
corporation_ticker = models.CharField(max_length=254)
|
corporation_ticker = models.CharField(max_length=254)
|
||||||
member_count = models.IntegerField()
|
member_count = models.IntegerField()
|
||||||
is_blue = models.BooleanField(default=False)
|
|
||||||
alliance = models.ForeignKey(EveAllianceInfo, blank=True, null=True)
|
alliance = models.ForeignKey(EveAllianceInfo, blank=True, null=True)
|
||||||
|
|
||||||
def __str__(self):
|
def __str__(self):
|
||||||
|
@ -330,9 +330,9 @@ class EveXmlProvider(EveProvider):
|
|||||||
self.adapter,
|
self.adapter,
|
||||||
id,
|
id,
|
||||||
corpinfo['name'],
|
corpinfo['name'],
|
||||||
|
corpinfo['ticker'],
|
||||||
corpinfo['ceo']['id'],
|
corpinfo['ceo']['id'],
|
||||||
corpinfo['members']['current'],
|
corpinfo['members']['current'],
|
||||||
corpinfo['ticker'],
|
|
||||||
corpinfo['alliance']['id'] if corpinfo['alliance'] else None,
|
corpinfo['alliance']['id'] if corpinfo['alliance'] else None,
|
||||||
)
|
)
|
||||||
return model
|
return model
|
||||||
|
@ -1,123 +1,29 @@
|
|||||||
from __future__ import unicode_literals
|
from __future__ import unicode_literals
|
||||||
from django.conf import settings
|
from django.conf import settings
|
||||||
from celery.task import periodic_task
|
from celery.task import periodic_task
|
||||||
from django.contrib.auth.models import User
|
|
||||||
from notifications import notify
|
|
||||||
from celery import task
|
from celery import task
|
||||||
from celery.task.schedules import crontab
|
from celery.task.schedules import crontab
|
||||||
from authentication.models import AuthServicesInfo
|
|
||||||
from eveonline.managers import EveManager
|
from eveonline.managers import EveManager
|
||||||
from eveonline.models import EveApiKeyPair
|
|
||||||
from services.managers.eve_api_manager import EveApiManager
|
|
||||||
from eveonline.models import EveCharacter
|
|
||||||
from eveonline.models import EveCorporationInfo
|
from eveonline.models import EveCorporationInfo
|
||||||
from eveonline.models import EveAllianceInfo
|
from eveonline.models import EveAllianceInfo
|
||||||
from eveonline.providers import eve_adapter_factory, ObjectNotFound
|
from eveonline.providers import ObjectNotFound
|
||||||
from authentication.tasks import set_state
|
|
||||||
import logging
|
import logging
|
||||||
import evelink
|
|
||||||
|
|
||||||
logger = logging.getLogger(__name__)
|
logger = logging.getLogger(__name__)
|
||||||
|
|
||||||
|
|
||||||
@task
|
@task
|
||||||
def refresh_api(api):
|
def update_corp(corp_id, is_blue=None):
|
||||||
logger.debug('Running update on api key %s' % api.api_id)
|
EveManager.update_corporation(corp_id, is_blue=is_blue)
|
||||||
still_valid = True
|
|
||||||
try:
|
|
||||||
EveApiManager.validate_api(api.api_id, api.api_key, api.user)
|
|
||||||
# Update characters
|
|
||||||
characters = EveManager.get_characters_from_api(api)
|
|
||||||
for c in characters:
|
|
||||||
try:
|
|
||||||
EveManager.update_character_obj(c)
|
|
||||||
except EveCharacter.DoesNotExist:
|
|
||||||
logger.debug("API key %s has a new character on the account: %s" % (api.api_id, c))
|
|
||||||
EveManager.create_character_obj(c, api.user, api.api_id)
|
|
||||||
current_chars = EveCharacter.objects.filter(api_id=api.api_id)
|
|
||||||
for c in current_chars:
|
|
||||||
if not int(c.character_id) in [c.id for c in characters]:
|
|
||||||
logger.info("Character %s no longer found on API ID %s" % (c, api.api_id))
|
|
||||||
c.delete()
|
|
||||||
except evelink.api.APIError as e:
|
|
||||||
logger.warning('Received unexpected APIError (%s) while updating API %s' % (e.code, api.api_id))
|
|
||||||
except EveApiManager.ApiInvalidError:
|
|
||||||
logger.debug("API key %s is no longer valid; it and its characters will be deleted." % api.api_id)
|
|
||||||
notify(api.user, "API Failed Validation", message="Your API key ID %s is no longer valid." % api.api_id,
|
|
||||||
level="danger")
|
|
||||||
still_valid = False
|
|
||||||
except EveApiManager.ApiAccountValidationError:
|
|
||||||
logger.info(
|
|
||||||
"Determined api key %s for user %s no longer meets account access requirements." % (api.api_id, api.user))
|
|
||||||
notify(api.user, "API Failed Validation",
|
|
||||||
message="Your API key ID %s is no longer account-wide as required." % api.api_id, level="danger")
|
|
||||||
still_valid = False
|
|
||||||
except EveApiManager.ApiMaskValidationError as e:
|
|
||||||
logger.info("Determined api key %s for user %s no longer meets minimum access mask as required." % (
|
|
||||||
api.api_id, api.user))
|
|
||||||
notify(api.user, "API Failed Validation",
|
|
||||||
message="Your API key ID %s no longer meets access mask requirements. Required: %s Got: %s" % (
|
|
||||||
api.api_id, e.required_mask, e.api_mask), level="danger")
|
|
||||||
still_valid = False
|
|
||||||
except EveApiManager.ApiServerUnreachableError as e:
|
|
||||||
logger.warn("Error updating API %s\n%s" % (api.api_id, str(e)))
|
|
||||||
finally:
|
|
||||||
if not still_valid:
|
|
||||||
EveManager.delete_characters_by_api_id(api.api_id, api.user.id)
|
|
||||||
EveManager.delete_api_key_pair(api.api_id, api.user.id)
|
|
||||||
notify(api.user, "API Key Deleted",
|
|
||||||
message="Your API key ID %s is invalid. It and its associated characters have been deleted." % api.api_id,
|
|
||||||
level="danger")
|
|
||||||
|
|
||||||
|
|
||||||
@task
|
@task
|
||||||
def refresh_user_apis(user):
|
def update_alliance(alliance_id, is_blue=None):
|
||||||
logger.debug('Refreshing all APIs belonging to user %s' % user)
|
EveManager.update_alliance(alliance_id, is_blue=is_blue)
|
||||||
apis = EveApiKeyPair.objects.filter(user=user)
|
EveManager.populate_alliance(alliance_id)
|
||||||
for x in apis:
|
|
||||||
refresh_api(x)
|
|
||||||
# Check our main character
|
|
||||||
auth = AuthServicesInfo.objects.get(user=user)
|
|
||||||
if auth.main_char_id:
|
|
||||||
if EveCharacter.objects.filter(character_id=auth.main_char_id).exists() is False:
|
|
||||||
logger.info(
|
|
||||||
"User %s main character id %s missing model. Clearning main character." % (user, auth.main_char_id))
|
|
||||||
auth.main_char_id = ''
|
|
||||||
auth.save()
|
|
||||||
notify(user, "Main Character Reset",
|
|
||||||
message="Your specified main character no longer has a model.\nThis could be the result of "
|
|
||||||
"an invalid API.\nYour main character ID has been reset.",
|
|
||||||
level="warn")
|
|
||||||
set_state(user)
|
|
||||||
|
|
||||||
|
|
||||||
@periodic_task(run_every=crontab(minute=0, hour="*/3"))
|
|
||||||
def run_api_refresh():
|
|
||||||
if not EveApiManager.check_if_api_server_online():
|
|
||||||
logger.warn("Aborted scheduled API key refresh: API server unreachable")
|
|
||||||
return
|
|
||||||
|
|
||||||
for u in User.objects.all():
|
|
||||||
refresh_user_apis.delay(u)
|
|
||||||
|
|
||||||
|
|
||||||
@task
|
|
||||||
def update_corp(id, is_blue=None):
|
|
||||||
EveManager.update_corporation(id, is_blue=is_blue)
|
|
||||||
|
|
||||||
|
|
||||||
@task
|
|
||||||
def update_alliance(id, is_blue=None):
|
|
||||||
EveManager.update_alliance(id, is_blue=is_blue)
|
|
||||||
EveManager.populate_alliance(id)
|
|
||||||
|
|
||||||
|
|
||||||
@periodic_task(run_every=crontab(minute=0, hour="*/2"))
|
@periodic_task(run_every=crontab(minute=0, hour="*/2"))
|
||||||
def run_corp_update():
|
def run_corp_update():
|
||||||
if not EveApiManager.check_if_api_server_online():
|
|
||||||
logger.warn("Aborted updating corp and alliance models: API server unreachable")
|
|
||||||
return
|
|
||||||
|
|
||||||
# generate member corps
|
# generate member corps
|
||||||
for corp_id in settings.STR_CORP_IDS + settings.STR_BLUE_CORP_IDS:
|
for corp_id in settings.STR_CORP_IDS + settings.STR_BLUE_CORP_IDS:
|
||||||
is_blue = True if corp_id in settings.STR_BLUE_CORP_IDS else False
|
is_blue = True if corp_id in settings.STR_BLUE_CORP_IDS else False
|
||||||
@ -151,72 +57,3 @@ def run_corp_update():
|
|||||||
for alliance in EveAllianceInfo.objects.exclude(
|
for alliance in EveAllianceInfo.objects.exclude(
|
||||||
alliance_id__in=settings.STR_ALLIANCE_IDS + settings.STR_BLUE_ALLIANCE_IDS):
|
alliance_id__in=settings.STR_ALLIANCE_IDS + settings.STR_BLUE_ALLIANCE_IDS):
|
||||||
update_alliance.delay(alliance.alliance_id)
|
update_alliance.delay(alliance.alliance_id)
|
||||||
|
|
||||||
try:
|
|
||||||
# create standings
|
|
||||||
standings = EveApiManager.get_corp_standings()
|
|
||||||
if standings:
|
|
||||||
standings = standings[settings.STANDING_LEVEL]
|
|
||||||
for standing in standings:
|
|
||||||
if float(standings[standing]['standing']) >= settings.BLUE_STANDING:
|
|
||||||
logger.debug("Standing %s meets threshold" % standing)
|
|
||||||
if EveApiManager.check_if_id_is_alliance(standing):
|
|
||||||
logger.debug("Standing %s is an alliance" % standing)
|
|
||||||
if EveAllianceInfo.objects.filter(alliance_id=standing).exists():
|
|
||||||
alliance = EveAllianceInfo.objects.get(alliance_id=standing)
|
|
||||||
if alliance.is_blue is not True:
|
|
||||||
logger.info("Updating alliance %s as blue" % alliance)
|
|
||||||
alliance.is_blue = True
|
|
||||||
alliance.save()
|
|
||||||
else:
|
|
||||||
EveManager.create_alliance(standing, is_blue=True)
|
|
||||||
elif EveApiManager.check_if_id_is_corp(standing):
|
|
||||||
logger.debug("Standing %s is a corp" % standing)
|
|
||||||
if EveCorporationInfo.objects.filter(corporation_id=standing).exists():
|
|
||||||
corp = EveCorporationInfo.objects.get(corporation_id=standing)
|
|
||||||
if corp.is_blue is not True:
|
|
||||||
logger.info("Updating corp %s as blue" % corp)
|
|
||||||
corp.is_blue = True
|
|
||||||
corp.save()
|
|
||||||
else:
|
|
||||||
logger.info("Creating model for blue corp with id %s" % standing)
|
|
||||||
EveManager.create_corporation(standing, is_blue=True)
|
|
||||||
|
|
||||||
# update alliance standings
|
|
||||||
for alliance in EveAllianceInfo.objects.filter(is_blue=True):
|
|
||||||
if int(alliance.alliance_id) in standings:
|
|
||||||
if float(standings[int(alliance.alliance_id)]['standing']) < float(settings.BLUE_STANDING):
|
|
||||||
logger.info("Alliance %s no longer meets minimum blue standing threshold" % alliance)
|
|
||||||
alliance.is_blue = False
|
|
||||||
alliance.save()
|
|
||||||
elif alliance.alliance_id not in settings.STR_BLUE_ALLIANCE_IDS:
|
|
||||||
logger.info("Alliance %s no longer in standings" % alliance)
|
|
||||||
alliance.is_blue = False
|
|
||||||
alliance.save()
|
|
||||||
|
|
||||||
# update corp standings
|
|
||||||
for corp in EveCorporationInfo.objects.filter(is_blue=True):
|
|
||||||
if int(corp.corporation_id) in standings:
|
|
||||||
if float(standings[int(corp.corporation_id)]['standing']) < float(settings.BLUE_STANDING):
|
|
||||||
logger.info("Corp %s no longer meets minimum blue standing threshold" % corp)
|
|
||||||
corp.is_blue = False
|
|
||||||
corp.save()
|
|
||||||
elif corp.corporation_id not in settings.STR_BLUE_CORP_IDS:
|
|
||||||
if corp.alliance:
|
|
||||||
if not corp.alliance.is_blue:
|
|
||||||
logger.info("Corp %s and its alliance %s are no longer blue" % (corp, corp.alliance))
|
|
||||||
corp.is_blue = False
|
|
||||||
corp.save()
|
|
||||||
else:
|
|
||||||
logger.info("Corp %s is no longer blue" % corp)
|
|
||||||
corp.is_blue = False
|
|
||||||
corp.save()
|
|
||||||
except evelink.api.APIError as e:
|
|
||||||
logger.error("Model update failed with error code %s" % e.code)
|
|
||||||
|
|
||||||
# delete unnecessary alliance models
|
|
||||||
EveAllianceInfo.objects.filter(is_blue=False).exclude(alliance_id__in=settings.STR_ALLIANCE_IDS).delete()
|
|
||||||
|
|
||||||
# delete unnecessary corp models
|
|
||||||
EveCorporationInfo.objects.filter(is_blue=False).exclude(corporation_id__in=settings.STR_CORP_IDS).exclude(
|
|
||||||
alliance__alliance_id__in=settings.STR_ALLIANCE_IDS).delete()
|
|
||||||
|
@ -1,17 +0,0 @@
|
|||||||
from django import template
|
|
||||||
from django.conf import settings
|
|
||||||
from django.utils.safestring import mark_safe
|
|
||||||
|
|
||||||
register = template.Library()
|
|
||||||
|
|
||||||
|
|
||||||
@register.filter(name='api_link')
|
|
||||||
def api_link(api, style_class):
|
|
||||||
if settings.API_KEY_AUDIT_URL:
|
|
||||||
url = settings.API_KEY_AUDIT_URL.format(api_id=api.api_id, vcode=api.api_key, pk=api.pk)
|
|
||||||
element = "<a href='{url}' class='{style}' target='_new'>{api_id}</a>".format(url=url, style=style_class,
|
|
||||||
api_id=api.api_id)
|
|
||||||
else:
|
|
||||||
element = "<a href='#' class='{style}' onclick='return prompt({prompt}, {vcode})'>{api_id}</a>".format(
|
|
||||||
style=style_class, prompt='"Verification Code"', vcode='"%s"' % api.api_key, api_id=api.api_id)
|
|
||||||
return mark_safe(element)
|
|
@ -1,176 +1,3 @@
|
|||||||
from __future__ import unicode_literals
|
from __future__ import unicode_literals
|
||||||
from django.shortcuts import render, redirect, get_object_or_404
|
|
||||||
from django.contrib.auth.decorators import login_required
|
|
||||||
from django.contrib import messages
|
|
||||||
from django.utils.translation import ugettext_lazy as _
|
|
||||||
from eveonline.forms import UpdateKeyForm
|
|
||||||
from eveonline.managers import EveManager
|
|
||||||
from authentication.managers import AuthServicesInfoManager
|
|
||||||
from services.managers.eve_api_manager import EveApiManager
|
|
||||||
from eveonline.models import EveApiKeyPair, EveCharacter
|
|
||||||
from authentication.models import AuthServicesInfo
|
|
||||||
from authentication.tasks import set_state
|
|
||||||
from eveonline.tasks import refresh_api
|
|
||||||
from esi.decorators import token_required
|
|
||||||
from django.conf import settings
|
|
||||||
import logging
|
|
||||||
|
|
||||||
logger = logging.getLogger(__name__)
|
|
||||||
|
|
||||||
|
|
||||||
@login_required
|
|
||||||
def add_api_key(request):
|
|
||||||
logger.debug("add_api_key called by user %s" % request.user)
|
|
||||||
if request.method == 'POST':
|
|
||||||
form = UpdateKeyForm(request.user, request.POST)
|
|
||||||
logger.debug("Request type POST with form valid: %s" % form.is_valid())
|
|
||||||
if form.is_valid():
|
|
||||||
if EveApiKeyPair.objects.filter(api_id=form.cleaned_data['api_id'],
|
|
||||||
api_key=form.cleaned_data['api_key']).exists():
|
|
||||||
# allow orphaned keys to proceed to SSO validation upon re-entry
|
|
||||||
api_key = EveApiKeyPair.objects.get(api_id=form.cleaned_data['api_id'],
|
|
||||||
api_key=form.cleaned_data['api_key'])
|
|
||||||
elif EveApiKeyPair.objects.filter(api_id=form.cleaned_data['api_id']).exists():
|
|
||||||
logger.warn('API %s re-added with different vcode.' % form.cleaned_data['api_id'])
|
|
||||||
EveApiKeyPair.objects.filter(api_id=form.cleaned_data['api_id']).delete()
|
|
||||||
api_key = EveApiKeyPair.objects.create(api_id=form.cleaned_data['api_id'],
|
|
||||||
api_key=form.cleaned_data['api_key'])
|
|
||||||
else:
|
|
||||||
api_key = EveApiKeyPair.objects.create(api_id=form.cleaned_data['api_id'],
|
|
||||||
api_key=form.cleaned_data['api_key'])
|
|
||||||
owner = None
|
|
||||||
if not settings.API_SSO_VALIDATION:
|
|
||||||
# set API and character owners if SSO validation not requested
|
|
||||||
api_key.user = request.user
|
|
||||||
api_key.save()
|
|
||||||
owner = request.user
|
|
||||||
# Grab characters associated with the key pair
|
|
||||||
characters = EveManager.get_characters_from_api(api_key)
|
|
||||||
[EveManager.create_character_obj(c, owner, api_key.api_id) for c in characters if
|
|
||||||
not EveCharacter.objects.filter(character_id=c.id).exists()]
|
|
||||||
logger.info("Successfully processed api add form for user %s" % request.user)
|
|
||||||
if not settings.API_SSO_VALIDATION:
|
|
||||||
messages.success(request, _('Added API key %(apiid)s to your account.') % {"apiid": form.cleaned_data['api_id']})
|
|
||||||
auth = AuthServicesInfo.objects.get(user=request.user)
|
|
||||||
if not auth.main_char_id:
|
|
||||||
return redirect('auth_characters')
|
|
||||||
return redirect("auth_dashboard")
|
|
||||||
else:
|
|
||||||
logger.debug('Requesting SSO validation of API %s by user %s' % (api_key.api_id, request.user))
|
|
||||||
return render(request, 'registered/apisso.html', context={'api': api_key})
|
|
||||||
else:
|
|
||||||
logger.debug("Form invalid: returning to form.")
|
|
||||||
else:
|
|
||||||
logger.debug("Providing empty update key form for user %s" % request.user)
|
|
||||||
form = UpdateKeyForm(request.user)
|
|
||||||
context = {'form': form, 'apikeypairs': EveManager.get_api_key_pairs(request.user.id)}
|
|
||||||
return render(request, 'registered/addapikey.html', context=context)
|
|
||||||
|
|
||||||
|
|
||||||
@login_required
|
|
||||||
@token_required(new=True)
|
|
||||||
def api_sso_validate(request, token, api_id):
|
|
||||||
logger.debug('api_sso_validate called by user %s for api %s' % (request.user, api_id))
|
|
||||||
api = get_object_or_404(EveApiKeyPair, api_id=api_id)
|
|
||||||
if api.user and api.user != request.user:
|
|
||||||
logger.warning('User %s attempting to take ownership of api %s from %s' % (request.user, api_id, api.user))
|
|
||||||
messages.warning(request, _('API %(apiid)s already claimed by user %(user)s') % {"apiid": api_id, "user": api.user})
|
|
||||||
return redirect('auth_dashboard')
|
|
||||||
elif api.sso_verified:
|
|
||||||
logger.debug('API %s has already been verified.' % api_id)
|
|
||||||
messages.info(request, _('API %(apiid)s has already been verified') % {"apiid": api_id})
|
|
||||||
return redirect('auth_dashboard')
|
|
||||||
logger.debug('API %s has not been verified. Checking if token for %s matches.' % (api_id, token.character_name))
|
|
||||||
characters = EveApiManager.get_characters_from_api(api.api_id, api.api_key).result
|
|
||||||
if token.character_id in characters:
|
|
||||||
api.user = request.user
|
|
||||||
api.sso_verified = True
|
|
||||||
api.save()
|
|
||||||
EveCharacter.objects.filter(character_id__in=characters).update(user=request.user, api_id=api_id)
|
|
||||||
messages.success(request, _('Confirmed ownership of API %(apiid)s') % {"apiid": api.api_id})
|
|
||||||
auth = AuthServicesInfo.objects.get(user=request.user)
|
|
||||||
if not auth.main_char_id:
|
|
||||||
return redirect('auth_characters')
|
|
||||||
return redirect('auth_dashboard')
|
|
||||||
else:
|
|
||||||
messages.warning(request, _('%(character)s not found on API %(apiid)s. Please SSO as a character on the API.') % {
|
|
||||||
"character": token.character_name, "apiid": api.api_id})
|
|
||||||
return render(request, 'registered/apisso.html', context={'api': api})
|
|
||||||
|
|
||||||
|
|
||||||
@login_required
|
|
||||||
def dashboard_view(request):
|
|
||||||
logger.debug("dashboard_view called by user %s" % request.user)
|
|
||||||
auth_info = AuthServicesInfo.objects.get(user=request.user)
|
|
||||||
apikeypairs = EveManager.get_api_key_pairs(request.user.id)
|
|
||||||
sso_validation = settings.API_SSO_VALIDATION or False
|
|
||||||
api_chars = []
|
|
||||||
|
|
||||||
if apikeypairs:
|
|
||||||
for api in apikeypairs:
|
|
||||||
api_chars.append({
|
|
||||||
'id': api.api_id,
|
|
||||||
'sso_verified': api.sso_verified if sso_validation else True,
|
|
||||||
'characters': EveCharacter.objects.filter(api_id=api.api_id),
|
|
||||||
})
|
|
||||||
|
|
||||||
context = {
|
|
||||||
'main': EveManager.get_character_by_id(auth_info.main_char_id),
|
|
||||||
'apis': api_chars,
|
|
||||||
'api_sso_validation': settings.API_SSO_VALIDATION or False,
|
|
||||||
}
|
|
||||||
return render(request, 'registered/dashboard.html', context=context)
|
|
||||||
|
|
||||||
|
|
||||||
@login_required
|
|
||||||
def api_key_removal(request, api_id):
|
|
||||||
logger.debug("api_key_removal called by user %s for api id %s" % (request.user, api_id))
|
|
||||||
authinfo = AuthServicesInfo.objects.get(user=request.user)
|
|
||||||
EveManager.delete_api_key_pair(api_id, request.user.id)
|
|
||||||
EveManager.delete_characters_by_api_id(api_id, request.user.id)
|
|
||||||
messages.success(request, _('Deleted API key %(apiid)s') % {"apiid": api_id})
|
|
||||||
logger.info("Succesfully processed api delete request by user %s for api %s" % (request.user, api_id))
|
|
||||||
if not EveCharacter.objects.filter(character_id=authinfo.main_char_id).exists():
|
|
||||||
authinfo.main_char_id = None
|
|
||||||
authinfo.save()
|
|
||||||
set_state(request.user)
|
|
||||||
return redirect("auth_dashboard")
|
|
||||||
|
|
||||||
|
|
||||||
@login_required
|
|
||||||
def characters_view(request):
|
|
||||||
logger.debug("characters_view called by user %s" % request.user)
|
|
||||||
render_items = {'characters': EveCharacter.objects.filter(user=request.user),
|
|
||||||
'authinfo': AuthServicesInfo.objects.get(user=request.user)}
|
|
||||||
return render(request, 'registered/characters.html', context=render_items)
|
|
||||||
|
|
||||||
|
|
||||||
@login_required
|
|
||||||
def main_character_change(request, char_id):
|
|
||||||
logger.debug("main_character_change called by user %s for character id %s" % (request.user, char_id))
|
|
||||||
if EveCharacter.objects.filter(character_id=char_id).exists() and EveCharacter.objects.get(
|
|
||||||
character_id=char_id).user == request.user:
|
|
||||||
AuthServicesInfoManager.update_main_char_id(char_id, request.user)
|
|
||||||
messages.success(request, _('Changed main character ID to %(charid)s') % {"charid": char_id})
|
|
||||||
set_state(request.user)
|
|
||||||
return redirect("auth_dashboard")
|
|
||||||
messages.error(request, _('Failed to change main character - selected character is not owned by your account.'))
|
|
||||||
return redirect("auth_characters")
|
|
||||||
|
|
||||||
|
|
||||||
@login_required
|
|
||||||
def user_refresh_api(request, api_id):
|
|
||||||
logger.debug("user_refresh_api called by user %s for api id %s" % (request.user, api_id))
|
|
||||||
if EveApiKeyPair.objects.filter(api_id=api_id).exists():
|
|
||||||
api_key_pair = EveApiKeyPair.objects.get(api_id=api_id)
|
|
||||||
if api_key_pair.user == request.user:
|
|
||||||
refresh_api(api_key_pair)
|
|
||||||
messages.success(request, _('Refreshed API key %(apiid)s') % {"apiid": api_id})
|
|
||||||
set_state(request.user)
|
|
||||||
else:
|
|
||||||
messages.warning(request, _('You are not authorized to refresh that API key.'))
|
|
||||||
logger.warn("User %s not authorized to refresh api id %s" % (request.user, api_id))
|
|
||||||
else:
|
|
||||||
messages.warning(request, _('Unable to locate API key %(apiid)s') % {"apiid": api_id})
|
|
||||||
logger.warn("User %s unable to refresh api id %s - api key not found" % (request.user, api_id))
|
|
||||||
return redirect("auth_dashboard")
|
|
||||||
|
@ -1,11 +1,11 @@
|
|||||||
from __future__ import unicode_literals
|
from __future__ import unicode_literals
|
||||||
from django import forms
|
from django import forms
|
||||||
from optimer.models import optimer
|
from optimer.models import OpTimer
|
||||||
from django.utils.translation import ugettext_lazy as _
|
from django.utils.translation import ugettext_lazy as _
|
||||||
|
|
||||||
|
|
||||||
def get_fleet_list():
|
def get_fleet_list():
|
||||||
fleets = optimer.objects.all()
|
fleets = OpTimer.objects.all()
|
||||||
fleetlist = [("None", "None")]
|
fleetlist = [("None", "None")]
|
||||||
for fleet in fleets:
|
for fleet in fleets:
|
||||||
fleetlist.append((fleet.operation_name, fleet.operation_name))
|
fleetlist.append((fleet.operation_name, fleet.operation_name))
|
||||||
@ -17,4 +17,4 @@ class FatlinkForm(forms.Form):
|
|||||||
fatname = forms.CharField(label=_('Name of fat-link'), required=True)
|
fatname = forms.CharField(label=_('Name of fat-link'), required=True)
|
||||||
duration = forms.IntegerField(label=_("Duration of fat-link"), required=True, initial=30, min_value=1,
|
duration = forms.IntegerField(label=_("Duration of fat-link"), required=True, initial=30, min_value=1,
|
||||||
max_value=2147483647)
|
max_value=2147483647)
|
||||||
fleet = forms.ModelChoiceField(label=_("Fleet"), queryset=optimer.objects.all().order_by('operation_name'))
|
fleet = forms.ModelChoiceField(label=_("Fleet"), queryset=OpTimer.objects.all().order_by('operation_name'))
|
||||||
|
20
fleetactivitytracking/migrations/0004_auto_20170322_2335.py
Normal file
20
fleetactivitytracking/migrations/0004_auto_20170322_2335.py
Normal file
@ -0,0 +1,20 @@
|
|||||||
|
# -*- coding: utf-8 -*-
|
||||||
|
# Generated by Django 1.10.5 on 2017-03-22 23:35
|
||||||
|
from __future__ import unicode_literals
|
||||||
|
|
||||||
|
from django.db import migrations, models
|
||||||
|
|
||||||
|
|
||||||
|
class Migration(migrations.Migration):
|
||||||
|
|
||||||
|
dependencies = [
|
||||||
|
('fleetactivitytracking', '0003_auto_20160906_2354'),
|
||||||
|
]
|
||||||
|
|
||||||
|
operations = [
|
||||||
|
migrations.AlterField(
|
||||||
|
model_name='fatlink',
|
||||||
|
name='fleet',
|
||||||
|
field=models.CharField(default='', max_length=254),
|
||||||
|
),
|
||||||
|
]
|
@ -1,4 +1,4 @@
|
|||||||
{% extends 'public/base.html' %}
|
{% extends 'registered/base.html' %}
|
||||||
{% load i18n %}
|
{% load i18n %}
|
||||||
{% block title %}Fleet Participation{% endblock %}
|
{% block title %}Fleet Participation{% endblock %}
|
||||||
{% block page_title %}{% trans "Fleet Participation" %}{% endblock %}
|
{% block page_title %}{% trans "Fleet Participation" %}{% endblock %}
|
||||||
|
@ -1,4 +1,4 @@
|
|||||||
{% extends "public/base.html" %}
|
{% extends "registered/base.html" %}
|
||||||
{% load bootstrap %}
|
{% load bootstrap %}
|
||||||
{% load staticfiles %}
|
{% load staticfiles %}
|
||||||
{% load i18n %}
|
{% load i18n %}
|
||||||
|
@ -1,4 +1,4 @@
|
|||||||
{% extends "public/base.html" %}
|
{% extends "registered/base.html" %}
|
||||||
{% load bootstrap %}
|
{% load bootstrap %}
|
||||||
{% load staticfiles %}
|
{% load staticfiles %}
|
||||||
{% load i18n %}
|
{% load i18n %}
|
||||||
|
@ -1,4 +1,4 @@
|
|||||||
{% extends "public/base.html" %}
|
{% extends "registered/base.html" %}
|
||||||
{% load bootstrap %}
|
{% load bootstrap %}
|
||||||
{% load staticfiles %}
|
{% load staticfiles %}
|
||||||
{% load i18n %}
|
{% load i18n %}
|
||||||
|
@ -1,4 +1,4 @@
|
|||||||
{% extends "public/base.html" %}
|
{% extends "registered/base.html" %}
|
||||||
{% load bootstrap %}
|
{% load bootstrap %}
|
||||||
{% load staticfiles %}
|
{% load staticfiles %}
|
||||||
{% load i18n %}
|
{% load i18n %}
|
||||||
|
@ -1,4 +1,4 @@
|
|||||||
{% extends "public/base.html" %}
|
{% extends "registered/base.html" %}
|
||||||
{% load bootstrap %}
|
{% load bootstrap %}
|
||||||
{% load staticfiles %}
|
{% load staticfiles %}
|
||||||
{% load i18n %}
|
{% load i18n %}
|
||||||
|
@ -1,4 +1,4 @@
|
|||||||
{% extends "public/base.html" %}
|
{% extends "registered/base.html" %}
|
||||||
{% load bootstrap %}
|
{% load bootstrap %}
|
||||||
{% load staticfiles %}
|
{% load staticfiles %}
|
||||||
{% load i18n %}
|
{% load i18n %}
|
||||||
|
@ -1,6 +1,6 @@
|
|||||||
from __future__ import unicode_literals
|
from __future__ import unicode_literals
|
||||||
from django.conf import settings
|
from django.conf import settings
|
||||||
from django.shortcuts import render, redirect
|
from django.shortcuts import render, redirect, get_object_or_404
|
||||||
from django.core.exceptions import ObjectDoesNotExist
|
from django.core.exceptions import ObjectDoesNotExist
|
||||||
from django.contrib.auth.decorators import login_required
|
from django.contrib.auth.decorators import login_required
|
||||||
from django.contrib.auth.decorators import permission_required
|
from django.contrib.auth.decorators import permission_required
|
||||||
@ -197,58 +197,53 @@ def fatlink_monthly_personal_statistics_view(request, year, month, char_id=None)
|
|||||||
@token_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'])
|
||||||
def click_fatlink_view(request, token, hash, fatname):
|
def click_fatlink_view(request, token, hash, fatname):
|
||||||
try:
|
fatlink = get_object_or_404(Fatlink, hash=hash, name=fatname)
|
||||||
fatlink = Fatlink.objects.filter(hash=hash)[0]
|
|
||||||
|
|
||||||
if (timezone.now() - fatlink.fatdatetime) < datetime.timedelta(seconds=(fatlink.duration * 60)):
|
if (timezone.now() - fatlink.fatdatetime) < datetime.timedelta(seconds=(fatlink.duration * 60)):
|
||||||
|
|
||||||
character = EveManager.get_character_by_id(token.character_id)
|
character = EveManager.get_character_by_id(token.character_id)
|
||||||
|
|
||||||
if character:
|
if character:
|
||||||
# get data
|
# get data
|
||||||
c = token.get_esi_client(Location='v1', Universe='v2')
|
c = token.get_esi_client(Location='v1', Universe='v2')
|
||||||
location = c.Location.get_characters_character_id_location(character_id=token.character_id).result()
|
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()
|
ship = c.Location.get_characters_character_id_ship(character_id=token.character_id).result()
|
||||||
location['solar_system_name'] = \
|
location['solar_system_name'] = \
|
||||||
c.Universe.get_universe_systems_system_id(system_id=location['solar_system_id']).result()[
|
c.Universe.get_universe_systems_system_id(system_id=location['solar_system_id']).result()[
|
||||||
|
'name']
|
||||||
|
if location['structure_id']:
|
||||||
|
location['station_name'] = \
|
||||||
|
c.Universe.get_universe_structures_structure_id(structure_id=location['structure_id']).result()[
|
||||||
'name']
|
'name']
|
||||||
if location['structure_id']:
|
elif location['station_id']:
|
||||||
location['station_name'] = \
|
location['station_name'] = \
|
||||||
c.Universe.get_universe_structures_structure_id(structure_id=location['structure_id']).result()[
|
c.Universe.get_universe_stations_station_id(station_id=location['station_id']).result()['name']
|
||||||
'name']
|
|
||||||
elif location['station_id']:
|
|
||||||
location['station_name'] = \
|
|
||||||
c.Universe.get_universe_stations_station_id(station_id=location['station_id']).result()['name']
|
|
||||||
else:
|
|
||||||
location['station_name'] = "No Station"
|
|
||||||
ship['ship_type_name'] = EveManager.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 = character.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].decode())
|
|
||||||
messages.error(request, ' '.join(err_messages))
|
|
||||||
else:
|
else:
|
||||||
context = {'character_id': token.character_id,
|
location['station_name'] = "No Station"
|
||||||
'character_name': token.character_name}
|
ship['ship_type_name'] = EveManager.get_itemtype(ship['ship_type_id']).name
|
||||||
return render(request, 'fleetactivitytracking/characternotexisting.html', context=context)
|
|
||||||
|
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 = character.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].decode())
|
||||||
|
messages.error(request, ' '.join(err_messages))
|
||||||
else:
|
else:
|
||||||
messages.error(request, _('FAT link has expired.'))
|
context = {'character_id': token.character_id,
|
||||||
except (ObjectDoesNotExist, KeyError):
|
'character_name': token.character_name}
|
||||||
logger.exception("Failed to process FAT link.")
|
return render(request, 'fleetactivitytracking/characternotexisting.html', context=context)
|
||||||
messages.error(request, _('Invalid FAT link.'))
|
else:
|
||||||
return redirect('auth_fatlink_view')
|
messages.error(request, _('FAT link has expired.'))
|
||||||
|
|
||||||
|
|
||||||
@login_required
|
@login_required
|
||||||
|
@ -5,7 +5,6 @@ from django.contrib.auth.decorators import login_required
|
|||||||
from django.contrib.auth.decorators import permission_required
|
from django.contrib.auth.decorators import permission_required
|
||||||
from django.template.defaulttags import register
|
from django.template.defaulttags import register
|
||||||
from fleetup.managers import FleetUpManager
|
from fleetup.managers import FleetUpManager
|
||||||
from authentication.decorators import members_and_blues
|
|
||||||
|
|
||||||
import logging
|
import logging
|
||||||
|
|
||||||
@ -18,7 +17,7 @@ def get_item(dictionary, key):
|
|||||||
|
|
||||||
|
|
||||||
@login_required
|
@login_required
|
||||||
@members_and_blues()
|
@permission_required('auth.view_fleetup')
|
||||||
def fleetup_view(request):
|
def fleetup_view(request):
|
||||||
logger.debug("fleetup_view called by user %s" % request.user)
|
logger.debug("fleetup_view called by user %s" % request.user)
|
||||||
|
|
||||||
@ -35,6 +34,7 @@ def fleetup_view(request):
|
|||||||
|
|
||||||
@login_required
|
@login_required
|
||||||
@permission_required('auth.human_resources')
|
@permission_required('auth.human_resources')
|
||||||
|
@permission_required('auth.view_fleetup')
|
||||||
def fleetup_characters(request):
|
def fleetup_characters(request):
|
||||||
logger.debug("fleetup_characters called by user %s" % request.user)
|
logger.debug("fleetup_characters called by user %s" % request.user)
|
||||||
|
|
||||||
@ -46,7 +46,7 @@ def fleetup_characters(request):
|
|||||||
|
|
||||||
|
|
||||||
@login_required
|
@login_required
|
||||||
@members_and_blues()
|
@permission_required('auth.view_fleetup')
|
||||||
def fleetup_fittings(request):
|
def fleetup_fittings(request):
|
||||||
logger.debug("fleetup_fittings called by user %s" % request.user)
|
logger.debug("fleetup_fittings called by user %s" % request.user)
|
||||||
fitting_list = FleetUpManager.get_fleetup_fittings()
|
fitting_list = FleetUpManager.get_fleetup_fittings()
|
||||||
@ -55,7 +55,7 @@ def fleetup_fittings(request):
|
|||||||
|
|
||||||
|
|
||||||
@login_required
|
@login_required
|
||||||
@members_and_blues()
|
@permission_required('auth.view_fleetup')
|
||||||
def fleetup_fitting(request, fittingnumber):
|
def fleetup_fitting(request, fittingnumber):
|
||||||
logger.debug("fleetup_fitting called by user %s" % request.user)
|
logger.debug("fleetup_fitting called by user %s" % request.user)
|
||||||
fitting_eft = FleetUpManager.get_fleetup_fitting_eft(fittingnumber)
|
fitting_eft = FleetUpManager.get_fleetup_fitting_eft(fittingnumber)
|
||||||
@ -69,7 +69,7 @@ def fleetup_fitting(request, fittingnumber):
|
|||||||
|
|
||||||
|
|
||||||
@login_required
|
@login_required
|
||||||
@members_and_blues()
|
@permission_required('auth.view_fleetup')
|
||||||
def fleetup_doctrines(request):
|
def fleetup_doctrines(request):
|
||||||
logger.debug("fleetup_doctrines called by user %s" % request.user)
|
logger.debug("fleetup_doctrines called by user %s" % request.user)
|
||||||
doctrines_list = FleetUpManager.get_fleetup_doctrines()
|
doctrines_list = FleetUpManager.get_fleetup_doctrines()
|
||||||
@ -78,7 +78,7 @@ def fleetup_doctrines(request):
|
|||||||
|
|
||||||
|
|
||||||
@login_required
|
@login_required
|
||||||
@members_and_blues()
|
@permission_required('auth.view_fleetup')
|
||||||
def fleetup_doctrine(request, doctrinenumber):
|
def fleetup_doctrine(request, doctrinenumber):
|
||||||
logger.debug("fleetup_doctrine called by user %s" % request.user)
|
logger.debug("fleetup_doctrine called by user %s" % request.user)
|
||||||
doctrine = FleetUpManager.get_fleetup_doctrine(doctrinenumber)
|
doctrine = FleetUpManager.get_fleetup_doctrine(doctrinenumber)
|
||||||
|
@ -1,6 +1,5 @@
|
|||||||
from django.contrib.auth.models import Group
|
from django.contrib.auth.models import Group
|
||||||
from django.conf import settings
|
|
||||||
from authentication.managers import UserState
|
|
||||||
|
|
||||||
class GroupManager:
|
class GroupManager:
|
||||||
def __init__(self):
|
def __init__(self):
|
||||||
@ -39,7 +38,7 @@ class GroupManager:
|
|||||||
:return: bool True if user can manage groups, False otherwise
|
:return: bool True if user can manage groups, False otherwise
|
||||||
"""
|
"""
|
||||||
if user.is_authenticated:
|
if user.is_authenticated:
|
||||||
return cls.has_management_permission(user) or (user.leads_groups.all() and UserState.member_state(user))
|
return cls.has_management_permission(user) or user.leads_groups.all()
|
||||||
return False
|
return False
|
||||||
|
|
||||||
@classmethod
|
@classmethod
|
||||||
@ -51,6 +50,5 @@ class GroupManager:
|
|||||||
:return: True if the user can manage the group
|
:return: True if the user can manage the group
|
||||||
"""
|
"""
|
||||||
if user.is_authenticated:
|
if user.is_authenticated:
|
||||||
return cls.has_management_permission(user) or (
|
return cls.has_management_permission(user) or user.leads_groups.filter(group=group).exists()
|
||||||
user.leads_groups.filter(group=group).exists() and UserState.member_state(user))
|
|
||||||
return False
|
return False
|
||||||
|
@ -1,5 +1,5 @@
|
|||||||
from __future__ import unicode_literals
|
from __future__ import unicode_literals
|
||||||
from django.shortcuts import render, redirect
|
from django.shortcuts import render, redirect, get_object_or_404
|
||||||
from django.contrib.auth.decorators import login_required
|
from django.contrib.auth.decorators import login_required
|
||||||
from django.contrib.auth.decorators import user_passes_test
|
from django.contrib.auth.decorators import user_passes_test
|
||||||
from django.contrib.auth.models import Group
|
from django.contrib.auth.models import Group
|
||||||
@ -11,8 +11,6 @@ from django.core.exceptions import ObjectDoesNotExist, PermissionDenied
|
|||||||
from django.http import Http404
|
from django.http import Http404
|
||||||
from groupmanagement.managers import GroupManager
|
from groupmanagement.managers import GroupManager
|
||||||
from groupmanagement.models import GroupRequest
|
from groupmanagement.models import GroupRequest
|
||||||
from authentication.models import AuthServicesInfo
|
|
||||||
from authentication.managers import UserState
|
|
||||||
from eveonline.managers import EveManager
|
from eveonline.managers import EveManager
|
||||||
from django.utils.translation import ugettext_lazy as _
|
from django.utils.translation import ugettext_lazy as _
|
||||||
|
|
||||||
@ -72,8 +70,8 @@ def group_membership(request):
|
|||||||
@user_passes_test(GroupManager.can_manage_groups)
|
@user_passes_test(GroupManager.can_manage_groups)
|
||||||
def group_membership_list(request, group_id):
|
def group_membership_list(request, group_id):
|
||||||
logger.debug("group_membership_list called by user %s for group id %s" % (request.user, group_id))
|
logger.debug("group_membership_list called by user %s for group id %s" % (request.user, group_id))
|
||||||
|
group = get_object_or_404(Group, id=group_id)
|
||||||
try:
|
try:
|
||||||
group = Group.objects.get(id=group_id)
|
|
||||||
|
|
||||||
# Check its a joinable group i.e. not corp or internal
|
# Check its a joinable group i.e. not corp or internal
|
||||||
# And the user has permission to manage it
|
# And the user has permission to manage it
|
||||||
@ -88,11 +86,10 @@ def group_membership_list(request, group_id):
|
|||||||
members = list()
|
members = list()
|
||||||
|
|
||||||
for member in group.user_set.all().order_by('username'):
|
for member in group.user_set.all().order_by('username'):
|
||||||
authinfo = AuthServicesInfo.objects.get(user=member)
|
|
||||||
|
|
||||||
members.append({
|
members.append({
|
||||||
'user': member,
|
'user': member,
|
||||||
'main_char': EveManager.get_character_by_id(authinfo.main_char_id)
|
'main_char': member.profile.main_character
|
||||||
})
|
})
|
||||||
|
|
||||||
render_items = {'group': group, 'members': members}
|
render_items = {'group': group, 'members': members}
|
||||||
@ -105,9 +102,8 @@ def group_membership_list(request, group_id):
|
|||||||
def group_membership_remove(request, group_id, user_id):
|
def group_membership_remove(request, group_id, user_id):
|
||||||
logger.debug("group_membership_remove called by user %s for group id %s on user id %s" %
|
logger.debug("group_membership_remove called by user %s for group id %s on user id %s" %
|
||||||
(request.user, group_id, user_id))
|
(request.user, group_id, user_id))
|
||||||
|
group = get_object_or_404(Group, id=group_id)
|
||||||
try:
|
try:
|
||||||
group = Group.objects.get(id=group_id)
|
|
||||||
|
|
||||||
# Check its a joinable group i.e. not corp or internal
|
# Check its a joinable group i.e. not corp or internal
|
||||||
# And the user has permission to manage it
|
# And the user has permission to manage it
|
||||||
if not GroupManager.joinable_group(group) or not GroupManager.can_manage_group(request.user, group):
|
if not GroupManager.joinable_group(group) or not GroupManager.can_manage_group(request.user, group):
|
||||||
@ -134,8 +130,8 @@ def group_membership_remove(request, group_id, user_id):
|
|||||||
@user_passes_test(GroupManager.can_manage_groups)
|
@user_passes_test(GroupManager.can_manage_groups)
|
||||||
def group_accept_request(request, group_request_id):
|
def group_accept_request(request, group_request_id):
|
||||||
logger.debug("group_accept_request called by user %s for grouprequest id %s" % (request.user, group_request_id))
|
logger.debug("group_accept_request called by user %s for grouprequest id %s" % (request.user, group_request_id))
|
||||||
|
group_request = get_object_or_404(GroupRequest, id=group_request_id)
|
||||||
try:
|
try:
|
||||||
group_request = GroupRequest.objects.get(id=group_request_id)
|
|
||||||
group, created = Group.objects.get_or_create(name=group_request.group.name)
|
group, created = Group.objects.get_or_create(name=group_request.group.name)
|
||||||
|
|
||||||
if not GroupManager.joinable_group(group_request.group) or \
|
if not GroupManager.joinable_group(group_request.group) or \
|
||||||
@ -169,9 +165,8 @@ def group_accept_request(request, group_request_id):
|
|||||||
@user_passes_test(GroupManager.can_manage_groups)
|
@user_passes_test(GroupManager.can_manage_groups)
|
||||||
def group_reject_request(request, group_request_id):
|
def group_reject_request(request, group_request_id):
|
||||||
logger.debug("group_reject_request called by user %s for group request id %s" % (request.user, group_request_id))
|
logger.debug("group_reject_request called by user %s for group request id %s" % (request.user, group_request_id))
|
||||||
|
group_request = get_object_or_404(GroupRequest, id=group_request_id)
|
||||||
try:
|
try:
|
||||||
group_request = GroupRequest.objects.get(id=group_request_id)
|
|
||||||
|
|
||||||
if not GroupManager.can_manage_group(request.user, group_request.group):
|
if not GroupManager.can_manage_group(request.user, group_request.group):
|
||||||
raise PermissionDenied
|
raise PermissionDenied
|
||||||
|
|
||||||
@ -202,9 +197,8 @@ def group_reject_request(request, group_request_id):
|
|||||||
def group_leave_accept_request(request, group_request_id):
|
def group_leave_accept_request(request, group_request_id):
|
||||||
logger.debug(
|
logger.debug(
|
||||||
"group_leave_accept_request called by user %s for group request id %s" % (request.user, group_request_id))
|
"group_leave_accept_request called by user %s for group request id %s" % (request.user, group_request_id))
|
||||||
|
group_request = get_object_or_404(GroupRequest, id=group_request_id)
|
||||||
try:
|
try:
|
||||||
group_request = GroupRequest.objects.get(id=group_request_id)
|
|
||||||
|
|
||||||
if not GroupManager.can_manage_group(request.user, group_request.group):
|
if not GroupManager.can_manage_group(request.user, group_request.group):
|
||||||
raise PermissionDenied
|
raise PermissionDenied
|
||||||
|
|
||||||
@ -237,9 +231,8 @@ def group_leave_accept_request(request, group_request_id):
|
|||||||
def group_leave_reject_request(request, group_request_id):
|
def group_leave_reject_request(request, group_request_id):
|
||||||
logger.debug(
|
logger.debug(
|
||||||
"group_leave_reject_request called by user %s for group request id %s" % (request.user, group_request_id))
|
"group_leave_reject_request called by user %s for group request id %s" % (request.user, group_request_id))
|
||||||
|
group_request = get_object_or_404(GroupRequest, id=group_request_id)
|
||||||
try:
|
try:
|
||||||
group_request = GroupRequest.objects.get(id=group_request_id)
|
|
||||||
|
|
||||||
if not GroupManager.can_manage_group(request.user, group_request.group):
|
if not GroupManager.can_manage_group(request.user, group_request.group):
|
||||||
raise PermissionDenied
|
raise PermissionDenied
|
||||||
|
|
||||||
@ -307,12 +300,11 @@ def group_request_add(request, group_id):
|
|||||||
logger.info("%s joining %s as is an open group" % (request.user, group))
|
logger.info("%s joining %s as is an open group" % (request.user, group))
|
||||||
request.user.groups.add(group)
|
request.user.groups.add(group)
|
||||||
return redirect("auth_groups")
|
return redirect("auth_groups")
|
||||||
auth_info = AuthServicesInfo.objects.get(user=request.user)
|
|
||||||
grouprequest = GroupRequest()
|
grouprequest = GroupRequest()
|
||||||
grouprequest.status = _('Pending')
|
grouprequest.status = _('Pending')
|
||||||
grouprequest.group = group
|
grouprequest.group = group
|
||||||
grouprequest.user = request.user
|
grouprequest.user = request.user
|
||||||
grouprequest.main_char = EveManager.get_character_by_id(auth_info.main_char_id)
|
grouprequest.main_char = request.user.profile.main_character
|
||||||
grouprequest.leave_request = False
|
grouprequest.leave_request = False
|
||||||
grouprequest.save()
|
grouprequest.save()
|
||||||
logger.info("Created group request for user %s to group %s" % (request.user, Group.objects.get(id=group_id)))
|
logger.info("Created group request for user %s to group %s" % (request.user, Group.objects.get(id=group_id)))
|
||||||
@ -338,12 +330,11 @@ def group_request_leave(request, group_id):
|
|||||||
logger.info("%s leaving %s as is an open group" % (request.user, group))
|
logger.info("%s leaving %s as is an open group" % (request.user, group))
|
||||||
request.user.groups.remove(group)
|
request.user.groups.remove(group)
|
||||||
return redirect("auth_groups")
|
return redirect("auth_groups")
|
||||||
auth_info = AuthServicesInfo.objects.get(user=request.user)
|
|
||||||
grouprequest = GroupRequest()
|
grouprequest = GroupRequest()
|
||||||
grouprequest.status = _('Pending')
|
grouprequest.status = _('Pending')
|
||||||
grouprequest.group = group
|
grouprequest.group = group
|
||||||
grouprequest.user = request.user
|
grouprequest.user = request.user
|
||||||
grouprequest.main_char = EveManager.get_character_by_id(auth_info.main_char_id)
|
grouprequest.main_char = request.user.profile.main_character
|
||||||
grouprequest.leave_request = True
|
grouprequest.leave_request = True
|
||||||
grouprequest.save()
|
grouprequest.save()
|
||||||
logger.info("Created group leave request for user %s to group %s" % (request.user, Group.objects.get(id=group_id)))
|
logger.info("Created group leave request for user %s to group %s" % (request.user, Group.objects.get(id=group_id)))
|
||||||
|
50
hrapplications/migrations/0002_auto_20170322_2335.py
Normal file
50
hrapplications/migrations/0002_auto_20170322_2335.py
Normal file
@ -0,0 +1,50 @@
|
|||||||
|
# -*- coding: utf-8 -*-
|
||||||
|
# Generated by Django 1.10.5 on 2017-03-22 23:35
|
||||||
|
from __future__ import unicode_literals
|
||||||
|
|
||||||
|
from django.db import migrations, models
|
||||||
|
|
||||||
|
|
||||||
|
class Migration(migrations.Migration):
|
||||||
|
|
||||||
|
dependencies = [
|
||||||
|
('hrapplications', '0001_initial'),
|
||||||
|
]
|
||||||
|
|
||||||
|
operations = [
|
||||||
|
migrations.AlterField(
|
||||||
|
model_name='hrapplication',
|
||||||
|
name='about',
|
||||||
|
field=models.TextField(default=''),
|
||||||
|
),
|
||||||
|
migrations.AlterField(
|
||||||
|
model_name='hrapplication',
|
||||||
|
name='character_name',
|
||||||
|
field=models.CharField(default='', max_length=254),
|
||||||
|
),
|
||||||
|
migrations.AlterField(
|
||||||
|
model_name='hrapplication',
|
||||||
|
name='extra',
|
||||||
|
field=models.TextField(default=''),
|
||||||
|
),
|
||||||
|
migrations.AlterField(
|
||||||
|
model_name='hrapplication',
|
||||||
|
name='full_api_id',
|
||||||
|
field=models.CharField(default='', max_length=254),
|
||||||
|
),
|
||||||
|
migrations.AlterField(
|
||||||
|
model_name='hrapplication',
|
||||||
|
name='full_api_key',
|
||||||
|
field=models.CharField(default='', max_length=254),
|
||||||
|
),
|
||||||
|
migrations.AlterField(
|
||||||
|
model_name='hrapplication',
|
||||||
|
name='is_a_spi',
|
||||||
|
field=models.CharField(default='', max_length=254),
|
||||||
|
),
|
||||||
|
migrations.AlterField(
|
||||||
|
model_name='hrapplicationcomment',
|
||||||
|
name='comment',
|
||||||
|
field=models.CharField(default='', max_length=254),
|
||||||
|
),
|
||||||
|
]
|
@ -5,8 +5,6 @@ from django.contrib.auth.models import User
|
|||||||
|
|
||||||
from eveonline.models import EveCharacter
|
from eveonline.models import EveCharacter
|
||||||
from eveonline.models import EveCorporationInfo
|
from eveonline.models import EveCorporationInfo
|
||||||
from eveonline.models import EveApiKeyPair
|
|
||||||
from authentication.models import AuthServicesInfo
|
|
||||||
|
|
||||||
|
|
||||||
@python_2_unicode_compatible
|
@python_2_unicode_compatible
|
||||||
@ -47,21 +45,12 @@ class Application(models.Model):
|
|||||||
|
|
||||||
@property
|
@property
|
||||||
def main_character(self):
|
def main_character(self):
|
||||||
try:
|
return self.user.profile.main_character
|
||||||
auth = AuthServicesInfo.objects.get(user=self.user)
|
|
||||||
char = EveCharacter.objects.get(character_id=auth.main_char_id)
|
|
||||||
return char
|
|
||||||
except:
|
|
||||||
return None
|
|
||||||
|
|
||||||
@property
|
@property
|
||||||
def characters(self):
|
def characters(self):
|
||||||
return EveCharacter.objects.filter(user=self.user)
|
return EveCharacter.objects.filter(user=self.user)
|
||||||
|
|
||||||
@property
|
|
||||||
def apis(self):
|
|
||||||
return EveApiKeyPair.objects.filter(user=self.user)
|
|
||||||
|
|
||||||
@property
|
@property
|
||||||
def reviewer_str(self):
|
def reviewer_str(self):
|
||||||
if self.reviewer_character:
|
if self.reviewer_character:
|
||||||
|
@ -11,7 +11,6 @@ from hrapplications.models import ApplicationComment
|
|||||||
from hrapplications.forms import HRApplicationCommentForm
|
from hrapplications.forms import HRApplicationCommentForm
|
||||||
from hrapplications.forms import HRApplicationSearchForm
|
from hrapplications.forms import HRApplicationSearchForm
|
||||||
from eveonline.models import EveCharacter
|
from eveonline.models import EveCharacter
|
||||||
from authentication.models import AuthServicesInfo
|
|
||||||
|
|
||||||
import logging
|
import logging
|
||||||
|
|
||||||
@ -19,11 +18,7 @@ logger = logging.getLogger(__name__)
|
|||||||
|
|
||||||
|
|
||||||
def create_application_test(user):
|
def create_application_test(user):
|
||||||
auth = AuthServicesInfo.objects.get(user=user)
|
return bool(user.profile.main_character)
|
||||||
if auth.main_char_id:
|
|
||||||
return True
|
|
||||||
else:
|
|
||||||
return False
|
|
||||||
|
|
||||||
|
|
||||||
@login_required
|
@login_required
|
||||||
@ -31,13 +26,7 @@ def hr_application_management_view(request):
|
|||||||
logger.debug("hr_application_management_view called by user %s" % request.user)
|
logger.debug("hr_application_management_view called by user %s" % request.user)
|
||||||
corp_applications = []
|
corp_applications = []
|
||||||
finished_corp_applications = []
|
finished_corp_applications = []
|
||||||
auth_info = AuthServicesInfo.objects.get(user=request.user)
|
main_char = request.user.profile.main_character
|
||||||
main_char = None
|
|
||||||
if auth_info.main_char_id:
|
|
||||||
try:
|
|
||||||
main_char = EveCharacter.objects.get(character_id=auth_info.main_char_id)
|
|
||||||
except EveCharacter.DoesNotExist:
|
|
||||||
pass
|
|
||||||
if request.user.is_superuser:
|
if request.user.is_superuser:
|
||||||
corp_applications = Application.objects.filter(approved=None)
|
corp_applications = Application.objects.filter(approved=None)
|
||||||
finished_corp_applications = Application.objects.exclude(approved=None)
|
finished_corp_applications = Application.objects.exclude(approved=None)
|
||||||
@ -99,7 +88,6 @@ def hr_application_personal_view(request, app_id):
|
|||||||
'buttons': False,
|
'buttons': False,
|
||||||
'comments': ApplicationComment.objects.filter(application=app),
|
'comments': ApplicationComment.objects.filter(application=app),
|
||||||
'comment_form': HRApplicationCommentForm(),
|
'comment_form': HRApplicationCommentForm(),
|
||||||
'apis': [],
|
|
||||||
}
|
}
|
||||||
return render(request, 'registered/hrapplicationview.html', context=context)
|
return render(request, 'registered/hrapplicationview.html', context=context)
|
||||||
else:
|
else:
|
||||||
@ -141,17 +129,14 @@ def hr_application_view(request, app_id):
|
|||||||
return redirect(hr_application_view, app_id)
|
return redirect(hr_application_view, app_id)
|
||||||
else:
|
else:
|
||||||
logger.warn("User %s does not have permission to add ApplicationComments" % request.user)
|
logger.warn("User %s does not have permission to add ApplicationComments" % request.user)
|
||||||
|
return redirect(hr_application_view, app_id)
|
||||||
else:
|
else:
|
||||||
logger.debug("Returning blank HRApplication comment form.")
|
logger.debug("Returning blank HRApplication comment form.")
|
||||||
form = HRApplicationCommentForm()
|
form = HRApplicationCommentForm()
|
||||||
apis = []
|
|
||||||
if request.user.has_perm('hrapplications.view_apis'):
|
|
||||||
apis = app.apis
|
|
||||||
context = {
|
context = {
|
||||||
'app': app,
|
'app': app,
|
||||||
'responses': ApplicationResponse.objects.filter(application=app),
|
'responses': ApplicationResponse.objects.filter(application=app),
|
||||||
'buttons': True,
|
'buttons': True,
|
||||||
'apis': apis,
|
|
||||||
'comments': ApplicationComment.objects.filter(application=app),
|
'comments': ApplicationComment.objects.filter(application=app),
|
||||||
'comment_form': form,
|
'comment_form': form,
|
||||||
}
|
}
|
||||||
@ -219,11 +204,9 @@ def hr_application_search(request):
|
|||||||
if request.user.is_superuser:
|
if request.user.is_superuser:
|
||||||
app_list = Application.objects.all()
|
app_list = Application.objects.all()
|
||||||
else:
|
else:
|
||||||
auth_info = AuthServicesInfo.objects.get(user=request.user)
|
|
||||||
try:
|
try:
|
||||||
character = EveCharacter.objects.get(character_id=auth_info.main_char_id)
|
app_list = Application.objects.filter(form__corp__corporation_id=request.user.profile.main_character.corporation_id)
|
||||||
app_list = Application.objects.filter(form__corp__corporation_id=character.corporation_id)
|
except AttributeError:
|
||||||
except EveCharacter.DoesNotExist:
|
|
||||||
logger.warn(
|
logger.warn(
|
||||||
"User %s missing main character model: unable to filter applications to search" % request.user)
|
"User %s missing main character model: unable to filter applications to search" % request.user)
|
||||||
for application in app_list:
|
for application in app_list:
|
||||||
@ -267,14 +250,8 @@ def hr_application_mark_in_progress(request, app_id):
|
|||||||
app = get_object_or_404(Application, pk=app_id)
|
app = get_object_or_404(Application, pk=app_id)
|
||||||
if not app.reviewer:
|
if not app.reviewer:
|
||||||
logger.info("User %s marking %s in progress" % (request.user, app))
|
logger.info("User %s marking %s in progress" % (request.user, app))
|
||||||
auth_info = AuthServicesInfo.objects.get(user=request.user)
|
|
||||||
try:
|
|
||||||
character = EveCharacter.objects.get(character_id=auth_info.main_char_id)
|
|
||||||
except EveCharacter.DoesNotExist:
|
|
||||||
logger.warn("User %s marking %s in review has no main character" % (request.user, app))
|
|
||||||
character = None
|
|
||||||
app.reviewer = request.user
|
app.reviewer = request.user
|
||||||
app.reviewer_character = character
|
app.reviewer_character = request.user.profile.main_character
|
||||||
app.save()
|
app.save()
|
||||||
notify(app.user, "Application In Progress",
|
notify(app.user, "Application In Progress",
|
||||||
message="Your application to %s is being reviewed by %s" % (app.form.corp, app.reviewer_str))
|
message="Your application to %s is being reviewed by %s" % (app.form.corp, app.reviewer_str))
|
||||||
|
@ -1078,76 +1078,76 @@ msgstr "Aktualisiere SRP Menge"
|
|||||||
msgid "Saved changes to SRP fleet %(fleetname)s"
|
msgid "Saved changes to SRP fleet %(fleetname)s"
|
||||||
msgstr "Änderungen der SRP flotte %(fleetname)s gespeichert"
|
msgstr "Änderungen der SRP flotte %(fleetname)s gespeichert"
|
||||||
|
|
||||||
#: stock/templates/public/base.html:85
|
#: stock/templates/registered/base.html:85
|
||||||
msgid "Admin"
|
msgid "Admin"
|
||||||
msgstr "Admin"
|
msgstr "Admin"
|
||||||
|
|
||||||
#: stock/templates/public/base.html:87
|
#: stock/templates/registered/base.html:87
|
||||||
msgid "Logout"
|
msgid "Logout"
|
||||||
msgstr "Ausloggen"
|
msgstr "Ausloggen"
|
||||||
|
|
||||||
#: stock/templates/public/base.html:89 stock/templates/public/login.html:14
|
#: stock/templates/registered/base.html:89 stock/templates/public/login.html:14
|
||||||
#: stock/templates/registration/password_reset_complete.html:49
|
#: stock/templates/registration/password_reset_complete.html:49
|
||||||
msgid "Login"
|
msgid "Login"
|
||||||
msgstr "Einloggen"
|
msgstr "Einloggen"
|
||||||
|
|
||||||
#: stock/templates/public/base.html:101
|
#: stock/templates/registered/base.html:101
|
||||||
msgid "Main Navigation"
|
msgid "Main Navigation"
|
||||||
msgstr "Haupmenü"
|
msgstr "Haupmenü"
|
||||||
|
|
||||||
#: stock/templates/public/base.html:106
|
#: stock/templates/registered/base.html:106
|
||||||
msgid " Dashboard"
|
msgid " Dashboard"
|
||||||
msgstr " Dashboard"
|
msgstr " Dashboard"
|
||||||
|
|
||||||
#: stock/templates/public/base.html:113
|
#: stock/templates/registered/base.html:113
|
||||||
msgid " Groups"
|
msgid " Groups"
|
||||||
msgstr " Gruppen"
|
msgstr " Gruppen"
|
||||||
|
|
||||||
#: stock/templates/public/base.html:120
|
#: stock/templates/registered/base.html:120
|
||||||
msgid " Help"
|
msgid " Help"
|
||||||
msgstr " Hilfe"
|
msgstr " Hilfe"
|
||||||
|
|
||||||
#: stock/templates/public/base.html:126
|
#: stock/templates/registered/base.html:126
|
||||||
msgid "Aux Navigation"
|
msgid "Aux Navigation"
|
||||||
msgstr "Zusatz Navigation"
|
msgstr "Zusatz Navigation"
|
||||||
|
|
||||||
#: stock/templates/public/base.html:131
|
#: stock/templates/registered/base.html:131
|
||||||
msgid " Services"
|
msgid " Services"
|
||||||
msgstr " Dienste"
|
msgstr " Dienste"
|
||||||
|
|
||||||
#: stock/templates/public/base.html:140
|
#: stock/templates/registered/base.html:140
|
||||||
msgid " Applications"
|
msgid " Applications"
|
||||||
msgstr " Bewerbungen"
|
msgstr " Bewerbungen"
|
||||||
|
|
||||||
#: stock/templates/public/base.html:148
|
#: stock/templates/registered/base.html:148
|
||||||
msgid " Corporation Stats"
|
msgid " Corporation Stats"
|
||||||
msgstr " Korporationsstatistiken"
|
msgstr " Korporationsstatistiken"
|
||||||
|
|
||||||
#: stock/templates/public/base.html:156
|
#: stock/templates/registered/base.html:156
|
||||||
msgid " Group Management"
|
msgid " Group Management"
|
||||||
msgstr " Gruppenverwaltung"
|
msgstr " Gruppenverwaltung"
|
||||||
|
|
||||||
#: stock/templates/public/base.html:174
|
#: stock/templates/registered/base.html:174
|
||||||
msgid " Fleet Operations"
|
msgid " Fleet Operations"
|
||||||
msgstr " Flottenoperationen"
|
msgstr " Flottenoperationen"
|
||||||
|
|
||||||
#: stock/templates/public/base.html:181
|
#: stock/templates/registered/base.html:181
|
||||||
msgid " Structure Timers"
|
msgid " Structure Timers"
|
||||||
msgstr " Strukturen Timer"
|
msgstr " Strukturen Timer"
|
||||||
|
|
||||||
#: stock/templates/public/base.html:188
|
#: stock/templates/registered/base.html:188
|
||||||
msgid " Fleet Activity Tracking"
|
msgid " Fleet Activity Tracking"
|
||||||
msgstr " Flottenaktivitäts-Tracking"
|
msgstr " Flottenaktivitäts-Tracking"
|
||||||
|
|
||||||
#: stock/templates/public/base.html:194
|
#: stock/templates/registered/base.html:194
|
||||||
msgid " Ship Replacement"
|
msgid " Ship Replacement"
|
||||||
msgstr " Schiff’s erstattung"
|
msgstr " Schiff’s erstattung"
|
||||||
|
|
||||||
#: stock/templates/public/base.html:200
|
#: stock/templates/registered/base.html:200
|
||||||
msgid "Util"
|
msgid "Util"
|
||||||
msgstr "Werkzeuge"
|
msgstr "Werkzeuge"
|
||||||
|
|
||||||
#: stock/templates/public/base.html:204
|
#: stock/templates/registered/base.html:204
|
||||||
#: stock/templates/registration/password_change_done.html:10
|
#: stock/templates/registration/password_change_done.html:10
|
||||||
#: stock/templates/registration/password_change_form.html:9
|
#: stock/templates/registration/password_change_form.html:9
|
||||||
#: stock/templates/registration/password_change_form.html:18
|
#: stock/templates/registration/password_change_form.html:18
|
||||||
@ -1155,7 +1155,7 @@ msgstr "Werkzeuge"
|
|||||||
msgid "Change Password"
|
msgid "Change Password"
|
||||||
msgstr "Passwort ändern"
|
msgstr "Passwort ändern"
|
||||||
|
|
||||||
#: stock/templates/public/base.html:211
|
#: stock/templates/registered/base.html:211
|
||||||
msgid " Fleet Broadcast Formatter"
|
msgid " Fleet Broadcast Formatter"
|
||||||
msgstr "Flottenübertragungen Formatierer "
|
msgstr "Flottenübertragungen Formatierer "
|
||||||
|
|
||||||
|
@ -19,14 +19,15 @@ class NotificationHandler(logging.Handler):
|
|||||||
message += "\n\n"
|
message += "\n\n"
|
||||||
message = message + record.exc_text
|
message = message + record.exc_text
|
||||||
|
|
||||||
users = User.objects.filter(Q(groups__permissions=perm) | Q(user_permissions=perm) | Q(is_superuser=True)).distinct()
|
users = User.objects.filter(
|
||||||
|
Q(groups__permissions=perm) | Q(user_permissions=perm) | Q(is_superuser=True)).distinct()
|
||||||
|
|
||||||
for user in users:
|
for user in users:
|
||||||
notify(
|
notify(
|
||||||
user,
|
user,
|
||||||
"%s [%s:%s]" % (record.levelname, record.funcName, record.lineno),
|
"%s [%s:%s]" % (record.levelname, record.funcName, record.lineno),
|
||||||
level = str([item[0] for item in Notification.LEVEL_CHOICES if item[1] == record.levelname][0]),
|
level=str([item[0] for item in Notification.LEVEL_CHOICES if item[1] == record.levelname][0]),
|
||||||
message = message
|
message=message
|
||||||
)
|
)
|
||||||
except Permission.DoesNotExist:
|
except Permission.DoesNotExist:
|
||||||
pass
|
pass
|
||||||
|
20
notifications/migrations/0003_auto_20170322_2335.py
Normal file
20
notifications/migrations/0003_auto_20170322_2335.py
Normal file
@ -0,0 +1,20 @@
|
|||||||
|
# -*- coding: utf-8 -*-
|
||||||
|
# Generated by Django 1.10.5 on 2017-03-22 23:35
|
||||||
|
from __future__ import unicode_literals
|
||||||
|
|
||||||
|
from django.db import migrations, models
|
||||||
|
|
||||||
|
|
||||||
|
class Migration(migrations.Migration):
|
||||||
|
|
||||||
|
dependencies = [
|
||||||
|
('notifications', '0002_auto_20160910_1649'),
|
||||||
|
]
|
||||||
|
|
||||||
|
operations = [
|
||||||
|
migrations.AlterField(
|
||||||
|
model_name='notification',
|
||||||
|
name='level',
|
||||||
|
field=models.CharField(choices=[('danger', 'CRITICAL'), ('danger', 'ERROR'), ('warning', 'WARN'), ('info', 'INFO'), ('success', 'DEBUG')], max_length=10),
|
||||||
|
),
|
||||||
|
]
|
@ -1,6 +1,6 @@
|
|||||||
from __future__ import unicode_literals
|
from __future__ import unicode_literals
|
||||||
from django.contrib import admin
|
from django.contrib import admin
|
||||||
|
|
||||||
from optimer.models import optimer
|
from optimer.models import OpTimer
|
||||||
|
|
||||||
admin.site.register(optimer)
|
admin.site.register(OpTimer)
|
||||||
|
@ -3,7 +3,7 @@ from django import forms
|
|||||||
from django.utils.translation import ugettext_lazy as _
|
from django.utils.translation import ugettext_lazy as _
|
||||||
|
|
||||||
|
|
||||||
class opForm(forms.Form):
|
class OpForm(forms.Form):
|
||||||
doctrine = forms.CharField(max_length=254, required=True, label=_('Doctrine'))
|
doctrine = forms.CharField(max_length=254, required=True, label=_('Doctrine'))
|
||||||
system = forms.CharField(max_length=254, required=True, label=_("System"))
|
system = forms.CharField(max_length=254, required=True, label=_("System"))
|
||||||
location = forms.CharField(max_length=254, required=True, label=_("Location"))
|
location = forms.CharField(max_length=254, required=True, label=_("Location"))
|
||||||
|
50
optimer/migrations/0002_auto_20170322_2335.py
Normal file
50
optimer/migrations/0002_auto_20170322_2335.py
Normal file
@ -0,0 +1,50 @@
|
|||||||
|
# -*- coding: utf-8 -*-
|
||||||
|
# Generated by Django 1.10.5 on 2017-03-22 23:35
|
||||||
|
from __future__ import unicode_literals
|
||||||
|
|
||||||
|
from django.db import migrations, models
|
||||||
|
|
||||||
|
|
||||||
|
class Migration(migrations.Migration):
|
||||||
|
|
||||||
|
dependencies = [
|
||||||
|
('optimer', '0001_initial'),
|
||||||
|
]
|
||||||
|
|
||||||
|
operations = [
|
||||||
|
migrations.AlterField(
|
||||||
|
model_name='optimer',
|
||||||
|
name='details',
|
||||||
|
field=models.CharField(default='', max_length=254),
|
||||||
|
),
|
||||||
|
migrations.AlterField(
|
||||||
|
model_name='optimer',
|
||||||
|
name='doctrine',
|
||||||
|
field=models.CharField(default='', max_length=254),
|
||||||
|
),
|
||||||
|
migrations.AlterField(
|
||||||
|
model_name='optimer',
|
||||||
|
name='duration',
|
||||||
|
field=models.CharField(default='', max_length=25),
|
||||||
|
),
|
||||||
|
migrations.AlterField(
|
||||||
|
model_name='optimer',
|
||||||
|
name='fc',
|
||||||
|
field=models.CharField(default='', max_length=254),
|
||||||
|
),
|
||||||
|
migrations.AlterField(
|
||||||
|
model_name='optimer',
|
||||||
|
name='location',
|
||||||
|
field=models.CharField(default='', max_length=254),
|
||||||
|
),
|
||||||
|
migrations.AlterField(
|
||||||
|
model_name='optimer',
|
||||||
|
name='operation_name',
|
||||||
|
field=models.CharField(default='', max_length=254),
|
||||||
|
),
|
||||||
|
migrations.AlterField(
|
||||||
|
model_name='optimer',
|
||||||
|
name='system',
|
||||||
|
field=models.CharField(default='', max_length=254),
|
||||||
|
),
|
||||||
|
]
|
@ -7,7 +7,7 @@ from datetime import datetime
|
|||||||
|
|
||||||
|
|
||||||
@python_2_unicode_compatible
|
@python_2_unicode_compatible
|
||||||
class optimer(models.Model):
|
class OpTimer(models.Model):
|
||||||
class Meta:
|
class Meta:
|
||||||
ordering = ['start']
|
ordering = ['start']
|
||||||
|
|
||||||
|
@ -6,11 +6,8 @@ from django.utils.translation import ugettext_lazy as _
|
|||||||
from django.shortcuts import get_object_or_404
|
from django.shortcuts import get_object_or_404
|
||||||
from django.shortcuts import render, redirect
|
from django.shortcuts import render, redirect
|
||||||
from django.contrib import messages
|
from django.contrib import messages
|
||||||
from authentication.models import AuthServicesInfo
|
from optimer.form import OpForm
|
||||||
from eveonline.managers import EveManager
|
from optimer.models import OpTimer
|
||||||
from optimer.form import opForm
|
|
||||||
from optimer.models import optimer
|
|
||||||
from authentication.decorators import members_and_blues
|
|
||||||
|
|
||||||
import logging
|
import logging
|
||||||
|
|
||||||
@ -18,11 +15,10 @@ logger = logging.getLogger(__name__)
|
|||||||
|
|
||||||
|
|
||||||
@login_required
|
@login_required
|
||||||
@members_and_blues()
|
|
||||||
@permission_required('auth.optimer_view')
|
@permission_required('auth.optimer_view')
|
||||||
def optimer_view(request):
|
def optimer_view(request):
|
||||||
logger.debug("optimer_view called by user %s" % request.user)
|
logger.debug("optimer_view called by user %s" % request.user)
|
||||||
render_items = {'optimer': optimer.objects.all(), }
|
render_items = {'optimer': OpTimer.objects.all(), }
|
||||||
|
|
||||||
return render(request, 'registered/operationmanagement.html', context=render_items)
|
return render(request, 'registered/operationmanagement.html', context=render_items)
|
||||||
|
|
||||||
@ -32,16 +28,15 @@ def optimer_view(request):
|
|||||||
def add_optimer_view(request):
|
def add_optimer_view(request):
|
||||||
logger.debug("add_optimer_view called by user %s" % request.user)
|
logger.debug("add_optimer_view called by user %s" % request.user)
|
||||||
if request.method == 'POST':
|
if request.method == 'POST':
|
||||||
form = opForm(request.POST)
|
form = OpForm(request.POST)
|
||||||
logger.debug("Request type POST contains form valid: %s" % form.is_valid())
|
logger.debug("Request type POST contains form valid: %s" % form.is_valid())
|
||||||
if form.is_valid():
|
if form.is_valid():
|
||||||
# Get Current Time
|
# Get Current Time
|
||||||
post_time = timezone.now()
|
post_time = timezone.now()
|
||||||
# Get character
|
# Get character
|
||||||
auth_info = AuthServicesInfo.objects.get(user=request.user)
|
character = request.user.profile.main_character
|
||||||
character = EveManager.get_character_by_id(auth_info.main_char_id)
|
|
||||||
# handle valid form
|
# handle valid form
|
||||||
op = optimer()
|
op = OpTimer()
|
||||||
op.doctrine = form.cleaned_data['doctrine']
|
op.doctrine = form.cleaned_data['doctrine']
|
||||||
op.system = form.cleaned_data['system']
|
op.system = form.cleaned_data['system']
|
||||||
op.location = form.cleaned_data['location']
|
op.location = form.cleaned_data['location']
|
||||||
@ -58,7 +53,7 @@ def add_optimer_view(request):
|
|||||||
return redirect("/optimer/")
|
return redirect("/optimer/")
|
||||||
else:
|
else:
|
||||||
logger.debug("Returning new opForm")
|
logger.debug("Returning new opForm")
|
||||||
form = opForm()
|
form = OpForm()
|
||||||
|
|
||||||
render_items = {'form': form}
|
render_items = {'form': form}
|
||||||
|
|
||||||
@ -69,14 +64,10 @@ def add_optimer_view(request):
|
|||||||
@permission_required('auth.optimer_management')
|
@permission_required('auth.optimer_management')
|
||||||
def remove_optimer(request, optimer_id):
|
def remove_optimer(request, optimer_id):
|
||||||
logger.debug("remove_optimer called by user %s for operation id %s" % (request.user, optimer_id))
|
logger.debug("remove_optimer called by user %s for operation id %s" % (request.user, optimer_id))
|
||||||
if optimer.objects.filter(id=optimer_id).exists():
|
op = get_object_or_404(OpTimer, id=optimer_id)
|
||||||
op = optimer.objects.get(id=optimer_id)
|
op.delete()
|
||||||
op.delete()
|
logger.info("Deleting optimer id %s by user %s" % (optimer_id, request.user))
|
||||||
logger.info("Deleting optimer id %s by user %s" % (optimer_id, request.user))
|
messages.success(request, _('Removed operation timer for %(opname)s.') % {"opname": op.operation_name})
|
||||||
messages.success(request, _('Removed operation timer for %(opname)s.') % {"opname": op.operation_name})
|
|
||||||
else:
|
|
||||||
logger.error("Unable to delete optimer id %s for user %s - operation matching id not found." % (
|
|
||||||
optimer_id, request.user))
|
|
||||||
return redirect("auth_optimer_view")
|
return redirect("auth_optimer_view")
|
||||||
|
|
||||||
|
|
||||||
@ -84,13 +75,12 @@ def remove_optimer(request, optimer_id):
|
|||||||
@permission_required('auth.optimer_management')
|
@permission_required('auth.optimer_management')
|
||||||
def edit_optimer(request, optimer_id):
|
def edit_optimer(request, optimer_id):
|
||||||
logger.debug("edit_optimer called by user %s for optimer id %s" % (request.user, optimer_id))
|
logger.debug("edit_optimer called by user %s for optimer id %s" % (request.user, optimer_id))
|
||||||
op = get_object_or_404(optimer, id=optimer_id)
|
op = get_object_or_404(OpTimer, id=optimer_id)
|
||||||
if request.method == 'POST':
|
if request.method == 'POST':
|
||||||
form = opForm(request.POST)
|
form = OpForm(request.POST)
|
||||||
logger.debug("Received POST request containing update optimer form, is valid: %s" % form.is_valid())
|
logger.debug("Received POST request containing update optimer form, is valid: %s" % form.is_valid())
|
||||||
if form.is_valid():
|
if form.is_valid():
|
||||||
auth_info = AuthServicesInfo.objects.get(user=request.user)
|
character = request.user.profile.main_character
|
||||||
character = EveManager.get_character_by_id(auth_info.main_char_id)
|
|
||||||
op.doctrine = form.cleaned_data['doctrine']
|
op.doctrine = form.cleaned_data['doctrine']
|
||||||
op.system = form.cleaned_data['system']
|
op.system = form.cleaned_data['system']
|
||||||
op.location = form.cleaned_data['location']
|
op.location = form.cleaned_data['location']
|
||||||
@ -115,5 +105,5 @@ def edit_optimer(request, optimer_id):
|
|||||||
'fc': op.fc,
|
'fc': op.fc,
|
||||||
'details': op.details,
|
'details': op.details,
|
||||||
}
|
}
|
||||||
form = opForm(initial=data)
|
form = OpForm(initial=data)
|
||||||
return render(request, 'registered/optimerupdate.html', context={'form': form})
|
return render(request, 'registered/optimerupdate.html', context={'form': form})
|
||||||
|
@ -1,4 +1,4 @@
|
|||||||
{% extends "public/base.html" %}
|
{% extends "registered/base.html" %}
|
||||||
{% load bootstrap %}
|
{% load bootstrap %}
|
||||||
{% load staticfiles %}
|
{% load staticfiles %}
|
||||||
{% load i18n %}
|
{% load i18n %}
|
||||||
|
@ -1,4 +1,4 @@
|
|||||||
{% extends "public/base.html" %}
|
{% extends "registered/base.html" %}
|
||||||
{% load bootstrap %}
|
{% load bootstrap %}
|
||||||
{% load staticfiles %}
|
{% load staticfiles %}
|
||||||
{% load i18n %}
|
{% load i18n %}
|
||||||
|
@ -16,6 +16,7 @@ django-bootstrap-form
|
|||||||
django-navhelper
|
django-navhelper
|
||||||
django-bootstrap-pagination
|
django-bootstrap-pagination
|
||||||
django-redis>=4.4
|
django-redis>=4.4
|
||||||
|
django-registration
|
||||||
|
|
||||||
# awating release for fix to celery/django-celery#447
|
# awating release for fix to celery/django-celery#447
|
||||||
# django-celery
|
# django-celery
|
||||||
|
@ -1,5 +0,0 @@
|
|||||||
from __future__ import unicode_literals
|
|
||||||
from eveonline.tasks import run_corp_update
|
|
||||||
|
|
||||||
run_corp_update()
|
|
||||||
quit()
|
|
@ -1,11 +1,8 @@
|
|||||||
from __future__ import unicode_literals
|
from __future__ import unicode_literals
|
||||||
|
|
||||||
from django.template.loader import render_to_string
|
from django.template.loader import render_to_string
|
||||||
from django.utils.safestring import mark_safe
|
|
||||||
|
|
||||||
from alliance_auth.hooks import get_hooks
|
from alliance_auth.hooks import get_hooks
|
||||||
from authentication.states import MEMBER_STATE, BLUE_STATE
|
|
||||||
from authentication.models import AuthServicesInfo
|
|
||||||
|
|
||||||
|
|
||||||
class ServicesHook:
|
class ServicesHook:
|
||||||
@ -72,13 +69,12 @@ class ServicesHook:
|
|||||||
def service_active_for_user(self, user):
|
def service_active_for_user(self, user):
|
||||||
pass
|
pass
|
||||||
|
|
||||||
def show_service_ctrl(self, user, state):
|
def show_service_ctrl(self, user):
|
||||||
"""
|
"""
|
||||||
Whether the service control should be displayed to the given user
|
Whether the service control should be displayed to the given user
|
||||||
who has the given service state. Usually this function wont
|
who has the given service state. Usually this function wont
|
||||||
require overloading.
|
require overloading.
|
||||||
:param user: django.contrib.auth.models.User
|
:param user: django.contrib.auth.models.User
|
||||||
:param state: auth user state
|
|
||||||
:return: bool True if the service should be shown
|
:return: bool True if the service should be shown
|
||||||
"""
|
"""
|
||||||
return self.service_active_for_user(user) or user.is_superuser
|
return self.service_active_for_user(user) or user.is_superuser
|
||||||
|
12
services/management/commands/verify_service_accounts.py
Normal file
12
services/management/commands/verify_service_accounts.py
Normal file
@ -0,0 +1,12 @@
|
|||||||
|
from django.core.management.base import BaseCommand
|
||||||
|
from django.contrib.auth.models import User
|
||||||
|
from services.tasks import validate_services
|
||||||
|
|
||||||
|
|
||||||
|
class Command(BaseCommand):
|
||||||
|
help = "Ensures all service accounts belong to users with required permissions."
|
||||||
|
|
||||||
|
def handle(self, *args, **options):
|
||||||
|
for u in User.objects.all():
|
||||||
|
validate_services(u)
|
||||||
|
self.stdout.write(self.style.SUCCESS('Verified all user service accounts.'))
|
@ -1,353 +0,0 @@
|
|||||||
from __future__ import unicode_literals
|
|
||||||
import evelink.api
|
|
||||||
import evelink.char
|
|
||||||
import evelink.eve
|
|
||||||
from authentication.states import MEMBER_STATE, BLUE_STATE
|
|
||||||
from authentication.models import AuthServicesInfo
|
|
||||||
from eveonline.models import EveCharacter
|
|
||||||
from django.conf import settings
|
|
||||||
import requests
|
|
||||||
try:
|
|
||||||
from urllib2 import HTTPError, URLError
|
|
||||||
except ImportError: # py3
|
|
||||||
from urllib.error import URLError, HTTPError
|
|
||||||
|
|
||||||
import logging
|
|
||||||
|
|
||||||
logger = logging.getLogger(__name__)
|
|
||||||
|
|
||||||
|
|
||||||
class EveApiManager:
|
|
||||||
def __init__(self):
|
|
||||||
pass
|
|
||||||
|
|
||||||
class ApiValidationError(Exception):
|
|
||||||
def __init__(self, msg, api_id):
|
|
||||||
self.msg = msg
|
|
||||||
self.api_id = api_id
|
|
||||||
|
|
||||||
def __str__(self):
|
|
||||||
return self.msg
|
|
||||||
|
|
||||||
class ApiMaskValidationError(ApiValidationError):
|
|
||||||
def __init__(self, required_mask, api_mask, api_id):
|
|
||||||
msg = 'Insufficient API mask provided. Required: %s Got: %s' % (required_mask, api_mask)
|
|
||||||
self.required_mask = required_mask
|
|
||||||
self.api_mask = api_mask
|
|
||||||
super(EveApiManager.ApiMaskValidationError, self).__init__(msg, api_id)
|
|
||||||
|
|
||||||
class ApiAccountValidationError(ApiValidationError):
|
|
||||||
def __init__(self, api_id):
|
|
||||||
msg = 'Insufficient API access provided. Full account access is required, got character restricted.'
|
|
||||||
super(EveApiManager.ApiAccountValidationError, self).__init__(msg, api_id)
|
|
||||||
|
|
||||||
class ApiInvalidError(ApiValidationError):
|
|
||||||
def __init__(self, api_id):
|
|
||||||
msg = 'Key is invalid.'
|
|
||||||
super(EveApiManager.ApiInvalidError, self).__init__(msg, api_id)
|
|
||||||
|
|
||||||
class ApiServerUnreachableError(Exception):
|
|
||||||
def __init__(self, e):
|
|
||||||
self.error = e
|
|
||||||
|
|
||||||
def __str__(self):
|
|
||||||
return 'Unable to reach API servers: %s' % str(self.error)
|
|
||||||
|
|
||||||
@staticmethod
|
|
||||||
def get_characters_from_api(api_id, api_key):
|
|
||||||
logger.debug("Getting characters from api id %s" % api_id)
|
|
||||||
api = evelink.api.API(api_key=(api_id, api_key))
|
|
||||||
# Should get characters
|
|
||||||
account = evelink.account.Account(api=api)
|
|
||||||
chars = account.characters()
|
|
||||||
logger.debug("Retrieved characters %s from api id %s" % (chars, api_id))
|
|
||||||
return chars
|
|
||||||
|
|
||||||
@staticmethod
|
|
||||||
def get_corporation_ticker_from_id(corp_id):
|
|
||||||
logger.debug("Getting ticker for corp id %s" % corp_id)
|
|
||||||
api = evelink.api.API()
|
|
||||||
corp = evelink.corp.Corp(api)
|
|
||||||
response = corp.corporation_sheet(corp_id)
|
|
||||||
logger.debug("Retrieved corp sheet for id %s: %s" % (corp_id, response))
|
|
||||||
ticker = response[0]['ticker']
|
|
||||||
logger.debug("Determined corp id %s ticker: %s" % (corp_id, ticker))
|
|
||||||
return ticker
|
|
||||||
|
|
||||||
@staticmethod
|
|
||||||
def get_alliance_information(alliance_id):
|
|
||||||
logger.debug("Getting info for alliance with id %s" % alliance_id)
|
|
||||||
api = evelink.api.API()
|
|
||||||
eve = evelink.eve.EVE(api=api)
|
|
||||||
alliance = eve.alliances()
|
|
||||||
results = alliance[0][int(alliance_id)]
|
|
||||||
logger.debug("Got alliance info %s" % results)
|
|
||||||
return results
|
|
||||||
|
|
||||||
@staticmethod
|
|
||||||
def get_corporation_information(corp_id):
|
|
||||||
logger.debug("Getting info for corp with id %s" % corp_id)
|
|
||||||
api = evelink.api.API()
|
|
||||||
corp = evelink.corp.Corp(api=api)
|
|
||||||
corpinfo = corp.corporation_sheet(corp_id=int(corp_id))
|
|
||||||
results = corpinfo[0]
|
|
||||||
logger.debug("Got corp info %s" % results)
|
|
||||||
return results
|
|
||||||
|
|
||||||
@staticmethod
|
|
||||||
def get_api_info(api_id, api_key):
|
|
||||||
api = evelink.api.API(api_key=(api_id, api_key))
|
|
||||||
account = evelink.account.Account(api=api)
|
|
||||||
return account.key_info()[0]
|
|
||||||
|
|
||||||
@staticmethod
|
|
||||||
def check_api_is_type_account(api_id, api_key):
|
|
||||||
logger.debug("Checking if api id %s is account." % api_id)
|
|
||||||
api = evelink.api.API(api_key=(api_id, api_key))
|
|
||||||
account = evelink.account.Account(api=api)
|
|
||||||
info = account.key_info()
|
|
||||||
logger.debug("API id %s is type %s" % (api_id, info[0]['type']))
|
|
||||||
return info[0]['type'] == "account"
|
|
||||||
|
|
||||||
@staticmethod
|
|
||||||
def check_api_is_full(api_id, api_key):
|
|
||||||
logger.debug("Checking if api id %s meets member requirements." % api_id)
|
|
||||||
api = evelink.api.API(api_key=(api_id, api_key))
|
|
||||||
account = evelink.account.Account(api=api)
|
|
||||||
info = account.key_info()
|
|
||||||
logger.debug("API has mask %s, required is %s" % (info[0]['access_mask'], settings.MEMBER_API_MASK))
|
|
||||||
return info[0]['access_mask'] & int(settings.MEMBER_API_MASK) == int(settings.MEMBER_API_MASK)
|
|
||||||
|
|
||||||
@staticmethod
|
|
||||||
def check_blue_api_is_full(api_id, api_key):
|
|
||||||
logger.debug("Checking if api id %s meets blue requirements." % api_id)
|
|
||||||
api = evelink.api.API(api_key=(api_id, api_key))
|
|
||||||
account = evelink.account.Account(api=api)
|
|
||||||
info = account.key_info()
|
|
||||||
logger.debug("API has mask %s, required is %s" % (info[0]['access_mask'], settings.BLUE_API_MASK))
|
|
||||||
return info[0]['access_mask'] & int(settings.BLUE_API_MASK) == int(settings.BLUE_API_MASK)
|
|
||||||
|
|
||||||
@staticmethod
|
|
||||||
def get_api_info(api_id, api_key):
|
|
||||||
logger.debug("Getting api info for key id %s" % api_id)
|
|
||||||
api = evelink.api.API(api_key=(api_id, api_key))
|
|
||||||
account = evelink.account.Account(api=api)
|
|
||||||
info = account.key_info()
|
|
||||||
logger.debug("Got info for api id %s: %s" % (api_id, info))
|
|
||||||
return info
|
|
||||||
|
|
||||||
@staticmethod
|
|
||||||
def api_key_is_valid(api_id, api_key):
|
|
||||||
logger.debug("Checking if api id %s is valid." % api_id)
|
|
||||||
api = evelink.api.API(api_key=(api_id, api_key))
|
|
||||||
account = evelink.account.Account(api=api)
|
|
||||||
account.key_info()
|
|
||||||
logger.info("Verified api id %s is still valid." % api_id)
|
|
||||||
return True
|
|
||||||
|
|
||||||
@staticmethod
|
|
||||||
def check_if_api_server_online():
|
|
||||||
logger.debug("Checking if API server online.")
|
|
||||||
try:
|
|
||||||
api = evelink.api.API()
|
|
||||||
server = evelink.server.Server(api=api)
|
|
||||||
server.server_status()
|
|
||||||
logger.info("Verified API server is online and reachable.")
|
|
||||||
return True
|
|
||||||
except evelink.api.APIError:
|
|
||||||
logger.exception("APIError occured while trying to query api server. Possibly offline?")
|
|
||||||
|
|
||||||
logger.warn("Unable to reach API server.")
|
|
||||||
return False
|
|
||||||
|
|
||||||
@staticmethod
|
|
||||||
def check_if_id_is_corp(corp_id):
|
|
||||||
logger.debug("Checking if id %s is a corp." % corp_id)
|
|
||||||
try:
|
|
||||||
api = evelink.api.API()
|
|
||||||
corp = evelink.corp.Corp(api=api)
|
|
||||||
corpinfo = corp.corporation_sheet(corp_id=int(corp_id))
|
|
||||||
assert corpinfo[0]
|
|
||||||
logger.debug("Confirmed id %s is a corp." % corp_id)
|
|
||||||
return True
|
|
||||||
except evelink.api.APIError as error:
|
|
||||||
if int(error.code) == '523':
|
|
||||||
logger.debug("Confirmed id %s is not a corp" % corp_id)
|
|
||||||
return False
|
|
||||||
logger.debug("APIError occured while checking if id %s is corp. Possibly not corp?" % corp_id)
|
|
||||||
|
|
||||||
logger.debug("Unable to verify id %s is corp." % corp_id)
|
|
||||||
return False
|
|
||||||
|
|
||||||
@staticmethod
|
|
||||||
def get_corp_standings():
|
|
||||||
if settings.CORP_API_ID and settings.CORP_API_VCODE:
|
|
||||||
logger.debug("Getting corp standings with api id %s" % settings.CORP_API_ID)
|
|
||||||
api = evelink.api.API(api_key=(settings.CORP_API_ID, settings.CORP_API_VCODE))
|
|
||||||
corp = evelink.corp.Corp(api=api)
|
|
||||||
corpinfo = corp.contacts()
|
|
||||||
results = corpinfo.result
|
|
||||||
logger.debug("Got corp standings from settings: %s" % results)
|
|
||||||
return results
|
|
||||||
else:
|
|
||||||
logger.debug("No corp API key supplied in settings. Unable to get standings.")
|
|
||||||
return {}
|
|
||||||
|
|
||||||
@staticmethod
|
|
||||||
def get_corp_membertracking(api, vcode):
|
|
||||||
try:
|
|
||||||
logger.debug("Getting corp membertracking with api id %s" % settings.CORP_API_ID)
|
|
||||||
api = evelink.api.API(api_key=(api, vcode))
|
|
||||||
corp = evelink.corp.Corp(api=api)
|
|
||||||
membertracking = corp.members()
|
|
||||||
results = membertracking.result
|
|
||||||
logger.debug("Got corp membertracking from settings: %s" % results)
|
|
||||||
return results
|
|
||||||
except evelink.api.APIError:
|
|
||||||
logger.exception("Unhandled APIError occured.")
|
|
||||||
return {}
|
|
||||||
|
|
||||||
@staticmethod
|
|
||||||
def check_if_id_is_alliance(alliance_id):
|
|
||||||
logger.debug("Checking if id %s is an alliance." % alliance_id)
|
|
||||||
try:
|
|
||||||
api = evelink.api.API()
|
|
||||||
eve = evelink.eve.EVE(api=api)
|
|
||||||
alliance = eve.alliances()
|
|
||||||
results = alliance.result[int(alliance_id)]
|
|
||||||
if results:
|
|
||||||
logger.debug("Confirmed id %s is an alliance." % alliance_id)
|
|
||||||
return True
|
|
||||||
except evelink.api.APIError:
|
|
||||||
logger.exception(
|
|
||||||
"APIError occured while checking if id %s is an alliance. Possibly not alliance?" % alliance_id)
|
|
||||||
except KeyError:
|
|
||||||
logger.debug("Alliance with id %s not found in active alliance list." % alliance_id)
|
|
||||||
return False
|
|
||||||
logger.debug("Unable to verify id %s is an an alliance." % alliance_id)
|
|
||||||
return False
|
|
||||||
|
|
||||||
@staticmethod
|
|
||||||
def check_if_id_is_character(character_id):
|
|
||||||
logger.debug("Checking if id %s is a character." % character_id)
|
|
||||||
try:
|
|
||||||
api = evelink.api.API()
|
|
||||||
eve = evelink.eve.EVE(api=api)
|
|
||||||
results = eve.character_info_from_id(character_id)
|
|
||||||
if results:
|
|
||||||
logger.debug("Confirmed id %s is a character." % character_id)
|
|
||||||
return True
|
|
||||||
except evelink.api.APIError:
|
|
||||||
logger.debug(
|
|
||||||
"APIError occured while checking if id %s is a character. Possibly not character?" % character_id,
|
|
||||||
exc_info=True)
|
|
||||||
|
|
||||||
logger.debug("Unable to verify id %s is a character." % character_id)
|
|
||||||
return False
|
|
||||||
|
|
||||||
@staticmethod
|
|
||||||
def check_if_alliance_exists(alliance_id):
|
|
||||||
logger.debug("Checking if alliance id %s exists." % alliance_id)
|
|
||||||
try:
|
|
||||||
api = evelink.api.API()
|
|
||||||
eve = evelink.eve.EVE(api=api)
|
|
||||||
alliances = eve.alliances()
|
|
||||||
if int(alliance_id) in alliances[0]:
|
|
||||||
logger.debug("Verified alliance id %s exists." % alliance_id)
|
|
||||||
return True
|
|
||||||
else:
|
|
||||||
logger.debug("Verified alliance id %s does not exist." % alliance_id)
|
|
||||||
return False
|
|
||||||
except evelink.api.APIError:
|
|
||||||
logger.exception("Unhandled APIError occured.")
|
|
||||||
return False
|
|
||||||
except ValueError:
|
|
||||||
# attempts to catch error resulting from checking alliance_of nonetype models
|
|
||||||
logger.exception("Unhandled ValueError occured. Possible nonetype alliance model.")
|
|
||||||
return False
|
|
||||||
except:
|
|
||||||
logger.warn("Exception prevented verification of alliance id %s existance. Assuming false." % alliance_id)
|
|
||||||
return False
|
|
||||||
|
|
||||||
@staticmethod
|
|
||||||
def check_if_corp_exists(corp_id):
|
|
||||||
logger.debug("Checking if corp id %s exists." % corp_id)
|
|
||||||
try:
|
|
||||||
api = evelink.api.API()
|
|
||||||
corp = evelink.corp.Corp(api=api)
|
|
||||||
corpinfo = corp.corporation_sheet(corp_id=corp_id)
|
|
||||||
if corpinfo[0]['members']['current'] > 0:
|
|
||||||
logger.debug(
|
|
||||||
"Verified corp id %s exists with member count %s" % (corp_id, corpinfo[0]['members']['current']))
|
|
||||||
return True
|
|
||||||
else:
|
|
||||||
logger.debug(
|
|
||||||
"Verified corp id %s has closed. Member count %s" % (corp_id, corpinfo[0]['members']['current']))
|
|
||||||
return False
|
|
||||||
except evelink.api.APIError:
|
|
||||||
# could be smart and check for error code523 to verify error due to no corp instead of catch-all
|
|
||||||
logger.exception("Unhandled APIError occured.")
|
|
||||||
return False
|
|
||||||
except:
|
|
||||||
logger.warn("Exception prevented verification of corp id %s existance. Assuming false." % corp_id)
|
|
||||||
return False
|
|
||||||
|
|
||||||
@staticmethod
|
|
||||||
def validate_member_api(api_id, api_key):
|
|
||||||
if settings.MEMBER_API_ACCOUNT:
|
|
||||||
if EveApiManager.check_api_is_type_account(api_id, api_key) is False:
|
|
||||||
logger.info("Api id %s is not type account as required for members - failed validation." % api_id)
|
|
||||||
return False
|
|
||||||
|
|
||||||
if EveApiManager.check_api_is_full(api_id, api_key) is False:
|
|
||||||
logger.info("Api id %s does not meet member access mask requirements - failed validation." % api_id)
|
|
||||||
return False
|
|
||||||
return True
|
|
||||||
|
|
||||||
@staticmethod
|
|
||||||
def validate_blue_api(api_id, api_key):
|
|
||||||
if settings.BLUE_API_ACCOUNT:
|
|
||||||
if EveApiManager.check_api_is_type_account(api_id, api_key) is False:
|
|
||||||
logger.info("Api id %s is not type account as required for blues - failed validation." % api_id)
|
|
||||||
return False
|
|
||||||
if EveApiManager.check_blue_api_is_full(api_id, api_key) is False:
|
|
||||||
logger.info("Api id %s does not meet minimum blue access mask requirements - failed validation." % api_id)
|
|
||||||
return False
|
|
||||||
return True
|
|
||||||
|
|
||||||
@staticmethod
|
|
||||||
def validate_api(api_id, api_key, user):
|
|
||||||
try:
|
|
||||||
info = EveApiManager.get_api_info(api_id, api_key).result
|
|
||||||
except evelink.api.APIError as e:
|
|
||||||
if int(e.code) == 222:
|
|
||||||
raise EveApiManager.ApiInvalidError(api_id)
|
|
||||||
raise e
|
|
||||||
except (requests.exceptions.RequestException, HTTPError, URLError) as e:
|
|
||||||
raise EveApiManager.ApiServerUnreachableError(e)
|
|
||||||
auth = AuthServicesInfo.objects.get(user=user)
|
|
||||||
states = [auth.state]
|
|
||||||
from authentication.tasks import determine_membership_by_character # circular import issue
|
|
||||||
chars = info['characters']
|
|
||||||
for char in chars:
|
|
||||||
evechar = EveCharacter()
|
|
||||||
evechar.character_name = chars[char]['name']
|
|
||||||
evechar.corporation_id = chars[char]['corp']['id']
|
|
||||||
evechar.alliance_id = chars[char]['alliance']['id']
|
|
||||||
states.append(determine_membership_by_character(evechar))
|
|
||||||
if MEMBER_STATE not in states and BLUE_STATE not in states:
|
|
||||||
# default to requiring member keys for applications
|
|
||||||
states.append(MEMBER_STATE)
|
|
||||||
logger.debug('Checking API %s for states %s' % (api_id, states))
|
|
||||||
for state in states:
|
|
||||||
if (state == MEMBER_STATE and settings.MEMBER_API_ACCOUNT) or (
|
|
||||||
state == BLUE_STATE and settings.BLUE_API_ACCOUNT):
|
|
||||||
if info['type'] != 'account':
|
|
||||||
raise EveApiManager.ApiAccountValidationError(api_id)
|
|
||||||
if state == MEMBER_STATE:
|
|
||||||
if int(info['access_mask']) & int(settings.MEMBER_API_MASK) != int(settings.MEMBER_API_MASK):
|
|
||||||
raise EveApiManager.ApiMaskValidationError(settings.MEMBER_API_MASK, info['access_mask'], api_id)
|
|
||||||
elif state == BLUE_STATE:
|
|
||||||
if int(info['access_mask']) & int(settings.BLUE_API_MASK) != int(settings.BLUE_API_MASK):
|
|
||||||
raise EveApiManager.ApiMaskValidationError(settings.BLUE_API_MASK, info['access_mask'], api_id)
|
|
||||||
return True
|
|
20
services/migrations/0003_auto_20170322_2335.py
Normal file
20
services/migrations/0003_auto_20170322_2335.py
Normal file
@ -0,0 +1,20 @@
|
|||||||
|
# -*- coding: utf-8 -*-
|
||||||
|
# Generated by Django 1.10.5 on 2017-03-22 23:35
|
||||||
|
from __future__ import unicode_literals
|
||||||
|
|
||||||
|
from django.db import migrations, models
|
||||||
|
|
||||||
|
|
||||||
|
class Migration(migrations.Migration):
|
||||||
|
|
||||||
|
dependencies = [
|
||||||
|
('services', '0002_auto_20161016_0135'),
|
||||||
|
]
|
||||||
|
|
||||||
|
operations = [
|
||||||
|
migrations.AlterField(
|
||||||
|
model_name='groupcache',
|
||||||
|
name='service',
|
||||||
|
field=models.CharField(choices=[('discourse', 'discourse'), ('discord', 'discord')], max_length=254, unique=True),
|
||||||
|
),
|
||||||
|
]
|
@ -2,7 +2,6 @@ from __future__ import unicode_literals
|
|||||||
|
|
||||||
import logging
|
import logging
|
||||||
|
|
||||||
from django.conf import settings
|
|
||||||
from django.template.loader import render_to_string
|
from django.template.loader import render_to_string
|
||||||
|
|
||||||
from alliance_auth import hooks
|
from alliance_auth import hooks
|
||||||
|
@ -7,7 +7,6 @@ from django.conf import settings
|
|||||||
from django.contrib.auth.models import User
|
from django.contrib.auth.models import User
|
||||||
from django.core.exceptions import ObjectDoesNotExist
|
from django.core.exceptions import ObjectDoesNotExist
|
||||||
|
|
||||||
from eveonline.managers import EveManager
|
|
||||||
from notifications import notify
|
from notifications import notify
|
||||||
from services.modules.discord.manager import DiscordOAuthManager
|
from services.modules.discord.manager import DiscordOAuthManager
|
||||||
from services.tasks import only_one
|
from services.tasks import only_one
|
||||||
@ -60,6 +59,7 @@ class DiscordTasks:
|
|||||||
return True
|
return True
|
||||||
|
|
||||||
@staticmethod
|
@staticmethod
|
||||||
|
@only_one
|
||||||
@app.task(bind=True, name='discord.update_groups')
|
@app.task(bind=True, name='discord.update_groups')
|
||||||
def update_groups(task_self, pk):
|
def update_groups(task_self, pk):
|
||||||
user = User.objects.get(pk=pk)
|
user = User.objects.get(pk=pk)
|
||||||
@ -98,18 +98,21 @@ class DiscordTasks:
|
|||||||
user = User.objects.get(pk=pk)
|
user = User.objects.get(pk=pk)
|
||||||
logger.debug("Updating discord nickname for user %s" % user)
|
logger.debug("Updating discord nickname for user %s" % user)
|
||||||
if DiscordTasks.has_account(user):
|
if DiscordTasks.has_account(user):
|
||||||
character = EveManager.get_main_character(user)
|
if user.profile.main_character:
|
||||||
logger.debug("Updating user %s discord nickname to %s" % (user, character.character_name))
|
character = user.profile.main_character
|
||||||
try:
|
logger.debug("Updating user %s discord nickname to %s" % (user, character.character_name))
|
||||||
DiscordOAuthManager.update_nickname(user.discord.uid, character.character_name)
|
try:
|
||||||
except Exception as e:
|
DiscordOAuthManager.update_nickname(user.discord.uid, character.character_name)
|
||||||
if self:
|
except Exception as e:
|
||||||
logger.exception("Discord nickname sync failed for %s, retrying in 10 mins" % user)
|
if self:
|
||||||
raise self.retry(countdown=60 * 10)
|
logger.exception("Discord nickname sync failed for %s, retrying in 10 mins" % user)
|
||||||
else:
|
raise self.retry(countdown=60 * 10)
|
||||||
# Rethrow
|
else:
|
||||||
raise e
|
# Rethrow
|
||||||
logger.debug("Updated user %s discord nickname." % user)
|
raise e
|
||||||
|
logger.debug("Updated user %s discord nickname." % user)
|
||||||
|
else:
|
||||||
|
logger.debug("User %s does not have a main character" % user)
|
||||||
else:
|
else:
|
||||||
logger.debug("User %s does not have a discord account" % user)
|
logger.debug("User %s does not have a discord account" % user)
|
||||||
|
|
||||||
|
@ -46,7 +46,7 @@ class DiscourseService(ServicesHook):
|
|||||||
|
|
||||||
def render_services_ctrl(self, request):
|
def render_services_ctrl(self, request):
|
||||||
return render_to_string(self.service_ctrl_template, {
|
return render_to_string(self.service_ctrl_template, {
|
||||||
'char': EveManager.get_main_character(request.user)
|
'char': request.user.profile.main_character
|
||||||
}, request=request)
|
}, request=request)
|
||||||
|
|
||||||
|
|
||||||
|
@ -4,10 +4,6 @@ from django.conf import settings
|
|||||||
from django.contrib import messages
|
from django.contrib import messages
|
||||||
from django.contrib.auth.decorators import login_required
|
from django.contrib.auth.decorators import login_required
|
||||||
from django.shortcuts import render, redirect
|
from django.shortcuts import render, redirect
|
||||||
from authentication.states import MEMBER_STATE, BLUE_STATE, NONE_STATE
|
|
||||||
from eveonline.models import EveCharacter
|
|
||||||
from eveonline.managers import EveManager
|
|
||||||
from authentication.models import AuthServicesInfo
|
|
||||||
|
|
||||||
from .manager import DiscourseManager
|
from .manager import DiscourseManager
|
||||||
from .tasks import DiscourseTasks
|
from .tasks import DiscourseTasks
|
||||||
@ -39,16 +35,15 @@ def discourse_sso(request):
|
|||||||
|
|
||||||
## Check if user has access
|
## Check if user has access
|
||||||
|
|
||||||
auth = AuthServicesInfo.objects.get(user=request.user)
|
|
||||||
if not request.user.has_perm(ACCESS_PERM):
|
if not request.user.has_perm(ACCESS_PERM):
|
||||||
messages.error(request, 'You are not authorized to access Discourse.')
|
messages.error(request, 'You are not authorized to access Discourse.')
|
||||||
return redirect('auth_dashboard')
|
return redirect('auth_dashboard')
|
||||||
|
|
||||||
if not auth.main_char_id:
|
if not request.user.profile.main_character:
|
||||||
messages.error(request, "You must have a main character set to access Discourse.")
|
messages.error(request, "You must have a main character set to access Discourse.")
|
||||||
return redirect('auth_characters')
|
return redirect('auth_characters')
|
||||||
|
|
||||||
main_char = EveManager.get_main_character(request.user)
|
main_char = request.user.profile.main_character
|
||||||
if main_char is None:
|
if main_char is None:
|
||||||
messages.error(request, "Your main character is missing a database model. Please select a new one.")
|
messages.error(request, "Your main character is missing a database model. Please select a new one.")
|
||||||
return redirect('auth_characters')
|
return redirect('auth_characters')
|
||||||
@ -60,8 +55,7 @@ def discourse_sso(request):
|
|||||||
messages.error(request, 'No SSO payload or signature. Please contact support if this problem persists.')
|
messages.error(request, 'No SSO payload or signature. Please contact support if this problem persists.')
|
||||||
return redirect('auth_dashboard')
|
return redirect('auth_dashboard')
|
||||||
|
|
||||||
## Validate the payload
|
# Validate the payload
|
||||||
|
|
||||||
try:
|
try:
|
||||||
payload = unquote(payload).encode('utf-8')
|
payload = unquote(payload).encode('utf-8')
|
||||||
decoded = base64.decodestring(payload).decode('utf-8')
|
decoded = base64.decodestring(payload).decode('utf-8')
|
||||||
@ -92,24 +86,23 @@ def discourse_sso(request):
|
|||||||
'name': username,
|
'name': username,
|
||||||
}
|
}
|
||||||
|
|
||||||
if auth.main_char_id:
|
if main_char:
|
||||||
params['avatar_url'] = 'https://image.eveonline.com/Character/%s_256.jpg' % auth.main_char_id
|
params['avatar_url'] = 'https://image.eveonline.com/Character/%s_256.jpg' % main_char.main_char_id
|
||||||
|
|
||||||
return_payload = base64.encodestring(urlencode(params).encode('utf-8'))
|
return_payload = base64.encodestring(urlencode(params).encode('utf-8'))
|
||||||
h = hmac.new(key, return_payload, digestmod=hashlib.sha256)
|
h = hmac.new(key, return_payload, digestmod=hashlib.sha256)
|
||||||
query_string = urlencode({'sso': return_payload, 'sig': h.hexdigest()})
|
query_string = urlencode({'sso': return_payload, 'sig': h.hexdigest()})
|
||||||
|
|
||||||
## Record activation and queue group sync
|
# Record activation and queue group sync
|
||||||
|
|
||||||
if not DiscourseTasks.has_account(request.user):
|
if not DiscourseTasks.has_account(request.user):
|
||||||
discourse_user = DiscourseUser()
|
discourse_user = DiscourseUser()
|
||||||
discourse_user.user = request.user
|
discourse_user.user = request.user
|
||||||
discourse_user.enabled = True
|
discourse_user.enabled = True
|
||||||
discourse_user.save()
|
discourse_user.save()
|
||||||
DiscourseTasks.update_groups.apply_async(args=[request.user.pk], countdown=30) # wait 30s for new user creation on Discourse
|
# wait 30s for new user creation on Discourse before triggering group sync
|
||||||
|
DiscourseTasks.update_groups.apply_async(args=[request.user.pk], countdown=30)
|
||||||
## Redirect back to Discourse
|
|
||||||
|
|
||||||
|
# Redirect back to Discourse
|
||||||
url = '%s/session/sso_login' % settings.DISCOURSE_URL
|
url = '%s/session/sso_login' % settings.DISCOURSE_URL
|
||||||
return redirect('%s?%s' % (url, query_string))
|
return redirect('%s?%s' % (url, query_string))
|
||||||
|
|
||||||
|
@ -22,7 +22,7 @@ ACCESS_PERM = 'ipboard.access_ipboard'
|
|||||||
@permission_required(ACCESS_PERM)
|
@permission_required(ACCESS_PERM)
|
||||||
def activate_ipboard_forum(request):
|
def activate_ipboard_forum(request):
|
||||||
logger.debug("activate_ipboard_forum called by user %s" % request.user)
|
logger.debug("activate_ipboard_forum called by user %s" % request.user)
|
||||||
character = EveManager.get_main_character(request.user)
|
character = request.user.profile.main_character
|
||||||
logger.debug("Adding ipboard user for user %s with main character %s" % (request.user, character))
|
logger.debug("Adding ipboard user for user %s with main character %s" % (request.user, character))
|
||||||
result = IPBoardManager.add_user(character.character_name, request.user.email)
|
result = IPBoardManager.add_user(character.character_name, request.user.email)
|
||||||
if result[0] != "":
|
if result[0] != "":
|
||||||
|
@ -4,8 +4,6 @@ from django.contrib import messages
|
|||||||
from django.contrib.auth.decorators import login_required, permission_required
|
from django.contrib.auth.decorators import login_required, permission_required
|
||||||
from django.shortcuts import render, redirect
|
from django.shortcuts import render, redirect
|
||||||
|
|
||||||
from authentication.decorators import members_and_blues
|
|
||||||
from eveonline.managers import EveManager
|
|
||||||
from services.forms import ServicePasswordForm
|
from services.forms import ServicePasswordForm
|
||||||
|
|
||||||
from .manager import Ips4Manager
|
from .manager import Ips4Manager
|
||||||
@ -23,7 +21,7 @@ ACCESS_PERM = 'ips4.access_ips4'
|
|||||||
@permission_required(ACCESS_PERM)
|
@permission_required(ACCESS_PERM)
|
||||||
def activate_ips4(request):
|
def activate_ips4(request):
|
||||||
logger.debug("activate_ips4 called by user %s" % request.user)
|
logger.debug("activate_ips4 called by user %s" % request.user)
|
||||||
character = EveManager.get_main_character(request.user)
|
character = request.user.profile.main_character
|
||||||
logger.debug("Adding IPS4 user for user %s with main character %s" % (request.user, character))
|
logger.debug("Adding IPS4 user for user %s with main character %s" % (request.user, character))
|
||||||
result = Ips4Manager.add_user(character.character_name, request.user.email)
|
result = Ips4Manager.add_user(character.character_name, request.user.email)
|
||||||
# if empty we failed
|
# if empty we failed
|
||||||
|
@ -22,7 +22,7 @@ ACCESS_PERM = 'market.access_market'
|
|||||||
@permission_required(ACCESS_PERM)
|
@permission_required(ACCESS_PERM)
|
||||||
def activate_market(request):
|
def activate_market(request):
|
||||||
logger.debug("activate_market called by user %s" % request.user)
|
logger.debug("activate_market called by user %s" % request.user)
|
||||||
character = EveManager.get_main_character(request.user)
|
character = request.user.profile.main_character
|
||||||
if character is not None:
|
if character is not None:
|
||||||
logger.debug("Adding market user for user %s with main character %s" % (request.user, character))
|
logger.debug("Adding market user for user %s with main character %s" % (request.user, character))
|
||||||
result = MarketManager.add_user(character.character_name, request.user.email, character.character_id,
|
result = MarketManager.add_user(character.character_name, request.user.email, character.character_id,
|
||||||
|
@ -3,16 +3,11 @@ from django.contrib.auth.decorators import login_required, permission_required
|
|||||||
from django.shortcuts import render, redirect
|
from django.shortcuts import render, redirect
|
||||||
from django.contrib import messages
|
from django.contrib import messages
|
||||||
|
|
||||||
from eveonline.managers import EveManager
|
|
||||||
from eveonline.models import EveAllianceInfo
|
from eveonline.models import EveAllianceInfo
|
||||||
from authentication.states import MEMBER_STATE, BLUE_STATE, NONE_STATE
|
|
||||||
from authentication.models import AuthServicesInfo
|
|
||||||
|
|
||||||
from services.forms import ServicePasswordForm
|
from services.forms import ServicePasswordForm
|
||||||
|
|
||||||
from .manager import MumbleManager
|
from .manager import MumbleManager
|
||||||
from .tasks import MumbleTasks
|
from .tasks import MumbleTasks
|
||||||
from .models import MumbleUser
|
|
||||||
|
|
||||||
import logging
|
import logging
|
||||||
|
|
||||||
@ -25,20 +20,11 @@ ACCESS_PERM = 'mumble.access_mumble'
|
|||||||
@permission_required(ACCESS_PERM)
|
@permission_required(ACCESS_PERM)
|
||||||
def activate_mumble(request):
|
def activate_mumble(request):
|
||||||
logger.debug("activate_mumble called by user %s" % request.user)
|
logger.debug("activate_mumble called by user %s" % request.user)
|
||||||
authinfo = AuthServicesInfo.objects.get(user=request.user)
|
character = request.user.profile.main_character
|
||||||
character = EveManager.get_main_character(request.user)
|
|
||||||
ticker = character.corporation_ticker
|
ticker = character.corporation_ticker
|
||||||
|
|
||||||
if authinfo.state == BLUE_STATE:
|
logger.debug("Adding mumble user for %s with main character %s" % (request.user, character))
|
||||||
logger.debug("Adding mumble user for blue user %s with main character %s" % (request.user, character))
|
result = MumbleManager.create_user(request.user, ticker, character.character_name)
|
||||||
# Blue members should have alliance ticker (if in alliance)
|
|
||||||
if EveAllianceInfo.objects.filter(alliance_id=character.alliance_id).exists():
|
|
||||||
alliance = EveAllianceInfo.objects.filter(alliance_id=character.alliance_id)[0]
|
|
||||||
ticker = alliance.alliance_ticker
|
|
||||||
result = MumbleManager.create_user(request.user, ticker, character.character_name, blue=True)
|
|
||||||
else:
|
|
||||||
logger.debug("Adding mumble user for user %s with main character %s" % (request.user, character))
|
|
||||||
result = MumbleManager.create_user(request.user, ticker, character.character_name)
|
|
||||||
|
|
||||||
if result:
|
if result:
|
||||||
logger.debug("Updated authserviceinfo for user %s with mumble credentials. Updating groups." % request.user)
|
logger.debug("Updated authserviceinfo for user %s with mumble credentials. Updating groups." % request.user)
|
||||||
|
@ -4,12 +4,7 @@ from django.contrib import messages
|
|||||||
from django.contrib.auth.decorators import login_required, permission_required
|
from django.contrib.auth.decorators import login_required, permission_required
|
||||||
from django.contrib.auth.models import Group
|
from django.contrib.auth.models import Group
|
||||||
from django.shortcuts import render, redirect
|
from django.shortcuts import render, redirect
|
||||||
|
|
||||||
from authentication.decorators import members_and_blues
|
|
||||||
from eveonline.managers import EveManager
|
|
||||||
from eveonline.models import EveCharacter
|
|
||||||
from services.forms import ServicePasswordForm
|
from services.forms import ServicePasswordForm
|
||||||
|
|
||||||
from .manager import OpenfireManager
|
from .manager import OpenfireManager
|
||||||
from .tasks import OpenfireTasks
|
from .tasks import OpenfireTasks
|
||||||
from .forms import JabberBroadcastForm
|
from .forms import JabberBroadcastForm
|
||||||
@ -28,7 +23,7 @@ ACCESS_PERM = 'openfire.access_openfire'
|
|||||||
@permission_required(ACCESS_PERM)
|
@permission_required(ACCESS_PERM)
|
||||||
def activate_jabber(request):
|
def activate_jabber(request):
|
||||||
logger.debug("activate_jabber called by user %s" % request.user)
|
logger.debug("activate_jabber called by user %s" % request.user)
|
||||||
character = EveManager.get_main_character(request.user)
|
character = request.user.profile.main_character
|
||||||
logger.debug("Adding jabber user for user %s with main character %s" % (request.user, character))
|
logger.debug("Adding jabber user for user %s with main character %s" % (request.user, character))
|
||||||
info = OpenfireManager.add_user(character.character_name)
|
info = OpenfireManager.add_user(character.character_name)
|
||||||
# If our username is blank means we already had a user
|
# If our username is blank means we already had a user
|
||||||
@ -101,7 +96,7 @@ def jabber_broadcast_view(request):
|
|||||||
form.fields['group'].choices = allchoices
|
form.fields['group'].choices = allchoices
|
||||||
logger.debug("Received POST request containing form, valid: %s" % form.is_valid())
|
logger.debug("Received POST request containing form, valid: %s" % form.is_valid())
|
||||||
if form.is_valid():
|
if form.is_valid():
|
||||||
main_char = EveManager.get_main_character(request.user)
|
main_char = request.user.profile.main_character
|
||||||
logger.debug("Processing jabber broadcast for user %s with main character %s" % (request.user, main_char))
|
logger.debug("Processing jabber broadcast for user %s with main character %s" % (request.user, main_char))
|
||||||
if main_char is not None:
|
if main_char is not None:
|
||||||
message_to_send = form.cleaned_data[
|
message_to_send = form.cleaned_data[
|
||||||
|
@ -19,7 +19,7 @@ class Phpbb3Service(ServicesHook):
|
|||||||
ServicesHook.__init__(self)
|
ServicesHook.__init__(self)
|
||||||
self.name = 'phpbb3'
|
self.name = 'phpbb3'
|
||||||
self.urlpatterns = urlpatterns
|
self.urlpatterns = urlpatterns
|
||||||
self.service_url = settings.FORUM_URL # TODO: This needs to be renamed at some point...
|
self.service_url = settings.PHPBB3_URL
|
||||||
self.access_perm = 'phpbb3.access_phpbb3'
|
self.access_perm = 'phpbb3.access_phpbb3'
|
||||||
|
|
||||||
@property
|
@property
|
||||||
|
@ -4,8 +4,6 @@ from django.contrib import messages
|
|||||||
from django.contrib.auth.decorators import login_required, permission_required
|
from django.contrib.auth.decorators import login_required, permission_required
|
||||||
from django.shortcuts import render, redirect
|
from django.shortcuts import render, redirect
|
||||||
|
|
||||||
from authentication.decorators import members_and_blues
|
|
||||||
from eveonline.managers import EveManager
|
|
||||||
from services.forms import ServicePasswordForm
|
from services.forms import ServicePasswordForm
|
||||||
|
|
||||||
from .manager import Phpbb3Manager
|
from .manager import Phpbb3Manager
|
||||||
@ -24,7 +22,7 @@ ACCESS_PERM = 'phpbb3.access_phpbb3'
|
|||||||
def activate_forum(request):
|
def activate_forum(request):
|
||||||
logger.debug("activate_forum called by user %s" % request.user)
|
logger.debug("activate_forum called by user %s" % request.user)
|
||||||
# Valid now we get the main characters
|
# Valid now we get the main characters
|
||||||
character = EveManager.get_main_character(request.user)
|
character = request.user.profile.main_character
|
||||||
logger.debug("Adding phpbb user for user %s with main character %s" % (request.user, character))
|
logger.debug("Adding phpbb user for user %s with main character %s" % (request.user, character))
|
||||||
result = Phpbb3Manager.add_user(character.character_name, request.user.email, ['REGISTERED'],
|
result = Phpbb3Manager.add_user(character.character_name, request.user.email, ['REGISTERED'],
|
||||||
character.character_id)
|
character.character_id)
|
||||||
@ -66,7 +64,7 @@ def deactivate_forum(request):
|
|||||||
def reset_forum_password(request):
|
def reset_forum_password(request):
|
||||||
logger.debug("reset_forum_password called by user %s" % request.user)
|
logger.debug("reset_forum_password called by user %s" % request.user)
|
||||||
if Phpbb3Tasks.has_account(request.user):
|
if Phpbb3Tasks.has_account(request.user):
|
||||||
character = EveManager.get_main_character(request.user)
|
character = request.user.profile.main_character
|
||||||
result = Phpbb3Manager.update_user_password(request.user.phpbb3.username, character.character_id)
|
result = Phpbb3Manager.update_user_password(request.user.phpbb3.username, character.character_id)
|
||||||
# false we failed
|
# false we failed
|
||||||
if result != "":
|
if result != "":
|
||||||
@ -95,7 +93,7 @@ def set_forum_password(request):
|
|||||||
if form.is_valid() and Phpbb3Tasks.has_account(request.user):
|
if form.is_valid() and Phpbb3Tasks.has_account(request.user):
|
||||||
password = form.cleaned_data['password']
|
password = form.cleaned_data['password']
|
||||||
logger.debug("Form contains password of length %s" % len(password))
|
logger.debug("Form contains password of length %s" % len(password))
|
||||||
character = EveManager.get_main_character(request.user)
|
character = request.user.profile.main_character
|
||||||
result = Phpbb3Manager.update_user_password(request.user.phpbb3.username, character.character_id,
|
result = Phpbb3Manager.update_user_password(request.user.phpbb3.username, character.character_id,
|
||||||
password=password)
|
password=password)
|
||||||
if result != "":
|
if result != "":
|
||||||
|
@ -21,8 +21,7 @@ ACCESS_PERM = 'seat.access_seat'
|
|||||||
@permission_required(ACCESS_PERM)
|
@permission_required(ACCESS_PERM)
|
||||||
def activate_seat(request):
|
def activate_seat(request):
|
||||||
logger.debug("activate_seat called by user %s" % request.user)
|
logger.debug("activate_seat called by user %s" % request.user)
|
||||||
# Valid now we get the main characters
|
character = request.user.profile.main_character
|
||||||
character = EveManager.get_main_character(request.user)
|
|
||||||
logger.debug("Checking SeAT for inactive users with the same username")
|
logger.debug("Checking SeAT for inactive users with the same username")
|
||||||
stat = SeatManager.check_user_status(character.character_name)
|
stat = SeatManager.check_user_status(character.character_name)
|
||||||
if stat == {}:
|
if stat == {}:
|
||||||
|
@ -23,7 +23,7 @@ ACCESS_PERM = 'smf.access_smf'
|
|||||||
def activate_smf(request):
|
def activate_smf(request):
|
||||||
logger.debug("activate_smf called by user %s" % request.user)
|
logger.debug("activate_smf called by user %s" % request.user)
|
||||||
# Valid now we get the main characters
|
# Valid now we get the main characters
|
||||||
character = EveManager.get_main_character(request.user)
|
character = request.user.profile.main_character
|
||||||
logger.debug("Adding smf user for user %s with main character %s" % (request.user, character))
|
logger.debug("Adding smf user for user %s with main character %s" % (request.user, character))
|
||||||
result = SmfManager.add_user(character.character_name, request.user.email, ['Member'], character.character_id)
|
result = SmfManager.add_user(character.character_name, request.user.email, ['Member'], character.character_id)
|
||||||
# if empty we failed
|
# if empty we failed
|
||||||
@ -64,7 +64,7 @@ def deactivate_smf(request):
|
|||||||
@permission_required(ACCESS_PERM)
|
@permission_required(ACCESS_PERM)
|
||||||
def reset_smf_password(request):
|
def reset_smf_password(request):
|
||||||
logger.debug("reset_smf_password called by user %s" % request.user)
|
logger.debug("reset_smf_password called by user %s" % request.user)
|
||||||
character = EveManager.get_main_character(request.user)
|
character = request.user.profile.main_character
|
||||||
if SmfTasks.has_account(request.user) and character is not None:
|
if SmfTasks.has_account(request.user) and character is not None:
|
||||||
result = SmfManager.update_user_password(request.user.smf.username, character.character_id)
|
result = SmfManager.update_user_password(request.user.smf.username, character.character_id)
|
||||||
# false we failed
|
# false we failed
|
||||||
@ -90,7 +90,7 @@ def set_smf_password(request):
|
|||||||
logger.debug("Received POST request with form.")
|
logger.debug("Received POST request with form.")
|
||||||
form = ServicePasswordForm(request.POST)
|
form = ServicePasswordForm(request.POST)
|
||||||
logger.debug("Form is valid: %s" % form.is_valid())
|
logger.debug("Form is valid: %s" % form.is_valid())
|
||||||
character = EveManager.get_main_character(request.user)
|
character = request.user.profile.main_character
|
||||||
if form.is_valid() and SmfTasks.has_account(request.user) and character is not None:
|
if form.is_valid() and SmfTasks.has_account(request.user) and character is not None:
|
||||||
password = form.cleaned_data['password']
|
password = form.cleaned_data['password']
|
||||||
logger.debug("Form contains password of length %s" % len(password))
|
logger.debug("Form contains password of length %s" % len(password))
|
||||||
|
@ -33,11 +33,6 @@ class Teamspeak3Manager:
|
|||||||
sanatized = "[" + corp_ticker + "]" + username
|
sanatized = "[" + corp_ticker + "]" + username
|
||||||
return sanatized[:30]
|
return sanatized[:30]
|
||||||
|
|
||||||
@staticmethod
|
|
||||||
def __generate_username_blue(username, corp_ticker):
|
|
||||||
sanatized = "[BLUE][" + corp_ticker + "]" + username
|
|
||||||
return sanatized[:30]
|
|
||||||
|
|
||||||
@staticmethod
|
@staticmethod
|
||||||
def _get_userid(uid):
|
def _get_userid(uid):
|
||||||
logger.debug("Looking for uid %s on TS3 server." % uid)
|
logger.debug("Looking for uid %s on TS3 server." % uid)
|
||||||
@ -210,34 +205,6 @@ class Teamspeak3Manager:
|
|||||||
logger.exception("Failed to add teamspeak user %s - received response: %s" % (username_clean, ret))
|
logger.exception("Failed to add teamspeak user %s - received response: %s" % (username_clean, ret))
|
||||||
return "", ""
|
return "", ""
|
||||||
|
|
||||||
@staticmethod
|
|
||||||
def add_blue_user(username, corp_ticker):
|
|
||||||
username_clean = Teamspeak3Manager.__santatize_username(Teamspeak3Manager.__generate_username_blue(username,
|
|
||||||
corp_ticker))
|
|
||||||
server = Teamspeak3Manager.__get_created_server()
|
|
||||||
logger.debug("Adding user to TS3 server with cleaned username %s" % username_clean)
|
|
||||||
server_groups = Teamspeak3Manager._group_list()
|
|
||||||
if settings.DEFAULT_BLUE_GROUP not in server_groups:
|
|
||||||
Teamspeak3Manager._create_group(settings.DEFAULT_BLUE_GROUP)
|
|
||||||
|
|
||||||
blue_group_id = Teamspeak3Manager._group_id_by_name(settings.DEFAULT_BLUE_GROUP)
|
|
||||||
|
|
||||||
try:
|
|
||||||
ret = server.send_command('tokenadd', {'tokentype': 0, 'tokenid1': blue_group_id, 'tokenid2': 0,
|
|
||||||
'tokendescription': username_clean,
|
|
||||||
'tokencustomset': "ident=sso_uid value=%s" % username_clean})
|
|
||||||
except TeamspeakError as e:
|
|
||||||
logger.error("Failed to add blue teamspeak user %s: %s" % (username, str(e)))
|
|
||||||
return "",""
|
|
||||||
|
|
||||||
try:
|
|
||||||
token = ret['keys']['token']
|
|
||||||
logger.info("Created permission token for blue user %s on TS3 server" % username_clean)
|
|
||||||
return username_clean, token
|
|
||||||
except:
|
|
||||||
logger.exception("Failed to add blue teamspeak user %s - received response: %s" % (username_clean, ret))
|
|
||||||
return "", ""
|
|
||||||
|
|
||||||
@staticmethod
|
@staticmethod
|
||||||
def delete_user(uid):
|
def delete_user(uid):
|
||||||
server = Teamspeak3Manager.__get_created_server()
|
server = Teamspeak3Manager.__get_created_server()
|
||||||
|
@ -3,13 +3,10 @@ from __future__ import unicode_literals
|
|||||||
import logging
|
import logging
|
||||||
|
|
||||||
from alliance_auth.celeryapp import app
|
from alliance_auth.celeryapp import app
|
||||||
from celery.schedules import crontab
|
|
||||||
from django.conf import settings
|
|
||||||
from django.contrib.auth.models import User
|
from django.contrib.auth.models import User
|
||||||
from django.core.exceptions import ObjectDoesNotExist
|
from django.core.exceptions import ObjectDoesNotExist
|
||||||
from notifications import notify
|
from notifications import notify
|
||||||
|
|
||||||
from authentication.models import AuthServicesInfo
|
|
||||||
from .util.ts3 import TeamspeakError
|
from .util.ts3 import TeamspeakError
|
||||||
from .manager import Teamspeak3Manager
|
from .manager import Teamspeak3Manager
|
||||||
from .models import AuthTS, TSgroup, UserTSgroup, Teamspeak3User
|
from .models import AuthTS, TSgroup, UserTSgroup, Teamspeak3User
|
||||||
|
Some files were not shown because too many files have changed in this diff Show More
Loading…
x
Reference in New Issue
Block a user