forked from unit/ldap-panel
96 lines
2.4 KiB
Python
Executable File
96 lines
2.4 KiB
Python
Executable File
#!/usr/bin/env python3
|
|
|
|
import os
|
|
from os import path
|
|
|
|
from configparser import ConfigParser
|
|
|
|
import bottle
|
|
from bottle import get, post, static_file, request, route, template
|
|
from bottle import SimpleTemplate
|
|
|
|
import ldap
|
|
|
|
|
|
@get('/')
|
|
def get_index():
|
|
return index_tpl()
|
|
|
|
|
|
@post('/')
|
|
def post_index():
|
|
form = request.forms.getunicode
|
|
|
|
def error(msg):
|
|
return index_tpl(username=form('username'), alerts=[('error', msg)])
|
|
|
|
if form('new-password') != form('confirm-password'):
|
|
return error("Password doesn't match the confirmation!")
|
|
|
|
if len(form('new-password')) < 8:
|
|
return error("Password must be at least 8 characters long!")
|
|
|
|
try:
|
|
ldap_change_password(form('username'),
|
|
form('old-password'), form('new-password'))
|
|
except Exception as exc:
|
|
print(f"Unsuccessful attempt to change password for {form('username')}: {exc=}")
|
|
return error(str(exc))
|
|
|
|
print("Password successfully changed for: {}"
|
|
.format(form('username')))
|
|
|
|
return index_tpl(alerts=[('success', "Password has been changed")])
|
|
|
|
|
|
@route('/static/<filename>', name='static')
|
|
def serve_static(filename):
|
|
return static_file(filename, root=path.join(BASE_DIR, 'static'))
|
|
|
|
|
|
def index_tpl(**kwargs):
|
|
return template('index', **kwargs)
|
|
|
|
|
|
def ldap_change_password(username, old, new):
|
|
dn_name = "uid={},{}".format(username, CONF['ldap']['base'])
|
|
l = ldap.initialize(CONF['ldap']['host'])
|
|
l.set_option(ldap.OPT_X_TLS_CACERTFILE, CONF['ldap']['tls_cacert'])
|
|
l.set_option(ldap.OPT_X_TLS, ldap.OPT_X_TLS_DEMAND)
|
|
if CONF['ldap']['tls'] == "True":
|
|
l.start_tls_s()
|
|
l.simple_bind_s(dn_name, old)
|
|
l.passwd_s(dn_name, old, new)
|
|
l.unbind_s()
|
|
|
|
|
|
def read_config():
|
|
config = ConfigParser()
|
|
config.read([path.join(BASE_DIR, 'settings.ini'),
|
|
os.getenv('CONF_FILE', '')])
|
|
return config
|
|
|
|
|
|
class Error(Exception):
|
|
pass
|
|
|
|
|
|
BASE_DIR = path.dirname(__file__)
|
|
CONF = read_config()
|
|
|
|
ldap.set_option(ldap.OPT_X_TLS_REQUIRE_CERT, ldap.OPT_X_TLS_NEVER)
|
|
|
|
bottle.TEMPLATE_PATH = [BASE_DIR]
|
|
|
|
# Set default attributes to pass into templates.
|
|
SimpleTemplate.defaults = dict(CONF['html'])
|
|
SimpleTemplate.defaults['url'] = bottle.url
|
|
|
|
|
|
# Run bottle internal server when invoked directly (mainly for development).
|
|
if __name__ == '__main__':
|
|
bottle.run(**CONF['server'])
|
|
# Run bottle in application mode (in production under uWSGI server).
|
|
else:
|
|
application = bottle.default_app()
|