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


+

+

+ + +
+

+

+ + + + + + + {% if pluginpermissions %} + {% for pperm in pluginpermissions %} + {% if pperm.plugin in plugins %} + end test + {% endif %} + + + + + {% endfor %} + {% else %} + + + + {% endif %} +
NameAuthBlobOptionen
{{ pperm.plugin }} +
+ + +
+
+
+ +
+
+
Du hast bisher keinem Plugin zugriff auf deinen Account gewährt
+ Perms {{ pluginpermissions }}
+

+

Second Idea for Plugin interface

+
+

+ + + + + + + {% if pluginpermissions %} + {% for plugin in plugins %} + + + + + {% endfor %} + {% else %} + + + + {% endif %} +
NameAuthBlobOptionen
{{ plugin }} + {%if plugin not in unallowedplugins %} +
+ + +
+ {%endif%} +
+
+ {%if plugin in unallowedplugins %} + + {%else%} + + {%endif%} +
+
+
Du hast bisher keinem Plugin zugriff auf deinen Account gewährt
+

{% 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))