diff --git a/alliance_auth/urls.py b/alliance_auth/urls.py index 78f3fbd4..5db17229 100755 --- a/alliance_auth/urls.py +++ b/alliance_auth/urls.py @@ -95,6 +95,7 @@ urlpatterns = patterns('', url(r'^deactivate_forum/$', 'services.views.deactivate_forum', name='auth_deactivate_forum'), url(r'^reset_forum_password/$', 'services.views.reset_forum_password', name='auth_reset_forum_password'), + url(r'^set_forum_password/$', 'services.views.set_forum_password', name='auth_set_forum_password'), # Jabber Service Control @@ -102,12 +103,14 @@ urlpatterns = patterns('', url(r'^deactivate_jabber/$', 'services.views.deactivate_jabber', name='auth_deactivate_jabber'), url(r'^reset_jabber_password/$', 'services.views.reset_jabber_password', name='auth_reset_jabber_password'), + url(r'^set_jabber_password/$', 'services.views.set_jabber_password', name='auth_set_jabber_password'), # Mumble service control url(r'^activate_mumble/$', 'services.views.activate_mumble', name='auth_activate_mumble'), url(r'^deactivate_mumble/$', 'services.views.deactivate_mumble', name='auth_deactivate_mumble'), url(r'^reset_mumble_password/$', 'services.views.reset_mumble_password', name='auth_reset_mumble_password'), + url(r'^set_mumble_password/$', 'services.views.set_mumble_password', name='auth_set_mumble_password'), # Ipboard service control url(r'^activate_ipboard/$', 'services.views.activate_ipboard_forum', @@ -116,6 +119,7 @@ urlpatterns = patterns('', name='auth_deactivate_ipboard'), url(r'^reset_ipboard_password/$', 'services.views.reset_ipboard_password', name='auth_reset_ipboard_password'), + url(r'^set_ipboard_password/$', 'services.views.set_ipboard_password', name='auth_set_ipboard_password'), # Teamspeak3 service control url(r'^activate_teamspeak3/$', 'services.views.activate_teamspeak3', diff --git a/services/forms.py b/services/forms.py index 65277517..ec76ef12 100644 --- a/services/forms.py +++ b/services/forms.py @@ -35,3 +35,11 @@ class FleetFormatterForm(forms.Form): class DiscordForm(forms.Form): email = forms.CharField(label="Email Address", required=True) password = forms.CharField(label="Password", required=True, widget=forms.PasswordInput) + +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 diff --git a/services/managers/ipboard_manager.py b/services/managers/ipboard_manager.py index 16ea220a..677062a2 100755 --- a/services/managers/ipboard_manager.py +++ b/services/managers/ipboard_manager.py @@ -137,8 +137,9 @@ class IPBoardManager: IPBoardManager.remove_user_from_group(username, g) @staticmethod - def update_user_password(username, email): + def update_user_password(username, email, plain_password=None): logger.debug("Settings new IPBoard password for user %s" % username) - plain_password = IPBoardManager.__generate_random_pass() + if not plain_password: + plain_password = IPBoardManager.__generate_random_pass() IPBoardManager.update_user(username, email, plain_password) return plain_password diff --git a/services/managers/mumble_manager.py b/services/managers/mumble_manager.py index 4306249a..68d157df 100755 --- a/services/managers/mumble_manager.py +++ b/services/managers/mumble_manager.py @@ -213,10 +213,11 @@ class MumbleManager: return False @staticmethod - def update_user_password(username): + def update_user_password(username, password=None): logger.debug("Updating mumble user %s password." % username) dbcursor = connections['mumble'].cursor() - password = MumbleManager.__generate_random_pass() + if not password: + password = MumbleManager.__generate_random_pass() pwhash = MumbleManager._gen_pwhash(password) logger.debug("Proceeding with mumble user %s password update - pwhash starts with %s" % (username, pwhash[0:5])) if MumbleManager.check_user_exist(username): diff --git a/services/managers/openfire_manager.py b/services/managers/openfire_manager.py index 0e4fdd85..f82f69c3 100755 --- a/services/managers/openfire_manager.py +++ b/services/managers/openfire_manager.py @@ -82,10 +82,11 @@ class OpenfireManager: logger.info("Unlocked openfire user %s" % username) @staticmethod - def update_user_pass(username): + def update_user_pass(username, password=None): logger.debug("Updating openfire user %s password." % username) try: - password = OpenfireManager.__generate_random_pass() + if not password: + password = OpenfireManager.__generate_random_pass() api = ofUsers(settings.OPENFIRE_ADDRESS, settings.OPENFIRE_SECRET_KEY) api.update_user(username, password=password) logger.info("Updated openfire user %s password." % username) diff --git a/services/managers/phpbb3_manager.py b/services/managers/phpbb3_manager.py index 98939e6a..7b19acc3 100755 --- a/services/managers/phpbb3_manager.py +++ b/services/managers/phpbb3_manager.py @@ -248,10 +248,11 @@ class Phpbb3Manager: return False @staticmethod - def update_user_password(username, characterid): + def update_user_password(username, characterid, password=None): logger.debug("Updating phpbb user %s password" % username) cursor = connections['phpbb3'].cursor() - password = Phpbb3Manager.__generate_random_pass() + if not password: + 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])) diff --git a/services/views.py b/services/views.py index 6cac1456..6e96bebe 100755 --- a/services/views.py +++ b/services/views.py @@ -26,6 +26,7 @@ from celerytask.tasks import update_discord_groups from forms import JabberBroadcastForm from forms import FleetFormatterForm from forms import DiscordForm +from forms import ServicePasswordForm from util import check_if_user_has_permission import threading @@ -457,3 +458,128 @@ def activate_discord(request): logger.debug("Rendering form for user %s with success %s" % (request.user, success)) context = {'form': form, 'success': success} return render_to_response('registered/discord.html', context, context_instance=RequestContext(request)) + +@login_required +@user_passes_test(service_blue_alliance_test) +def set_forum_password(request): + logger.debug("set_forum_password called by user %s" % request.user) + error = None + if request.method == 'POST': + logger.debug("Received POST request with form.") + form = ServicePasswordForm(request.POST) + logger.debug("Form is valid: %s" % form.is_valid()) + if form.is_valid(): + password = form.cleaned_data['password'] + logger.debug("Form contains password of length %s" % len(password)) + authinfo = AuthServicesInfoManager.get_auth_service_info(request.user) + result = Phpbb3Manager.update_user_password(authinfo.forum_username, authinfo.main_char_id, password=password) + if result != "": + AuthServicesInfoManager.update_user_forum_info(authinfo.forum_username, result, request.user) + logger.info("Succesfully reset forum password for user %s" % request.user) + return HttpResponseRedirect("/services/") + else: + logger.error("Failed to install custom forum password for user %s" % request.user) + error = "Failed to install custom password." + else: + error = "Invalid password provided" + else: + logger.debug("Request is not type POST - providing empty form.") + form = ServicePasswordForm() + + logger.debug("Rendering form for user %s" % request.user) + context = {'form': form, 'service': 'Forum'} + return render_to_response('registered/service_password.html', context, context_instance=RequestContext(request)) + +@login_required +@user_passes_test(service_blue_alliance_test) +def set_mumble_password(request): + logger.debug("set_mumble_password called by user %s" % request.user) + error = None + if request.method == 'POST': + logger.debug("Received POST request with form.") + form = ServicePasswordForm(request.POST) + logger.debug("Form is valid: %s" % form.is_valid()) + if form.is_valid(): + password = form.cleaned_data['password'] + logger.debug("Form contains password of length %s" % len(password)) + authinfo = AuthServicesInfoManager.get_auth_service_info(request.user) + result = MumbleManager.update_user_password(authinfo.mumble_username, password=password) + if result != "": + AuthServicesInfoManager.update_user_mumble_info(authinfo.mumble_username, result, request.user) + logger.info("Succesfully reset forum password for user %s" % request.user) + return HttpResponseRedirect("/services/") + else: + logger.error("Failed to install custom mumble password for user %s" % request.user) + error = "Failed to install custom password." + else: + error = "Invalid password provided" + else: + logger.debug("Request is not type POST - providing empty form.") + form = ServicePasswordForm() + + logger.debug("Rendering form for user %s" % request.user) + context = {'form': form, 'service': 'Mumble', 'error': error} + return render_to_response('registered/service_password.html', context, context_instance=RequestContext(request)) + +@login_required +@user_passes_test(service_blue_alliance_test) +def set_jabber_password(request): + logger.debug("set_jabber_password called by user %s" % request.user) + error = None + if request.method == 'POST': + logger.debug("Received POST request with form.") + form = ServicePasswordForm(request.POST) + logger.debug("Form is valid: %s" % form.is_valid()) + if form.is_valid(): + password = form.cleaned_data['password'] + logger.debug("Form contains password of length %s" % len(password)) + authinfo = AuthServicesInfoManager.get_auth_service_info(request.user) + result = OpenfireManager.update_user_pass(authinfo.jabber_username, password=password) + if result != "": + AuthServicesInfoManager.update_user_jabber_info(authinfo.jabber_username, result, request.user) + logger.info("Succesfully reset forum password for user %s" % request.user) + return HttpResponseRedirect("/services/") + else: + logger.error("Failed to install custom jabber password for user %s" % request.user) + error = "Failed to install custom password." + else: + error = "Invalid password provided" + else: + logger.debug("Request is not type POST - providing empty form.") + form = ServicePasswordForm() + + logger.debug("Rendering form for user %s" % request.user) + context = {'form': form, 'service': 'Jabber', 'error': error} + return render_to_response('registered/service_password.html', context, context_instance=RequestContext(request)) + +@login_required +@user_passes_test(service_blue_alliance_test) +def set_ipboard_password(request): + logger.debug("set_ipboard_password called by user %s" % request.user) + error = None + if request.method == 'POST': + logger.debug("Received POST request with form.") + form = ServicePasswordForm(request.POST) + logger.debug("Form is valid: %s" % form.is_valid()) + if form.is_valid(): + password = form.cleaned_data['password'] + logger.debug("Form contains password of length %s" % len(password)) + authinfo = AuthServicesInfoManager.get_auth_service_info(request.user) + result = IPBoardManager.update_user_password(authinfo.ipboard_username, request.user.email, plain_password=password) + if result != "": + AuthServicesInfoManager.update_user_ipboard_info(authinfo.ipboard_username, result, request.user) + logger.info("Succesfully reset forum password for user %s" % request.user) + return HttpResponseRedirect("/services/") + else: + logger.error("Failed to install custom ipboard password for user %s" % request.user) + error = "Failed to install custom password." + else: + error = "Invalid password provided" + else: + logger.debug("Request is not type POST - providing empty form.") + form = ServicePasswordForm() + + logger.debug("Rendering form for user %s" % request.user) + context = {'form': form, 'service': 'IPBoard', 'error': error} + return render_to_response('registered/service_password.html', context, context_instance=RequestContext(request)) + diff --git a/stock/templates/registered/service_password.html b/stock/templates/registered/service_password.html new file mode 100644 index 00000000..5f8df0f1 --- /dev/null +++ b/stock/templates/registered/service_password.html @@ -0,0 +1,38 @@ +{% extends "public/base.html" %} +{% load bootstrap %} +{% load staticfiles %} + +{% block title %}Alliance Auth{% endblock %} + +{% block page_title %}Service Password Change{% endblock page_title %} +{% block extra_css %}{% endblock extra_css %} + +{% block content %} +
+

Set {{service}} Password

+ {% if error %} +
+
+
+ +
+
+
+ {% endif %} +
+
+
+

Passwords are stored as plain text. Don't re-use another password.

+ +
+
+
+
+ +{% endblock content %} diff --git a/stock/templates/registered/services.html b/stock/templates/registered/services.html index 9a9f7541..d7b65b47 100755 --- a/stock/templates/registered/services.html +++ b/stock/templates/registered/services.html @@ -30,6 +30,10 @@ class="glyphicon glyphicon-ok"> {% else %} + + + @@ -53,6 +57,10 @@ class="glyphicon glyphicon-ok"> {% else %} + + + @@ -77,6 +85,10 @@ class="glyphicon glyphicon-ok"> {% else %} + + + @@ -102,6 +114,10 @@ class="glyphicon glyphicon-ok"> {% else %} + + + @@ -200,6 +216,10 @@ class="glyphicon glyphicon-ok"> {% else %} + + + @@ -224,6 +244,10 @@ class="glyphicon glyphicon-ok"> {% else %} + + + @@ -248,6 +272,10 @@ class="glyphicon glyphicon-ok"> {% else %} + + + @@ -273,6 +301,10 @@ class="glyphicon glyphicon-ok"> {% else %} + + +