예제 #1
0
    def put(self, *args, **kwargs):
        if not self.is_superuser:
            return self.write(dict(code=-1, msg='不是超级管理员,没有权限'))

        data = json.loads(self.request.body.decode("utf-8"))
        user_list = data.get('user_list', None)

        if len(user_list) != 1:
            return self.write(dict(code=-2, msg='一次只能选择一个用户,且不能为空'))

        user_id = user_list[0]
        with DBContext('r') as session:
            user_info = session.query(Users).filter(
                Users.user_id == user_id).first()

        ### 生成token
        if user_info.superuser == '0':
            is_superuser = True
        else:
            is_superuser = False

        token_info = dict(user_id=user_id,
                          username=user_info.username,
                          nickname=user_info.nickname,
                          is_superuser=is_superuser,
                          exp_time=1100)
        auth_token = AuthToken()
        auth_key = auth_token.encode_auth_token_v2(**token_info)
        if isinstance(auth_key, bytes): auth_key = auth_key.decode()

        redis_conn = cache_conn()
        configs_init('all')
        config_info = redis_conn.hgetall(const.APP_SETTINGS)
        config_info = convert(config_info)
        obj = SendMail(
            mail_host=config_info.get(const.EMAIL_HOST),
            mail_port=config_info.get(const.EMAIL_PORT),
            mail_user=config_info.get(const.EMAIL_HOST_USER),
            mail_password=config_info.get(const.EMAIL_HOST_PASSWORD),
            mail_ssl=True
            if config_info.get(const.EMAIL_USE_SSL) == '1' else False,
            mail_tls=True
            if config_info.get(const.EMAIL_USE_TLS) == '1' else False)

        with DBContext('w', None, True) as session:
            mail_to = session.query(Users.email).filter(
                Users.user_id == self.get_current_id()).first()

        if mail_to[0] == user_info.email:
            obj.send_mail(mail_to[0], '令牌,有效期三年', auth_key, subtype='plain')
        else:
            obj.send_mail(mail_to[0], '令牌,有效期三年', auth_key, subtype='plain')
            obj.send_mail(user_info.email,
                          '令牌,有效期三年',
                          auth_key,
                          subtype='plain')
        return self.write(dict(code=0, msg='Token已经发送到邮箱', data=auth_key))
예제 #2
0
    def prepare(self):

        # 验证客户端CSRF,如请求为GET,则不验证,否则验证。最后将写入新的key
        cache = get_cache()
        if self.request.method != 'GET':
            csrf_key = self.get_cookie('csrf_key')
            pipeline = cache.get_pipeline()
            result = cache.get(csrf_key, private=False, pipeline=pipeline)
            cache.delete(csrf_key, private=False, pipeline=pipeline)
            if result != '1':
                raise HTTPError(400, 'csrf error')

        cache.set(self.new_csrf_key, 1, expire=1800, private=False)
        self.set_cookie('csrf_key', self.new_csrf_key)

        ### 登陆验证
        auth_key = self.get_cookie('auth_key', None)
        if not auth_key:
            # 没登录,就让跳到登陆页面
            raise HTTPError(401, 'auth failed 1')

        else:
            auth_token = AuthToken()
            user_info = auth_token.decode_auth_token(auth_key)
            self.user_id = user_info.get('user_id', None)
            self.username = user_info.get('username', None)
            self.nickname = user_info.get('nickname', None)
            self.is_super = user_info.get('is_superuser', False)

            if not self.user_id:
                raise HTTPError(401, 'auth failed 2')
            else:
                self.user_id = str(self.user_id)
                self.set_secure_cookie("user_id", self.user_id)
                self.set_secure_cookie("nickname", self.nickname)
                self.set_secure_cookie("username", self.username)

        self.is_superuser = self.is_super
        ## 此处为示例, 如果通过API给个鉴权,则注释
        ### 如果不是超级管理员,开始鉴权
        # my_verify = MyVerify(self.user_id)
        # if self.is_super:
        #     # 没权限,就让跳到权限页面 0代表有权限,1代表没权限
        #     if not my_verify.get_verify(self.request.method, self.request.uri):
        #         '''如果没有权限,就刷新一次权限'''
        #         my_verify.write_verify()
        #
        #     if not my_verify.get_verify(self.request.method, self.request.uri):
        #         raise HTTPError(403, 'request forbidden!')

        ### 写入日志 改为网关收集
예제 #3
0
    def prepare(self):

        # 验证客户端CSRF,如请求为GET,则不验证,否则验证。最后将写入新的key
        cache = get_cache()
        if self.request.method not in ("GET", "HEAD", "OPTIONS"):
            csrf_key = self.get_cookie('csrf_key')
            pipeline = cache.get_pipeline()
            result = cache.get(csrf_key, private=False, pipeline=pipeline)
            cache.delete(csrf_key, private=False, pipeline=pipeline)
            if result != '1':
                raise HTTPError(402, 'csrf error')

        cache.set(self.new_csrf_key, 1, expire=1800, private=False)
        self.set_cookie('csrf_key', self.new_csrf_key)

        # 登陆验证
        auth_key = self.get_cookie('auth_key', None)
        if not auth_key:
            if Authentication_KEY in self.request.headers.keys():
                try:
                    auth_key = self.request.headers[Authentication_KEY].split()[1]
                except:
                    print("不是 JWT-token 格式")

        if not auth_key:
            url_auth_key = self.get_argument('auth_key', default=None, strip=True)
            if url_auth_key:
                auth_key = bytes(url_auth_key, encoding='utf-8')

        if not auth_key:
            raise HTTPError(401, '用户认证失败')

        user_info = AuthToken().decode_auth_token(auth_key)
        self.user = user_info
예제 #4
0
    def prepare(self):

        # 验证客户端CSRF,如请求为GET,则不验证,否则验证。最后将写入新的key
        cache = get_cache()
        if self.request.method != 'GET':
            csrf_key = self.get_cookie('csrf_key')
            pipeline = cache.get_pipeline()
            result = cache.get(csrf_key, private=False, pipeline=pipeline)
            cache.delete(csrf_key, private=False, pipeline=pipeline)
            if result != '1':
                raise HTTPError(402, 'csrf error')

        cache.set(self.new_csrf_key, 1, expire=1800, private=False)
        self.set_cookie('csrf_key', self.new_csrf_key)

        ### 登陆验证
        auth_key = self.get_cookie('auth_key', None)
        if not auth_key:
            # 没登录,就让跳到登陆页面
            raise HTTPError(401, 'auth failed 1')

        else:
            auth_token = AuthToken()
            user_info = auth_token.decode_auth_token(auth_key)
            self.user_id = user_info.get('user_id', None)
            self.username = user_info.get('username', None)
            self.nickname = user_info.get('nickname', None)
            self.email = user_info.get('email', None)
            self.is_super = user_info.get('is_superuser', False)

            if not self.user_id:
                raise HTTPError(401, 'auth failed 2')
            else:
                self.user_id = str(self.user_id)
                self.set_secure_cookie("user_id", self.user_id)
                self.set_secure_cookie("nickname", self.nickname)
                self.set_secure_cookie("username", self.username)
                self.set_secure_cookie("email", str(self.email))

        self.is_superuser = self.is_super
예제 #5
0
    def codo_login(self):
        ### 登陆验证
        auth_key = self.get_cookie('auth_key', None)
        if not auth_key:
            url_auth_key = self.get_argument('auth_key',
                                             default=None,
                                             strip=True)
            if url_auth_key: auth_key = bytes(url_auth_key, encoding='utf-8')

        if not auth_key: raise HTTPError(401, 'auth failed')

        if self.token_verify:
            auth_token = AuthToken()
            user_info = auth_token.decode_auth_token(auth_key)
        else:
            user_info = jwt.decode(auth_key,
                                   options={
                                       "verify_signature": False
                                   }).get('data')

        if not user_info: raise HTTPError(401, 'auth failed')

        self.user_id = user_info.get('user_id', None)
        self.username = user_info.get('username', None)
        self.nickname = user_info.get('nickname', None)
        self.email = user_info.get('email', None)
        self.is_super = user_info.get('is_superuser', False)

        if not self.user_id: raise HTTPError(401, 'auth failed')

        self.user_id = str(self.user_id)
        self.set_secure_cookie("user_id", self.user_id)
        self.set_secure_cookie("nickname", self.nickname)
        self.set_secure_cookie("username", self.username)
        self.set_secure_cookie("email", str(self.email))
        self.is_superuser = self.is_super
예제 #6
0
    def post(self, *args, **kwargs):
        data = json.loads(self.request.body.decode("utf-8"))
        username = data.get('username', None)
        password = data.get('password', None)
        dynamic = data.get('dynamic', None)

        if not username or not password: return self.write(dict(code=-1, msg='账号密码不能为空'))

        redis_conn = cache_conn()
        configs_init('all')
        if is_mail(username):
            login_mail = redis_conn.hget(const.APP_SETTINGS, const.EMAILLOGIN_DOMAIN)
            if login_mail:
                if is_mail(username, login_mail.decode('utf-8')):
                    email = username
                    username = email.split("@")[0]
                    email_server = redis_conn.hget(const.APP_SETTINGS, const.EMAILLOGIN_SERVER).decode('utf-8')
                    if not email_server:
                        return self.write(dict(code=-9, msg='请配置邮箱服务的SMTP服务地址'))

                    if not mail_login(email, password, email_server):
                        return self.write(dict(code=-2, msg='邮箱登陆认证失败'))

                    with DBContext('r') as session:
                        user_info = session.query(Users).filter(Users.email == email, Users.username == username,
                                                                Users.status != '10').first()
                    if not user_info:
                        return self.write(dict(code=-3, msg='邮箱认证通过,请根据邮箱完善用户信息', username=username, email=email))

        else:
            with DBContext('r') as session:
                user_info = session.query(Users).filter(Users.username == username, Users.password == gen_md5(password),
                                                        Users.status != '10').first()

            if not user_info:
                # redis_conn = cache_conn()
                # configs_init('all')
                ldap_login = redis_conn.hget(const.APP_SETTINGS, const.LDAP_ENABLE)
                ldap_login = convert(ldap_login)
                if ldap_login != '1':
                    return self.write(dict(code=-4, msg='账号密码错误'))

                ### 如果开启了LDAP认证 则进行LDAP认证
                else:
                    ####
                    config_info = redis_conn.hgetall(const.APP_SETTINGS)
                    config_info = convert(config_info)
                    ldap_ssl = True if config_info.get(const.LDAP_USE_SSL) == '1' else False

                    obj = LdapApi(config_info.get(const.LDAP_SERVER_HOST), config_info.get(const.LDAP_ADMIN_DN),
                                  config_info.get(const.LDAP_ADMIN_PASSWORD),
                                  int(config_info.get(const.LDAP_SERVER_PORT, 389)),
                                  ldap_ssl)

                    ldap_pass_info = obj.ldap_auth(username, password, config_info.get(const.LDAP_SEARCH_BASE),
                                                   config_info.get(const.LDAP_SEARCH_FILTER))

                    if ldap_pass_info[0]:
                        with DBContext('r') as session:
                            if not ldap_pass_info[2]:
                                return self.write(dict(code=-11, msg='LDAP认证成功,但是没有找到用户邮箱,请完善!'))
                            else:
                                user_info = session.query(Users).filter(Users.email == ldap_pass_info[2],
                                                                        Users.username == username,
                                                                        Users.status != '10').first()
                            if not user_info:
                                return self.write(dict(code=-3, msg='LDAP认证通过,完善用户信息', username=ldap_pass_info[1],
                                                       email=ldap_pass_info[2]))
                    else:
                        return self.write(dict(code=-4, msg='账号密码错误'))

        if 'user_info' not in dir():
            return self.write(dict(code=-4, msg='账号异常'))

        if user_info.status != '0':
            return self.write(dict(code=-4, msg='账号被禁用'))

        is_superuser = True if user_info.superuser == '0' else False

        ### 如果被标记为必须动态验证切没有输入动态密钥,则跳转到二维码添加密钥的地方
        ### 默认为 True, False 则全局禁用MFA
        mfa_global = False if convert(redis_conn.hget(const.APP_SETTINGS, const.MFA_GLOBAL)) == '1' else True
        if mfa_global and user_info.google_key:
            if not dynamic:
                ### 第一次不带MFA的认证
                return self.write(dict(code=1, msg='跳转二次认证'))
            else:
                ### 二次认证
                t_otp = pyotp.TOTP(user_info.google_key)
                if t_otp.now() != str(dynamic):
                    return self.write(dict(code=-5, msg='MFA错误'))

        user_id = str(user_info.user_id)
        ### 生成token 并写入cookie
        token_exp_hours = redis_conn.hget(const.APP_SETTINGS, const.TOKEN_EXP_TIME)
        if token_exp_hours and convert(token_exp_hours):
            token_info = dict(user_id=user_id, username=user_info.username, nickname=user_info.nickname,
                              email=user_info.email, is_superuser=is_superuser, exp_hours=token_exp_hours)
        else:
            token_info = dict(user_id=user_id, username=user_info.username, nickname=user_info.nickname,
                              email=user_info.email, is_superuser=is_superuser)
        auth_token = AuthToken()
        auth_key = auth_token.encode_auth_token_v2(**token_info)
        login_ip_list = self.request.headers.get("X-Forwarded-For")
        if login_ip_list:
            login_ip = login_ip_list.split(",")[0]
            with DBContext('w', None, True) as session:
                session.query(Users).filter(Users.user_id == user_id).update({Users.last_ip: login_ip})
                session.commit()

        self.set_secure_cookie("nickname", user_info.nickname)
        self.set_secure_cookie("username", user_info.username)
        self.set_secure_cookie("user_id", str(user_info.user_id))
        self.set_cookie('auth_key', auth_key, expires_days=1)

        ### 后端权限写入缓存
        my_verify = MyVerify(user_id, is_superuser)
        my_verify.write_verify()
        ### 前端权限写入缓存
        # get_user_rules(user_id, is_superuser)

        return self.write(dict(code=0, auth_key=auth_key.decode(), username=user_info.username,
                               nickname=user_info.nickname, msg='登录成功'))
예제 #7
0
    def post(self, *args, **kwargs):
        data = json.loads(self.request.body.decode("utf-8"))
        username = data.get('username', None)
        password = data.get('password', None)
        dynamic = data.get('dynamic', None)
        next_url = data.get('next_url', None)

        if not username or not password:
            return self.write(dict(code=-1, msg='账号密码不能为空'))
        if is_mail(username):
            redis_conn = cache_conn()
            configs_init('all')
            login_mail = redis_conn.hget(const.APP_SETTINGS,
                                         const.EMAILLOGIN_DOMAIN)
            if login_mail:
                if is_mail(username, login_mail.decode('utf-8')):
                    email = username
                    username = email.split("@")[0]
                    email_server = redis_conn.hget(
                        const.APP_SETTINGS,
                        const.EMAILLOGIN_SERVER).decode('utf-8')
                    if not email_server:
                        return self.write(dict(code=-9,
                                               msg='请配置邮箱服务的SMTP服务地址'))

                    if not mail_login(email, password, email_server):
                        return self.write(dict(code=-2, msg='邮箱登陆认证失败'))

                    with DBContext('r') as session:
                        user_info = session.query(Users).filter(
                            Users.email == email, Users.username == username,
                            Users.status != '10').first()
                    if not user_info:
                        return self.write(
                            dict(code=-3,
                                 msg='邮箱认证通过,请根据邮箱完善用户信息',
                                 email=email))

        else:
            with DBContext('r') as session:
                user_info = session.query(Users).filter(
                    Users.username == username,
                    Users.password == gen_md5(password),
                    Users.status != '10').first()

            if not user_info:
                return self.write(dict(code=-4, msg='账号密码错误'))

        if user_info.status != '0':
            return self.write(dict(code=-4, msg='账号被禁用'))

        if user_info.superuser == '0':
            is_superuser = True
        else:
            is_superuser = False

        ### 如果被标记为必须动态验证切没有输入动态密钥,则跳转到二维码添加密钥的地方
        if user_info.google_key:
            totp = pyotp.TOTP(user_info.google_key)
            if dynamic:
                if totp.now() != str(dynamic):
                    return self.write(dict(code=-5, msg='MFA错误'))

            else:
                return self.write(dict(code=-8, msg='请输入MFA'))

        user_id = str(user_info.user_id)
        ### 生成token 并写入cookie
        token_info = dict(user_id=user_id,
                          username=user_info.username,
                          nickname=user_info.nickname,
                          is_superuser=is_superuser)
        auth_token = AuthToken()
        auth_key = auth_token.encode_auth_token(**token_info)
        login_ip_list = self.request.headers.get("X-Forwarded-For")
        if login_ip_list:
            login_ip = login_ip_list.split(",")[0]
            with DBContext('w', None, True) as session:
                session.query(Users).filter(Users.user_id == user_id).update(
                    {Users.last_ip: login_ip})

        self.set_secure_cookie("nickname", user_info.nickname)
        self.set_secure_cookie("username", user_info.username)
        self.set_secure_cookie("user_id", str(user_info.user_id))
        self.set_cookie('auth_key', auth_key, expires_days=1)

        ### 后端权限写入缓存
        my_verify = MyVerify(user_id)
        my_verify.write_verify()
        ### 前端权限写入缓存
        get_user_rules(user_id)

        return self.write(
            dict(code=0,
                 auth_key=auth_key.decode(encoding="utf-8"),
                 username=user_info.username,
                 nickname=user_info.nickname,
                 next_url=next_url,
                 msg='登录成功'))