mirror of
https://gitlab.com/allianceauth/allianceauth.git
synced 2026-02-06 07:06:19 +01:00
Adarnof's Little Things (#547)
* Port to Django 1.10 Initial migrations for current states of all models. Requires faking to retain data. Removed all references to render_to_response, replacing with render shortcut. Same for HttpResponseRedirect to render shortcut. Corrected notification signal import to wait for app registry to finish loading. * Correct typos from render conversion * Modify models to suppress Django field warnings * Script for automatic database conversion - fakes initial migrations to preserve data Include LOGIN_URL setting * Correct context processor import typo * Removed pathfinder support. Current pathfinder versions require SSO, not APIs added to database. Conditionally load additional database definitions only if services are enabled. Prevents errors when running auth without creating all possible databases. * Condense context processors * Include Django 1.10 installation in migrate script Remove syncdb/evolve, replace with migrate for update script * Replaced member/blue perms with user state system Removed sigtracker Initial migrations for default perms and groups Removed perm bootstrapping on first run * Clean up services list * Remove fleet fittings page * Provide action feedback via django messaging Display unread notification count Correct left navbar alignment * Stop storing service passwords. Provide them one time upon activation or reset. Closes #177 * Add group sync buttons to admin site Allow searcing of AuthServicesInfo models Display user main character * Correct button CSS to remove underlines on hover * Added bulk actions to notifications Altered notification default ordering * Centralize API key validation. Remove unused error count on API key model. Restructure API key refresh task to queue all keys per user and await completion. Closes #350 * Example configuration files for supervisor. Copy to /etc/supervisor/conf.d and restart to take effect. Closes #521 Closes #266 * Pre-save receiver for member/blue state switching Removed is_blue field Added link to admin site * Remove all hardcoded URLs from views and templates Correct missing render arguments Closes #540 * Correct celeryd process directory * Migration to automatically set user states. Runs instead of waiting for next API refresh cycle. Should make the transition much easier. * Verify service accounts accessible to member state * Restructure project to remove unnecessary apps. (celerytask, util, portal, registraion apps) Added workarounds for python 3 compatibility. * Correct python2 compatibility * Check services against state being changed to * Python3 compatibility fixes * Relocate x2bool py3 fix * SSO integration for logging in to existing accounts. * Add missing url names for fleetup reverse * Sanitize groupnames before syncing. * Correct trailing slash preventing url resolution * Alter group name sanitization to allow periods and hyphens * Correct state check on pre_save model for corp/alliance group assignment * Remove sigtracker table from old dbs to allow user deletion * Include missing celery configuration * Teamspeak error handling * Prevent celery worker deadlock on async group result wait * Correct active navbar links for translated urls. Correct corp status url resolution for some links. Remove DiscordAuthToken model.
This commit is contained in:
@@ -0,0 +1,2 @@
|
||||
from __future__ import unicode_literals
|
||||
default_app_config = 'services.apps.ServicesConfig'
|
||||
|
||||
@@ -1,13 +1,15 @@
|
||||
from __future__ import unicode_literals
|
||||
from django.contrib import admin
|
||||
from .models import AuthTS
|
||||
from .models import DiscordAuthToken
|
||||
from .models import MumbleUser
|
||||
from .models import GroupCache
|
||||
from services.models import AuthTS
|
||||
from services.models import MumbleUser
|
||||
from services.models import GroupCache
|
||||
|
||||
|
||||
class AuthTSgroupAdmin(admin.ModelAdmin):
|
||||
fields = ['auth_group','ts_group']
|
||||
fields = ['auth_group', 'ts_group']
|
||||
filter_horizontal = ('ts_group',)
|
||||
|
||||
|
||||
admin.site.register(AuthTS, AuthTSgroupAdmin)
|
||||
|
||||
admin.site.register(MumbleUser)
|
||||
|
||||
10
services/apps.py
Normal file
10
services/apps.py
Normal file
@@ -0,0 +1,10 @@
|
||||
from __future__ import unicode_literals
|
||||
|
||||
from django.apps import AppConfig
|
||||
|
||||
|
||||
class ServicesConfig(AppConfig):
|
||||
name = 'services'
|
||||
|
||||
def ready(self):
|
||||
import services.signals
|
||||
31
services/context_processors.py
Normal file
31
services/context_processors.py
Normal file
@@ -0,0 +1,31 @@
|
||||
from __future__ import unicode_literals
|
||||
from django.conf import settings
|
||||
from django.utils import timezone
|
||||
|
||||
|
||||
def auth_settings(request):
|
||||
return {
|
||||
'DOMAIN': settings.DOMAIN,
|
||||
'MUMBLE_URL': settings.MUMBLE_URL,
|
||||
'FORUM_URL': settings.FORUM_URL,
|
||||
'TEAMSPEAK3_PUBLIC_URL': settings.TEAMSPEAK3_PUBLIC_URL,
|
||||
'JACK_KNIFE_URL': settings.JACK_KNIFE_URL,
|
||||
'DISCORD_SERVER_ID': settings.DISCORD_GUILD_ID,
|
||||
'KILLBOARD_URL': settings.KILLBOARD_URL,
|
||||
'DISCOURSE_URL': settings.DISCOURSE_URL,
|
||||
'IPS4_URL': settings.IPS4_URL,
|
||||
'SMF_URL': settings.SMF_URL,
|
||||
'MARKET_URL': settings.MARKET_URL,
|
||||
'EXTERNAL_MEDIA_URL': settings.EXTERNAL_MEDIA_URL,
|
||||
'CURRENT_UTC_TIME': timezone.now(),
|
||||
'BLUE_API_MASK': settings.BLUE_API_MASK,
|
||||
'BLUE_API_ACCOUNT': settings.BLUE_API_ACCOUNT,
|
||||
'MEMBER_API_MASK': settings.MEMBER_API_MASK,
|
||||
'MEMBER_API_ACCOUNT': settings.MEMBER_API_ACCOUNT,
|
||||
'JABBER_URL': settings.JABBER_URL,
|
||||
'ALLIANCE_NAME': settings.ALLIANCE_NAME,
|
||||
'ALLIANCE_ID': settings.ALLIANCE_ID,
|
||||
'CORP_NAME': settings.CORP_NAME,
|
||||
'CORP_ID': settings.CORP_ID,
|
||||
'IS_CORP': settings.IS_CORP,
|
||||
}
|
||||
@@ -1,7 +1,9 @@
|
||||
from __future__ import unicode_literals
|
||||
from django import forms
|
||||
from services.managers.teamspeak3_manager import Teamspeak3Manager
|
||||
from django.utils.translation import ugettext_lazy as _
|
||||
|
||||
|
||||
class JabberBroadcastForm(forms.Form):
|
||||
group = forms.ChoiceField(label=_('Group'), widget=forms.Select)
|
||||
message = forms.CharField(label=_('Message'), widget=forms.Textarea)
|
||||
@@ -17,23 +19,29 @@ class FleetFormatterForm(forms.Form):
|
||||
formup_time = forms.CharField(label=_('Formup Time:'), required=True)
|
||||
expected_duration = forms.CharField(label=_('Expected Duration:'), required=True)
|
||||
purpose = forms.CharField(label=_('Purpose:'), required=True)
|
||||
reimbursable = forms.ChoiceField(label=_('Reimbursable?*'), choices=[(_('Yes'), _('Yes')), (_('No'), _('No'))], required=True)
|
||||
important = forms.ChoiceField(label=_('Important?*'), choices=[(_('Yes'), _('Yes')), (_('No'), _('No'))], required=True)
|
||||
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(label=_('Comments'), 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)
|
||||
update_avatar = forms.BooleanField(label=_("Update Avatar"), required=False, initial=True)
|
||||
|
||||
|
||||
class ServicePasswordForm(forms.Form):
|
||||
password = forms.CharField(label=_("Password"), required=True)
|
||||
|
||||
def clean_password(self):
|
||||
password = self.cleaned_data['password']
|
||||
if not len(password) >= 8:
|
||||
raise forms.ValidationError(_("Password must be at least 8 characters long."))
|
||||
return password
|
||||
|
||||
|
||||
class TeamspeakJoinForm(forms.Form):
|
||||
username = forms.CharField(widget=forms.HiddenInput())
|
||||
|
||||
|
||||
@@ -0,0 +1 @@
|
||||
from __future__ import unicode_literals
|
||||
|
||||
@@ -1,11 +1,9 @@
|
||||
from __future__ import unicode_literals
|
||||
import requests
|
||||
import json
|
||||
from django.conf import settings
|
||||
import re
|
||||
import os
|
||||
import urllib
|
||||
import base64
|
||||
from services.models import DiscordAuthToken, GroupCache
|
||||
from django.conf import settings
|
||||
from services.models import GroupCache
|
||||
from requests_oauthlib import OAuth2Session
|
||||
import logging
|
||||
import datetime
|
||||
@@ -16,442 +14,10 @@ logger = logging.getLogger(__name__)
|
||||
DISCORD_URL = "https://discordapp.com/api"
|
||||
EVE_IMAGE_SERVER = "https://image.eveonline.com"
|
||||
|
||||
class DiscordAPIManager:
|
||||
|
||||
def __init__(self, server_id, email, password, user=None):
|
||||
self.token = DiscordAPIManager.get_token_by_user(email, password, user)
|
||||
self.email = email
|
||||
self.password = password
|
||||
self.server_id = server_id
|
||||
logger.debug("Initialized DiscordAPIManager with server id %s" % self.server_id)
|
||||
|
||||
@staticmethod
|
||||
def validate_token(token):
|
||||
custom_headers = {'accept': 'application/json', 'authorization': token}
|
||||
path = DISCORD_URL + "/users/@me"
|
||||
r = requests.get(path, headers=custom_headers)
|
||||
if r.status_code == 200:
|
||||
logger.debug("Token starting with %s passed validation." % token[0:5])
|
||||
return True
|
||||
else:
|
||||
logger.debug("Token starting with %s failed validation with status code %s" % (token[0:5], r.status_code))
|
||||
return False
|
||||
|
||||
@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))
|
||||
logger.debug("Received status code %s during token generation for settings discord user." % r.status_code)
|
||||
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)
|
||||
logger.debug("Received status code %s after banning user %s" % (r.status_code, user_id))
|
||||
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)
|
||||
logger.debug("Received status code %s after deleting ban for user %s" % (r.status_code, user_id))
|
||||
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)
|
||||
logger.debug("Received status code %s after generating new role." % r.status_code)
|
||||
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))
|
||||
logger.debug("Received status code %s after editing role id %s" % (r.status_code, role_id))
|
||||
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()
|
||||
|
||||
def accept_invite(self, invite_id):
|
||||
custom_headers = {'accept': 'application/json', 'authorization': self.token}
|
||||
path = DISCORD_URL + "/invite/" + str(invite_id)
|
||||
r = requests.post(path, headers=custom_headers)
|
||||
logger.debug("Received status code %s after accepting invite." % r.status_code)
|
||||
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))
|
||||
logger.debug("Received status code %s after creating invite." % r.status_code)
|
||||
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))
|
||||
logger.debug("Received status code %s after setting roles of user %s to %s" % (r.status_code, user_id, role_ids))
|
||||
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)
|
||||
logger.debug("Received status code %s after retrieving role list from server." % r.status_code)
|
||||
r.raise_for_status()
|
||||
return r.json()
|
||||
|
||||
def get_group_id(self, group_name):
|
||||
logger.debug("Determining role id for group name %s" % group_name)
|
||||
all_roles = self.get_roles()
|
||||
logger.debug("Retrieved role list for server: %s" % all_roles)
|
||||
for role in all_roles:
|
||||
logger.debug("Checking role %s" % role)
|
||||
if role['name'] == group_name:
|
||||
logger.debug("Found role matching name: %s" % role['id'])
|
||||
return role['id']
|
||||
logger.debug("Role not found on server. Raising KeyError")
|
||||
raise KeyError('Group not found on server: ' + group_name)
|
||||
|
||||
@staticmethod
|
||||
def get_token_by_user(email, password, user):
|
||||
if DiscordAuthToken.objects.filter(email=email).exists():
|
||||
auth = DiscordAuthToken.objects.get(email=email)
|
||||
if not auth.user == user:
|
||||
raise ValueError("User mismatch while validating DiscordAuthToken for email %s - user %s, requesting user %s" % (email, auth.user, user))
|
||||
logger.debug("Discord auth token cached for supplied email starting with %s" % email[0:3])
|
||||
auth = DiscordAuthToken.objects.get(email=email, user=user)
|
||||
if DiscordAPIManager.validate_token(auth.token):
|
||||
logger.debug("Token still valid. Returning token starting with %s" % auth.token[0:5])
|
||||
return auth.token
|
||||
else:
|
||||
logger.debug("Token has expired. Deleting.")
|
||||
auth.delete()
|
||||
logger.debug("Generating auth token for email starting with %s user %s and password of length %s" % (email[0:3], user, len(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))
|
||||
logger.debug("Received status code %s after generating auth token for custom user." % r.status_code)
|
||||
r.raise_for_status()
|
||||
token = r.json()['token']
|
||||
auth = DiscordAuthToken(email=email, token=token, user=user)
|
||||
auth.save()
|
||||
logger.debug("Created cached token for email starting with %s" % email[0:3])
|
||||
return token
|
||||
|
||||
def get_profile(self):
|
||||
custom_headers = {'accept': 'application/json', 'authorization': self.token}
|
||||
path = DISCORD_URL + "/users/@me"
|
||||
r = requests.get(path, headers=custom_headers)
|
||||
logger.debug("Received status code %s after retrieving user profile with email %s" % (r.status_code, self.email[0:3]))
|
||||
r.raise_for_status()
|
||||
return r.json()
|
||||
|
||||
@staticmethod
|
||||
def get_user_profile(email, password, user):
|
||||
token = DiscordAPIManager.get_token_by_user(email, password, user)
|
||||
custom_headers = {'accept': 'application/json', 'authorization': token}
|
||||
path = DISCORD_URL + "/users/@me"
|
||||
r = requests.get(path, headers=custom_headers)
|
||||
logger.debug("Received status code %s after retrieving user profile with email %s" % (r.status_code, email[0:3]))
|
||||
r.raise_for_status()
|
||||
return r.json()
|
||||
|
||||
@staticmethod
|
||||
def set_user_password(email, current_password, new_password, user):
|
||||
profile = DiscordAPIManager.get_user_profile(email, current_password, user)
|
||||
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 set_user_avatar(email, current_password, user, avatar_url):
|
||||
profile = DiscordAPIManager.get_user_profile(email, current_password, user)
|
||||
avatar = "data:image/jpeg;base64," + base64.b64encode(urllib.urlopen(avatar_url).read())
|
||||
username = profile['username']
|
||||
data = {
|
||||
'avatar': avatar,
|
||||
'username': username,
|
||||
'password': current_password,
|
||||
'email': email
|
||||
}
|
||||
path = DISCORD_URL + "/users/@me"
|
||||
custom_headers = {'content-type':'application/json', 'authorization': DiscordAPIManager.get_token_by_user(email, current_password, user)}
|
||||
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):
|
||||
logger.debug("Updating groups for user_id %s: %s" % (user_id, groups))
|
||||
group_ids = []
|
||||
api = DiscordAPIManager(settings.DISCORD_SERVER_ID, settings.DISCORD_USER_EMAIL, settings.DISCORD_USER_PASSWORD)
|
||||
if len(groups) == 0:
|
||||
logger.debug("No groups provided - generating empty array of group ids.")
|
||||
group_ids = []
|
||||
else:
|
||||
for g in groups:
|
||||
try:
|
||||
logger.debug("Retrieving group id for group %s" % g)
|
||||
group_id = api.get_group_id(g)
|
||||
group_ids.append(group_id)
|
||||
logger.debug("Got id %s" % group_id)
|
||||
except:
|
||||
logger.debug("Group id retrieval generated exception - generating new group on discord server.", exc_info=True)
|
||||
group_ids.append(DiscordManager.create_group(g))
|
||||
logger.info("Setting discord groups for user %s to %s" % (user_id, group_ids))
|
||||
api.set_roles(user_id, group_ids)
|
||||
|
||||
@staticmethod
|
||||
def create_group(groupname):
|
||||
logger.debug("Creating new group %s" % groupname)
|
||||
api = DiscordAPIManager(settings.DISCORD_SERVER_ID, settings.DISCORD_USER_EMAIL, settings.DISCORD_USER_PASSWORD)
|
||||
new_group = api.generate_role()
|
||||
logger.debug("Created new role on server with id %s: %s" % (new_group['id'], new_group))
|
||||
named_group = api.edit_role(new_group['id'], groupname)
|
||||
logger.debug("Renamed group id %s to %s" % (new_group['id'], groupname))
|
||||
logger.info("Created new group on discord server with name %s" % 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, user):
|
||||
new_password = DiscordManager.__generate_random_pass()
|
||||
try:
|
||||
profile = DiscordAPIManager.set_user_password(email, current_password, new_password, user)
|
||||
return new_password
|
||||
except:
|
||||
return current_password
|
||||
|
||||
@staticmethod
|
||||
def update_user_avatar(email, password, user, char_id):
|
||||
try:
|
||||
char_url = EVE_IMAGE_SERVER + "/character/" + str(char_id) + "_256.jpg"
|
||||
logger.debug("Character image URL for %s: %s" % (user, char_url))
|
||||
DiscordAPIManager.set_user_avatar(email, password, user, char_url)
|
||||
return True
|
||||
except:
|
||||
return False
|
||||
|
||||
@staticmethod
|
||||
def add_user(email, password, user):
|
||||
try:
|
||||
logger.debug("Adding new user %s to discord with email %s and password of length %s" % (user, email[0:3], len(password)))
|
||||
server_api = DiscordAPIManager(settings.DISCORD_SERVER_ID, settings.DISCORD_USER_EMAIL, settings.DISCORD_USER_PASSWORD)
|
||||
user_api = DiscordAPIManager(settings.DISCORD_SERVER_ID, email, password, user=user)
|
||||
profile = user_api.get_profile()
|
||||
logger.debug("Got profile for user: %s" % profile)
|
||||
user_id = profile['id']
|
||||
logger.debug("Determined user id: %s" % user_id)
|
||||
|
||||
if server_api.check_if_user_banned(user_id):
|
||||
logger.debug("User is currently banned. Unbanning %s" % user_id)
|
||||
server_api.unban_user(user_id)
|
||||
invite_code = server_api.create_invite()['code']
|
||||
logger.debug("Generated invite code beginning with %s" % invite_code[0:5])
|
||||
user_api.accept_invite(invite_code)
|
||||
logger.info("Added user to discord server %s with id %s" % (settings.DISCORD_SERVER_ID, user_id))
|
||||
return user_id
|
||||
except:
|
||||
logger.exception("An unhandled exception has occured.")
|
||||
return ""
|
||||
|
||||
@staticmethod
|
||||
def delete_user(user_id):
|
||||
try:
|
||||
logger.debug("Deleting user with id %s from discord server." % user_id)
|
||||
api = DiscordAPIManager(settings.DISCORD_SERVER_ID, settings.DISCORD_USER_EMAIL, settings.DISCORD_USER_PASSWORD)
|
||||
DiscordManager.update_groups(user_id, [])
|
||||
api.ban_user(user_id)
|
||||
logger.info("Deleted user with id %s from discord server id %s" % (user_id, settings.DISCORD_SERVER_ID))
|
||||
return True
|
||||
except:
|
||||
logger.exception("An unhandled exception has occured.")
|
||||
return False
|
||||
|
||||
AUTH_URL = "https://discordapp.com/api/oauth2/authorize"
|
||||
TOKEN_URL = "https://discordapp.com/api/oauth2/token"
|
||||
|
||||
# kick, manage roles
|
||||
# kick, manage roles, manage nicknames
|
||||
BOT_PERMISSIONS = 0x00000002 + 0x10000000 + 0x08000000
|
||||
|
||||
# get user ID, accept invite
|
||||
@@ -462,7 +28,16 @@ SCOPES = [
|
||||
|
||||
GROUP_CACHE_MAX_AGE = datetime.timedelta(minutes=30)
|
||||
|
||||
|
||||
class DiscordOAuthManager:
|
||||
def __init__(self):
|
||||
pass
|
||||
|
||||
@staticmethod
|
||||
def _sanitize_groupname(name):
|
||||
name = name.strip(' _')
|
||||
return re.sub('[^\w.-]', '', name)
|
||||
|
||||
@staticmethod
|
||||
def generate_bot_add_url():
|
||||
return AUTH_URL + '?client_id=' + settings.DISCORD_APP_ID + '&scope=bot&permissions=' + str(BOT_PERMISSIONS)
|
||||
@@ -506,11 +81,12 @@ class DiscordOAuthManager:
|
||||
@staticmethod
|
||||
def update_nickname(user_id, nickname):
|
||||
try:
|
||||
custom_headers = {'content-type':'application/json', 'authorization': 'Bot ' + settings.DISCORD_BOT_TOKEN}
|
||||
data = { 'nick': nickname, }
|
||||
custom_headers = {'content-type': 'application/json', 'authorization': 'Bot ' + settings.DISCORD_BOT_TOKEN}
|
||||
data = {'nick': nickname, }
|
||||
path = DISCORD_URL + "/guilds/" + str(settings.DISCORD_GUILD_ID) + "/members/" + str(user_id)
|
||||
r = requests.patch(path, headers=custom_headers, json=data)
|
||||
logger.debug("Got status code %s after setting nickname for Discord user ID %s (%s)" % (r.status_code, user_id, nickname))
|
||||
logger.debug("Got status code %s after setting nickname for Discord user ID %s (%s)" % (
|
||||
r.status_code, user_id, nickname))
|
||||
if r.status_code == 404:
|
||||
logger.warn("Discord user ID %s could not be found in server." % user_id)
|
||||
return True
|
||||
@@ -584,7 +160,7 @@ class DiscordOAuthManager:
|
||||
|
||||
@staticmethod
|
||||
def __generate_role():
|
||||
custom_headers = {'accept':'application/json', 'authorization': 'Bot ' + settings.DISCORD_BOT_TOKEN}
|
||||
custom_headers = {'accept': 'application/json', 'authorization': 'Bot ' + settings.DISCORD_BOT_TOKEN}
|
||||
path = DISCORD_URL + "/guilds/" + str(settings.DISCORD_GUILD_ID) + "/roles"
|
||||
r = requests.post(path, headers=custom_headers)
|
||||
logger.debug("Received status code %s after generating new role." % r.status_code)
|
||||
@@ -593,11 +169,11 @@ class DiscordOAuthManager:
|
||||
|
||||
@staticmethod
|
||||
def __edit_role(role_id, name, color=0, hoist=True, permissions=36785152):
|
||||
custom_headers = {'content-type':'application/json', 'authorization': 'Bot ' + settings.DISCORD_BOT_TOKEN}
|
||||
custom_headers = {'content-type': 'application/json', 'authorization': 'Bot ' + settings.DISCORD_BOT_TOKEN}
|
||||
data = {
|
||||
'color': color,
|
||||
'hoist': hoist,
|
||||
'name': name,
|
||||
'name': name,
|
||||
'permissions': permissions,
|
||||
}
|
||||
path = DISCORD_URL + "/guilds/" + str(settings.DISCORD_GUILD_ID) + "/roles/" + str(role_id)
|
||||
@@ -609,13 +185,13 @@ class DiscordOAuthManager:
|
||||
@staticmethod
|
||||
def __create_group(name):
|
||||
role = DiscordOAuthManager.__generate_role()
|
||||
new_role = DiscordOAuthManager.__edit_role(role['id'], name)
|
||||
DiscordOAuthManager.__edit_role(role['id'], name)
|
||||
DiscordOAuthManager.__update_group_cache()
|
||||
|
||||
@staticmethod
|
||||
def update_groups(user_id, groups):
|
||||
custom_headers = {'content-type':'application/json', 'authorization': 'Bot ' + settings.DISCORD_BOT_TOKEN}
|
||||
group_ids = [DiscordOAuthManager.__group_name_to_id(g) for g in groups]
|
||||
custom_headers = {'content-type': 'application/json', 'authorization': 'Bot ' + settings.DISCORD_BOT_TOKEN}
|
||||
group_ids = [DiscordOAuthManager.__group_name_to_id(DiscordOAuthManager._sanitize_groupname(g)) for g in groups]
|
||||
path = DISCORD_URL + "/guilds/" + str(settings.DISCORD_GUILD_ID) + "/members/" + str(user_id)
|
||||
data = {'roles': group_ids}
|
||||
r = requests.patch(path, headers=custom_headers, json=data)
|
||||
|
||||
@@ -1,8 +1,10 @@
|
||||
from __future__ import unicode_literals
|
||||
import logging
|
||||
import requests
|
||||
import os
|
||||
import datetime
|
||||
import json
|
||||
import re
|
||||
from django.conf import settings
|
||||
from django.utils import timezone
|
||||
from services.models import GroupCache
|
||||
@@ -113,7 +115,11 @@ ENDPOINTS = {
|
||||
},
|
||||
}
|
||||
|
||||
|
||||
class DiscourseManager:
|
||||
def __init__(self):
|
||||
pass
|
||||
|
||||
GROUP_CACHE_MAX_AGE = datetime.timedelta(minutes=30)
|
||||
REVOKED_EMAIL = 'revoked@' + settings.DOMAIN
|
||||
SUSPEND_DAYS = 99999
|
||||
@@ -136,7 +142,7 @@ class DiscourseManager:
|
||||
if arg in kwargs:
|
||||
data[arg] = kwargs[arg]
|
||||
for arg in kwargs:
|
||||
if not arg in endpoint['args']['required'] and not arg in endpoint['args']['optional']:
|
||||
if arg not in endpoint['args']['required'] and arg not in endpoint['args']['optional']:
|
||||
logger.warn("Received unrecognized kwarg %s for endpoint %s" % (arg, endpoint))
|
||||
r = endpoint['method'](settings.DISCOURSE_URL + path, params=params, json=data)
|
||||
out = r.text
|
||||
@@ -218,10 +224,10 @@ class DiscourseManager:
|
||||
|
||||
@staticmethod
|
||||
def __generate_group_dict(names):
|
||||
dict = {}
|
||||
group_dict = {}
|
||||
for name in names:
|
||||
dict[name] = DiscourseManager.__group_name_to_id(name)
|
||||
return dict
|
||||
group_dict[name] = DiscourseManager.__group_name_to_id(name)
|
||||
return group_dict
|
||||
|
||||
@staticmethod
|
||||
def __get_user_groups(username):
|
||||
@@ -271,7 +277,8 @@ class DiscourseManager:
|
||||
def __suspend_user(username):
|
||||
id = DiscourseManager.__user_name_to_id(username)
|
||||
endpoint = ENDPOINTS['users']['suspend']
|
||||
return DiscourseManager.__exc(endpoint, id, duration=DiscourseManager.SUSPEND_DAYS, reason=DiscourseManager.SUSPEND_REASON)
|
||||
return DiscourseManager.__exc(endpoint, id, duration=DiscourseManager.SUSPEND_DAYS,
|
||||
reason=DiscourseManager.SUSPEND_REASON)
|
||||
|
||||
@staticmethod
|
||||
def __unsuspend(username):
|
||||
@@ -287,9 +294,15 @@ class DiscourseManager:
|
||||
@staticmethod
|
||||
def _sanatize_username(username):
|
||||
sanatized = username.replace(" ", "_")
|
||||
sanatized = sanatized.strip(' _')
|
||||
sanatized = sanatized.replace("'", "")
|
||||
return sanatized
|
||||
|
||||
@staticmethod
|
||||
def _sanitize_groupname(name):
|
||||
name = name.strip(' _')
|
||||
return re.sub('[^\w]', '', name)
|
||||
|
||||
@staticmethod
|
||||
def add_user(username, email):
|
||||
logger.debug("Adding new discourse user %s" % username)
|
||||
@@ -306,7 +319,7 @@ class DiscourseManager:
|
||||
return safe_username, password
|
||||
except:
|
||||
logger.exception("Failed to add new discourse user %s" % username)
|
||||
return "",""
|
||||
return "", ""
|
||||
|
||||
@staticmethod
|
||||
def delete_user(username):
|
||||
@@ -323,15 +336,16 @@ class DiscourseManager:
|
||||
def update_groups(username, raw_groups):
|
||||
groups = []
|
||||
for g in raw_groups:
|
||||
groups.append(g[:20])
|
||||
groups.append(DiscourseManager._sanitize_groupname(g[:20]))
|
||||
logger.debug("Updating discourse user %s groups to %s" % (username, groups))
|
||||
group_dict = DiscourseManager.__generate_group_dict(groups)
|
||||
inv_group_dict = {v:k for k,v in group_dict.items()}
|
||||
inv_group_dict = {v: k for k, v in group_dict.items()}
|
||||
user_groups = DiscourseManager.__get_user_groups(username)
|
||||
add_groups = [group_dict[x] for x in group_dict if not group_dict[x] in user_groups]
|
||||
rem_groups = [x for x in user_groups if not inv_group_dict[x] in groups]
|
||||
if add_groups or rem_groups:
|
||||
logger.info("Updating discourse user %s groups: adding %s, removing %s" % (username, add_groups, rem_groups))
|
||||
logger.info(
|
||||
"Updating discourse user %s groups: adding %s, removing %s" % (username, add_groups, rem_groups))
|
||||
for g in add_groups:
|
||||
DiscourseManager.__add_user_to_group(g, username)
|
||||
for g in rem_groups:
|
||||
|
||||
@@ -1,20 +1,48 @@
|
||||
from __future__ import unicode_literals
|
||||
import evelink.api
|
||||
import evelink.char
|
||||
import evelink.eve
|
||||
|
||||
from authentication.states import MEMBER_STATE, BLUE_STATE
|
||||
from authentication.models import AuthServicesInfo
|
||||
from eveonline.models import EveCharacter
|
||||
from django.conf import settings
|
||||
|
||||
import logging
|
||||
|
||||
logger = logging.getLogger(__name__)
|
||||
|
||||
class EveApiManager():
|
||||
|
||||
class EveApiManager:
|
||||
def __init__(self):
|
||||
pass
|
||||
|
||||
class ApiValidationError(Exception):
|
||||
def __init__(self, msg, api_id):
|
||||
self.msg = msg
|
||||
self.api_id = api_id
|
||||
|
||||
def __str__(self):
|
||||
return self.msg
|
||||
|
||||
class ApiMaskValidationError(ApiValidationError):
|
||||
def __init__(self, required_mask, api_mask, api_id):
|
||||
msg = 'Insufficient API mask provided. Required: %s Got: %s' % (required_mask, api_mask)
|
||||
self.required_mask = required_mask
|
||||
self.api_mask = api_mask
|
||||
super(EveApiManager.ApiMaskValidationError, self).__init__(msg, api_id)
|
||||
|
||||
class ApiAccountValidationError(ApiValidationError):
|
||||
def __init__(self, api_id):
|
||||
msg = 'Insufficient API access provided. Full account access is required, got character restricted.'
|
||||
super(EveApiManager.ApiAccountValidationError, self).__init__(msg, api_id)
|
||||
|
||||
class ApiInvalidError(ApiValidationError):
|
||||
def __init__(self, api_id):
|
||||
msg = 'Key is invalid.'
|
||||
super(EveApiManager.ApiInvalidError, self).__init__(msg, api_id)
|
||||
|
||||
@staticmethod
|
||||
def get_characters_from_api(api_id, api_key):
|
||||
chars = []
|
||||
logger.debug("Getting characters from api id %s" % api_id)
|
||||
api = evelink.api.API(api_key=(api_id, api_key))
|
||||
# Should get characters
|
||||
@@ -26,7 +54,6 @@ class EveApiManager():
|
||||
@staticmethod
|
||||
def get_corporation_ticker_from_id(corp_id):
|
||||
logger.debug("Getting ticker for corp id %s" % corp_id)
|
||||
ticker = ""
|
||||
api = evelink.api.API()
|
||||
corp = evelink.corp.Corp(api)
|
||||
response = corp.corporation_sheet(corp_id)
|
||||
@@ -37,7 +64,6 @@ class EveApiManager():
|
||||
|
||||
@staticmethod
|
||||
def get_alliance_information(alliance_id):
|
||||
results = {}
|
||||
logger.debug("Getting info for alliance with id %s" % alliance_id)
|
||||
api = evelink.api.API()
|
||||
eve = evelink.eve.EVE(api=api)
|
||||
@@ -49,7 +75,6 @@ class EveApiManager():
|
||||
@staticmethod
|
||||
def get_corporation_information(corp_id):
|
||||
logger.debug("Getting info for corp with id %s" % corp_id)
|
||||
results = {}
|
||||
api = evelink.api.API()
|
||||
corp = evelink.corp.Corp(api=api)
|
||||
corpinfo = corp.corporation_sheet(corp_id=int(corp_id))
|
||||
@@ -57,6 +82,12 @@ class EveApiManager():
|
||||
logger.debug("Got corp info %s" % results)
|
||||
return results
|
||||
|
||||
@staticmethod
|
||||
def get_api_info(api_id, api_key):
|
||||
api = evelink.api.API(api_key=(api_id, api_key))
|
||||
account = evelink.account.Account(api=api)
|
||||
return account.key_info()[0]
|
||||
|
||||
@staticmethod
|
||||
def check_api_is_type_account(api_id, api_key):
|
||||
logger.debug("Checking if api id %s is account." % api_id)
|
||||
@@ -83,7 +114,7 @@ class EveApiManager():
|
||||
info = account.key_info()
|
||||
logger.debug("API has mask %s, required is %s" % (info[0]['access_mask'], settings.BLUE_API_MASK))
|
||||
return info[0]['access_mask'] & int(settings.BLUE_API_MASK) == int(settings.BLUE_API_MASK)
|
||||
|
||||
|
||||
@staticmethod
|
||||
def get_api_info(api_id, api_key):
|
||||
logger.debug("Getting api info for key id %s" % api_id)
|
||||
@@ -98,7 +129,7 @@ class EveApiManager():
|
||||
logger.debug("Checking if api id %s is valid." % api_id)
|
||||
api = evelink.api.API(api_key=(api_id, api_key))
|
||||
account = evelink.account.Account(api=api)
|
||||
info = account.key_info()
|
||||
account.key_info()
|
||||
logger.info("Verified api id %s is still valid." % api_id)
|
||||
return True
|
||||
|
||||
@@ -108,10 +139,10 @@ class EveApiManager():
|
||||
try:
|
||||
api = evelink.api.API()
|
||||
server = evelink.server.Server(api=api)
|
||||
info = server.server_status()
|
||||
server.server_status()
|
||||
logger.info("Verified API server is online and reachable.")
|
||||
return True
|
||||
except evelink.api.APIError as error:
|
||||
except evelink.api.APIError:
|
||||
logger.exception("APIError occured while trying to query api server. Possibly offline?")
|
||||
|
||||
logger.warn("Unable to reach API server.")
|
||||
@@ -124,7 +155,7 @@ class EveApiManager():
|
||||
api = evelink.api.API()
|
||||
corp = evelink.corp.Corp(api=api)
|
||||
corpinfo = corp.corporation_sheet(corp_id=int(corp_id))
|
||||
results = corpinfo[0]
|
||||
assert corpinfo[0]
|
||||
logger.debug("Confirmed id %s is a corp." % corp_id)
|
||||
return True
|
||||
except evelink.api.APIError as error:
|
||||
@@ -160,11 +191,10 @@ class EveApiManager():
|
||||
results = membertracking.result
|
||||
logger.debug("Got corp membertracking from settings: %s" % results)
|
||||
return results
|
||||
except evelink.api.APIError as error:
|
||||
except evelink.api.APIError:
|
||||
logger.exception("Unhandled APIError occured.")
|
||||
return {}
|
||||
|
||||
|
||||
@staticmethod
|
||||
def check_if_id_is_alliance(alliance_id):
|
||||
logger.debug("Checking if id %s is an alliance." % alliance_id)
|
||||
@@ -176,8 +206,9 @@ class EveApiManager():
|
||||
if results:
|
||||
logger.debug("Confirmed id %s is an alliance." % alliance_id)
|
||||
return True
|
||||
except evelink.api.APIError as error:
|
||||
logger.exception("APIError occured while checking if id %s is an alliance. Possibly not alliance?" % alliance_id)
|
||||
except evelink.api.APIError:
|
||||
logger.exception(
|
||||
"APIError occured while checking if id %s is an alliance. Possibly not alliance?" % alliance_id)
|
||||
except KeyError:
|
||||
logger.debug("Alliance with id %s not found in active alliance list." % alliance_id)
|
||||
return False
|
||||
@@ -194,8 +225,10 @@ class EveApiManager():
|
||||
if results:
|
||||
logger.debug("Confirmed id %s is a character." % character_id)
|
||||
return True
|
||||
except evelink.api.APIError as error:
|
||||
logger.debug("APIError occured while checking if id %s is a character. Possibly not character?" % character_id, exc_info=True)
|
||||
except evelink.api.APIError:
|
||||
logger.debug(
|
||||
"APIError occured while checking if id %s is a character. Possibly not character?" % character_id,
|
||||
exc_info=True)
|
||||
|
||||
logger.debug("Unable to verify id %s is a character." % character_id)
|
||||
return False
|
||||
@@ -213,15 +246,16 @@ class EveApiManager():
|
||||
else:
|
||||
logger.debug("Verified alliance id %s does not exist." % alliance_id)
|
||||
return False
|
||||
except evelink.api.APIError as error:
|
||||
except evelink.api.APIError:
|
||||
logger.exception("Unhandled APIError occured.")
|
||||
return False
|
||||
except ValueError as error:
|
||||
#attempts to catch error resulting from checking alliance_of nonetype models
|
||||
except ValueError:
|
||||
# attempts to catch error resulting from checking alliance_of nonetype models
|
||||
logger.exception("Unhandled ValueError occured. Possible nonetype alliance model.")
|
||||
return False
|
||||
logger.warn("Exception prevented verification of alliance id %s existance. Assuming false." % alliance_id)
|
||||
return False
|
||||
except:
|
||||
logger.warn("Exception prevented verification of alliance id %s existance. Assuming false." % alliance_id)
|
||||
return False
|
||||
|
||||
@staticmethod
|
||||
def check_if_corp_exists(corp_id):
|
||||
@@ -231,17 +265,20 @@ class EveApiManager():
|
||||
corp = evelink.corp.Corp(api=api)
|
||||
corpinfo = corp.corporation_sheet(corp_id=corp_id)
|
||||
if corpinfo[0]['members']['current'] > 0:
|
||||
logger.debug("Verified corp id %s exists with member count %s" % (corp_id, corpinfo[0]['members']['current']))
|
||||
logger.debug(
|
||||
"Verified corp id %s exists with member count %s" % (corp_id, corpinfo[0]['members']['current']))
|
||||
return True
|
||||
else:
|
||||
logger.debug("Verified corp id %s has closed. Member count %s" % (corp_id, corpinfo[0]['members']['current']))
|
||||
logger.debug(
|
||||
"Verified corp id %s has closed. Member count %s" % (corp_id, corpinfo[0]['members']['current']))
|
||||
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
|
||||
except evelink.api.APIError:
|
||||
# could be smart and check for error code523 to verify error due to no corp instead of catch-all
|
||||
logger.exception("Unhandled APIError occured.")
|
||||
return False
|
||||
logger.warn("Exception prevented verification of corp id %s existance. Assuming false." % corp_id)
|
||||
return False
|
||||
except:
|
||||
logger.warn("Exception prevented verification of corp id %s existance. Assuming false." % corp_id)
|
||||
return False
|
||||
|
||||
@staticmethod
|
||||
def validate_member_api(api_id, api_key):
|
||||
@@ -249,7 +286,7 @@ class EveApiManager():
|
||||
if EveApiManager.check_api_is_type_account(api_id, api_key) is False:
|
||||
logger.info("Api id %s is not type account as required for members - failed validation." % api_id)
|
||||
return False
|
||||
|
||||
|
||||
if EveApiManager.check_api_is_full(api_id, api_key) is False:
|
||||
logger.info("Api id %s does not meet member access mask requirements - failed validation." % api_id)
|
||||
return False
|
||||
@@ -265,3 +302,40 @@ class EveApiManager():
|
||||
logger.info("Api id %s does not meet minimum blue access mask requirements - failed validation." % api_id)
|
||||
return False
|
||||
return True
|
||||
|
||||
@staticmethod
|
||||
def validate_api(api_id, api_key, user):
|
||||
try:
|
||||
info = EveApiManager.get_api_info(api_id, api_key).result
|
||||
chars = EveApiManager.get_characters_from_api(api_id, api_key).result
|
||||
except evelink.api.APIError as e:
|
||||
if int(e.code) in [221, 222]:
|
||||
raise e
|
||||
raise EveApiManager.ApiInvalidError(api_id)
|
||||
except Exception:
|
||||
raise EveApiManager.ApiInvalidError(api_id)
|
||||
auth, c = AuthServicesInfo.objects.get_or_create(user=user)
|
||||
states = [auth.state]
|
||||
from authentication.tasks import determine_membership_by_character # circular import issue
|
||||
for char in chars:
|
||||
evechar = EveCharacter()
|
||||
evechar.character_name = chars[char]['name']
|
||||
evechar.corporation_id = chars[char]['corp']['id']
|
||||
evechar.alliance_id = chars[char]['alliance']['id']
|
||||
states.append(determine_membership_by_character(evechar))
|
||||
if MEMBER_STATE not in states and BLUE_STATE not in states:
|
||||
# default to requiring member keys for applications
|
||||
states.append(MEMBER_STATE)
|
||||
logger.debug('Checking API %s for states %s' % (api_id, states))
|
||||
for state in states:
|
||||
if (state == MEMBER_STATE and settings.MEMBER_API_ACCOUNT) or (
|
||||
state == BLUE_STATE and settings.BLUE_API_ACCOUNT):
|
||||
if info['type'] != 'account':
|
||||
raise EveApiManager.ApiAccountValidationError(api_id)
|
||||
if state == MEMBER_STATE:
|
||||
if int(info['access_mask']) & int(settings.MEMBER_API_MASK) != int(settings.MEMBER_API_MASK):
|
||||
raise EveApiManager.ApiMaskValidationError(settings.MEMBER_API_MASK, info['access_mask'], api_id)
|
||||
elif state == BLUE_STATE:
|
||||
if int(info['access_mask']) & int(settings.BLUE_API_MASK) != int(settings.BLUE_API_MASK):
|
||||
raise EveApiManager.ApiMaskValidationError(settings.BLUE_API_MASK, info['access_mask'], api_id)
|
||||
return True
|
||||
|
||||
@@ -1,13 +1,9 @@
|
||||
from django.conf import settings
|
||||
|
||||
import logging
|
||||
from __future__ import unicode_literals
|
||||
import requests
|
||||
#import requests_cache
|
||||
import json
|
||||
|
||||
#requests_cache.install_cache("{}/evewho".format(settings.EVEWHO_CACHE_DIR), backend="sqlite", expire_after=3600)
|
||||
|
||||
class EveWhoManager():
|
||||
class EveWhoManager:
|
||||
def __init__(self):
|
||||
pass
|
||||
|
||||
@@ -18,11 +14,11 @@ class EveWhoManager():
|
||||
data = json.loads(jsondata.decode())
|
||||
|
||||
members = {}
|
||||
page_count=0
|
||||
page_count = 0
|
||||
while len(data["characters"]):
|
||||
for row in data["characters"]:
|
||||
members[int(row["character_id"])] = {"name":row["name"], "id":int(row["character_id"])}
|
||||
page_count=page_count+1
|
||||
members[int(row["character_id"])] = {"name": row["name"], "id": int(row["character_id"])}
|
||||
page_count += 1
|
||||
jsondata = requests.get(url + "&page=%i" % page_count).content
|
||||
data = json.loads(jsondata.decode())
|
||||
|
||||
|
||||
@@ -1,5 +1,5 @@
|
||||
from __future__ import unicode_literals
|
||||
from django.conf import settings
|
||||
from django.http import HttpResponse
|
||||
from datetime import datetime
|
||||
|
||||
import logging
|
||||
@@ -13,43 +13,45 @@ userid = settings.FLEETUP_USER_ID
|
||||
apiid = settings.FLEETUP_API_ID
|
||||
groupid = settings.FLEETUP_GROUP_ID
|
||||
|
||||
class FleetUpManager():
|
||||
|
||||
class FleetUpManager:
|
||||
def __init__(self):
|
||||
pass
|
||||
|
||||
@staticmethod
|
||||
def get_fleetup_members():
|
||||
url = "http://api.fleet-up.com/Api.svc/" + str(appkey) + "/" + str(userid) + "/" + str(apiid) + "/GroupCharacters/" + str(groupid) + ""
|
||||
url = "http://api.fleet-up.com/Api.svc/" + str(appkey) + "/" + str(userid) + "/" + str(
|
||||
apiid) + "/GroupCharacters/" + str(groupid) + ""
|
||||
try:
|
||||
jsondata = requests.get(url).content
|
||||
fmembers=json.loads(jsondata.decode())
|
||||
return {row["UserId"]:{"user_id":row["UserId"],
|
||||
"char_name":row["EveCharName"],
|
||||
"char_id":row["EveCharId"],
|
||||
"corporation":row["Corporation"]} for row in fmembers["Data"]}
|
||||
fmembers = json.loads(jsondata.decode())
|
||||
return {row["UserId"]: {"user_id": row["UserId"],
|
||||
"char_name": row["EveCharName"],
|
||||
"char_id": row["EveCharId"],
|
||||
"corporation": row["Corporation"]} for row in fmembers["Data"]}
|
||||
except requests.exceptions.ConnectionError:
|
||||
logger.warn("Can't connect to Fleet-Up API, is it offline?!")
|
||||
except (ValueError, UnicodeDecodeError):
|
||||
logger.debug("No fleetup members retrieved.")
|
||||
return {}
|
||||
|
||||
|
||||
@staticmethod
|
||||
def get_fleetup_operations():
|
||||
url = "http://api.fleet-up.com/Api.svc/" + str(appkey) + "/" + str(userid) + "/" + str(apiid) + "/Operations/" + str(groupid) + ""
|
||||
url = "http://api.fleet-up.com/Api.svc/" + str(appkey) + "/" + str(userid) + "/" + str(
|
||||
apiid) + "/Operations/" + str(groupid) + ""
|
||||
try:
|
||||
jsondata = requests.get(url).content
|
||||
foperations=json.loads(jsondata.decode())
|
||||
return {row["StartString"]:{"subject":row["Subject"],
|
||||
"start": (datetime.strptime(row["StartString"], "%Y-%m-%d %H:%M:%S")),
|
||||
"end": (datetime.strptime(row["EndString"], "%Y-%m-%d %H:%M:%S")),
|
||||
"operation_id":row["OperationId"],
|
||||
"location":row["Location"],
|
||||
"location_info":row["LocationInfo"],
|
||||
"details":row["Details"],
|
||||
"url":row["Url"],
|
||||
"doctrine":row["Doctrines"],
|
||||
"organizer":row["Organizer"]} for row in foperations["Data"]}
|
||||
foperations = json.loads(jsondata.decode())
|
||||
return {row["StartString"]: {"subject": row["Subject"],
|
||||
"start": (datetime.strptime(row["StartString"], "%Y-%m-%d %H:%M:%S")),
|
||||
"end": (datetime.strptime(row["EndString"], "%Y-%m-%d %H:%M:%S")),
|
||||
"operation_id": row["OperationId"],
|
||||
"location": row["Location"],
|
||||
"location_info": row["LocationInfo"],
|
||||
"details": row["Details"],
|
||||
"url": row["Url"],
|
||||
"doctrine": row["Doctrines"],
|
||||
"organizer": row["Organizer"]} for row in foperations["Data"]}
|
||||
except requests.exceptions.ConnectionError:
|
||||
logger.warn("Can't connect to Fleet-Up API, is it offline?!")
|
||||
except (ValueError, UnicodeDecodeError):
|
||||
@@ -58,18 +60,19 @@ class FleetUpManager():
|
||||
|
||||
@staticmethod
|
||||
def get_fleetup_timers():
|
||||
url = "http://api.fleet-up.com/Api.svc/" + str(appkey) + "/" + str(userid) + "/" + str(apiid) + "/Timers/" + str(groupid) + ""
|
||||
url = "http://api.fleet-up.com/Api.svc/" + str(appkey) + "/" + str(userid) + "/" + str(
|
||||
apiid) + "/Timers/" + str(groupid) + ""
|
||||
try:
|
||||
jsondata = requests.get(url).content
|
||||
ftimers=json.loads(jsondata.decode())
|
||||
return {row["ExpiresString"]:{"solarsystem":row["SolarSystem"],
|
||||
"planet":row["Planet"],
|
||||
"moon":row["Moon"],
|
||||
"owner":row["Owner"],
|
||||
"type":row["Type"],
|
||||
"timer_type":row["TimerType"],
|
||||
"expires": (datetime.strptime(row["ExpiresString"], "%Y-%m-%d %H:%M:%S")),
|
||||
"notes":row["Notes"]} for row in ftimers["Data"]}
|
||||
ftimers = json.loads(jsondata.decode())
|
||||
return {row["ExpiresString"]: {"solarsystem": row["SolarSystem"],
|
||||
"planet": row["Planet"],
|
||||
"moon": row["Moon"],
|
||||
"owner": row["Owner"],
|
||||
"type": row["Type"],
|
||||
"timer_type": row["TimerType"],
|
||||
"expires": (datetime.strptime(row["ExpiresString"], "%Y-%m-%d %H:%M:%S")),
|
||||
"notes": row["Notes"]} for row in ftimers["Data"]}
|
||||
except requests.exceptions.ConnectionError:
|
||||
logger.warn("Can't connect to Fleet-Up API, is it offline?!")
|
||||
except (ValueError, UnicodeDecodeError):
|
||||
@@ -78,45 +81,50 @@ class FleetUpManager():
|
||||
|
||||
@staticmethod
|
||||
def get_fleetup_doctrines():
|
||||
url = "http://api.fleet-up.com/Api.svc/" + str(appkey) + "/" + str(userid) + "/" + str(apiid) + "/Doctrines/" + str(groupid) + ""
|
||||
url = "http://api.fleet-up.com/Api.svc/" + str(appkey) + "/" + str(userid) + "/" + str(
|
||||
apiid) + "/Doctrines/" + str(groupid) + ""
|
||||
try:
|
||||
jsondata = requests.get(url).content
|
||||
fdoctrines=json.loads(jsondata.decode())
|
||||
return {"fleetup_doctrines":fdoctrines["Data"]}
|
||||
fdoctrines = json.loads(jsondata.decode())
|
||||
return {"fleetup_doctrines": fdoctrines["Data"]}
|
||||
except requests.exceptions.ConnectionError:
|
||||
logger.warn("Can't connect to Fleet-Up API, is it offline?!")
|
||||
except (ValueError, UnicodeDecodeError):
|
||||
logger.debug("No fleetup doctrines retrieved.")
|
||||
return {"fleetup_doctrines":[]}
|
||||
return {"fleetup_doctrines": []}
|
||||
|
||||
@staticmethod
|
||||
def get_fleetup_doctrine(doctrinenumber):
|
||||
url = "http://api.fleet-up.com/Api.svc/" + str(appkey) + "/" + str(userid) + "/" + str(apiid) + "/DoctrineFittings/%s" % doctrinenumber
|
||||
url = "http://api.fleet-up.com/Api.svc/" + str(appkey) + "/" + str(userid) + "/" + str(
|
||||
apiid) + "/DoctrineFittings/%s" % doctrinenumber
|
||||
try:
|
||||
jsondata = requests.get(url).content
|
||||
fdoctrine=json.loads(jsondata.decode())
|
||||
return {"fitting_doctrine":fdoctrine}
|
||||
fdoctrine = json.loads(jsondata.decode())
|
||||
return {"fitting_doctrine": fdoctrine}
|
||||
except requests.exceptions.ConnectionError:
|
||||
logger.warn("Can't connect to Fleet-Up API, is it offline?!")
|
||||
except (ValueError, UnicodeDecodeError):
|
||||
logger.warn("Fleetup doctrine number %s not found" % doctrinenumber)
|
||||
return {"fitting_doctrine":{}}
|
||||
return {"fitting_doctrine": {}}
|
||||
|
||||
@staticmethod
|
||||
def get_fleetup_fittings():
|
||||
url = "http://api.fleet-up.com/Api.svc/" + str(appkey) + "/" + str(userid) + "/" + str(apiid) + "/Fittings/" + str(groupid) + ""
|
||||
url = "http://api.fleet-up.com/Api.svc/" + str(appkey) + "/" + str(userid) + "/" + str(
|
||||
apiid) + "/Fittings/" + str(groupid) + ""
|
||||
try:
|
||||
jsondata = requests.get(url).content
|
||||
ffittings=json.loads(jsondata.decode())
|
||||
return {row["FittingId"]:{"fitting_id":row["FittingId"],
|
||||
"name":row["Name"],
|
||||
"icon_id":row["EveTypeId"],
|
||||
"hull":row["HullType"],
|
||||
"shiptype":row["ShipType"],
|
||||
"estimated":row["EstPrice"],
|
||||
"faction":row["Faction"],
|
||||
"categories":row["Categories"],
|
||||
"last_update":(datetime.strptime(row["LastUpdatedString"], "%Y-%m-%d %H:%M:%S"))} for row in ffittings["Data"]}
|
||||
ffittings = json.loads(jsondata.decode())
|
||||
return {row["FittingId"]: {"fitting_id": row["FittingId"],
|
||||
"name": row["Name"],
|
||||
"icon_id": row["EveTypeId"],
|
||||
"hull": row["HullType"],
|
||||
"shiptype": row["ShipType"],
|
||||
"estimated": row["EstPrice"],
|
||||
"faction": row["Faction"],
|
||||
"categories": row["Categories"],
|
||||
"last_update": (
|
||||
datetime.strptime(row["LastUpdatedString"], "%Y-%m-%d %H:%M:%S"))} for row in
|
||||
ffittings["Data"]}
|
||||
except requests.exceptions.ConnectionError:
|
||||
logger.warn("Can't connect to Fleet-Up API, is it offline?!")
|
||||
except (ValueError, UnicodeDecodeError):
|
||||
@@ -125,25 +133,27 @@ class FleetUpManager():
|
||||
|
||||
@staticmethod
|
||||
def get_fleetup_fitting(fittingnumber):
|
||||
url = "http://api.fleet-up.com/Api.svc/" + str(appkey) + "/" + str(userid) + "/" + str(apiid) + "/Fitting/%s" % fittingnumber
|
||||
url = "http://api.fleet-up.com/Api.svc/" + str(appkey) + "/" + str(userid) + "/" + str(
|
||||
apiid) + "/Fitting/%s" % fittingnumber
|
||||
try:
|
||||
jsondata = requests.get(url).content
|
||||
ffitting=json.loads(jsondata.decode())
|
||||
return {"fitting_data":ffitting["Data"]}
|
||||
ffitting = json.loads(jsondata.decode())
|
||||
return {"fitting_data": ffitting["Data"]}
|
||||
except requests.exceptions.ConnectionError:
|
||||
logger.warn("Can't connect to Fleet-Up API, is it offline?!")
|
||||
except (ValueError, UnicodeDecodeError):
|
||||
logger.warn("Fleetup fitting number %s not found" % fittingnumber)
|
||||
except KeyError:
|
||||
logger.warn("Failed to retrieve fleetup fitting number %s" % fittingnumber)
|
||||
return {"fitting_data":{}}
|
||||
return {"fitting_data": {}}
|
||||
|
||||
@staticmethod
|
||||
def get_fleetup_doctrineid(fittingnumber):
|
||||
url = "http://api.fleet-up.com/Api.svc/" + str(appkey) + "/" + str(userid) + "/" + str(apiid) + "/Fitting/%s" % fittingnumber
|
||||
url = "http://api.fleet-up.com/Api.svc/" + str(appkey) + "/" + str(userid) + "/" + str(
|
||||
apiid) + "/Fitting/%s" % fittingnumber
|
||||
try:
|
||||
jsondata = requests.get(url).content
|
||||
fdoctrineid=json.loads(jsondata.decode())
|
||||
fdoctrineid = json.loads(jsondata.decode())
|
||||
return fdoctrineid['Data']['Doctrines'][0]['DoctrineId']
|
||||
except requests.exceptions.ConnectionError:
|
||||
logger.warn("Can't connect to Fleet-Up API, is it offline?!")
|
||||
@@ -155,13 +165,14 @@ class FleetUpManager():
|
||||
|
||||
@staticmethod
|
||||
def get_fleetup_fitting_eft(fittingnumber):
|
||||
url = "http://api.fleet-up.com/Api.svc/" + str(appkey) + "/" + str(userid) + "/" + str(apiid) + "/Fitting/%s/eft" % fittingnumber
|
||||
url = "http://api.fleet-up.com/Api.svc/" + str(appkey) + "/" + str(userid) + "/" + str(
|
||||
apiid) + "/Fitting/%s/eft" % fittingnumber
|
||||
try:
|
||||
jsondata = requests.get(url).content
|
||||
ffittingeft=json.loads(jsondata.decode())
|
||||
return {"fitting_eft":ffittingeft["Data"]["FittingData"]}
|
||||
ffittingeft = json.loads(jsondata.decode())
|
||||
return {"fitting_eft": ffittingeft["Data"]["FittingData"]}
|
||||
except requests.exceptions.ConnectionError:
|
||||
logger.warn("Can't connect to Fleet-Up API, is it offline?!")
|
||||
except (ValueError, UnicodeDecodeError):
|
||||
logger.warn("Fleetup fitting eft not found for fitting number %s" % fittingnumber)
|
||||
return {"fitting_eft":{}}
|
||||
return {"fitting_eft": {}}
|
||||
|
||||
@@ -1,6 +1,13 @@
|
||||
from __future__ import unicode_literals
|
||||
import os
|
||||
import xmlrpclib
|
||||
import re
|
||||
from hashlib import md5
|
||||
try:
|
||||
from xmlrpclib import Server
|
||||
except ImportError:
|
||||
# python 3
|
||||
from xmlrpc import server as Server
|
||||
|
||||
|
||||
from django.conf import settings
|
||||
|
||||
@@ -8,6 +15,7 @@ import logging
|
||||
|
||||
logger = logging.getLogger(__name__)
|
||||
|
||||
|
||||
class IPBoardManager:
|
||||
def __init__(self):
|
||||
pass
|
||||
@@ -21,17 +29,21 @@ class IPBoardManager:
|
||||
def __generate_random_pass():
|
||||
return os.urandom(8).encode('hex')
|
||||
|
||||
@staticmethod
|
||||
def _sanitize_groupname(name):
|
||||
name = name.strip(' _')
|
||||
return re.sub('[^\w.-]', '', name)
|
||||
|
||||
@staticmethod
|
||||
def exec_xmlrpc(func, **kwargs):
|
||||
""" Send a XMLRPC request """
|
||||
try:
|
||||
server = xmlrpclib.Server(settings.IPBOARD_ENDPOINT, verbose=False)
|
||||
server = Server(settings.IPBOARD_ENDPOINT, verbose=False)
|
||||
params = {}
|
||||
for i in kwargs:
|
||||
params[i] = kwargs[i]
|
||||
params['api_key'] = settings.IPBOARD_APIKEY
|
||||
params['api_module'] = settings.IPBOARD_APIMODULE
|
||||
print params
|
||||
|
||||
return getattr(server, func)(params)
|
||||
except:
|
||||
@@ -44,22 +56,22 @@ class IPBoardManager:
|
||||
logger.debug("Adding user to IPBoard with username %s" % sanatized)
|
||||
plain_password = IPBoardManager.__generate_random_pass()
|
||||
password = md5(plain_password).hexdigest()
|
||||
ret = IPBoardManager.exec_xmlrpc('createUser', username=sanatized, email=str(email), display_name=sanatized,
|
||||
md5_passwordHash=password)
|
||||
IPBoardManager.exec_xmlrpc('createUser', username=sanatized, email=str(email), display_name=sanatized,
|
||||
md5_passwordHash=password)
|
||||
logger.info("Added IPBoard user with username %s" % sanatized)
|
||||
return sanatized, plain_password
|
||||
|
||||
@staticmethod
|
||||
def delete_user(username):
|
||||
""" Delete user """
|
||||
ret = IPBoardManager.exec_xmlrpc('deleteUser', username=username)
|
||||
IPBoardManager.exec_xmlrpc('deleteUser', username=username)
|
||||
logger.info("Deleted IPBoard user with username %s" % username)
|
||||
return username
|
||||
|
||||
@staticmethod
|
||||
def disable_user(username):
|
||||
""" Disable user """
|
||||
ret = IPBoardManager.exec_xmlrpc('disableUser', username=username)
|
||||
IPBoardManager.exec_xmlrpc('disableUser', username=username)
|
||||
logger.info("Disabled IPBoard user with username %s" % username)
|
||||
return username
|
||||
|
||||
@@ -67,8 +79,9 @@ class IPBoardManager:
|
||||
def update_user(username, email, password):
|
||||
""" Add user to service """
|
||||
password = md5(password).hexdigest()
|
||||
logger.debug("Updating IPBoard username %s with email %s and password hash starting with %s" % (username, email, password[0:5]))
|
||||
ret = IPBoardManager.exec_xmlrpc('updateUser', username=username, email=email, md5_passwordHash=password)
|
||||
logger.debug("Updating IPBoard username %s with email %s and password hash starting with %s" % (
|
||||
username, email, password[0:5]))
|
||||
IPBoardManager.exec_xmlrpc('updateUser', username=username, email=email, md5_passwordHash=password)
|
||||
logger.info("Updated IPBoard user with username %s" % username)
|
||||
return username
|
||||
|
||||
@@ -111,7 +124,6 @@ class IPBoardManager:
|
||||
|
||||
@staticmethod
|
||||
def help_me():
|
||||
"Random help me"
|
||||
ret = IPBoardManager.exec_xmlrpc('helpMe')
|
||||
return ret
|
||||
|
||||
@@ -120,13 +132,13 @@ class IPBoardManager:
|
||||
logger.debug("Updating IPBoard user %s with groups %s" % (username, groups))
|
||||
forum_groups = IPBoardManager.get_all_groups()
|
||||
user_groups = set(IPBoardManager.get_user_groups(username))
|
||||
act_groups = set([g.replace(' ', '-') for g in groups])
|
||||
act_groups = set([IPBoardManager._sanitize_groupname(g) for g in groups])
|
||||
addgroups = act_groups - user_groups
|
||||
remgroups = user_groups - act_groups
|
||||
|
||||
logger.info("Updating IPBoard groups for user %s - adding %s, removing %s" % (username, addgroups, remgroups))
|
||||
for g in addgroups:
|
||||
if not g in forum_groups:
|
||||
if g not in forum_groups:
|
||||
IPBoardManager.add_group(g)
|
||||
logger.debug("Adding user %s to IPBoard group %s" % (username, g))
|
||||
IPBoardManager.add_user_to_group(username, g)
|
||||
|
||||
@@ -1,27 +1,21 @@
|
||||
from __future__ import unicode_literals
|
||||
import logging
|
||||
from django.conf import settings
|
||||
import requests
|
||||
import os
|
||||
from django.db import connections
|
||||
from passlib.hash import bcrypt
|
||||
from django.utils import timezone
|
||||
|
||||
|
||||
logger = logging.getLogger(__name__)
|
||||
|
||||
class Ips4Manager:
|
||||
|
||||
class Ips4Manager:
|
||||
SQL_ADD_USER = r"INSERT INTO core_members (name, email, members_pass_hash, members_pass_salt, " \
|
||||
r"member_group_id) VALUES (%s, %s, %s, %s, %s)"
|
||||
SQL_GET_ID = r"SELECT member_id FROM core_members WHERE name = %s"
|
||||
SQL_UPDATE_PASSWORD = r"UPDATE core_members SET members_pass_hash = %s, members_pass_salt = %s WHERE name = %s"
|
||||
SQL_DEL_USER = r"DELETE FROM core_members WHERE member_id = %s"
|
||||
|
||||
|
||||
|
||||
MEMBER_GROUP_ID = 3
|
||||
|
||||
|
||||
@staticmethod
|
||||
def add_user(username, email):
|
||||
logger.debug("Adding new IPS4 user %s" % username)
|
||||
@@ -30,7 +24,6 @@ class Ips4Manager:
|
||||
hash_result = hash
|
||||
rounds_striped = hash_result.strip('$2a$13$')
|
||||
salt = rounds_striped[:22]
|
||||
joined_date = timezone.now
|
||||
group = Ips4Manager.MEMBER_GROUP_ID
|
||||
cursor = connections['ips4'].cursor()
|
||||
cursor.execute(Ips4Manager.SQL_ADD_USER, [username, email, hash, salt, group])
|
||||
@@ -53,7 +46,6 @@ class Ips4Manager:
|
||||
def __generate_random_pass():
|
||||
return os.urandom(8).encode('hex')
|
||||
|
||||
|
||||
@staticmethod
|
||||
def delete_user(id):
|
||||
logger.debug("Deleting IPS4 user id %s" % id)
|
||||
@@ -107,4 +99,4 @@ class Ips4Manager:
|
||||
return plain_password
|
||||
else:
|
||||
logger.error("Unable to update ips4 user %s password" % username)
|
||||
return ""
|
||||
return ""
|
||||
|
||||
@@ -1,18 +1,21 @@
|
||||
from __future__ import unicode_literals
|
||||
import logging
|
||||
from django.conf import settings
|
||||
import requests
|
||||
import os
|
||||
|
||||
from django.db import connections
|
||||
from passlib.hash import bcrypt
|
||||
## requires yum install libffi-devel and pip install bcrypt
|
||||
|
||||
# requires yum install libffi-devel and pip install bcrypt
|
||||
|
||||
logger = logging.getLogger(__name__)
|
||||
|
||||
class marketManager:
|
||||
|
||||
SQL_ADD_USER = r"INSERT INTO fos_user (username, username_canonical, email, email_canonical, enabled, salt, password," \
|
||||
r"locked, expired, roles, credentials_expired, characterid, characterName)" \
|
||||
class marketManager:
|
||||
def __init__(self):
|
||||
pass
|
||||
|
||||
SQL_ADD_USER = r"INSERT INTO fos_user (username, username_canonical, email, email_canonical, enabled, salt," \
|
||||
r"password, locked, expired, roles, credentials_expired, characterid, characterName)" \
|
||||
r"VALUES (%s, %s, %s, %s, 1,%s, %s, 0, 0, 'a:0:{}', 0, %s, %s) "
|
||||
SQL_GET_USER_ID = r"SELECT id FROM fos_user WHERE username = %s"
|
||||
SQL_DISABLE_USER = r"UPDATE fos_user SET enabled = '0' WHERE username = %s"
|
||||
@@ -22,7 +25,6 @@ class marketManager:
|
||||
SQL_CHECK_USERNAME = r"SELECT username FROM fos_user WHERE username = %s"
|
||||
SQL_UPDATE_USER = r"UPDATE fos_user SET password = %s, salt = %s, enabled = '1' WHERE username = %s"
|
||||
|
||||
|
||||
@staticmethod
|
||||
def __santatize_username(username):
|
||||
sanatized = username.replace(" ", "_")
|
||||
@@ -56,7 +58,6 @@ class marketManager:
|
||||
logger.debug("User %s email address not found on alliance market" % username)
|
||||
return False
|
||||
|
||||
|
||||
@staticmethod
|
||||
def add_user(username, email, characterid, charactername):
|
||||
logger.debug("Adding new market user %s" % username)
|
||||
@@ -66,8 +67,8 @@ class marketManager:
|
||||
rounds_striped = hash_result.strip('$2a$13$')
|
||||
salt = rounds_striped[:22]
|
||||
username_clean = marketManager.__santatize_username(username)
|
||||
if marketManager.check_username(username)== False:
|
||||
if marketManager.check_user_email(username, email) == False:
|
||||
if not marketManager.check_username(username):
|
||||
if not marketManager.check_user_email(username, email):
|
||||
try:
|
||||
logger.debug("Adding user %s to alliance market" % username)
|
||||
cursor = connections['market'].cursor()
|
||||
|
||||
@@ -1,10 +1,6 @@
|
||||
from __future__ import unicode_literals
|
||||
import os
|
||||
import hashlib
|
||||
import sys
|
||||
|
||||
import django
|
||||
from django.db import connections
|
||||
from django.conf import settings
|
||||
|
||||
from services.models import MumbleUser
|
||||
|
||||
@@ -12,7 +8,10 @@ import logging
|
||||
|
||||
logger = logging.getLogger(__name__)
|
||||
|
||||
|
||||
class MumbleManager:
|
||||
def __init__(self):
|
||||
pass
|
||||
|
||||
@staticmethod
|
||||
def __santatize_username(username):
|
||||
@@ -41,10 +40,11 @@ class MumbleManager:
|
||||
username_clean = MumbleManager.__santatize_username(MumbleManager.__generate_username(username, corp_ticker))
|
||||
password = MumbleManager.__generate_random_pass()
|
||||
pwhash = MumbleManager._gen_pwhash(password)
|
||||
logger.debug("Proceeding with mumble user creation: clean username %s, pwhash starts with %s" % (username_clean, pwhash[0:5]))
|
||||
logger.debug("Proceeding with mumble user creation: clean username %s, pwhash starts with %s" % (
|
||||
username_clean, pwhash[0:5]))
|
||||
if MumbleUser.objects.filter(username=username_clean).exists() is False:
|
||||
logger.info("Creating mumble user %s" % username_clean)
|
||||
model = MumbleUser.objects.create(username=username_clean, pwhash=pwhash)
|
||||
MumbleUser.objects.create(username=username_clean, pwhash=pwhash)
|
||||
return username_clean, password
|
||||
else:
|
||||
logger.warn("Mumble user %s already exists. Updating password")
|
||||
@@ -57,13 +57,15 @@ class MumbleManager:
|
||||
@staticmethod
|
||||
def create_blue_user(corp_ticker, username):
|
||||
logger.debug("Creating mumble blue user with username %s and ticker %s" % (username, corp_ticker))
|
||||
username_clean = MumbleManager.__santatize_username(MumbleManager.__generate_username_blue(username, corp_ticker))
|
||||
username_clean = MumbleManager.__santatize_username(
|
||||
MumbleManager.__generate_username_blue(username, corp_ticker))
|
||||
password = MumbleManager.__generate_random_pass()
|
||||
pwhash = MumbleManager._gen_pwhash(password)
|
||||
logger.debug("Proceeding with mumble user creation: clean username %s, pwhash starts with %s" % (username_clean, pwhash[0:5]))
|
||||
logger.debug("Proceeding with mumble user creation: clean username %s, pwhash starts with %s" % (
|
||||
username_clean, pwhash[0:5]))
|
||||
if MumbleUser.objects.filter(username=username_clean).exists() is False:
|
||||
logger.info("Creating mumble user %s" % username_clean)
|
||||
model = MumbleUser.objects.create(username=username_clean, pwhash=pwhash)
|
||||
MumbleUser.objects.create(username=username_clean, pwhash=pwhash)
|
||||
return username_clean, password
|
||||
else:
|
||||
logger.warn("Mumble user %s already exists. Updating password")
|
||||
@@ -102,7 +104,7 @@ class MumbleManager:
|
||||
def update_groups(username, groups):
|
||||
logger.debug("Updating mumble user %s groups %s" % (username, groups))
|
||||
safe_groups = list(set([g.replace(' ', '-') for g in groups]))
|
||||
groups =''
|
||||
groups = ''
|
||||
for g in safe_groups:
|
||||
groups = groups + g + ','
|
||||
groups = groups.strip(',')
|
||||
|
||||
@@ -1,9 +1,14 @@
|
||||
from __future__ import unicode_literals
|
||||
from django.utils import six
|
||||
import re
|
||||
import os
|
||||
from urlparse import urlparse
|
||||
try:
|
||||
from urlparse import urlparse
|
||||
except ImportError:
|
||||
# python 3
|
||||
from urllib.parse import urlparse
|
||||
|
||||
import xmpp
|
||||
from django.contrib.auth.models import User
|
||||
from django.contrib.auth.models import Group
|
||||
import sleekxmpp
|
||||
from django.conf import settings
|
||||
import threading
|
||||
from ofrestapi.users import Users as ofUsers
|
||||
@@ -13,6 +18,7 @@ import logging
|
||||
|
||||
logger = logging.getLogger(__name__)
|
||||
|
||||
|
||||
class OpenfireManager:
|
||||
def __init__(self):
|
||||
pass
|
||||
@@ -38,6 +44,11 @@ class OpenfireManager:
|
||||
def __generate_random_pass():
|
||||
return os.urandom(8).encode('hex')
|
||||
|
||||
@staticmethod
|
||||
def _sanitize_groupname(name):
|
||||
name = name.strip(' _')
|
||||
return re.sub('[^\w.-]', '', name)
|
||||
|
||||
@staticmethod
|
||||
def add_user(username):
|
||||
logger.debug("Adding username %s to openfire." % username)
|
||||
@@ -95,30 +106,33 @@ class OpenfireManager:
|
||||
return ""
|
||||
|
||||
@staticmethod
|
||||
def update_user_groups(username, password, groups):
|
||||
def update_user_groups(username, groups):
|
||||
logger.debug("Updating openfire user %s groups %s" % (username, groups))
|
||||
api = ofUsers(settings.OPENFIRE_ADDRESS, settings.OPENFIRE_SECRET_KEY)
|
||||
response = api.get_user_groups(username)
|
||||
remote_groups = []
|
||||
if response:
|
||||
remote_groups = response['groupname']
|
||||
if isinstance(remote_groups, basestring):
|
||||
if isinstance(remote_groups, six.string_types):
|
||||
remote_groups = [remote_groups]
|
||||
logger.debug("Openfire user %s has groups %s" % (username, remote_groups))
|
||||
add_groups = []
|
||||
del_groups = []
|
||||
for g in groups:
|
||||
if not g in remote_groups:
|
||||
g = OpenfireManager._sanitize_groupname(g)
|
||||
if g not in remote_groups:
|
||||
add_groups.append(g)
|
||||
for g in remote_groups:
|
||||
if not g in groups:
|
||||
g = OpenfireManager._sanitize_groupname(g)
|
||||
if g not in groups:
|
||||
del_groups.append(g)
|
||||
logger.info("Updating openfire groups for user %s - adding %s, removing %s" % (username, add_groups, del_groups))
|
||||
logger.info(
|
||||
"Updating openfire groups for user %s - adding %s, removing %s" % (username, add_groups, del_groups))
|
||||
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):
|
||||
logger.debug("Deleting openfire groups %s from user %s" % (groups, username))
|
||||
@@ -129,30 +143,58 @@ class OpenfireManager:
|
||||
@staticmethod
|
||||
def send_broadcast_message(group_name, broadcast_message):
|
||||
logger.debug("Sending jabber ping to group %s with message %s" % (group_name, broadcast_message))
|
||||
# create to address
|
||||
client = xmpp.Client(settings.JABBER_URL)
|
||||
client.connect(server=(settings.JABBER_SERVER, settings.JABBER_PORT))
|
||||
client.auth(settings.BROADCAST_USER, settings.BROADCAST_USER_PASSWORD, 'broadcast')
|
||||
|
||||
to_address = group_name + '@' + settings.BROADCAST_SERVICE_NAME + '.' + settings.JABBER_URL
|
||||
logger.debug("Determined ping to address: %s" % to_address)
|
||||
message = xmpp.Message(to_address, broadcast_message)
|
||||
message.setAttr('type', 'chat')
|
||||
client.send(message)
|
||||
client.Process(1)
|
||||
xmpp = PingBot(settings.BROADCAST_USER, settings.BROADCAST_USER_PASSWORD, to_address, broadcast_message)
|
||||
xmpp.register_plugin('xep_0030') # Service Discovery
|
||||
xmpp.register_plugin('xep_0199') # XMPP Ping
|
||||
if xmpp.connect():
|
||||
xmpp.process(block=True)
|
||||
logger.info("Sent jabber ping to group %s" % group_name)
|
||||
else:
|
||||
raise ValueError("Unable to connect to jabber server.")
|
||||
|
||||
client.disconnect()
|
||||
logger.info("Sent jabber ping to group %s" % group_name)
|
||||
|
||||
class XmppThread (threading.Thread):
|
||||
def __init__(self, threadID, name, counter, group, message,):
|
||||
class PingBot(sleekxmpp.ClientXMPP):
|
||||
"""
|
||||
A copy-paste of the example client bot from
|
||||
http://sleekxmpp.com/getting_started/sendlogout.html
|
||||
"""
|
||||
def __init__(self, jid, password, recipient, message):
|
||||
sleekxmpp.ClientXMPP.__init__(self, jid, password)
|
||||
|
||||
# The message we wish to send, and the JID that
|
||||
# will receive it.
|
||||
self.recipient = recipient
|
||||
self.msg = message
|
||||
|
||||
# The session_start event will be triggered when
|
||||
# the bot establishes its connection with the server
|
||||
# and the XML streams are ready for use. We want to
|
||||
# listen for this event so that we we can initialize
|
||||
# our roster.
|
||||
self.add_event_handler("session_start", self.start)
|
||||
|
||||
def start(self, event):
|
||||
self.send_presence()
|
||||
self.get_roster()
|
||||
|
||||
self.send_message(mto=self.recipient,
|
||||
mbody=self.msg,
|
||||
mtype='chat')
|
||||
|
||||
# Using wait=True ensures that the send queue will be
|
||||
# emptied before ending the session.
|
||||
self.disconnect(wait=True)
|
||||
|
||||
|
||||
class XmppThread(threading.Thread):
|
||||
def __init__(self, thread_id, name, counter, group, message, ):
|
||||
threading.Thread.__init__(self)
|
||||
self.threadID = threadID
|
||||
self.threadID = thread_id
|
||||
self.name = name
|
||||
self.counter = counter
|
||||
self.group = group
|
||||
self.message = message
|
||||
|
||||
def run(self):
|
||||
print "Starting " + self.name
|
||||
OpenfireManager.send_broadcast_message(self.group, self.message)
|
||||
print "Exiting " + self.name
|
||||
|
||||
@@ -1,196 +0,0 @@
|
||||
import logging
|
||||
from django.conf import settings
|
||||
import requests
|
||||
import os
|
||||
from django.db import connections
|
||||
from passlib.hash import bcrypt
|
||||
from eveonline.managers import EveManager
|
||||
from authentication.managers import AuthServicesInfo
|
||||
from eveonline.models import EveCharacter
|
||||
from eveonline.models import EveApiKeyPair
|
||||
|
||||
logger = logging.getLogger(__name__)
|
||||
|
||||
class pathfinderManager:
|
||||
|
||||
SQL_ADD_USER = r"INSERT INTO user (name, email, password, active) VALUES (%s, %s, %s, %s)"
|
||||
SQL_ADD_API = r"INSERT INTO user_api (userid, keyid, vCode, active) VALUES (%s, %s, %s, %s)"
|
||||
SQL_ADD_CHARACTER = r"INSERT INTO user_character (userid, apiId, characterId, isMain) VALUES (%s, %s, %s, %s)"
|
||||
SQL_GET_APIID = r"SELECT id, keyId FROM user_api WHERE userId = %s"
|
||||
SQL_GET_USERID = r"SELECT id FROM user WHERE name = %s"
|
||||
SQL_DISABLE_USER = r"UPDATE user SET active = '0' WHERE name = %s"
|
||||
SQL_UPDATE_USER = r"UPDATE user SET active = '1', password = %s WHERE name = %s"
|
||||
SQL_CHECK_USER = r"SELECT name FROM user WHERE name = %s"
|
||||
SQL_CHECK_EMAIL = r"SELECT email from user WHERE email = %s"
|
||||
SQL_SET_MAIN = r"UPDATE user_character SET isMain = 1 WHERE characterId = %s"
|
||||
|
||||
|
||||
@staticmethod
|
||||
def __santatize_username(username):
|
||||
sanatized = username.replace(" ", "_")
|
||||
return sanatized.lower()
|
||||
|
||||
@staticmethod
|
||||
def __generate_random_pass():
|
||||
return os.urandom(8).encode('hex')
|
||||
|
||||
@staticmethod
|
||||
def check_username(username):
|
||||
logger.debug("Checking for pathfinder username %s" % username)
|
||||
cursor = connections['pathfinder'].cursor()
|
||||
cursor.execute(pathfinderManager.SQL_CHECK_USER, [pathfinderManager.__santatize_username(username)])
|
||||
row = cursor.fetchone()
|
||||
if row:
|
||||
logger.debug("Found user %s on pathfinder" % username)
|
||||
return True
|
||||
logger.debug("User %s not found on pathfinder" % username)
|
||||
return False
|
||||
|
||||
@staticmethod
|
||||
def update_user_info(username):
|
||||
logger.debug("Updating pathfinder user %s" % username)
|
||||
try:
|
||||
username_clean = pathfinderManager.__santatize_username(username)
|
||||
plain_password = pathfinderManager.__generate_random_pass()
|
||||
passwd = bcrypt.encrypt(plain_password, rounds=10)
|
||||
cursor = connections['pathfinder'].cursor()
|
||||
cursor.execute(pathfinderManager.SQL_UPDATE_USER, [passwd, username_clean])
|
||||
return username_clean, plain_password
|
||||
except:
|
||||
logger.debug("Pathfinder update user failed for %s" % username)
|
||||
return "", ""
|
||||
|
||||
@staticmethod
|
||||
def update_custom_password(username, plain_password):
|
||||
logger.debug("Updating pathfinder user id %s password" % username)
|
||||
if pathfinderManager.check_username(username):
|
||||
username_clean = pathfinderManager.__santatize_username(username)
|
||||
passwd = bcrypt.encrypt(plain_password, rounds=10)
|
||||
cursor = connections['pathfinder'].cursor()
|
||||
cursor.execute(pathfinderManager.SQL_UPDATE_USER, [passwd, username_clean])
|
||||
return plain_password
|
||||
else:
|
||||
logger.error("Unable to update ips4 user %s password" % username)
|
||||
return ""
|
||||
|
||||
@staticmethod
|
||||
def disable_user(username):
|
||||
logger.debug("Disabling user %s" % username)
|
||||
if pathfinderManager.check_username(username) == True:
|
||||
try:
|
||||
cursor = connections['pathfinder'].cursor()
|
||||
cursor.execute(pathfinderManager.SQL_DISABLE_USER, [pathfinderManager.__santatize_username(username)])
|
||||
return True
|
||||
except:
|
||||
logger.debug("User %s not found cannot disable" % username)
|
||||
|
||||
|
||||
|
||||
@staticmethod
|
||||
def add_user(username, email, charactername):
|
||||
logger.debug("Adding new pathfinder user %s" % username)
|
||||
plain_password = pathfinderManager.__generate_random_pass()
|
||||
passwd = bcrypt.encrypt(plain_password, rounds=10)
|
||||
username_clean = pathfinderManager.__santatize_username(username)
|
||||
auth_id = pathfinderManager.get_authid_by_username(charactername)
|
||||
|
||||
if pathfinderManager.check_username(username)== False:
|
||||
if pathfinderManager.check_email(username, email) == False:
|
||||
try:
|
||||
logger.debug("Adding user %s to pathfinder" % username)
|
||||
cursor = connections['pathfinder'].cursor()
|
||||
cursor.execute(pathfinderManager.SQL_ADD_USER, [username_clean,email, passwd, '1'])
|
||||
path_id = pathfinderManager.get_pathfinder_user_id(username_clean)
|
||||
api_keys = pathfinderManager.get_api_key_pairs(auth_id)
|
||||
main_character = AuthServicesInfo.objects.get(user=auth_id).main_char_id
|
||||
|
||||
for keyId, key in api_keys.items():
|
||||
cursor.execute(pathfinderManager.SQL_ADD_API, [path_id, keyId, key, '1'])
|
||||
|
||||
char_apis = pathfinderManager.get_char_id(auth_id)
|
||||
|
||||
for c,a in char_apis.items():
|
||||
cursor.execute(pathfinderManager.SQL_ADD_CHARACTER, [path_id, (pathfinderManager.get_pathfinder_api_id(username, path_id)), c, '0'])
|
||||
|
||||
pathfinderManager.set_main_char(username, main_character)
|
||||
return username_clean, plain_password
|
||||
|
||||
except:
|
||||
logger.exception("Unsuccessful attempt at adding user %s to pathfinder on add_user" % username)
|
||||
return "",""
|
||||
else:
|
||||
logger.debug("pathfinder username %s already exists Updating instead" % username)
|
||||
username_clean, password = pathfinderManager.update_user_info(username)
|
||||
return username_clean, password
|
||||
else:
|
||||
logger.debug("pathfinder username %s already exists Updating instead" % username)
|
||||
username_clean, password = pathfinderManager.update_user_info(username)
|
||||
return username_clean, password
|
||||
|
||||
@staticmethod
|
||||
def set_main_char (username, main_character):
|
||||
try:
|
||||
cursor = connections['pathfinder'].cursor()
|
||||
cursor.execute(pathfinderManager.SQL_SET_MAIN, [main_character])
|
||||
except:
|
||||
logger.debug("Failed setting main character for user %s"% username)
|
||||
return ""
|
||||
|
||||
@staticmethod
|
||||
def get_api_key_pairs(user_id):
|
||||
char = EveCharacter.objects.all().filter(user_id=user_id)
|
||||
api_list = dict()
|
||||
for c in char:
|
||||
api_pair = EveApiKeyPair.objects.get(api_id=c.api_id)
|
||||
api_list[api_pair.api_id] = api_pair.api_key
|
||||
return api_list
|
||||
|
||||
@staticmethod
|
||||
def get_char_id(auth_id):
|
||||
char = EveCharacter.objects.all().filter(user_id=auth_id)
|
||||
char_list = dict()
|
||||
for c in char:
|
||||
char_list[c.character_id] = c.api_id
|
||||
logger.debug("printing char list %s" % char_list)
|
||||
return char_list
|
||||
|
||||
@staticmethod
|
||||
def get_authid_by_username(username):
|
||||
authid = EveCharacter.objects.get(character_name=username).user_id
|
||||
return authid
|
||||
|
||||
@staticmethod
|
||||
def get_pathfinder_user_id(username):
|
||||
cursor = connections['pathfinder'].cursor()
|
||||
cursor.execute(pathfinderManager.SQL_GET_USERID, [username])
|
||||
row = cursor.fetchone()
|
||||
if row:
|
||||
logger.debug("Pathfinder ID for user %s is %s" % (username, row[0]))
|
||||
return int(row[0])
|
||||
else:
|
||||
logger.debug("failed to get pathfinder ID for user %s" % username)
|
||||
return ""
|
||||
|
||||
@staticmethod
|
||||
def get_pathfinder_api_id(username, path_id):
|
||||
cursor = connections['pathfinder'].cursor()
|
||||
cursor.execute(pathfinderManager.SQL_GET_APIID, [path_id])
|
||||
row = cursor.fetchone()
|
||||
if row:
|
||||
logger.debug("Pathfinder API ID for user %s is %s" % (username, row[0]))
|
||||
return int(row[0])
|
||||
else:
|
||||
logger.debug("failed to get pathfinder API ID for user %s" % username)
|
||||
return ""
|
||||
|
||||
@staticmethod
|
||||
def check_email(username, email):
|
||||
logger.debug("Checking if email %s exists for username %s" % (email,username))
|
||||
cursor = connections['pathfinder'].cursor()
|
||||
cursor.execute(pathfinderManager.SQL_CHECK_EMAIL, [email])
|
||||
row = cursor.fetchone()
|
||||
if row:
|
||||
logger.debug("Found user %s email on pathfinder" % username)
|
||||
return True
|
||||
logger.debug("User %s email not found on pathfinder" % username)
|
||||
return False
|
||||
@@ -1,5 +1,7 @@
|
||||
from __future__ import unicode_literals
|
||||
import os
|
||||
import calendar
|
||||
import re
|
||||
from datetime import datetime
|
||||
|
||||
from passlib.apps import phpbb3_context
|
||||
@@ -11,6 +13,7 @@ from django.conf import settings
|
||||
|
||||
logger = logging.getLogger(__name__)
|
||||
|
||||
|
||||
class Phpbb3Manager:
|
||||
SQL_ADD_USER = r"INSERT INTO phpbb_users (username, username_clean, " \
|
||||
r"user_password, user_email, group_id, user_regdate, user_permissions, " \
|
||||
@@ -37,8 +40,9 @@ 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"
|
||||
|
||||
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"
|
||||
|
||||
SQL_CLEAR_USER_PERMISSIONS = r"UPDATE phpbb_users SET user_permissions = '' WHERE user_Id = %s"
|
||||
|
||||
SQL_DEL_SESSION = r"DELETE FROM phpbb_sessions where session_user_id = %s"
|
||||
@@ -70,6 +74,11 @@ class Phpbb3Manager:
|
||||
sanatized = sanatized.replace("'", "_")
|
||||
return sanatized.lower()
|
||||
|
||||
@staticmethod
|
||||
def _sanitize_groupname(name):
|
||||
name = name.strip(' _')
|
||||
return re.sub('[^\w.-]', '', name)
|
||||
|
||||
@staticmethod
|
||||
def __get_group_id(groupname):
|
||||
logger.debug("Getting phpbb3 group id for groupname %s" % groupname)
|
||||
@@ -153,7 +162,8 @@ class Phpbb3Manager:
|
||||
|
||||
@staticmethod
|
||||
def add_user(username, email, groups, characterid):
|
||||
logger.debug("Adding phpbb user with username %s, email %s, groups %s, characterid %s" % (username, email, groups, characterid))
|
||||
logger.debug("Adding phpbb user with username %s, email %s, groups %s, characterid %s" % (
|
||||
username, email, groups, characterid))
|
||||
cursor = connections['phpbb3'].cursor()
|
||||
|
||||
username_clean = Phpbb3Manager.__santatize_username(username)
|
||||
@@ -195,7 +205,7 @@ class Phpbb3Manager:
|
||||
Phpbb3Manager.update_groups(username, [])
|
||||
logger.info("Disabled phpbb user %s" % username)
|
||||
return True
|
||||
except TypeError as e:
|
||||
except TypeError:
|
||||
logger.exception("TypeError occured while disabling user %s - failed to disable." % username)
|
||||
return False
|
||||
|
||||
@@ -218,7 +228,7 @@ class Phpbb3Manager:
|
||||
if userid is not None:
|
||||
forum_groups = Phpbb3Manager.__get_all_groups()
|
||||
user_groups = set(Phpbb3Manager.__get_user_groups(userid))
|
||||
act_groups = set([g.replace(' ', '-') for g in groups])
|
||||
act_groups = set([Phpbb3Manager._sanitize_groupname(g) for g in groups])
|
||||
addgroups = act_groups - user_groups
|
||||
remgroups = user_groups - act_groups
|
||||
logger.info("Updating phpbb user %s groups - adding %s, removing %s" % (username, addgroups, remgroups))
|
||||
@@ -244,7 +254,9 @@ class Phpbb3Manager:
|
||||
cursor.execute(Phpbb3Manager.SQL_REMOVE_USER_GROUP, [userid, groupid])
|
||||
logger.info("Removed phpbb user %s from group %s" % (username, group))
|
||||
except:
|
||||
logger.exception("Exception prevented removal of phpbb user %s with id %s from group %s with id %s" % (username, userid, group, groupid))
|
||||
logger.exception(
|
||||
"Exception prevented removal of phpbb user %s with id %s from group %s with id %s" % (
|
||||
username, userid, group, groupid))
|
||||
pass
|
||||
|
||||
@staticmethod
|
||||
@@ -267,7 +279,8 @@ class Phpbb3Manager:
|
||||
password = Phpbb3Manager.__generate_random_pass()
|
||||
if Phpbb3Manager.check_user(username):
|
||||
pwhash = Phpbb3Manager.__gen_hash(password)
|
||||
logger.debug("Proceeding to update phpbb user %s password with pwhash starting with %s" % (username, pwhash[0:5]))
|
||||
logger.debug(
|
||||
"Proceeding to update phpbb user %s password with pwhash starting with %s" % (username, pwhash[0:5]))
|
||||
cursor.execute(Phpbb3Manager.SQL_UPDATE_USER_PASSWORD, [pwhash, username])
|
||||
Phpbb3Manager.__add_avatar(username, characterid)
|
||||
logger.info("Updated phpbb user %s password." % username)
|
||||
@@ -277,7 +290,8 @@ class Phpbb3Manager:
|
||||
|
||||
@staticmethod
|
||||
def __update_user_info(username, email, password):
|
||||
logger.debug("Updating phpbb user %s info: username %s password of length %s" % (username, email, len(password)))
|
||||
logger.debug(
|
||||
"Updating phpbb user %s info: username %s password of length %s" % (username, email, len(password)))
|
||||
cursor = connections['phpbb3'].cursor()
|
||||
try:
|
||||
cursor.execute(Phpbb3Manager.SQL_DIS_USER, [email, password, username])
|
||||
|
||||
@@ -1,15 +1,21 @@
|
||||
from __future__ import unicode_literals
|
||||
import os
|
||||
import calendar
|
||||
from datetime import datetime
|
||||
import hashlib
|
||||
import logging
|
||||
import re
|
||||
|
||||
from django.db import connections
|
||||
from django.conf import settings
|
||||
|
||||
logger = logging.getLogger(__name__)
|
||||
|
||||
|
||||
class smfManager:
|
||||
def __init__(self):
|
||||
pass
|
||||
|
||||
SQL_ADD_USER = r"INSERT INTO smf_members (member_name, passwd, email_address, date_registered, real_name," \
|
||||
r" buddy_list, message_labels, openid_uri, signature, ignore_boards) " \
|
||||
r"VALUES (%s, %s, %s, %s, %s, 0, 0, 0, 0, 0)"
|
||||
@@ -36,7 +42,10 @@ class smfManager:
|
||||
|
||||
SQL_ADD_USER_AVATAR = r"UPDATE smf_members SET avatar = %s WHERE id_member = %s"
|
||||
|
||||
|
||||
@staticmethod
|
||||
def _sanitize_groupname(name):
|
||||
name = name.strip(' _')
|
||||
return re.sub('[^\w.-]', '', name)
|
||||
|
||||
@staticmethod
|
||||
def generate_random_pass():
|
||||
@@ -44,7 +53,7 @@ class smfManager:
|
||||
|
||||
@staticmethod
|
||||
def gen_hash(username_clean, passwd):
|
||||
return hashlib.sha1((username_clean) + passwd).hexdigest()
|
||||
return hashlib.sha1(username_clean + passwd).hexdigest()
|
||||
|
||||
@staticmethod
|
||||
def santatize_username(username):
|
||||
@@ -66,7 +75,6 @@ class smfManager:
|
||||
logger.info("Created smf group %s" % groupname)
|
||||
return smfManager.get_group_id(groupname)
|
||||
|
||||
|
||||
@staticmethod
|
||||
def get_group_id(groupname):
|
||||
logger.debug("Getting smf group id for groupname %s" % groupname)
|
||||
@@ -88,7 +96,6 @@ class smfManager:
|
||||
logger.debug("User %s not found on smf" % username)
|
||||
return False
|
||||
|
||||
|
||||
@staticmethod
|
||||
def add_avatar(member_name, characterid):
|
||||
logger.debug("Adding EVE character id %s portrait as smf avatar for user %s" % (characterid, member_name))
|
||||
@@ -133,7 +140,8 @@ class smfManager:
|
||||
|
||||
@staticmethod
|
||||
def add_user(username, email_address, groups, characterid):
|
||||
logger.debug("Adding smf user with member_name %s, email_address %s, characterid %s" % (username, email_address, characterid))
|
||||
logger.debug("Adding smf user with member_name %s, email_address %s, characterid %s" % (
|
||||
username, email_address, characterid))
|
||||
cursor = connections['smf'].cursor()
|
||||
username_clean = smfManager.santatize_username(username)
|
||||
passwd = smfManager.generate_random_pass()
|
||||
@@ -141,12 +149,13 @@ class smfManager:
|
||||
logger.debug("Proceeding to add smf user %s and pwhash starting with %s" % (username, pwhash[0:5]))
|
||||
register_date = smfManager.get_current_utc_date()
|
||||
# check if the username was simply revoked
|
||||
if smfManager.check_user(username)is True :
|
||||
if smfManager.check_user(username) is True:
|
||||
logger.warn("Unable to add smf user with username %s - already exists. Updating user instead." % username)
|
||||
smfManager.__update_user_info(username_clean, email_address, pwhash)
|
||||
else:
|
||||
try:
|
||||
cursor.execute(smfManager.SQL_ADD_USER, [username_clean, passwd, email_address, register_date, username_clean])
|
||||
cursor.execute(smfManager.SQL_ADD_USER,
|
||||
[username_clean, passwd, email_address, register_date, username_clean])
|
||||
smfManager.add_avatar(username_clean, characterid)
|
||||
logger.info("Added smf member_name %s" % username_clean)
|
||||
smfManager.update_groups(username_clean, groups)
|
||||
@@ -157,7 +166,8 @@ class smfManager:
|
||||
|
||||
@staticmethod
|
||||
def __update_user_info(username, email_address, passwd):
|
||||
logger.debug("Updating smf user %s info: username %s password of length %s" % (username, email_address, len(passwd)))
|
||||
logger.debug(
|
||||
"Updating smf user %s info: username %s password of length %s" % (username, email_address, len(passwd)))
|
||||
cursor = connections['smf'].cursor()
|
||||
try:
|
||||
cursor.execute(smfManager.SQL_DIS_USER, [email_address, passwd, username])
|
||||
@@ -185,19 +195,18 @@ class smfManager:
|
||||
if userid is not None:
|
||||
forum_groups = smfManager.get_all_groups()
|
||||
user_groups = set(smfManager.get_user_groups(userid))
|
||||
act_groups = set([g.replace(' ', '-') for g in groups])
|
||||
act_groups = set([smfManager._sanitize_groupname(g) for g in groups])
|
||||
addgroups = act_groups - user_groups
|
||||
remgroups = user_groups - act_groups
|
||||
logger.info("Updating smf user %s groups - adding %s, removing %s" % (username, addgroups, remgroups))
|
||||
act_group_id = set()
|
||||
for g in addgroups:
|
||||
if not g in forum_groups:
|
||||
if g not in forum_groups:
|
||||
forum_groups[g] = smfManager.create_group(g)
|
||||
act_group_id.add(str(smfManager.get_group_id(g)))
|
||||
string_groups = ','.join(act_group_id)
|
||||
smfManager.add_user_to_group(userid, string_groups)
|
||||
|
||||
|
||||
@staticmethod
|
||||
def add_user_to_group(userid, groupid):
|
||||
logger.debug("Adding smf user id %s to group id %s" % (userid, groupid))
|
||||
@@ -230,11 +239,11 @@ class smfManager:
|
||||
try:
|
||||
pwhash = smfManager.gen_hash(username, password)
|
||||
cursor.execute(smfManager.SQL_DIS_USER, [revoke_email, pwhash, username])
|
||||
userid = smfManager.get_user_id(username)
|
||||
smfManager.get_user_id(username)
|
||||
smfManager.update_groups(username, [])
|
||||
logger.info("Disabled smf user %s" % username)
|
||||
return True
|
||||
except TypeError as e:
|
||||
except TypeError:
|
||||
logger.exception("TypeError occured while disabling user %s - failed to disable." % username)
|
||||
return False
|
||||
|
||||
@@ -247,14 +256,11 @@ class smfManager:
|
||||
if smfManager.check_user(username):
|
||||
username_clean = smfManager.santatize_username(username)
|
||||
pwhash = smfManager.gen_hash(username_clean, password)
|
||||
logger.debug("Proceeding to update smf user %s password with pwhash starting with %s" % (username, pwhash[0:5]))
|
||||
logger.debug(
|
||||
"Proceeding to update smf user %s password with pwhash starting with %s" % (username, pwhash[0:5]))
|
||||
cursor.execute(smfManager.SQL_UPDATE_USER_PASSWORD, [pwhash, username])
|
||||
smfManager.add_avatar(username, characterid)
|
||||
logger.info("Updated smf user %s password." % username)
|
||||
return password
|
||||
logger.error("Unable to update smf user %s password - user not found on smf." % username)
|
||||
return ""
|
||||
|
||||
|
||||
|
||||
|
||||
|
||||
@@ -1,46 +1,49 @@
|
||||
from __future__ import unicode_literals
|
||||
from django.conf import settings
|
||||
|
||||
|
||||
import json
|
||||
import urllib2
|
||||
import requests
|
||||
import logging
|
||||
|
||||
|
||||
logger = logging.getLogger(__name__)
|
||||
|
||||
class srpManager():
|
||||
|
||||
class srpManager:
|
||||
def __init__(self):
|
||||
pass
|
||||
|
||||
@staticmethod
|
||||
def get_kill_id (killboard_link):
|
||||
str = (killboard_link)
|
||||
set = '0123456789'
|
||||
kill_id = ''.join([c for c in str if c in set])
|
||||
def get_kill_id(killboard_link):
|
||||
num_set = '0123456789'
|
||||
kill_id = ''.join([c for c in killboard_link if c in num_set])
|
||||
return kill_id
|
||||
|
||||
@staticmethod
|
||||
def get_kill_data (kill_id):
|
||||
def get_kill_data(kill_id):
|
||||
url = ("https://www.zkillboard.com/api/killID/%s" % kill_id)
|
||||
request = urllib2.Request(url)
|
||||
request.add_header('User-Agent',"%s Alliance Auth" % settings.DOMAIN)
|
||||
request.add_header('Content-Type','application/json')
|
||||
response = urllib2.urlopen(request)
|
||||
result = json.load(response)[0]
|
||||
headers = {
|
||||
'User-Agent': "%s Alliance Auth" % settings.DOMAIN,
|
||||
'Content-Type': 'application/json',
|
||||
}
|
||||
r = requests.get(url, headers=headers)
|
||||
result = r.json()[0]
|
||||
if result:
|
||||
ship_type = result['victim']['shipTypeID']
|
||||
logger.debug("Ship type for kill ID %s is determined to be %s" % (kill_id, ship_type))
|
||||
ship_value = result['zkb']['totalValue']
|
||||
logger.debug("total loss value for kill id %s is %s" %(kill_id, ship_value))
|
||||
return (ship_type, ship_value)
|
||||
logger.debug("total loss value for kill id %s is %s" % (kill_id, ship_value))
|
||||
return ship_type, ship_value
|
||||
else:
|
||||
raise ValueError("Invalid Kill ID")
|
||||
|
||||
@staticmethod
|
||||
def get_ship_name (ship_type):
|
||||
def get_ship_name(ship_type):
|
||||
url = ("https://jetbalsa.com/api/json.php/invTypes/%s" % ship_type)
|
||||
request = urllib2.Request(url)
|
||||
request.add_header('User-Agent',"%s Alliance Auth" % settings.DOMAIN)
|
||||
request.add_header('Content-Type','application/json')
|
||||
response = urllib2.urlopen(request)
|
||||
result = json.load(response)
|
||||
headers = {
|
||||
'User-Agent': "%s Alliance Auth" % settings.DOMAIN,
|
||||
'Content-Type': 'application/json',
|
||||
}
|
||||
r = requests.get(url, headers=headers)
|
||||
result = r.json()
|
||||
if result:
|
||||
ship_name = result['typeName']
|
||||
logger.debug("ship type %s determined to be %s" % (ship_type, ship_name))
|
||||
@@ -48,13 +51,3 @@ class srpManager():
|
||||
else:
|
||||
logger.debug("ship type %s is invalid" % ship_type)
|
||||
raise ValueError("Cannot get ship name")
|
||||
|
||||
|
||||
|
||||
|
||||
|
||||
|
||||
|
||||
|
||||
|
||||
|
||||
|
||||
@@ -1,11 +1,13 @@
|
||||
from __future__ import unicode_literals
|
||||
from django.conf import settings
|
||||
|
||||
from services.managers.util.ts3 import TS3Server
|
||||
from services.managers.util.ts3 import TS3Server, TeamspeakError
|
||||
from services.models import TSgroup
|
||||
import logging
|
||||
|
||||
logger = logging.getLogger(__name__)
|
||||
|
||||
|
||||
class Teamspeak3Manager:
|
||||
def __init__(self):
|
||||
pass
|
||||
@@ -117,10 +119,9 @@ class Teamspeak3Manager:
|
||||
def _add_user_to_group(uid, groupid):
|
||||
logger.debug("Adding group id %s to TS3 user id %s" % (groupid, uid))
|
||||
server = Teamspeak3Manager.__get_created_server()
|
||||
server_groups = Teamspeak3Manager._group_list()
|
||||
user_groups = Teamspeak3Manager._user_group_list(uid)
|
||||
|
||||
if not groupid in user_groups.values():
|
||||
|
||||
if groupid not in user_groups.values():
|
||||
logger.debug("User does not have group already. Issuing command to add.")
|
||||
server.send_command('servergroupaddclient',
|
||||
{'sgid': str(groupid), 'cldbid': uid})
|
||||
@@ -130,7 +131,6 @@ class Teamspeak3Manager:
|
||||
def _remove_user_from_group(uid, groupid):
|
||||
logger.debug("Removing group id %s from TS3 user id %s" % (groupid, uid))
|
||||
server = Teamspeak3Manager.__get_created_server()
|
||||
server_groups = Teamspeak3Manager._group_list()
|
||||
user_groups = Teamspeak3Manager._user_group_list(uid)
|
||||
|
||||
if str(groupid) in user_groups.values():
|
||||
@@ -149,39 +149,45 @@ class Teamspeak3Manager:
|
||||
for key in remote_groups:
|
||||
logger.debug("Typecasting remote_group value at position %s to int: %s" % (key, remote_groups[key]))
|
||||
remote_groups[key] = int(remote_groups[key])
|
||||
|
||||
|
||||
for group in local_groups:
|
||||
logger.debug("Checking local group %s" % group)
|
||||
if group.ts_group_id not in remote_groups.values():
|
||||
logger.debug("Local group id %s not found on server. Deleting model %s" % (group.ts_group_id, group))
|
||||
logger.debug(
|
||||
"Local group id %s not found on server. Deleting model %s" % (group.ts_group_id, group))
|
||||
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)
|
||||
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:
|
||||
logger.debug("Local group does not exist for TS group %s. Creating TSgroup model %s" % (remote_groups[key], g))
|
||||
logger.debug("Local group does not exist for TS group %s. Creating TSgroup model %s" % (
|
||||
remote_groups[key], g))
|
||||
g.save()
|
||||
except TeamspeakError as e:
|
||||
logger.error("Error occured while syncing TS group db: %s" % str(e))
|
||||
except:
|
||||
logger.exception("An unhandled exception has occured while syncing TS groups.")
|
||||
pass
|
||||
|
||||
@staticmethod
|
||||
def add_user(username, corp_ticker):
|
||||
username_clean = Teamspeak3Manager.__santatize_username(Teamspeak3Manager.__generate_username(username,
|
||||
corp_ticker))
|
||||
corp_ticker))
|
||||
server = Teamspeak3Manager.__get_created_server()
|
||||
token = ""
|
||||
logger.debug("Adding user to TS3 server with cleaned username %s" % username_clean)
|
||||
server_groups = Teamspeak3Manager._group_list()
|
||||
|
||||
if not settings.DEFAULT_AUTH_GROUP in server_groups:
|
||||
if settings.DEFAULT_AUTH_GROUP not in server_groups:
|
||||
Teamspeak3Manager._create_group(settings.DEFAULT_AUTH_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,
|
||||
'tokencustomset': "ident=sso_uid value=%s" % username_clean})
|
||||
try:
|
||||
ret = server.send_command('tokenadd', {'tokentype': 0, 'tokenid1': alliance_group_id, 'tokenid2': 0,
|
||||
'tokendescription': username_clean,
|
||||
'tokencustomset': "ident=sso_uid value=%s" % username_clean})
|
||||
except TeamspeakError as e:
|
||||
logger.error("Failed to add teamspeak user %s: %s" % (username, str(e)))
|
||||
return "",""
|
||||
|
||||
try:
|
||||
token = ret['keys']['token']
|
||||
@@ -189,24 +195,27 @@ class Teamspeak3Manager:
|
||||
return username_clean, token
|
||||
except:
|
||||
logger.exception("Failed to add teamspeak user %s - received response: %s" % (username_clean, ret))
|
||||
return "",""
|
||||
return "", ""
|
||||
|
||||
@staticmethod
|
||||
def add_blue_user(username, corp_ticker):
|
||||
username_clean = Teamspeak3Manager.__santatize_username(Teamspeak3Manager.__generate_username_blue(username,
|
||||
corp_ticker))
|
||||
corp_ticker))
|
||||
server = Teamspeak3Manager.__get_created_server()
|
||||
token = ""
|
||||
logger.debug("Adding user to TS3 server with cleaned username %s" % username_clean)
|
||||
server_groups = Teamspeak3Manager._group_list()
|
||||
if not settings.DEFAULT_BLUE_GROUP in server_groups:
|
||||
if settings.DEFAULT_BLUE_GROUP not in server_groups:
|
||||
Teamspeak3Manager._create_group(settings.DEFAULT_BLUE_GROUP)
|
||||
|
||||
blue_group_id = Teamspeak3Manager._group_id_by_name(settings.DEFAULT_BLUE_GROUP)
|
||||
|
||||
ret = server.send_command('tokenadd', {'tokentype': 0, 'tokenid1': blue_group_id, 'tokenid2': 0,
|
||||
'tokendescription': username_clean,
|
||||
'tokencustomset': "ident=sso_uid value=%s" % username_clean})
|
||||
try:
|
||||
ret = server.send_command('tokenadd', {'tokentype': 0, 'tokenid1': blue_group_id, 'tokenid2': 0,
|
||||
'tokendescription': username_clean,
|
||||
'tokencustomset': "ident=sso_uid value=%s" % username_clean})
|
||||
except TeamspeakError as e:
|
||||
logger.error("Failed to add blue teamspeak user %s: %s" % (username, str(e)))
|
||||
return "",""
|
||||
|
||||
try:
|
||||
token = ret['keys']['token']
|
||||
@@ -214,10 +223,7 @@ class Teamspeak3Manager:
|
||||
return username_clean, token
|
||||
except:
|
||||
logger.exception("Failed to add blue teamspeak user %s - received response: %s" % (username_clean, ret))
|
||||
return "",""
|
||||
|
||||
|
||||
|
||||
return "", ""
|
||||
|
||||
@staticmethod
|
||||
def delete_user(uid):
|
||||
@@ -235,7 +241,12 @@ class Teamspeak3Manager:
|
||||
logger.exception("Failed to delete user id %s from TS3 - received response %s" % (uid, client))
|
||||
return False
|
||||
|
||||
ret = server.send_command('clientdbdelete', {'cldbid': user})
|
||||
try:
|
||||
ret = server.send_command('clientdbdelete', {'cldbid': user})
|
||||
except TeamspeakError as e:
|
||||
logger.error("Failed to delete teamspeak user %s: %s" % (uid, str(e)))
|
||||
return False
|
||||
|
||||
if ret == '0':
|
||||
logger.info("Deleted user with id %s from TS3 server." % uid)
|
||||
return True
|
||||
@@ -291,4 +302,3 @@ class Teamspeak3Manager:
|
||||
for g in remgroups:
|
||||
logger.info("Removing Teamspeak user %s from group %s" % (userid, g))
|
||||
Teamspeak3Manager._remove_user_from_group(userid, g)
|
||||
|
||||
|
||||
@@ -1 +1,2 @@
|
||||
from __future__ import unicode_literals
|
||||
__author__ = 'r4stl1n'
|
||||
|
||||
@@ -1,8 +1,9 @@
|
||||
from __future__ import unicode_literals
|
||||
import socket
|
||||
import logging
|
||||
|
||||
|
||||
class ConnectionError():
|
||||
class ConnectionError:
|
||||
def __init__(self, ip, port):
|
||||
self.ip = ip
|
||||
self.port = port
|
||||
@@ -22,8 +23,7 @@ ts3_escape = {'/': r"\/",
|
||||
"\t": r'\t',
|
||||
"\v": r'\v'}
|
||||
|
||||
|
||||
class TS3Proto():
|
||||
class TS3Proto:
|
||||
bytesin = 0
|
||||
bytesout = 0
|
||||
|
||||
@@ -66,7 +66,7 @@ class TS3Proto():
|
||||
while True:
|
||||
resp = self._sockfile.readline()
|
||||
resp = self.parse_command(resp)
|
||||
if not 'command' in resp:
|
||||
if 'command' not in resp:
|
||||
data.append(resp)
|
||||
else:
|
||||
break
|
||||
@@ -78,7 +78,7 @@ class TS3Proto():
|
||||
else:
|
||||
return data[0]
|
||||
else:
|
||||
return resp['keys']['id']
|
||||
raise TeamspeakError(resp['keys']['id'])
|
||||
|
||||
def construct_command(self, command, keys=None, opts=None):
|
||||
"""
|
||||
@@ -139,7 +139,7 @@ class TS3Proto():
|
||||
v = [v[0], '='.join(v[1:])]
|
||||
key, value = v
|
||||
keys[key] = self._unescape_str(value)
|
||||
elif (not v == ['']):
|
||||
elif not v == ['']:
|
||||
if v[0][0] and v[0][0] == '-':
|
||||
# Option
|
||||
opts.append(v[0][1:])
|
||||
@@ -159,9 +159,10 @@ class TS3Proto():
|
||||
@type value: string/int
|
||||
"""
|
||||
|
||||
if isinstance(value, int): return "%d" % value
|
||||
if isinstance(value, int):
|
||||
return "%d" % value
|
||||
value = value.replace("\\", r'\\')
|
||||
for i, j in ts3_escape.iteritems():
|
||||
for i, j in ts3_escape:
|
||||
value = value.replace(i, j)
|
||||
return value
|
||||
|
||||
@@ -173,13 +174,13 @@ class TS3Proto():
|
||||
@type value: string/int
|
||||
"""
|
||||
|
||||
if isinstance(value, int): return "%d" % value
|
||||
if isinstance(value, int):
|
||||
return "%d" % value
|
||||
value = value.replace(r"\\", "\\")
|
||||
for i, j in ts3_escape.iteritems():
|
||||
for i, j in ts3_escape:
|
||||
value = value.replace(j, i)
|
||||
return value
|
||||
|
||||
|
||||
def send(self, payload):
|
||||
if self._connected:
|
||||
self._log.debug('Sent: %s' % payload)
|
||||
@@ -230,7 +231,7 @@ class TS3Server(TS3Proto):
|
||||
"""
|
||||
Send a global message to the current Virtual Server
|
||||
@param msg: Message
|
||||
@type ip: str
|
||||
@type msg: str
|
||||
"""
|
||||
if self._connected:
|
||||
return self.send_command('gm', keys={'msg': msg})
|
||||
@@ -243,3 +244,213 @@ class TS3Server(TS3Proto):
|
||||
"""
|
||||
if self._connected and id > 0:
|
||||
self.send_command('use', keys={'sid': id})
|
||||
|
||||
|
||||
class TeamspeakError:
|
||||
def __init__(self, code, msg=None):
|
||||
self.code = str(code)
|
||||
if not msg:
|
||||
msg = ts3_errors[self.code]
|
||||
self.msg = msg
|
||||
|
||||
def __str__(self):
|
||||
return self.code + ' ' + self.msg
|
||||
|
||||
ts3_errors = {
|
||||
'0': 'unknown error code',
|
||||
'1': 'undefined error',
|
||||
'2': 'not implemented',
|
||||
'3': '',
|
||||
'4': '',
|
||||
'5': 'library time limit reached',
|
||||
'256': 'command not found',
|
||||
'257': 'unable to bind network port',
|
||||
'258': 'no network port available',
|
||||
'512': 'invalid clientID',
|
||||
'513': 'nickname is already in use',
|
||||
'514': 'invalid error code',
|
||||
'515': 'max clients protocol limit reached',
|
||||
'516': 'invalid client type',
|
||||
'517': 'already subscribed',
|
||||
'518': 'not logged in',
|
||||
'519': 'could not validate client identity',
|
||||
'520': 'invalid loginname or password',
|
||||
'521': 'too many clones already connected',
|
||||
'522': 'client version outdated, please update',
|
||||
'523': 'client is online',
|
||||
'524': 'client is flooding',
|
||||
'525': 'client is modified',
|
||||
'526': 'can not verify client at this moment',
|
||||
'527': 'client is not permitted to log in',
|
||||
'528': 'client is not subscribed to the channel',
|
||||
'768': 'invalid channelID',
|
||||
'769': 'max channels protocol limit reached',
|
||||
'770': 'already member of channel',
|
||||
'771': 'channel name is already in use',
|
||||
'772': 'channel not empty',
|
||||
'773': 'can not delete default channel',
|
||||
'774': 'default channel requires permanent',
|
||||
'775': 'invalid channel flags',
|
||||
'776': 'permanent channel can not be child of non permanent channel',
|
||||
'777': 'channel maxclient reached',
|
||||
'778': 'channel maxfamily reached',
|
||||
'779': 'invalid channel order',
|
||||
'780': 'channel does not support filetransfers',
|
||||
'781': 'invalid channel password',
|
||||
'782': 'channel is private channel',
|
||||
'783': 'invalid security hash supplied by client',
|
||||
'1024': 'invalid serverID',
|
||||
'1025': 'server is running',
|
||||
'1026': 'server is shutting down',
|
||||
'1027': 'server maxclient reached',
|
||||
'1028': 'invalid server password',
|
||||
'1029': 'deployment active',
|
||||
'1030': 'unable to stop own server in your connection class',
|
||||
'1031': 'server is virtual',
|
||||
'1032': 'server wrong machineID',
|
||||
'1033': 'server is not running',
|
||||
'1034': 'server is booting up',
|
||||
'1035': 'server got an invalid status for this operation',
|
||||
'1036': 'server modal quit',
|
||||
'1037': 'server version is too old for command',
|
||||
'1280': 'database error',
|
||||
'1281': 'database empty result set',
|
||||
'1282': 'database duplicate entry',
|
||||
'1283': 'database no modifications',
|
||||
'1284': 'database invalid constraint',
|
||||
'1285': 'database reinvoke command',
|
||||
'1536': 'invalid quote',
|
||||
'1537': 'invalid parameter count',
|
||||
'1538': 'invalid parameter',
|
||||
'1539': 'parameter not found',
|
||||
'1540': 'convert error',
|
||||
'1541': 'invalid parameter size',
|
||||
'1542': 'missing required parameter',
|
||||
'1543': 'invalid checksum',
|
||||
'1792': 'virtual server got a critical error',
|
||||
'1793': 'Connection lost',
|
||||
'1794': 'not connected',
|
||||
'1795': 'no cached connection info',
|
||||
'1796': 'currently not possible',
|
||||
'1797': 'failed connection initialization',
|
||||
'1798': 'could not resolve hostname',
|
||||
'1799': 'invalid server connection handler ID',
|
||||
'1800': 'could not initialize Input Manager',
|
||||
'1801': 'client library not initialized',
|
||||
'1802': 'server library not initialized',
|
||||
'1803': 'too many whisper targets',
|
||||
'1804': 'no whisper targets found',
|
||||
'2048': 'invalid file name',
|
||||
'2049': 'invalid file permissions',
|
||||
'2050': 'file already exists',
|
||||
'2051': 'file not found',
|
||||
'2052': 'file input/output error',
|
||||
'2053': 'invalid file transfer ID',
|
||||
'2054': 'invalid file path',
|
||||
'2055': 'no files available',
|
||||
'2056': 'overwrite excludes resume',
|
||||
'2057': 'invalid file size',
|
||||
'2058': 'file already in use',
|
||||
'2059': 'could not open file transfer connection',
|
||||
'2060': 'no space left on device (disk full?)',
|
||||
'2061': "file exceeds file system's maximum file size",
|
||||
'2062': 'file transfer connection timeout',
|
||||
'2063': 'lost file transfer connection',
|
||||
'2064': 'file exceeds supplied file size',
|
||||
'2065': 'file transfer complete',
|
||||
'2066': 'file transfer canceled',
|
||||
'2067': 'file transfer interrupted',
|
||||
'2068': 'file transfer server quota exceeded',
|
||||
'2069': 'file transfer client quota exceeded',
|
||||
'2070': 'file transfer reset',
|
||||
'2071': 'file transfer limit reached',
|
||||
'2304': 'preprocessor disabled',
|
||||
'2305': 'internal preprocessor',
|
||||
'2306': 'internal encoder',
|
||||
'2307': 'internal playback',
|
||||
'2308': 'no capture device available',
|
||||
'2309': 'no playback device available',
|
||||
'2310': 'could not open capture device',
|
||||
'2311': 'could not open playback device',
|
||||
'2312': 'ServerConnectionHandler has a device registered',
|
||||
'2313': 'invalid capture device',
|
||||
'2314': 'invalid clayback device',
|
||||
'2315': 'invalid wave file',
|
||||
'2316': 'wave file type not supported',
|
||||
'2317': 'could not open wave file',
|
||||
'2318': 'internal capture',
|
||||
'2319': 'device still in use',
|
||||
'2320': 'device already registerred',
|
||||
'2321': 'device not registered/known',
|
||||
'2322': 'unsupported frequency',
|
||||
'2323': 'invalid channel count',
|
||||
'2324': 'read error in wave',
|
||||
'2325': 'sound need more data',
|
||||
'2326': 'sound device was busy',
|
||||
'2327': 'there is no sound data for this period',
|
||||
'2328': 'Channelmask set bits count (speakers) is not the same as channel (count)',
|
||||
'2560': 'invalid group ID',
|
||||
'2561': 'duplicate entry',
|
||||
'2562': 'invalid permission ID',
|
||||
'2563': 'empty result set',
|
||||
'2564': 'access to default group is forbidden',
|
||||
'2565': 'invalid size',
|
||||
'2566': 'invalid value',
|
||||
'2567': 'group is not empty',
|
||||
'2568': 'insufficient client permissions',
|
||||
'2569': 'insufficient group modify power',
|
||||
'2570': 'insufficient permission modify power',
|
||||
'2571': 'template group is currently used',
|
||||
'2572': 'permission error',
|
||||
'2816': 'virtualserver limit reached',
|
||||
'2817': 'max slot limit reached',
|
||||
'2818': 'license file not found',
|
||||
'2819': 'license date not ok',
|
||||
'2820': 'unable to connect to accounting server',
|
||||
'2821': 'unknown accounting error',
|
||||
'2822': 'accounting server error',
|
||||
'2823': 'instance limit reached',
|
||||
'2824': 'instance check error',
|
||||
'2825': 'license file invalid',
|
||||
'2826': 'virtualserver is running elsewhere',
|
||||
'2827': 'virtualserver running in same instance already',
|
||||
'2828': 'virtualserver already started',
|
||||
'2829': 'virtualserver not started',
|
||||
'2830': '',
|
||||
'3072': 'invalid message id',
|
||||
'3328': 'invalid ban id',
|
||||
'3329': 'connection failed, you are banned',
|
||||
'3330': 'rename failed, new name is banned',
|
||||
'3331': 'flood ban',
|
||||
'3584': 'unable to initialize tts',
|
||||
'3840': 'invalid privilege key',
|
||||
'4096': '',
|
||||
'4097': '',
|
||||
'4098': '',
|
||||
'4099': '',
|
||||
'4100': '',
|
||||
'4101': '',
|
||||
'4102': '',
|
||||
'4103': '',
|
||||
'4352': 'invalid password',
|
||||
'4353': 'invalid request',
|
||||
'4354': 'no (more) slots available',
|
||||
'4355': 'pool missing',
|
||||
'4356': 'pool unknown',
|
||||
'4357': 'unknown ip location (perhaps LAN ip?)',
|
||||
'4358': 'internal error (tried exceeded)',
|
||||
'4359': 'too many slots requested',
|
||||
'4360': 'too many reserved',
|
||||
'4361': 'could not connect to provisioning server',
|
||||
'4368': 'authentication server not connected',
|
||||
'4369': 'authentication data too large',
|
||||
'4370': 'already initialized',
|
||||
'4371': 'not initialized',
|
||||
'4372': 'already connecting',
|
||||
'4373': 'already connected',
|
||||
'4374': '',
|
||||
'4375': 'io_error',
|
||||
'4376': '',
|
||||
'4377': '',
|
||||
'4378': '',
|
||||
}
|
||||
|
||||
@@ -1,3 +1,4 @@
|
||||
from __future__ import unicode_literals
|
||||
import os
|
||||
import requests
|
||||
import json
|
||||
@@ -8,130 +9,131 @@ import logging
|
||||
|
||||
logger = logging.getLogger(__name__)
|
||||
|
||||
|
||||
class XenForoManager:
|
||||
def __init__(self):
|
||||
if not settings.XENFORO_ENDPOINT:
|
||||
logger.debug("Could not find XenForo endpoint")
|
||||
if not settings.XENFORO_APIKEY:
|
||||
logger.debug("XenForo API Key not found")
|
||||
pass
|
||||
def __init__(self):
|
||||
if not settings.XENFORO_ENDPOINT:
|
||||
logger.debug("Could not find XenForo endpoint")
|
||||
if not settings.XENFORO_APIKEY:
|
||||
logger.debug("XenForo API Key not found")
|
||||
pass
|
||||
|
||||
@staticmethod
|
||||
def __sanitize_username(username):
|
||||
sanitized = username.replace(" ", "_")
|
||||
return sanitized
|
||||
@staticmethod
|
||||
def __sanitize_username(username):
|
||||
sanitized = username.replace(" ", "_")
|
||||
return sanitized
|
||||
|
||||
@staticmethod
|
||||
def __generate_password():
|
||||
return os.urandom(8).encode('hex')
|
||||
@staticmethod
|
||||
def __generate_password():
|
||||
return os.urandom(8).encode('hex')
|
||||
|
||||
@staticmethod
|
||||
def exec_http_request(http_params):
|
||||
default_params = {
|
||||
'hash': settings.XENFORO_APIKEY
|
||||
}
|
||||
http_params.update(default_params)
|
||||
r = requests.get(settings.XENFORO_ENDPOINT, params=http_params)
|
||||
return r
|
||||
@staticmethod
|
||||
def exec_http_request(http_params):
|
||||
default_params = {
|
||||
'hash': settings.XENFORO_APIKEY
|
||||
}
|
||||
http_params.update(default_params)
|
||||
r = requests.get(settings.XENFORO_ENDPOINT, params=http_params)
|
||||
return r
|
||||
|
||||
@staticmethod
|
||||
def add_user(username, email):
|
||||
@staticmethod
|
||||
def add_user(username, email):
|
||||
|
||||
sanitized = XenForoManager.__sanitize_username(username)
|
||||
password = XenForoManager.__generate_password();
|
||||
sanitized = XenForoManager.__sanitize_username(username)
|
||||
password = XenForoManager.__generate_password()
|
||||
|
||||
data = {
|
||||
'action': 'register',
|
||||
'username': sanitized,
|
||||
'password': password,
|
||||
'email': email,
|
||||
'group': settings.XENFORO_DEFAULT_GROUP,
|
||||
'visible': '1',
|
||||
'user_state': 'valid'
|
||||
}
|
||||
data = {
|
||||
'action': 'register',
|
||||
'username': sanitized,
|
||||
'password': password,
|
||||
'email': email,
|
||||
'group': settings.XENFORO_DEFAULT_GROUP,
|
||||
'visible': '1',
|
||||
'user_state': 'valid'
|
||||
}
|
||||
|
||||
r = XenForoManager.exec_http_request(data)
|
||||
|
||||
# check if the user already exist but was disabled
|
||||
if r.status_code != 200:
|
||||
if json.loads(r.text)['error'] == 7:
|
||||
data = XenForoManager.reactivate_user(sanitized)
|
||||
return data
|
||||
r = XenForoManager.exec_http_request(data)
|
||||
|
||||
response = {
|
||||
'response': {
|
||||
'message': r.text,
|
||||
'status_code': r.status_code
|
||||
}
|
||||
}
|
||||
data.update(response)
|
||||
return data
|
||||
# check if the user already exist but was disabled
|
||||
if r.status_code != 200:
|
||||
if json.loads(r.text)['error'] == 7:
|
||||
data = XenForoManager.reactivate_user(sanitized)
|
||||
return data
|
||||
|
||||
@staticmethod
|
||||
def reset_password(username):
|
||||
response = {
|
||||
'response': {
|
||||
'message': r.text,
|
||||
'status_code': r.status_code
|
||||
}
|
||||
}
|
||||
data.update(response)
|
||||
return data
|
||||
|
||||
password = XenForoManager.__generate_password();
|
||||
@staticmethod
|
||||
def reset_password(username):
|
||||
|
||||
data = {
|
||||
'action': 'editUser',
|
||||
'user': username,
|
||||
'password': password
|
||||
}
|
||||
password = XenForoManager.__generate_password()
|
||||
|
||||
r = XenForoManager.exec_http_request(data)
|
||||
data = {
|
||||
'action': 'editUser',
|
||||
'user': username,
|
||||
'password': password
|
||||
}
|
||||
|
||||
response = {
|
||||
'response': {
|
||||
'message': r.text,
|
||||
'status_code': r.status_code
|
||||
}
|
||||
}
|
||||
data.update(response)
|
||||
return data
|
||||
r = XenForoManager.exec_http_request(data)
|
||||
|
||||
@staticmethod
|
||||
def disable_user(username):
|
||||
data = {
|
||||
'action': 'editUser',
|
||||
'user': username,
|
||||
'remove_groups': settings.XENFORO_DEFAULT_GROUP
|
||||
}
|
||||
r = XenForoManager.exec_http_request(data)
|
||||
return r
|
||||
response = {
|
||||
'response': {
|
||||
'message': r.text,
|
||||
'status_code': r.status_code
|
||||
}
|
||||
}
|
||||
data.update(response)
|
||||
return data
|
||||
|
||||
@staticmethod
|
||||
def reactivate_user(username):
|
||||
data = {
|
||||
'action': 'editUser',
|
||||
'user': username,
|
||||
'add_groups': settings.XENFORO_DEFAULT_GROUP,
|
||||
'password': XenForoManager.__generate_password()
|
||||
}
|
||||
r = XenForoManager.exec_http_request(data)
|
||||
response = {
|
||||
'response': {
|
||||
'message': r.text,
|
||||
'status_code': r.status_code
|
||||
},
|
||||
'username': username
|
||||
}
|
||||
data.update(response)
|
||||
return data
|
||||
@staticmethod
|
||||
def disable_user(username):
|
||||
data = {
|
||||
'action': 'editUser',
|
||||
'user': username,
|
||||
'remove_groups': settings.XENFORO_DEFAULT_GROUP
|
||||
}
|
||||
r = XenForoManager.exec_http_request(data)
|
||||
return r
|
||||
|
||||
@staticmethod
|
||||
def update_user_password(username, raw_password):
|
||||
data = {
|
||||
'action': 'editUser',
|
||||
'user': username,
|
||||
'password': raw_password
|
||||
}
|
||||
r = XenForoManager.exec_http_request(data)
|
||||
response = {
|
||||
'response': {
|
||||
'message': r.text,
|
||||
'status_code': r.status_code
|
||||
},
|
||||
'username': username
|
||||
}
|
||||
data.update(response)
|
||||
return data
|
||||
@staticmethod
|
||||
def reactivate_user(username):
|
||||
data = {
|
||||
'action': 'editUser',
|
||||
'user': username,
|
||||
'add_groups': settings.XENFORO_DEFAULT_GROUP,
|
||||
'password': XenForoManager.__generate_password()
|
||||
}
|
||||
r = XenForoManager.exec_http_request(data)
|
||||
response = {
|
||||
'response': {
|
||||
'message': r.text,
|
||||
'status_code': r.status_code
|
||||
},
|
||||
'username': username
|
||||
}
|
||||
data.update(response)
|
||||
return data
|
||||
|
||||
@staticmethod
|
||||
def update_user_password(username, raw_password):
|
||||
data = {
|
||||
'action': 'editUser',
|
||||
'user': username,
|
||||
'password': raw_password
|
||||
}
|
||||
r = XenForoManager.exec_http_request(data)
|
||||
response = {
|
||||
'response': {
|
||||
'message': r.text,
|
||||
'status_code': r.status_code
|
||||
},
|
||||
'username': username
|
||||
}
|
||||
data.update(response)
|
||||
return data
|
||||
|
||||
83
services/migrations/0001_initial.py
Normal file
83
services/migrations/0001_initial.py
Normal file
@@ -0,0 +1,83 @@
|
||||
# -*- coding: utf-8 -*-
|
||||
# Generated by Django 1.10.1 on 2016-09-05 21:40
|
||||
from __future__ import unicode_literals
|
||||
|
||||
from django.conf import settings
|
||||
from django.db import migrations, models
|
||||
import django.db.models.deletion
|
||||
|
||||
|
||||
class Migration(migrations.Migration):
|
||||
|
||||
initial = True
|
||||
|
||||
dependencies = [
|
||||
('auth', '0008_alter_user_username_max_length'),
|
||||
migrations.swappable_dependency(settings.AUTH_USER_MODEL),
|
||||
]
|
||||
|
||||
operations = [
|
||||
migrations.CreateModel(
|
||||
name='AuthTS',
|
||||
fields=[
|
||||
('id', models.AutoField(auto_created=True, primary_key=True, serialize=False, verbose_name='ID')),
|
||||
('auth_group', models.ForeignKey(on_delete=django.db.models.deletion.CASCADE, to='auth.Group')),
|
||||
],
|
||||
options={
|
||||
'verbose_name': 'Auth / TS Group',
|
||||
},
|
||||
),
|
||||
migrations.CreateModel(
|
||||
name='DiscordAuthToken',
|
||||
fields=[
|
||||
('id', models.AutoField(auto_created=True, primary_key=True, serialize=False, verbose_name='ID')),
|
||||
('email', models.CharField(max_length=254, unique=True)),
|
||||
('token', models.CharField(max_length=254)),
|
||||
('user', models.ForeignKey(null=True, on_delete=django.db.models.deletion.CASCADE, to=settings.AUTH_USER_MODEL)),
|
||||
],
|
||||
),
|
||||
migrations.CreateModel(
|
||||
name='GroupCache',
|
||||
fields=[
|
||||
('id', models.AutoField(auto_created=True, primary_key=True, serialize=False, verbose_name='ID')),
|
||||
('created', models.DateTimeField(auto_now_add=True)),
|
||||
('groups', models.TextField(default={})),
|
||||
('service', models.CharField(choices=[(b'discourse', b'discourse'), (b'discord', b'discord')], max_length=254, unique=True)),
|
||||
],
|
||||
),
|
||||
migrations.CreateModel(
|
||||
name='MumbleUser',
|
||||
fields=[
|
||||
('id', models.AutoField(auto_created=True, primary_key=True, serialize=False, verbose_name='ID')),
|
||||
('username', models.CharField(max_length=254, unique=True)),
|
||||
('pwhash', models.CharField(max_length=40)),
|
||||
('groups', models.TextField(blank=True, null=True)),
|
||||
],
|
||||
),
|
||||
migrations.CreateModel(
|
||||
name='TSgroup',
|
||||
fields=[
|
||||
('ts_group_id', models.IntegerField(primary_key=True, serialize=False)),
|
||||
('ts_group_name', models.CharField(max_length=30)),
|
||||
],
|
||||
options={
|
||||
'verbose_name': 'TS Group',
|
||||
},
|
||||
),
|
||||
migrations.CreateModel(
|
||||
name='UserTSgroup',
|
||||
fields=[
|
||||
('id', models.AutoField(auto_created=True, primary_key=True, serialize=False, verbose_name='ID')),
|
||||
('ts_group', models.ManyToManyField(to='services.TSgroup')),
|
||||
('user', models.ForeignKey(on_delete=django.db.models.deletion.CASCADE, to=settings.AUTH_USER_MODEL)),
|
||||
],
|
||||
options={
|
||||
'verbose_name': 'User TS Group',
|
||||
},
|
||||
),
|
||||
migrations.AddField(
|
||||
model_name='authts',
|
||||
name='ts_group',
|
||||
field=models.ManyToManyField(to='services.TSgroup'),
|
||||
),
|
||||
]
|
||||
22
services/migrations/0002_auto_20161016_0135.py
Normal file
22
services/migrations/0002_auto_20161016_0135.py
Normal file
@@ -0,0 +1,22 @@
|
||||
# -*- coding: utf-8 -*-
|
||||
# Generated by Django 1.10.1 on 2016-10-16 01:35
|
||||
from __future__ import unicode_literals
|
||||
|
||||
from django.db import migrations
|
||||
|
||||
|
||||
class Migration(migrations.Migration):
|
||||
|
||||
dependencies = [
|
||||
('services', '0001_initial'),
|
||||
]
|
||||
|
||||
operations = [
|
||||
migrations.RemoveField(
|
||||
model_name='discordauthtoken',
|
||||
name='user',
|
||||
),
|
||||
migrations.DeleteModel(
|
||||
name='DiscordAuthToken',
|
||||
),
|
||||
]
|
||||
0
services/migrations/__init__.py
Normal file
0
services/migrations/__init__.py
Normal file
@@ -1,44 +1,45 @@
|
||||
from __future__ import unicode_literals
|
||||
from django.utils.encoding import python_2_unicode_compatible
|
||||
from django.db import models
|
||||
from django.contrib.auth.models import Group, User
|
||||
|
||||
|
||||
@python_2_unicode_compatible
|
||||
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'
|
||||
verbose_name = 'TS Group'
|
||||
|
||||
def __str__(self):
|
||||
return self.ts_group_name
|
||||
|
||||
|
||||
|
||||
@python_2_unicode_compatible
|
||||
class AuthTS(models.Model):
|
||||
auth_group = models.ForeignKey('auth.Group')
|
||||
ts_group = models.ManyToManyField(TSgroup)
|
||||
|
||||
class Meta:
|
||||
verbose_name='Auth / TS Group'
|
||||
verbose_name = 'Auth / TS Group'
|
||||
|
||||
def __str__(self):
|
||||
return self.auth_group.name
|
||||
|
||||
|
||||
@python_2_unicode_compatible
|
||||
class UserTSgroup(models.Model):
|
||||
user = models.ForeignKey('auth.User')
|
||||
ts_group = models.ManyToManyField(TSgroup)
|
||||
|
||||
class Meta:
|
||||
verbose_name='User TS Group'
|
||||
verbose_name = 'User TS Group'
|
||||
|
||||
def __str__(self):
|
||||
return self.user.name
|
||||
|
||||
class DiscordAuthToken(models.Model):
|
||||
email = models.CharField(max_length=254, unique=True)
|
||||
token = models.CharField(max_length=254)
|
||||
user = models.ForeignKey(User, on_delete=models.CASCADE, null=True)
|
||||
def __str__(self):
|
||||
output = "Discord Token for email %s user %s" % (self.email, self.user)
|
||||
return output.encode('utf-8')
|
||||
|
||||
@python_2_unicode_compatible
|
||||
class MumbleUser(models.Model):
|
||||
username = models.CharField(max_length=254, unique=True)
|
||||
pwhash = models.CharField(max_length=40)
|
||||
@@ -47,6 +48,8 @@ class MumbleUser(models.Model):
|
||||
def __str__(self):
|
||||
return self.username
|
||||
|
||||
|
||||
@python_2_unicode_compatible
|
||||
class GroupCache(models.Model):
|
||||
SERVICE_CHOICES = (
|
||||
("discourse", "discourse"),
|
||||
|
||||
98
services/signals.py
Normal file
98
services/signals.py
Normal file
@@ -0,0 +1,98 @@
|
||||
from __future__ import unicode_literals
|
||||
from django.db.models.signals import m2m_changed
|
||||
from django.db.models.signals import post_save
|
||||
from django.db.models.signals import pre_save
|
||||
from django.db.models.signals import post_delete
|
||||
from django.db.models.signals import pre_delete
|
||||
from django.dispatch import receiver
|
||||
from django.contrib.auth.models import User
|
||||
import logging
|
||||
from services.tasks import update_jabber_groups
|
||||
from services.tasks import update_mumble_groups
|
||||
from services.tasks import update_forum_groups
|
||||
from services.tasks import update_ipboard_groups
|
||||
from services.tasks import update_discord_groups
|
||||
from services.tasks import update_teamspeak3_groups
|
||||
from services.tasks import update_discourse_groups
|
||||
from services.tasks import update_smf_groups
|
||||
from authentication.tasks import set_state
|
||||
from authentication.tasks import disable_member
|
||||
from authentication.models import AuthServicesInfo
|
||||
from services.models import AuthTS
|
||||
|
||||
logger = logging.getLogger(__name__)
|
||||
|
||||
|
||||
@receiver(m2m_changed, sender=User.groups.through)
|
||||
def m2m_changed_user_groups(sender, instance, action, *args, **kwargs):
|
||||
logger.debug("Received m2m_changed from %s groups with action %s" % (instance, action))
|
||||
if action == "post_add" or action == "post_remove" or action == "post_clear":
|
||||
logger.debug("Triggering service group update for %s" % instance)
|
||||
auth, c = AuthServicesInfo.objects.get_or_create(user=instance)
|
||||
if auth.jabber_username:
|
||||
update_jabber_groups.delay(instance.pk)
|
||||
if auth.teamspeak3_uid:
|
||||
update_teamspeak3_groups.delay(instance.pk)
|
||||
if auth.forum_username:
|
||||
update_forum_groups.delay(instance.pk)
|
||||
if auth.smf_username:
|
||||
update_smf_groups.delay(instance.pk)
|
||||
if auth.ipboard_username:
|
||||
update_ipboard_groups.delay(instance.pk)
|
||||
if auth.discord_uid:
|
||||
update_discord_groups.delay(instance.pk)
|
||||
if auth.mumble_username:
|
||||
update_mumble_groups.delay(instance.pk)
|
||||
if auth.discourse_username:
|
||||
update_discourse_groups.delay(instance.pk)
|
||||
if auth.smf_username:
|
||||
update_smf_groups.delay(instance.pk)
|
||||
|
||||
|
||||
def trigger_all_ts_update():
|
||||
for auth in AuthServicesInfo.objects.filter(teamspeak3_uid__isnull=False):
|
||||
update_teamspeak3_groups.delay(auth.user.pk)
|
||||
|
||||
|
||||
@receiver(m2m_changed, sender=AuthTS.ts_group.through)
|
||||
def m2m_changed_authts_group(sender, instance, action, *args, **kwargs):
|
||||
logger.debug("Received m2m_changed from %s ts_group with action %s" % (instance, action))
|
||||
if action == "post_add" or action == "post_remove":
|
||||
trigger_all_ts_update()
|
||||
|
||||
|
||||
@receiver(post_save, sender=AuthTS)
|
||||
def post_save_authts(sender, instance, *args, **kwargs):
|
||||
logger.debug("Received post_save from %s" % instance)
|
||||
trigger_all_ts_update()
|
||||
|
||||
|
||||
@receiver(post_delete, sender=AuthTS)
|
||||
def post_delete_authts(sender, instance, *args, **kwargs):
|
||||
logger.debug("Received post_delete signal from %s" % instance)
|
||||
trigger_all_ts_update()
|
||||
|
||||
|
||||
@receiver(pre_delete, sender=User)
|
||||
def pre_delete_user(sender, instance, *args, **kwargs):
|
||||
logger.debug("Received pre_delete from %s" % instance)
|
||||
disable_member(instance)
|
||||
|
||||
|
||||
@receiver(pre_save, sender=User)
|
||||
def pre_save_user(sender, instance, *args, **kwargs):
|
||||
logger.debug("Received pre_save from %s" % instance)
|
||||
# check if user is being marked active/inactive
|
||||
if not instance.pk:
|
||||
# new model being created
|
||||
return
|
||||
try:
|
||||
old_instance = User.objects.get(pk=instance.pk)
|
||||
if old_instance.is_active and not instance.is_active:
|
||||
logger.info("Disabling services for inactivation of user %s" % instance)
|
||||
disable_member(instance)
|
||||
elif instance.is_active and not old_instance.is_active:
|
||||
logger.info("Assessing state of reactivated user %s" % instance)
|
||||
set_state(instance)
|
||||
except User.DoesNotExist:
|
||||
pass
|
||||
@@ -1,20 +1,47 @@
|
||||
from authentication.models import AuthServicesInfo
|
||||
from celerytask.models import SyncGroupCache
|
||||
from __future__ import unicode_literals
|
||||
from django.conf import settings
|
||||
import logging
|
||||
from django.contrib.auth.models import User
|
||||
from celery import task
|
||||
from services.models import UserTSgroup
|
||||
from services.models import AuthTS
|
||||
from services.models import TSgroup
|
||||
from services.models import DiscordAuthToken
|
||||
from services.models import MumbleUser
|
||||
from authentication.managers import AuthServicesInfoManager
|
||||
from authentication.models import AuthServicesInfo
|
||||
from services.managers.openfire_manager import OpenfireManager
|
||||
from services.managers.phpbb3_manager import Phpbb3Manager
|
||||
from services.managers.mumble_manager import MumbleManager
|
||||
from services.managers.ipboard_manager import IPBoardManager
|
||||
from services.managers.teamspeak3_manager import Teamspeak3Manager
|
||||
from services.managers.discord_manager import DiscordOAuthManager
|
||||
from services.managers.xenforo_manager import XenForoManager
|
||||
from services.managers.market_manager import marketManager
|
||||
from services.managers.discourse_manager import DiscourseManager
|
||||
from services.managers.smf_manager import smfManager
|
||||
from services.managers.util.ts3 import TeamspeakError
|
||||
from authentication.states import MEMBER_STATE, BLUE_STATE
|
||||
from notifications import notify
|
||||
from celery.task import periodic_task
|
||||
from celery.task.schedules import crontab
|
||||
|
||||
logger = logging.getLogger(__name__)
|
||||
|
||||
|
||||
@periodic_task(run_every=crontab(minute="*/30"))
|
||||
def run_ts3_group_update():
|
||||
if settings.ENABLE_AUTH_TEAMSPEAK3 or settings.ENABLE_BLUE_TEAMSPEAK3:
|
||||
logger.debug("TS3 installed. Syncing local group objects.")
|
||||
Teamspeak3Manager._sync_ts_group_db()
|
||||
|
||||
|
||||
def disable_teamspeak():
|
||||
if settings.ENABLE_AUTH_TEAMSPEAK3:
|
||||
logger.warn("ENABLE_AUTH_TEAMSPEAK3 still True, after disabling users will still be able to create teamspeak accounts")
|
||||
logger.warn(
|
||||
"ENABLE_AUTH_TEAMSPEAK3 still True, after disabling users will still be able to create teamspeak accounts")
|
||||
if settings.ENABLE_BLUE_TEAMSPEAK3:
|
||||
logger.warn("ENABLE_BLUE_TEAMSPEAK3 still True, after disabling blues will still be able to create teamspeak accounts")
|
||||
logger.warn(
|
||||
"ENABLE_BLUE_TEAMSPEAK3 still True, after disabling blues will still be able to create teamspeak accounts")
|
||||
for auth in AuthServicesInfo.objects.all():
|
||||
if auth.teamspeak3_uid:
|
||||
logger.info("Clearing %s Teamspeak3 UID" % auth.user)
|
||||
@@ -32,6 +59,7 @@ def disable_teamspeak():
|
||||
TSgroup.objects.all().delete()
|
||||
logger.info("Teamspeak3 disabled")
|
||||
|
||||
|
||||
def disable_forum():
|
||||
if settings.ENABLE_AUTH_FORUM:
|
||||
logger.warn("ENABLE_AUTH_FORUM still True, after disabling users will still be able to create forum accounts")
|
||||
@@ -46,8 +74,7 @@ def disable_forum():
|
||||
logger.info("Clearing %s forum password" % auth.user)
|
||||
auth.forum_password = ''
|
||||
auth.save()
|
||||
logger.info("Deleting all SyncGroupCache models for forum")
|
||||
SyncGroupCache.objects.filter(servicename="forum").delete()
|
||||
|
||||
|
||||
def disable_jabber():
|
||||
if settings.ENABLE_AUTH_JABBER:
|
||||
@@ -63,8 +90,7 @@ def disable_jabber():
|
||||
logger.info("Clearing %s jabber password" % auth.user)
|
||||
auth.jabber_password = ''
|
||||
auth.save()
|
||||
logger.info("Deleting all SyncGroupCache models for jabber")
|
||||
SyncGroupCache.objects.filter(servicename="jabber").delete()
|
||||
|
||||
|
||||
def disable_mumble():
|
||||
if settings.ENABLE_AUTH_MUMBLE:
|
||||
@@ -80,16 +106,17 @@ def disable_mumble():
|
||||
logger.info("Clearing %s mumble password" % auth.user)
|
||||
auth.mumble_password = ''
|
||||
auth.save()
|
||||
logger.info("Deleting all SyncGroupCache models for mumble")
|
||||
SyncGroupCache.objects.filter(servicename="mumble").delete()
|
||||
logger.info("Deleting all MumbleUser models")
|
||||
MumbleUser.objects.all().delete()
|
||||
|
||||
|
||||
def disable_ipboard():
|
||||
if settings.ENABLE_AUTH_IPBOARD:
|
||||
logger.warn("ENABLE_AUTH_IPBOARD still True, after disabling users will still be able to create IPBoard accounts")
|
||||
logger.warn(
|
||||
"ENABLE_AUTH_IPBOARD still True, after disabling users will still be able to create IPBoard accounts")
|
||||
if settings.ENABLE_BLUE_IPBOARD:
|
||||
logger.warn("ENABLE_BLUE_IPBOARD still True, after disabling blues will still be able to create IPBoard accounts")
|
||||
logger.warn(
|
||||
"ENABLE_BLUE_IPBOARD still True, after disabling blues will still be able to create IPBoard accounts")
|
||||
for auth in AuthServicesInfo.objects.all():
|
||||
if auth.ipboard_username:
|
||||
logger.info("Clearing %s ipboard username" % auth.user)
|
||||
@@ -99,8 +126,6 @@ def disable_ipboard():
|
||||
logger.info("Clearing %s ipboard password" % auth.user)
|
||||
auth.ipboard_password = ''
|
||||
auth.save()
|
||||
logger.info("Deleting all SyncGroupCache models for ipboard")
|
||||
SyncGroupCache.objects.filter(servicename="ipboard").delete()
|
||||
|
||||
|
||||
def disable_discord():
|
||||
@@ -113,5 +138,349 @@ def disable_discord():
|
||||
logger.info("Clearing %s Discord UID" % auth.user)
|
||||
auth.discord_uid = ''
|
||||
auth.save()
|
||||
logger.info("Deleting all DiscordAuthToken models")
|
||||
DiscordAuthToken.objects.all().delete()
|
||||
|
||||
|
||||
def deactivate_services(user):
|
||||
change = False
|
||||
logger.debug("Deactivating services for user %s" % user)
|
||||
authinfo = AuthServicesInfo.objects.get_or_create(user=user)[0]
|
||||
if authinfo.mumble_username and authinfo.mumble_username != "":
|
||||
logger.debug("User %s has mumble account %s. Deleting." % (user, authinfo.mumble_username))
|
||||
MumbleManager.delete_user(authinfo.mumble_username)
|
||||
AuthServicesInfoManager.update_user_mumble_info("", user)
|
||||
change = True
|
||||
if authinfo.jabber_username and authinfo.jabber_username != "":
|
||||
logger.debug("User %s has jabber account %s. Deleting." % (user, authinfo.jabber_username))
|
||||
OpenfireManager.delete_user(authinfo.jabber_username)
|
||||
AuthServicesInfoManager.update_user_jabber_info("", user)
|
||||
change = True
|
||||
if authinfo.forum_username and authinfo.forum_username != "":
|
||||
logger.debug("User %s has forum account %s. Deleting." % (user, authinfo.forum_username))
|
||||
Phpbb3Manager.disable_user(authinfo.forum_username)
|
||||
AuthServicesInfoManager.update_user_forum_info("", user)
|
||||
change = True
|
||||
if authinfo.ipboard_username and authinfo.ipboard_username != "":
|
||||
logger.debug("User %s has ipboard account %s. Deleting." % (user, authinfo.ipboard_username))
|
||||
IPBoardManager.disable_user(authinfo.ipboard_username)
|
||||
AuthServicesInfoManager.update_user_ipboard_info("", user)
|
||||
change = True
|
||||
if authinfo.teamspeak3_uid and authinfo.teamspeak3_uid != "":
|
||||
logger.debug("User %s has mumble account %s. Deleting." % (user, authinfo.teamspeak3_uid))
|
||||
Teamspeak3Manager.delete_user(authinfo.teamspeak3_uid)
|
||||
AuthServicesInfoManager.update_user_teamspeak3_info("", "", user)
|
||||
change = True
|
||||
if authinfo.discord_uid and authinfo.discord_uid != "":
|
||||
logger.debug("User %s has discord account %s. Deleting." % (user, authinfo.discord_uid))
|
||||
DiscordOAuthManager.delete_user(authinfo.discord_uid)
|
||||
AuthServicesInfoManager.update_user_discord_info("", user)
|
||||
change = True
|
||||
if authinfo.xenforo_username and authinfo.xenforo_password != "":
|
||||
logger.debug("User %s has a XenForo account %s. Deleting." % (user, authinfo.xenforo_username))
|
||||
XenForoManager.disable_user(authinfo.xenforo_username)
|
||||
AuthServicesInfoManager.update_user_xenforo_info("", user)
|
||||
change = True
|
||||
if authinfo.market_username and authinfo.market_username != "":
|
||||
logger.debug("User %s has a Market account %s. Deleting." % (user, authinfo.market_username))
|
||||
marketManager.disable_user(authinfo.market_username)
|
||||
AuthServicesInfoManager.update_user_market_info("", user)
|
||||
change = True
|
||||
if authinfo.discourse_username and authinfo.discourse_username != "":
|
||||
logger.debug("User %s has a Discourse account %s. Deleting." % (user, authinfo.discourse_username))
|
||||
DiscourseManager.delete_user(authinfo.discourse_username)
|
||||
AuthServicesInfoManager.update_user_discourse_info("", user)
|
||||
change = True
|
||||
if authinfo.smf_username and authinfo.smf_username != "":
|
||||
logger.debug("User %s has a SMF account %s. Deleting." % (user, authinfo.smf_username))
|
||||
smfManager.disable_user(authinfo.smf_username)
|
||||
AuthServicesInfoManager.update_user_smf_info("", user)
|
||||
change = True
|
||||
if change:
|
||||
notify(user, "Services Disabled", message="Your services accounts have been disabled.", level="danger")
|
||||
|
||||
|
||||
@task
|
||||
def validate_services(user, state):
|
||||
if state == MEMBER_STATE:
|
||||
setting_string = 'AUTH'
|
||||
elif state == BLUE_STATE:
|
||||
setting_string = 'BLUE'
|
||||
else:
|
||||
deactivate_services(user)
|
||||
return
|
||||
logger.debug('Ensuring user %s services are available to state %s' % (user, state))
|
||||
auth = AuthServicesInfo.objects.get_or_create(user=user)[0]
|
||||
if auth.mumble_username and not getattr(settings, 'ENABLE_%s_MUMBLE' % setting_string, False):
|
||||
MumbleManager.delete_user(auth.mumble_username)
|
||||
AuthServicesInfoManager.update_user_mumble_info("", user)
|
||||
notify(user, 'Mumble Account Disabled', level='danger')
|
||||
if auth.jabber_username and not getattr(settings, 'ENABLE_%s_JABBER' % setting_string, False):
|
||||
OpenfireManager.delete_user(auth.jabber_username)
|
||||
AuthServicesInfoManager.update_user_jabber_info("", user)
|
||||
notify(user, 'Jabber Account Disabled', level='danger')
|
||||
if auth.forum_username and not getattr(settings, 'ENABLE_%s_FORUM' % setting_string, False):
|
||||
Phpbb3Manager.disable_user(auth.forum_username)
|
||||
AuthServicesInfoManager.update_user_forum_info("", user)
|
||||
notify(user, 'Forum Account Disabled', level='danger')
|
||||
if auth.ipboard_username and not getattr(settings, 'ENABLE_%s_IPBOARD' % setting_string, False):
|
||||
IPBoardManager.disable_user(auth.ipboard_username)
|
||||
AuthServicesInfoManager.update_user_ipboard_info("", user)
|
||||
notify(user, 'IPBoard Account Disabled', level='danger')
|
||||
if auth.teamspeak3_uid and not getattr(settings, 'ENABLE_%s_TEAMSPEAK' % setting_string, False):
|
||||
Teamspeak3Manager.delete_user(auth.teamspeak3_uid)
|
||||
AuthServicesInfoManager.update_user_teamspeak3_info("", "", user)
|
||||
notify(user, 'TeamSpeak3 Account Disabled', level='danger')
|
||||
if auth.discord_uid and not getattr(settings, 'ENABLE_%s_DISCORD' % setting_string, False):
|
||||
DiscordOAuthManager.delete_user(auth.discord_uid)
|
||||
AuthServicesInfoManager.update_user_discord_info("", user)
|
||||
notify(user, 'Discord Account Disabled', level='danger')
|
||||
if auth.xenforo_username and not getattr(settings, 'ENABLE_%s_XENFORO' % setting_string, False):
|
||||
XenForoManager.disable_user(auth.xenforo_username)
|
||||
AuthServicesInfoManager.update_user_xenforo_info("", user)
|
||||
notify(user, 'XenForo Account Disabled', level='danger')
|
||||
if auth.market_username and not getattr(settings, 'ENABLE_%s_MARKET' % setting_string, False):
|
||||
marketManager.disable_user(auth.market_username)
|
||||
AuthServicesInfoManager.update_user_market_info("", user)
|
||||
notify(user, 'Alliance Market Account Disabled', level='danger')
|
||||
if auth.discourse_username and not getattr(settings, 'ENABLE_%s_DISCOURSE' % setting_string, False):
|
||||
DiscourseManager.delete_user(auth.discourse_username)
|
||||
AuthServicesInfoManager.update_user_discourse_info("", user)
|
||||
notify(user, 'Discourse Account Disabled', level='danger')
|
||||
if auth.smf_username and not getattr(settings, 'ENABLE_%s_SMF' % setting_string, False):
|
||||
smfManager.disable_user(auth.smf_username)
|
||||
AuthServicesInfoManager.update_user_smf_info(auth.smf_username, user)
|
||||
notify(user, "SMF Account Disabled", level='danger')
|
||||
|
||||
|
||||
@task
|
||||
def update_jabber_groups(pk):
|
||||
user = User.objects.get(pk=pk)
|
||||
logger.debug("Updating jabber groups for user %s" % user)
|
||||
authserviceinfo = AuthServicesInfo.objects.get(user=user)
|
||||
groups = []
|
||||
for group in user.groups.all():
|
||||
groups.append(str(group.name))
|
||||
if len(groups) == 0:
|
||||
groups.append('empty')
|
||||
logger.debug("Updating user %s jabber groups to %s" % (user, groups))
|
||||
try:
|
||||
OpenfireManager.update_user_groups(authserviceinfo.jabber_username, groups)
|
||||
except:
|
||||
logger.exception("Jabber group sync failed for %s, retrying in 10 mins" % user)
|
||||
raise self.retry(countdown=60 * 10)
|
||||
logger.debug("Updated user %s jabber groups." % user)
|
||||
|
||||
|
||||
@task
|
||||
def update_all_jabber_groups():
|
||||
logger.debug("Updating ALL jabber groups")
|
||||
for user in AuthServicesInfo.objects.exclude(jabber_username__exact=''):
|
||||
update_jabber_groups.delay(user.user_id)
|
||||
|
||||
|
||||
@task
|
||||
def update_mumble_groups(pk):
|
||||
user = User.objects.get(pk=pk)
|
||||
logger.debug("Updating mumble groups for user %s" % user)
|
||||
authserviceinfo = AuthServicesInfo.objects.get(user=user)
|
||||
groups = []
|
||||
for group in user.groups.all():
|
||||
groups.append(str(group.name))
|
||||
if len(groups) == 0:
|
||||
groups.append('empty')
|
||||
logger.debug("Updating user %s mumble groups to %s" % (user, groups))
|
||||
try:
|
||||
MumbleManager.update_groups(authserviceinfo.mumble_username, groups)
|
||||
except:
|
||||
logger.exception("Mumble group sync failed for %s, retrying in 10 mins" % user)
|
||||
raise self.retry(countdown=60 * 10)
|
||||
logger.debug("Updated user %s mumble groups." % user)
|
||||
|
||||
|
||||
@task
|
||||
def update_all_mumble_groups():
|
||||
logger.debug("Updating ALL mumble groups")
|
||||
for user in AuthServicesInfo.objects.exclude(mumble_username__exact=''):
|
||||
update_mumble_groups.delay(user.user_id)
|
||||
|
||||
|
||||
@task
|
||||
def update_forum_groups(pk):
|
||||
user = User.objects.get(pk=pk)
|
||||
logger.debug("Updating forum groups for user %s" % user)
|
||||
authserviceinfo = AuthServicesInfo.objects.get(user=user)
|
||||
groups = []
|
||||
for group in user.groups.all():
|
||||
groups.append(str(group.name))
|
||||
if len(groups) == 0:
|
||||
groups.append('empty')
|
||||
logger.debug("Updating user %s forum groups to %s" % (user, groups))
|
||||
try:
|
||||
Phpbb3Manager.update_groups(authserviceinfo.forum_username, groups)
|
||||
except:
|
||||
logger.exception("Phpbb group sync failed for %s, retrying in 10 mins" % user)
|
||||
raise self.retry(countdown=60 * 10)
|
||||
logger.debug("Updated user %s forum groups." % user)
|
||||
|
||||
|
||||
@task
|
||||
def update_all_forum_groups():
|
||||
logger.debug("Updating ALL forum groups")
|
||||
for user in AuthServicesInfo.objects.exclude(forum_username__exact=''):
|
||||
update_forum_groups.delay(user.user_id)
|
||||
|
||||
|
||||
@task
|
||||
def update_smf_groups(pk):
|
||||
user = User.objects.get(pk=pk)
|
||||
logger.debug("Updating smf groups for user %s" % user)
|
||||
authserviceinfo = AuthServicesInfo.objects.get(user=user)
|
||||
groups = []
|
||||
for group in user.groups.all():
|
||||
groups.append(str(group.name))
|
||||
if len(groups) == 0:
|
||||
groups.append('empty')
|
||||
logger.debug("Updating user %s smf groups to %s" % (user, groups))
|
||||
try:
|
||||
smfManager.update_groups(authserviceinfo.smf_username, groups)
|
||||
except:
|
||||
logger.exception("smf group sync failed for %s, retrying in 10 mins" % user)
|
||||
raise self.retry(countdown=60 * 10)
|
||||
logger.debug("Updated user %s smf groups." % user)
|
||||
|
||||
|
||||
@task
|
||||
def update_all_smf_groups():
|
||||
logger.debug("Updating ALL smf groups")
|
||||
for user in AuthServicesInfo.objects.exclude(smf_username__exact=''):
|
||||
update_smf_groups.delay(user.user_id)
|
||||
|
||||
|
||||
@task
|
||||
def update_ipboard_groups(pk):
|
||||
user = User.objects.get(pk=pk)
|
||||
logger.debug("Updating user %s ipboard groups." % user)
|
||||
authserviceinfo = AuthServicesInfo.objects.get(user=user)
|
||||
groups = []
|
||||
for group in user.groups.all():
|
||||
groups.append(str(group.name))
|
||||
if len(groups) == 0:
|
||||
groups.append('empty')
|
||||
logger.debug("Updating user %s ipboard groups to %s" % (user, groups))
|
||||
try:
|
||||
IPBoardManager.update_groups(authserviceinfo.ipboard_username, groups)
|
||||
except:
|
||||
logger.exception("IPBoard group sync failed for %s, retrying in 10 mins" % user)
|
||||
raise self.retry(countdown=60 * 10)
|
||||
logger.debug("Updated user %s ipboard groups." % user)
|
||||
|
||||
|
||||
@task
|
||||
def update_all_ipboard_groups():
|
||||
logger.debug("Updating ALL ipboard groups")
|
||||
for user in AuthServicesInfo.objects.exclude(ipboard_username__exact=''):
|
||||
update_ipboard_groups.delay(user.user_id)
|
||||
|
||||
|
||||
@task
|
||||
def update_teamspeak3_groups(pk):
|
||||
user = User.objects.get(pk=pk)
|
||||
logger.debug("Updating user %s 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
|
||||
logger.debug("Updating user %s teamspeak3 groups to %s" % (user, groups))
|
||||
try:
|
||||
Teamspeak3Manager.update_groups(authserviceinfo.teamspeak3_uid, groups)
|
||||
logger.debug("Updated user %s teamspeak3 groups." % user)
|
||||
except TeamspeakError as e:
|
||||
logger.error("Error occured while syncing TS groups for %s: %s" % (user, str(e)))
|
||||
raise self.retry(countdown=60*10)
|
||||
|
||||
|
||||
@task
|
||||
def update_all_teamspeak3_groups():
|
||||
logger.debug("Updating ALL teamspeak3 groups")
|
||||
for user in AuthServicesInfo.objects.exclude(teamspeak3_uid__exact=''):
|
||||
update_teamspeak3_groups.delay(user.user_id)
|
||||
|
||||
|
||||
@task
|
||||
def update_discord_groups(pk):
|
||||
user = User.objects.get(pk=pk)
|
||||
logger.debug("Updating discord groups for user %s" % user)
|
||||
authserviceinfo = AuthServicesInfo.objects.get(user=user)
|
||||
groups = []
|
||||
for group in user.groups.all():
|
||||
groups.append(str(group.name))
|
||||
if len(groups) == 0:
|
||||
logger.debug("No syncgroups found for user. Adding empty group.")
|
||||
groups.append('empty')
|
||||
logger.debug("Updating user %s discord groups to %s" % (user, groups))
|
||||
try:
|
||||
DiscordOAuthManager.update_groups(authserviceinfo.discord_uid, groups)
|
||||
except:
|
||||
logger.exception("Discord group sync failed for %s, retrying in 10 mins" % user)
|
||||
raise self.retry(countdown=60 * 10)
|
||||
logger.debug("Updated user %s discord groups." % user)
|
||||
|
||||
|
||||
@task
|
||||
def update_all_discord_groups():
|
||||
logger.debug("Updating ALL discord groups")
|
||||
for user in AuthServicesInfo.objects.exclude(discord_uid__exact=''):
|
||||
update_discord_groups.delay(user.user_id)
|
||||
|
||||
|
||||
@task
|
||||
def update_discord_nickname(pk):
|
||||
user = User.objects.get(pk=pk)
|
||||
logger.debug("Updating discord nickname for user %s" % user)
|
||||
authserviceinfo = AuthServicesInfo.objects.get(user=user)
|
||||
character = EveManager.get_character_by_id(authserviceinfo.main_char_id)
|
||||
logger.debug("Updating user %s discord nickname to %s" % (user, character.character_name))
|
||||
try:
|
||||
DiscordOAuthManager.update_nickname(authserviceinfo.discord_uid, character.character_name)
|
||||
except:
|
||||
logger.exception("Discord nickname sync failed for %s, retrying in 10 mins" % user)
|
||||
raise self.retry(countdown=60 * 10)
|
||||
logger.debug("Updated user %s discord nickname." % user)
|
||||
|
||||
|
||||
@task
|
||||
def update_all_discord_nicknames():
|
||||
logger.debug("Updating ALL discord nicknames")
|
||||
for user in AuthServicesInfo.objects.exclude(discord_uid__exact=''):
|
||||
update_discord_nickname(user.user_id)
|
||||
|
||||
|
||||
@task
|
||||
def update_discourse_groups(pk):
|
||||
user = User.objects.get(pk=pk)
|
||||
logger.debug("Updating discourse groups for user %s" % user)
|
||||
authserviceinfo = AuthServicesInfo.objects.get(user=user)
|
||||
groups = []
|
||||
for group in user.groups.all():
|
||||
groups.append(str(group.name))
|
||||
if len(groups) == 0:
|
||||
logger.debug("No syncgroups found for user. Adding empty group.")
|
||||
groups.append('empty')
|
||||
logger.debug("Updating user %s discourse groups to %s" % (user, groups))
|
||||
try:
|
||||
DiscourseManager.update_groups(authserviceinfo.discourse_username, groups)
|
||||
except:
|
||||
logger.warn("Discourse group sync failed for %s, retrying in 10 mins" % user, exc_info=True)
|
||||
raise self.retry(countdown=60 * 10)
|
||||
logger.debug("Updated user %s discourse groups." % user)
|
||||
|
||||
|
||||
@task
|
||||
def update_all_discourse_groups():
|
||||
logger.debug("Updating ALL discourse groups")
|
||||
for user in AuthServicesInfo.objects.exclude(discourse_username__exact=''):
|
||||
update_discourse_groups.delay(user.user_id)
|
||||
|
||||
1002
services/views.py
1002
services/views.py
File diff suppressed because it is too large
Load Diff
Reference in New Issue
Block a user