126 lines
4.3 KiB
Python
126 lines
4.3 KiB
Python
import flask; from flask import request
|
|
import functools
|
|
|
|
from voussoirkit import vlogging
|
|
|
|
import etiquette
|
|
|
|
log = vlogging.getLogger(__name__)
|
|
|
|
class PermissionManager:
|
|
def __init__(self, site):
|
|
self.site = site
|
|
|
|
def admin_only(self):
|
|
if request.is_localhost:
|
|
request.checked_permissions = True
|
|
return True
|
|
elif request.session.user and request.session.user.has_permission(etiquette.constants.PERMISSION_ADMIN):
|
|
request.checked_permissions = True
|
|
return True
|
|
else:
|
|
raise etiquette.exceptions.Unauthorized()
|
|
|
|
def localhost_only(self):
|
|
if request.is_localhost:
|
|
request.checked_permissions = True
|
|
return True
|
|
else:
|
|
raise etiquette.exceptions.Unauthorized()
|
|
|
|
def logged_in(self, user=None):
|
|
'''
|
|
Require that the visitor be logged in as any user, or as one
|
|
specific user.
|
|
'''
|
|
if request.session and request.session.user and user is None:
|
|
request.checked_permissions = True
|
|
return True
|
|
if request.session and request.session.user and request.session.user == user:
|
|
request.checked_permissions = True
|
|
return True
|
|
else:
|
|
raise etiquette.exceptions.Unauthorized()
|
|
|
|
def early_read(self):
|
|
'''
|
|
This method does not set request.checked_permissions and must be used
|
|
along with one of the other checks. However, this check can act as a
|
|
cheap blocker against logged-out users before the caller wastes any time
|
|
loading items from the database to check more specific permissions.
|
|
For example, it is used by several of the bulk endpoints before checking
|
|
any of the individual items.
|
|
'''
|
|
if request.is_localhost:
|
|
return True
|
|
elif self.site.server_config['anonymous_read'] or request.session.user:
|
|
return True
|
|
else:
|
|
raise etiquette.exceptions.Unauthorized()
|
|
|
|
def edit_thing(self, thing):
|
|
if request.is_localhost:
|
|
request.checked_permissions = True
|
|
return True
|
|
elif request.session.user and request.session.user.has_object_permission(thing, 'edit'):
|
|
request.checked_permissions = True
|
|
return True
|
|
else:
|
|
raise etiquette.exceptions.Unauthorized()
|
|
|
|
def delete_thing(self, thing):
|
|
if request.is_localhost:
|
|
request.checked_permissions = True
|
|
return True
|
|
elif request.session.user and request.session.user.has_object_permission(thing, 'delete'):
|
|
request.checked_permissions = True
|
|
return True
|
|
else:
|
|
raise etiquette.exceptions.Unauthorized()
|
|
|
|
def permission_string(self, permission_string):
|
|
'''
|
|
Require that the user has this specific permission string (mostly for
|
|
the CREATE permissions rather than edit/delete permissions).
|
|
'''
|
|
if request.is_localhost:
|
|
request.checked_permissions = True
|
|
return True
|
|
elif request.session.user and permission_string in request.session.user.get_permissions():
|
|
request.checked_permissions = True
|
|
return True
|
|
else:
|
|
raise etiquette.exceptions.Unauthorized()
|
|
|
|
def read(self):
|
|
'''
|
|
BE CAREFUL WITH CACHED ENDPOINTS. Use read_decorator instead.
|
|
'''
|
|
if request.is_localhost:
|
|
request.checked_permissions = True
|
|
return True
|
|
elif self.site.server_config['anonymous_read'] or request.session.user:
|
|
request.checked_permissions = True
|
|
return True
|
|
else:
|
|
raise etiquette.exceptions.Unauthorized()
|
|
|
|
def read_decorator(self, endpoint):
|
|
'''
|
|
Make sure to place read_decorator ABOVE the cached_endpoint decorator so
|
|
Python runs this one first.
|
|
'''
|
|
log.debug('Decorating %s with basic_decorator.', endpoint)
|
|
@functools.wraps(endpoint)
|
|
def wrapped(*args, **kwargs):
|
|
self.read()
|
|
return endpoint(*args, **kwargs)
|
|
return wrapped
|
|
|
|
def global_public(self):
|
|
'''
|
|
This check always passes. Use this for the root and login page so people
|
|
can log in.
|
|
'''
|
|
request.checked_permissions = True
|
|
return True
|