Skip to content
Snippets Groups Projects
Commit c4a049f5 authored by Christian Dresen's avatar Christian Dresen
Browse files

Several fixes

[Profile Settings]
- Fixed LDAP connection when changing password or user information
- Using  field employeeNumber for card ID

[Password Reset]
- Added password reset email
- Activated password reset function

[Misc]
- Added functionality to send Emails
parent 524763d6
No related branches found
No related tags found
No related merge requests found
Showing with 110 additions and 43 deletions
...@@ -8,7 +8,7 @@ PW_RESET_TOKEN_LIFETIME = 5 ...@@ -8,7 +8,7 @@ PW_RESET_TOKEN_LIFETIME = 5
[ldap] [ldap]
LDAP_HOST = ldap LDAP_HOST = ldap
LDAP_BIND_DN = cn=admin,dc=warpzone,dc=ms LDAP_BIND_DN = cn=admin,dc=warpzone,dc=ms
LDAP_PASSWORD = k7dAw8j2 LDAP_PASSWORD =
LDAP_USER_SEARCH_PATH = ou=users,dc=warpzone,dc=ms LDAP_USER_SEARCH_PATH = ou=users,dc=warpzone,dc=ms
LDAP_GROUP_SEARCH_PATH = dc=warpzone,dc=ms LDAP_GROUP_SEARCH_PATH = dc=warpzone,dc=ms
...@@ -18,5 +18,14 @@ LDAP_GROUP_IS_ACTIVE = cn=active,ou=groups,dc=warpzone,dc=ms ...@@ -18,5 +18,14 @@ LDAP_GROUP_IS_ACTIVE = cn=active,ou=groups,dc=warpzone,dc=ms
LDAP_GROUP_IS_STAFF = cn=superuser,ou=groups,ou=warpauth,ou=infrastructure,dc=warpzone,dc=ms LDAP_GROUP_IS_STAFF = cn=superuser,ou=groups,ou=warpauth,ou=infrastructure,dc=warpzone,dc=ms
LDAP_GROUP_SUPERUSER = cn=superuser,ou=groups,ou=warpauth,ou=infrastructure,dc=warpzone,dc=ms LDAP_GROUP_SUPERUSER = cn=superuser,ou=groups,ou=warpauth,ou=infrastructure,dc=warpzone,dc=ms
[email]
SMTP_HOST = smtp.warpzone.ms
SMTP_PORT = 25
SMTP_USERNAME = noreply@warpzone.ms
SMTP_PASSWORD =
SMTP_EMAIL_FROM = noreply@warpzone.ms
SMTP_USE_TLS = True
SUBJECT_PREFIX = '[WarpInfra] '
[misc] [misc]
LOG_PATH = /var/log/ LOG_PATH = /var/log/
\ No newline at end of file
...@@ -9,7 +9,9 @@ class PasswordResetToken(models.Model): ...@@ -9,7 +9,9 @@ class PasswordResetToken(models.Model):
email = models.CharField(max_length=100) email = models.CharField(max_length=100)
hash = models.CharField(max_length=100) hash = models.CharField(max_length=100)
created = models.DateTimeField(auto_now_add=True) created = models.DateTimeField(auto_now_add=True)
def __str__(self):
return self.hash
# LDAP # LDAP
...@@ -22,7 +24,7 @@ class LdapUser(ldapdb.models.Model): ...@@ -22,7 +24,7 @@ class LdapUser(ldapdb.models.Model):
last_name = CharField(db_column='sn', max_length=200) last_name = CharField(db_column='sn', max_length=200)
email = CharField(db_column='mail', max_length=200) email = CharField(db_column='mail', max_length=200)
cn = CharField(db_column='cn', max_length=200) cn = CharField(db_column='cn', max_length=200)
card_id = CharField(db_column='pager', max_length=200) card_id = CharField(db_column='employeeNumber', max_length=200)
uidNumber = CharField(db_column='uidNumber', max_length=200) uidNumber = CharField(db_column='uidNumber', max_length=200)
gidNumber = CharField(db_column='gidNumber', max_length=200) gidNumber = CharField(db_column='gidNumber', max_length=200)
homeDirectory = CharField(db_column='homeDirectory', max_length=200) homeDirectory = CharField(db_column='homeDirectory', max_length=200)
......
...@@ -26,5 +26,7 @@ ...@@ -26,5 +26,7 @@
</div> </div>
</div> </div>
</div> </div>
<script>
$('a[href="{{ selected_tab }}"]').tab('show');
</script>
{% endblock %} {% endblock %}
\ No newline at end of file
...@@ -2,9 +2,13 @@ ...@@ -2,9 +2,13 @@
<div> <div>
<br /> <br />
{% if error %} {% if error_passwd %}
<div class="alert alert-danger">{{ error }}</div><br> <div class="alert alert-danger">{{ error_passwd }}</div><br>
{% endif %} {% endif %}
{% if success_passwd %}
<div class="alert alert-success">{% trans "Password changed successfully" %}</div><br>
{% endif %}
<form class="form-horizontal" method="POST" action="/profile/change_password/" role="form"> <form class="form-horizontal" method="POST" action="/profile/change_password/" role="form">
{% csrf_token %} {% csrf_token %}
<div class="form-group"> <div class="form-group">
......
...@@ -2,10 +2,16 @@ ...@@ -2,10 +2,16 @@
{% load bootstrap %} {% load bootstrap %}
<div> <div>
<br/> <br/>
<p class="lead">{% trans "Groups" %}</p><p /> <p class="lead">{% trans "User data" %}</p><p />
<div class="panel panel-default"> <div class="panel panel-default">
<div class="panel-body"> <div class="panel-body">
{% if error_info %}
<div class="alert alert-danger">{{ error_info }}</div><br>
{% endif %}
{% if success_info %}
<div class="alert alert-success">{% trans "Information changed successfully" %}</div><br>
{% endif %}
<form class="form-horizontal" action="/profile/change_information/" method="POST" role="form"> <form class="form-horizontal" action="/profile/change_information/" method="POST" role="form">
{{ ldap_user_form | bootstrap_horizontal }} {{ ldap_user_form | bootstrap_horizontal }}
<div class="form-group"> <div class="form-group">
...@@ -18,7 +24,9 @@ ...@@ -18,7 +24,9 @@
</div> </div>
</div> </div>
<div class="panel panel-default"> <div class="panel panel-default">
<div class="panel-body"> <div class="panel-body">
<p class="lead">{% trans "Groups" %}</p><p />
<table class="table"> <table class="table">
{% for ldap_group in ldap_groups %} {% for ldap_group in ldap_groups %}
<tr><td>{{ ldap_group }}</td></tr> <tr><td>{{ ldap_group }}</td></tr>
......
...@@ -8,7 +8,7 @@ ...@@ -8,7 +8,7 @@
<div class="alert alert-success"> <div class="alert alert-success">
{% trans "Your password was sucessfully changed. You will be redirected within 5 seconds. If not please click" %} {% trans "Your password was sucessfully changed. You will be redirected within 5 seconds. If not please click" %}
<a href="/login">{% trans "here" %}</a> <a href="/login">{% trans "here" %}</a>
<meta refresh> <meta http-equiv="refresh" content="5; url=/login">
</div> </div>
{% else %} {% else %}
<form class="form" style="max-width: 330px; margin: 0 auto; padding: 40px"> <form class="form" style="max-width: 330px; margin: 0 auto; padding: 40px">
......
...@@ -3,10 +3,11 @@ ...@@ -3,10 +3,11 @@
{% block title %}{% trans "Reset Password" %}{% endblock %} {% block title %}{% trans "Reset Password" %}{% endblock %}
{% block content %} {% block content %}
{% if request.POST %} {% if request.POST %}
<h2 class="form-signin-heading">{% trans "If your information were right, you've got an Email" %}</h2> {% if error %}
<div class="alert alert-danger">{{ error }}</div><br>
Token is: <a href="{{ debug }}">{{ debug }}</a> {% else %}
<div class="alert alert-success">{% trans "If your information were right, you've got an Email" %}</div><br>
{% endif %}
{% else %} {% else %}
<form class="form" style="max-width: 330px; margin: 0 auto; padding: 40px"> <form class="form" style="max-width: 330px; margin: 0 auto; padding: 40px">
{% csrf_token %} {% csrf_token %}
......
...@@ -13,7 +13,7 @@ urlpatterns = [ ...@@ -13,7 +13,7 @@ urlpatterns = [
url(r'^register/$', register.register, name='index'), url(r'^register/$', register.register, name='index'),
url(r'^reset_password/$', reset_password.gen_token, name='index'), url(r'^reset_password/$', reset_password.gen_token, name='index'),
# url(r'^reset_password/(?P<reset_hash>\w+)/$', reset_password.change_password, name='index'), url(r'^reset_password/(?P<reset_hash>\w+)/$', reset_password.change_password, name='index'),
url(r'^profile/$', profile.index, name='index'), url(r'^profile/$', profile.index, name='index'),
url(r'^profile/change_password/$', profile.change_password, name='change_password'), url(r'^profile/change_password/$', profile.change_password, name='change_password'),
......
...@@ -14,10 +14,21 @@ import logging ...@@ -14,10 +14,21 @@ import logging
# ToDo: first- and lastname, email, public? # ToDo: first- and lastname, email, public?
## ##
def setUserObject(request):
pages['ldap_groups'] = request.user.ldap_user.group_names
pages['ldap_user_form'] = LdapUserForm(instance=LdapUser.objects.get(uid=str(request.user)))
def clear_error_messages():
pages["error_info"] = ""
pages["success_info"] = False
pages["error_passwd"] = ""
pages["success_passwd"] = False
pages["selected_tab"]=""
@login_required(login_url='/login/', redirect_field_name=None) @login_required(login_url='/login/', redirect_field_name=None)
def index(request): def index(request):
pages["error"] = "" clear_error_messages()
pages["success"] = False
pages['ldap_groups'] = request.user.ldap_user.group_names pages['ldap_groups'] = request.user.ldap_user.group_names
pages['ldap_user_form'] = LdapUserForm(instance=LdapUser.objects.get(uid=str(request.user))) pages['ldap_user_form'] = LdapUserForm(instance=LdapUser.objects.get(uid=str(request.user)))
return HttpResponse(render(request, 'warpauth/profile.html', pages)) return HttpResponse(render(request, 'warpauth/profile.html', pages))
...@@ -25,7 +36,8 @@ def index(request): ...@@ -25,7 +36,8 @@ def index(request):
@login_required(login_url='/login/', redirect_field_name=None) @login_required(login_url='/login/', redirect_field_name=None)
def change_information(request): def change_information(request):
pages["error"] = "" clear_error_messages()
setUserObject(request)
if request.method != 'POST': if request.method != 'POST':
return redirect("/profile") return redirect("/profile")
...@@ -33,13 +45,13 @@ def change_information(request): ...@@ -33,13 +45,13 @@ def change_information(request):
first_name = request.POST["first_name"] first_name = request.POST["first_name"]
last_name = request.POST["last_name"] last_name = request.POST["last_name"]
email = request.POST["email"] email = request.POST["email"]
card_id = request.POST["card_id"]
f = forms.EmailField() f = forms.EmailField()
try: try:
f.clean(email) f.clean(email)
except ValidationError as e: except ValidationError as e:
pages["error"] = "Invalid Email" pages["error_info"] = "Invalid Email"
return redirect("/profile") return HttpResponse(render(request, 'warpauth/profile.html', pages))
cn = first_name + " " + last_name cn = first_name + " " + last_name
cn = cn.strip() cn = cn.strip()
if first_name == "": if first_name == "":
...@@ -48,32 +60,38 @@ def change_information(request): ...@@ -48,32 +60,38 @@ def change_information(request):
last_name = "None" last_name = "None"
if cn == "": if cn == "":
cn = "None" cn = "None"
user.first_name = first_name user.first_name = first_name
user.last_name = last_name user.last_name = last_name
user.cn = cn user.cn = cn
user.email = email user.email = email
user.card_id=card_id
user.save() user.save()
return redirect("/profile") pages["success_info"] = True
setUserObject(request)
return HttpResponse(render(request, 'warpauth/profile.html', pages))
@login_required(login_url='/login/', redirect_field_name=None) @login_required(login_url='/login/', redirect_field_name=None)
def change_password(request): def change_password(request):
pages["error"] = "" clear_error_messages()
pages["success"] = False pages["selected_tab"]="#change_passwd"
if request.method != 'POST': if request.method != 'POST':
return redirect("/") return redirect("/profile")
print("old_pw" == "")
if "old_pw" not in request.POST or "new_pw" not in request.POST or "new_pw_confirm" not in request.POST: if request.POST["old_pw"] == "" or request.POST["new_pw"] == "" or request.POST["new_pw_confirm"] == "":
pages["error"] = "Please fill in all fields" pages["error_passwd"] = "Please fill in all fields"
elif request.POST["new_pw"] != request.POST["new_pw_confirm"]: elif request.POST["new_pw"] != request.POST["new_pw_confirm"]:
pages["error"] = "Password confirmation did not match" pages["error_passwd"] = "Password confirmation did not match"
else: else:
ldap_connector = LDAPConnector() ldap_connector = LDAPConnector()
ret = ldap_connector.change_password(request.user.ldap_user.dn, request.POST["old_pw"], request.POST["new_pw"]) ret = ldap_connector.change_user_password(request.user.ldap_user.dn, request.POST["old_pw"], request.POST["new_pw"])
if ret == -1: if ret == -1:
pages["error"] = "Old password did not match" pages["error_passwd"] = "Old password did not match"
else: else:
pages["success"] = True pages["success_passwd"] = True
pages['ldap_groups'] = request.user.ldap_user.group_names
pages['ldap_user_form'] = LdapUserForm(instance=LdapUser.objects.get(uid=str(request.user)))
return HttpResponse(render(request, 'warpauth/profile.html', pages)) return HttpResponse(render(request, 'warpauth/profile.html', pages))
...@@ -7,6 +7,7 @@ from django.core.exceptions import ObjectDoesNotExist, ValidationError ...@@ -7,6 +7,7 @@ from django.core.exceptions import ObjectDoesNotExist, ValidationError
from django.http import HttpResponse from django.http import HttpResponse
from django.shortcuts import render from django.shortcuts import render
from warpauth.ldap_connector import LDAPConnector from warpauth.ldap_connector import LDAPConnector
from warpzone.utils import send_email
from warpauth.util import * from warpauth.util import *
from warpauth.models import PasswordResetToken, LdapUser from warpauth.models import PasswordResetToken, LdapUser
...@@ -21,6 +22,7 @@ from warpzone.settings import PW_RESET_TOKEN_LIFETIME ...@@ -21,6 +22,7 @@ from warpzone.settings import PW_RESET_TOKEN_LIFETIME
def gen_token(request): def gen_token(request):
logger = logging.getLogger("reset_password") logger = logging.getLogger("reset_password")
pages["error"] = ""
if request.POST: if request.POST:
try: try:
usr = LdapUser.objects.get(uid=request.POST["username"]) usr = LdapUser.objects.get(uid=request.POST["username"])
...@@ -30,7 +32,9 @@ def gen_token(request): ...@@ -30,7 +32,9 @@ def gen_token(request):
p.email = usr.email p.email = usr.email
p.hash = hashlib.sha1(os.urandom(128)).hexdigest() p.hash = hashlib.sha1(os.urandom(128)).hexdigest()
p.save() p.save()
pages["debug"] = "http://localhost/reset_password/%s" % p.hash ret = send_email(p.email, "Requested Password Reset", "http://localhost/reset_password/%s" % p.hash)
if not ret:
pages["error"] = "Error while sending the email. Please contact the administrator."
logger.info("Success for %s", usr.uid) logger.info("Success for %s", usr.uid)
except Exception as e: except Exception as e:
print(e) print(e)
...@@ -42,19 +46,14 @@ def gen_token(request): ...@@ -42,19 +46,14 @@ def gen_token(request):
# #
# Function to change user password with a reset Token # Function to change user password with a reset Token
# ToDo: Implement Email after password change # ToDo: Implement Email after password change
# ToDo: Implement automatic redirection if succeeded in template
# #
def change_password(request, reset_hash=None): def change_password(request, reset_hash=None):
# logger = logging.getLogger("reset_password") pages["token_error"] = False
# Debug
for pw in PasswordResetToken.objects.all():
print(pw.hash)
#
try: try:
pw_reset_token = PasswordResetToken.objects.get(hash=reset_hash) pw_reset_token = PasswordResetToken.objects.get(hash=reset_hash)
time_difference = datetime.datetime.now() - pw_reset_token.created time_difference = datetime.datetime.now() - pw_reset_token.created
if time_difference.seconds/60 > PW_RESET_TOKEN_LIFETIME: if time_difference.seconds/60 > int(PW_RESET_TOKEN_LIFETIME):
pw_reset_token.delete() pw_reset_token.delete()
raise ValidationError("Token not valid") raise ValidationError("Token not valid")
...@@ -72,7 +71,5 @@ def change_password(request, reset_hash=None): ...@@ -72,7 +71,5 @@ def change_password(request, reset_hash=None):
except (ObjectDoesNotExist, ValidationError) as e: except (ObjectDoesNotExist, ValidationError) as e:
print(e) print(e)
pages["token_error"] = True pages["token_error"] = True
except Exception as e:
print(e)
return HttpResponse(render(request, 'warpauth/reset_password/change_password.html', pages)) return HttpResponse(render(request, 'warpauth/reset_password/change_password.html', pages))
...@@ -25,6 +25,15 @@ LDAP_GROUP_IS_ACTIVE = config.get('ldap','LDAP_GROUP_IS_ACTIVE') ...@@ -25,6 +25,15 @@ LDAP_GROUP_IS_ACTIVE = config.get('ldap','LDAP_GROUP_IS_ACTIVE')
LDAP_GROUP_IS_STAFF = config.get('ldap','LDAP_GROUP_IS_STAFF') LDAP_GROUP_IS_STAFF = config.get('ldap','LDAP_GROUP_IS_STAFF')
LDAP_GROUP_SUPERUSER = config.get('ldap','LDAP_GROUP_SUPERUSER') LDAP_GROUP_SUPERUSER = config.get('ldap','LDAP_GROUP_SUPERUSER')
# SMTP
EMAIL_BACKEND = 'django.core.mail.backends.smtp.EmailBackend'
EMAIL_HOST = config.get('email','SMTP_HOST')
EMAIL_HOST_USER = config.get('email','SMTP_USERNAME')
EMAIL_FROM = config.get('email','SMTP_EMAIL_FROM')
EMAIL_HOST_PASSWORD = config.get('email','SMTP_PASSWORD')
EMAIL_USE_TLS = config.get('email','SMTP_USE_TLS')
EMAIL_SUBJECT_PREFIX = config.get('email','SUBJECT_PREFIX')
# SECURITY # SECURITY
PW_RESET_TOKEN_LIFETIME = config.get('security','PW_RESET_TOKEN_LIFETIME') PW_RESET_TOKEN_LIFETIME = config.get('security','PW_RESET_TOKEN_LIFETIME')
SECRET_KEY = config.get('security','SECRET_KEY') SECRET_KEY = config.get('security','SECRET_KEY')
...@@ -53,7 +62,7 @@ INSTALLED_APPS = ( ...@@ -53,7 +62,7 @@ INSTALLED_APPS = (
# WARPPAY # WARPPAY
'rest_framework', 'rest_framework',
'rest_framework.authtoken', 'rest_framework.authtoken',
# 'warppay' 'warppay'
) )
MIDDLEWARE_CLASSES = ( MIDDLEWARE_CLASSES = (
...@@ -97,7 +106,7 @@ LOCALE_PATHS = ( ...@@ -97,7 +106,7 @@ LOCALE_PATHS = (
DATABASES = { DATABASES = {
'default': { 'default': {
'ENGINE': 'django.db.backends.sqlite3', 'ENGINE': 'django.db.backends.sqlite3',
'NAME': '/opt/database/warpzone.db' 'NAME': 'warpzone.db'
}, },
'ldap': { 'ldap': {
'ENGINE': 'ldapdb.backends.ldap', 'ENGINE': 'ldapdb.backends.ldap',
......
from django.core.mail import send_mail
from django.conf import settings
def send_email(to_address, subject, content):
try:
send_mail(
'[WarpInfra] %s' % subject,
content,
settings.EMAIL_FROM,
[to_address],
fail_silently=False,
)
return True
except Exception as e:
print(e)
return False
\ No newline at end of file
0% Loading or .
You are about to add 0 people to the discussion. Proceed with caution.
Finish editing this message first!
Please register or to comment