Private
Public Access
1
0

rules first attempt

This commit is contained in:
Sander Roosendaal
2020-01-10 08:06:18 +01:00
parent 1f96ff4fa7
commit 79afd29b19
6 changed files with 126 additions and 82 deletions

View File

@@ -39,6 +39,9 @@ import pandas as pd
from dateutil import parser
import datetime
import rules
from rules.contrib.models import RulesModel
from rowers.rows import validate_file_extension
from collections import OrderedDict
from timezonefinder import TimezoneFinder
@@ -53,6 +56,37 @@ from rowsandall_app.settings import (
TWEET_CONSUMER_SECRET,
)
# PERMISSIONS
@rules.predicate
def is_team_manager(user,team):
print('aap')
return team.manager == user
@rules.predicate
def is_team_member(user,team):
members = Rower.objects.filter(team__in=[team])
return user in [member.user for member in members]
@rules.predicate
def is_coach(user):
r = Rower.objects.get(user=user)
return r.rowerplan in ['coach','freecoach']
@rules.predicate
def can_view_team(user,team):
# user based
r = Rower.objects.get(user=user)
if r.rowerplan == 'basic' and team.manager.rower.rowerplan != 'coach':
return False
# team is public
if team.private == 'open':
return True
# team is private
return is_team_member(user,team) | is_team_manager(user,team)
# END PERMISSIONS
tweetapi = twitter.Api(consumer_key=TWEET_CONSUMER_KEY,
consumer_secret=TWEET_CONSUMER_SECRET,
access_token_key=TWEET_ACCESS_TOKEN_KEY,
@@ -331,7 +365,7 @@ def is_not_basic(user):
# For future Team functionality
@python_2_unicode_compatible
class Team(models.Model):
class Team(RulesModel):
choices = (
('private','private'),
('open','open'),
@@ -350,6 +384,13 @@ class Team(models.Model):
viewing = models.CharField(max_length=30,choices=viewchoices,default='allmembers',verbose_name='Sharing Behavior')
class Meta:
rules_permissions = {
"add": is_coach,
"change": is_team_manager,
"delete": is_team_manager,
"view": can_view_team,
}
def __str__(self):
return self.name

View File

@@ -22,7 +22,7 @@ class IsOwnerOrReadOnly(permissions.BasePermission):
return obj.user == request.user
class IsOwnerOrNot(permissions.BasePermission):
def has_object_permission(self, request, view, obj):
r = Rower.objects.get(user=request.user)
return (obj.user == r)

View File

@@ -23,7 +23,7 @@ queuehigh = django_rq.get_queue('low')
from rowers.models import (
Rower, Workout, Team, TeamInvite,User,TeamRequest, CoachRequest, CoachOffer,
CoachingGroup
CoachingGroup,is_team_manager,is_team_member,is_coach
)
from rowers.tasks import (
@@ -53,14 +53,15 @@ def handle_remove_workouts_team(ws,t):
return 1
def handle_add_workouts_team(ws,t):
for w in ws:
w.team.add(t)
return 1
def update_team(t,name,manager,private,notes,viewing):
if t.manager != manager:
if not is_team_manager(t,manager):
return (0,'You are not the manager of this team')
try:
t.name = name
@@ -82,7 +83,7 @@ def create_team(name,manager,private='open',notes='',viewing='allmembers'):
ts = Team.objects.filter(manager=manager)
if len(ts)>=1:
return (0,'You need to upgrade to the Coach plan to have more than one team')
try:
t = Team(name=name,manager=manager,notes=notes,
private=private,viewing=viewing)
@@ -116,7 +117,7 @@ def remove_team(id):
def add_coach(coach,rower):
# get coaching group
coachgroup = coach.mycoachgroup
if coachgroup is None:
coachgroup = CoachingGroup(name=coach.user.first_name)
@@ -126,7 +127,7 @@ def add_coach(coach,rower):
if get_coach_club_size(coach)<coach.clubsize:
rower.coachinggroups.add(coach.mycoachgroup)
return (1,"Added Coach")
else:
return (0,"Maximum number of athletes reached")
@@ -137,14 +138,14 @@ def add_member(id,rower):
rower.team.add(t)
except ValidationError as e:
return(0,"Couldn't add member: "+str(e.message))
# code to add all workouts
ws = Workout.objects.filter(user=rower)
res = handle_add_workouts_team(ws,t)
# set_teamplanexpires(rower)
return (id,'Member added')
def remove_member(id,rower):
@@ -154,7 +155,7 @@ def remove_member(id,rower):
ws = Workout.objects.filter(user=rower,team=t)
res = handle_remove_workouts_team(ws,t)
# set_teamplanexpires(rower)
return (id,'Member removed')
@@ -166,7 +167,7 @@ def remove_coach(coach,rower):
coachgroup.save()
coach.mycoachgroup = coachgroup
coach.save()
rower.coachinggroups.remove(coachgroup)
return (1,'Coach removed')
@@ -188,7 +189,7 @@ def rower_get_coaches(rower):
pass
return coaches
def coach_getcoachees(coach):
if coach.mycoachgroup and coach.rowerplan in ('coach','freecoach'):
@@ -206,14 +207,14 @@ def coach_remove_athlete(coach,rower):
coachgroup.save()
coach.mycoachgroup = coachgroup
coach.save()
rower.coachinggroups.remove(coachgroup)
return (1,'Coach removed')
def mgr_remove_member(id,manager,rower):
t = Team.objects.get(id=id)
if t.manager == manager:
if is_team_manager(t,manager):
remove_member(id,rower)
send_email_member_dropped(id,rower)
return (id,'Member removed')
@@ -270,7 +271,7 @@ def send_coachrequest_email(rekwest):
res = myqueue(queuehigh,
handle_sendemail_coachrequest,
email,name,code,coachname)
def send_coacheerequest_email(rekwest):
name = rekwest.user.first_name + " " + rekwest.user.last_name
email = rekwest.user.email
@@ -282,7 +283,7 @@ def send_coacheerequest_email(rekwest):
res = myqueue(queuehigh,
handle_sendemail_coacheerequest,
email,name,code,coachname)
def create_request(team,user):
r2 = Rower.objects.get(user=user)
r = Rower.objects.get(user=team.manager)
@@ -299,11 +300,11 @@ def create_request(team,user):
u = User.objects.get(id=user)
rekwest = TeamRequest(team=team,user=u,code=code)
rekwest.save()
send_request_email(rekwest)
return (rekwest.id,'The request was created')
return (0,'Something went wrong in create_request')
def get_coach_club_size(coach):
@@ -341,11 +342,11 @@ def create_coaching_offer(coach,user):
return (0,'You are not a coach')
def create_invite(team,manager,user=None,email=''):
r = Rower.objects.get(user=manager)
if team.manager != manager:
if not is_team_manager(team,manager):
return (0,'Not the team manager')
if user:
try:
@@ -365,7 +366,7 @@ def create_invite(team,manager,user=None,email=''):
user=None
except Rower.MultipleObjectsReturned:
return (0,'There is more than one user with that email address')
# if count_club_members(team.manager)+count_invites(team.manager) <= r.clubsize:
codes = [i.code for i in TeamInvite.objects.all()]
code = uuid.uuid4().hex[:10].upper()
@@ -376,8 +377,8 @@ def create_invite(team,manager,user=None,email=''):
invite = TeamInvite(team=team,code=code,user=user,email=email)
invite.save()
return (invite.id,'Invitation created')
return (0,'Nothing done')
def revoke_request(user,id):
@@ -402,7 +403,7 @@ def reject_revoke_coach_offer(user,id):
if rekwest.coach.user == user:
rekwest.delete()
return (1,'Request removed')
elif rekwest.user == user:
send_coachoffer_rejected_email(rekwest)
@@ -410,7 +411,7 @@ def reject_revoke_coach_offer(user,id):
return (1,'Request removed')
else:
return (0,'Not permitted')
def reject_revoke_coach_request(user,id):
try:
rekwest = CoachRequest.objects.get(id=id)
@@ -433,26 +434,26 @@ def revoke_invite(manager,id):
except TeamInvite.DoesNotExist:
return (0,'The invitation is invalid')
if invite.team.manager==manager:
if is_team_manager(invite.team,manager):
invite.delete()
return (1,'Invitation revoked')
else:
return (0,'You are not the team manager')
def reject_request(manager,id):
try:
rekwest = TeamRequest.objects.get(id=id)
except TeamRequest.DoesNotExist:
return (0,'The request is invalid')
if rekwest.team.manager==manager:
if is_team_manager(rekwest.team,manager):
send_request_reject_email(rekwest)
rekwest.delete()
return (1,'Request rejected')
else:
return (0,'You are not the manager for this request')
def reject_invitation(user,id):
try:
invite = TeamInvite.objects.get(id=id)
@@ -472,14 +473,14 @@ def send_invite_email(id):
invitation = TeamInvite.objects.get(id=id)
except TeamInvite.DoesNotExist:
return (0,'Invitation doesn not exist')
if invitation.user:
email = invitation.user.email
name = invitation.user.first_name + " " + invitation.user.last_name
else:
email = invitation.email
name = ''
code = invitation.code
teamname = invitation.team.name
manager = invitation.team.manager.first_name+' '+invitation.team.manager.last_name
@@ -514,7 +515,7 @@ def send_email_member_dropped(teamid,rower):
email,name,teamname,manager)
return (1,'Member dropped email sent')
def send_request_accept_email(rekwest):
id = rekwest.id
@@ -527,7 +528,7 @@ def send_request_accept_email(rekwest):
email,name,teamname,manager)
return (1,'Invitation email sent')
def send_request_reject_email(rekwest):
id = rekwest.id
@@ -606,7 +607,7 @@ def send_request_email(rekwest):
def process_request_code(manager,code):
code = code.upper()
try:
rekwest = TeamRequest.objects.get(code=code)
except TeamRequest.DoesNotExist:
@@ -622,10 +623,10 @@ def process_request_code(manager,code):
if not result:
return (result,"The member couldn't be added")
send_request_accept_email(rekwest)
rekwest.delete()
return (result,'The member was added')
@@ -641,7 +642,7 @@ def process_invite_code(user,code):
if nu > invitation.issuedate+timedelta(days=inviteduration):
revoke_invite(invitation.team.manager,invitation.id)
return (0,'The invitation has expired')
t = invitation.team
result, comment = add_member(t.id,r)
if not result:
@@ -698,7 +699,7 @@ def process_coachoffer_code(user,code):
return result
else:
send_coachoffer_accepted_email(rekwest)
rekwest.delete()
return result
@@ -732,7 +733,7 @@ def send_coachrequest_accepted_email(rekwest):
res = myqueue(queuehigh,
handle_sendemail_coachrequest_accepted,
email,coachname,name)
def send_coachoffer_accepted_email(rekwest):
coachname = rekwest.coach.user.first_name + " " + rekwest.coach.user.last_name
@@ -743,5 +744,3 @@ def send_coachoffer_accepted_email(rekwest):
res = myqueue(queuehigh,
handle_sendemail_coachoffer_accepted,
coachemail,coachname,name)

View File

@@ -240,7 +240,7 @@ from rq import Queue,cancel_job
from django.core.cache import cache
from django_mailbox.models import Message,Mailbox,MessageAttachment
from rules.contrib.views import permission_required, objectgetter
# Utility to get stroke data in a JSON response
class JSONResponse(HttpResponse):

View File

@@ -6,7 +6,8 @@ from __future__ import unicode_literals
from rowers.views.statements import *
@login_required()
#@login_required()
@permission_required('teams.view_team',fn=objectgetter(Team,'id'))
def team_view(request,id=0,userid=0):
ismember = 0
hasrequested = 0
@@ -16,25 +17,25 @@ def team_view(request,id=0,userid=0):
teams.remove_expired_invites()
try:
t = Team.objects.get(id=id)
except Team.DoesNotExist:
raise Http404("Team doesn't exist")
if r.rowerplan == 'basic' and t.manager.rower.rowerplan != 'coach':
raise PermissionDenied("You need to be on a Paid Plan to see or join this team")
#if r.rowerplan == 'basic' and t.manager.rower.rowerplan != 'coach':
# raise PermissionDenied("You need to be on a Paid Plan to see or join this team")
q = User.objects.filter(rower__isnull=False,rower__team__in=myteams).distinct().exclude(rower__team__name=t.name)
mygroups = [request.user.rower.mycoachgroup]
q2 = User.objects.filter(rower__isnull=False,rower__coachinggroups__in=mygroups).distinct().exclude(rower__team__name=t.name)
q = q | q2
if request.method == 'POST' and request.user == t.manager and 'email' in request.POST:
inviteform = TeamInviteForm(request.POST)
inviteform.fields['user'].queryset = q
if inviteform.is_valid():
cd = inviteform.cleaned_data
@@ -59,7 +60,7 @@ def team_view(request,id=0,userid=0):
teams.send_team_message(t,message)
messages.info(request,'Message was sent to all team members')
groupmessageform = TeamMessageForm()
elif request.user == t.manager:
inviteform = TeamInviteForm()
inviteform.fields['user'].queryset = q
@@ -68,7 +69,7 @@ def team_view(request,id=0,userid=0):
inviteform = ''
groupmessageform = ''
members = Rower.objects.filter(team=t).order_by('user__last_name','user__first_name')
thisteammyrequests = TeamRequest.objects.filter(team=t,user=request.user)
if len(thisteammyrequests):
@@ -112,7 +113,7 @@ def team_leaveconfirm_view(request,id=0):
raise Http404("Team doesn't exist")
myteams, memberteams, otherteams = get_teams(request)
breadcrumbs = [
{
'url':reverse(rower_teams_view),
@@ -144,7 +145,7 @@ def rower_calcdps_view(request):
ws = [(w.id,w.csvfilename) for w in Workout.objects.filter(user=r)]
res = myqueue(queue,handle_updatedps,r.user.email,ws,debug=False,
emailbounced=r.emailbounced)
emailbounced=r.emailbounced)
messages.info(request,"Your workouts are being updated in the background. You will receive email when this is done.")
@@ -155,7 +156,7 @@ def rower_calcdps_view(request):
def team_leave_view(request,id=0):
r = getrower(request.user)
teams.remove_member(id,r)
url = reverse(rower_teams_view)
response = HttpResponseRedirect(url)
return response
@@ -164,7 +165,7 @@ from rowers.forms import TeamInviteCodeForm
def get_teams(request):
r = Rower.objects.get(user=request.user)
myteams = Team.objects.filter(
manager=request.user).order_by('name')
memberteams = Team.objects.filter(
@@ -191,7 +192,7 @@ def rower_teams_view(request):
messages.error(request,text)
else:
form = TeamInviteCodeForm()
r = getrower(request.user)
ts = Team.objects.filter(rower=r)
@@ -208,7 +209,7 @@ def rower_teams_view(request):
mycoachoffers = CoachOffer.objects.filter(coach=r)
# user is invited (by coach)
coachoffers = CoachOffer.objects.filter(user=r.user)
# user requests a coach
mycoachrequests = CoachRequest.objects.filter(user=r.user)
# user is requested to coach
@@ -230,7 +231,7 @@ def rower_teams_view(request):
potentialcoaches = [c for c in potentialcoaches if c.rower not in invitedcoaches+coaches]
potentialcoaches = [c for c in potentialcoaches if teams.get_coach_club_size(c.rower)<c.rower.clubsize]
coachees = teams.coach_getcoachees(request.user.rower)
if request.user.rower.rowerplan == 'coach':
@@ -253,7 +254,7 @@ def rower_teams_view(request):
potentialathletes = []
potentialathletes = [a for a in potentialathletes if a.user not in invitingathletes]
# clubsize = teams.count_invites(request.user)+teams.count_club_members(request.user)
# max_clubsize = r.clubsize
@@ -265,7 +266,7 @@ def rower_teams_view(request):
}
]
return render(request, 'teams.html',
{
'teams':ts,
@@ -312,7 +313,7 @@ def manager_member_drop_view(request,teamid,userid,
messages.info(request,text)
else:
messages.error(request,text)
url = reverse(rower_teams_view)
return HttpResponseRedirect(url)
@@ -441,14 +442,14 @@ def team_requestmembership_view(request,teamid,userid):
url = reverse('paidplans')
return HttpResponseRedirect(url)
res,text = teams.create_request(t,userid)
if res:
messages.info(request,text)
else:
messages.error(request,text)
url = reverse('team_view',kwargs={
'id':int(teamid),
})
@@ -583,14 +584,14 @@ def rower_invitations_view(request,code=None,message='',successmessage=''):
url = reverse(rower_teams_view,kwargs={
})
return HttpResponseRedirect(url)
@login_required()
def team_edit_view(request,id=0):
try:
t = Team.objects.get(id=id)
except Team.DoesNotExist:
raise Http404("Team does not exist")
if request.method == 'POST':
teamcreateform = TeamForm(request.POST,instance=t)
if teamcreateform.is_valid():
@@ -612,7 +613,7 @@ def team_edit_view(request,id=0):
'id':int(id),
}
)
response = HttpResponseRedirect(url)
return response
@@ -620,7 +621,7 @@ def team_edit_view(request,id=0):
teamcreateform = TeamForm(instance=t)
myteams, memberteams, otherteams = get_teams(request)
breadcrumbs = [
{
'url':reverse(rower_teams_view),
@@ -659,8 +660,8 @@ def team_create_view(request):
url = reverse('paidplans')
return HttpResponseRedirect(url)
if request.method == 'POST':
teamcreateform = TeamForm(request.POST)
if teamcreateform.is_valid():
@@ -677,7 +678,7 @@ def team_create_view(request):
messages.error(request,message)
url = reverse('paidplans')
return HttpResponseRedirect(url)
url = reverse('rower_teams_view')
response = HttpResponseRedirect(url)
return response
@@ -686,7 +687,7 @@ def team_create_view(request):
teamcreateform = TeamForm()
myteams, memberteams, otherteams = get_teams(request)
breadcrumbs = [
{
'url':reverse(rower_teams_view),
@@ -708,7 +709,8 @@ def team_create_view(request):
'breadcrumbs':breadcrumbs,
})
@login_required()
#@login_required()
@permission_required('teams.delete_team',fn=objectgetter(Team,'id'))
def team_deleteconfirm_view(request,id):
r = getrower(request.user)
try:
@@ -719,7 +721,7 @@ def team_deleteconfirm_view(request,id):
raise PermissionDenied("You are not allowed to delete this team")
myteams, memberteams, otherteams = get_teams(request)
breadcrumbs = [
{
'url':reverse(rower_teams_view),
@@ -755,7 +757,7 @@ def team_delete_view(request,id):
raise PermissionDenied("You are not allowed to delete this team")
teams.remove_team(t.id)
url = reverse(rower_teams_view)
response = HttpResponseRedirect(url)
return response
@@ -771,11 +773,11 @@ def team_members_stats_view(request,id):
raise PermissionDenied("You are not allowed to see this page")
members = Rower.objects.filter(team=t).order_by("user__last_name","user__first_name")
theusers = [member.user for member in members]
myteams, memberteams, otherteams = get_teams(request)
breadcrumbs = [
{
'url':reverse(rower_teams_view),
@@ -790,7 +792,7 @@ def team_members_stats_view(request,id):
'name': 'Members Stats'
}
]
response = render(request,'teamstats.html',
{
'teams':get_my_teams(request.user),