From a1052df6088433e23f2d5c9fd1c419d6193f479f Mon Sep 17 00:00:00 2001
From: seba
Date: Fri, 30 Sep 2011 17:22:26 +0200
Subject: [PATCH] Plugin + API + Changing user works
---
devel/README | 13 +++
k4ever/api2/decorators.py | 66 ++++++++++++++-
k4ever/api2/handlers.py | 10 ++-
k4ever/main/admin.py | 4 +-
k4ever/main/models.py | 21 +++--
k4ever/main/templates/settings/settings.html | 87 +++++++++++++++++++-
k4ever/main/views.py | 7 +-
7 files changed, 194 insertions(+), 14 deletions(-)
create mode 100644 devel/README
diff --git a/devel/README b/devel/README
new file mode 100644
index 0000000..934a99b
--- /dev/null
+++ b/devel/README
@@ -0,0 +1,13 @@
+Kassensystem
+
+
+
+Installation Process
+====================
+ - edit settings.py for database
+ - Add Usergroups: ('Normal User', 'Plugin') ( to be renamed)
+ - ./manage.py syncdb
+
+
+API
+===
diff --git a/k4ever/api2/decorators.py b/k4ever/api2/decorators.py
index 8a05cb3..e90c59f 100644
--- a/k4ever/api2/decorators.py
+++ b/k4ever/api2/decorators.py
@@ -1,6 +1,9 @@
from functools import wraps
+from django.contrib.auth.models import User, Group
+from piston.utils import rc
+from main.models import Plugin, PluginPermission
-def changeUserOnPlugin(apiFunc):
+def manglePluginPerms(apiFunc):
""" Changes to a given user when the authenticated user is an plugin
When the user which called the apifunc is an plugin this function
@@ -15,9 +18,66 @@ def changeUserOnPlugin(apiFunc):
@wraps(apiFunc)
def wrapper(self, request, *args, **kwargs):
- return self.apiFunc(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
+ 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!
+ return apiFunc(self, request, *args, **kwargs)
+ except Groups.DoesNotExist:
+ pass
+ ret = rc.FORBIDDEN
-
+ return rc.FORBIDDEN
+ return wrapper
diff --git a/k4ever/api2/handlers.py b/k4ever/api2/handlers.py
index 0bc63d3..0baf20d 100644
--- a/k4ever/api2/handlers.py
+++ b/k4ever/api2/handlers.py
@@ -2,11 +2,12 @@ from piston.handler import BaseHandler
from piston.utils import rc
from k4ever.buyable.models import *
from k4ever.transaction.models import *
-from decorators import changeUserOnPlugin
+from django.contrib.auth.decorators import user_passes_test
+from django.contrib.auth.models import Group
+from decorators import *
from decimal import Decimal, InvalidOperation
import datetime
-
def getInt(d, key, default):
try:
return int(d.get(key, default))
@@ -39,6 +40,7 @@ class BuyableItemHandler(BaseHandler):
error.write("This buyable does not exist in our database")
return error
+ @manglePluginPerms
def create(self, request, itemId=None):
if not request.content_type:
request.data = request.POST
@@ -81,6 +83,7 @@ class TransactionTransactHandler(BaseHandler):
model = Transaction
fields = ('amount', 'dateTime', 'checked', ('transactionType', ('id', 'name')))
+ @manglePluginPerms
def read(self, request):
num = getInt(request.GET, 'num', 0)
if num < 0:
@@ -91,6 +94,7 @@ class TransactionTransactHandler(BaseHandler):
return userTrans[:num]
return userTrans
+ @manglePluginPerms
def create(self, request):
amount = getDecimal(request.POST, 'amount', Decimal(0))
tTypeId = getInt(request.POST, 'type', -1)
@@ -121,6 +125,8 @@ class TransactionTypeHandler(BaseHandler):
class AccountBalanceHandler(BaseHandler):
allowed_methods = ('GET',)
+
+ @manglePluginPerms
def read(self, request):
balance = request.user.get_profile().balance
return {'balance': balance}
diff --git a/k4ever/main/admin.py b/k4ever/main/admin.py
index 4477270..94d0a4c 100644
--- a/k4ever/main/admin.py
+++ b/k4ever/main/admin.py
@@ -1,5 +1,7 @@
-from models import UserProfile
+from models import UserProfile, Plugin, PluginPermission
from django.contrib import admin
admin.site.register(UserProfile)
+admin.site.register(Plugin)
+admin.site.register(PluginPermission)
diff --git a/k4ever/main/models.py b/k4ever/main/models.py
index c15a09c..27f20be 100644
--- a/k4ever/main/models.py
+++ b/k4ever/main/models.py
@@ -18,12 +18,21 @@ def createUserProfile(sender, instance, created, **kwargs):
post_save.connect(createUserProfile, sender=User)
+class Plugin(models.Model):
+ name = models.CharField(max_length=40)
+ user = models.ForeignKey(User, unique=True)
+ author = models.CharField(max_length=40)
+ version = models.CharField(max_length=40)
+ descr = models.TextField(default='')
+ uniqueAuthblob = models.BooleanField(default=False)
+
+ def __unicode__(self):
+ return self.name
+
class PluginPermission(models.Model):
user = models.ForeignKey(User)
plugin = models.ForeignKey('Plugin')
- authBlob = models.TextField()
-
-class Plugin(models.Model):
- user = models.ForeignKey(User)
- uniqueAuthblob = models.BooleanField(default=False)
-
+ authBlob = models.TextField(default='')
+
+ def __unicode__(self):
+ return "%s allows %s" % (self.user, self.plugin)
diff --git a/k4ever/main/templates/settings/settings.html b/k4ever/main/templates/settings/settings.html
index 03842ff..0206990 100644
--- a/k4ever/main/templates/settings/settings.html
+++ b/k4ever/main/templates/settings/settings.html
@@ -7,6 +7,91 @@
- Plugin permissions
+ Plugin Berechtigungen
+
+
+
+
+
+ Perms {{ pluginpermissions }}
+
+ Second Idea for Plugin interface
+
+
+
+
{% endblock %}
diff --git a/k4ever/main/views.py b/k4ever/main/views.py
index 4022526..b0f2776 100644
--- a/k4ever/main/views.py
+++ b/k4ever/main/views.py
@@ -2,6 +2,8 @@ from django.shortcuts import render_to_response
from django.template import RequestContext
from django.contrib.auth.decorators import login_required
from django.db.models import Count
+from main.models import Plugin, PluginPermission
+
from buyable.models import Purchase, Buyable
@@ -20,4 +22,7 @@ def register(request):
@login_required
def settings(request):
- return render_to_response("settings/settings.html", RequestContext(request))
+ plugins = Plugin.objects.all()
+ unallowed = Plugin.objects.exclude(pluginpermission__user=request.user)
+ perms = PluginPermission.objects.filter(user=request.user)
+ return render_to_response("settings/settings.html", {'plugins': plugins, 'unallowedplugins': unallowed, 'pluginpermissions': perms}, RequestContext(request))