Merge pull request #166 from Adarnof/passwords

Custom service passwords
This commit is contained in:
Adarnof 2016-01-06 13:23:36 -05:00
commit f5bd9133fa
9 changed files with 220 additions and 8 deletions

View File

@ -95,6 +95,7 @@ urlpatterns = patterns('',
url(r'^deactivate_forum/$', 'services.views.deactivate_forum', name='auth_deactivate_forum'), url(r'^deactivate_forum/$', 'services.views.deactivate_forum', name='auth_deactivate_forum'),
url(r'^reset_forum_password/$', 'services.views.reset_forum_password', url(r'^reset_forum_password/$', 'services.views.reset_forum_password',
name='auth_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 # Jabber Service Control
@ -102,12 +103,14 @@ urlpatterns = patterns('',
url(r'^deactivate_jabber/$', 'services.views.deactivate_jabber', name='auth_deactivate_jabber'), url(r'^deactivate_jabber/$', 'services.views.deactivate_jabber', name='auth_deactivate_jabber'),
url(r'^reset_jabber_password/$', 'services.views.reset_jabber_password', url(r'^reset_jabber_password/$', 'services.views.reset_jabber_password',
name='auth_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 # Mumble service control
url(r'^activate_mumble/$', 'services.views.activate_mumble', name='auth_activate_mumble'), 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'^deactivate_mumble/$', 'services.views.deactivate_mumble', name='auth_deactivate_mumble'),
url(r'^reset_mumble_password/$', 'services.views.reset_mumble_password', url(r'^reset_mumble_password/$', 'services.views.reset_mumble_password',
name='auth_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 # Ipboard service control
url(r'^activate_ipboard/$', 'services.views.activate_ipboard_forum', url(r'^activate_ipboard/$', 'services.views.activate_ipboard_forum',
@ -116,6 +119,7 @@ urlpatterns = patterns('',
name='auth_deactivate_ipboard'), name='auth_deactivate_ipboard'),
url(r'^reset_ipboard_password/$', 'services.views.reset_ipboard_password', url(r'^reset_ipboard_password/$', 'services.views.reset_ipboard_password',
name='auth_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 # Teamspeak3 service control
url(r'^activate_teamspeak3/$', 'services.views.activate_teamspeak3', url(r'^activate_teamspeak3/$', 'services.views.activate_teamspeak3',

View File

@ -35,3 +35,11 @@ class FleetFormatterForm(forms.Form):
class DiscordForm(forms.Form): class DiscordForm(forms.Form):
email = forms.CharField(label="Email Address", required=True) email = forms.CharField(label="Email Address", required=True)
password = forms.CharField(label="Password", required=True, widget=forms.PasswordInput) 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

View File

@ -137,8 +137,9 @@ class IPBoardManager:
IPBoardManager.remove_user_from_group(username, g) IPBoardManager.remove_user_from_group(username, g)
@staticmethod @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) 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) IPBoardManager.update_user(username, email, plain_password)
return plain_password return plain_password

View File

@ -213,10 +213,11 @@ class MumbleManager:
return False return False
@staticmethod @staticmethod
def update_user_password(username): def update_user_password(username, password=None):
logger.debug("Updating mumble user %s password." % username) logger.debug("Updating mumble user %s password." % username)
dbcursor = connections['mumble'].cursor() dbcursor = connections['mumble'].cursor()
password = MumbleManager.__generate_random_pass() if not password:
password = MumbleManager.__generate_random_pass()
pwhash = MumbleManager._gen_pwhash(password) pwhash = MumbleManager._gen_pwhash(password)
logger.debug("Proceeding with mumble user %s password update - pwhash starts with %s" % (username, pwhash[0:5])) logger.debug("Proceeding with mumble user %s password update - pwhash starts with %s" % (username, pwhash[0:5]))
if MumbleManager.check_user_exist(username): if MumbleManager.check_user_exist(username):

View File

@ -82,10 +82,11 @@ class OpenfireManager:
logger.info("Unlocked openfire user %s" % username) logger.info("Unlocked openfire user %s" % username)
@staticmethod @staticmethod
def update_user_pass(username): def update_user_pass(username, password=None):
logger.debug("Updating openfire user %s password." % username) logger.debug("Updating openfire user %s password." % username)
try: try:
password = OpenfireManager.__generate_random_pass() if not password:
password = OpenfireManager.__generate_random_pass()
api = ofUsers(settings.OPENFIRE_ADDRESS, settings.OPENFIRE_SECRET_KEY) api = ofUsers(settings.OPENFIRE_ADDRESS, settings.OPENFIRE_SECRET_KEY)
api.update_user(username, password=password) api.update_user(username, password=password)
logger.info("Updated openfire user %s password." % username) logger.info("Updated openfire user %s password." % username)

View File

@ -248,10 +248,11 @@ class Phpbb3Manager:
return False return False
@staticmethod @staticmethod
def update_user_password(username, characterid): def update_user_password(username, characterid, password=None):
logger.debug("Updating phpbb user %s password" % username) logger.debug("Updating phpbb user %s password" % username)
cursor = connections['phpbb3'].cursor() cursor = connections['phpbb3'].cursor()
password = Phpbb3Manager.__generate_random_pass() if not password:
password = Phpbb3Manager.__generate_random_pass()
if Phpbb3Manager.check_user(username): if Phpbb3Manager.check_user(username):
pwhash = Phpbb3Manager.__gen_hash(password) 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]))

View File

@ -26,6 +26,7 @@ from celerytask.tasks import update_discord_groups
from forms import JabberBroadcastForm from forms import JabberBroadcastForm
from forms import FleetFormatterForm from forms import FleetFormatterForm
from forms import DiscordForm from forms import DiscordForm
from forms import ServicePasswordForm
from util import check_if_user_has_permission from util import check_if_user_has_permission
import threading import threading
@ -457,3 +458,128 @@ def activate_discord(request):
logger.debug("Rendering form for user %s with success %s" % (request.user, success)) logger.debug("Rendering form for user %s with success %s" % (request.user, success))
context = {'form': form, 'success': success} context = {'form': form, 'success': success}
return render_to_response('registered/discord.html', context, context_instance=RequestContext(request)) 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))

View File

@ -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 %}
<div class="col-lg-12">
<h1 class="page-header text-center">Set {{service}} Password</h1>
{% if error %}
<div class="container-fluid">
<div class="col-md-4 col-md-offset-4">
<div class="row">
<div class="alert alert-danger text-center" role="alert">{{error}}</div>
</div>
</div>
</div>
{% endif %}
<div class="container-fluid">
<div class="col-md-4 col-md-offset-4">
<div class="row">
<p>Passwords are stored as plain text. Don't re-use another password.</p>
<form class="form-signin" role="form" action="" method="POST"
onsubmit="submitbutton.disabled = true; return true;">
{% csrf_token %}
{{ form|bootstrap }}
<br/>
<button class="btn btn-lg btn-primary btn-block" name="submitbutton" type="submit">Set Password</button>
</form>
</div>
</div>
</div>
</div>
{% endblock content %}

View File

@ -30,6 +30,10 @@
class="glyphicon glyphicon-ok"></span></button> class="glyphicon glyphicon-ok"></span></button>
</a> </a>
{% else %} {% else %}
<a href="{% url 'auth_set_forum_password' %}">
<button type="button" class="btn btn-warning"><span
class="glyphicon glyphicon-pencil"></span></button>
</a>
<a href="{% url 'auth_reset_forum_password' %}"> <a href="{% url 'auth_reset_forum_password' %}">
<button type="button" class="btn btn-primary"><span <button type="button" class="btn btn-primary"><span
class="glyphicon glyphicon-refresh"></span></button> class="glyphicon glyphicon-refresh"></span></button>
@ -53,6 +57,10 @@
class="glyphicon glyphicon-ok"></span></button> class="glyphicon glyphicon-ok"></span></button>
</a> </a>
{% else %} {% else %}
<a href="{% url 'auth_set_ipboard_password' %}">
<button type="button" class="btn btn-warning"><span
class="glyphicon glyphicon-pencil"></span></button>
</a>
<a href="{% url 'auth_reset_ipboard_password' %}"> <a href="{% url 'auth_reset_ipboard_password' %}">
<button type="button" class="btn btn-primary"><span <button type="button" class="btn btn-primary"><span
class="glyphicon glyphicon-refresh"></span></button> class="glyphicon glyphicon-refresh"></span></button>
@ -77,6 +85,10 @@
class="glyphicon glyphicon-ok"></span></button> class="glyphicon glyphicon-ok"></span></button>
</a> </a>
{% else %} {% else %}
<a href="{% url 'auth_set_jabber_password' %}">
<button type="button" class="btn btn-warning"><span
class="glyphicon glyphicon-pencil"></span></button>
</a>
<a href="{% url 'auth_reset_jabber_password' %}"> <a href="{% url 'auth_reset_jabber_password' %}">
<button type="button" class="btn btn-primary"><span <button type="button" class="btn btn-primary"><span
class="glyphicon glyphicon-refresh"></span></button> class="glyphicon glyphicon-refresh"></span></button>
@ -102,6 +114,10 @@
class="glyphicon glyphicon-ok"></span></button> class="glyphicon glyphicon-ok"></span></button>
</a> </a>
{% else %} {% else %}
<a href="{% url 'auth_set_mumble_password' %}">
<button type="button" class="btn btn-warning"><span
class="glyphicon glyphicon-pencil"></span></button>
</a>
<a href="{% url 'auth_reset_mumble_password' %}"> <a href="{% url 'auth_reset_mumble_password' %}">
<button type="button" class="btn btn-primary"><span <button type="button" class="btn btn-primary"><span
class="glyphicon glyphicon-refresh"></span></button> class="glyphicon glyphicon-refresh"></span></button>
@ -200,6 +216,10 @@
class="glyphicon glyphicon-ok"></span></button> class="glyphicon glyphicon-ok"></span></button>
</a> </a>
{% else %} {% else %}
<a href="{% url 'auth_set_forum_password' %}">
<button type="button" class="btn btn-warning"><span
class="glyphicon glyphicon-pencil"></span></button>
</a>
<a href="{% url 'auth_reset_forum_password' %}"> <a href="{% url 'auth_reset_forum_password' %}">
<button type="button" class="btn btn-primary"><span <button type="button" class="btn btn-primary"><span
class="glyphicon glyphicon-refresh"></span></button> class="glyphicon glyphicon-refresh"></span></button>
@ -224,6 +244,10 @@
class="glyphicon glyphicon-ok"></span></button> class="glyphicon glyphicon-ok"></span></button>
</a> </a>
{% else %} {% else %}
<a href="{% url 'auth_set_ipboard_password' %}">
<button type="button" class="btn btn-warning"><span
class="glyphicon glyphicon-pencil"></span></button>
</a>
<a href="{% url 'auth_reset_ipboard_password' %}"> <a href="{% url 'auth_reset_ipboard_password' %}">
<button type="button" class="btn btn-primary"><span <button type="button" class="btn btn-primary"><span
class="glyphicon glyphicon-refresh"></span></button> class="glyphicon glyphicon-refresh"></span></button>
@ -248,6 +272,10 @@
class="glyphicon glyphicon-ok"></span></button> class="glyphicon glyphicon-ok"></span></button>
</a> </a>
{% else %} {% else %}
<a href="{% url 'auth_set_jabber_password' %}">
<button type="button" class="btn btn-warning"><span
class="glyphicon glyphicon-pencil"></span></button>
</a>
<a href="{% url 'auth_reset_jabber_password' %}"> <a href="{% url 'auth_reset_jabber_password' %}">
<button type="button" class="btn btn-primary"><span <button type="button" class="btn btn-primary"><span
class="glyphicon glyphicon-refresh"></span></button> class="glyphicon glyphicon-refresh"></span></button>
@ -273,6 +301,10 @@
class="glyphicon glyphicon-ok"></span></button> class="glyphicon glyphicon-ok"></span></button>
</a> </a>
{% else %} {% else %}
<a href="{% url 'auth_set_mumble_password' %}">
<button type="button" class="btn btn-warning"><span
class="glyphicon glyphicon-pencil"></span></button>
</a>
<a href="{% url 'auth_reset_mumble_password' %}"> <a href="{% url 'auth_reset_mumble_password' %}">
<button type="button" class="btn btn-primary"><span <button type="button" class="btn btn-primary"><span
class="glyphicon glyphicon-refresh"></span></button> class="glyphicon glyphicon-refresh"></span></button>