from functools import wraps from django.contrib.auth.models import User, Group from piston.utils import rc from main.models import Plugin, PluginPermission 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(name="Plugin") # 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