예제 #1
0
    def set_password(self, password):
        """
        修改密码, 同时修改所有关联帐号的密码
        @param password 新密码
        @return [users]
        """
        hash = auth.encode_password(password)
        plain_password = auth.encode_plain_password(password)
        username_prefix = self.phone_number + ('js' if self.type == 3 else 'xs')
        with db.user as c:
            users = c.auth_user.filter(username__startswith=username_prefix, type=self.type)[:]
            if users:
                user_ids = [u.id for u in users]
                c.auth_user.filter(id__in=user_ids).update(password=hash)
                c.auth_profile.filter(user_id__in=user_ids).update(password=plain_password)
            self.auser.password = hash
            self.password = hash
            if self.aprofile:
                self.aprofile.password = plain_password

            # 更新缓存
            for user in users:
                user.password = hash
                cache.auth_user.set(user.id, user)
                if self.aprofile:
                    cache.auth_profile.set(user.id, self.aprofile)
                else:
                    cache.auth_profile.delete(user.id)

            return users
예제 #2
0
def import_user(user_type, phone_number, real_name, gender=1, join_unit_id=0, subject_id=0, sn_code='', send_pwd=0):
    """
    导入用户资料, 如果是短信开通则open_option="open",如果验证码开通sn_code不能为空,二者选其一
    -------------------------------------------
    徐威       2015-03-22
    王晨光     2017-06-06
    -------------------------------------------
    :param user_type: 用户类型 1学生 3老师
    :param phone_number: 手机号
    :param real_name: 姓名
    :param join_unit_id: 要加入的班级ID
    :param sn_code: 二次短信验证码
    :param subject_id: 开通学科ID
        subject_id 和 sn_code 都为空则暂不开通
    :param send_pwd: 是否发送帐号密码 1是 0否
    :return: (新用户ID, error)
    """
    username = find_a_username(user_type, phone_number)
    nowt = int(time.time())
    password = "".join(random.sample('1234567890', 6))  # 随机生成6位密码
    # 创建auth_user
    if db.user.auth_user.filter(username=username).exists():
        return None, u"用户已存在"
    user_id = db.user.auth_user.create(
        username=username,
        password=auth.encode_password(password),
        type=user_type,
        real_name=real_name,
        date_joined=nowt,
        status=1,
        sid=0,
        grade_id=0,
        phone=phone_number,
        platform_id=1
    )
    db.user.auth_profile.create(
        user_id=user_id,
        nickname=real_name,
        sex=1,
        password=auth.encode_plain_password(password)
    )
    if not user_id:
        return None, u"用户已存在"
    user = db.user.auth_user.get(id=user_id)
    # 加入班级
    join_unit_class_by_id(user, join_unit_id)

    # 是否发送账号密码
    if send_pwd:
        send_password([user_id])
    return user_id, None
예제 #3
0
def phone_login(request):
    """
    @api {post} /account/login/web [登录]WEB登录
    @apiGroup account
    @apiParamExample {json} 请求示例
    {
        "username":"******",
        "password":"******",
        "pass_flag": 1      # 0 以前的老接口,不加密,  1 现在的新程序,加密
    }
    @apiParam {String} username 手机号或帐号
    @apiParam {String} password 密码
    @apiSuccessExample {json} 成功返回
    {
        "next": "",
        "error": "",
        "message": "",
        "data": [
            {
                "real_name": "张三",
                "school_name": "创恒中学",
                "unit_name": "100班",
                "type":1,
                "portrait": "头像",
                "tbkt_token": "有效期7天的token"
            },
        ],
        "response": "ok"
    }
    * type = 1 学生
    * type = 3 教师
    """
    args = request.QUERY.casts(username=str, password=str, pass_flag=int)
    username = args.username or ''
    password = args.password or ''
    pass_flag = int(args.pass_flag or 0)
    username = username.strip().lower()
    out = []
    if not username:
        return ajax.jsonp_fail(request, message='请输入用户名或手机号')
    if not password:
        return ajax.jsonp_fail(request, message='请输入密码')

    if pass_flag:
        password = auth.safe_pass_decode(password)

    # 模糊匹配(根据手机号+密码猜测具体帐号)
    if username.isdigit():
        encoded_password = auth.encode_plain_password(password)
        sql = """
        select u.username, u.status from auth_user u
        inner join auth_profile p on p.user_id=u.id and p.password='******'
        where u.phone='%s'
        """ % (encoded_password, username)
        binds = db.user_slave.fetchall_dict(sql)
        if not binds:
            return ajax.jsonp_fail(request, message="账号或密码错误!")

        now_binds = [b for b in binds if int(b.status) != 2]
        if not now_binds:
            return ajax.jsonp_fail(request, message="该账号已被禁用,请联系客服")
    else:
        user, auth_user = com_user.authenticate(username=username, password=password)
        if not user:
            return ajax.jsonp_fail(request, message='账号或密码错误,是否找回密码?')

        if int(user.status) == 2:
            return ajax.jsonp_fail(request, message='该账号已被禁用,请联系客服')

        # 登录检查
        error = com_user.web_login_check(user)
        if error:
            return ajax.jsonp_fail(request, message=error)

        # 登录日志
        thread_pool.call(common.login_handle, request, args, user)
        # 输入后缀xs,js 准确返回用户信息
        if not username.isdigit():
            d = dict(
                real_name=user.real_name,
                school_name=user.school_name if user.school_name else "",
                unit_name=user.unit.name if user.unit else "",
                portrait=user.portrait,
                type=user.type,
                tbkt_token=auth.login(request, user.id),
                dept_id=user.dept_id,

            )
            out.append(d)
            return ajax.jsonp_ok(request, out)

    # 手机号下的所有账号
    sql = """
    select  u.id, u.real_name, p.portrait, u.type,p.password,u.sid,u.dept_id, u.status
    from auth_user u inner join auth_profile p on u.id = p.user_id and u.phone = "%s"
    where u.type in (1,3) and u.dept_id in (1,2) and u.status != 2
    order by u.type desc
        """ % username
    users = db.user_slave.fetchall_dict(sql)
    if not users:
        return ajax.jsonp_fail(request, message='账号或密码错误,是否找回密码?')

    user_ids = [i.id for i in users]
    regions = db.ketang.mobile_order_region.select("school_name", "unit_class_id", "user_id") \
                  .filter(user_id__in=user_ids).group_by("user_id")[:]
    units_id = [i.unit_class_id for i in regions]
    region_map = {i.user_id: i for i in regions}
    units = db.slave.school_unit_class.select("unit_name", "id").filter(id__in=units_id)[:]
    units_map = {i.id: i.unit_name for i in units}
    for i in users:
        region = region_map.get(i.id)
        unit_id = region.unit_class_id if region else 0
        school_name = region.school_name if region else ""
        unit_name = units_map.get(unit_id, "")

        d = dict(
            real_name=i.real_name,
            school_name=school_name,
            unit_name=unit_name,
            type=i.type,
            portrait=get_portrait(i, i.type),
            # 'portrait': com_user.get_portrait(u, u.type),
            tbkt_token=create_token(i.id),
            sid=i.sid,
            dept_id=i.dept_id
        )
        out.append(d)
    return ajax.jsonp_ok(request, out)
예제 #4
0
def p_login(request, role):
    """
    @api {post} /account/login/? [登录]登录
    @apiGroup account
    @apiParamExample {json} 请求示例
        /account/login/s 学生登录
        /account/login/t 老师登录

        {
            "username":"******", 
            "password":"******",
            "pass_flag": 1      # 0 以前的老接口,不加密,  1 现在的新程序,加密
            "login_type": 90,   # 登录类型 1是网站 其他是手机APP
            "version": "6.0.1", 
            "name": "865f8521b18fe9b",
            "model": "MI 4LTE",
            "platform": "Android",
            "uuid": "A100005064E391",
            "appversion": "1.0.0"
        }
    @apiParam {String} username 手机号或帐号
    @apiParam {String} password 密码
    @apiParam {Integer} login_type (可选)登录类型 88:Android教辅学生 90:Android教辅教师 89:IOS教辅学生 91:IOS教辅教师
    @apiParam {String} version (可选)系统版本号
    @apiParam {String} name (可选)设备名称
    @apiParam {String} model (可选)手机型号
    @apiParam {String} platform (可选)平台名称
    @apiParam {String} uuid (可选)设备序列号
    @apiParam {String} appversion (可选)app版本
    @apiSuccessExample {json} 成功返回
        {
            "next": "",
            "error": "",
            "message": "",
            "tbkt_token": "eHl3dHR3PHF0eHh5dXlzcnY8cXR4eHF4dHVwdQ",
            "app_version": {
                "h5": 0,
                "api": 1,
                "must": 0
            },
            "data": "",
            "response": "ok"
        }

        登录成功后, 服务器会在响应头中添加 Tbkt-Token: xxxx 头域, 分配给客户端一个token.
        客户端应记录这个 tbkt_token 并在之后的请求中带上 Tbkt-Token: xxxx
        到时如果服务器没有收到 tbkt_token 或者 tbkt_token 过期(7天), 则返回:
        {
            "message": "请您先登录",
            "next": "",
            "data": "",
            "response": "fail",
            "error": "no_user"
        }
        
        其他请求也要看下响应头里有没有给新token, 有就更新token.

        检测新版本机制:
        客户端每个请求头加一个 App-Type: 9安卓学生 10安卓教师 11苹果学生 12苹果教师 13 H5学生 14 H5教师
        服务器返回头会加一个 App-Version: {"h5": H5版本号, "api": 客户端版本号, "must": 0不强制升级客户端 1强制升级客户端}
    @apiSuccessExample {json} 失败返回
        {"message": "帐号或密码错误", "error": "", "data": "", "response": "fail", "next": ""}

        如果error=switch就进入切换身份页面让他选角色
    @apiSuccessExample {json} Python示例
        import requests

        r = requests.post('http://127.0.0.1:4000/account/login/t', 
                        params={'username':'******', 'password':'******'})
        cookies = r.cookies
        r = requests.post('http://127.0.0.1:4000/class/getpwd', 
                        params={'bind_id':'4210824'}, cookies=cookies)
        print r.json()
    @apiSuccessExample {json} Java示例
        public static final MediaType JSON = MediaType.parse("application/json; charset=utf-8");
        OkHttpClient client = new OkHttpClient();
        String post(String url, String json) throws IOException {
            RequestBody body = RequestBody.create(JSON, json);
            Request request = new Request.Builder()
                    .addHeader("Cookie","tbkt_token="+tbkt_token)
                    .url(url)
                    .post(body)
                    .build();
            Response response = client.newCall(request).execute();
            if (response.isSuccessful()) {
                return response.body().string();
            } else {
                throw new IOException("Unexpected code " + response);
            }
        }

        // webview
        CookieManage cookiemanager = CookieManager.getInstance();
        cookiemanager.setAcceptCookie(true);
        cookiemanager.setCookie(url,"sessionid="+sessionid);
    @apiSuccessExample {json} C#示例
        HttpClient client = CreateClientASMtoken("");
        HttpResponseMessage response = client.GetAsync("http://localhost").Result;

        IEnumerable<string> rawCookies = response.Headers.GetValues("Set-Cookie");
    """
    # return ajax.jsonp_fail(request, message=u'系统升级,暂停服务 20点至次日18点', error=u'升级')
    args = request.QUERY.casts(username=str, password=str,
                               login_type=int, version=str, name=unicode, model=unicode, platform=str,
                               uuid=str, appversion=str, pass_flag=int)
    username = args.username or ''
    password = args.password or ''
    pass_flag = int(args.pass_flag or 0)
    username = username.strip().lower()
    if not username:
        return ajax.jsonp_fail(request, message='请输入用户名或手机号')
    if not password:
        return ajax.jsonp_fail(request, message='请输入密码')
    login_type = args.login_type

    if pass_flag:
        password = auth.safe_pass_decode(password)

    # 模糊匹配(根据手机号+密码猜测具体帐号)
    if username.isdigit():
        type = 3 if role == 't' else 1
        encoded_password = auth.encode_plain_password(password)
        sql = """
        select u.username, u.status from auth_user u
        inner join auth_profile p on p.user_id=u.id and p.password='******'
        where u.phone='%s' and u.type=%s
        """ % (encoded_password, username, type)
        binds = db.user_slave.fetchall_dict(sql)
        if not binds:
            return ajax.jsonp_fail(request, message='账号或密码错误,是否找回密码?')

        now_binds = [b for b in binds if int(b.status) != 2]
        if not now_binds:
            return ajax.jsonp_fail(request, message="该账号已被禁用,请联系客服")

        bind = now_binds[0]
        if bind:
            username = bind.username
        elif role == 't':
            username += 'js'
        else:
            username += 'xs'

    elif role == 't' and not RE_TEACHER_USERNAME.match(username):
        return ajax.jsonp_fail(request, message='请输入正确的教师帐号')
    elif role == 's' and not RE_STUDENT_USERNAME.match(username):
        return ajax.jsonp_fail(request, message='请输入正确的学生帐号')

    user, auth_user = com_user.authenticate(username=username, password=password)
    if not user:
        return ajax.jsonp_fail(request, message='账号或密码错误,是否找回密码?')

    if int(user.status) == 2:
        return ajax.jsonp_fail(request, message='该账号已被禁用,请联系客服')

    # 登录检查
    if login_type > 1:
        error = com_user.app_login_check(user)
        if error:
            # 如果当前角色不让进, 通知他切换到别的角色
            n = db.user_slave.auth_user.filter(phone=user.phone_number, type=user.type).count()
            if n > 1:
                auth.login(request, user.id)
                return ajax.jsonp_fail(request, 'switch', message=error)
            return ajax.jsonp_fail(request, message=error)
    else:
        error = com_user.web_login_check(user)
        if error:
            return ajax.jsonp_fail(request, message=error)

    # 登录日志
    thread_pool.call(common.login_handle, request, args, user)

    data = {
        'flag': "0",
        'user_id': user.id
    }
    auth.login(request, user.id)
    if user.type==1:
        result=common.real_name_filter(user.real_name)
        if not result:
            data = {
                'flag': "1",
                'user_id': user.id
            }
            return ajax.jsonp_ok(request,data)
    return ajax.jsonp_ok(request, data)
예제 #5
0
def register(platform_id, user_type, phone, real_name, subject_id, dept_type):
    """
    注册一个帐号, 生成随机密码, 名字留空
    ----------------------
    王晨光     2017-2-21
    ----------------------
    @param platform_id  平台ID
    @param user_type    用户类型 1学生 3老师
    @param phone        手机号
    @param real_name    姓名
    @param subject_id   老师学科ID
    @param dept_type    学段: 1小学 2初中
    @return             {'user_id':用户ID, 'username':用户名, 'password':新密码}
        返回None表示帐号已存在
    """

    def foo(user):
        profile = com_user.get_profile(user.id)
        assert profile, 'user_id: %s' % user.id
        password = auth.decode_plain_password(profile.password)
        return {'user_id': user.id, 'username': user.username, 'password': password}

    # 不允许同名用户注册
    user = db.user.auth_user.select('id', 'username').get(phone=phone, real_name=real_name, type=user_type)
    if user:
        return foo(user)

    username = alloc_username(phone, user_type)
    user = db.user.auth_user.select('id', 'username').get(username=username)
    if user:
        return foo(user)

    nowt = int(time.time())
    # 沿用已有帐号的密码
    sql = """
    select p.password from auth_user u
    inner join auth_profile p on p.user_id=u.id
    where u.type=%s and u.phone='%s'
    limit 1
    """ % (user_type, phone)
    profile = db.user_slave.fetchone_dict(sql)
    if profile:
        password = auth.decode_plain_password(profile.password)
    else:
        password = "".join(random.sample('1234567890', 8))  # 新帐号随机生成6位密码
    # if user_type == 3:
    #     dept_type = 0
    with db.user as c:
        user_id = c.auth_user.create(
            ignore=True,
            username=username,
            password=auth.encode_password(password),
            type=user_type,
            real_name=real_name,
            last_login=0,
            date_joined=nowt,
            status=1,
            phone=phone,
            platform_id=platform_id,
            grade_id=0,
            sid=subject_id,
            dept_id=dept_type,
        )
        # duplicate
        if not user_id:
            user = db.user.select('id', 'username').get(username=username)
            assert user, '%s' % username
            return foo(user)
        # create auth_profile
        plain_password = auth.encode_plain_password(password)
        c.auth_profile.create(
            user_id=user_id,
            nickname='',
            portrait='',
            sex=1,
            password=plain_password,
        )

    # 如果本手机号已经是移动开通状态, 那么这个用户也插入一条开通主记录
    mslist = db.ketang_slave.mobile_subject.filter(phone_number=phone, platform_id=platform_id,
                                                   pay_type='cmcc').group_by('subject_id')[:]
    details = []
    for m in mslist:
        if nowt >= m.open_date and (m.cancel_date <= 0 or nowt < m.cancel_date):
            details.append({
                'user_id': user_id,
                'phone_number': phone,
                'subject_id': m.subject_id,
                'open_date': m.open_date,
                'cancel_date': m.cancel_date,
                'pay_type': m.pay_type,
                'platform_id': platform_id,
                'add_date': nowt,
            })
    if details:
        db.ketang.mobile_subject.bulk_create(details, ignore=True)

    return {'user_id': user_id, 'username': username, 'password': password}