Coverage for airflow/contrib/auth/backends/ldap_auth.py: 58%

# Coverage for airflow/contrib/auth/backends/ldap_auth.py : 58%

## 92 statements 53 run 39 missing 0 excluded

Hot-keys on this page

r m x p toggle line displays

j k next/prev highlighted chunk

0 (zero) top of page

1 (one) first highlighted chunk

1 2 3 4 5 6 7 8 9 10 11 12 13 14 15 16 17 18 19 20 21 22 23 24 25 26 27 28 29 30 31 32 33 34 35 36 37 38 39 40 41 42 43 44 45 46 47 48 49 50 51 52 53 54 55 56 57 58 59 60 61 62 63 64 65 66 67 68 69 70 71 72 73 74 75 76 77 78 79 80 81 82 83 84 85 86 87 88 89 90 91 92 93 94 95 96 97 98 99 100 101 102 103 104 105 106 107 108 109 110 111 112 113 114 115 116 117 118 119 120 121 122 123 124 125 126 127 128 129 130 131 132 133 134 135 136 137 138 139 140 141 142 143 144 145 146 147 148 149 150 151 152 153 154 155 | import flask_login from flask_login import login_required, current_user, logout_user from flask import flash from wtforms import ( Form, PasswordField, StringField) from wtforms.validators import InputRequired from ldap3 import Server, Connection, Tls, LEVEL import ssl from flask import url_for, redirect from airflow import settings from airflow import models from airflow import configuration DEFAULT_USERNAME = 'airflow' login_manager = flask_login.LoginManager() login_manager.login_view = 'airflow.login' # Calls login() bellow login_manager.login_message = None class AuthenticationError(Exception): pass def get_ldap_connection(dn=None, password=None): tls_configuration = None use_ssl = False try: cacert = configuration.get("ldap", "cacert") tls_configuration = Tls(validate=ssl.CERT_REQUIRED, ca_certs_file=cacert) use_ssl = True except: pass server = Server(configuration.get("ldap", "uri"), use_ssl, tls_configuration) conn = Connection(server, dn, password) if not conn.bind(): raise AuthenticationError("Username or password incorrect") return conn class LdapUser(models.User): def __init__(self, user): self.user = user @staticmethod def try_login(username, password): conn = get_ldap_connection(configuration.get("ldap", "bind_user"), configuration.get("ldap", "bind_password")) search_filter = "(&({0})({1}={2}))".format( configuration.get("ldap", "user_filter"), configuration.get("ldap", "user_name_attr"), username ) # todo: BASE or ONELEVEL? res = conn.search(configuration.get("ldap", "basedn"), search_filter, search_scope=LEVEL) # todo: use list or result? if not res: raise AuthenticationError("Invalid username or password") entry = conn.response[0] conn.unbind() conn = get_ldap_connection(entry['dn'], password) if not conn: raise AuthenticationError("Invalid username or password") def is_active(self): '''Required by flask_login''' return True def is_authenticated(self): '''Required by flask_login''' return True def is_anonymous(self): '''Required by flask_login''' return False def data_profiling(self): '''Provides access to data profiling tools''' return True def is_superuser(self): '''Access all the things''' return True @login_manager.user_loader def load_user(userid): session = settings.Session() user = session.query(models.User).filter(models.User.id == userid).first() session.expunge_all() session.commit() session.close() return LdapUser(user) def login(self, request): if current_user.is_authenticated(): flash("You are already logged in") return redirect(url_for('admin.index')) username = None password = None form = LoginForm(request.form) if request.method == 'POST' and form.validate(): username = request.form.get("username") password = request.form.get("password") if not username or not password: return self.render('airflow/login.html', title="Airflow - Login", form=form) try: LdapUser.try_login(username, password) session = settings.Session() user = session.query(models.User).filter( models.User.username == DEFAULT_USERNAME).first() if not user: user = models.User( username=DEFAULT_USERNAME, is_superuser=True) session.merge(user) session.commit() flask_login.login_user(LdapUser(user)) session.commit() session.close() return redirect(request.args.get("next") or url_for("admin.index")) except AuthenticationError: flash("Incorrect login details") return self.render('airflow/login.html', title="Airflow - Login", form=form) class LoginForm(Form): username = StringField('Username', [InputRequired()]) password = PasswordField('Password', [InputRequired()])