You can not select more than 25 topics Topics must start with a letter or number, can include dashes ('-') and can be up to 35 characters long.
 
 
 

97 lines
2.5 KiB

  1. #!/usr/bin/env python3
  2. import os
  3. from os import path
  4. from configparser import ConfigParser
  5. import bottle
  6. from bottle import get, post, static_file, request, route, template
  7. from bottle import SimpleTemplate
  8. import ldap
  9. @get('/')
  10. def get_index():
  11. return index_tpl()
  12. @post('/')
  13. def post_index():
  14. form = request.forms.getunicode
  15. def error(msg):
  16. return index_tpl(username=form('username'), alerts=[('error', msg)])
  17. if form('new-password') != form('confirm-password'):
  18. return error("Password doesn't match the confirmation!")
  19. if len(form('new-password')) < 8:
  20. return error("Password must be at least 8 characters long!")
  21. try:
  22. ldap_change_password(form('username'),
  23. form('old-password'), form('new-password'))
  24. except Error as e:
  25. print("Unsuccessful attemp to change password for {}: {}"
  26. .format(form('username'), str(e)))
  27. return error(str(e))
  28. print("Password successfully changed for: {}"
  29. .format(form('username')))
  30. return index_tpl(alerts=[('success', "Password has been changed")])
  31. @route('/static/<filename>', name='static')
  32. def serve_static(filename):
  33. return static_file(filename, root=path.join(BASE_DIR, 'static'))
  34. def index_tpl(**kwargs):
  35. return template('index', **kwargs)
  36. def ldap_change_password(username, old, new):
  37. dn_name = "uid={},{}".format(username, CONF['ldap']['base'])
  38. l = ldap.initialize(CONF['ldap']['host'])
  39. l.set_option(ldap.OPT_X_TLS_CACERTFILE, CONF['ldap']['tls_cacert'])
  40. l.set_option(ldap.OPT_X_TLS, ldap.OPT_X_TLS_DEMAND)
  41. if CONF['ldap']['tls'] == "True":
  42. l.start_tls_s()
  43. l.simple_bind_s(dn_name, old)
  44. l.passwd_s(dn_name, old, new)
  45. l.unbind_s()
  46. def read_config():
  47. config = ConfigParser()
  48. config.read([path.join(BASE_DIR, 'settings.ini'),
  49. os.getenv('CONF_FILE', '')])
  50. return config
  51. class Error(Exception):
  52. pass
  53. BASE_DIR = path.dirname(__file__)
  54. CONF = read_config()
  55. ldap.set_option(ldap.OPT_X_TLS_REQUIRE_CERT, ldap.OPT_X_TLS_NEVER)
  56. bottle.TEMPLATE_PATH = [BASE_DIR]
  57. # Set default attributes to pass into templates.
  58. SimpleTemplate.defaults = dict(CONF['html'])
  59. SimpleTemplate.defaults['url'] = bottle.url
  60. # Run bottle internal server when invoked directly (mainly for development).
  61. if __name__ == '__main__':
  62. bottle.run(**CONF['server'])
  63. # Run bottle in application mode (in production under uWSGI server).
  64. else:
  65. application = bottle.default_app()