123456789101112131415161718192021222324252627282930313233343536373839404142434445464748495051525354555657585960616263646566676869707172737475767778798081828384858687888990919293949596979899100101102103104105106107108109110111112113114115116117118119120121122123124125126127128129130131132133134135136137138139140141142143144145146147148149150151152153154155156157158159160161162163164165166167168169170171172173174175176177178179180181182183184185186187188189190191192193194195196197198199200201202203204205206207208209210211212213214215216217218219220221222223224225226227228229230231232233234 |
- #-*- coding:utf-8 -*-
- # Copyright 2017 Xiaomi, Inc.
- #
- # Licensed under the Apache License, Version 2.0 (the "License");
- # you may not use this file except in compliance with the License.
- # You may obtain a copy of the License at
- #
- # http://www.apache.org/licenses/LICENSE-2.0
- #
- # Unless required by applicable law or agreed to in writing, software
- # distributed under the License is distributed on an "AS IS" BASIS,
- # WITHOUT WARRANTIES OR CONDITIONS OF ANY KIND, either express or implied.
- # See the License for the specific language governing permissions and
- # limitations under the License.
- import json
- import requests
- from flask import g, redirect, session, abort, request
- from functools import wraps
- from rrd import config
- 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
- else:
- return request.headers.getlist("X-Forward-For")[0]
- def require_login(redir="/auth/login"):
- def _(f):
- @wraps(f)
- def __(*a, **kw):
- if not g.user:
- return redirect(redir or "/auth/login")
- return f(*a, **kw)
- return __
- return _
- def require_login_abort(status_code=403, msg="login first"):
- def _(f):
- @wraps(f)
- def __(*a, **kw):
- if not g.user:
- return abort(status_code, msg)
- return f(*a, **kw)
- return __
- return _
- def require_login_json(json_msg={"ok":False, "msg":"login first"}):
- def _(f):
- @wraps(f)
- def __(*a, **kw):
- if not g.user:
- return json.dumps(json_msg)
- return f(*a, **kw)
- return __
- return _
- def set_user_cookie(user_token, session_):
- if not user_token:
- return None
- session_[config.SITE_COOKIE] = "%s:%s" % (user_token.name, user_token.sig)
- def clear_user_cookie(session_):
- session_[config.SITE_COOKIE] = ""
- def get_usertoken_from_session(session_):
- if config.SITE_COOKIE in session_:
- cookies = session_[config.SITE_COOKIE]
- if not cookies:
- return None
- name, sig = cookies.split(":")
- return UserToken(name, sig)
- def get_current_user_profile(user_token):
- if not user_token:
- return
- h = {"Content-type": "application/json"}
- r = corelib.auth_requests("GET", "%s/user/current" %config.API_ADDR, headers=h)
- if r.status_code != 200:
- return
- j = r.json()
- return User(j["id"], j["name"], j["cnname"], j["email"], j["phone"], j["im"], j["qq"], j["role"])
- def logout_user(user_token):
- if not user_token:
- return
- r = corelib.auth_requests("GET", "%s/user/logout" %config.API_ADDR)
- if r.status_code != 200:
- raise Exception("%s:%s" %(r.status_code, r.text))
- clear_user_cookie(session)
- def login_user(name, password):
- params = {
- "name": name,
- "password": password,
- }
- r = requests.post("%s/user/login" %config.API_ADDR, data=params)
- if r.status_code != 200:
- raise Exception("%s : %s" %(r.status_code, r.text))
- j = r.json()
- ut = UserToken(j["name"], j["sig"])
- set_user_cookie(ut, session)
- return ut
- def admin_login_user(name, Apitoken):
- params = {
- "name": name,
- }
- h = {
- "Apitoken": Apitoken
- }
- r = requests.post("%s/admin/login" %config.API_ADDR, data=params, headers=h)
- log.debug("%s:%s" %(r.status_code, r.text))
- if r.status_code != 200:
- if json.loads(r.text)["error"] == "no such user":
- return None
- else:
- raise Exception("%s : %s" %(r.status_code, r.text))
- j = r.json()
- ut = UserToken(j["name"], j["sig"])
- 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
- bind_pass = config.LDAP_BIND_PASS
- base_dn = config.LDAP_BASE_DN
- search_filter = config.LDAP_SEARCH_FMT
- try:
- search_filter = config.LDAP_SEARCH_FMT %name
- except TypeError: pass
- cli = None
- try:
- ldap_server = config.LDAP_SERVER if (config.LDAP_SERVER.startswith("ldap://") or config.LDAP_SERVER.startswith("ldaps://")) else "ldaps://%s" % config.LDAP_SERVER if config.LDAP_TLS_START_TLS else "ldap://%s" % config.LDAP_SERVER
- log.debug("ldap_server:%s bind_dn:%s base_dn:%s filter:%s attrs:%s" %(ldap_server, bind_dn, config.LDAP_BASE_DN, search_filter, config.LDAP_ATTRS))
- cli = ldap.initialize(ldap_server)
- cli.protocol_version = ldap.VERSION3
- if config.LDAP_TLS_START_TLS or ldap_server.startswith('ldaps://'):
- if config.LDAP_TLS_CACERTFILE:
- cli.set_option(ldap.OPT_X_TLS_CACERTFILE, config.LDAP_TLS_CACERTFILE)
- if config.LDAP_TLS_CERTFILE:
- cli.set_option(ldap.OPT_X_TLS_CERTFILE, config.LDAP_TLS_CERTFILE)
- if config.LDAP_TLS_KEYFILE:
- cli.set_option(ldap.OPT_X_TLS_KEYFILE, config.LDAP_TLS_KEYFILE)
- if config.LDAP_TLS_REQUIRE_CERT:
- cli.set_option(ldap.OPT_X_TLS_REQUIRE_CERT, config.LDAP_TLS_REQUIRE_CERT)
- if config.LDAP_TLS_CIPHER_SUITE:
- cli.set_option(ldap.OPT_X_TLS_CIPHER_SUITE, config.LDAP_TLS_CIPHER_SUITE)
- cli.bind_s(bind_dn, bind_pass, ldap.AUTH_SIMPLE)
- result = cli.search_s(base_dn, ldap.SCOPE_SUBTREE, search_filter, config.LDAP_ATTRS)
- log.debug("ldap result: %s" % result)
- user_dn = result[0][0]
- cli.bind_s(user_dn, password, ldap.AUTH_SIMPLE)
- d = result[0][1]
- email = d['mail'][0]
- cnname = d['cn'][0]
- if 'sn' in d and 'givenName' in d:
- cnname = d['givenName'][0] + ' ' + d['sn'][0]
- if 'displayName' in d:
- cnname = d['displayName'][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:
- if "desc" in e[0]:
- raise NameError(e[0]["desc"])
- cli and cli.unbind_s()
- raise e
- except (IndexError, KeyError) as e:
- if str(e) == "list index out of range":
- raise IndexError("no such user")
- # result = [], so result out of range
- raise e
- finally:
- cli and cli.unbind_s()
- def get_Apitoken(name, password):
- d = {
- "name": name, "password": password,
- }
-
- h = {"Content-type":"application/json"}
-
- r = requests.post("%s/user/login" %(config.API_ADDR,), \
- data=json.dumps(d), headers=h)
- log.debug("%s:%s" %(r.status_code, r.text))
-
- if r.status_code != 200:
- raise Exception("%s %s" %(r.status_code, r.text))
- sig = json.loads(r.text)["sig"]
- return json.dumps({"name":name,"sig":sig})
- def create_user(user_info):
- h = {"Content-type":"application/json"}
-
- r = requests.post("%s/user/create" %(config.API_ADDR,), \
- data=json.dumps(user_info), headers=h)
- log.debug("%s:%s" %(r.status_code, r.text))
-
- if r.status_code != 200:
- raise Exception("%s %s" %(r.status_code, r.text))
-
- return
|