#!/usr/bin/env python # -*- coding: utf-8 -*- from flask import Blueprint, g, make_response from flask import request from flask import session import json import jimit as ji from models.initialize import app from api.base import Base from models import User from models import Utils from models import Rules __author__ = 'James Iter' __date__ = '2017/9/14' __contact__ = 'james.iter.cn@gmail.com' __copyright__ = '(c) 2017 by James Iter.' blueprint = Blueprint( 'api_user', __name__, url_prefix='/api/user' ) blueprints = Blueprint( 'api_users', __name__, url_prefix='/api/users' ) user_base = Base(the_class=User, the_blueprint=blueprint, the_blueprints=blueprints) @Utils.dumps2response def r_sign_in(): args_rules = [ Rules.LOGIN_NAME.value, Rules.PASSWORD.value ] user = User() user.login_name = request.json.get('login_name') user.password = request.json.get('password') try: ji.Check.previewing(args_rules, user.__dict__) plain_password = user.password user.get_by('login_name') if not ji.Security.ji_pbkdf2_check(password=plain_password, password_hash=user.password): ret = dict() ret['state'] = ji.Common.exchange_state(40101) ret['state']['sub']['zh-cn'] = ''.join([ret['state']['sub']['zh-cn'], u': 鉴权失败']) raise ji.PreviewingError(json.dumps(ret, ensure_ascii=False)) token = Utils.generate_token(user.id) session['token'] = token rep = make_response() rep.data = json.dumps({'state': ji.Common.exchange_state(20000)}, ensure_ascii=False) return rep except ji.PreviewingError, e: return json.loads(e.message) @Utils.dumps2response def r_sign_out(): for key in session.keys(): session.pop(key=key) @Utils.dumps2response def r_change_password(): args_rules = [ Rules.ID.value ] user = User() user.id = g.token.get('uid', 0).__str__() try: ji.Check.previewing(args_rules, user.__dict__) user.get() old_password = request.json.get('old_password', '') if not ji.Security.ji_pbkdf2_check(password=old_password, password_hash=user.password): ret = dict() ret['state'] = ji.Common.exchange_state(40101) ret['state']['sub']['zh-cn'] = ''.join([ret['state']['sub']['zh-cn'], u': 鉴权失败']) raise ji.PreviewingError(json.dumps(ret, ensure_ascii=False)) args_rules = [ Rules.PASSWORD.value ] user.password = request.json.get('password') ji.Check.previewing(args_rules, user.__dict__) user.password = ji.Security.ji_pbkdf2(user.password) user.update() except ji.PreviewingError, e: return json.loads(e.message) @Utils.dumps2response def r_reset_password(token): args_rules = [ Rules.TOKEN.value ] try: ji.Check.previewing(args_rules, {'token': token}) token = Utils.verify_token(token, audience='r_reset_password') user = User() user.id = token['uid'] user.get() args_rules = [ Rules.PASSWORD.value ] user.password = request.json.get('password') ji.Check.previewing(args_rules, user.__dict__) user.password = ji.Security.ji_pbkdf2(user.password) user.update() except (ji.PreviewingError, ji.JITError), e: return json.loads(e.message) @Utils.dumps2response def r_send_reset_password_email(login_name): args_rules = [ Rules.LOGIN_NAME.value ] try: ji.Check.previewing(args_rules, {'login_name': login_name}) user = User() try: user.login_name = login_name user.get_by('login_name') except ji.PreviewingError, e: # 如果 login_name 没有找到,则尝试从email里面查找 # 因为用户可能会把登录名理解成email user.email = login_name user.get_by('email') host_url = request.host_url.rstrip('/') # 5 分钟有效期 token = Utils.generate_token(uid=user.id, ttl=300, audience='r_reset_password') reset_password_url = '/'.join([host_url, 'reset_password', token]) smtp_server = ji.NetUtils.smtp_init(host=app.config['smtp_host'], port=app.config.get('smtp_port', None), login_name=app.config['smtp_user'], password=app.config['smtp_password'], tls=app.config['smtp_starttls']) ji.NetUtils.send_mail(smtp_server=smtp_server, sender=app.config['smtp_user'], receivers=[user.email], title=u'重置登录密码', message=u'请复制以下地址到浏览器中打开:' + reset_password_url) ret = dict() ret['state'] = ji.Common.exchange_state(20000) ret['data'] = {'email': user.email} return ret except ji.PreviewingError, e: return json.loads(e.message)