diff --git a/dynamicweb/settings/base.py b/dynamicweb/settings/base.py index 53a75f3a..4d1bd92e 100644 --- a/dynamicweb/settings/base.py +++ b/dynamicweb/settings/base.py @@ -57,6 +57,7 @@ INSTALLED_APPS = ( 'stored_messages', 'mptt', 'parler', + 'guardian', 'taggit', 'taggit_autosuggest', # 'django_select2', @@ -183,6 +184,10 @@ DATABASES = { } +AUTHENTICATION_BACKENDS = ( + 'guardian.backends.ObjectPermissionBackend', + 'django.contrib.auth.backends.ModelBackend', +) # Internationalization @@ -461,3 +466,6 @@ if DEBUG: from .local import * else: from .prod import * + + +GUARDIAN_GET_INIT_ANONYMOUS_USER = 'membership.models.get_anonymous_user_instance' diff --git a/hosting/admin.py b/hosting/admin.py index 640878f5..70359b77 100644 --- a/hosting/admin.py +++ b/hosting/admin.py @@ -30,6 +30,9 @@ class HostingOrderAdmin(admin.ModelAdmin): # If the Stripe payment was successed, set order status approved obj.set_approved() + # Assigning permissions + obj.assign_permissions(customer.user) + context = { 'order': obj, 'vm': obj.vm_plan, diff --git a/hosting/migrations/0026_auto_20160625_0028.py b/hosting/migrations/0026_auto_20160625_0028.py new file mode 100644 index 00000000..7f98eea9 --- /dev/null +++ b/hosting/migrations/0026_auto_20160625_0028.py @@ -0,0 +1,19 @@ +# -*- coding: utf-8 -*- +# Generated by Django 1.9.4 on 2016-06-25 00:28 +from __future__ import unicode_literals + +from django.db import migrations + + +class Migration(migrations.Migration): + + dependencies = [ + ('hosting', '0025_auto_20160621_0522'), + ] + + operations = [ + migrations.AlterModelOptions( + name='virtualmachineplan', + options={'permissions': (('view_virtualmachineplan', 'View Virtual Machine Plan'), ('cancel_virtualmachineplan', 'Cancel Virtual Machine Plan'))}, + ), + ] diff --git a/hosting/migrations/0027_auto_20160711_0210.py b/hosting/migrations/0027_auto_20160711_0210.py new file mode 100644 index 00000000..4644942c --- /dev/null +++ b/hosting/migrations/0027_auto_20160711_0210.py @@ -0,0 +1,19 @@ +# -*- coding: utf-8 -*- +# Generated by Django 1.9.4 on 2016-07-11 02:10 +from __future__ import unicode_literals + +from django.db import migrations + + +class Migration(migrations.Migration): + + dependencies = [ + ('hosting', '0026_auto_20160625_0028'), + ] + + operations = [ + migrations.AlterModelOptions( + name='hostingorder', + options={'permissions': (('view_hostingorder', 'View Hosting Order'),)}, + ), + ] diff --git a/hosting/models.py b/hosting/models.py index 099b7894..e5899b0e 100644 --- a/hosting/models.py +++ b/hosting/models.py @@ -4,13 +4,12 @@ from django.db import models from django.utils.translation import ugettext_lazy as _ from django.utils.functional import cached_property - - from Crypto.PublicKey import RSA from stored_messages.settings import stored_messages_settings from membership.models import StripeCustomer from utils.models import BillingAddress +from utils.mixins import AssignPermissionsMixin from .managers import VMPlansManager @@ -83,7 +82,7 @@ class VirtualMachineType(models.Model): } -class VirtualMachinePlan(models.Model): +class VirtualMachinePlan(AssignPermissionsMixin, models.Model): PENDING_STATUS = 'pending' ONLINE_STATUS = 'online' @@ -105,6 +104,10 @@ class VirtualMachinePlan(models.Model): (NODEJS, 'Debian, NodeJS'), ) + permissions = ('view_virtualmachineplan', + 'cancel_virtualmachineplan', + 'change_virtualmachineplan') + cores = models.IntegerField() memory = models.IntegerField() disk_size = models.IntegerField() @@ -117,6 +120,12 @@ class VirtualMachinePlan(models.Model): objects = VMPlansManager() + class Meta: + permissions = ( + ('view_virtualmachineplan', 'View Virtual Machine Plan'), + ('cancel_virtualmachineplan', 'Cancel Virtual Machine Plan'), + ) + def __str__(self): return self.name @@ -143,6 +152,7 @@ class VirtualMachinePlan(models.Model): @classmethod def create(cls, data, user): instance = cls.objects.create(**data) + instance.assign_permissions(user) return instance @staticmethod @@ -168,7 +178,7 @@ class VirtualMachinePlan(models.Model): self.save(update_fields=['status']) -class HostingOrder(models.Model): +class HostingOrder(AssignPermissionsMixin, models.Model): ORDER_APPROVED_STATUS = 'Approved' ORDER_DECLINED_STATUS = 'Declined' @@ -182,6 +192,13 @@ class HostingOrder(models.Model): cc_brand = models.CharField(max_length=10) stripe_charge_id = models.CharField(max_length=100, null=True) + permissions = ('view_hostingorder',) + + class Meta: + permissions = ( + ('view_hostingorder', 'View Hosting Order'), + ) + def __str__(self): return "%s" % (self.id) @@ -193,6 +210,7 @@ class HostingOrder(models.Model): def create(cls, vm_plan=None, customer=None, billing_address=None): instance = cls.objects.create(vm_plan=vm_plan, customer=customer, billing_address=billing_address) + instance.assign_permissions(customer.user) return instance def set_approved(self): diff --git a/hosting/templates/hosting/base_short.html b/hosting/templates/hosting/base_short.html index c71434e7..29fb2861 100644 --- a/hosting/templates/hosting/base_short.html +++ b/hosting/templates/hosting/base_short.html @@ -10,7 +10,7 @@ - nngleich + ungleich diff --git a/hosting/views.py b/hosting/views.py index 18d8819e..61d387f2 100644 --- a/hosting/views.py +++ b/hosting/views.py @@ -12,7 +12,7 @@ from django.http import HttpResponseRedirect from django.contrib.auth import authenticate, login from django.conf import settings - +from guardian.mixins import PermissionRequiredMixin from stored_messages.settings import stored_messages_settings from stored_messages.models import Message from stored_messages.api import mark_read @@ -406,10 +406,11 @@ class PaymentVMView(LoginRequiredMixin, FormView): return self.form_invalid(form) -class OrdersHostingDetailView(LoginRequiredMixin, DetailView): +class OrdersHostingDetailView(PermissionRequiredMixin, LoginRequiredMixin, DetailView): template_name = "hosting/order_detail.html" context_object_name = "order" login_url = reverse_lazy('hosting:login') + permission_required = ['view_hostingorder'] model = HostingOrder @@ -447,11 +448,12 @@ class VirtualMachinesPlanListView(LoginRequiredMixin, ListView): return super(VirtualMachinesPlanListView, self).get_queryset() -class VirtualMachineView(LoginRequiredMixin, UpdateView): +class VirtualMachineView(PermissionRequiredMixin, LoginRequiredMixin, UpdateView): template_name = "hosting/virtual_machine_detail.html" login_url = reverse_lazy('hosting:login') model = VirtualMachinePlan context_object_name = "virtual_machine" + permission_required = ['view_virtualmachineplan', 'cancel_virtualmachineplan'] fields = '__all__' def get_success_url(self): diff --git a/membership/models.py b/membership/models.py index 0b528c3f..7672a7b4 100644 --- a/membership/models.py +++ b/membership/models.py @@ -16,6 +16,12 @@ REGISTRATION_MESSAGE = {'subject': "Validation mail", 'from': 'test@test.com'} +def get_anonymous_user_instance(User): + return CustomUser(name='Anonymous', email='anonymous@ungleich.ch', + validation_slug=make_password(None)) + + + class MyUserManager(BaseUserManager): def create_user(self, email, name, password=None): """ @@ -103,10 +109,10 @@ class CustomUser(AbstractBaseUser, PermissionsMixin): def __str__(self): # __unicode__ on Python 2 return self.email - def has_perm(self, perm, obj=None): - "Does the user have a specific permission?" - # Simplest possible answer: Yes, always - return self.is_admin + # def has_perm(self, perm, obj=None): + # "Does the user have a specific permission?" + # # Simplest possible answer: Yes, always + # return self.is_admin def has_module_perms(self, app_label): "Does the user have permissions to view the app `app_label`?" diff --git a/requirements.txt b/requirements.txt index 4bd93ee0..4619fae8 100644 --- a/requirements.txt +++ b/requirements.txt @@ -19,6 +19,7 @@ django-polymorphic model-mommy pycryptodome django-stored-messages +django-guardian #PLUGINS djangocms_flash diff --git a/utils/mixins.py b/utils/mixins.py new file mode 100644 index 00000000..ebcb221a --- /dev/null +++ b/utils/mixins.py @@ -0,0 +1,31 @@ +from guardian.shortcuts import assign_perm + + +class AssignPermissionsMixin(object): + permissions = tuple() + user = None + obj = None + kwargs = dict() + + def assign_permissions(self, user): + for permission in self.permissions: + assign_perm(permission, user, self) + + # def save(self, *args, **kwargs): + # self.kwargs = kwargs + # self.get_objs() + + # create = False + # if not self.pk: + # create = True + + # super(AssignPermissionsMixin, self).save(*args, **kwargs) + + # if create: + # self.assign_permissions() + + # def get_objs(self): + # self.user = self.kwargs.pop('user', None) + # self.obj = self.kwargs.pop('obj', None) + # assert self.user, 'Se necesita el parĂ¡metro user para poder asignar los permisos' + # assert self.obj, 'Se necesita el parĂ¡metro obj para poder asignar los permisos'