Pārlūkot izejas kodu

support ldap login

laiwei 8 gadi atpakaļ
vecāks
revīzija
90764f7aa0
6 mainītis faili ar 89 papildinājumiem un 2 dzēšanām
  1. 1 0
      pip_requirements.txt
  2. 8 0
      rrd/config.py
  3. 2 1
      rrd/static/js/g.js
  4. 1 1
      rrd/view/__init__.py
  5. 25 0
      rrd/view/auth/auth.py
  6. 52 0
      rrd/view/utils.py

+ 1 - 0
pip_requirements.txt

@@ -5,3 +5,4 @@ gunicorn==18.0
 python-dateutil==2.2
 requests==2.3.0
 mysql-python
+python-ldap

+ 8 - 0
rrd/config.py

@@ -18,6 +18,14 @@ DB_USER = "root"
 DB_PASS = ""
 DB_NAME = "falcon_portal"
 
+# ldap config
+LDAP_ENABLED = False
+LDAP_SERVER = "ldap.forumsys.com:389"
+LDAP_BASE_DN = "dc=example,dc=com"
+LDAP_BINDDN_FMT = "uid=%s,dc=example,dc=com"
+LDAP_SEARCH_FMT = "uid=%s"
+LDAP_ATTRS = ["cn","mail","telephoneNumber"]
+
 # portal site config
 MAINTAINERS = ['root']
 CONTACT = 'root@open-falcon.org'

+ 2 - 1
rrd/static/js/g.js

@@ -49,7 +49,8 @@ function login() {
 	}
 	$.post('/auth/login', {
 		'name' : $('#name').val(),
-		'password' : $("#password").val()
+		'password' : $("#password").val(),
+        'ldap' : useLdap
 	}, function(json) {
 		if (json.msg.length > 0) {
 			err_message_quietly(json.msg);

+ 1 - 1
rrd/view/__init__.py

@@ -22,7 +22,7 @@ def app_before():
     g.user = get_current_user_profile(g.user_token)
 
     path = request.path
-    if not g.user and not path.startswith("/auth/login"):
+    if not g.user and not path.startswith("/auth/login") and not path.startswith("/static/"):
         return redirect("/auth/login")
 
     if path.startswith("/screen"):

+ 25 - 0
rrd/view/auth/auth.py

@@ -4,6 +4,7 @@ import requests
 import json
 from rrd import app
 from rrd import config
+from rrd.model.user import User
 from rrd.view import utils as view_utils
 
 from rrd.utils.logger import logging
@@ -22,10 +23,34 @@ def auth_login():
 
         name = request.form.get("name")
         password = request.form.get("password")
+        ldap = request.form.get("ldap") or "0"
+
         if not name or not password:
             ret["msg"] = "no name or password"
             return json.dumps(ret)
 
+        if ldap == "1":
+            try:
+                ldap_info = view_utils.ldap_login_user(name, password)
+
+                h = {"Content-type":"application/json"}
+                d = {
+                    "name": name,
+                    "password": password,
+                    "cnname": ldap_info['cnname'],
+                    "email": ldap_info['email'],
+                    "phone": ldap_info['phone'],
+                }
+
+                r = requests.post("%s/user/create" %(config.API_ADDR,), \
+                        data=json.dumps(d), headers=h)
+                log.debug("%s:%s" %(r.status_code, r.text))
+
+                #TODO: update password in db if ldap password changed
+            except Exception as e:
+                ret["msg"] = str(e)
+                return json.dumps(ret)
+
         try:
             ut = view_utils.login_user(name, password)
             if not ut:

+ 52 - 0
rrd/view/utils.py

@@ -10,6 +10,9 @@ from rrd import corelib
 from rrd.utils import randbytes
 from rrd.model.user import User, UserToken
 
+from rrd.utils.logger import logging
+log = logging.getLogger(__file__)
+
 def remote_ip():
     if not request.headers.getlist("X-Forward-For"):
         return request.remote_addr
@@ -98,3 +101,52 @@ def login_user(name, password):
     set_user_cookie(ut, session)
     return ut
 
+
+def ldap_login_user(name, password):
+    import ldap
+    if not config.LDAP_ENABLED:
+        raise Exception("ldap not enabled")
+
+    bind_dn = config.LDAP_BINDDN_FMT
+    try:
+        bind_dn = config.LDAP_BINDDN_FMT %name
+    except TypeError: pass
+
+    search_filter = config.LDAP_SEARCH_FMT
+    try:
+        search_filter = config.LDAP_SEARCH_FMT %name
+    except TypeError: pass
+    print bind_dn
+    print search_filter
+
+    cli = None
+    try:
+        ldap_server = config.LDAP_SERVER if config.LDAP_SERVER.startswith("ldap://") else "ldap://%s" %config.LDAP_SERVER
+        log.debug("bind_dn=%s base_dn=%s filter=%s attrs=%s" %(bind_dn, config.LDAP_BASE_DN, search_filter, config.LDAP_ATTRS))
+        cli = ldap.initialize(ldap_server)
+        cli.bind_s(bind_dn, password)
+        result = cli.search_s(config.LDAP_BASE_DN, ldap.SCOPE_SUBTREE, search_filter, config.LDAP_ATTRS)
+        log.debug("ldap result: %s" % result)
+        d = result[0][1]
+        email = d['mail'][0]
+        cnname = d['cn'][0]
+        if 'telephoneNumber' in d:
+            phone = d['telephoneNumber'] and d['telephoneNumber'][0] or ""
+        else:
+            phone = ""
+    
+        return {
+                "name": name,
+                "password": password,
+                "cnname": cnname,
+                "email": email,
+                "phone": phone,
+        }
+    except ldap.LDAPError as e:
+        cli and cli.unbind_s()
+        raise e
+    except (IndexError, KeyError) as e:
+        raise e
+    finally:
+        cli and cli.unbind_s()
+