user.py 5.0 KB

123456789101112131415161718192021222324252627282930313233343536373839404142434445464748495051525354555657585960616263646566676869707172737475767778798081828384858687888990919293949596979899100101102103104105106107108109110111112113114115116117118119120121122123124125126127128129130131132133134135136137138139140141142143144145146147148149150151152153154155156157158159160161162163164165166167168169170171172173174175176177178179180181182183184185186
  1. #!/usr/bin/env python
  2. # -*- coding: utf-8 -*-
  3. from flask import Blueprint, g, make_response
  4. from flask import request
  5. from flask import session
  6. import json
  7. import jimit as ji
  8. from models.initialize import app
  9. from api.base import Base
  10. from models import User
  11. from models import Utils
  12. from models import Rules
  13. __author__ = 'James Iter'
  14. __date__ = '2017/9/14'
  15. __contact__ = 'james.iter.cn@gmail.com'
  16. __copyright__ = '(c) 2017 by James Iter.'
  17. blueprint = Blueprint(
  18. 'api_user',
  19. __name__,
  20. url_prefix='/api/user'
  21. )
  22. blueprints = Blueprint(
  23. 'api_users',
  24. __name__,
  25. url_prefix='/api/users'
  26. )
  27. user_base = Base(the_class=User, the_blueprint=blueprint, the_blueprints=blueprints)
  28. @Utils.dumps2response
  29. def r_sign_in():
  30. args_rules = [
  31. Rules.LOGIN_NAME.value,
  32. Rules.PASSWORD.value
  33. ]
  34. user = User()
  35. user.login_name = request.json.get('login_name')
  36. user.password = request.json.get('password')
  37. try:
  38. ji.Check.previewing(args_rules, user.__dict__)
  39. plain_password = user.password
  40. user.get_by('login_name')
  41. if not ji.Security.ji_pbkdf2_check(password=plain_password, password_hash=user.password):
  42. ret = dict()
  43. ret['state'] = ji.Common.exchange_state(40101)
  44. ret['state']['sub']['zh-cn'] = ''.join([ret['state']['sub']['zh-cn'], u': 鉴权失败'])
  45. raise ji.PreviewingError(json.dumps(ret, ensure_ascii=False))
  46. token = Utils.generate_token(user.id)
  47. session['token'] = token
  48. rep = make_response()
  49. rep.data = json.dumps({'state': ji.Common.exchange_state(20000)}, ensure_ascii=False)
  50. return rep
  51. except ji.PreviewingError, e:
  52. return json.loads(e.message)
  53. @Utils.dumps2response
  54. def r_sign_out():
  55. for key in session.keys():
  56. session.pop(key=key)
  57. @Utils.dumps2response
  58. def r_change_password():
  59. args_rules = [
  60. Rules.ID.value
  61. ]
  62. user = User()
  63. user.id = g.token.get('uid', 0).__str__()
  64. try:
  65. ji.Check.previewing(args_rules, user.__dict__)
  66. user.get()
  67. old_password = request.json.get('old_password', '')
  68. if not ji.Security.ji_pbkdf2_check(password=old_password, password_hash=user.password):
  69. ret = dict()
  70. ret['state'] = ji.Common.exchange_state(40101)
  71. ret['state']['sub']['zh-cn'] = ''.join([ret['state']['sub']['zh-cn'], u': 鉴权失败'])
  72. raise ji.PreviewingError(json.dumps(ret, ensure_ascii=False))
  73. args_rules = [
  74. Rules.PASSWORD.value
  75. ]
  76. user.password = request.json.get('password')
  77. ji.Check.previewing(args_rules, user.__dict__)
  78. user.password = ji.Security.ji_pbkdf2(user.password)
  79. user.update()
  80. except ji.PreviewingError, e:
  81. return json.loads(e.message)
  82. @Utils.dumps2response
  83. def r_reset_password(token):
  84. args_rules = [
  85. Rules.TOKEN.value
  86. ]
  87. try:
  88. ji.Check.previewing(args_rules, {'token': token})
  89. token = Utils.verify_token(token, audience='r_reset_password')
  90. user = User()
  91. user.id = token['uid']
  92. user.get()
  93. args_rules = [
  94. Rules.PASSWORD.value
  95. ]
  96. user.password = request.json.get('password')
  97. ji.Check.previewing(args_rules, user.__dict__)
  98. user.password = ji.Security.ji_pbkdf2(user.password)
  99. user.update()
  100. except (ji.PreviewingError, ji.JITError), e:
  101. return json.loads(e.message)
  102. @Utils.dumps2response
  103. def r_send_reset_password_email(login_name):
  104. args_rules = [
  105. Rules.LOGIN_NAME.value
  106. ]
  107. try:
  108. ji.Check.previewing(args_rules, {'login_name': login_name})
  109. user = User()
  110. try:
  111. user.login_name = login_name
  112. user.get_by('login_name')
  113. except ji.PreviewingError, e:
  114. # 如果 login_name 没有找到,则尝试从email里面查找
  115. # 因为用户可能会把登录名理解成email
  116. user.email = login_name
  117. user.get_by('email')
  118. host_url = request.host_url.rstrip('/')
  119. # 5 分钟有效期
  120. token = Utils.generate_token(uid=user.id, ttl=300, audience='r_reset_password')
  121. reset_password_url = '/'.join([host_url, 'reset_password', token])
  122. smtp_server = ji.NetUtils.smtp_init(host=app.config['smtp_host'], port=app.config.get('smtp_port', None),
  123. login_name=app.config['smtp_user'], password=app.config['smtp_password'],
  124. tls=app.config['smtp_starttls'])
  125. ji.NetUtils.send_mail(smtp_server=smtp_server, sender=app.config['smtp_user'],
  126. receivers=[user.email], title=u'重置登录密码',
  127. message=u'请复制以下地址到浏览器中打开:' + reset_password_url)
  128. ret = dict()
  129. ret['state'] = ji.Common.exchange_state(20000)
  130. ret['data'] = {'email': user.email}
  131. return ret
  132. except ji.PreviewingError, e:
  133. return json.loads(e.message)