# 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

