k4ever/k4ever/api2/decorators.py

109 lines
3.3 KiB
Python

# This file is part of k4ever, a point-of-sale system
# Contact............ <k4ever@lists.someserver.de>
# Website............ http://k4ever.someserver.de/
# Bug tracker........ http://k4ever.someserver.de/report
#
# Licensed under GNU Affero General Public License v3 or later
from functools import wraps
from django.contrib.auth.models import User, Group
from piston.utils import rc
from main.models import Plugin, PluginPermission
from settings import PLUGIN_GROUP_ID
def manglePluginPerms(apiFunc):
""" Changes to a given user when the authenticated user is an plugin.
When the user which called the apifunc is a plugin this function
goes through the following steps:
- searches the user it should change to
- checks if this user allowed the plugin to "speak for him"
- change the request so it looks like the user called himself
- add an plugin_user entry containing the previous request user
This decorator is intended to be used with django piston, so on error
it will return the appropriate rc.* values.
"""
@wraps(apiFunc)
def wrapper(self, request, *args, **kwargs):
if request.method != 'GET':
if not request.content_type:
request.data = request.POST
else:
request.data = request.GET
# 0. is user a plugin?
try:
group = request.user.groups.get(name="Plugin")
except Group.DoesNotExist:
# user is not a plugin, exec the apiFunc
return apiFunc(self, request, *args, **kwargs)
# get the plugin for the user
# FIXME: Could throw exception when we have no plugin for the
# user - where should we report this?
plugin = Plugin.objects.get(user=request.user)
# 1. find user!
user = None
try:
user = User.objects.get(username=request.data.get('user', ''))
except User.DoesNotExist:
ret = rc.NOT_HERE
ret.write("\nThe user you requested could not be found\n")
return ret
# 2. does the plugin has permission for this user?
perms = None
try:
perms = PluginPermission.objects.get(user=user, plugin=plugin)
except PluginPermission.DoesNotExist:
ret = rc.FORBIDDEN
ret.write("\nThe user did not grant you permission to act on his behalf\n")
return ret
# 3. put stuff into the request
request.user = user
request.plugin = plugin
request.pluginperms = perms
return apiFunc(self, request, *args, **kwargs)
return wrapper
def requirePlugin(apiFunc):
"""Check if user is a plugin.
Checks if the user is a member of the "Plugin" Group. Returns a rc.FORBIDDEN
if not.
"""
@wraps(apiFunc)
def wrapper(self, request, *args, **kwargs):
try:
if request.user:
group = request.user.groups.get(pk=PLUGIN_GROUP_ID)
# no exception, exec apiFunc!
request.plugin = Plugin.objects.get(user=request.user)
return apiFunc(self, request, *args, **kwargs)
except Group.DoesNotExist:
pass
ret = rc.FORBIDDEN
ret.write("\nA plugin is required for this api function\n")
return ret
return wrapper
def fix_mime(mime_func):
""" Fix mimetype by truncating everything behind a ';'.
This is used to fix pistons ``piston.utils.Mimer.content_type``."""
@wraps(mime_func)
def wrapper(self):
ctype = self.request.META.get('CONTENT_TYPE', None)
if ctype and ctype.find(";") >= 0:
ctype = self.request.META['CONTENT_TYPE'] = ctype.split(";")[0]
return mime_func(self)
return wrapper