From a8b9e02ea54639a68707547940250d6e09017d54 Mon Sep 17 00:00:00 2001 From: Levi Date: Sun, 26 Jun 2016 14:50:48 -0500 Subject: [PATCH 1/2] started hosting permissions --- dynamicweb/settings/base.py | 8 +++++ hosting/migrations/0026_auto_20160625_0028.py | 19 ++++++++++++ hosting/models.py | 14 ++++++++- hosting/templates/emails/new_booked_vm.html | 1 + hosting/templates/emails/new_booked_vm.txt | 1 + hosting/templates/emails/vm_charged.html | 1 + hosting/templates/emails/vm_charged.txt | 1 + membership/models.py | 5 +++ requirements.txt | 1 + utils/mixins.py | 31 +++++++++++++++++++ 10 files changed, 81 insertions(+), 1 deletion(-) create mode 100644 hosting/migrations/0026_auto_20160625_0028.py create mode 100644 utils/mixins.py diff --git a/dynamicweb/settings/base.py b/dynamicweb/settings/base.py index ab2d6763..7ab11944 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', @@ -182,6 +183,10 @@ DATABASES = { } +AUTHENTICATION_BACKENDS = ( + 'django.contrib.auth.backends.ModelBackend', + 'guardian.backends.ObjectPermissionBackend', +) # Internationalization @@ -460,3 +465,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/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/models.py b/hosting/models.py index 887f0777..c8980aa9 100644 --- a/hosting/models.py +++ b/hosting/models.py @@ -10,6 +10,7 @@ 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 @@ -82,7 +83,7 @@ class VirtualMachineType(models.Model): } -class VirtualMachinePlan(models.Model): +class VirtualMachinePlan(AssignPermissionsMixin, models.Model): PENDING_STATUS = 'pending' ONLINE_STATUS = 'online' @@ -104,6 +105,10 @@ class VirtualMachinePlan(models.Model): (NODEJS, 'Debian, NodeJS'), ) + permissions = ('virtualmachineplan.view_virtualmachineplan', + 'virtualmachineplan.cancel_virtualmachineplan', + 'virtualmachineplan.change_virtualmachineplan') + cores = models.IntegerField() memory = models.IntegerField() disk_size = models.IntegerField() @@ -116,6 +121,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 @@ -142,6 +153,7 @@ class VirtualMachinePlan(models.Model): @classmethod def create(cls, data, user): instance = cls.objects.create(**data) + instance.assign_permissions(user) return instance @staticmethod diff --git a/hosting/templates/emails/new_booked_vm.html b/hosting/templates/emails/new_booked_vm.html index 0a3d2742..0f9b4f6e 100644 --- a/hosting/templates/emails/new_booked_vm.html +++ b/hosting/templates/emails/new_booked_vm.html @@ -1,3 +1,4 @@ +{% load static from staticfiles %} diff --git a/hosting/templates/emails/new_booked_vm.txt b/hosting/templates/emails/new_booked_vm.txt index 0a3d2742..0f9b4f6e 100644 --- a/hosting/templates/emails/new_booked_vm.txt +++ b/hosting/templates/emails/new_booked_vm.txt @@ -1,3 +1,4 @@ +{% load static from staticfiles %} diff --git a/hosting/templates/emails/vm_charged.html b/hosting/templates/emails/vm_charged.html index b8837645..33568d05 100644 --- a/hosting/templates/emails/vm_charged.html +++ b/hosting/templates/emails/vm_charged.html @@ -1,3 +1,4 @@ +{% load static from staticfiles %} diff --git a/hosting/templates/emails/vm_charged.txt b/hosting/templates/emails/vm_charged.txt index b8837645..33568d05 100644 --- a/hosting/templates/emails/vm_charged.txt +++ b/hosting/templates/emails/vm_charged.txt @@ -1,3 +1,4 @@ +{% load static from staticfiles %} diff --git a/membership/models.py b/membership/models.py index 0b528c3f..0feaf467 100644 --- a/membership/models.py +++ b/membership/models.py @@ -16,6 +16,11 @@ REGISTRATION_MESSAGE = {'subject': "Validation mail", 'from': 'test@test.com'} +def get_anonymous_user_instance(User): + return User.register('Anonymous', None, 'anonymous@ungleich.ch') + + + class MyUserManager(BaseUserManager): def create_user(self, email, name, password=None): """ 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' From 4352094680c142c825c345265f20191d31b21d97 Mon Sep 17 00:00:00 2001 From: Levi Date: Sun, 10 Jul 2016 22:08:51 -0500 Subject: [PATCH 2/2] =?UTF-8?q?Added=20=E2=80=98view=20virtual=20machine?= =?UTF-8?q?=20plan=20=E2=80=99=20permission,=20Added=20=E2=80=98delete=20v?= =?UTF-8?q?irtual=20machine=20plan=E2=80=99=20permission=20,=20Added=20?= =?UTF-8?q?=E2=80=98view=20hosting=20order=E2=80=99=20permission?= MIME-Version: 1.0 Content-Type: text/plain; charset=UTF-8 Content-Transfer-Encoding: 8bit --- dynamicweb/settings/base.py | 2 +- hosting/admin.py | 3 +++ hosting/migrations/0027_auto_20160711_0210.py | 19 +++++++++++++++++++ hosting/models.py | 18 ++++++++++++------ hosting/templates/hosting/base_short.html | 2 +- hosting/views.py | 8 +++++--- membership/models.py | 11 ++++++----- 7 files changed, 47 insertions(+), 16 deletions(-) create mode 100644 hosting/migrations/0027_auto_20160711_0210.py diff --git a/dynamicweb/settings/base.py b/dynamicweb/settings/base.py index 85a380a3..4d1bd92e 100644 --- a/dynamicweb/settings/base.py +++ b/dynamicweb/settings/base.py @@ -185,8 +185,8 @@ DATABASES = { AUTHENTICATION_BACKENDS = ( - 'django.contrib.auth.backends.ModelBackend', 'guardian.backends.ObjectPermissionBackend', + 'django.contrib.auth.backends.ModelBackend', ) 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/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 7ce64696..e5899b0e 100644 --- a/hosting/models.py +++ b/hosting/models.py @@ -4,8 +4,6 @@ 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 @@ -106,9 +104,9 @@ class VirtualMachinePlan(AssignPermissionsMixin, models.Model): (NODEJS, 'Debian, NodeJS'), ) - permissions = ('virtualmachineplan.view_virtualmachineplan', - 'virtualmachineplan.cancel_virtualmachineplan', - 'virtualmachineplan.change_virtualmachineplan') + permissions = ('view_virtualmachineplan', + 'cancel_virtualmachineplan', + 'change_virtualmachineplan') cores = models.IntegerField() memory = models.IntegerField() @@ -180,7 +178,7 @@ class VirtualMachinePlan(AssignPermissionsMixin, models.Model): self.save(update_fields=['status']) -class HostingOrder(models.Model): +class HostingOrder(AssignPermissionsMixin, models.Model): ORDER_APPROVED_STATUS = 'Approved' ORDER_DECLINED_STATUS = 'Declined' @@ -194,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) @@ -205,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 0feaf467..7672a7b4 100644 --- a/membership/models.py +++ b/membership/models.py @@ -17,7 +17,8 @@ REGISTRATION_MESSAGE = {'subject': "Validation mail", def get_anonymous_user_instance(User): - return User.register('Anonymous', None, 'anonymous@ungleich.ch') + return CustomUser(name='Anonymous', email='anonymous@ungleich.ch', + validation_slug=make_password(None)) @@ -108,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`?"