permission.py 3.0 KB

12345678910111213141516171819202122232425262728293031323334353637383940414243444546474849505152535455565758596061626364656667686970717273747576777879808182838485868788899091929394
  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-3-29 17:49:46 (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. class RestfulView(object):
  52. decorators = ()
  53. def __call__(self, func):
  54. f = self.method(func)
  55. if self.decorators:
  56. for dec in reversed(self.decorators):
  57. f = dec(f)
  58. return f
  59. def method(self, func):
  60. @wraps(func)
  61. def decorator(*args, **kwargs):
  62. meth = getattr(self, request.method.lower(), None)
  63. if request.method == 'HEAD':
  64. meth = getattr(self, 'get', None)
  65. if meth is not None:
  66. check = meth(*args, **kwargs)
  67. if isinstance(check, bool) and check:
  68. return func(*args, **kwargs)
  69. elif check:
  70. return check or self.callback()
  71. return func(*args, **kwargs)
  72. return decorator
  73. def callback(self):
  74. abort(403)