def list_files_of_type(request, pk): """ Lists all files of one type of professional skill. :param request: :param pk: filetype to show delivered files for :return: """ ftype = get_object_or_404(FileType, pk=pk) if get_grouptype('3') in request.user.groups.all() or \ get_grouptype('6') in request.user.groups.all(): files = StudentFile.objects.filter(Type=ftype).distinct() elif get_grouptype('1') in request.user.groups.all() or \ get_grouptype('2') in request.user.groups.all(): # type1 or type2 dists = get_distributions(request.user, timeslot=get_timeslot()) if not dists: # raise PermissionDenied('You do not have any distributed students at this moment.') return render( request, 'base.html', context={ 'Message': 'You do not have any distributed students at this moment.' }) files = StudentFile.objects.filter(Type=ftype, Distribution__in=dists) # elif not request.user.groups.exists(): # files = StudentFile.objects.filter(Type=ftype, Distribution=request.user.distribution.get(TimeSlot=get_timeslot())) else: raise PermissionDenied('Not allowed.') return render(request, 'professionalskills/list_files.html', { 'type': ftype, 'files': files, })
def __init__(self, *args, **kwargs): self.request = kwargs.pop('request', None) super().__init__(*args, **kwargs) self.fields['ResponsibleStaff'].queryset = get_grouptype( '1').user_set.all() self.fields['Assistants'].queryset = get_grouptype('2').user_set.all() | \ get_grouptype('2u').user_set.all() | \ get_grouptype('1').user_set.all() self.fields[ 'ResponsibleStaff'].label_from_instance = self.user_label_from_instance self.fields[ 'Assistants'].label_from_instance = self.user_label_from_instance self.fields['addAssistantsEmail'].widget.attrs[ 'placeholder'] = "Add assistant via email address" self.fields['Private'].queryset = User.objects.filter(groups=None) # no user label_from_instance for private students because privacy. self.fields['addPrivatesEmail'].widget.attrs[ 'placeholder'] = "Add private student via email address" if get_timephase_number() == 1: self.fields['TimeSlot'].queryset = TimeSlot.objects.filter( End__gt=datetime.now()) self.fields['TimeSlot'].initial = get_timeslot() else: if self.request.user.is_superuser or get_grouptype( '3') in self.request.user.groups.all(): self.fields['TimeSlot'].queryset = TimeSlot.objects.all() else: # phase 2+, only add for future timeslot self.fields['TimeSlot'].queryset = TimeSlot.objects.filter( Begin__gt=datetime.now())
def list_pending(request): """ Get and show the pending proposals for a given user. :param request: :return: """ projects = [] if get_grouptype("2") in request.user.groups.all() or get_grouptype("2u") in request.user.groups.all(): # type2 can only be assistant projects = get_all_projects().filter(Q(Assistants__id=request.user.id) & Q(Status__exact=1)) elif get_grouptype("1") in request.user.groups.all(): # type1 can be responsible, trackhead or assistant projects = get_all_projects().filter((Q(Assistants__id=request.user.id) & Q(Status__exact=1)) | (Q(ResponsibleStaff=request.user.id) & Q(Status__exact=2)) | (Q(Track__Head=request.user.id) & Q(Status__exact=3)) ).distinct() if get_grouptype('4') in request.user.groups.all() and request.user.administratorgroups.exists(): for group in request.user.administratorgroups.all(): projects = set(list(chain(list(projects), list(get_all_projects().filter(Q(Group=group) & Q(Status__lte=2)))))) title = 'Pending projects for your group' else: title = 'Pending projects' return render(request, "proposals/list_projects_custom.html", { 'projects': projects, 'favorite_projects': get_favorites(request.user), "title": title, })
def wrapper(*args, **kw): request = args[0] # user needs to be logged in (so no need for login_required on top of this) if not request.user.is_authenticated: page = args[0].path return redirect_to_login( next=page, login_url='index:login', redirect_field_name='next', ) # type 3 and 6 can always view professional skills. # Everyone can view it in phase 6 (execution) and later (presenting). if get_timephase_number() < 5 and \ get_grouptype("3") not in request.user.groups.all() and \ get_grouptype("6") not in request.user.groups.all(): raise PermissionDenied( "Student files are not available in this phase") if not request.user.groups.exists( ) and not request.user.distributions.exists(): raise PermissionDenied( "Student files are available after you are distributed to a project." ) return fn(*args, **kw)
def upgrade_status_api(request, pk): """ API call to increase the status of a proposal. :param request: :param pk: id of proposal :return: """ obj = get_object_or_404(Proposal, pk=pk) if obj.Status == 4: return HttpResponse("Already at final stage", status=403) if obj.Status == 3 and obj.nextyear(): return HttpResponse("Cannot publish proposal for future timeslot", status=403) elif get_timephase_number() > 2 and \ obj.TimeSlot == get_timeslot() and \ get_grouptype('3') not in request.user.groups.all(): return HttpResponse( "Proposal frozen in this timeslot. The timephase of editing has ended.", status=403) elif request.user in obj.Assistants.all() and obj.Status >= 2: return HttpResponse( "You are an assistant and not allowed to increase status further", status=403) # Done in can_edit decorator # elif obj.Track.Head != request.user and obj.Status > 2 and not get_grouptype('3') in request.user.groups.all(): # return HttpResponse("Not allowed to publish as non track head", status=403) else: oldstatus = obj.Status if oldstatus == 2: # per default go to publish from 4, 3 is only used if it is explicitly downgraded newstatus = 4 else: newstatus = obj.Status + 1 obj.Status = newstatus obj.save() mail_proposal_all(request, obj) notification = ProposalStatusChange() notification.Subject = obj notification.Actor = request.user notification.StatusFrom = oldstatus notification.StatusTo = newstatus notification.save() if obj.Status > 3: for assistant in obj.Assistants.all(): if get_grouptype("2u") in assistant.groups.all(): verify_assistant_fn(assistant) if obj.Status == 4: # put the object in cache if status goes from 3->4 cache.set('proposal_{}'.format(pk), obj, None) cache.delete('listproposalsbodyhtml') return HttpResponse(getStatStr(obj.Status))
def get_distributions(user, timeslot=None): """ Function to return the distributions that a given staff user is allowed to see Type3 and 6 should see all distributions, to be able to mail them. :param user: The user to test :param timeslot: TimeSlot to get distributions from :return empty queryset on fail """ if get_grouptype('2u') in user.groups.all(): return Distribution.objects.none() if timeslot is None: timeslot = get_timeslot() if timeslot is None: return Distribution.objects.none( ) # similar to None, but can be used in chained filter. des_all = Distribution.objects.filter(TimeSlot=timeslot) if get_grouptype("3") in user.groups.all( ) or user.is_superuser or get_grouptype("6") in user.groups.all(): return des_all else: tracks = Track.objects.filter(Head=user) if planning_public() and timeslot == get_timeslot(): return des_all.filter( Q(Proposal__Track__in=tracks) | Q(Proposal__ResponsibleStaff=user) | Q(Proposal__Assistants__id=user.id) | Q(presentationtimeslot__Presentations__Assessors__id=user.id) ).distinct() else: return des_all.filter( Q(Proposal__Track__in=tracks) | Q(Proposal__ResponsibleStaff=user) | Q(Proposal__Assistants__id=user.id)).distinct()
def create_project(request): """ Create a new proposal. Only for staff. Generating a new proposal for this timeslot is only allowed in the first timephase. In other timephases projects can only be generated for the next timeslot. :param request: :return: """ if request.method == 'POST': form = ProposalFormCreate(request.POST, request=request) if form.is_valid(): prop = form.save() mail_proposal_all(request, prop) check_content_policy.CPVCheckThread(prop).start() if prop.Private.all(): for std in prop.Private.all(): mail_proposal_private(prop, std, "A private proposal was created for you.") return render(request, "proposals/message_project.html", {"Message": "Proposal created!", "Proposal": prop}) else: init = {} if get_grouptype("1") in request.user.groups.all(): init["ResponsibleStaff"] = request.user.id elif get_grouptype("2") in request.user.groups.all() or get_grouptype('2u'): init["Assistants"] = [request.user.id] form = ProposalFormCreate(request=request, initial=init) if get_timephase_number() == 1: return render(request, 'GenericForm.html', {'form': form, 'formtitle': 'Create new Proposal', 'buttontext': 'Create and go to next step'}) else: return render(request, 'GenericForm.html', {'form': form, 'formtitle': 'Create new Proposal (For next timeslot)', 'buttontext': 'Create and go to next step'})
def list_own_projects(request, timeslot=None): """ This lists all proposals that the given user has something to do with. Either a responsible or assistant. For Type3staff this lists all proposals. This is the usual view for staff to view their proposals. :param request: :param timeslot: optional timeslot to view proposals from, default is current ts. :return: """ if timeslot: ts = get_object_or_404(TimeSlot, pk=timeslot) projects = get_all_projects(old=True).filter(TimeSlot=ts) else: ts = None projects = get_all_projects(old=True).filter(TimeSlot=None) # proposals of future timeslot if get_grouptype("3") in request.user.groups.all() or get_grouptype("5") in request.user.groups.all(): pass else: projects = projects.filter(Q(ResponsibleStaff=request.user) | Q(Assistants=request.user)).distinct() projects = prefetch(projects) return render(request, 'proposals/list_projects_custom.html', { 'hide_sidebar': True, 'projects': projects, 'favorite_projects': get_favorites(request.user), 'timeslots': get_recent_timeslots(), 'timeslot': ts, })
def can_downgrade_project_fn(user, proj): """ Check if user can downgrade a project. upgrade is same as with can_edit_project_fn :param user: :param proj: :return: """ if proj.prevyear(): return False, "This is an old proposal. Changing history is not allowed." if proj.Status == 1: return False, "Already at first stage." # support staf, superusers are always allowed to downgrade if get_grouptype("3") in user.groups.all() \ or user.is_superuser: return True, "" # proposals of this year, check timephases if proj.TimeSlot == get_timeslot(): # if no timephase is enabled than forbid editing if get_timephase_number() < 0: return False, "No editing allowed, system is closed" # if timephase is after checking phase no editing is allowed, except for support staff if get_timephase_number() > 2 and not get_grouptype( "3") in user.groups.all(): return False, "Proposal is frozen in this timeslot" # if status is 3 or 4 Responsible can downgrade 3-2 in timephase 1 only if proj.Status >= 3 and proj.ResponsibleStaff == user and get_timephase_number( ) == 1: return True, "" # Track head can downgrade in phase 1 and 2 if get_timephase_number() <= 2 and ( proj.Track.Head == user or group_administrator_status(proj, user) > 1): return True, "" else: # if status is 3 Responsible can downgrade 3-2 if not in this timeslot if proj.Status == 3 and proj.ResponsibleStaff == user: return True, "" # Track head is allowed all for not this timeslot if proj.Track.Head == user or group_administrator_status(proj, user) > 1: return True, "" # if status is 2 and user is assistant downgrade is allowed if proj.Status == 2 \ and (user in proj.Assistants.all() or proj.ResponsibleStaff == user): return True, "" return False, "You are not allowed to downgrade this project."
def __init__(self, *args, **kwargs): self.request = kwargs.pop('request', None) self.support = get_grouptype('3') in self.request.user.groups.all() super().__init__(*args, **kwargs) self.fields[ 'Assistants'].label_from_instance = self.user_label_from_instance self.fields['Assistants'].queryset = get_grouptype('2').user_set.all() | \ get_grouptype('2u').user_set.all() | \ get_grouptype('1').user_set.all() if not self.support: self.fields.pop('ResponsibleStaff')
def __init__(self, *args, **kwargs): super().__init__(*args, **kwargs) self.fields[ 'Assessors'].label_from_instance = self.user_label_from_instance self.fields['Assessors'].queryset = get_grouptype('2').user_set.all().select_related('usermeta') | \ get_grouptype('2u').user_set.all().select_related('usermeta') | \ get_grouptype('1').user_set.all().select_related('usermeta') self.fields[ 'PresentationAssessors'].label_from_instance = self.user_label_from_instance self.fields['PresentationAssessors'].queryset = get_grouptype( '7').user_set.all().select_related('usermeta')
def set_level(user): try: grant = AccessGrant.objects.get(Email=user.email) except AccessGrant.DoesNotExist: return if grant.Level == 1: user.groups.add(get_grouptype("1")) user.save() if grant.Level == 2: if get_grouptype("2u") in user.groups.all(): user.groups.remove(get_grouptype("2u")) user.groups.add(get_grouptype("2")) user.save()
def view_response(request, pk): """ Form to let a student view a staff response / rubric :param request: :param pk: pk of studentfile :return: """ if get_grouptype('2u') in request.user.groups.all(): raise PermissionDenied("Please have your account verified first.") fileobj = get_object_or_404(StudentFile, pk=pk) # allow type3 and type6 to view results and all responsibles. if not get_grouptype('3') in request.user.groups.all( ) and not get_grouptype('6') in request.user.groups.all(): if (request.user not in fileobj.Distribution.Proposal.Assistants.all() and request.user != fileobj.Distribution.Proposal.ResponsibleStaff and request.user != fileobj.Distribution.Proposal.Track.Head and request.user != fileobj.Distribution.Student): raise PermissionDenied("You cannot view this file response.") try: responseobj = fileobj.staffresponse except StaffResponse.DoesNotExist: return render(request, 'base.html', {"Message": "This file is not (yet) graded."}) aspect_forms = [] for i, aspect in enumerate(fileobj.Type.aspects.all()): try: aspect_result = StaffResponseFileAspectResult.objects.get( Aspect=aspect, Response=responseobj) except StaffResponseFileAspectResult.DoesNotExist: aspect_result = StaffResponseFileAspectResult(Aspect=aspect, Response=responseobj) aspect_forms.append({ "form": StaffResponseFileAspectResultForm(instance=aspect_result, prefix="aspect" + str(i)), "aspect": aspect }) return render( request, 'professionalskills/view_response.html', { 'file': fileobj, 'response': responseobj, 'aspectoptions': StaffResponseFileAspectResult.ResultOptions })
def list_students_xlsx(request): """ Same as liststudents but as XLSX. The combination of students and grades is done in general_excel. :param request: """ if get_timephase_number() < 0: if get_timeslot() is None: raise PermissionDenied("System is closed.") else: if get_timephase_number() < 4: raise PermissionDenied("Students are not yet distributed") if get_timephase_number() < 5 and not get_grouptype( "3") in request.user.groups.all(): return render( request, "base.html", { 'Message': "When the phase 'Distribution of projects is " "finished, you can view your students here." }) typ = GradeCategory.objects.filter(TimeSlot=get_timeslot()) des = get_distributions(request.user) file = get_list_students_xlsx(des, typ) response = HttpResponse(content=file) response[ 'Content-Type'] = 'application/vnd.openxmlformats-officedocument.spreadsheetml.sheet' response[ 'Content-Disposition'] = 'attachment; filename=students-grades.xlsx' return response
def finalize_preview(request, pk, step=0): """ Edit grade for a category as indexed by step. For each student as given by pk. Also edit the individual aspects of each grade category. For trackheads and responsible staff :param request: :param pk: id of distribution :param step: number of step in the menu, index of category :return: """ ts = get_timeslot() if not hasattr(ts, 'resultoptions'): raise PermissionDenied("Results menu is not yet visible.") else: if not get_timeslot().resultoptions.Visible: raise PermissionDenied("Results menu is not yet visible.") dstr = get_object_or_404(Distribution, pk=pk) if not hasattr(dstr, 'presentationtimeslot'): raise PermissionDenied('This student does not have a presentation planned. Please plan it first.') if not request.user.is_superuser and \ request.user != dstr.Proposal.Track.Head and \ request.user != dstr.Proposal.ResponsibleStaff and \ get_grouptype('3') not in request.user.groups.all() and \ request.user not in dstr.presentationtimeslot.Presentations.Assessors.all(): raise PermissionDenied("You do not have the correct permissions to view print preview.") return render(request, "results/finalize_grades.html", { "dstr": dstr, "catresults": dstr.results.all(), "final": all(f.Final is True for f in dstr.results.all()) if dstr.results.all() else False, "finalgrade": dstr.TotalGradeRounded(), "preview": True, })
def student_files(request, fileid, distid=''): """ Student file, uploaded by student as professionalskill. Model in students-app Type3 and 4 (support and profskill) staff can see all studentfiles. Responsible and assistant of student can view files. Student itself can view its own files :param request: :param fileid: id of the student file. :param distid: id of the distribution of the student. :return: """ # first try PK, then filename try: obj = StudentFile.objects.get(id=fileid) except: # accessed by distribution, then by filename, (the old way) obj = get_object_or_404(StudentFile, File='dist_{}/{}'.format(distid, fileid)) if get_grouptype("3") in request.user.groups.all() \ or Group.objects.get(name='type4staff') in request.user.groups.all() \ or obj.Distribution.Proposal.ResponsibleStaff == request.user \ or request.user in obj.Distribution.Proposal.Assistants.all() \ or obj.Distribution.Student == request.user: # Allowed to view this file return sendfile(request, obj.File.path, attachment=True, attachment_filename=obj.OriginalName) else: # not allowed raise PermissionDenied("You are not allowed to view this file.")
def sessionList(request): """ List all active sessions (logged in users) with the possibility to kill a session (logout the user) :param request: """ sessions = Session.objects.filter(expire_date__gte=timezone.now()) uid_list = [] for session in sessions: data = session.get_decoded() uid_list.append(data.get('_auth_user_id', None)) users = [] for user in User.objects.filter(id__in=uid_list): if get_grouptype("3") in user.groups.all(): continue try: lastlogin = UserLogin.objects.filter( Subject=user).latest('Timestamp') users.append({'user': user, 'lastlogin': lastlogin}) except: # a session without a user (should not happen, only when user is deleted recently) pass return render(request, "godpowers/listSessions.html", {"users": users})
def has_group(user, group_names): """ Check groups for given user. :param user: :param group_names: :return: """ if user.is_anonymous: return False if user.is_superuser: if group_names == "students": return False else: return True if group_names == "any": if user.groups.exists(): return True else: return False elif group_names == "students": if not user.groups.exists(): return True else: return False # check groups for group_name in group_names.split(';'): if group_name == 'type2staffunverified': shortname = '2u' else: shortname = group_name[4] group = get_grouptype(shortname) if group in user.groups.all(): return True return False
def __init__(self, *args, **kwargs): self.request = kwargs.pop('request', None) super().__init__(*args, **kwargs) self.fields['ResponsibleStaff'].queryset = get_grouptype( '1').user_set.all().select_related('usermeta') self.fields['Assistants'].queryset = get_grouptype('2').user_set.all().select_related('usermeta') | \ get_grouptype('2u').user_set.all().select_related('usermeta') | \ get_grouptype('1').user_set.all().select_related('usermeta') self.fields[ 'ResponsibleStaff'].label_from_instance = self.user_label_from_instance self.fields[ 'Assistants'].label_from_instance = self.user_label_from_instance # self.fields['addAssistantsEmail'].widget.attrs['placeholder'] = "Add assistant via email address" self.fields['Private'].queryset = User.objects.filter( groups=None).select_related('usermeta') self.fields[ 'Private'].label_from_instance = self.user_label_from_instance # no user label_from_instance for private students because privacy. self.fields['addPrivatesEmail'].widget.attrs[ 'placeholder'] = "Add private student via email address" self.fields['TimeSlot'].empty_label = 'Future' if get_timephase_number() == 1: self.fields['TimeSlot'].queryset = TimeSlot.objects.filter( End__gt=datetime.now()).order_by('-Begin') self.fields['TimeSlot'].initial = get_timeslot() else: if self.request.user.is_superuser or get_grouptype( '3') in self.request.user.groups.all(): self.fields['TimeSlot'].queryset = TimeSlot.objects.all( ).order_by('-Begin') try: self.fields['TimeSlot'].initial = TimeSlot.objects.filter( Begin__gt=datetime.now()).order_by('-Begin')[ 0] # autofill to first next available timeslot. except IndexError: self.fields['TimeSlot'].initial = None else: # phase 2+, only add for future timeslot tss = TimeSlot.objects.filter( Begin__gt=datetime.now()).order_by('-Begin') self.fields['TimeSlot'].queryset = tss try: self.fields['TimeSlot'].initial = tss[ 0] # autofill to first next available timeslot. except IndexError: self.fields['TimeSlot'].initial = None
def clean(self): """ Merge Private and addPrivatesEmail to Private, Merge addAssistantsEmail and Assistants to Assistants Verify validity of added users via email. Make sure the Private and Assistant dropdown field exist on the form, otherwise addAssistantEmail and addPrivateEmail are not saved. :return: updated Assistants and Privates """ cleaned_data = super().clean() # add and check private students privates = [] if cleaned_data.get('Private'): privates += cleaned_data.get('Private') if cleaned_data.get('addPrivatesEmail'): privates += cleaned_data.get('addPrivatesEmail') privates = set(privates) for account in privates: for p in account.personal_proposal.all(): if p.TimeSlot == cleaned_data.get( 'TimeSlot') and p.pk != self.instance.pk: raise ValidationError( "Student {} already has another private proposal!". format(account.usermeta.get_nice_name())) cleaned_data['Private'] = privates # add and check assistants. assistants = [] if cleaned_data.get('Assistants'): assistants += cleaned_data.get('Assistants') # if cleaned_data.get('addAssistantsEmail'): # assistants += cleaned_data.get('addAssistantsEmail') assistants = set(assistants) for account in assistants: if account == cleaned_data.get('ResponsibleStaff'): raise ValidationError( "The responsible staff member cannot be assistants of its own project." ) # for assistants added using email, the queryset is not checked, so check groups now. if get_grouptype('2') not in account.groups.all() and \ get_grouptype('2u') not in account.groups.all() and \ get_grouptype('1') not in account.groups.all(): raise ValidationError( "The user {} is not allowed as assistant. Please contact the support staff if this user needs to be added." .format(account.usermeta.get_nice_name())) cleaned_data['Assistants'] = assistants return cleaned_data
def can_respond_file(user, dist): if dist.TimeSlot == get_timeslot(): # current timeslot if user in dist.Proposal.Assistants.all() \ or user == dist.Proposal.ResponsibleStaff \ or user == dist.Proposal.Track.Head \ or get_grouptype('3') in user.groups.all(): return True return False
def wrapper(*args, **kw): if 'pk' in kw: pk = int(kw['pk']) else: pk = int(args[1]) proj = get_cached_project(pk) request = args[0] # user needs to be logged in (so no need for login_required on top of this) if not request.user.is_authenticated: page = args[0].path return redirect_to_login( next=page, login_url='index:login', redirect_field_name='next', ) # support staf or superusers are always allowed to view if get_grouptype( "3") in request.user.groups.all() or request.user.is_superuser: return fn(*args, **kw) # user is staffmember and involved in the project if proj.ResponsibleStaff == request.user \ or request.user in proj.Assistants.all() \ or proj.Track.Head == request.user: return fn(*args, **kw) # group administrators can view proposal if group_administrator_status(proj, request.user) > 0: return fn(*args, **kw) # if project is published, non private and its the right time phase if proj.Status == 4: if not proj.Private.exists() or request.user in proj.Private.all( ): # only non-private proposals # else staff members are allowed to view public proposals in all timeslots and timephases # this includes assessors as they are type1 or type2. if request.user.groups.exists(): return fn(*args, **kw) # students view public proposals or private student views his proposal: Only in timephase after 2 elif get_timephase_number( ) > 2 and proj.TimeSlot == get_timeslot(): return fn(*args, **kw) # assessors are allowed to view status4 private projects if they have to assess it. elif planning_public() and \ proj.Private.exists() and \ request.user.groups.exists() and \ proj.TimeSlot == get_timeslot(): for dist in proj.distributions.all(): try: if request.user in dist.presentationtimeslot.Presentations.Assessors.all( ): return fn(*args, **kw) except PresentationTimeSlot.DoesNotExist: continue raise PermissionDenied( "You are not allowed to view this project page.")
def check_user(request, user): # insert checks on login here if user.is_superuser: return render(request, 'base.html', status=403, context={ 'Message': 'Superusers are not allowed to login via SSO. Please use 2FA login.'}) else: # block all except supportstaff if there is no timeslot # support staff needs login to be able to set a new timeslot or timephase. if not get_timeslot() and not get_grouptype('3') in user.groups.all(): # if there isn't a timeslot and not type3 return render(request, 'base.html', status=403, context={"Message": "Login is currently not available."}) # login functions for staff and students. if is_staff(user): set_level(user) if not user.groups.exists(): # existing staff member already have groups # new staff members get automatically type2staffunverified user.groups.add(get_grouptype("2u")) return True else: if not enrolled_osiris(user): return render(request, 'base.html', status=403, context={"Message": "You are not enrolled in our system yet. Please login once through canvas module BEP Marketplace"}) elif get_timephase_number() < 3: # if there isn't a timephase, this returns -1, so login is blocked. return render(request, 'base.html', status=403, context={"Message": "Student login is not available in " "this timephase."}) else: # student is enrolled in osiris. Set its usermeta from the osiris data data = osirisData() osirisdata = data.get(user.email) if osirisdata is not None: set_osiris(user, osirisdata) if get_timephase_number() > 5: # only students with project are allowed if not user.distributions.exists(): return render(request, 'base.html', status=403, context={"Message": "You don't have a project assigned" " to you, therefore login is not " "allowed in this timephase."}) if get_timeslot() not in user.usermeta.TimeSlot.all(): # user is not active in this timeslot # not in this timeslot so old user, canvas app sets timeslot # this security will fail if canvas does not close off old courses as it does now return render(request, 'base.html', status=403, context={"Message": "You already did your BEP once" ", login is not allowed."}) return True
def save(self, commit=True): if commit: super().save(commit=True) # if type2 created this project if get_grouptype('2') in self.request.user.groups.all() or \ get_grouptype('2u') in self.request.user.groups.all(): self.instance.Assistants.add( self.request.user ) # in case assistant forgets to add itself # mailing users on this project is done in the view. self.instance.save() if self.cleaned_data['copy']: # do not copy assistants p = self.cleaned_data['copy'] if p.images.exists(): for a in p.images.all(): f = ContentFile(a.File.read()) b = ProjectImage( Caption=a.Caption, OriginalName=a.OriginalName, Proposal=self.instance, ) b.File.save(ProjectFile.make_upload_path( b, a.OriginalName), f, save=False) b.full_clean( ) # This will crash hard if an invalid type is supplied, which can't happen b.save() if p.attachments.exists(): for a in p.attachments.all(): f = ContentFile(a.File.read()) b = ProjectAttachment( Caption=a.Caption, OriginalName=a.OriginalName, Proposal=self.instance, ) b.File.save(ProjectFile.make_upload_path( b, a.OriginalName), f, save=False) b.full_clean( ) # This will crash hard if an invalid type is supplied, which can't happen b.save() return self.instance
def list_staff(request): """ List all staff with a distributed projects :param request: :return: """ def nint(nr): """ :param <int> nr: :return: """ if nr is None: return 0 else: return int(nr) staff = get_all_staff().filter( Q(groups=get_grouptype("2")) | Q(groups=get_grouptype("1"))).prefetch_related( 'proposalsresponsible', 'proposals') se = [] for s in staff: p1 = s.proposalsresponsible.filter(TimeSlot=get_timeslot()) p2 = s.proposals.filter(TimeSlot=get_timeslot()) pt1 = p1.count() pt2 = p2.count() pts = pt1 + pt2 dt1 = nint( p1.annotate(Count('distributions')).aggregate( Sum('distributions__count'))['distributions__count__sum']) dt2 = nint( p2.annotate(Count('distributions')).aggregate( Sum('distributions__count'))['distributions__count__sum']) dts = dt1 + dt2 se.append({ "user": s, "pt1": pt1, "pt2": pt2, "pts": pts, "dt1": dt1, "dt2": dt2, "dts": dts }) return render(request, 'support/list_staff.html', {"staff": se})
def get_unverified_users(): """ return unverified users for type3staff. :return: """ val = get_grouptype('2u').user_set.filter(is_active=True) val = val.values_list('usermeta__Fullname', flat=True) return val
def is_staff(user): """ Check whether the user is staff. Staff has an @tue.nl email, students have @student.tue.nl email. :param user: :return: """ if user.email.split('@')[-1].lower() in settings.STAFF_EMAIL_DOMAINS or get_grouptype('3') in user.groups.all(): return True return False
def clean_Group(self): group = self.cleaned_data['Group'] if self.request.user.groups.count() == 1 and get_grouptype( '4') in self.request.user.groups.all(): # user is groupadmin and not assistant/responsible. rw_groups = get_writable_admingroups(self.request.user) if group not in rw_groups: raise ValidationError( "You are not allowed to create a project for that group. You are only allowed to " "create projects for {}".format(print_list(rw_groups))) return group
def verify_assistants(request): """ Page to let support staff give type2staffunverified the type2staff status. Can also be done using the userlist. :param request: :return: """ accounts = list(get_grouptype("2u").user_set.all()) return render(request, "support/verifyAccounts.html", {"accounts": accounts})
def can_create_project_fn(user): """ Check if a user can create a project. Allowed for responsible, assistant and studyadvisors Group administrators can create projects when they have rw access. in BEP also type3 can create projects :param user: user :return: tuple with Boolean and String. """ if get_grouptype('2') in user.groups.all() or \ get_grouptype('1') in user.groups.all() or \ get_grouptype('3') in user.groups.all() or \ get_grouptype('2u') in user.groups.all(): return True, '' if get_grouptype('4') in user.groups.all(): if len(get_writable_admingroups(user)) != 0: return True, '' else: return False, "You are not allowed to create projects, you are read-only group administrator." return False, "You are not allowed to create new projects."