Ejemplo n.º 1
0
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,
    })
Ejemplo n.º 2
0
    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())
Ejemplo n.º 3
0
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,
    })
Ejemplo n.º 4
0
    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)
Ejemplo n.º 5
0
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))
Ejemplo n.º 6
0
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()
Ejemplo n.º 7
0
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'})
Ejemplo n.º 8
0
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,
    })
Ejemplo n.º 9
0
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."
Ejemplo n.º 10
0
 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')
Ejemplo n.º 11
0
 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')
Ejemplo n.º 12
0
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()
Ejemplo n.º 13
0
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
        })
Ejemplo n.º 14
0
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
Ejemplo n.º 15
0
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,
    })
Ejemplo n.º 16
0
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.")
Ejemplo n.º 17
0
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})
Ejemplo n.º 18
0
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
Ejemplo n.º 19
0
    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
Ejemplo n.º 20
0
    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
Ejemplo n.º 21
0
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
Ejemplo n.º 22
0
    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.")
Ejemplo n.º 23
0
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
Ejemplo n.º 24
0
 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
Ejemplo n.º 25
0
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})
Ejemplo n.º 26
0
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
Ejemplo n.º 27
0
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
Ejemplo n.º 28
0
 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
Ejemplo n.º 29
0
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})
Ejemplo n.º 30
0
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."