From baf249473245ab40b7d3416b88468ccd6cf8f73c Mon Sep 17 00:00:00 2001 From: Aidaho12 Date: Thu, 8 Nov 2018 14:49:03 +0600 Subject: [PATCH] v3.3 Ldap support --- app/create_db.py | 53 +++++++++++++++++++++- app/login.py | 92 +++++++++++++++++++++++++++----------- app/options.py | 31 ++++++++++++- app/sql.py | 5 ++- app/templates/admin.html | 3 ++ app/templates/base.html | 2 +- app/templates/servers.html | 3 ++ app/users.py | 9 ++-- inc/users.js | 35 +++++++++++++++ install.sh | 4 +- requirements.txt | 3 +- update.sh | 4 +- 12 files changed, 207 insertions(+), 37 deletions(-) diff --git a/app/create_db.py b/app/create_db.py index 717b7164..7be68309 100644 --- a/app/create_db.py +++ b/app/create_db.py @@ -268,6 +268,53 @@ def update_db_v_3_2_8(**kwargs): return True cur.close() con.close() + + +def update_db_v_3_3(**kwargs): + con, cur = get_cur() + sql = [ "INSERT INTO settings (param, value, section, `desc`) values('ldap_enable', '0', 'ldap', 'If 1 ldap enabled');", + "INSERT INTO settings (param, value, section, `desc`) values('ldap_server', '', 'ldap', 'IP address ldap server');", + "INSERT INTO settings (param, value, section, `desc`) values('ldap_port', '389', 'ldap', 'Default port is 389 or 636');", + "INSERT INTO settings (param, value, section, `desc`) values('ldap_user', '', 'ldap', 'Login for connect to LDAP server. Enter: user@domain.com');", + "INSERT INTO settings (param, value, section, `desc`) values('ldap_password', '', 'ldap', 'Password for connect to LDAP server');", + "INSERT INTO settings (param, value, section, `desc`) values('ldap_base', '', 'ldap', 'Base domain. Example: dc=domain, dc=com');"] + try: + for i in sql: + cur.execute(i) + con.commit() + except sqltool.Error as e: + if kwargs.get('silent') != 1: + if e.args[0] == 'duplicate column name: desc' or e == "1060 (42S21): Duplicate column name 'desc' ": + print('Updating... go to version 3.2') + else: + print("An error occurred:", e) + return False + else: + pass + return True + cur.close() + con.close() + +def update_db_v_3_31(**kwargs): + con, cur = get_cur() + sql = """ + ALTER TABLE `user` ADD COLUMN ldap_user INTEGER NOT NULL DEFAULT 0; + """ + try: + cur.execute(sql) + con.commit() + except sqltool.Error as e: + if kwargs.get('silent') != 1: + if e.args[0] == 'duplicate column name: ldap_user' or e == " 1060 (42S21): Duplicate column name 'ldap_user' ": + print('Updating... go to version 3.3') + else: + print("An error occurred:", e) + return False + else: + print("DB was update to 3.3
") + return True + cur.close() + con.close() def update_all(): update_db_v_31() @@ -275,6 +322,8 @@ def update_all(): update_db_v_3_21() update_db_v_3_2_3() update_db_v_3_2_8() + update_db_v_3_3() + update_db_v_3_31() def update_all_silent(): update_db_v_31(silent=1) @@ -282,8 +331,10 @@ def update_all_silent(): update_db_v_3_21(silent=1) update_db_v_3_2_3(silent=1) update_db_v_3_2_8(silent=1) + update_db_v_3_3(silent=1) + update_db_v_3_31(silent=1) if __name__ == "__main__": create_table() update_all() - + \ No newline at end of file diff --git a/app/login.py b/app/login.py index 455a5e58..c90706c1 100644 --- a/app/login.py +++ b/app/login.py @@ -25,6 +25,60 @@ db_create = "" error_log = "" error = "" +def send_cookie(login): + session_ttl = int() + session_ttl = sql.get_setting('session_ttl') + session_ttl = int(session_ttl) + expires = datetime.datetime.utcnow() + datetime.timedelta(days=session_ttl) + user_uuid = str(uuid.uuid4()) + user_token = str(uuid.uuid4()) + + c = http.cookies.SimpleCookie(os.environ.get("HTTP_COOKIE")) + c["uuid"] = user_uuid + c["uuid"]["path"] = "/app/" + c["uuid"]["expires"] = expires.strftime("%a, %d %b %Y %H:%M:%S GMT") + print(c) + sql.write_user_uuid(login, user_uuid) + sql.write_user_token(login, user_token) + funct.logging('locahost', sql.get_user_name_by_uuid(user_uuid)+' log in') + print("Content-type: text/html\n") + print('ok') + sys.exit() + + +def check_in_ldap(user, password): + import ldap + + server = sql.get_setting('ldap_server') + port = sql.get_setting('ldap_port') + + l = ldap.initialize("ldap://"+server+':'+port) + try: + l.protocol_version = ldap.VERSION3 + l.set_option(ldap.OPT_REFERRALS, 0) + + bind = l.simple_bind_s(user, password) + except ldap.INVALID_CREDENTIALS: + print("Content-type: text/html\n") + print('
Invalid credentials


') + sys.exit() + except ldap.SERVER_DOWN: + print("Content-type: text/html\n") + print('
Server down') + sys.exit() + except ldap.LDAPError as e: + if type(e.message) == dict and e.message.has_key('desc'): + print("Content-type: text/html\n") + print('
Other LDAP error: %s


' % e.message['desc']) + sys.exit() + else: + print("Content-type: text/html\n") + print('
Other LDAP error: %s


' % e) + sys.exit() + + send_cookie(user) + + if ref is None: ref = "/index.html" @@ -57,33 +111,21 @@ if form.getvalue('logout'): if login is not None and password is not None: - USERS = sql.select_users() - session_ttl = int() - session_ttl = sql.get_setting('session_ttl') - session_ttl = int(session_ttl) - - expires = datetime.datetime.utcnow() + datetime.timedelta(days=session_ttl) - user_uuid = str(uuid.uuid4()) - user_token = str(uuid.uuid4()) - - for users in USERS: - if login in users[1] and password == users[3]: - c = http.cookies.SimpleCookie(os.environ.get("HTTP_COOKIE")) - c["uuid"] = user_uuid - c["uuid"]["path"] = "/app/" - c["uuid"]["expires"] = expires.strftime("%a, %d %b %Y %H:%M:%S GMT") - print(c) - sql.write_user_uuid(login, user_uuid) - sql.write_user_token(login, user_token) - funct.logging('locahost', sql.get_user_name_by_uuid(user_uuid)+' log in') - print("Content-type: text/html\n") - print('ok') - sys.exit() + USERS = sql.select_users(user=login) + for users in USERS: + if users[6] == 1: + if login in users[1]: + check_in_ldap(login, password) + else: + if login in users[1] and password == users[3]: + send_cookie(login) + else: + print("Content-type: text/html\n") + print('
Somthing wrong :( I\'m sad about this, but try again!


') + sys.exit() print("Content-type: text/html\n") - print('
Somthing wrong :( I\'m sad about this, but try again!


') - sys.exit() - + if login is None: print("Content-type: text/html\n") if create_db.check_db(): diff --git a/app/options.py b/app/options.py index 1aba94b6..c4ba5370 100644 --- a/app/options.py +++ b/app/options.py @@ -614,4 +614,33 @@ if form.getvalue('get_lists'): list = os.path.dirname(os.getcwd())+"/"+sql.get_setting('lists_path')+"/"+form.getvalue('group')+"/"+form.getvalue('color') lists = funct.get_files(dir=list, format="lst") for list in lists: - print(list) \ No newline at end of file + print(list) + +if form.getvalue('get_ldap_email'): + username = form.getvalue('get_ldap_email') + import ldap + + server = sql.get_setting('ldap_server') + port = sql.get_setting('ldap_port') + user = sql.get_setting('ldap_user') + password = sql.get_setting('ldap_password') + + l = ldap.initialize("ldap://"+server+':'+port) + try: + l.protocol_version = ldap.VERSION3 + l.set_option(ldap.OPT_REFERRALS, 0) + + bind = l.simple_bind_s(user, password) + + base = "dc=kar-tel, dc=local" + criteria = "(&(objectClass=user)(sAMAccountName="+username+"))" + attributes = ['mail'] + result = l.search_s(base, ldap.SCOPE_SUBTREE, criteria, attributes) + + results = [entry for dn, entry in result if isinstance(entry, dict)] + try: + print('["'+results[0]['mail'][0].decode("utf-8")+'","'+user.split('@')[1]+'"]') + except: + print('error: user not found') + finally: + l.unbind() \ No newline at end of file diff --git a/app/sql.py b/app/sql.py index aaa96e9d..017e61af 100644 --- a/app/sql.py +++ b/app/sql.py @@ -22,7 +22,10 @@ def out_error(e): def add_user(user, email, password, role, group): con, cur = create_db.get_cur() - sql = """INSERT INTO user (username, email, password, role, groups) VALUES ('%s', '%s', '%s', '%s', '%s')""" % (user, email, password, role, group) + if password != 'aduser': + sql = """INSERT INTO user (username, email, password, role, groups) VALUES ('%s', '%s', '%s', '%s', '%s')""" % (user, email, password, role, group) + else: + sql = """INSERT INTO user (username, email, role, groups, ldap_user) VALUES ('%s', '%s', '%s', '%s', '1')""" % (user, email, role, group) try: cur.execute(sql) con.commit() diff --git a/app/templates/admin.html b/app/templates/admin.html index f4e39337..ba5e31e3 100644 --- a/app/templates/admin.html +++ b/app/templates/admin.html @@ -447,6 +447,9 @@ + {% if ldap_enable == '1' %} + Search user in AD + {% endif %} diff --git a/app/templates/base.html b/app/templates/base.html index 52ea0375..8909863c 100644 --- a/app/templates/base.html +++ b/app/templates/base.html @@ -99,7 +99,7 @@ diff --git a/app/templates/servers.html b/app/templates/servers.html index ddc1411e..424b9ac4 100644 --- a/app/templates/servers.html +++ b/app/templates/servers.html @@ -340,6 +340,9 @@ + {% if ldap_enable == '1' %} + Search user in AD + {% endif %} diff --git a/app/users.py b/app/users.py index 8322f780..982ca0e2 100644 --- a/app/users.py +++ b/app/users.py @@ -1,7 +1,7 @@ #!/usr/bin/env python3 # -*- coding: utf-8 -*- -import html, http +import http import cgi import sys import os @@ -20,20 +20,23 @@ try: cookie = http.cookies.SimpleCookie(os.environ.get("HTTP_COOKIE")) user_id = cookie.get('uuid') user = sql.get_user_name_by_uuid(user_id.value) + users = sql.select_users() servers = sql.get_dick_permit() token = sql.get_token(user_id.value) + ldap_enable = sql.get_setting('ldap_enable') except: pass output_from_parsed_template = template.render(title = "Admin area: users manage", role = sql.get_user_role_by_uuid(user_id.value), user = user, - users = sql.select_users(), + users = users, groups = sql.select_groups(), servers = sql.select_servers(full=1), roles = sql.select_roles(), masters = sql.select_servers(get_master_servers=1), sshs = sql.select_ssh(), telegrams = sql.select_telegram(), - token = token) + token = token, + ldap_enable = ldap_enable) print(output_from_parsed_template) diff --git a/inc/users.js b/inc/users.js index 533c6ad7..de4f606a 100644 --- a/inc/users.js +++ b/inc/users.js @@ -362,6 +362,41 @@ $( function() { var id = $(this).attr('id').split('-'); updateTelegram(id[1]) }); + $('#search_ldap_user').click(function() { + var valid = true; + $('#error').remove(); + allFields = $( [] ).add( $('#new-username') ) + allFields.removeClass( "ui-state-error" ); + valid = valid && checkLength( $('#new-username'), "user name", 1 ); + user = $('#new-username').val() + if (valid) { + $.ajax( { + url: "options.py", + data: { + get_ldap_email: $('#new-username').val(), + token: $('#token').val() + }, + type: "GET", + success: function( data ) { + data = data.replace(/\s+/g,' '); + if (data.indexOf('error') != '-1') { + alert(data) + $('#new-email').val(''); + $('#new-password').attr('readonly', false); + $('#new-password').val(''); + } else { + var json = $.parseJSON(data); + $('.alert-danger').remove(); + $('#new-email').val(json[0]); + $('#new-username').val(user+'@'+json[1]); + $('#new-password').val('aduser'); + $('#new-password').attr('readonly', true); + } + } + } ); + clearTips(); + } + }); } ); diff --git a/install.sh b/install.sh index 18773ead..c209874e 100644 --- a/install.sh +++ b/install.sh @@ -40,7 +40,7 @@ echo "" echo "################################" if hash apt-get 2>/dev/null; then - apt-get install git net-tools lshw dos2unix apache2 gcc netcat python3.5 python3-pip g++ freetype2-demos libatlas-base-dev -y + apt-get install git net-tools lshw dos2unix apache2 gcc netcat python3.5 python3-pip g++ freetype2-demos libatlas-base-dev openldap-dev -y HTTPD_CONFIG="/etc/apache2/apache2.conf" HAPROXY_WI_VHOST_CONF="/etc/apache2/sites-enabled/haproxy-wi.conf" HTTPD_NAME="apache2" @@ -57,7 +57,7 @@ else yum -y install epel-release fi yum -y install https://centos7.iuscommunity.org/ius-release.rpm - yum -y install git nmap-ncat net-tools python35u dos2unix python35u-pip httpd python35u-devel gcc-c++ + yum -y install git nmap-ncat net-tools python35u dos2unix python35u-pip httpd python35u-devel gcc-c++ openldap-devel HTTPD_CONFIG="/etc/httpd/conf/httpd.conf" HAPROXY_WI_VHOST_CONF="/etc/httpd/conf.d/haproxy-wi.conf" HTTPD_NAME="httpd" diff --git a/requirements.txt b/requirements.txt index 1e6ff95c..1cd5b511 100644 --- a/requirements.txt +++ b/requirements.txt @@ -13,4 +13,5 @@ future==0.13.1 mysql-connector-python==8.0.11 Jinja2==2.10 pandas==0.22.0 -bokeh==0.13.0 \ No newline at end of file +bokeh==0.13.0 +python-ldap>=3.1.0 \ No newline at end of file diff --git a/update.sh b/update.sh index f4ab31c9..45e618ff 100644 --- a/update.sh +++ b/update.sh @@ -15,10 +15,10 @@ chmod +x app/*py chmod +x app/tools/*py if hash apt-get 2>/dev/null; then - apt-get install git net-tools lshw dos2unix apache2 gcc netcat python3-pip gcc-c++ -y + apt-get install git net-tools lshw dos2unix apache2 gcc netcat python3-pip gcc-c++ openldap-devel -y else yum -y install https://centos7.iuscommunity.org/ius-release.rpm - yum -y install git nmap-ncat net-tools python35u dos2unix python35u-pip httpd python35u-devel gcc-c++ + yum -y install git nmap-ncat net-tools python35u dos2unix python35u-pip httpd python35u-devel gcc-c++ openldap-devel fi cd app/