Merge branch 'bugfix' into 'master'

Fix broken accounting + security fixs

See merge request !57
This commit is contained in:
Skia 2017-03-28 08:11:02 +02:00
commit a078bae260
4 changed files with 28 additions and 13 deletions

View File

@ -5,6 +5,7 @@ from django.core.exceptions import ValidationError
from django.contrib.auth import logout, login, authenticate from django.contrib.auth import logout, login, authenticate
from django.forms import CheckboxSelectMultiple, Select, DateInput, TextInput, DateTimeInput from django.forms import CheckboxSelectMultiple, Select, DateInput, TextInput, DateTimeInput
from django.utils.translation import ugettext_lazy as _ from django.utils.translation import ugettext_lazy as _
from django.utils.translation import ugettext
from phonenumber_field.widgets import PhoneNumberInternationalFallbackWidget from phonenumber_field.widgets import PhoneNumberInternationalFallbackWidget
from ajax_select.fields import AutoCompleteSelectField from ajax_select.fields import AutoCompleteSelectField
@ -59,7 +60,7 @@ class SelectFile(TextInput):
'title': _("Choose file"), 'title': _("Choose file"),
'name': name, 'name': name,
} }
output += '<span name="' + name + '" class="choose_file_button">' + _("Choose file") + '</span>' output += '<span name="' + name + '" class="choose_file_button">' + ugettext("Choose file") + '</span>'
return output return output
class SelectUser(TextInput): class SelectUser(TextInput):
@ -73,7 +74,7 @@ class SelectUser(TextInput):
'title': _("Choose user"), 'title': _("Choose user"),
'name': name, 'name': name,
} }
output += '<span name="' + name + '" class="choose_user_button">' + _("Choose user") + '</span>' output += '<span name="' + name + '" class="choose_user_button">' + ugettext("Choose user") + '</span>'
return output return output
# Forms # Forms

View File

@ -262,6 +262,14 @@ class UserStatsView(UserTabsMixin, CanViewMixin, DetailView):
template_name = "core/user_stats.jinja" template_name = "core/user_stats.jinja"
current_tab = 'stats' current_tab = 'stats'
def dispatch(self, request, *arg, **kwargs):
profile = self.get_object()
if (profile != request.user and not request.user.is_root):
raise PermissionDenied
return super(UserStatsView, self).dispatch(request, *arg, **kwargs)
def get_context_data(self, **kwargs): def get_context_data(self, **kwargs):
kwargs = super(UserStatsView, self).get_context_data(**kwargs) kwargs = super(UserStatsView, self).get_context_data(**kwargs)
from counter.models import Counter, Product, Selling from counter.models import Counter, Product, Selling

View File

@ -6,7 +6,7 @@ from django.core.urlresolvers import reverse
from django.forms import ValidationError from django.forms import ValidationError
from django.contrib.sites.shortcuts import get_current_site from django.contrib.sites.shortcuts import get_current_site
from datetime import timedelta from datetime import timedelta, date
import random import random
import string import string
import os import os
@ -35,6 +35,11 @@ class Customer(models.Model):
def __str__(self): def __str__(self):
return "%s - %s" % (self.user.username, self.account_id) return "%s - %s" % (self.user.username, self.account_id)
@property
def can_buy(self):
return (self.user.subscriptions.last() and
(date.today() - self.user.subscriptions.last().subscription_end) < timedelta(days=90))
def generate_account_id(number): def generate_account_id(number):
number = str(number) number = str(number)
letter = random.choice(string.ascii_lowercase) letter = random.choice(string.ascii_lowercase)

View File

@ -1,4 +1,5 @@
from django.shortcuts import render from django.shortcuts import render, get_object_or_404
from django.http import Http404
from django.core.exceptions import PermissionDenied from django.core.exceptions import PermissionDenied
from django.views.generic import ListView, DetailView, RedirectView, TemplateView from django.views.generic import ListView, DetailView, RedirectView, TemplateView
from django.views.generic.edit import UpdateView, CreateView, DeleteView, ProcessFormView, FormMixin from django.views.generic.edit import UpdateView, CreateView, DeleteView, ProcessFormView, FormMixin
@ -49,9 +50,7 @@ class GetUserForm(forms.Form):
cus = Customer.objects.filter(account_id__iexact=cleaned_data['code']).first() cus = Customer.objects.filter(account_id__iexact=cleaned_data['code']).first()
elif cleaned_data['id'] is not None: elif cleaned_data['id'] is not None:
cus = Customer.objects.filter(user=cleaned_data['id']).first() cus = Customer.objects.filter(user=cleaned_data['id']).first()
sub = cus.user if cus is not None else None if (cus is None or not cus.can_buy):
if (cus is None or sub is None or not sub.subscriptions.last() or
(date.today() - sub.subscriptions.last().subscription_end) > timedelta(days=90)):
raise forms.ValidationError(_("User not found")) raise forms.ValidationError(_("User not found"))
cleaned_data['user_id'] = cus.user.id cleaned_data['user_id'] = cus.user.id
cleaned_data['user'] = cus.user cleaned_data['user'] = cus.user
@ -60,12 +59,10 @@ class GetUserForm(forms.Form):
class RefillForm(forms.ModelForm): class RefillForm(forms.ModelForm):
error_css_class = 'error' error_css_class = 'error'
required_css_class = 'required' required_css_class = 'required'
amount = forms.FloatField(min_value=0, widget=forms.NumberInput(attrs={'class':'focus'}))
class Meta: class Meta:
model = Refilling model = Refilling
fields = ['amount', 'payment_method', 'bank'] fields = ['amount', 'payment_method', 'bank']
widgets = {
'amount': forms.NumberInput(attrs={'class':'focus'},)
}
class CounterTabsMixin(TabedViewMixin): class CounterTabsMixin(TabedViewMixin):
def get_tabs_title(self): def get_tabs_title(self):
@ -159,9 +156,14 @@ class CounterClick(CounterTabsMixin, CanViewMixin, DetailView):
pk_url_kwarg = "counter_id" pk_url_kwarg = "counter_id"
current_tab = "counter" current_tab = "counter"
def dispatch(self, request, *args, **kwargs):
self.customer = get_object_or_404(Customer, user__id=self.kwargs['user_id'])
if not self.customer.can_buy:
raise Http404
return super(CounterClick, self).dispatch(request, *args, **kwargs)
def get(self, request, *args, **kwargs): def get(self, request, *args, **kwargs):
"""Simple get view""" """Simple get view"""
self.customer = Customer.objects.filter(user__id=self.kwargs['user_id']).first()
if 'basket' not in request.session.keys(): # Init the basket session entry if 'basket' not in request.session.keys(): # Init the basket session entry
request.session['basket'] = {} request.session['basket'] = {}
request.session['basket_total'] = 0 request.session['basket_total'] = 0
@ -180,7 +182,6 @@ class CounterClick(CounterTabsMixin, CanViewMixin, DetailView):
def post(self, request, *args, **kwargs): def post(self, request, *args, **kwargs):
""" Handle the many possibilities of the post request """ """ Handle the many possibilities of the post request """
self.object = self.get_object() self.object = self.get_object()
self.customer = Customer.objects.filter(user__id=self.kwargs['user_id']).first()
self.refill_form = None self.refill_form = None
if ((self.object.type != "BAR" and not request.user.is_authenticated()) or if ((self.object.type != "BAR" and not request.user.is_authenticated()) or
(self.object.type == "BAR" and (self.object.type == "BAR" and
@ -275,7 +276,7 @@ class CounterClick(CounterTabsMixin, CanViewMixin, DetailView):
total_qty_mod_6 = self.get_total_quantity_for_pid(request, pid) % 6 total_qty_mod_6 = self.get_total_quantity_for_pid(request, pid) % 6
bq = int((total_qty_mod_6 + q) / 6) # Integer division bq = int((total_qty_mod_6 + q) / 6) # Integer division
q -= bq q -= bq
if self.customer.amount < (total + q*float(price)): # Check for enough money if self.customer.amount < (total + round(q*float(price),2)): # Check for enough money
request.session['not_enough'] = True request.session['not_enough'] = True
return False return False
if product.limit_age >= 18 and not self.customer.user.date_of_birth: if product.limit_age >= 18 and not self.customer.user.date_of_birth: