permission.py 3.2 KB

123456789101112131415161718192021222324252627282930313233343536373839404142434445464748495051525354555657585960616263646566676869707172737475767778798081828384858687888990919293949596979899100101102103104105
  1. #!/usr/bin/env python
  2. # -*- coding: utf-8 -*-
  3. # **************************************************************************
  4. # Copyright © 2017 jianglin
  5. # File Name: permission.py
  6. # Author: jianglin
  7. # Email: xiyang0807@gmail.com
  8. # Created: 2017-03-28 16:02:43 (CST)
  9. # Last Update:星期日 2017-4-2 11:47:33 (CST)
  10. # By:
  11. # Description:
  12. # **************************************************************************
  13. from collections import namedtuple
  14. from functools import partial, wraps
  15. from flask import abort, current_app, flash, redirect, request, url_for
  16. from flask_login import current_user, login_required
  17. from flask_principal import (Need, Permission, RoleNeed, UserNeed,
  18. identity_loaded)
  19. super_permission = Permission(RoleNeed('super'))
  20. confirm_permission = Permission(RoleNeed('confirmed')).union(super_permission)
  21. auth_permission = Permission(RoleNeed('auth')).union(confirm_permission)
  22. guest_permission = Permission(RoleNeed('guest')).union(auth_permission)
  23. _TopicNeed = namedtuple('Topic', ['method', 'value'])
  24. TopicNeed = partial(_TopicNeed, 'PUT')
  25. _ReplyNeed = namedtuple('Reply', ['method', 'value'])
  26. ReplyNeed = partial(_ReplyNeed, 'edit')
  27. _CollectNeed = namedtuple('Collect', ['method', 'value'])
  28. CollectNeed = partial(_CollectNeed, 'edit')
  29. class TopicPermission(Permission):
  30. def __init__(self, pk):
  31. need = TopicNeed(pk)
  32. super(TopicPermission, self).__init__(need)
  33. class ReplyPermission(Permission):
  34. def __init__(self, pk):
  35. need = ReplyNeed(pk)
  36. super(ReplyPermission, self).__init__(need)
  37. class CollectPermission(Permission):
  38. def __init__(self, pk):
  39. need = CollectNeed(pk)
  40. super(CollectPermission, self).__init__(need)
  41. def is_confirmed(func):
  42. @wraps(func)
  43. def _is_confirmed(*args, **kwargs):
  44. if not current_user.is_authenticated:
  45. return redirect(url_for('auth.login', next=request.path))
  46. if confirm_permission.can():
  47. return func(*args, **kwargs)
  48. flash('请验证你的帐号', 'warning')
  49. return redirect(url_for('user.user', username=current_user.username))
  50. return _is_confirmed
  51. def is_guest(func):
  52. @wraps(func)
  53. def _is_guest(*args, **kwargs):
  54. if not current_user.is_authenticated:
  55. return func(*args, **kwargs)
  56. flash('你已登陆,请勿重复登陆')
  57. return redirect('/')
  58. return _is_guest
  59. class RestfulView(object):
  60. decorators = ()
  61. def __call__(self, func):
  62. f = self.method(func)
  63. if self.decorators:
  64. for dec in reversed(self.decorators):
  65. f = dec(f)
  66. return f
  67. def method(self, func):
  68. @wraps(func)
  69. def decorator(*args, **kwargs):
  70. meth = getattr(self, request.method.lower(), None)
  71. if request.method == 'HEAD':
  72. meth = getattr(self, 'get', None)
  73. if meth is not None:
  74. check = meth(*args, **kwargs)
  75. if isinstance(check, bool) and check:
  76. return func(*args, **kwargs)
  77. elif check:
  78. return check or self.callback()
  79. return func(*args, **kwargs)
  80. return decorator
  81. def callback(self):
  82. abort(403)