diff --git a/rowers/rower_rules.py b/rowers/rower_rules.py index 93bbdcd7..924376bf 100644 --- a/rowers/rower_rules.py +++ b/rowers/rower_rules.py @@ -98,6 +98,10 @@ def can_start_plantrial(user): return user.rower.plantrialexpires == datetime.date(1970,1,1) +@rules.predicate +def is_staff(user): + return user.is_staff + @rules.predicate def is_coach(user): return user.rower.rowerplan in ['coach','freecoach'] @@ -274,6 +278,7 @@ def can_plan_user(user,rower): rules.add_perm('rower.add_plan',can_plan_user) # replaces checkaccessplanuser rules.add_perm('rower.is_coach',is_coach_user) # replaces checkaccessuser rules.add_perm('rower.is_pro',ispromember) +rules.add_perm('rower.is_staff',is_staff) # WORKOUT permissions diff --git a/rowers/tests/.~lock.viewnames.csv# b/rowers/tests/.~lock.viewnames.csv# index 5aff9c40..c1247cdc 100644 --- a/rowers/tests/.~lock.viewnames.csv# +++ b/rowers/tests/.~lock.viewnames.csv# @@ -1 +1 @@ -,sander,sander-pc,01.02.2020 09:22,file:///home/sander/.config/libreoffice/4; \ No newline at end of file +,sander,sander-pc,01.02.2020 11:32,file:///home/sander/.config/libreoffice/4; \ No newline at end of file diff --git a/rowers/tests/viewnames.csv b/rowers/tests/viewnames.csv index 9d4432f9..18cbf41a 100644 --- a/rowers/tests/viewnames.csv +++ b/rowers/tests/viewnames.csv @@ -58,12 +58,12 @@ 56,62,workout_forcecurve_view,force curve,TRUE,302,pro,200,302,pro,403,302,coach,200,302,FALSE,FALSE,TRUE,FALSE,TRUE 57,63,workout_unsubscribe_view,unsubscribe from comments,TRUE,302,basic,200,302,basic,200,302,basic,200,302,FALSE,FALSE,TRUE,FALSE,TRUE 58,64,workout_comment_view,comment on workout,TRUE,302,basic,200,302,basic,200,302,coach,200,302,FALSE,FALSE,TRUE,FALSE,TRUE -59,65,workout_tcxemail_view,download TCX file,TRUE,403,basic,200,302,basic,403,403,coach,200,403,FALSE,FALSE,TRUE,TRUE,FALSE -60,66,workout_gpxemail_view,,TRUE,200,basic,200,302,basic,200,302,coach,200,302,FALSE,FALSE,TRUE,FALSE,FALSE -61,67,workout_csvemail_view,,TRUE,200,basic,200,302,basic,200,302,coach,200,302,FALSE,FALSE,TRUE,FALSE,FALSE -62,68,workout_csvtoadmin_view,,TRUE,200,basic,200,302,basic,200,302,coach,200,302,FALSE,FALSE,TRUE,FALSE,FALSE -63,69,workout_edit_view,,TRUE,200,basic,200,302,basic,200,302,coach,200,302,FALSE,FALSE,TRUE,FALSE,FALSE -64,70,workout_map_view,,TRUE,200,basic,200,302,basic,200,302,coach,200,302,FALSE,FALSE,TRUE,FALSE,FALSE +59,65,workout_tcxemail_view,download TCX file,TRUE,403,basic,200,302,basic,403,403,coach,200,403,FALSE,FALSE,TRUE,FALSE,TRUE +60,66,workout_gpxemail_view,download GPX file,TRUE,403,basic,200,302,basic,403,403,coach,200,403,FALSE,FALSE,TRUE,FALSE,TRUE +61,67,workout_csvemail_view,download CSV file,TRUE,403,basic,200,302,basic,403,403,coach,200,403,FALSE,FALSE,TRUE,FALSE,TRUE +62,68,workout_csvtoadmin_view,send CSV to admin,TRUE,403,basic,200,200,basic,200,200,coach,200,200,TRUE,FALSE,TRUE,FALSE,TRUE +63,69,workout_edit_view,Edit Workout,TRUE,403,basic,200,403,basic,403,403,coach,200,403,FALSE,FALSE,TRUE,FALSE,TRUE +64,70,workout_map_view,View workout Map,TRUE,302,basic,200,302,basic,200,302,coach,200,302,FALSE,FALSE,TRUE,TRUE,TRUE 65,71,workout_update_cp_view,,TRUE,200,basic,200,302,basic,200,302,coach,200,302,FALSE,FALSE,TRUE,FALSE,FALSE 66,72,instroke_chart,,TRUE,200,basic,200,302,basic,200,302,coach,200,302,FALSE,FALSE,FALSE,FALSE,FALSE 67,73,instroke_view,,TRUE,200,basic,200,302,basic,200,302,coach,200,302,FALSE,FALSE,TRUE,FALSE,FALSE diff --git a/rowers/views/exportviews.py b/rowers/views/exportviews.py index afdfc7c9..b415696a 100644 --- a/rowers/views/exportviews.py +++ b/rowers/views/exportviews.py @@ -261,6 +261,7 @@ def workout_csvemail_view(request,id=0): # Get Workout CSV file and send it to user's email address @login_required() +@permission_required('rower.is_staff',fn=get_user_by_userid,raise_exception=True) def workout_csvtoadmin_view(request,id=0): message = "" r = getrower(request.user) diff --git a/rowers/views/paymentviews.py b/rowers/views/paymentviews.py index 34a1f133..344f84ac 100644 --- a/rowers/views/paymentviews.py +++ b/rowers/views/paymentviews.py @@ -13,8 +13,8 @@ def paidplans_view(request): else: r = None - - + + return render(request, 'paidplans.html', {'rower':r}) @@ -24,7 +24,7 @@ def billing_view(request): if not PAYMENT_PROCESSING_ON: url = reverse('promembership') return HttpResponseRedirect(url) - + r = request.user.rower if r.paymentprocessor != 'braintree' and r.paymenttype == 'recurring': @@ -42,7 +42,7 @@ def billing_view(request): for attr, value in cd.items(): setattr(r, attr, value) r.save() - + if billingaddressform.is_valid(): if planselectform.is_valid(): plan = planselectform.cleaned_data['plan'] @@ -58,7 +58,7 @@ def billing_view(request): }) return HttpResponseRedirect(url) - + else: billingaddressform = RowerBillingAddressForm(instance=r) planselectform = PlanSelectForm(paymentprocessor='braintree') @@ -69,13 +69,13 @@ def billing_view(request): 'billingaddressform':billingaddressform, 'planselectform':planselectform, }) - + @login_required() def upgrade_view(request): if not PAYMENT_PROCESSING_ON: url = reverse('promembership') return HttpResponseRedirect(url) - + r = request.user.rower if r.paymentprocessor != 'braintree' and r.paymenttype == 'recurring': @@ -93,7 +93,7 @@ def upgrade_view(request): for attr, value in cd.items(): setattr(r, attr, value) r.save() - + if planselectform.is_valid(): plan = planselectform.cleaned_data['plan'] if billingaddressform.is_valid(): @@ -102,7 +102,7 @@ def upgrade_view(request): 'planid':plan.id }) return HttpResponseRedirect(url) - + else: billingaddressform = RowerBillingAddressForm(instance=r) planselectform = PlanSelectForm(paymentprocessor='braintree', @@ -114,13 +114,13 @@ def upgrade_view(request): 'billingaddressform':billingaddressform, 'planselectform':planselectform, }) - + @login_required() def downgrade_view(request): if not PAYMENT_PROCESSING_ON: url = reverse('promembership') return HttpResponseRedirect(url) - + r = request.user.rower if r.paymentprocessor != 'braintree' and r.paymenttype == 'recurring': @@ -138,7 +138,7 @@ def downgrade_view(request): for attr, value in cd.items(): setattr(r, attr, value) r.save() - + if planselectform.is_valid(): plan = planselectform.cleaned_data['plan'] @@ -150,14 +150,14 @@ def downgrade_view(request): return HttpResponseRedirect(url) else: nextview = downgrade_confirm_view - + if billingaddressform.is_valid(): url = reverse(nextview, kwargs={ 'planid':plan.id }) return HttpResponseRedirect(url) - + else: billingaddressform = RowerBillingAddressForm(instance=r) planselectform = PlanSelectForm(paymentprocessor='braintree', @@ -169,17 +169,17 @@ def downgrade_view(request): 'billingaddressform':billingaddressform, 'planselectform':planselectform, }) - + @login_required() def plan_stop_view(request): if not PAYMENT_PROCESSING_ON: url = reverse('promembership') return HttpResponseRedirect(url) - + r = request.user.rower subscriptions = [] - + if r.paymentprocessor != 'braintree' and r.paymenttype == 'recurring': messages.error(request,'Automated payment processing is currently only available through BrainTree (by PayPal). You are currently on a recurring payment plan with PayPal. Contact the site administrator at support@rowsandall.com before you proceed') @@ -189,7 +189,7 @@ def plan_stop_view(request): except ProcessorCustomerError: r.paymentprocessor = None r.save() - + return render(request, @@ -203,7 +203,7 @@ def plan_tobasic_view(request,id=0): if not PAYMENT_PROCESSING_ON: url = reverse('promembership') return HttpResponseRedirect(url) - + r = request.user.rower if r.paidplan.paymentprocessor == 'braintree': @@ -217,15 +217,15 @@ def plan_tobasic_view(request,id=0): url = reverse(plan_stop_view) return HttpResponseRedirect(url) - - + + @login_required() def upgrade_confirm_view(request,planid = 0): if not PAYMENT_PROCESSING_ON: url = reverse('promembership') return HttpResponseRedirect(url) - + try: plan = PaidPlan.objects.get(id=planid) except PaidPlan.DoesNotExist: @@ -253,7 +253,7 @@ def downgrade_confirm_view(request,planid = 0): if not PAYMENT_PROCESSING_ON: url = reverse('promembership') return HttpResponseRedirect(url) - + try: plan = PaidPlan.objects.get(id=planid) except PaidPlan.DoesNotExist: @@ -279,7 +279,7 @@ def payment_confirm_view(request,planid = 0): if not PAYMENT_PROCESSING_ON: url = reverse('promembership') return HttpResponseRedirect(url) - + try: plan = PaidPlan.objects.get(id=planid) except PaidPlan.DoesNotExist: @@ -350,13 +350,13 @@ def checkouts_view(request): url = reverse(paidplans_view) return HttpResponseRedirect(url) - + @login_required() def upgrade_checkouts_view(request): if not PAYMENT_PROCESSING_ON: url = reverse('promembership') return HttpResponseRedirect(url) - + r = request.user.rower @@ -402,7 +402,7 @@ def downgrade_checkouts_view(request): if not PAYMENT_PROCESSING_ON: url = reverse('promembership') return HttpResponseRedirect(url) - + r = request.user.rower @@ -450,7 +450,7 @@ def payment_completed_view(request): amount = request.GET.get('amount',0) - + r = request.user.rower return render(request, @@ -465,7 +465,7 @@ def downgrade_completed_view(request): if not PAYMENT_PROCESSING_ON: url = reverse('promembership') return HttpResponseRedirect(url) - + r = request.user.rower return render(request, @@ -480,7 +480,7 @@ def rower_register_view(request): nextpage = request.GET.get('next','/rowers/list-workouts/') if nextpage == '': nextpage = '/rowers/list-workouts/' - + if request.method == 'POST': #form = RegistrationFormUniqueEmail(request.POST) form = RegistrationFormSex(request.POST) @@ -517,7 +517,7 @@ def rower_register_view(request): timestr = strftime("%Y%m%d-%H%M%S") f2 = f[:-7]+timestr+'.csv.gz' copyfile(f,f2) - + response = dataprep.new_workout_from_file(therower,f2, title='New User Sample Data', notes='This is an example workout to get you started') @@ -527,17 +527,17 @@ def rower_register_view(request): w.startdatetime = timezone.now() w.date = timezone.now().date() w.save() - + # Create and send email fullemail = first_name + " " + last_name + " " + "<" + email + ">" subject = "Thank you for registering on rowsandall.com" from_address = 'Sander Roosendaal ' d = {'first_name':theuser.first_name} - + send_template_email(from_address,[fullemail], subject,'registeremail.html',d) - + subject2 = "New User" message2 = "New user registered.\n" @@ -550,7 +550,7 @@ def rower_register_view(request): theuser = authenticate(username=username,password=password) login(request,theuser) - + return HttpResponseRedirect(nextpage) # '/rowers/register/thankyou/') @@ -572,7 +572,7 @@ def freecoach_register_view(request): nextpage = request.GET.get('next','/rowers/me/teams/') if nextpage == '': nextpage = '/rowers/me/teams/' - + if request.method == 'POST': #form = RegistrationFormUniqueEmail(request.POST) form = RegistrationFormSex(request.POST) @@ -605,17 +605,17 @@ def freecoach_register_view(request): # create default favorite charts add_defaultfavorites(therower) - + # Create and send email fullemail = first_name + " " + last_name + " " + "<" + email + ">" subject = "Thank you for registering on rowsandall.com" from_address = 'Sander Roosendaal ' d = {'first_name':theuser.first_name} - + send_template_email(from_address,[fullemail], subject,'coachregisteremail.html',d) - + subject2 = "New Free Coach" message2 = "New Free Coach registered.\n" @@ -628,7 +628,7 @@ def freecoach_register_view(request): theuser = authenticate(username=username,password=password) login(request,theuser) - + return HttpResponseRedirect(nextpage) else: @@ -647,6 +647,7 @@ def freecoach_register_view(request): 'next':nextpage,}) @login_required() +@permission_required('rower.is_staff',fn=get_user_by_userid,raise_exception=True) def transactions_view(request): if not request.user.is_staff: raise PermissionDenied("Not Allowed") @@ -662,7 +663,7 @@ def transactions_view(request): response = HttpResponse(df.to_csv()) response['Content-Disposition'] = 'attachment; filename="%s"' % filename response['Content-Type'] = 'application/octet-stream' - + return response else: @@ -673,4 +674,3 @@ def transactions_view(request): { 'dateform':dateform }) -