init
This commit is contained in:
		
							
								
								
									
										3
									
								
								README.md
									
									
									
									
									
										Normal file
									
								
							
							
						
						
									
										3
									
								
								README.md
									
									
									
									
									
										Normal file
									
								
							@@ -0,0 +1,3 @@
 | 
				
			|||||||
 | 
					# Flask LDAP user management
 | 
				
			||||||
 | 
					
 | 
				
			||||||
 | 
					Web app for adding,delating and modifying users using LDAP
 | 
				
			||||||
							
								
								
									
										5
									
								
								luser/__init__.py
									
									
									
									
									
										Normal file
									
								
							
							
						
						
									
										5
									
								
								luser/__init__.py
									
									
									
									
									
										Normal file
									
								
							@@ -0,0 +1,5 @@
 | 
				
			|||||||
 | 
					from flask import Flask
 | 
				
			||||||
 | 
					
 | 
				
			||||||
 | 
					app = Flask(__name__)
 | 
				
			||||||
 | 
					
 | 
				
			||||||
 | 
					from luser import routes
 | 
				
			||||||
							
								
								
									
										203
									
								
								luser/models.py
									
									
									
									
									
										Normal file
									
								
							
							
						
						
									
										203
									
								
								luser/models.py
									
									
									
									
									
										Normal file
									
								
							@@ -0,0 +1,203 @@
 | 
				
			|||||||
 | 
					from ldap3 import Server,Connection,ALL,MODIFY_REPLACE
 | 
				
			||||||
 | 
					from datetime import datetime
 | 
				
			||||||
 | 
					
 | 
				
			||||||
 | 
					class LUSER():
 | 
				
			||||||
 | 
					    '''
 | 
				
			||||||
 | 
					        Class that represents secure connection to LDAP server
 | 
				
			||||||
 | 
					
 | 
				
			||||||
 | 
					        LDAPhost := string IP or hostname of LDAP server
 | 
				
			||||||
 | 
					        admin_user := string DN of LDAP admin user
 | 
				
			||||||
 | 
					        admin_pass := string password of LDAP admin user
 | 
				
			||||||
 | 
					        base := string base in LDAP system where users are made
 | 
				
			||||||
 | 
					        basealt := string base in LDAP system where users are made with password hashes generated for openalt
 | 
				
			||||||
 | 
					    '''
 | 
				
			||||||
 | 
					
 | 
				
			||||||
 | 
					    def __init__(self, ldap_host, admin_user, admin_pass, base, basealt=''):
 | 
				
			||||||
 | 
					        self.ldap_host = ldap_host
 | 
				
			||||||
 | 
					        self.admin_user = admin_user
 | 
				
			||||||
 | 
					        self.admin_pass = admin_pass
 | 
				
			||||||
 | 
					        self.base = base
 | 
				
			||||||
 | 
					        self.basealt = basealt
 | 
				
			||||||
 | 
					        self.alt = True
 | 
				
			||||||
 | 
					        ldapserver = Server(ldap_host, use_ssl=True)
 | 
				
			||||||
 | 
					        self.ldapconnection = Connection(ldapserver, admin_user, admin_pass, auto_bind=True)
 | 
				
			||||||
 | 
					
 | 
				
			||||||
 | 
					        # uid and gid of most recently registered users
 | 
				
			||||||
 | 
					        self.lastuid = 1337
 | 
				
			||||||
 | 
					        self.lastgid = 1337
 | 
				
			||||||
 | 
					
 | 
				
			||||||
 | 
					        # Set alt boolean to false if basealt not set
 | 
				
			||||||
 | 
					        if basealt == '':
 | 
				
			||||||
 | 
					            self.alt = False
 | 
				
			||||||
 | 
					
 | 
				
			||||||
 | 
					    def prepareluser(self):
 | 
				
			||||||
 | 
					        '''
 | 
				
			||||||
 | 
					           Create base on LDAP host
 | 
				
			||||||
 | 
					        '''
 | 
				
			||||||
 | 
					
 | 
				
			||||||
 | 
					        # Split base string with commas to find values of organization and dc
 | 
				
			||||||
 | 
					        baselist = self.base.split(",")
 | 
				
			||||||
 | 
					        basealtlist = self.basealt.split(",")
 | 
				
			||||||
 | 
					        
 | 
				
			||||||
 | 
					        # Find ou in base and set it as organization variable
 | 
				
			||||||
 | 
					        for i in baselist:
 | 
				
			||||||
 | 
					            if i.split('=')[0] == 'ou':
 | 
				
			||||||
 | 
					                organization = i.split('=')[1]
 | 
				
			||||||
 | 
					                break
 | 
				
			||||||
 | 
					
 | 
				
			||||||
 | 
					        for i in basealtlist:
 | 
				
			||||||
 | 
					            if i.split('=')[0] == 'ou':
 | 
				
			||||||
 | 
					                organizationalt = i.split('=')[1]
 | 
				
			||||||
 | 
					                break
 | 
				
			||||||
 | 
					
 | 
				
			||||||
 | 
					        # Find first dc and set it as dc variable        
 | 
				
			||||||
 | 
					        for i in baselist:
 | 
				
			||||||
 | 
					            if i.split('=')[0] == 'dc':
 | 
				
			||||||
 | 
					                dc = i.split('=')[1]
 | 
				
			||||||
 | 
					                break
 | 
				
			||||||
 | 
					
 | 
				
			||||||
 | 
					        for i in basealtlist:
 | 
				
			||||||
 | 
					            if i.split('=')[0] == 'dc':
 | 
				
			||||||
 | 
					                dcalt = i.split('=')[1]
 | 
				
			||||||
 | 
					                break
 | 
				
			||||||
 | 
					
 | 
				
			||||||
 | 
					        # Find full dc and set it as dcfull variable
 | 
				
			||||||
 | 
					        for i in baselist:
 | 
				
			||||||
 | 
					            if i.split('=')[0] == 'dc':
 | 
				
			||||||
 | 
					                dcfull += ',dc=' + i.split('=')[1]
 | 
				
			||||||
 | 
					
 | 
				
			||||||
 | 
					        for i in basealtlist:
 | 
				
			||||||
 | 
					            if i.split('=')[0] == 'dc':
 | 
				
			||||||
 | 
					                dcfullalt += ',dc=' + i.split('=')[1]
 | 
				
			||||||
 | 
					
 | 
				
			||||||
 | 
					        # Remove first column character
 | 
				
			||||||
 | 
					        dcfull = dcfull[1:]
 | 
				
			||||||
 | 
					        dcfullalt = dcfull[1:]
 | 
				
			||||||
 | 
					
 | 
				
			||||||
 | 
					        # Create organization on LDAP server and store boolean indicating it's success
 | 
				
			||||||
 | 
					
 | 
				
			||||||
 | 
					        rcode1 = self.ldapconnection.add(f'dc={dcfull}', ['dcObject', 'organization'], {'o' : dc, 'dc' : dc})
 | 
				
			||||||
 | 
					
 | 
				
			||||||
 | 
					        if self.alt:
 | 
				
			||||||
 | 
					            rcode2 = self.ldapconnection.add(f'dc={dcfullalt}', ['dcObject', 'organization'], {'o' : dcalt, 'dc' : dcalt})
 | 
				
			||||||
 | 
					        else:
 | 
				
			||||||
 | 
					            rcode2 = True
 | 
				
			||||||
 | 
					
 | 
				
			||||||
 | 
					        # Create organizational units on LDAP server and store boolean indicating it's success
 | 
				
			||||||
 | 
					
 | 
				
			||||||
 | 
					        rcode3 = self.ldapconnection.add(self.base, ['top', 'organizationalUnit'], {'ou' : organization})
 | 
				
			||||||
 | 
					
 | 
				
			||||||
 | 
					        if self.alt :
 | 
				
			||||||
 | 
					            rcode4 = self.ldapconnection.add(self.basealt, ['top', 'organizationalUnit'], {'ou' : organizationalt})
 | 
				
			||||||
 | 
					        else:
 | 
				
			||||||
 | 
					            rcode4 = True
 | 
				
			||||||
 | 
					
 | 
				
			||||||
 | 
					
 | 
				
			||||||
 | 
					        # Return True only if all return values are true
 | 
				
			||||||
 | 
					
 | 
				
			||||||
 | 
					        return rcode1 and rcode2 and rcode3 and rcode4
 | 
				
			||||||
 | 
					
 | 
				
			||||||
 | 
					    def lastpwchangenow(self):
 | 
				
			||||||
 | 
					        '''
 | 
				
			||||||
 | 
					            Return time of last password change for the user set to current time 
 | 
				
			||||||
 | 
					            messured in days from UNIX epoch
 | 
				
			||||||
 | 
					        '''
 | 
				
			||||||
 | 
					
 | 
				
			||||||
 | 
					        return str((datetime.utcnow() - datetime(1970,1,1)).days)
 | 
				
			||||||
 | 
					
 | 
				
			||||||
 | 
					    def add(self, user, password, althash=""):
 | 
				
			||||||
 | 
					        '''
 | 
				
			||||||
 | 
					            Add a user to base in LDAP with user and pass as credentials
 | 
				
			||||||
 | 
					            user := string containing username
 | 
				
			||||||
 | 
					            password := string containing user password
 | 
				
			||||||
 | 
					            althash := string containing user password/hash for the alternative base
 | 
				
			||||||
 | 
					        '''
 | 
				
			||||||
 | 
					
 | 
				
			||||||
 | 
					        # Increase UID and GID counters
 | 
				
			||||||
 | 
					        self.lastuid += 1
 | 
				
			||||||
 | 
					        self.lastgid += 1
 | 
				
			||||||
 | 
					
 | 
				
			||||||
 | 
					
 | 
				
			||||||
 | 
					        # Add user to base 
 | 
				
			||||||
 | 
					        id = f"uid={user}"
 | 
				
			||||||
 | 
					
 | 
				
			||||||
 | 
					        # Object classes of a user entry
 | 
				
			||||||
 | 
					        objectClass = ['top', 'person', 'organizationalPerson', 'inetOrgPerson', 'posixAccount', 'shadowAccount']
 | 
				
			||||||
 | 
					
 | 
				
			||||||
 | 
					        # Attributes for a user entry
 | 
				
			||||||
 | 
					        attributes = {'cn' : user, 'sn' : user, 'givenName' : user, 'uid' : user, 'uidNumber' : self.lastuid, 'gidNumber' : self.lastgid, 'homeDirectory' : f'/home/{user}', 'loginShell' : '/usr/bin/git-shell', 'gecos' : 'SystemUser', 'shadowLastChange' : self.lastpwchangenow(), 'shadowMax' : '45', 'userPassword' : password}
 | 
				
			||||||
 | 
					
 | 
				
			||||||
 | 
					        attributesalt = {'cn' : user, 'sn' : user, 'givenName' : user, 'uid' : user, 'uidNumber' : self.lastuid, 'gidNumber' : self.lastgid, 'homeDirectory' : f'/home/{user}', 'loginShell' : '/usr//bin/git-shell', 'gecos' : 'SystemUser', 'shadowLastChange' : self.lastpwchangenow(), 'shadowMax' : '45', 'userPassword' : althash}
 | 
				
			||||||
 | 
					
 | 
				
			||||||
 | 
					        # Return boolean value of new user entry
 | 
				
			||||||
 | 
					        rcode1 = self.ldapconnection.add(f'{id},{self.base}', objectClass, attributes)
 | 
				
			||||||
 | 
					
 | 
				
			||||||
 | 
					        # If alternative base is set add the same user to the alternative base as well, if not act as if it was success
 | 
				
			||||||
 | 
					        if self.alt:
 | 
				
			||||||
 | 
					            rcode2 = self.ldapconnection.add(f'{id},{self.basealt}', objectClass, attributesalt)
 | 
				
			||||||
 | 
					        else:
 | 
				
			||||||
 | 
					            rcode2 = True
 | 
				
			||||||
 | 
					
 | 
				
			||||||
 | 
					        # Return True only if both entries was successful
 | 
				
			||||||
 | 
					        return rcode1 and rcode2
 | 
				
			||||||
 | 
					
 | 
				
			||||||
 | 
					    def changepassword(self, user, newpass, althash=''):
 | 
				
			||||||
 | 
					        '''
 | 
				
			||||||
 | 
					            Change password of user to newpass
 | 
				
			||||||
 | 
					
 | 
				
			||||||
 | 
					            user := string containing username
 | 
				
			||||||
 | 
					            newpass := string containing new password
 | 
				
			||||||
 | 
					            althash := string containing password/hash for alternative base
 | 
				
			||||||
 | 
					        '''
 | 
				
			||||||
 | 
					        
 | 
				
			||||||
 | 
					        # This variable holds boolean indicating successful change of user password
 | 
				
			||||||
 | 
					        chpassbool = self.ldapconnection.modify(f'uid={user},{self.base}', {'userPassword': (MODIFY_REPLACE,[newpass])})
 | 
				
			||||||
 | 
					
 | 
				
			||||||
 | 
					        # If alternative base is set modify user password/hash with althash, if not, pretend change was successful
 | 
				
			||||||
 | 
					        if self.alt:
 | 
				
			||||||
 | 
					            chpassboolalt = self.ldapconnection.modify(f'uid={user},{self.basealt}', {'userPassword': (MODIFY_REPLACE,[althash])})
 | 
				
			||||||
 | 
					        else:
 | 
				
			||||||
 | 
					            chpassboolalt = True
 | 
				
			||||||
 | 
					
 | 
				
			||||||
 | 
					        # This variable holds boolean indicating successful change of shadowLastChange value to current time
 | 
				
			||||||
 | 
					        chlastchangebool = self.ldapconnection.modify(f'uid={user},{self.base}', {'shadowLastChange' : (MODIFY_REPLACE,[self.lastpwchangenow()])})
 | 
				
			||||||
 | 
					
 | 
				
			||||||
 | 
					        # If alternative base is set modify user password/hash with althash, if not, pretend change was successful
 | 
				
			||||||
 | 
					        if self.alt:
 | 
				
			||||||
 | 
					            chlastchangeboolalt = self.ldapconnection.modify(f'uid={user},{self.base}', {'shadowLastChange' : (MODIFY_REPLACE, [self.lastpwchangenow()])})
 | 
				
			||||||
 | 
					        else:
 | 
				
			||||||
 | 
					            chlastchangeboolalt = True
 | 
				
			||||||
 | 
					
 | 
				
			||||||
 | 
					        # Return True only if changing of both password and time of last password change was successful
 | 
				
			||||||
 | 
					        return chpassbool and chpassboolalt and chlastchangebool and chlastchangeboolalt
 | 
				
			||||||
 | 
					
 | 
				
			||||||
 | 
					    def delete(self, user):
 | 
				
			||||||
 | 
					        '''
 | 
				
			||||||
 | 
					           Delete user given username of user
 | 
				
			||||||
 | 
					
 | 
				
			||||||
 | 
					           user := string containing username
 | 
				
			||||||
 | 
					        '''
 | 
				
			||||||
 | 
					
 | 
				
			||||||
 | 
					        rcode1 = self.ldapconnection.delete(f'uid={user},{self.base}')
 | 
				
			||||||
 | 
					
 | 
				
			||||||
 | 
					        # If alternative base is set delete user from alternative base, if not, pretend deletion was successful
 | 
				
			||||||
 | 
					        if self.alt:
 | 
				
			||||||
 | 
					            rcode2 = self.ldapconnection.delete(f'uid={user},{self.basealt}')
 | 
				
			||||||
 | 
					        else:
 | 
				
			||||||
 | 
					            rcode2 = True
 | 
				
			||||||
 | 
					
 | 
				
			||||||
 | 
					        # Return True only if deletion from both bases was successful
 | 
				
			||||||
 | 
					        return rcode1 and rcode2
 | 
				
			||||||
 | 
					
 | 
				
			||||||
 | 
					    def getpassword(self, user):
 | 
				
			||||||
 | 
					        '''
 | 
				
			||||||
 | 
					           Retrive password of a user 
 | 
				
			||||||
 | 
					
 | 
				
			||||||
 | 
					           user := string containing username
 | 
				
			||||||
 | 
					        '''
 | 
				
			||||||
 | 
					
 | 
				
			||||||
 | 
					        # Search LDAP entries that have object class inetOrgPerson and uid attribute equal to given user field
 | 
				
			||||||
 | 
					        self.ldapconnection.search(search_base=self.base,search_filter=f'(&(objectClass=inetOrgPerson)(uid={user}))', attributes=['userPassword'])
 | 
				
			||||||
 | 
					
 | 
				
			||||||
 | 
					        # Return userPassword attribute from the response
 | 
				
			||||||
 | 
					        return self.ldapconnection.response[0]['attributes']['userPassword'][0].decode('utf-8')
 | 
				
			||||||
							
								
								
									
										129
									
								
								luser/routes.py
									
									
									
									
									
										Normal file
									
								
							
							
						
						
									
										129
									
								
								luser/routes.py
									
									
									
									
									
										Normal file
									
								
							@@ -0,0 +1,129 @@
 | 
				
			|||||||
 | 
					from flask import render_template, request, redirect
 | 
				
			||||||
 | 
					from luser import app
 | 
				
			||||||
 | 
					from luser.models import LUSER
 | 
				
			||||||
 | 
					from passlib.hash import ldap_salted_sha1,sha512_crypt
 | 
				
			||||||
 | 
					import subprocess
 | 
				
			||||||
 | 
					import random
 | 
				
			||||||
 | 
					import base64
 | 
				
			||||||
 | 
					import os
 | 
				
			||||||
 | 
					
 | 
				
			||||||
 | 
					LDAPHOST = 'ldap.example.org'
 | 
				
			||||||
 | 
					LDAPADMINNAME = 'cn=admin,dc=example,dc=org'
 | 
				
			||||||
 | 
					LDAPPASS = 'verysecr3t'
 | 
				
			||||||
 | 
					USERBASE = 'ou=Users,dc=example,dc=org'
 | 
				
			||||||
 | 
					ALTUSERBASE = '' # Optional
 | 
				
			||||||
 | 
					CAPTCHA_PATH = '/var/luser/luser/static/account/register/captcha_img/'
 | 
				
			||||||
 | 
					
 | 
				
			||||||
 | 
					@app.route('/account/changepassword/', methods=['POST', 'GET'])
 | 
				
			||||||
 | 
					def changepassword():
 | 
				
			||||||
 | 
					    if request.method == 'GET':
 | 
				
			||||||
 | 
					        return render_template('changepassword.html')
 | 
				
			||||||
 | 
					    elif request.method == 'POST':
 | 
				
			||||||
 | 
					        username = request.form['username']
 | 
				
			||||||
 | 
					        oldpassword = request.form['oldpassword']
 | 
				
			||||||
 | 
					        newpassword = request.form['newpassword']
 | 
				
			||||||
 | 
					
 | 
				
			||||||
 | 
					        # Check lenght of password
 | 
				
			||||||
 | 
					        if len(newpassword) < 8:
 | 
				
			||||||
 | 
					            return 'Error: password is too short'
 | 
				
			||||||
 | 
					
 | 
				
			||||||
 | 
					        # Create a LUSER connection
 | 
				
			||||||
 | 
					        luser = LUSER(LDAPHOST,LDAPADMINNAME,LDAPPASS,USERBASE,ALTUSERBASE)
 | 
				
			||||||
 | 
					
 | 
				
			||||||
 | 
					        if ldap_salted_sha1.verify(oldpassword, luser.getpassword(username)) == False:
 | 
				
			||||||
 | 
					                return 'Wrong username/password combination'
 | 
				
			||||||
 | 
					
 | 
				
			||||||
 | 
					        ldaphash = ldap_salted_sha1.hash(newpassword)
 | 
				
			||||||
 | 
					        althash = sha512_crypt.hash(newpassword)
 | 
				
			||||||
 | 
					
 | 
				
			||||||
 | 
					        # Try to change user password
 | 
				
			||||||
 | 
					        try:
 | 
				
			||||||
 | 
					            if luser.changepassword(username, ldaphash, althash) == True:
 | 
				
			||||||
 | 
					                return 'User password successfuly changed'
 | 
				
			||||||
 | 
					            else:
 | 
				
			||||||
 | 
					                return 'User password change failed'
 | 
				
			||||||
 | 
					        except:
 | 
				
			||||||
 | 
					            return 'User password change failed, exception raised'
 | 
				
			||||||
 | 
					    else:
 | 
				
			||||||
 | 
					        return 'HTTP request method not recogniezed'
 | 
				
			||||||
 | 
					
 | 
				
			||||||
 | 
					@app.route('/account/unregister/', methods=['POST', 'GET'])
 | 
				
			||||||
 | 
					def unregister():
 | 
				
			||||||
 | 
					    if request.method == 'GET':
 | 
				
			||||||
 | 
					        return render_template('unregister.html')
 | 
				
			||||||
 | 
					    elif request.method == 'POST':
 | 
				
			||||||
 | 
					        username = request.form['username']
 | 
				
			||||||
 | 
					        password = request.form['password']
 | 
				
			||||||
 | 
					
 | 
				
			||||||
 | 
					        # Create a LUSER connection
 | 
				
			||||||
 | 
					        luser = LUSER(LDAPHOST,LDAPADMINNAME,LDAPPASS,USERBASE,ALTUSERBASE)
 | 
				
			||||||
 | 
					
 | 
				
			||||||
 | 
					        if ldap_salted_sha1.verify(password, luser.getpassword(username)) == False:
 | 
				
			||||||
 | 
					                return 'Wrong username/password combination'
 | 
				
			||||||
 | 
					
 | 
				
			||||||
 | 
					        # Try to delete user
 | 
				
			||||||
 | 
					        try:
 | 
				
			||||||
 | 
					            if luser.delete(username) == True:
 | 
				
			||||||
 | 
					                return 'User successfuly unregistered'
 | 
				
			||||||
 | 
					            else:
 | 
				
			||||||
 | 
					                return 'User unregistration failed'
 | 
				
			||||||
 | 
					        except:
 | 
				
			||||||
 | 
					            return 'User unregistration failed, exception raised'
 | 
				
			||||||
 | 
					    else:
 | 
				
			||||||
 | 
					        return 'HTTP request method not recogniezed'
 | 
				
			||||||
 | 
					
 | 
				
			||||||
 | 
					@app.route('/account/register/', methods=['POST', 'GET'])
 | 
				
			||||||
 | 
					def register():
 | 
				
			||||||
 | 
					    if request.method == 'GET':
 | 
				
			||||||
 | 
					        captcha_solution = str(random.randint(0,999999))
 | 
				
			||||||
 | 
					        captcha_hash = ldap_salted_sha1.hash(captcha_solution)
 | 
				
			||||||
 | 
					        captcha_filename = base64.b64encode(captcha_hash.encode('utf-8')).decode('utf-8')[8:-1] + ".png"
 | 
				
			||||||
 | 
					        captcha_path = CAPTCHA_PATH + captcha_filename
 | 
				
			||||||
 | 
					        captcha_file = open(captcha_path, 'w')
 | 
				
			||||||
 | 
					        subprocess.run(["/usr/local/bin/captcha.sh",captcha_solution],stdout=captcha_file)
 | 
				
			||||||
 | 
					        return render_template('register.html',imgsrc=captcha_filename,captchahash=captcha_hash)
 | 
				
			||||||
 | 
					    elif request.method == 'POST':
 | 
				
			||||||
 | 
					        username = request.form['username']
 | 
				
			||||||
 | 
					        password = request.form['password']
 | 
				
			||||||
 | 
					        captcha_answer = request.form['captchaa']
 | 
				
			||||||
 | 
					        captcha_filename = request.form['captchaq']
 | 
				
			||||||
 | 
					        captcha_path = CAPTCHA_PATH + captcha_filename
 | 
				
			||||||
 | 
					
 | 
				
			||||||
 | 
					        if captcha_filename[:-4].isalnum() == False and len(captcha_filename) != 47 :
 | 
				
			||||||
 | 
					            return 'Error: Captcha question is manipulated'
 | 
				
			||||||
 | 
					
 | 
				
			||||||
 | 
					        captcha_valid = True
 | 
				
			||||||
 | 
					
 | 
				
			||||||
 | 
					        if os.path.exists(captcha_path) == False:
 | 
				
			||||||
 | 
					            captcha_valid = False
 | 
				
			||||||
 | 
					        else:
 | 
				
			||||||
 | 
					            os.remove(captcha_path)
 | 
				
			||||||
 | 
					
 | 
				
			||||||
 | 
					        captcha_hash = base64.b64decode(base64.b64encode(b"{SSHA}").decode('utf-8') + captcha_filename[:-4] + "=").decode('utf-8')
 | 
				
			||||||
 | 
					
 | 
				
			||||||
 | 
					        if ldap_salted_sha1.verify(captcha_answer, captcha_hash) == False:
 | 
				
			||||||
 | 
					            captcha_valid = False
 | 
				
			||||||
 | 
					
 | 
				
			||||||
 | 
					        if captcha_valid == False:
 | 
				
			||||||
 | 
					            return 'Error: Captcha is wrong!'
 | 
				
			||||||
 | 
					
 | 
				
			||||||
 | 
					        # Check lenght of password
 | 
				
			||||||
 | 
					        if len(password) < 8:
 | 
				
			||||||
 | 
					            return 'Error: password is too short'
 | 
				
			||||||
 | 
					
 | 
				
			||||||
 | 
					        # Create a LUSER connection
 | 
				
			||||||
 | 
					        luser = LUSER(LDAPHOST,LDAPADMINNAME,LDAPPASS,USERBASE,ALTUSERBASE)
 | 
				
			||||||
 | 
					        # Try to add user
 | 
				
			||||||
 | 
					        try:
 | 
				
			||||||
 | 
					            ldaphash = ldap_salted_sha1.hash(password)
 | 
				
			||||||
 | 
					            althash = sha512_crypt.hash(password)
 | 
				
			||||||
 | 
					            #smtpctlout=subprocess.run(["smtpctl","encrypt", password],text=True,stdout=subprocess.PIPE)
 | 
				
			||||||
 | 
					            #smtpdhash=smtpctlout.stdout[:-1]
 | 
				
			||||||
 | 
					            if luser.add(username,ldaphash,althash):
 | 
				
			||||||
 | 
					                return 'User successfuly registered'
 | 
				
			||||||
 | 
					            else:
 | 
				
			||||||
 | 
					                return 'User registration failed, username probably taken'
 | 
				
			||||||
 | 
					        except:
 | 
				
			||||||
 | 
					            return 'User registration failed, exception raised'
 | 
				
			||||||
 | 
					    else:
 | 
				
			||||||
 | 
					        return 'HTTP request method not recogniezed'
 | 
				
			||||||
							
								
								
									
										35
									
								
								luser/templates/changepassword.html
									
									
									
									
									
										Normal file
									
								
							
							
						
						
									
										35
									
								
								luser/templates/changepassword.html
									
									
									
									
									
										Normal file
									
								
							@@ -0,0 +1,35 @@
 | 
				
			|||||||
 | 
					<!DOCTYPE html>
 | 
				
			||||||
 | 
					<html lang="sr">
 | 
				
			||||||
 | 
					<head>
 | 
				
			||||||
 | 
					    <meta charset="UTF-8">
 | 
				
			||||||
 | 
					    <meta name="viewport" content="width=device-width, initial-scale=1.0">
 | 
				
			||||||
 | 
					    <title>User password change in LDAP system</title>
 | 
				
			||||||
 | 
					    <style>
 | 
				
			||||||
 | 
					        .container {
 | 
				
			||||||
 | 
					            max-width:900px;
 | 
				
			||||||
 | 
					            margin: 0 auto;
 | 
				
			||||||
 | 
					            font-family: Arial, Helvetica, sans-serif;
 | 
				
			||||||
 | 
					            color: #3d3d3d;
 | 
				
			||||||
 | 
					        }
 | 
				
			||||||
 | 
					
 | 
				
			||||||
 | 
					        body {
 | 
				
			||||||
 | 
					            background-color: #e6e6e6;
 | 
				
			||||||
 | 
					        }
 | 
				
			||||||
 | 
					    </style>
 | 
				
			||||||
 | 
					</head>
 | 
				
			||||||
 | 
					<body>
 | 
				
			||||||
 | 
					   <main class="container">
 | 
				
			||||||
 | 
					        <h1 style="text-align:center;">Change password</h1>
 | 
				
			||||||
 | 
					        <form action="/account/changepassword/" method="POST" style="text-align:center;">
 | 
				
			||||||
 | 
					            <label for="username">username</label>
 | 
				
			||||||
 | 
					            <input type="text" name="username" id="username" placeholder="username" required>
 | 
				
			||||||
 | 
					            <label for="oldpassword">oldpassword</label>
 | 
				
			||||||
 | 
					            <input type="password" name="oldpassword" id="oldpassword" placeholder="oldpassword" required>
 | 
				
			||||||
 | 
					            <label for="newpassword">newpassword</label>
 | 
				
			||||||
 | 
					            <input type="password" name="newpassword" id="newpassword" placeholder="newpassword" required>
 | 
				
			||||||
 | 
					            <br>
 | 
				
			||||||
 | 
					            <button>Change Password</button>
 | 
				
			||||||
 | 
					        </form>
 | 
				
			||||||
 | 
					   </main> 
 | 
				
			||||||
 | 
					</body>
 | 
				
			||||||
 | 
					</html>
 | 
				
			||||||
							
								
								
									
										39
									
								
								luser/templates/register.html
									
									
									
									
									
										Normal file
									
								
							
							
						
						
									
										39
									
								
								luser/templates/register.html
									
									
									
									
									
										Normal file
									
								
							@@ -0,0 +1,39 @@
 | 
				
			|||||||
 | 
					<!DOCTYPE html>
 | 
				
			||||||
 | 
					<html lang="sr">
 | 
				
			||||||
 | 
					<head>
 | 
				
			||||||
 | 
					    <meta charset="UTF-8">
 | 
				
			||||||
 | 
					    <meta name="viewport" content="width=device-width, initial-scale=1.0">
 | 
				
			||||||
 | 
					    <title>User registration to LDAP system</title>
 | 
				
			||||||
 | 
					    <style>
 | 
				
			||||||
 | 
					        .container {
 | 
				
			||||||
 | 
					            max-width:900px;
 | 
				
			||||||
 | 
					            margin: 0 auto;
 | 
				
			||||||
 | 
					            font-family: Arial, Helvetica, sans-serif;
 | 
				
			||||||
 | 
					            color: #3d3d3d;
 | 
				
			||||||
 | 
					        }
 | 
				
			||||||
 | 
					
 | 
				
			||||||
 | 
					        body {
 | 
				
			||||||
 | 
					            background-color: #e6e6e6;
 | 
				
			||||||
 | 
					        }
 | 
				
			||||||
 | 
					    </style>
 | 
				
			||||||
 | 
					</head>
 | 
				
			||||||
 | 
					<body>
 | 
				
			||||||
 | 
					   <main class="container">
 | 
				
			||||||
 | 
					        <h1 style="text-align:center;">Register</h1>
 | 
				
			||||||
 | 
					        <form action="/account/register/" method="POST" style="text-align:center;">
 | 
				
			||||||
 | 
					            <label for="username">username</label>
 | 
				
			||||||
 | 
					            <input type="text" name="username" id="username" placeholder="username" required>
 | 
				
			||||||
 | 
					            <label for="password">password</label>
 | 
				
			||||||
 | 
					            <input type="password" name="password" id="password" placeholder="password" required>
 | 
				
			||||||
 | 
					            <p>password must be at least 8 characters long<p>
 | 
				
			||||||
 | 
					            <br>
 | 
				
			||||||
 | 
					            <img src=/account/register/captcha_img/{{ imgsrc }} alt="{{ captchahash }}" style="width:200">
 | 
				
			||||||
 | 
					            <p>
 | 
				
			||||||
 | 
					            <label for="captcha answer">captcha answer</label>
 | 
				
			||||||
 | 
					            <input type="text" name="captchaa" id="captchaa" placeholder="captcha answer" required>
 | 
				
			||||||
 | 
					            <input type="hidden" name="captchaq" id="captchaq"  value="{{ imgsrc }}">
 | 
				
			||||||
 | 
					            <button>Register</button>
 | 
				
			||||||
 | 
					        </form>
 | 
				
			||||||
 | 
					   </main> 
 | 
				
			||||||
 | 
					</body>
 | 
				
			||||||
 | 
					</html>
 | 
				
			||||||
							
								
								
									
										33
									
								
								luser/templates/unregister.html
									
									
									
									
									
										Normal file
									
								
							
							
						
						
									
										33
									
								
								luser/templates/unregister.html
									
									
									
									
									
										Normal file
									
								
							@@ -0,0 +1,33 @@
 | 
				
			|||||||
 | 
					<!DOCTYPE html>
 | 
				
			||||||
 | 
					<html lang="sr">
 | 
				
			||||||
 | 
					<head>
 | 
				
			||||||
 | 
					    <meta charset="UTF-8">
 | 
				
			||||||
 | 
					    <meta name="viewport" content="width=device-width, initial-scale=1.0">
 | 
				
			||||||
 | 
					    <title>User unregistration to LDAP system</title>
 | 
				
			||||||
 | 
					    <style>
 | 
				
			||||||
 | 
					        .container {
 | 
				
			||||||
 | 
					            max-width:900px;
 | 
				
			||||||
 | 
					            margin: 0 auto;
 | 
				
			||||||
 | 
					            font-family: Arial, Helvetica, sans-serif;
 | 
				
			||||||
 | 
					            color: #3d3d3d;
 | 
				
			||||||
 | 
					        }
 | 
				
			||||||
 | 
					
 | 
				
			||||||
 | 
					        body {
 | 
				
			||||||
 | 
					            background-color: #e6e6e6;
 | 
				
			||||||
 | 
					        }
 | 
				
			||||||
 | 
					    </style>
 | 
				
			||||||
 | 
					</head>
 | 
				
			||||||
 | 
					<body>
 | 
				
			||||||
 | 
					   <main class="container">
 | 
				
			||||||
 | 
					        <h1 style="text-align:center;">Unregister</h1>
 | 
				
			||||||
 | 
					        <form action="/account/unregister/" method="POST" style="text-align:center;">
 | 
				
			||||||
 | 
					            <label for="username">username</label>
 | 
				
			||||||
 | 
					            <input type="text" name="username" id="username" placeholder="username" required>
 | 
				
			||||||
 | 
					            <label for="password">password</label>
 | 
				
			||||||
 | 
					            <input type="password" name="password" id="password" placeholder="password" required>
 | 
				
			||||||
 | 
					            <br>
 | 
				
			||||||
 | 
					            <button>Unregister</button>
 | 
				
			||||||
 | 
					        </form>
 | 
				
			||||||
 | 
					   </main> 
 | 
				
			||||||
 | 
					</body>
 | 
				
			||||||
 | 
					</html>
 | 
				
			||||||
		Reference in New Issue
	
	Block a user