from ldap3 import Server, Connection, ALL from tornado.web import create_signed_value, decode_signed_value import pywebio from pywebio.input import * from pywebio.output import * from pywebio.session import * LDAP_AUTH_URL = "ldap://localhost:389" LDAP_AUTH_SEARCH_BASE = "dc=example,dc=org" SECRET = "encryption salt value" def ldap_authentication(user_name, user_pwd, auth_url, search_base): ldap_user_name = user_name.strip() ldap_user_pwd = user_pwd.strip() user = f'cn={ldap_user_name},{search_base}' server = Server(auth_url, get_info=ALL) connection = Connection(server, user=user, password=ldap_user_pwd) return connection.bind() def who(): user = input_group('Login', [ input("Username", name='username'), input("Password", type="password", name='password'), ]) if ldap_authentication(user['username'], user['password'], auth_url=LDAP_AUTH_URL, search_base=LDAP_AUTH_SEARCH_BASE): return user['username'] def persistent_auth(who, salt, expire_days=7): """Authenticate users and remember them for {expire_days} days. :param callback who: the function to auth user, it should return user name when auth succeed. :param str salt: salt value for encryption :param int expire_days: :return: user name """ # get token from user's web browser token = eval_js("localStorage.getItem(key)", key='token') # try to decrypt the username from the token, and ignore tokens created more than {expire_days} days ago username = decode_signed_value(salt, 'token', token, max_age_days=expire_days).decode("utf-8") if not token or not username: # no token or token validation failed while not username: username = who() if not username: toast('Auth failed, try again.', color='error') signed = create_signed_value(salt, 'token', username).decode("utf-8") # encrypt username to token run_js("localStorage.setItem(key, value)", key='token', value=signed) # set token to user's web browser return username def main(): user = persistent_auth(who, salt=SECRET) put_text('Welcome,', user) if __name__ == '__main__': pywebio.start_server(main, port=8080, debug=True)