-
-
-
-
diff --git a/.gitattributes b/.gitattributes new file mode 100644 index 00000000..9369413a --- /dev/null +++ b/.gitattributes @@ -0,0 +1 @@ +*/*.py.example linguist-language=Python diff --git a/.gitignore b/.gitignore index da2f9c3a..111ee21b 100644 --- a/.gitignore +++ b/.gitignore @@ -55,3 +55,8 @@ target/ .vagrant/ alliance_auth/settings.py +*Thumbs.db +nginx_config.txt + +# custom staticfiles +static/* diff --git a/README.md b/README.md index 7b8164f2..cdc61d82 100755 --- a/README.md +++ b/README.md @@ -4,15 +4,22 @@ Alliance Auth Alliance service auth to help large scale alliances manage services. Built for "The 99 Percent" open for anyone to use +[NEW Documentation and Setup Guides](http://allianceauth.com) + [Project Website](http://r4stl1n.github.io/allianceauth/) -[Dev Setup Guide] (http://r4stl1n.github.io/allianceauth/quicksetup.html) +[Old Dev Setup Guide] (http://r4stl1n.github.io/allianceauth/quicksetup.html) -[Production Setup Guide] (http://r4stl1n.github.io/allianceauth/fullsetup.html) +[Old Production Setup Guide] (http://r4stl1n.github.io/allianceauth/fullsetup.html) + +Join us in-game in the channel allianceauth for help and feature requests. Special Thanks: + Thanking [Nikdoof](https://github.com/nikdoof), without his old auth implementation this project wouldn't be as far as it is now. + + Thanks to Raynaldo for his original work on this system and getting it as far as it is today. Note: @@ -20,42 +27,6 @@ Note: the admin account for admin stuff do not attempt to use it for your personal services. Create a new normal account for this or things will break. -Update Note: - - The recent HRApplication update broke evolve somehow.. Im sure its in the way i - redid the models. To update when you get the evolve error is first. We need to - remove the old hr tables from mysql. We then need to wipe the evolve records in - the admin section of the auth. Also keep in mind that modifying the mysql database - is dangerous and could corrupt the database if mistakes are made. - - python manage.py syncdb - python manage.py evolve --hint --execute - - To wipe the mysql databse execute the following: - mysql -u MYSQLUSER -p - use ALLIANCEAUTHDATABASE; - drop table hrapplications_hrapplication; - drop table hrapplications_hrapplicationcomment; - - Now go back to the admin interface in both of the evolve sections delete all the entries. - After that go to your shell and run the following. - python manage.py syncdb; - python manage.py shell; - from util import bootstrap_permissions - bootstrap_permissions() - exit() - - This next step is only needed if you hadn't updated since teh IPBoard update. - Back to mysql database and execute the following: - mysql -u MYSQLUSER -p - use ALLIANCEAUTHDATBASE; - ALTER TABLE authentication_authservicesinfo ADD ipboard_password VARCHAR(254); - ALTER TABLE authentication_authservicesinfo ADD ipboard_username VARCHAR(254); - - Now restart mysql and httpd - sudo /etc/init.d/mysqld restart - sudo /etc/init.d/apache2 restart - Requirements: # Django Stuff # @@ -73,8 +44,8 @@ Requirements: python-xmpp python-dnspython - # Needed Apps - Rabbitmq server + # Needed Apps # + Rabbitmq server Startup Instructions: @@ -93,12 +64,17 @@ Special Permissions In Admin: auth | user | human_resources ( Corp only access to view applications ) auth | user | jabber_broadcast ( Access to broadcast a message over jabber to specific groups or all) auth | user | blue_member ( Auto Added to people who register has a blue when adding api key) - auth | user | corp_stats (View basic corp auth stats *who is authed etc*) + auth | user | corp_stats ( View basic corp auth stats *who is authed etc*) auth | user | timer_management ( Access to create and remove timers) + auth | user | timer_view ( Access to timerboard to view timers) auth | user | srp_management ( Allows for an individual to create and remove srp fleets and fleet data) +Active Developers + + Adarnof + Kaezon Rio Beta Testers/ Bug Fixers: - IskFiend ( Bug Fixes and Server Configuration ) - Mr McClain (Bug Fixes and server configuration) \ No newline at end of file + IskFiend ( Bug Fixes and Server Configuration ) + Mr McClain (Bug Fixes and server configuration) diff --git a/alliance_auth/.gitignore b/alliance_auth/.gitignore new file mode 100644 index 00000000..7c24c40c --- /dev/null +++ b/alliance_auth/.gitignore @@ -0,0 +1,2 @@ +/settings.py +!/*.example diff --git a/alliance_auth/settings.py.example b/alliance_auth/settings.py.example index 47efc40c..67535b05 100755 --- a/alliance_auth/settings.py.example +++ b/alliance_auth/settings.py.example @@ -1,4 +1,5 @@ """ +vim: set filetype=python: Django settings for alliance_auth project. For more information on this file, see @@ -6,6 +7,7 @@ https://docs.djangoproject.com/en/1.6/topics/settings/ For the full list of settings and their values, see https://docs.djangoproject.com/en/1.6/ref/settings/ + """ # Build paths inside the project like this: os.path.join(BASE_DIR, ...) @@ -20,6 +22,7 @@ BASE_DIR = os.path.dirname(os.path.dirname(__file__)) # See https://docs.djangoproject.com/en/1.6/howto/deployment/checklist/ # SECURITY WARNING: keep the secret key used in production secret! +# Generate a new key here: http://www.miniwebtool.com/django-secret-key-generator/ SECRET_KEY = os.environ.get('AA_SECRET_KEY', '5xvh4e0x&@-$6(kj%4^80pdo1n5v-!mtx(e(1tw@kn-1le*ts@') # SECURITY WARNING: don't run with debug turned on in production! @@ -77,8 +80,8 @@ DATABASES = { 'default': { 'ENGINE': 'django.db.backends.mysql', 'NAME': 'alliance_auth', - 'USER': os.environ.get('AA_DB_DEFAULT_USER', 'allianceauth'), - 'PASSWORD': os.environ.get('AA_DB_DEFAULT_PASSWORD', 'allianceauth'), + 'USER': os.environ.get('AA_DB_DEFAULT_USER', 'allianceserver'), + 'PASSWORD': os.environ.get('AA_DB_DEFAULT_PASSWORD', 'password'), 'HOST': os.environ.get('AA_DB_DEFAULT_HOST', '127.0.0.1'), 'PORT': os.environ.get('AA_DB_DEFAULT_PORT', '3306'), }, @@ -86,8 +89,8 @@ DATABASES = { 'phpbb3': { 'ENGINE': 'django.db.backends.mysql', 'NAME': 'alliance_forum', - 'USER': os.environ.get('AA_DB_PHPBB3_USER', 'allianceauth'), - 'PASSWORD': os.environ.get('AA_DB_PHPBB3_PASSWORD', 'allianceauth'), + 'USER': os.environ.get('AA_DB_PHPBB3_USER', 'allianceserver'), + 'PASSWORD': os.environ.get('AA_DB_PHPBB3_PASSWORD', 'password'), 'HOST': os.environ.get('AA_DB_PHPBB3_HOST', '127.0.0.1'), 'PORT': os.environ.get('AA_DB_PHPBB3_PORT', '3306'), }, @@ -95,8 +98,8 @@ DATABASES = { 'mumble': { 'ENGINE': 'django.db.backends.mysql', 'NAME': 'alliance_mumble', - 'USER': os.environ.get('AA_DB_MUMBLE_USER', 'alliancemumble'), - 'PASSWORD': os.environ.get('AA_DB_MUMBLE_PASSWORD', 'alliancemumble'), + 'USER': os.environ.get('AA_DB_MUMBLE_USER', 'allianceserver'), + 'PASSWORD': os.environ.get('AA_DB_MUMBLE_PASSWORD', 'password'), 'HOST': os.environ.get('AA_DB_MUMBLE_HOST', '127.0.0.1'), 'PORT': os.environ.get('AA_DB_MUMBLE_PORT', '3306'), } @@ -111,18 +114,25 @@ TEMPLATE_CONTEXT_PROCESSORS = ( 'django.core.context_processors.tz', 'django.contrib.messages.context_processors.messages', 'django.core.context_processors.request', + 'util.context_processors.is_corp', + 'util.context_processors.corp_id', + 'util.context_processors.corp_name', 'util.context_processors.alliance_id', 'util.context_processors.alliance_name', 'util.context_processors.jabber_url', - 'util.context_processors.domain_url' + 'util.context_processors.domain_url', + 'util.context_processors.member_api_mask', + 'util.context_processors.blue_api_mask', ) TEMPLATE_DIRS = ( - 'templates', + 'customization/templates', + 'stock/templates', ) STATICFILES_DIRS = ( - 'static', + 'customization/static', + 'stock/static', ) LOGIN_URL = '/login_user/' @@ -143,24 +153,35 @@ USE_TZ = True # Static files (CSS, JavaScript, Images) # https://docs.djangoproject.com/en/1.6/howto/static-files/ STATIC_URL = '/static/' +STATIC_ROOT = '/home/allianceserver/allianceauth/static/' ##################################################### ## -## Alliance configuration starts here +## Auth configuration starts here ## ##################################################### +########################### +# ALLIANCE / CORP TOGGLE +########################### +# Specifies to run membership checks against corp or alliance +# Set to FALSE for alliance +# Set to TRUE for corp +########################### +IS_CORP = 'True' == os.environ.get('AA_IS_CORP', 'True') + + ################# # EMAIL SETTINGS ################# # DOMAIN - The alliance auth domain_url # EMAIL_HOST - SMTP Server URL # EMAIL_PORT - SMTP Server PORT -# EMAIL_HOST_USER - Email Username +# EMAIL_HOST_USER - Email Username (for gmail, the part before @gmail.com) # EMAIL_HOST_PASSWORD - Email Password # EMAIL_USE_TLS - Set to use TLS encryption ################# -DOMAIN = os.environ.get('AA_DOMAIN', 'https://the99eve.com') +DOMAIN = os.environ.get('AA_DOMAIN', 'https://yourdomain.com') EMAIL_HOST = os.environ.get('AA_EMAIL_HOST', 'smtp.gmail.com') EMAIL_PORT = int(os.environ.get('AA_EMAIL_PORT', '587')) EMAIL_HOST_USER = os.environ.get('AA_EMAIL_HOST_USER', '') @@ -170,54 +191,82 @@ EMAIL_USE_TLS = 'True' == os.environ.get('AA_EMAIL_USE_TLS', 'True') ######################### # Default Group Settings ######################### -# DEFAULT_ALLIANCE_GROUP - Default group alliance members are put in +# DEFAULT_AUTH_GROUP - Default group members are put in # DEFAULT_BLUE_GROUP - Default group for blue members ######################### -DEFAULT_ALLIANCE_GROUP = os.environ.get('AA_DEFAULT_ALLIANCE_GROUP', 'AllianceMember') -DEFAULT_BLUE_GROUP = os.environ.get('AA_DEFAULT_BLUE_GROUP', 'BlueMember') +DEFAULT_AUTH_GROUP = os.environ.get('AA_DEFAULT_ALLIANCE_GROUP', 'Member') +DEFAULT_BLUE_GROUP = os.environ.get('AA_DEFAULT_BLUE_GROUP', 'Blue') ######################### # Alliance Service Setup ######################### -# ENABLE_ALLIANCE_FORUM - Enable forum support in the auth for alliance members -# ENABLE_ALLIANCE_JABBER - Enable jabber support in the auth for alliance members -# ENABLE_ALLIANCE_MUMBLE - Enable mumble support in the auth for alliance members -# ENABLE_ALLIANCE_IPBOARD - Enable IPBoard forum support in the auth for alliance members +# ENABLE_AUTH_FORUM - Enable forum support in the auth for auth'd members +# ENABLE_AUTH_JABBER - Enable jabber support in the auth for auth'd members +# ENABLE_AUTH_MUMBLE - Enable mumble support in the auth for auth'd members +# ENABLE_AUTH_IPBOARD - Enable IPBoard forum support in the auth for auth'd members +# ENABLE_AUTH_DISCORD - Enable Discord support in the auth for auth'd members ######################### -ENABLE_ALLIANCE_FORUM = 'True' == os.environ.get('AA_ENABLE_ALLIANCE_FORUM', 'True') -ENABLE_ALLIANCE_JABBER = 'True' == os.environ.get('AA_ENABLE_ALLIANCE_JABBER', 'True') -ENABLE_ALLIANCE_MUMBLE = 'True' == os.environ.get('AA_ENABLE_ALLIANCE_MUMBLE', 'True') -ENABLE_ALLIANCE_IPBOARD = 'True' == os.environ.get('AA_ENABLE_ALLIANCE_IPBOARD', 'False') -ENABLE_ALLIANCE_TEAMSPEAK3 = 'True' == os.environ.get('AA_ENABLE_ALLIANCE_TEAMSPEAK3', 'False') +ENABLE_AUTH_FORUM = 'True' == os.environ.get('AA_ENABLE_AUTH_FORUM', 'False') +ENABLE_AUTH_JABBER = 'True' == os.environ.get('AA_ENABLE_AUTH_JABBER', 'False') +ENABLE_AUTH_MUMBLE = 'True' == os.environ.get('AA_ENABLE_AUTH_MUMBLE', 'False') +ENABLE_AUTH_IPBOARD = 'True' == os.environ.get('AA_ENABLE_AUTH_IPBOARD', 'False') +ENABLE_AUTH_TEAMSPEAK3 = 'True' == os.environ.get('AA_ENABLE_AUTH_TEAMSPEAK3', 'False') +ENABLE_AUTH_DISCORD = 'True' == os.environ.get('AA_ENABLE_AUTH_DISCORD', 'False') ##################### # Blue service Setup ##################### +# BLUE_STANDING - The default lowest standings setting to consider blue # ENABLE_BLUE_FORUM - Enable forum support in the auth for blues # ENABLE_BLUE_JABBER - Enable jabber support in the auth for blues # ENABLE_BLUE_MUMBLE - Enable mumble support in the auth for blues # ENABLE_BLUE_IPBOARD - Enable IPBoard forum support in the auth for blues +# ENABLE_BLUE_DISCORD - Enable Discord support in the auth for blues ##################### +BLUE_STANDING = float(os.environ.get('AA_BLUE_STANDING', '5.0')) ENABLE_BLUE_FORUM = 'True' == os.environ.get('AA_ENABLE_BLUE_FORUM', 'False') ENABLE_BLUE_JABBER = 'True' == os.environ.get('AA_ENABLE_BLUE_JABBER', 'False') -ENABLE_BLUE_MUMBLE = 'True' == os.environ.get('AA_ENABLE_BLUE_MUMBLE', 'True') +ENABLE_BLUE_MUMBLE = 'True' == os.environ.get('AA_ENABLE_BLUE_MUMBLE', 'False') ENABLE_BLUE_IPBOARD = 'True' == os.environ.get('AA_ENABLE_BLUE_IPBOARD', 'False') ENABLE_BLUE_TEAMSPEAK3 = 'True' == os.environ.get('AA_ENABLE_BLUE_TEAMSPEAK3', 'False') +ENABLE_BLUE_DISCORD = 'True' == os.environ.get('AA_ENABLE_BLUE_DISCORD', 'False') + +######################### +# Corp Configuration +######################### +# If running in alliance mode, the following should be for the executor corp# +# CORP_ID - Set this to your corp ID (get this from https://zkillboard.com/corporation/#######) +# CORP_NAME - Set this to your Corporation Name +# 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 +######################## +CORP_ID = os.environ.get('AA_CORP_ID', '') +CORP_NAME = os.environ.get('AA_CORP_NAME', '') +CORP_API_ID = os.environ.get('AA_CORP_API_ID', '') +CORP_API_VCODE = os.environ.get('AA_CORP_API_VCODE', '') + ######################### # Alliance Configuration ######################### -# ALLIANCE_ID - Set this to your AllianceID +# ALLIANCE_ID - Set this to your Alliance ID (get this from https://zkillboard.com/alliance/#######) # ALLIANCE_NAME - Set this to your Alliance Name -# ALLIANCE_EXEC_CORP_ID - Set this to the api id for the exec corp -# ALLIANCE_EXEC_CORP_VCODE - Set this to the api vcode for the exe corp -# ALLIANCE_BLUE_STANDING - The default lowest standings setting to consider blue ######################## -ALLIANCE_ID = os.environ.get('AA_ALLIANCE_ID', '99001336') -ALLIANCE_NAME = os.environ.get('AA_ALLIANCE_NAME', 'Somealliance') -ALLIANCE_EXEC_CORP_ID = os.environ.get('AA_ALLIANCE_EXEC_CORP_ID', '') -ALLIANCE_EXEC_CORP_VCODE = os.environ.get('AA_ALLIANCE_EXEC_CORP_VCODE', '') -ALLIANCE_BLUE_STANDING = float(os.environ.get('AA_ALLIANCE_BLUE_STANDING', '5.0')) +ALLIANCE_ID = os.environ.get('AA_ALLIANCE_ID', '') +ALLIANCE_NAME = os.environ.get('AA_ALLIANCE_NAME', '') + +######################## +# 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 +####################### +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') ##################### # HR Configuration @@ -235,8 +284,8 @@ JACK_KNIFE_URL = os.environ.get('AA_JACK_KNIFE_URL', 'http://ridetheclown.com/ev # IPBOARD_APIKEY - Api key to interact with ipboard # IPBOARD_APIMODULE - Module for alliance auth *leave alone* ##################### -FORUM_URL = os.environ.get('AA_FORUM_URL', "http://someaddress.com") -IPBOARD_ENDPOINT = os.environ.get('AA_IPBOARD_ENDPOINT', 'someaddress.com/interface/board/index.php') +FORUM_URL = os.environ.get('AA_FORUM_URL', "http://yourdomain.com") +IPBOARD_ENDPOINT = os.environ.get('AA_IPBOARD_ENDPOINT', 'yourdomain.com/interface/board/index.php') IPBOARD_APIKEY = os.environ.get('AA_IPBOARD_APIKEY', 'somekeyhere') IPBOARD_APIMODULE = 'aa' @@ -246,18 +295,20 @@ IPBOARD_APIMODULE = 'aa' # JABBER_URL - Jabber address url # JABBER_PORT - Jabber service portal # JABBER_SERVER - Jabber server url -# OPENFIRE_ADDRESS - Address of the openfire admin console -# OPENFIRE_SECRET_KEY - Openfire userservice secret key +# OPENFIRE_ADDRESS - Address of the openfire admin console including port +# Please use http with 9090 or https with 9091 +# OPENFIRE_SECRET_KEY - Openfire REST API secret key # BROADCAST_USER - Broadcast user JID # BROADCAST_USER_PASSWORD - Broadcast user password ###################### -JABBER_URL = os.environ.get('AA_JABBER_URL', "someaddress.com") +JABBER_URL = os.environ.get('AA_JABBER_URL', "yourdomain.com") JABBER_PORT = int(os.environ.get('AA_JABBER_PORT', '5223')) -JABBER_SERVER = os.environ.get('AA_JABBER_SERVER', "someadddress.com") -OPENFIRE_ADDRESS = os.environ.get('AA_OPENFIRE_ADDRESS', "http://someaddress.com:9090/") +JABBER_SERVER = os.environ.get('AA_JABBER_SERVER', "yourdomain.com") +OPENFIRE_ADDRESS = os.environ.get('AA_OPENFIRE_ADDRESS', "http://yourdomain.com:9090") OPENFIRE_SECRET_KEY = os.environ.get('AA_OPENFIRE_SECRET_KEY', "somekey") BROADCAST_USER = os.environ.get('AA_BROADCAST_USER', "broadcast@") + JABBER_URL BROADCAST_USER_PASSWORD = os.environ.get('AA_BROADCAST_USER_PASSWORD', "somepassword") +BROADCAST_SERVICE_NAME = os.environ.get('AA_BROADCAST_SERVICE_NAME', "broadcast") ###################################### # Mumble Configuration @@ -265,7 +316,7 @@ BROADCAST_USER_PASSWORD = os.environ.get('AA_BROADCAST_USER_PASSWORD', "somepass # MUMBLE_URL - Mumble server url # MUMBLE_SERVER_ID - Mumble server id ###################################### -MUMBLE_URL = os.environ.get('AA_MUMBLE_URL', "someurl.com") +MUMBLE_URL = os.environ.get('AA_MUMBLE_URL', "yourdomain.com") MUMBLE_SERVER_ID = int(os.environ.get('AA_MUMBLE_SERVER_ID', '1')) ###################################### @@ -284,4 +335,15 @@ TEAMSPEAK3_SERVER_PORT = int(os.environ.get('AA_TEAMSPEAK3_SERVER_PORT', '10011' TEAMSPEAK3_SERVERQUERY_USER = os.environ.get('AA_TEAMSPEAK3_SERVERQUERY_USER', 'serveradmin') TEAMSPEAK3_SERVERQUERY_PASSWORD = os.environ.get('AA_TEAMSPEAK3_SERVERQUERY_PASSWORD', 'passwordhere') TEAMSPEAK3_VIRTUAL_SERVER = int(os.environ.get('AA_TEAMSPEAK3_VIRTUAL_SERVER', '1')) -TEAMSPEAK3_PUBLIC_URL = os.environ.get('AA_TEAMSPEAK3_PUBLIC_URL', 'someaddress.com') +TEAMSPEAK3_PUBLIC_URL = os.environ.get('AA_TEAMSPEAK3_PUBLIC_URL', 'yourdomain.com') + +###################################### +# Discord Configuration +###################################### +# DISCORD_SERVER_ID - ID of the server to manage +# DISCORD_USER_EMAIL - email of the server management user +# DISCORD_USER_PASSWORD - password of the server management user +###################################### +DISCORD_SERVER_ID = os.environ.get('AA_DISCORD_SERVER_ID', '') +DISCORD_USER_EMAIL = os.environ.get('AA_DISCORD_USER_EMAIL', '') +DISCORD_USER_PASSWORD = os.environ.get('AA_DISCORD_USER_PASSWORD', '') diff --git a/alliance_auth/urls.py b/alliance_auth/urls.py index 21758bf9..78f3fbd4 100755 --- a/alliance_auth/urls.py +++ b/alliance_auth/urls.py @@ -125,6 +125,11 @@ urlpatterns = patterns('', url(r'reset_teamspeak3_perm/$', 'services.views.reset_teamspeak3_perm', name='auth_reset_teamspeak3_perm'), + # Discord Service Control + url(r'^activate_discord/$', 'services.views.activate_discord', name='auth_activate_discord'), + url(r'^deactivate_discord/$', 'services.views.deactivate_discord', name='auth_deactivate_discord'), + url(r'^reset_discord/$', 'services.views.reset_discord', name='auth_reset_discord'), + # Tools url(r'^tool/fleet_formatter_tool/$', 'services.views.fleet_formatter_view', name='auth_fleet_format_tool_view'), diff --git a/authentication/managers.py b/authentication/managers.py index cee8b1f9..0cea7a07 100755 --- a/authentication/managers.py +++ b/authentication/managers.py @@ -80,3 +80,9 @@ class AuthServicesInfoManager: authserviceinfo.is_blue = is_blue authserviceinfo.save(update_fields=['is_blue']) + @staticmethod + def update_user_discord_info(user_id, user): + if User.objects.filter(username=user.username).exists(): + authserviceinfo = AuthServicesInfoManager.__get_or_create(user) + authserviceinfo.discord_uid = user_id + authserviceinfo.save(update_fields=['discord_uid']) diff --git a/authentication/models.py b/authentication/models.py index 2b8cfd2d..0727e79d 100755 --- a/authentication/models.py +++ b/authentication/models.py @@ -13,9 +13,10 @@ class AuthServicesInfo(models.Model): mumble_password = models.CharField(max_length=254, default="") teamspeak3_uid = models.CharField(max_length=254, default="") teamspeak3_perm_key = models.CharField(max_length=254, default="") + discord_uid = models.CharField(max_length=254, default="") main_char_id = models.CharField(max_length=64, default="") is_blue = models.BooleanField(default=False) user = models.ForeignKey(User) def __str__(self): - return self.user.username + ' - AuthInfo' \ No newline at end of file + return self.user.username + ' - AuthInfo' diff --git a/celerytask/tasks.py b/celerytask/tasks.py index 50b3660c..6aad687f 100755 --- a/celerytask/tasks.py +++ b/celerytask/tasks.py @@ -9,11 +9,42 @@ from services.managers.mumble_manager import MumbleManager from services.managers.phpbb3_manager import Phpbb3Manager from services.managers.ipboard_manager import IPBoardManager from services.managers.teamspeak3_manager import Teamspeak3Manager +from services.managers.discord_manager import DiscordManager +from services.models import AuthTS +from services.models import TSgroup from authentication.models import AuthServicesInfo from eveonline.managers import EveManager from services.managers.eve_api_manager import EveApiManager from util.common_task import deactivate_services +from util import add_member_permission +from util import remove_member_permission +from util import check_if_user_has_permission +from util.common_task import add_user_to_group +from util.common_task import remove_user_from_group +from util.common_task import generate_corp_group_name +from eveonline.models import EveCharacter +from eveonline.models import EveCorporationInfo +from authentication.managers import AuthServicesInfoManager +def disable_alliance_member(user, char_id): + remove_member_permission(user, 'member') + remove_user_from_group(user, settings.DEFAULT_AUTH_GROUP) + remove_user_from_group(user, + generate_corp_group_name( + EveManager.get_character_by_id(char_id).corporation_name)) + deactivate_services(user) + +def disable_expired_member(user): + deactivate_services(user) + user.user_permissions.clear() + user.groups.clear() + user.save() + +def disable_blue_member(user): + remove_member_permission(user, 'blue_member') + remove_user_from_group(user, settings.DEFAULT_BLUE_GROUP) + deactivate_services(user) + AuthServicesInfoManager.update_is_blue(False, user) def update_jabber_groups(user): syncgroups = SyncGroupCache.objects.filter(user=user) @@ -26,8 +57,6 @@ def update_jabber_groups(user): if len(groups) == 0: groups.append('empty') - print groups - OpenfireManager.update_user_groups(authserviceinfo.jabber_username, authserviceinfo.jabber_password, groups) @@ -71,6 +100,19 @@ def update_ipboard_groups(user): def update_teamspeak3_groups(user): + usergroups = user.groups.all() + authserviceinfo = AuthServicesInfo.objects.get(user=user) + groups = {} + for usergroup in usergroups: + filtered_groups = AuthTS.objects.filter(auth_group=usergroup) + if filtered_groups: + for filtered_group in filtered_groups: + for ts_group in filtered_group.ts_group.all(): + groups[ts_group.ts_group_name] = ts_group.ts_group_id + + Teamspeak3Manager.update_groups(authserviceinfo.teamspeak3_uid, groups) + +def update_discord_groups(user): syncgroups = SyncGroupCache.objects.filter(user=user) authserviceinfo = AuthServicesInfo.objects.get(user=user) groups = [] @@ -80,8 +122,7 @@ def update_teamspeak3_groups(user): if len(groups) == 0: groups.append('empty') - Teamspeak3Manager.update_groups(authserviceinfo.teamspeak3_uid, groups) - + DiscordManager.update_groups(authserviceinfo.discord_uid, groups) def create_syncgroup_for_user(user, groupname, servicename): synccache = SyncGroupCache() @@ -107,9 +148,11 @@ def add_to_databases(user, groups, syncgroups): if authserviceinfo: authserviceinfo = AuthServicesInfo.objects.get(user=user) - + + if authserviceinfo.teamspeak3_uid and authserviceinfo.teamspeak3_uid != "": + update_teamspeak3_groups(user) + for group in groups: - if authserviceinfo.jabber_username and authserviceinfo.jabber_username != "": if syncgroups.filter(groupname=group.name).filter(servicename="openfire").exists() is not True: create_syncgroup_for_user(user, group.name, "openfire") @@ -126,10 +169,10 @@ def add_to_databases(user, groups, syncgroups): if syncgroups.filter(groupname=group.name).filter(servicename="ipboard").exists() is not True: create_syncgroup_for_user(user, group.name, "ipboard") update_ipboard_groups(user) - if authserviceinfo.teamspeak3_uid and authserviceinfo.teamspeak3_uid != "": - if syncgroups.filter(groupname=group.name).filter(servicename="teamspeak3").exists() is not True: - create_syncgroup_for_user(user, group.name, "teamspeak3") - update_teamspeak3_groups(user) + if authserviceinfo.discord_uid and authserviceinfo.discord_uid != "": + if syncgroups.filter(groupname=group.name).filter(servicename="discord").exists() is not True: + create_syncgroup_for_user(user, group.name, "discord") + update_discord_groups(user) def remove_from_databases(user, groups, syncgroups): @@ -159,12 +202,15 @@ def remove_from_databases(user, groups, syncgroups): update_ipboard_groups(user) if authserviceinfo.teamspeak3_uid and authserviceinfo.teamspeak3_uid != "": update_teamspeak3_groups(user) + if authserviceinfo.discord_uid and authserviceinfo.discord_uid != "": + update_discord_groups(user) # Run every minute @periodic_task(run_every=crontab(minute="*/1")) def run_databaseUpdate(): users = User.objects.all() + Teamspeak3Manager._sync_ts_group_db() for user in users: groups = user.groups.all() syncgroups = SyncGroupCache.objects.filter(user=user) @@ -188,65 +234,163 @@ def run_api_refresh(): print 'Running update on user: ' + user.username if authserviceinfo.main_char_id: if authserviceinfo.main_char_id != "": + #preserve old corp ID for corp change test on members + oldcorp_id = 0 + if EveManager.get_character_by_id(authserviceinfo.main_char_id): + oldcorp_id = EveCharacter.objects.get(character_id=authserviceinfo.main_char_id).corporation_id for api_key_pair in api_key_pairs: print 'Running on ' + api_key_pair.api_id + ':' + api_key_pair.api_key if EveApiManager.api_key_is_valid(api_key_pair.api_id, api_key_pair.api_key): - # Update characters - characters = EveApiManager.get_characters_from_api(api_key_pair.api_id, - api_key_pair.api_key) - EveManager.update_characters_from_list(characters) - valid_key = True + #check to ensure API key meets min spec + still_valid = True + if authserviceinfo.is_blue: + if settings.BLUE_API_ACCOUNT: + if not EveApiManager.check_api_is_type_account(api_key_pair.api_id, api_key_pair.api_key): + still_valid = False + if not EveApiManager.check_blue_api_is_full(api_key_pair.api_id, api_key_pair.api_key): + still_valid = False + else: + if settings.MEMBER_API_ACCOUNT: + if not EveApiManager.check_api_is_type_account(api_key_pair.api_id, api_key_pair.api_key): + still_valid = False + if not EveApiManager.check_api_is_full(api_key_pair.api_id, api_key_pair.api_key): + still_valid = False + if still_valid is not True: + EveManager.delete_characters_by_api_id(api_key_pair.api_id, user.id) + EveManager.delete_api_key_pair(api_key_pair.api_id, user.id) + else: + # Update characters + characters = EveApiManager.get_characters_from_api(api_key_pair.api_id, + api_key_pair.api_key) + EveManager.update_characters_from_list(characters) + new_character = False + for char in characters.result: + # Ensure we have a model for all characters on key + if not EveManager.check_if_character_exist(characters.result[char]['name']): + new_character = True + if new_character: + EveManager.create_characters_from_list(characters, user, api_key_pair.api_key) + valid_key = True else: - EveManager.delete_characters_by_api_id(api_key_pair.api_id, user) - EveManager.delete_api_key_pair(api_key_pair.api_id, api_key_pair.api_key) + EveManager.delete_characters_by_api_id(api_key_pair.api_id, user.id) + EveManager.delete_api_key_pair(api_key_pair.api_id, user.id) if valid_key: # Check our main character character = EveManager.get_character_by_id(authserviceinfo.main_char_id) - corp = EveManager.get_corporation_info_by_id(character.corporation_id) - main_alliance_id = EveManager.get_charater_alliance_id_by_id(authserviceinfo.main_char_id) - if main_alliance_id == settings.ALLIANCE_ID: - pass - elif corp is not None: - if corp.is_blue is not True: - deactivate_services(user) + if character is not None and EveManager.check_if_corporation_exists_by_id(character.corporation_id): + corp = EveManager.get_corporation_info_by_id(character.corporation_id) + main_corp_id = EveManager.get_charater_corporation_id_by_id(authserviceinfo.main_char_id) + main_alliance_id = EveManager.get_charater_alliance_id_by_id(authserviceinfo.main_char_id) + if (settings.IS_CORP and main_corp_id == settings.CORP_ID) or (not settings.IS_CORP and main_alliance_id == settings.ALLIANCE_ID): + if not check_if_user_has_permission(user, "member"): + #transition from none or blue to member + if check_if_user_has_permission(user, "blue_member"): + #strip blue status + remove_member_permission(user, "blue_member") + remove_user_from_group(user, settings.DEFAULT_BLUE_GROUP) + AuthServicesInfoManager.update_is_blue(False, user) + #add to auth group + add_member_permission(user, "member") + add_user_to_group(user, settings.DEFAULT_AUTH_GROUP) + #add to required corp group + add_user_to_group(user, generate_corp_group_name(character.corporation_name)) + elif corp.corporation_id != oldcorp_id: + #changed corps, both corps auth'd, need to change group assignment + oldcorp = EveCorporationInfo.objects.get(corporation_id=oldcorp_id) + remove_user_from_group(user, generate_corp_group_name(oldcorp.corporation_name)) + add_user_to_group(user, generate_corp_group_name(character.corporation_name)) + #reset services to force new mumble names and group assignments + deactivate_services(user) + elif corp is not None: + if corp.is_blue is not True: + if check_if_user_has_permission(user, "member"): + #transition from member to nobody + disable_alliance_member(user, authserviceinfo.main_char_id) + elif check_if_user_has_permission(user, "blue_member"): + #transition from blue to nobody + disable_blue_member(user) + else: + #stay nobody, make sure no services + deactivate_services(user) + else: + if check_if_user_has_permission(user, "member"): + #remove auth member to prepare for member to blue transition + disable_alliance_member(user, authserviceinfo.main_char_id) + if not check_if_user_has_permission(user, "blue_member"): + #perform nobody to blue transition + add_member_permission(user, "blue_member") + add_user_to_group(user, settings.DEFAULT_BLUE_GROUP) + AuthServicesInfoManager.update_is_blue(True, user) + + else: + # disable accounts with missing corp model (not blue or member) + if check_if_user_has_permission(user, "member"): + disable_alliance_member(user, authserviceinfo.main_char_id) + elif check_if_user_has_permission(user, "blue_member"): + disable_blue_member(user) + else: + deactivate_services(user) else: - deactivate_services(user) + # nuke it, the hard way + disable_expired_member(user) else: - # nuke it - deactivate_services(user) + # disable accounts with invalid keys + disable_expired_member(user) + else: print 'No main_char_id set' # Run Every 2 hours @periodic_task(run_every=crontab(minute=0, hour="*/2")) -def run_alliance_corp_update(): +def run_corp_update(): # I am not proud of this block of code if EveApiManager.check_if_api_server_online(): - # Updated alliance info - alliance_info = EveApiManager.get_alliance_information(settings.ALLIANCE_ID) + if settings.IS_CORP: + # Create the corp + ownercorpinfo = EveApiManager.get_corporation_information(settings.CORP_ID) + if not EveManager.check_if_corporation_exists_by_id(ownercorpinfo['id']): + if ownercorpinfo['alliance']['id'] is None: + EveManager.create_corporation_info(ownercorpinfo['id'], ownercorpinfo['name'], ownercorpinfo['ticker'], + ownercorpinfo['members']['current'], False, None) + else: + alliance_info = EveApiManager.get_alliance_information(ownercorpinfo['alliance']['id']) + if not EveManager.check_if_alliance_exists_by_id(settings.ALLIANCE_ID): + EveManager.create_alliance_info(settings.ALLIANCE_ID, alliance_info['name'], alliance_info['ticker'], + alliance_info['executor_id'], alliance_info['member_count'], False) + alliance = EveManager.get_alliance_info_by_id(ownercorpinfo['alliance']['id']) + EveManager.create_corporation_info(ownercorpinfo['id'], ownercorpinfo['name'], ownercorpinfo['ticker'], + ownercorpinfo['members']['current'], False, alliance) - # Populate alliance info - if not EveManager.check_if_alliance_exists_by_id(settings.ALLIANCE_ID): - EveManager.create_alliance_info(settings.ALLIANCE_ID, alliance_info['name'], alliance_info['ticker'], - alliance_info['executor_id'], alliance_info['member_count'], False) + else: + # Updated alliance info + alliance_info = EveApiManager.get_alliance_information(settings.ALLIANCE_ID) + + # Populate alliance info + if not EveManager.check_if_alliance_exists_by_id(settings.ALLIANCE_ID): + EveManager.create_alliance_info(settings.ALLIANCE_ID, alliance_info['name'], alliance_info['ticker'], + alliance_info['executor_id'], alliance_info['member_count'], False) + alliance = EveManager.get_alliance_info_by_id(settings.ALLIANCE_ID) + # Create the corps in the alliance + for alliance_corp in alliance_info['member_corps']: + corpinfo = EveApiManager.get_corporation_information(alliance_corp) + if not EveManager.check_if_corporation_exists_by_id(corpinfo['id']): + EveManager.create_corporation_info(corpinfo['id'], corpinfo['name'], corpinfo['ticker'], + corpinfo['members']['current'], False, alliance) - alliance = EveManager.get_alliance_info_by_id(settings.ALLIANCE_ID) - - # Create the corps in the alliance - for alliance_corp in alliance_info['member_corps']: - corpinfo = EveApiManager.get_corporation_information(alliance_corp) - if not EveManager.check_if_corporation_exists_by_id(corpinfo['id']): - EveManager.create_corporation_info(corpinfo['id'], corpinfo['name'], corpinfo['ticker'], - corpinfo['members']['current'], False, alliance) + #determine what level of standings to check + #refer to https://github.com/eve-val/evelink/blob/master/evelink/parsing/contact_list.py#L43 + standing_level = 'alliance' + if settings.IS_CORP: + standing_level = 'corp' # Create the corps in the standings - alliance_standings = EveApiManager.get_alliance_standings() - if alliance_standings: - for standing_id in EveApiManager.get_alliance_standings()['alliance']: - if int(alliance_standings['alliance'][standing_id]['standing']) >= settings.ALLIANCE_BLUE_STANDING: + corp_standings = EveApiManager.get_corp_standings() + if corp_standings: + for standing_id in EveApiManager.get_corp_standings()[standing_level]: + if int(corp_standings[standing_level][standing_id]['standing']) >= settings.BLUE_STANDING: if EveApiManager.check_if_id_is_character(standing_id): pass elif EveApiManager.check_if_id_is_corp(standing_id): @@ -273,83 +417,96 @@ def run_alliance_corp_update(): blue_info['ticker'], blue_info['members']['current'], True, blue_alliance) - # Update all allinace info's - for all_alliance_info in EveManager.get_all_alliance_info(): - all_alliance_api_info = EveApiManager.get_alliance_information(all_alliance_info.alliance_id) - if all_alliance_info.alliance_id == settings.ALLIANCE_ID: - EveManager.update_alliance_info(all_alliance_api_info['id'], all_alliance_api_info['executor_id'], - all_alliance_api_info['member_count'], False) - else: - if 'alliance' in alliance_standings: - if int(all_alliance_info.alliance_id) in alliance_standings['alliance']: - if int(alliance_standings['alliance'][int(all_alliance_info.alliance_id)][ - 'standing']) >= settings.ALLIANCE_BLUE_STANDING: - EveManager.update_alliance_info(all_alliance_api_info['id'], - all_alliance_api_info['executor_id'], - all_alliance_api_info['member_count'], True) + # Update all allinace info's + for all_alliance_info in EveManager.get_all_alliance_info(): + if EveApiManager.check_if_alliance_exists(all_alliance_info.alliance_id): + all_alliance_api_info = EveApiManager.get_alliance_information(all_alliance_info.alliance_id) + if (not settings.IS_CORP and all_alliance_info.alliance_id == settings.ALLIANCE_ID): + EveManager.update_alliance_info(all_alliance_api_info['id'], all_alliance_api_info['executor_id'], + all_alliance_api_info['member_count'], False) + elif standing_level in corp_standings: + if int(all_alliance_info.alliance_id) in corp_standings[standing_level]: + if int(corp_standings[standing_level][int(all_alliance_info.alliance_id)][ + 'standing']) >= settings.BLUE_STANDING: + EveManager.update_alliance_info(all_alliance_api_info['id'], + all_alliance_api_info['executor_id'], + all_alliance_api_info['member_count'], True) + else: + EveManager.update_alliance_info(all_alliance_api_info['id'], + all_alliance_api_info['executor_id'], + all_alliance_api_info['member_count'], False) else: EveManager.update_alliance_info(all_alliance_api_info['id'], all_alliance_api_info['executor_id'], all_alliance_api_info['member_count'], False) - else: EveManager.update_alliance_info(all_alliance_api_info['id'], all_alliance_api_info['executor_id'], all_alliance_api_info['member_count'], False) else: - EveManager.update_alliance_info(all_alliance_api_info['id'], - all_alliance_api_info['executor_id'], - all_alliance_api_info['member_count'], False) + #alliance no longer exists + all_alliance_info.delete() - # Update corp infos - for all_corp_info in EveManager.get_all_corporation_info(): - alliance = None - corpinfo = EveApiManager.get_corporation_information(all_corp_info.corporation_id) - if corpinfo['alliance']['id'] is not None: - alliance = EveManager.get_alliance_info_by_id(corpinfo['alliance']['id']) + # Update corp infos + for all_corp_info in EveManager.get_all_corporation_info(): + if EveApiManager.check_if_corp_exists(all_corp_info.corporation_id): + alliance = None + corpinfo = EveApiManager.get_corporation_information(all_corp_info.corporation_id) + if corpinfo['alliance']['id'] is not None: + alliance = EveManager.get_alliance_info_by_id(corpinfo['alliance']['id']) - if alliance is not None and all_corp_info.alliance is not None: + if alliance is not None and all_corp_info.alliance is not None: - if all_corp_info.alliance.alliance_id == settings.ALLIANCE_ID: - EveManager.update_corporation_info(corpinfo['id'], corpinfo['members']['current'], alliance, False) - else: - if int(alliance.alliance_id) in alliance_standings['alliance']: - if int(alliance_standings['alliance'][int(alliance.alliance_id)][ - 'standing']) >= settings.ALLIANCE_BLUE_STANDING: - EveManager.update_corporation_info(corpinfo['id'], corpinfo['members']['current'], alliance, - True) + if (not settings.IS_CORP) and (all_corp_info.alliance.alliance_id == settings.ALLIANCE_ID): + EveManager.update_corporation_info(corpinfo['id'], corpinfo['members']['current'], alliance, False) + elif int(alliance.alliance_id) in corp_standings[standing_level]: + if int(corp_standings[standing_level][int(alliance.alliance_id)][ + 'standing']) >= settings.BLUE_STANDING: + EveManager.update_corporation_info(corpinfo['id'], corpinfo['members']['current'], alliance, + True) + else: + EveManager.update_corporation_info(corpinfo['id'], corpinfo['members']['current'], alliance, + False) else: EveManager.update_corporation_info(corpinfo['id'], corpinfo['members']['current'], alliance, False) else: - EveManager.update_corporation_info(corpinfo['id'], corpinfo['members']['current'], alliance, - False) - else: - if int(all_corp_info.corporation_id) in alliance_standings['alliance']: - if int(alliance_standings['alliance'][int(all_corp_info.corporation_id)][ - 'standing']) >= settings.ALLIANCE_BLUE_STANDING: - EveManager.update_corporation_info(corpinfo['id'], corpinfo['members']['current'], None, True) - else: - EveManager.update_corporation_info(corpinfo['id'], corpinfo['members']['current'], None, False) + if int(all_corp_info.corporation_id) in corp_standings[standing_level]: + if int(corp_standings[standing_level][int(all_corp_info.corporation_id)][ + 'standing']) >= settings.BLUE_STANDING: + EveManager.update_corporation_info(corpinfo['id'], corpinfo['members']['current'], None, True) + else: + EveManager.update_corporation_info(corpinfo['id'], corpinfo['members']['current'], None, False) + else: + EveManager.update_corporation_info(corpinfo['id'], corpinfo['members']['current'], None, False) else: - EveManager.update_corporation_info(corpinfo['id'], corpinfo['members']['current'], None, False) + #corp has closed + all_corp_info.delete() - # Nuke the none believers + # Remove irrelevent corp and alliance models # Check the corps for all_corp_info in EveManager.get_all_corporation_info(): - if all_corp_info.alliance is not None: - if all_corp_info.alliance.alliance_id is not None: + if settings.IS_CORP: + if all_corp_info.corporation_id != settings.CORP_ID: + if not all_corp_info.is_blue: + all_corp_info.delete() + else: + if all_corp_info.alliance is not None: if all_corp_info.alliance.alliance_id != settings.ALLIANCE_ID: if not all_corp_info.is_blue: all_corp_info.delete() - else: - if not all_corp_info.is_blue: + elif not all_corp_info.is_blue: all_corp_info.delete() # Check the alliances for all_alliance_info in EveManager.get_all_alliance_info(): - if all_alliance_info.alliance_id != settings.ALLIANCE_ID: + if settings.IS_CORP: + if all_alliance_info.is_blue is not True: + if ownercorpinfo['alliance']['id'] is not None: + if int(all_alliance_info.alliance_id) != ownercorpinfo['alliance']['id']: + all_alliance_info.delete() + else: + all_alliance_info.delete() + elif all_alliance_info.alliance_id != settings.ALLIANCE_ID: if all_alliance_info.is_blue is not True: all_alliance_info.delete() - - diff --git a/customization/.gitignore b/customization/.gitignore new file mode 100644 index 00000000..2120a1ca --- /dev/null +++ b/customization/.gitignore @@ -0,0 +1,7 @@ +#Ignore everything +* +#Except these +!.gitignore +!README.md +!templates +!static diff --git a/customization/README.md b/customization/README.md new file mode 100644 index 00000000..04749c5c --- /dev/null +++ b/customization/README.md @@ -0,0 +1,7 @@ +If you want to customize your site, place the custom files in the appropriate directories below. + +Place custom pages in the templates directory. + +Place custom images, css, etc in the static directory. + +Be sure to make folders are required to preserve the original file location. diff --git a/customization/static/.gitignore b/customization/static/.gitignore new file mode 100644 index 00000000..e15381a8 --- /dev/null +++ b/customization/static/.gitignore @@ -0,0 +1,5 @@ +# Ignore everything in this directory +* +# Except this file +!.gitignore +!README.md diff --git a/customization/static/README.md b/customization/static/README.md new file mode 100644 index 00000000..3edc5785 --- /dev/null +++ b/customization/static/README.md @@ -0,0 +1,7 @@ +Place your custom static files in this folder. Maintain the folder structure of the original static folder. + +For instance, if you have a custom background image for the index page, it would be located at: + +`customization/static/img/index_images/index_blank_bg.jpg` + +This directory will get searched first for the image, then fall back to the default. diff --git a/customization/templates/.gitignore b/customization/templates/.gitignore new file mode 100644 index 00000000..1d9c3463 --- /dev/null +++ b/customization/templates/.gitignore @@ -0,0 +1,5 @@ +#Ignore everything in this directory +* +# Except this file +!.gitignore +!README.md diff --git a/customization/templates/README.md b/customization/templates/README.md new file mode 100644 index 00000000..57cd34bc --- /dev/null +++ b/customization/templates/README.md @@ -0,0 +1,7 @@ +Place your custom templates in this folder. +Maintain the folder structure of the original templates folder. +For instance, if you have a custom index page, it would be located at: + +`customization/templates/public/index.html` + +This directory will get searched first, then fall back to the defaults. diff --git a/eveonline/forms.py b/eveonline/forms.py index 44b1138e..547862b9 100644 --- a/eveonline/forms.py +++ b/eveonline/forms.py @@ -1,4 +1,5 @@ from django import forms +from django.conf import settings from services.managers.eve_api_manager import EveApiManager from eveonline.managers import EveManager @@ -7,7 +8,7 @@ from eveonline.managers import EveManager 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") - is_blue = forms.BooleanField(label="Blue to alliance", required=False) + is_blue = forms.BooleanField(label="Blue to corp/alliance", required=False) def clean(self): if EveManager.check_if_api_key_pair_exist(self.cleaned_data['api_id']): @@ -19,13 +20,24 @@ class UpdateKeyForm(forms.Form): except: pass - if not check_blue: - if not EveApiManager.check_api_is_type_account(self.cleaned_data['api_id'], + if check_blue: + if settings.BLUE_API_ACCOUNT: + if not EveApiManager.check_api_is_type_account(self.cleaned_data['api_id'], + self.cleaned_data['api_key']): + raise forms.ValidationError(u'API not of type account') + + if not EveApiManager.check_blue_api_is_full(self.cleaned_data['api_id'], + self.cleaned_data['api_key']): + raise forms.ValidationError(u'API supplied is too restricted. Minimum access mask is ' + str(settings.BLUE_API_MASK)) + + else: + if settings.MEMBER_API_ACCOUNT: + if not EveApiManager.check_api_is_type_account(self.cleaned_data['api_id'], self.cleaned_data['api_key']): - raise forms.ValidationError(u'API not of type account') + raise forms.ValidationError(u'API not of type account') if not EveApiManager.check_api_is_full(self.cleaned_data['api_id'], self.cleaned_data['api_key']): - raise forms.ValidationError(u'API supplied is not a full api key') + raise forms.ValidationError(u'API supplied is too restricted. Minimum access mask is ' + str(settings.MEMBER_API_MASK)) - return self.cleaned_data \ No newline at end of file + return self.cleaned_data diff --git a/eveonline/managers.py b/eveonline/managers.py index 270ee7d5..b604b1c5 100644 --- a/eveonline/managers.py +++ b/eveonline/managers.py @@ -205,4 +205,9 @@ class EveManager: @staticmethod def get_all_alliance_info(): - return EveAllianceInfo.objects.all() \ No newline at end of file + return EveAllianceInfo.objects.all() + + @staticmethod + def get_charater_corporation_id_by_id(char_id): + if EveCharacter.objects.filter(character_id=char_id).exists(): + return EveCharacter.objects.get(character_id=char_id).corporation_id diff --git a/eveonline/views.py b/eveonline/views.py index 008c68dc..e6da28a0 100755 --- a/eveonline/views.py +++ b/eveonline/views.py @@ -22,9 +22,9 @@ from eveonline.models import EveApiKeyPair from authentication.models import AuthServicesInfo -def disable_alliance_member(user, char_id): - remove_member_permission(user, 'alliance_member') - remove_user_from_group(user, settings.DEFAULT_ALLIANCE_GROUP) +def disable_member(user, char_id): + remove_member_permission(user, 'member') + remove_user_from_group(user, settings.DEFAULT_AUTH_GROUP) remove_user_from_group(user, generate_corp_group_name( EveManager.get_character_by_id(char_id).corporation_name)) @@ -80,7 +80,7 @@ def api_key_removal(request, api_id): if authinfo.is_blue: disable_blue_member(request.user) else: - disable_alliance_member(request.user, authinfo.main_char_id) + disable_member(request.user, authinfo.main_char_id) EveManager.delete_api_key_pair(api_id, request.user.id) EveManager.delete_characters_by_api_id(api_id, request.user.id) @@ -104,9 +104,9 @@ def main_character_change(request, char_id): character_info = EveManager.get_character_by_id(char_id) corporation_info = EveManager.get_corporation_info_by_id(character_info.corporation_id) - if EveManager.get_charater_alliance_id_by_id(char_id) == settings.ALLIANCE_ID: - add_member_permission(request.user, 'alliance_member') - add_user_to_group(request.user, settings.DEFAULT_ALLIANCE_GROUP) + if (settings.IS_CORP and EveManager.get_charater_corporation_id_by_id(char_id) == settings.CORP_ID) or (not settings.IS_CORP and EveManager.get_charater_alliance_id_by_id(char_id) == settings.ALLIANCE_ID): + add_member_permission(request.user, 'member') + add_user_to_group(request.user, settings.DEFAULT_AUTH_GROUP) add_user_to_group(request.user, generate_corp_group_name(EveManager.get_character_by_id(char_id).corporation_name)) @@ -116,15 +116,15 @@ def main_character_change(request, char_id): add_user_to_group(request.user, settings.DEFAULT_BLUE_GROUP) AuthServicesInfoManager.update_is_blue(True, request.user) else: - if check_if_user_has_permission(request.user, 'alliance_member'): - disable_alliance_member(request.user, previousmainid) + if check_if_user_has_permission(request.user, 'member'): + disable_member(request.user, previousmainid) if check_if_user_has_permission(request.user, 'blue_member'): disable_blue_member(request.user) else: # TODO: disable serivces - if check_if_user_has_permission(request.user, 'alliance_member'): - disable_alliance_member(request.user, previousmainid) + if check_if_user_has_permission(request.user, 'member'): + disable_member(request.user, previousmainid) if check_if_user_has_permission(request.user, 'blue_member'): disable_blue_member(request.user) @@ -138,22 +138,23 @@ def main_character_change(request, char_id): def corp_stats_view(request): # Get the corp the member is in auth_info = AuthServicesInfo.objects.get(user=request.user) - main_char = EveCharacter.objects.get(character_id=auth_info.main_char_id) - corp = EveCorporationInfo.objects.get(corporation_id=main_char.corporation_id) - current_count = 0 - allcharacters = {} - all_characters = EveCharacter.objects.all() - for char in all_characters: - if char: - try: - if char.corporation_id == corp.corporation_id: - current_count = current_count + 1 - allcharacters[char.character_name] = EveApiKeyPair.objects.get(api_id=char.api_id) - except: - pass - - context = {"corp": corp, - "currentCount": current_count, - "characters": allcharacters} - - return render_to_response('registered/corpstats.html', context, context_instance=RequestContext(request)) + if EveCharacter.objects.filter(character_id=auth_info.main_char_id).exists(): + main_char = EveCharacter.objects.get(character_id=auth_info.main_char_id) + if EveCorporationInfo.objects.filter(corporation_id=main_char.corporation_id).exists(): + current_count = 0 + allcharacters = {} + corp = EveCorporationInfo.objects.get(corporation_id=main_char.corporation_id) + all_characters = EveCharacter.objects.all() + for char in all_characters: + if char: + try: + if char.corporation_id == corp.corporation_id: + current_count = current_count + 1 + allcharacters[char.character_name] = EveApiKeyPair.objects.get(api_id=char.api_id) + except: + pass + context = {"corp": corp, + "currentCount": current_count, + "characters": allcharacters} + return render_to_response('registered/corpstats.html', context, context_instance=RequestContext(request)) + return render_to_response('registered/corpstats.html', None, context_instance=RequestContext(request)) diff --git a/groupmanagement/admin.py b/groupmanagement/admin.py index 59a1e5c4..c89f1c75 100644 --- a/groupmanagement/admin.py +++ b/groupmanagement/admin.py @@ -2,7 +2,9 @@ from django.contrib import admin from models import GroupDescription from models import GroupRequest +from models import HiddenGroup admin.site.register(GroupDescription) admin.site.register(GroupRequest) +admin.site.register(HiddenGroup) diff --git a/groupmanagement/models.py b/groupmanagement/models.py index 895728d6..d6ca4ffe 100644 --- a/groupmanagement/models.py +++ b/groupmanagement/models.py @@ -21,4 +21,10 @@ class GroupRequest(models.Model): main_char = models.ForeignKey(EveCharacter) def __str__(self): - return self.user.username + ":" + self.group.name \ No newline at end of file + return self.user.username + ":" + self.group.name + +class HiddenGroup(models.Model): + group = models.ForeignKey(Group, unique=True) + + def __str__(self): + return self.group.name + " - Hidden" diff --git a/groupmanagement/views.py b/groupmanagement/views.py index 473c1493..44042e5f 100755 --- a/groupmanagement/views.py +++ b/groupmanagement/views.py @@ -8,6 +8,7 @@ from django.contrib.auth.models import Group from models import GroupDescription from models import GroupRequest +from models import HiddenGroup from authentication.managers import AuthServicesInfoManager from eveonline.managers import EveManager @@ -96,10 +97,12 @@ def groups_view(request): # Check if group is a corp if "Corp_" in group.name: pass - elif settings.DEFAULT_ALLIANCE_GROUP in group.name: + elif settings.DEFAULT_AUTH_GROUP in group.name: pass elif settings.DEFAULT_BLUE_GROUP in group.name: pass + elif HiddenGroup.objects.filter(group=group).exists(): + pass else: # Get the descriptionn groupDesc = GroupDescription.objects.filter(group=group) @@ -146,4 +149,4 @@ def group_request_leave(request, group_id): grouprequest.leave_request = True grouprequest.save() - return HttpResponseRedirect("/groups") \ No newline at end of file + return HttpResponseRedirect("/groups") diff --git a/hrapplications/forms.py b/hrapplications/forms.py index 8fa9671a..7d1ad0e7 100755 --- a/hrapplications/forms.py +++ b/hrapplications/forms.py @@ -3,13 +3,17 @@ from django.conf import settings from eveonline.models import EveCorporationInfo - class HRApplicationForm(forms.Form): allchoices = [] - for corp in EveCorporationInfo.objects.all(): - if corp.alliance is not None: - if corp.alliance.alliance_id == settings.ALLIANCE_ID: - allchoices.append((str(corp.corporation_id), str(corp.corporation_name))) + + if settings.IS_CORP: + corp = EveCorporationInfo.objects.get(corporation_id=settings.CORP_ID) + allchoices.append((str(corp.corporation_id), str(corp.corporation_name))) + else: + for corp in EveCorporationInfo.objects.all(): + if corp.alliance is not None: + if corp.alliance.alliance_id == settings.ALLIANCE_ID: + allchoices.append((str(corp.corporation_id), str(corp.corporation_name))) character_name = forms.CharField(max_length=254, required=True, label="Main Character Name") full_api_id = forms.CharField(max_length=254, required=True, label="API ID") @@ -26,4 +30,4 @@ class HRApplicationCommentForm(forms.Form): class HRApplicationSearchForm(forms.Form): - search_string = forms.CharField(max_length=254, required=True, label="Search String") \ No newline at end of file + search_string = forms.CharField(max_length=254, required=True, label="Search String") diff --git a/hrapplications/models.py b/hrapplications/models.py index 68fd06b4..3e6bd0ed 100755 --- a/hrapplications/models.py +++ b/hrapplications/models.py @@ -1,8 +1,8 @@ from django.db import models from django.contrib.auth.models import User -from eveonline.models import EveCorporationInfo from eveonline.models import EveCharacter +from eveonline.models import EveCorporationInfo class HRApplication(models.Model): @@ -33,4 +33,4 @@ class HRApplicationComment(models.Model): commenter_character = models.ForeignKey(EveCharacter) def __str__(self): - return str(self.application.character_name) + " - Comment" \ No newline at end of file + return str(self.application.character_name) + " - Comment" diff --git a/hrapplications/views.py b/hrapplications/views.py index 02bfc0bb..7345e7f9 100755 --- a/hrapplications/views.py +++ b/hrapplications/views.py @@ -28,14 +28,20 @@ def hr_application_management_view(request): # Get the corp the member is in auth_info = AuthServicesInfo.objects.get(user=request.user) if auth_info.main_char_id != "": - main_alliance_id = EveManager.get_charater_alliance_id_by_id(auth_info.main_char_id) - if main_alliance_id == settings.ALLIANCE_ID: - main_char = EveCharacter.objects.get(character_id=auth_info.main_char_id) - corp = EveCorporationInfo.objects.get(corporation_id=main_char.corporation_id) - corp_applications = HRApplication.objects.filter(corp=corp).filter(approved_denied=None) - else: + try: + main_corp_id = EveManager.get_charater_corporation_id_by_id(auth_info.main_char_id) + main_alliance_id = EveManager.get_charater_alliance_id_by_id(auth_info.main_char_id) + if (settings.IS_CORP and main_corp_id == settings.CORP_ID) or (not settings.IS_CORP and main_alliance_id == settings.ALLIANCE_ID): + main_char = EveCharacter.objects.get(character_id=auth_info.main_char_id) + if EveCorporationInfo.objects.filter(corporation_id=main_char.corporation_id).exists(): + corp = EveCorporationInfo.objects.get(corporation_id=main_char.corporation_id) + corp_applications = HRApplication.objects.filter(corp=corp).filter(approved_denied=None) + else: + corp_applications = None + else: + corp_applications = None + except: corp_applications = None - context = {'personal_apps': HRApplication.objects.all().filter(user=request.user), 'applications': corp_applications, 'search_form': HRApplicationSearchForm()} diff --git a/registration/forms.py b/registration/forms.py index 11d66f51..da570c7c 100644 --- a/registration/forms.py +++ b/registration/forms.py @@ -1,9 +1,10 @@ from django import forms from django.contrib.auth.models import User +import re class RegistrationForm(forms.Form): - username = forms.CharField(max_length=32, required=True) + username = forms.CharField(max_length=30, required=True) password = forms.CharField(widget=forms.PasswordInput(), required=True) password_again = forms.CharField(widget=forms.PasswordInput(), required=True, label="Password Again") email = forms.CharField(max_length=254, required=True) @@ -11,7 +12,7 @@ class RegistrationForm(forms.Form): def clean(self): if ' ' in self.cleaned_data['username']: - raise forms.ValidationError(u'Username can not contain a space') + raise forms.ValidationError(u'Username cannot contain a space') # We attempt to get the user object if we succeed we know email as been used try: @@ -20,6 +21,9 @@ class RegistrationForm(forms.Form): except: pass + if not re.match("^\w+$", self.cleaned_data['username']): + raise forms.ValidationError(u'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(u'Passwords do not match') @@ -28,4 +32,4 @@ class RegistrationForm(forms.Form): if self.cleaned_data['email'] != self.cleaned_data['email_again']: raise forms.ValidationError(u'Emails do not match') - return self.cleaned_data \ No newline at end of file + return self.cleaned_data diff --git a/requirements.txt b/requirements.txt index 72b6116a..f3a24ba3 100755 --- a/requirements.txt +++ b/requirements.txt @@ -1,15 +1,17 @@ # Python Stuff # - see bootstrap.sh mysql-python +mysqlclient evelink dnspython passlib xmpppy==0.5.0rc1 -python-openfire==0.2.3-beta +requests # Django Stuff # -django==1.6.1 +django==1.6.5 django-evolution django-bootstrap-form django-celery -git+git://github.com/nikdoof/python-ts3.git \ No newline at end of file +git+git://github.com/nikdoof/python-ts3.git +git+git://github.com/seamus-45/openfire-restapi.git diff --git a/run_alliance_corp_update.py b/run_alliance_corp_update.py index c41709f2..05b31ecc 100644 --- a/run_alliance_corp_update.py +++ b/run_alliance_corp_update.py @@ -1,6 +1,6 @@ from util import bootstrap_permissions -from celerytask.tasks import run_alliance_corp_update +from celerytask.tasks import run_corp_update bootstrap_permissions() -run_alliance_corp_update() +run_corp_update() quit() diff --git a/services/admin.py b/services/admin.py index 846f6b40..2026832a 100644 --- a/services/admin.py +++ b/services/admin.py @@ -1 +1,18 @@ -# Register your models here. +from django.contrib import admin +from .models import AuthTS +from .models import TSgroup +from .models import UserTSgroup + +class AuthTSgroupAdmin(admin.ModelAdmin): + fields = ['auth_group','ts_group'] + filter_horizontal = ('ts_group',) + +class TSgroupAdmin(admin.ModelAdmin): + fields = ['ts_group_name'] + +class UserTSgroupAdmin(admin.ModelAdmin): + fields = ['user','ts_group'] + filter_horizontal = ('ts_group',) + +admin.site.register(AuthTS, AuthTSgroupAdmin) +admin.site.register(TSgroup, TSgroupAdmin) \ No newline at end of file diff --git a/services/forms.py b/services/forms.py index cd322c0c..0696c939 100644 --- a/services/forms.py +++ b/services/forms.py @@ -24,3 +24,7 @@ class FleetFormatterForm(forms.Form): reimbursable = forms.ChoiceField(label='Reimbursable?*', choices=[('Yes', 'Yes'), ('No', 'No')], required=True) important = forms.ChoiceField(label='Important?*', choices=[('Yes', 'Yes'), ('No', 'No')], required=True) comments = forms.CharField(widget=forms.Textarea, required=False) + +class DiscordForm(forms.Form): + email = forms.CharField(label="Email Address", required=True) + password = forms.CharField(label="Password", required=True, widget=forms.PasswordInput) diff --git a/services/managers/discord_manager.py b/services/managers/discord_manager.py new file mode 100644 index 00000000..9ab4ff97 --- /dev/null +++ b/services/managers/discord_manager.py @@ -0,0 +1,355 @@ +import requests +import json +from django.conf import settings +import re +import os + +DISCORD_URL = "https://discordapp.com/api" + +class DiscordAPIManager: + + def __init__(self, server_id, email, password): + data = { + "email" : email, + "password": password, + } + custom_headers = {'content-type':'application/json'} + path = DISCORD_URL + "/auth/login" + r = requests.post(path, headers=custom_headers, data=json.dumps(data)) + r.raise_for_status() + self.token = r.json()['token'] + self.email = email + self.password = password + self.server_id = server_id + + def __del__(self): + if hasattr(self, 'token'): + if self.token and self.token != "": + data = {'token': self.token} + path = DISCORD_URL + "/auth/logout" + custom_headers = {'content-type':'application/json'} + r = requests.post(path, headers=custom_headers, data=json.dumps(data)) + r.raise_for_status() + + @staticmethod + def get_auth_token(): + data = { + "email" : settings.DISCORD_USER_EMAIL, + "password": settings.DISCORD_USER_PASSWORD, + } + custom_headers = {'content-type':'application/json'} + path = DISCORD_URL + "/auth/login" + r = requests.post(path, headers=custom_headers, data=json.dumps(data)) + r.raise_for_status() + return r.json()['token'] + + def add_server(self, name): + data = {"name": name} + custom_headers = {'content-type':'application/json', 'authorization': self.token} + path = DISCORD_URL + "/guilds" + r = requests.post(path, headers=custom_headers, data=json.dumps(data)) + r.raise_for_status() + return r.json() + + def rename_server(self, name): + data = {"name": name} + custom_headers = {'content-type':'application/json', 'authorization': self.token} + path = DISCORD_URL + "/guilds/" + str(self.server_id) + r = requests.patch(path, headers=custom_headers, data=json.dumps(data)) + r.raise_for_status() + return r.json() + + def delete_server(self): + custom_headers = {'content-type':'application/json', 'authorization': self.token} + path = DISCORD_URL + "/guilds/" + str(self.server_id) + r = requests.delete(path, headers=custom_headers) + r.raise_for_status() + + def get_members(self): + custom_headers = {'accept':'application/json', 'authorization': self.token} + path = DISCORD_URL + "/guilds/" + str(self.server_id) + "/members" + r = requests.get(path, headers=custom_headers) + r.raise_for_status() + return r.json() + + def get_bans(self): + custom_headers = {'accept':'application/json', 'authorization': self.token} + path = DISCORD_URL + "/guilds/" + str(self.server_id) + "/bans" + r = requests.get(path, headers=custom_headers) + r.raise_for_status() + return r.json() + + def ban_user(self, user_id, delete_message_age=0): + custom_headers = {'authorization': self.token} + path = DISCORD_URL + "/guilds/" + str(self.server_id) + "/bans/" + str(user_id) + "?delete-message-days=" + str(delete_message_age) + r = requests.put(path, headers=custom_headers) + r.raise_for_status() + + def unban_user(self, user_id): + custom_headers = {'authorization': self.token} + path = DISCORD_URL + "/guilds/" + str(self.server_id) + "/bans/" + str(user_id) + r = requests.delete(path, headers=custom_headers) + r.raise_for_status() + + def generate_role(self): + custom_headers = {'accept':'application/json', 'authorization': self.token} + path = DISCORD_URL + "/guilds/" + str(self.server_id) + "/roles" + r = requests.post(path, headers=custom_headers) + r.raise_for_status() + return r.json() + + def edit_role(self, role_id, name, color=0, hoist=True, permissions=36785152): + custom_headers = {'content-type':'application/json', 'authorization': self.token} + data = { + 'color': color, + 'hoist': hoist, + 'name': name, + 'permissions': permissions, + } + path = DISCORD_URL + "/guilds/" + str(self.server_id) + "/roles/" + str(role_id) + r = requests.patch(path, headers=custom_headers, data=json.dumps(data)) + r.raise_for_status() + return r.json() + + def delete_role(self, role_id): + custom_headers = {'authorization': self.token} + path = DISCORD_URL + "/guilds/" + str(self.server_id) + "/roles/" + str(role_id) + r = requests.delete(path, headers=custom_headers) + r.raise_for_status() + + @staticmethod + def get_invite(invite_id): + custom_headers = {'accept': 'application/json'} + path = DISCORD_URL + "/invite/" + str(invite_id) + r = requests.get(path, headers=custom_headers) + r.raise_for_status() + return r.json() + + @staticmethod + def accept_invite(invite_id, token): + custom_headers = {'accept': 'application/json', 'authorization': token} + path = DISCORD_URL + "/invite/" + str(invite_id) + r = requests.post(path, headers=custom_headers) + r.raise_for_status() + return r.json() + + def create_invite(self, max_age=600, max_uses=1, temporary=True, xkcdpass=False): + custom_headers = {'authorization': self.token} + path = DISCORD_URL + "/channels/" + str(self.server_id) + "/invites" + data = { + 'max_age': max_age, + 'max_uses': max_uses, + 'temporary': temporary, + 'xkcdpass': xkcdpass, + } + r = requests.post(path, headers=custom_headers, data=json.dumps(data)) + r.raise_for_status() + return r.json() + + def delete_invite(self, invite_id): + custom_headers = {'authorization': self.token} + path = DISCORD_URL + "/invite/" + str(invite_id) + r = requests.delete(path, headers=custom_headers) + r.raise_for_status() + + def set_roles(self, user_id, role_ids): + custom_headers = {'authorization': self.token, 'content-type':'application/json'} + path = DISCORD_URL + "/guilds/" + str(self.server_id) + "/members/" + str(user_id) + data = { 'roles': role_ids } + r = requests.patch(path, headers=custom_headers, data=json.dumps(data)) + r.raise_for_status() + + @staticmethod + def register_user(server_id, username, invite_code, password, email): + custom_headers = {'content-type': 'application/json'} + data = { + 'fingerprint': None, + 'username': username, + 'invite': invite_code, + 'password': password, + 'email': email, + } + path = DISCORD_URL + "/auth/register" + r = requests.post(path, headers=custom_headers, data=json.dumps(data)) + r.raise_for_status() + + def kick_user(self, user_id): + custom_headers = {'authorization': self.token} + path = DISCORD_URL + "/guilds/" + str(self.server_id) + "/members/" + str(user_id) + r = requests.delete(path, headers=custom_headers) + r.raise_for_status() + + def get_members(self): + custom_headers = {'authorization': self.token, 'accept':'application/json'} + path = DISCORD_URL + "/guilds/" + str(self.server_id) + "/members" + r = requests.get(path, headers=custom_headers) + r.raise_for_status() + return r.json() + + def get_user_id(self, username): + all_members = self.get_members() + for member in all_members: + if member['user']['username'] == username: + return member['user']['id'] + raise KeyError('User not found on server: ' + username) + + def get_roles(self): + custom_headers = {'authorization': self.token, 'accept':'application/json'} + path = DISCORD_URL + "/guilds/" + str(self.server_id) + "/roles" + r = requests.get(path, headers=custom_headers) + r.raise_for_status() + return r.json() + + def get_group_id(self, group_name): + all_roles = self.get_roles() + for role in all_roles: + if role['name'] == group_name: + return role['id'] + raise KeyError('Group not found on server: ' + group_name) + + @staticmethod + def get_token_by_user(email, password): + data = { + "email" : email, + "password": password, + } + custom_headers = {'content-type':'application/json'} + path = DISCORD_URL + "/auth/login" + r = requests.post(path, headers=custom_headers, data=json.dumps(data)) + r.raise_for_status() + return r.json()['token'] + + @staticmethod + def get_user_profile(email, password): + token = DiscordAPIManager.get_token_by_user(email, password) + custom_headers = {'accept': 'application/json', 'authorization': token} + path = DISCORD_URL + "/users/@me" + r = requests.get(path, headers=custom_headers) + r.raise_for_status() + return r.json() + + @staticmethod + def set_user_password(email, current_password, new_password): + profile = DiscordAPIManager.get_user_profile(email, current_password) + avatar = profile['avatar'] + username = profile['username'] + data = { + 'avatar': avatar, + 'username': username, + 'password': current_password, + 'new_password': new_password, + 'email': email, + } + path = DISCORD_URL + "/users/@me" + custom_headers = {'content-type':'application/json', 'authorization': DiscordAPIManager.get_token_by_user(email, current_password)} + r = requests.patch(path, headers=custom_headers, data=json.dumps(data)) + r.raise_for_status() + return r.json() + + @staticmethod + def destroy_user(email, current_password): + data = { + 'avatar': None, + 'username': os.urandom(8).encode('hex'), + 'password': current_password, + 'email': os.urandom(8).encode('hex') + '@test.com', + } + path = DISCORD_URL + "/users/@me" + custom_headers = {'content-type':'application/json', 'authorization': DiscordAPIManager.get_token_by_user(email, current_password)} + r = requests.patch(path, headers=custom_headers, data=json.dumps(data)) + r.raise_for_status + return r.json() + + def check_if_user_banned(self, user_id): + bans = self.get_bans() + for b in bans: + if b['user']['id'] == str(user_id): + return True + return False + +class DiscordManager: + def __init__(self): + pass + + @staticmethod + def __sanatize_username(username): + clean = re.sub(r'[^\w]','_', username) + return clean + + @staticmethod + def __generate_random_pass(): + return os.urandom(8).encode('hex') + + @staticmethod + def update_groups(user_id, groups): + group_ids = [] + api = DiscordAPIManager(settings.DISCORD_SERVER_ID, settings.DISCORD_USER_EMAIL, settings.DISCORD_USER_PASSWORD) + if len(groups) == 0: + group_ids = [] + else: + for g in groups: + try: + group_id = api.get_group_id(g) + group_ids.append(group_id) + except: + group_ids.append(DiscordManager.create_group(g)) + api.set_roles(user_id, group_ids) + + @staticmethod + def create_group(groupname): + api = DiscordAPIManager(settings.DISCORD_SERVER_ID, settings.DISCORD_USER_EMAIL, settings.DISCORD_USER_PASSWORD) + new_group = api.generate_role() + named_group = api.edit_role(new_group['id'], groupname) + return named_group['id'] + + @staticmethod + def lock_user(user_id): + try: + api = DiscordAPIManager(settings.DISCORD_SERVER_ID, settings.DISCORD_USER_EMAIL, settings.DISCORD_USER_PASSWORD) + api.ban_user(user_id) + return True + except: + return False + + @staticmethod + def unlock_user(user_id): + try: + api = DiscordAPIManager(settings.DISCORD_SERVER_ID, settings.DISCORD_USER_EMAIL, settings.DISCORD_USER_PASSWORD) + api.unban_user(user_id) + return True + except: + return False + + @staticmethod + def update_user_password(email, current_password): + new_password = DiscordManager.__generate_random_pass() + try: + profile = DiscordAPIManager.set_user_password(email, current_password, new_password) + return new_password + except: + return current_password + + @staticmethod + def add_user(email, password): + try: + api = DiscordAPIManager(settings.DISCORD_SERVER_ID, settings.DISCORD_USER_EMAIL, settings.DISCORD_USER_PASSWORD) + profile = DiscordAPIManager.get_user_profile(email, password) + user_id = profile['id'] + if api.check_if_user_banned(user_id): + api.unban_user(user_id) + invite_code = api.create_invite()['code'] + token = DiscordAPIManager.get_token_by_user(email, password) + DiscordAPIManager.accept_invite(invite_code, token) + return user_id + except: + return "" + + @staticmethod + def delete_user(user_id): + try: + api = DiscordAPIManager(settings.DISCORD_SERVER_ID, settings.DISCORD_USER_EMAIL, settings.DISCORD_USER_PASSWORD) + DiscordManager.update_groups(user_id, []) + api.ban_user(user_id) + return True + except: + return False diff --git a/services/managers/eve_api_manager.py b/services/managers/eve_api_manager.py index 5a77aaec..498feea1 100644 --- a/services/managers/eve_api_manager.py +++ b/services/managers/eve_api_manager.py @@ -81,13 +81,24 @@ class EveApiManager(): api = evelink.api.API(api_key=(api_id, api_key)) account = evelink.account.Account(api=api) info = account.key_info() - return info[0]['access_mask'] == 268435455 + return info[0]['access_mask'] & settings.MEMBER_API_MASK == int(settings.MEMBER_API_MASK) except evelink.api.APIError as error: print error return False + @staticmethod + def check_blue_api_is_full(api_id, api_key): + try: + api = evelink.api.API(api_key=(api_id, api_key)) + account = evelink.account.Account(api=api) + info = account.key_info() + return info[0]['access_mask'] & settings.BLUE_API_MASK == int(settings.BLUE_API_MASK) + + except evelink.api.APIError as error: + print error + @staticmethod def get_api_info(api_id, api_key): @@ -140,10 +151,10 @@ class EveApiManager(): return False @staticmethod - def get_alliance_standings(): - if settings.ALLIANCE_EXEC_CORP_ID != "": + def get_corp_standings(): + if settings.CORP_API_ID != "": try: - api = evelink.api.API(api_key=(settings.ALLIANCE_EXEC_CORP_ID, settings.ALLIANCE_EXEC_CORP_VCODE)) + 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[0] @@ -178,4 +189,39 @@ class EveApiManager(): except evelink.api.APIError as error: return False - return False \ No newline at end of file + return False + + @staticmethod + def check_if_alliance_exists(alliance_id): + try: + api = evelink.api.API() + eve = evelink.eve.EVE(api=api) + alliances = eve.alliances() + if int(alliance_id) in alliances[0]: + return True + else: + return False + except evelink.api.APIError as error: + print error + return False + except ValueError as error: + #attempts to catch error resulting from checking alliance_of nonetype models + print error + return False + return False + + @staticmethod + def check_if_corp_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: + return True + else: + return False + except evelink.api.APIError as error: + #could be smart and check for error code523 to verify error due to no corp instead of catch-all + print error + return False + return False diff --git a/services/managers/openfire_manager.py b/services/managers/openfire_manager.py index 929394b6..aea8bdf2 100755 --- a/services/managers/openfire_manager.py +++ b/services/managers/openfire_manager.py @@ -5,12 +5,9 @@ import xmpp from django.contrib.auth.models import User from django.contrib.auth.models import Group from django.conf import settings -from openfire import exception -from openfire import UserService - -from authentication.managers import AuthServicesInfoManager - import threading +from ofrestapi.users import Users as ofUsers +from ofrestapi import exception class OpenfireManager: @@ -44,7 +41,7 @@ class OpenfireManager: try: sanatized_username = OpenfireManager.__santatize_username(username) password = OpenfireManager.__generate_random_pass() - api = UserService(settings.OPENFIRE_ADDRESS, settings.OPENFIRE_SECRET_KEY) + api = ofUsers(settings.OPENFIRE_ADDRESS, settings.OPENFIRE_SECRET_KEY) api.add_user(sanatized_username, password) except exception.UserAlreadyExistsException: @@ -56,7 +53,7 @@ class OpenfireManager: @staticmethod def delete_user(username): try: - api = UserService(settings.OPENFIRE_ADDRESS, settings.OPENFIRE_SECRET_KEY) + api = ofUsers(settings.OPENFIRE_ADDRESS, settings.OPENFIRE_SECRET_KEY) api.delete_user(username) return True except exception.UserNotFoundException: @@ -64,37 +61,49 @@ class OpenfireManager: @staticmethod def lock_user(username): - api = UserService(settings.OPENFIRE_ADDRESS, settings.OPENFIRE_SECRET_KEY) + api = ofUsers(settings.OPENFIRE_ADDRESS, settings.OPENFIRE_SECRET_KEY) api.lock_user(username) @staticmethod def unlock_user(username): - api = UserService(settings.OPENFIRE_ADDRESS, settings.OPENFIRE_SECRET_KEY) + api = ofUsers(settings.OPENFIRE_ADDRESS, settings.OPENFIRE_SECRET_KEY) api.unlock_user(username) @staticmethod def update_user_pass(username): try: password = OpenfireManager.__generate_random_pass() - api = UserService(settings.OPENFIRE_ADDRESS, settings.OPENFIRE_SECRET_KEY) - api.update_user(username, password) + api = ofUsers(settings.OPENFIRE_ADDRESS, settings.OPENFIRE_SECRET_KEY) + api.update_user(username, password=password) return password except exception.UserNotFoundException: return "" @staticmethod def update_user_groups(username, password, groups): - try: - api = UserService(settings.OPENFIRE_ADDRESS, settings.OPENFIRE_SECRET_KEY) - api.update_user(username, password, "", "", groups) - except exception.HTTPException as e: - print e - + api = ofUsers(settings.OPENFIRE_ADDRESS, settings.OPENFIRE_SECRET_KEY) + response = api.get_user_groups(username) + remote_groups = [] + if response: + remote_groups = response['groupname'] + add_groups = [] + del_groups = [] + for g in groups: + if not g in remote_groups: + add_groups.append(g) + for g in remote_groups: + if not g in groups: + del_groups.append(g) + if add_groups: + api.add_user_groups(username, add_groups) + if del_groups: + api.delete_user_groups(username, del_groups) + @staticmethod def delete_user_groups(username, groups): - api = UserService(settings.OPENFIRE_ADDRESS, settings.OPENFIRE_SECRET_KEY) - api.delete_group(username, groups) + api = ofUsers(settings.OPENFIRE_ADDRESS, settings.OPENFIRE_SECRET_KEY) + api.delete_user_groups(username, groups) @staticmethod def send_broadcast_message(group_name, broadcast_message): @@ -103,27 +112,11 @@ class OpenfireManager: client.connect(server=(settings.JABBER_SERVER, settings.JABBER_PORT)) client.auth(settings.BROADCAST_USER, settings.BROADCAST_USER_PASSWORD, 'broadcast') - if group_name != 'all': - group = Group.objects.get(name=group_name) - for user in group.user_set.all(): - auth_info = AuthServicesInfoManager.get_auth_service_info(user) - if auth_info: - if auth_info.jabber_username != "": - to_address = auth_info.jabber_username + '@' + settings.JABBER_URL - message = xmpp.Message(to_address, broadcast_message) - message.setAttr('type', 'chat') - client.send(message) - client.Process(1) - else: - for user in User.objects.all(): - auth_info = AuthServicesInfoManager.get_auth_service_info(user) - if auth_info: - if auth_info.jabber_username != "": - to_address = auth_info.jabber_username + '@' + settings.JABBER_URL - message = xmpp.Message(to_address, broadcast_message) - message.setAttr('type', 'chat') - client.send(message) - client.Process(1) + to_address = group_name + '@' + settings.BROADCAST_SERVICE_NAME + '.' + settings.JABBER_URL + message = xmpp.Message(to_address, broadcast_message) + message.setAttr('type', 'chat') + client.send(message) + client.Process(1) client.disconnect() @@ -138,4 +131,4 @@ class XmppThread (threading.Thread): def run(self): print "Starting " + self.name OpenfireManager.send_broadcast_message(self.group, self.message) - print "Exiting " + self.name \ No newline at end of file + print "Exiting " + self.name diff --git a/services/managers/phpbb3_manager.py b/services/managers/phpbb3_manager.py index ce9dc62f..26ffea4d 100755 --- a/services/managers/phpbb3_manager.py +++ b/services/managers/phpbb3_manager.py @@ -32,9 +32,18 @@ class Phpbb3Manager: SQL_GET_USER_GROUPS = r"SELECT phpbb_groups.group_name FROM phpbb_groups , phpbb_user_group WHERE " \ r"phpbb_user_group.group_id = phpbb_groups.group_id AND user_id=%s" + SQL_ADD_USER_AVATAR = r"UPDATE phpbb_users SET user_avatar_type=2, user_avatar_width=64, user_avatar_height=64, user_avatar=%s WHERE user_id = %s" + def __init__(self): pass + @staticmethod + def __add_avatar(username, characterid): + avatar_url = "http://image.eveonline.com/Character/" + characterid + "_64.jpg" + cursor = connections['phpbb3'].cursor() + userid = Phpbb3Manager.__get_user_id(username) + cursor.execute(Phpbb3Manager.SQL_ADD_USER_AVATAR, [avatar_url, userid]) + @staticmethod def __generate_random_pass(): return os.urandom(8).encode('hex') @@ -113,7 +122,7 @@ class Phpbb3Manager: pass @staticmethod - def add_user(username, email, groups): + def add_user(username, email, groups, characterid): cursor = connections['phpbb3'].cursor() username_clean = Phpbb3Manager.__santatize_username(username) @@ -130,6 +139,7 @@ class Phpbb3Manager: email, 2, Phpbb3Manager.__get_current_utc_date(), "", ""]) Phpbb3Manager.update_groups(username_clean, groups) + Phpbb3Manager.__add_avatar(username_clean, characterid) except: pass @@ -203,12 +213,13 @@ class Phpbb3Manager: return False @staticmethod - def update_user_password(username): + def update_user_password(username, characterid): cursor = connections['phpbb3'].cursor() password = Phpbb3Manager.__generate_random_pass() if Phpbb3Manager.check_user(username): pwhash = Phpbb3Manager.__gen_hash(password) cursor.execute(Phpbb3Manager.SQL_UPDATE_USER_PASSWORD, [pwhash, username]) + Phpbb3Manager.__add_avatar(username, characterid) return password return "" @@ -219,4 +230,4 @@ class Phpbb3Manager: try: cursor.execute(Phpbb3Manager.SQL_DIS_USER, [email, password, username]) except: - pass \ No newline at end of file + pass diff --git a/services/managers/teamspeak3_manager.py b/services/managers/teamspeak3_manager.py index a8c2c65d..291b58a1 100755 --- a/services/managers/teamspeak3_manager.py +++ b/services/managers/teamspeak3_manager.py @@ -1,6 +1,7 @@ from django.conf import settings from services.managers.util.ts3 import TS3Server +from services.models import TSgroup class Teamspeak3Manager: @@ -93,30 +94,43 @@ class Teamspeak3Manager: return outlist @staticmethod - def _add_user_to_group(uid, groupname): - groupname = groupname[:30] + def _add_user_to_group(uid, groupid): server = Teamspeak3Manager.__get_created_server() server_groups = Teamspeak3Manager._group_list() user_groups = Teamspeak3Manager._user_group_list(uid) - - if not groupname in server_groups: - Teamspeak3Manager._create_group(groupname) - if not groupname in user_groups: + + if not groupid in user_groups.values(): server.send_command('servergroupaddclient', - {'sgid': Teamspeak3Manager._group_id_by_name(groupname), 'cldbid': uid}) + {'sgid': str(groupid), 'cldbid': uid}) @staticmethod - def _remove_user_from_group(uid, groupname): - groupname = groupname[:30] + def _remove_user_from_group(uid, groupid): server = Teamspeak3Manager.__get_created_server() server_groups = Teamspeak3Manager._group_list() user_groups = Teamspeak3Manager._user_group_list(uid) - if groupname in server_groups: - Teamspeak3Manager._create_group(groupname) - if groupname in user_groups: + if str(groupid) in user_groups.values(): server.send_command('servergroupdelclient', - {'sgid': Teamspeak3Manager._group_id_by_name(groupname), 'cldbid': uid}) + {'sgid': str(groupid), 'cldbid': uid}) + + @staticmethod + def _sync_ts_group_db(): + try: + remote_groups = Teamspeak3Manager._group_list() + local_groups = TSgroup.objects.all() + for key in remote_groups: + remote_groups[key] = int(remote_groups[key]) + + for group in local_groups: + if group.ts_group_id not in remote_groups.values(): + TSgroup.objects.filter(ts_group_id=group.ts_group_id).delete() + for key in remote_groups: + g = TSgroup(ts_group_id=remote_groups[key],ts_group_name=key) + q = TSgroup.objects.filter(ts_group_id=g.ts_group_id) + if not q: + g.save() + except: + pass @staticmethod def add_user(username, corp_ticker): @@ -127,10 +141,10 @@ class Teamspeak3Manager: server_groups = Teamspeak3Manager._group_list() - if not settings.DEFAULT_ALLIANCE_GROUP in server_groups: - Teamspeak3Manager._create_group(settings.DEFAULT_ALLIANCE_GROUP) + if not settings.DEFAULT_AUTH_GROUP in server_groups: + Teamspeak3Manager._create_group(settings.DEFAULT_AUTH_GROUP) - alliance_group_id = Teamspeak3Manager._group_id_by_name(settings.DEFAULT_ALLIANCE_GROUP) + alliance_group_id = Teamspeak3Manager._group_id_by_name(settings.DEFAULT_AUTH_GROUP) ret = server.send_command('tokenadd', {'tokentype': 0, 'tokenid1': alliance_group_id, 'tokenid2': 0, 'tokendescription': username_clean, @@ -206,28 +220,26 @@ class Teamspeak3Manager: return Teamspeak3Manager.add_blue_user(username, corpticker) @staticmethod - def update_groups(uid, l_groups): - print uid - print l_groups + def update_groups(uid, ts_groups): userid = Teamspeak3Manager._get_userid(uid) + addgroups = [] + remgroups = [] if userid is not None: - server_groups = Teamspeak3Manager._group_list() - user_groups = set(Teamspeak3Manager._user_group_list(userid)) - groups = [] - for l_group in l_groups: - groups.append(l_group[:30]) - - act_groups = set([g.replace(' ', '-') for g in groups]) - addgroups = act_groups - user_groups - remgroups = user_groups - act_groups + user_ts_groups = Teamspeak3Manager._user_group_list(userid) + for key in user_ts_groups: + user_ts_groups[key] = int(user_ts_groups[key]) + for ts_group_key in ts_groups: + if ts_groups[ts_group_key] not in user_ts_groups.values(): + addgroups.append(ts_groups[ts_group_key]) + for user_ts_group_key in user_ts_groups: + if user_ts_groups[user_ts_group_key] not in ts_groups.values(): + remgroups.append(user_ts_groups[user_ts_group_key]) print userid print addgroups print remgroups for g in addgroups: - if not g in server_groups.keys(): - Teamspeak3Manager._create_group(g) Teamspeak3Manager._add_user_to_group(userid, g) for g in remgroups: diff --git a/services/managers/util/ts3.py b/services/managers/util/ts3.py index f13a04ba..1122737b 100755 --- a/services/managers/util/ts3.py +++ b/services/managers/util/ts3.py @@ -139,11 +139,12 @@ class TS3Proto(): v = [v[0], '='.join(v[1:])] key, value = v keys[key] = self._unescape_str(value) - elif v[0][0] and v[0][0] == '-': - # Option - opts.append(v[0][1:]) - else: - command = v[0] + elif (not v == ['']): + if v[0][0] and v[0][0] == '-': + # Option + opts.append(v[0][1:]) + else: + command = v[0] d = {'keys': keys, 'opts': opts} if command: @@ -241,4 +242,4 @@ class TS3Server(TS3Proto): @type id: int """ if self._connected and id > 0: - self.send_command('use', keys={'sid': id}) \ No newline at end of file + self.send_command('use', keys={'sid': id}) diff --git a/services/models.py b/services/models.py index 6b202199..87a5ad57 100644 --- a/services/models.py +++ b/services/models.py @@ -1 +1,32 @@ -# Create your models here. +from django.db import models +from django.contrib.auth.models import Group + +class TSgroup(models.Model): + ts_group_id = models.IntegerField(primary_key=True) + ts_group_name = models.CharField(max_length=30) + + class Meta: + verbose_name='TS Group' + + def __str__(self): + return self.ts_group_name + +class AuthTS(models.Model): + auth_group = models.ForeignKey('auth.Group') + ts_group = models.ManyToManyField(TSgroup) + + class Meta: + verbose_name='Auth / TS Group' + + def __str__(self): + return self.auth_group.name + +class UserTSgroup(models.Model): + user = models.ForeignKey('auth.User') + ts_group = models.ManyToManyField(TSgroup) + + class Meta: + verbose_name='User TS Group' + + def __str__(self): + return self.user.name \ No newline at end of file diff --git a/services/views.py b/services/views.py index a48fca9a..dacefebd 100755 --- a/services/views.py +++ b/services/views.py @@ -12,6 +12,7 @@ from managers.phpbb3_manager import Phpbb3Manager from managers.mumble_manager import MumbleManager from managers.ipboard_manager import IPBoardManager from managers.teamspeak3_manager import Teamspeak3Manager +from managers.discord_manager import DiscordManager from authentication.managers import AuthServicesInfoManager from eveonline.managers import EveManager from celerytask.tasks import remove_all_syncgroups_for_service @@ -20,8 +21,10 @@ from celerytask.tasks import update_mumble_groups from celerytask.tasks import update_forum_groups from celerytask.tasks import update_ipboard_groups from celerytask.tasks import update_teamspeak3_groups +from celerytask.tasks import update_discord_groups from forms import JabberBroadcastForm from forms import FleetFormatterForm +from forms import DiscordForm from util import check_if_user_has_permission import threading @@ -91,7 +94,7 @@ def services_view(request): def service_blue_alliance_test(user): - return check_if_user_has_permission(user, 'alliance_member') or check_if_user_has_permission(user, 'blue_member') + return check_if_user_has_permission(user, 'member') or check_if_user_has_permission(user, 'blue_member') @login_required @@ -100,7 +103,7 @@ def activate_forum(request): authinfo = AuthServicesInfoManager.get_auth_service_info(request.user) # Valid now we get the main characters character = EveManager.get_character_by_id(authinfo.main_char_id) - result = Phpbb3Manager.add_user(character.character_name, request.user.email, ['REGISTERED']) + result = Phpbb3Manager.add_user(character.character_name, request.user.email, ['REGISTERED'], authinfo.main_char_id) # if empty we failed if result[0] != "": AuthServicesInfoManager.update_user_forum_info(result[0], result[1], request.user) @@ -126,7 +129,7 @@ def deactivate_forum(request): @user_passes_test(service_blue_alliance_test) def reset_forum_password(request): authinfo = AuthServicesInfoManager.get_auth_service_info(request.user) - result = Phpbb3Manager.update_user_password(authinfo.forum_username) + result = Phpbb3Manager.update_user_password(authinfo.forum_username, authinfo.main_char_id) # false we failed if result != "": AuthServicesInfoManager.update_user_forum_info(authinfo.forum_username, result, request.user) @@ -317,3 +320,48 @@ def fleet_fits(request): context = {} return render_to_response('registered/fleetfits.html', context, context_instance=RequestContext(request)) + +@login_required +@user_passes_test(service_blue_alliance_test) +def deactivate_discord(request): + authinfo = AuthServicesInfoManager.get_auth_service_info(request.user) + result = DiscordManager.delete_user(authinfo.discord_uid) + if result: + remove_all_syncgroups_for_service(request.user, "discord") + AuthServicesInfoManager.update_user_discord_info("", request.user) + return HttpResponseRedirect("/services/") + return HttpResponseRedirect("/dashboard") + +@login_required +@user_passes_test(service_blue_alliance_test) +def reset_discord(request): + authinfo = AuthServicesInfoManager.get_auth_service_info(request.user) + result = DiscordManager.delete_user(authinfo.discord_uid) + if result: + AuthServicesInfoManager.update_user_discord_info("",request.user) + return HttpResponseRedirect("/activate_discord/") + return HttpResponseRedirect("/services/") + +@login_required +@user_passes_test(service_blue_alliance_test) +def activate_discord(request): + success = False + if request.method == 'POST': + form = DiscordForm(request.POST) + if form.is_valid(): + email = form.cleaned_data['email'] + password = form.cleaned_data['password'] + try: + user_id = DiscordManager.add_user(email, password) + if user_id != "": + AuthServicesInfoManager.update_user_discord_info(user_id, request.user) + update_discord_groups(request.user) + success = True + return HttpResponseRedirect("/services/") + except: + pass + else: + form = DiscordForm() + + context = {'form': form, 'success': success} + return render_to_response('registered/discord.html', context, context_instance=RequestContext(request)) diff --git a/srp/views.py b/srp/views.py index 61a160be..2ae7061e 100755 --- a/srp/views.py +++ b/srp/views.py @@ -18,7 +18,7 @@ from form import SrpFleetMainUpdateForm def srp_util_test(user): - return check_if_user_has_permission(user, 'alliance_member') or check_if_user_has_permission(user, 'blue_member') + return check_if_user_has_permission(user, 'member') or check_if_user_has_permission(user, 'blue_member') @login_required @@ -273,4 +273,4 @@ def srp_fleet_edit_view(request, fleet_id): render_items = {'form': form, "no_fleet_id": no_fleet_id} return render_to_response('registered/srpfleetupdate.html', render_items, - context_instance=RequestContext(request)) \ No newline at end of file + context_instance=RequestContext(request)) diff --git a/static/.gitignore b/static/.gitignore new file mode 100644 index 00000000..7c9d611b --- /dev/null +++ b/static/.gitignore @@ -0,0 +1,3 @@ +* +!.gitignore +!README.md diff --git a/static/README.md b/static/README.md new file mode 100644 index 00000000..a402c777 --- /dev/null +++ b/static/README.md @@ -0,0 +1,5 @@ +Don't edit files in this folder. + +Populate the required static files with the command: + +`python manage.py collectstatic` diff --git a/static/admin/css/base.css b/stock/static/admin/css/base.css similarity index 100% rename from static/admin/css/base.css rename to stock/static/admin/css/base.css diff --git a/static/admin/css/changelists.css b/stock/static/admin/css/changelists.css similarity index 100% rename from static/admin/css/changelists.css rename to stock/static/admin/css/changelists.css diff --git a/static/admin/css/dashboard.css b/stock/static/admin/css/dashboard.css similarity index 100% rename from static/admin/css/dashboard.css rename to stock/static/admin/css/dashboard.css diff --git a/static/admin/css/forms.css b/stock/static/admin/css/forms.css similarity index 100% rename from static/admin/css/forms.css rename to stock/static/admin/css/forms.css diff --git a/static/admin/css/ie.css b/stock/static/admin/css/ie.css similarity index 100% rename from static/admin/css/ie.css rename to stock/static/admin/css/ie.css diff --git a/static/admin/css/login.css b/stock/static/admin/css/login.css similarity index 100% rename from static/admin/css/login.css rename to stock/static/admin/css/login.css diff --git a/static/admin/css/rtl.css b/stock/static/admin/css/rtl.css similarity index 100% rename from static/admin/css/rtl.css rename to stock/static/admin/css/rtl.css diff --git a/static/admin/css/widgets.css b/stock/static/admin/css/widgets.css similarity index 100% rename from static/admin/css/widgets.css rename to stock/static/admin/css/widgets.css diff --git a/static/admin/img/changelist-bg.gif b/stock/static/admin/img/changelist-bg.gif similarity index 100% rename from static/admin/img/changelist-bg.gif rename to stock/static/admin/img/changelist-bg.gif diff --git a/static/admin/img/changelist-bg_rtl.gif b/stock/static/admin/img/changelist-bg_rtl.gif similarity index 100% rename from static/admin/img/changelist-bg_rtl.gif rename to stock/static/admin/img/changelist-bg_rtl.gif diff --git a/static/admin/img/chooser-bg.gif b/stock/static/admin/img/chooser-bg.gif similarity index 100% rename from static/admin/img/chooser-bg.gif rename to stock/static/admin/img/chooser-bg.gif diff --git a/static/admin/img/chooser_stacked-bg.gif b/stock/static/admin/img/chooser_stacked-bg.gif similarity index 100% rename from static/admin/img/chooser_stacked-bg.gif rename to stock/static/admin/img/chooser_stacked-bg.gif diff --git a/static/admin/img/default-bg-reverse.gif b/stock/static/admin/img/default-bg-reverse.gif similarity index 100% rename from static/admin/img/default-bg-reverse.gif rename to stock/static/admin/img/default-bg-reverse.gif diff --git a/static/admin/img/default-bg.gif b/stock/static/admin/img/default-bg.gif similarity index 100% rename from static/admin/img/default-bg.gif rename to stock/static/admin/img/default-bg.gif diff --git a/static/admin/img/deleted-overlay.gif b/stock/static/admin/img/deleted-overlay.gif similarity index 100% rename from static/admin/img/deleted-overlay.gif rename to stock/static/admin/img/deleted-overlay.gif diff --git a/static/admin/img/gis/move_vertex_off.png b/stock/static/admin/img/gis/move_vertex_off.png similarity index 100% rename from static/admin/img/gis/move_vertex_off.png rename to stock/static/admin/img/gis/move_vertex_off.png diff --git a/static/admin/img/gis/move_vertex_on.png b/stock/static/admin/img/gis/move_vertex_on.png similarity index 100% rename from static/admin/img/gis/move_vertex_on.png rename to stock/static/admin/img/gis/move_vertex_on.png diff --git a/static/admin/img/icon-no.gif b/stock/static/admin/img/icon-no.gif similarity index 100% rename from static/admin/img/icon-no.gif rename to stock/static/admin/img/icon-no.gif diff --git a/static/admin/img/icon-unknown.gif b/stock/static/admin/img/icon-unknown.gif similarity index 100% rename from static/admin/img/icon-unknown.gif rename to stock/static/admin/img/icon-unknown.gif diff --git a/static/admin/img/icon-yes.gif b/stock/static/admin/img/icon-yes.gif similarity index 100% rename from static/admin/img/icon-yes.gif rename to stock/static/admin/img/icon-yes.gif diff --git a/static/admin/img/icon_addlink.gif b/stock/static/admin/img/icon_addlink.gif similarity index 100% rename from static/admin/img/icon_addlink.gif rename to stock/static/admin/img/icon_addlink.gif diff --git a/static/admin/img/icon_alert.gif b/stock/static/admin/img/icon_alert.gif similarity index 100% rename from static/admin/img/icon_alert.gif rename to stock/static/admin/img/icon_alert.gif diff --git a/static/admin/img/icon_calendar.gif b/stock/static/admin/img/icon_calendar.gif similarity index 100% rename from static/admin/img/icon_calendar.gif rename to stock/static/admin/img/icon_calendar.gif diff --git a/static/admin/img/icon_changelink.gif b/stock/static/admin/img/icon_changelink.gif similarity index 100% rename from static/admin/img/icon_changelink.gif rename to stock/static/admin/img/icon_changelink.gif diff --git a/static/admin/img/icon_clock.gif b/stock/static/admin/img/icon_clock.gif similarity index 100% rename from static/admin/img/icon_clock.gif rename to stock/static/admin/img/icon_clock.gif diff --git a/static/admin/img/icon_deletelink.gif b/stock/static/admin/img/icon_deletelink.gif similarity index 100% rename from static/admin/img/icon_deletelink.gif rename to stock/static/admin/img/icon_deletelink.gif diff --git a/static/admin/img/icon_error.gif b/stock/static/admin/img/icon_error.gif similarity index 100% rename from static/admin/img/icon_error.gif rename to stock/static/admin/img/icon_error.gif diff --git a/static/admin/img/icon_searchbox.png b/stock/static/admin/img/icon_searchbox.png similarity index 100% rename from static/admin/img/icon_searchbox.png rename to stock/static/admin/img/icon_searchbox.png diff --git a/static/admin/img/icon_success.gif b/stock/static/admin/img/icon_success.gif similarity index 100% rename from static/admin/img/icon_success.gif rename to stock/static/admin/img/icon_success.gif diff --git a/static/admin/img/inline-delete-8bit.png b/stock/static/admin/img/inline-delete-8bit.png similarity index 100% rename from static/admin/img/inline-delete-8bit.png rename to stock/static/admin/img/inline-delete-8bit.png diff --git a/static/admin/img/inline-delete.png b/stock/static/admin/img/inline-delete.png similarity index 100% rename from static/admin/img/inline-delete.png rename to stock/static/admin/img/inline-delete.png diff --git a/static/admin/img/inline-restore-8bit.png b/stock/static/admin/img/inline-restore-8bit.png similarity index 100% rename from static/admin/img/inline-restore-8bit.png rename to stock/static/admin/img/inline-restore-8bit.png diff --git a/static/admin/img/inline-restore.png b/stock/static/admin/img/inline-restore.png similarity index 100% rename from static/admin/img/inline-restore.png rename to stock/static/admin/img/inline-restore.png diff --git a/static/admin/img/inline-splitter-bg.gif b/stock/static/admin/img/inline-splitter-bg.gif similarity index 100% rename from static/admin/img/inline-splitter-bg.gif rename to stock/static/admin/img/inline-splitter-bg.gif diff --git a/static/admin/img/nav-bg-grabber.gif b/stock/static/admin/img/nav-bg-grabber.gif similarity index 100% rename from static/admin/img/nav-bg-grabber.gif rename to stock/static/admin/img/nav-bg-grabber.gif diff --git a/static/admin/img/nav-bg-reverse.gif b/stock/static/admin/img/nav-bg-reverse.gif similarity index 100% rename from static/admin/img/nav-bg-reverse.gif rename to stock/static/admin/img/nav-bg-reverse.gif diff --git a/static/admin/img/nav-bg-selected.gif b/stock/static/admin/img/nav-bg-selected.gif similarity index 100% rename from static/admin/img/nav-bg-selected.gif rename to stock/static/admin/img/nav-bg-selected.gif diff --git a/static/admin/img/nav-bg.gif b/stock/static/admin/img/nav-bg.gif similarity index 100% rename from static/admin/img/nav-bg.gif rename to stock/static/admin/img/nav-bg.gif diff --git a/static/admin/img/selector-icons.gif b/stock/static/admin/img/selector-icons.gif similarity index 100% rename from static/admin/img/selector-icons.gif rename to stock/static/admin/img/selector-icons.gif diff --git a/static/admin/img/selector-search.gif b/stock/static/admin/img/selector-search.gif similarity index 100% rename from static/admin/img/selector-search.gif rename to stock/static/admin/img/selector-search.gif diff --git a/static/admin/img/sorting-icons.gif b/stock/static/admin/img/sorting-icons.gif similarity index 100% rename from static/admin/img/sorting-icons.gif rename to stock/static/admin/img/sorting-icons.gif diff --git a/static/admin/img/tool-left.gif b/stock/static/admin/img/tool-left.gif similarity index 100% rename from static/admin/img/tool-left.gif rename to stock/static/admin/img/tool-left.gif diff --git a/static/admin/img/tool-left_over.gif b/stock/static/admin/img/tool-left_over.gif similarity index 100% rename from static/admin/img/tool-left_over.gif rename to stock/static/admin/img/tool-left_over.gif diff --git a/static/admin/img/tool-right.gif b/stock/static/admin/img/tool-right.gif similarity index 100% rename from static/admin/img/tool-right.gif rename to stock/static/admin/img/tool-right.gif diff --git a/static/admin/img/tool-right_over.gif b/stock/static/admin/img/tool-right_over.gif similarity index 100% rename from static/admin/img/tool-right_over.gif rename to stock/static/admin/img/tool-right_over.gif diff --git a/static/admin/img/tooltag-add.gif b/stock/static/admin/img/tooltag-add.gif similarity index 100% rename from static/admin/img/tooltag-add.gif rename to stock/static/admin/img/tooltag-add.gif diff --git a/static/admin/img/tooltag-add_over.gif b/stock/static/admin/img/tooltag-add_over.gif similarity index 100% rename from static/admin/img/tooltag-add_over.gif rename to stock/static/admin/img/tooltag-add_over.gif diff --git a/static/admin/img/tooltag-arrowright.gif b/stock/static/admin/img/tooltag-arrowright.gif similarity index 100% rename from static/admin/img/tooltag-arrowright.gif rename to stock/static/admin/img/tooltag-arrowright.gif diff --git a/static/admin/img/tooltag-arrowright_over.gif b/stock/static/admin/img/tooltag-arrowright_over.gif similarity index 100% rename from static/admin/img/tooltag-arrowright_over.gif rename to stock/static/admin/img/tooltag-arrowright_over.gif diff --git a/static/admin/js/LICENSE-JQUERY.txt b/stock/static/admin/js/LICENSE-JQUERY.txt similarity index 100% rename from static/admin/js/LICENSE-JQUERY.txt rename to stock/static/admin/js/LICENSE-JQUERY.txt diff --git a/static/admin/js/SelectBox.js b/stock/static/admin/js/SelectBox.js similarity index 100% rename from static/admin/js/SelectBox.js rename to stock/static/admin/js/SelectBox.js diff --git a/static/admin/js/SelectFilter2.js b/stock/static/admin/js/SelectFilter2.js similarity index 100% rename from static/admin/js/SelectFilter2.js rename to stock/static/admin/js/SelectFilter2.js diff --git a/static/admin/js/actions.js b/stock/static/admin/js/actions.js similarity index 100% rename from static/admin/js/actions.js rename to stock/static/admin/js/actions.js diff --git a/static/admin/js/actions.min.js b/stock/static/admin/js/actions.min.js similarity index 100% rename from static/admin/js/actions.min.js rename to stock/static/admin/js/actions.min.js diff --git a/static/admin/js/admin/DateTimeShortcuts.js b/stock/static/admin/js/admin/DateTimeShortcuts.js similarity index 100% rename from static/admin/js/admin/DateTimeShortcuts.js rename to stock/static/admin/js/admin/DateTimeShortcuts.js diff --git a/static/admin/js/admin/RelatedObjectLookups.js b/stock/static/admin/js/admin/RelatedObjectLookups.js similarity index 100% rename from static/admin/js/admin/RelatedObjectLookups.js rename to stock/static/admin/js/admin/RelatedObjectLookups.js diff --git a/static/admin/js/calendar.js b/stock/static/admin/js/calendar.js similarity index 100% rename from static/admin/js/calendar.js rename to stock/static/admin/js/calendar.js diff --git a/static/admin/js/collapse.js b/stock/static/admin/js/collapse.js similarity index 100% rename from static/admin/js/collapse.js rename to stock/static/admin/js/collapse.js diff --git a/static/admin/js/collapse.min.js b/stock/static/admin/js/collapse.min.js similarity index 100% rename from static/admin/js/collapse.min.js rename to stock/static/admin/js/collapse.min.js diff --git a/static/admin/js/core.js b/stock/static/admin/js/core.js similarity index 100% rename from static/admin/js/core.js rename to stock/static/admin/js/core.js diff --git a/static/admin/js/inlines.js b/stock/static/admin/js/inlines.js similarity index 100% rename from static/admin/js/inlines.js rename to stock/static/admin/js/inlines.js diff --git a/static/admin/js/inlines.min.js b/stock/static/admin/js/inlines.min.js similarity index 100% rename from static/admin/js/inlines.min.js rename to stock/static/admin/js/inlines.min.js diff --git a/static/admin/js/jquery.init.js b/stock/static/admin/js/jquery.init.js similarity index 100% rename from static/admin/js/jquery.init.js rename to stock/static/admin/js/jquery.init.js diff --git a/static/admin/js/jquery.js b/stock/static/admin/js/jquery.js similarity index 100% rename from static/admin/js/jquery.js rename to stock/static/admin/js/jquery.js diff --git a/static/admin/js/jquery.min.js b/stock/static/admin/js/jquery.min.js similarity index 100% rename from static/admin/js/jquery.min.js rename to stock/static/admin/js/jquery.min.js diff --git a/static/admin/js/prepopulate.js b/stock/static/admin/js/prepopulate.js similarity index 100% rename from static/admin/js/prepopulate.js rename to stock/static/admin/js/prepopulate.js diff --git a/static/admin/js/prepopulate.min.js b/stock/static/admin/js/prepopulate.min.js similarity index 100% rename from static/admin/js/prepopulate.min.js rename to stock/static/admin/js/prepopulate.min.js diff --git a/static/admin/js/timeparse.js b/stock/static/admin/js/timeparse.js similarity index 100% rename from static/admin/js/timeparse.js rename to stock/static/admin/js/timeparse.js diff --git a/static/admin/js/urlify.js b/stock/static/admin/js/urlify.js similarity index 100% rename from static/admin/js/urlify.js rename to stock/static/admin/js/urlify.js diff --git a/static/css/bootstrap-theme.min.css b/stock/static/css/bootstrap-theme.min.css similarity index 100% rename from static/css/bootstrap-theme.min.css rename to stock/static/css/bootstrap-theme.min.css diff --git a/static/css/bootstrap.min.css b/stock/static/css/bootstrap.min.css similarity index 100% rename from static/css/bootstrap.min.css rename to stock/static/css/bootstrap.min.css diff --git a/static/css/font-awesome.min.css b/stock/static/css/font-awesome.min.css similarity index 100% rename from static/css/font-awesome.min.css rename to stock/static/css/font-awesome.min.css diff --git a/static/css/jquery.datetimepicker.css b/stock/static/css/jquery.datetimepicker.css similarity index 100% rename from static/css/jquery.datetimepicker.css rename to stock/static/css/jquery.datetimepicker.css diff --git a/static/css/sb-admin-2.css b/stock/static/css/sb-admin-2.css similarity index 100% rename from static/css/sb-admin-2.css rename to stock/static/css/sb-admin-2.css diff --git a/static/fonts/FontAwesome.otf b/stock/static/fonts/FontAwesome.otf similarity index 100% rename from static/fonts/FontAwesome.otf rename to stock/static/fonts/FontAwesome.otf diff --git a/static/fonts/fontawesome-webfont.eot b/stock/static/fonts/fontawesome-webfont.eot similarity index 100% rename from static/fonts/fontawesome-webfont.eot rename to stock/static/fonts/fontawesome-webfont.eot diff --git a/static/fonts/fontawesome-webfont.svg b/stock/static/fonts/fontawesome-webfont.svg similarity index 100% rename from static/fonts/fontawesome-webfont.svg rename to stock/static/fonts/fontawesome-webfont.svg diff --git a/static/fonts/fontawesome-webfont.ttf b/stock/static/fonts/fontawesome-webfont.ttf similarity index 100% rename from static/fonts/fontawesome-webfont.ttf rename to stock/static/fonts/fontawesome-webfont.ttf diff --git a/static/fonts/fontawesome-webfont.woff b/stock/static/fonts/fontawesome-webfont.woff similarity index 100% rename from static/fonts/fontawesome-webfont.woff rename to stock/static/fonts/fontawesome-webfont.woff diff --git a/static/fonts/glyphicons-halflings-regular.eot b/stock/static/fonts/glyphicons-halflings-regular.eot similarity index 100% rename from static/fonts/glyphicons-halflings-regular.eot rename to stock/static/fonts/glyphicons-halflings-regular.eot diff --git a/static/fonts/glyphicons-halflings-regular.svg b/stock/static/fonts/glyphicons-halflings-regular.svg similarity index 100% rename from static/fonts/glyphicons-halflings-regular.svg rename to stock/static/fonts/glyphicons-halflings-regular.svg diff --git a/static/fonts/glyphicons-halflings-regular.ttf b/stock/static/fonts/glyphicons-halflings-regular.ttf similarity index 100% rename from static/fonts/glyphicons-halflings-regular.ttf rename to stock/static/fonts/glyphicons-halflings-regular.ttf diff --git a/static/fonts/glyphicons-halflings-regular.woff b/stock/static/fonts/glyphicons-halflings-regular.woff similarity index 100% rename from static/fonts/glyphicons-halflings-regular.woff rename to stock/static/fonts/glyphicons-halflings-regular.woff diff --git a/static/img/index_images/auth.png b/stock/static/img/index_images/auth.png similarity index 100% rename from static/img/index_images/auth.png rename to stock/static/img/index_images/auth.png diff --git a/static/img/index_images/forums.png b/stock/static/img/index_images/forums.png similarity index 100% rename from static/img/index_images/forums.png rename to stock/static/img/index_images/forums.png diff --git a/static/img/index_images/index_bg.jpg b/stock/static/img/index_images/index_bg.jpg similarity index 100% rename from static/img/index_images/index_bg.jpg rename to stock/static/img/index_images/index_bg.jpg diff --git a/static/img/index_images/index_blank_bg.jpg b/stock/static/img/index_images/index_blank_bg.jpg similarity index 100% rename from static/img/index_images/index_blank_bg.jpg rename to stock/static/img/index_images/index_blank_bg.jpg diff --git a/static/img/index_images/killboard.png b/stock/static/img/index_images/killboard.png similarity index 100% rename from static/img/index_images/killboard.png rename to stock/static/img/index_images/killboard.png diff --git a/stock/static/img/index_images/logo.png b/stock/static/img/index_images/logo.png new file mode 100644 index 00000000..b33ad850 Binary files /dev/null and b/stock/static/img/index_images/logo.png differ diff --git a/static/img/index_images/media.png b/stock/static/img/index_images/media.png similarity index 100% rename from static/img/index_images/media.png rename to stock/static/img/index_images/media.png diff --git a/static/js/bootstrap.min.js b/stock/static/js/bootstrap.min.js similarity index 100% rename from static/js/bootstrap.min.js rename to stock/static/js/bootstrap.min.js diff --git a/static/js/countdown.js b/stock/static/js/countdown.js similarity index 100% rename from static/js/countdown.js rename to stock/static/js/countdown.js diff --git a/static/js/dateformat.js b/stock/static/js/dateformat.js similarity index 100% rename from static/js/dateformat.js rename to stock/static/js/dateformat.js diff --git a/static/js/jquery.datetimepicker.js b/stock/static/js/jquery.datetimepicker.js similarity index 100% rename from static/js/jquery.datetimepicker.js rename to stock/static/js/jquery.datetimepicker.js diff --git a/static/js/jquery.min.js b/stock/static/js/jquery.min.js similarity index 100% rename from static/js/jquery.min.js rename to stock/static/js/jquery.min.js diff --git a/templates/public/base.html b/stock/templates/public/base.html similarity index 89% rename from templates/public/base.html rename to stock/templates/public/base.html index 55a6fc3c..279743d0 100755 --- a/templates/public/base.html +++ b/stock/templates/public/base.html @@ -36,7 +36,11 @@
@@ -76,7 +80,7 @@ class="fa fa-users fa-fw grayiconecolor"> Characters - {% if perms.auth.alliance_member %} + {% if perms.auth.member %}
+
+
-
-
-
-