Example #1
0
def _checkDeadline_helper(method, extension, moduleObj, request, tl, *args,
                          **kwargs):
    if tl != 'learn' and tl != 'teach':
        return (True, None)
    response = None
    canView = False
    if not_logged_in(request):
        response = HttpResponseRedirect(
            '%s?%s=%s' %
            (LOGIN_URL, REDIRECT_FIELD_NAME, quote(request.get_full_path())))
    else:
        canView = request.user.updateOnsite(request)
        if not canView:
            perm_name = {
                'learn': 'Student',
                'teach': 'Teacher'
            }[tl] + extension
            canView = Permission.user_has_perm(request.user,
                                               perm_name,
                                               program=request.program)
            #   For now, allow an exception if the user is of the wrong type
            #   This is because we are used to UserBits having a null user affecting everyone, regardless of user type.
            if not canView and Permission.valid_objects().filter(
                    permission_type=perm_name,
                    program=request.program,
                    user__isnull=True).exists():
                canView = True

    return (canView, response)
Example #2
0
def _checkDeadline_helper(method, extension, moduleObj, request, tl, *args, **kwargs):
    """
    Decide if a user can view a requested page; if not, offer a redirect.

    Given information about a request, return a pair of type (bool, None |
    response), which indicates whether the user can view the requested page,
    and an optional redirect if not.

    If the user is an administrator, annotate the request with information
    about what roles have permission to view the requested page.
    """
    if tl != 'learn' and tl != 'teach' and tl != 'volunteer':
        return (True, None)
    response = None
    canView = False
    perm_name = {'learn':'Student','teach':'Teacher','volunteer':'Volunteer'}[tl]+extension
    if not_logged_in(request):
        if not moduleObj.require_auth() and Permission.null_user_has_perm(permission_type=perm_name, program=request.program):
            canView = True
        else:
            response = HttpResponseRedirect('%s?%s=%s' % (LOGIN_URL, REDIRECT_FIELD_NAME, quote(request.get_full_path())))
    else:
        user = request.user
        program = request.program
        canView = user.updateOnsite(request)
        if not canView:
            canView = Permission.user_has_perm(user,
                                               perm_name,
                                               program=program)
            #   For now, allow an exception if the user is of the wrong type
            #   This is because we are used to UserBits having a null user affecting everyone, regardless of user type.
            if not canView and Permission.valid_objects().filter(permission_type=perm_name, program=program, user__isnull=True).exists():
                canView = True

            #   Give administrators additional information
            if user.isAdministrator(program=program):
                request.show_perm_info = True
                if getattr(request, 'perm_names', None) is not None:
                    request.perm_names.append(perm_name)
                else:
                    request.perm_names = [perm_name]

                roles_with_perm = Permission.list_roles_with_perm(perm_name, program)
                if getattr(request, 'roles_with_perm', None) is not None:
                    request.roles_with_perm += roles_with_perm
                else:
                    request.roles_with_perm = roles_with_perm

    return (canView, response)
Example #3
0
def ajax_qsd(request):
    """ Ajax function for in-line QSD editing.  """
    from django.utils import simplejson
    from esp.lib.templatetags.markdown import markdown

    result = {}
    post_dict = request.POST.copy()

    if (request.user.id is None):
        return HttpResponse(
            content=
            'Oops! Your session expired!\nPlease open another window, log in, and try again.\nYour changes will not be lost if you keep this page open.',
            status=500)
    if post_dict['cmd'] == "update":
        qsd = QuasiStaticData.objects.get(id=post_dict['id'])
        if not Permission.user_can_edit_qsd(request.user, qsd.url):
            return HttpResponse(
                content='Sorry, you do not have permission to edit this page.',
                status=500)

        # Since QSD now uses reversion, we want to only modify the data if we've actually changed something
        # The revision will automatically be created upon calling the save function of the model object
        if qsd.content != post_dict['data']:
            qsd.content = post_dict['data']
            qsd.load_cur_user_time(request, )
            qsd.save()

            # We should also purge the cache
            purge_page(qsd.url + ".html")

        result['status'] = 1
        result['content'] = markdown(qsd.content)
        result['id'] = qsd.id
    if post_dict['cmd'] == "create":
        if not Permission.user_can_edit_qsd(request.user, post_dict['url']):
            return HttpResponse(
                content="Sorry, you do not have permission to edit this page.",
                status=500)
        qsd, created = QuasiStaticData.objects.get_or_create(
            url=post_dict['url'], defaults={'author': request.user})
        qsd.content = post_dict['data']
        qsd.author = request.user
        qsd.save()
        result['status'] = 1
        result['content'] = markdown(qsd.content)
        result['id'] = qsd.id

    return HttpResponse(simplejson.dumps(result))
Example #4
0
 def testRolePerm(self):
     perm = 'Student/MainPage'
     other_user = ESPUser.objects.create(username='******')
     self.create_role_perm_for_program(perm)
     self.assertTrue(self.user_has_perm_for_program(perm))
     self.assertFalse(
         Permission.user_has_perm(other_user, perm, program=self.program))
Example #5
0
    def deadline_met(self, extension=''):

        #   Short-circuit the request middleware during testing, when we call
        #   this function without an actual request.
        if hasattr(self, 'user'):
            user = self.user
        else:
            request = get_current_request()
            user = request.user

        if not user or not self.program:
            raise ESPError(False), "There is no user or program object!"

        if self.module.module_type != 'learn' and self.module.module_type != 'teach':
            return True

        canView = user.isOnsite(self.program) or user.isAdministrator(
            self.program)

        if not canView:
            deadline = {
                'learn': 'Student',
                'teach': 'Teacher'
            }[self.module.module_type] + extension
            canView = Permission.user_has_perm(user,
                                               deadline,
                                               program=self.program)

        return canView
Example #6
0
 def testProgramPerm(self):
     perm = 'Student/MainPage'
     other_program = Program.objects.create(grade_min=7, grade_max=12)
     self.create_role_perm_for_program(perm)
     self.assertTrue(self.user_has_perm_for_program(perm))
     self.assertFalse(self.user_has_perm(perm))
     self.assertFalse(Permission.user_has_perm(self.user, perm, program=other_program))
Example #7
0
def ajax_qsd(request):
    """ Ajax function for in-line QSD editing.  """
    import json
    from markdown import markdown

    result = {}
    post_dict = request.POST.copy()

    if ( request.user.id is None ):
        return HttpResponse(content='Oops! Your session expired!\nPlease open another window, log in, and try again.\nYour changes will not be lost if you keep this page open.', status=401)
    if post_dict['cmd'] == "update":
        if not Permission.user_can_edit_qsd(request.user, post_dict['url']):
            return HttpResponse(content='Sorry, you do not have permission to edit this page.', status=403)

        qsd, created = QuasiStaticData.objects.get_or_create(url=post_dict['url'], defaults={'author': request.user})

        # Since QSD now uses reversion, we want to only modify the data if we've actually changed something
        # The revision will automatically be created upon calling the save function of the model object
        if qsd.content != post_dict['data']:
            qsd.content = post_dict['data']
            qsd.load_cur_user_time(request, )
            qsd.save()

            # We should also purge the cache
            purge_page(qsd.url+".html")

        result['status'] = 1
        result['content'] = markdown(qsd.content)
        result['url'] = qsd.url

    return HttpResponse(json.dumps(result))
Example #8
0
 def testProgramPerm(self):
     perm = 'Student/MainPage'
     other_program = Program.objects.create(grade_min=7, grade_max=12)
     self.create_role_perm_for_program(perm)
     self.assertTrue(self.user_has_perm_for_program(perm))
     self.assertFalse(self.user_has_perm(perm))
     self.assertFalse(Permission.user_has_perm(self.user, perm, program=other_program))
Example #9
0
def registration_redirect(request):
    """ A view which returns:
        - A redirect to the currently open registration if exactly one registration is open
        - A list of open registration links otherwise
    """
    from esp.users.models import ESPUser
    from esp.program.models import Program

    #   Make sure we have an ESPUser
    user = ESPUser(request.user)

    # prepare the rendered page so it points them to open student/teacher reg's
    ctxt = {}
    userrole = {}
    regperm = None
    if user.isStudent():
        userrole['name'] = 'Student'
        userrole['base'] = 'learn'
        userrole['reg'] = 'studentreg'
        regperm = 'Student/Classes'
    elif user.isTeacher():
        userrole['name'] = 'Teacher'
        userrole['base'] = 'teach'
        userrole['reg'] = 'teacherreg'
        regperm = 'Teacher/Classes'
    else:
        #   Default to student registration (this will only show if the program
        #   is found via the 'allowed_student_types' Tag)
        userrole['name'] = user.getUserTypes()[0]
        userrole['base'] = 'learn'
        userrole['reg'] = 'studentreg'
    ctxt['userrole'] = userrole

    if regperm:
        progs_deadline = list(Permission.program_by_perm(user, regperm))
    else:
        progs_deadline = []

    progs_tag = list(t.target \
            for t in Tag.objects.filter(key = "allowed_student_types").select_related() \
            if isinstance(t.target, Program) \
                and (set(user.getUserTypes()) & set(t.value.split(","))))
    progs = list(set(progs_deadline + progs_tag))  #distinct ones

    #   If we have 1 program, automatically redirect to registration for that program.
    #   Most chapters will want this, but it can be disabled by a Tag.
    if len(progs) == 1 and Tag.getBooleanTag('automatic_registration_redirect',
                                             default=True):
        ctxt['prog'] = progs[0]
        return HttpResponseRedirect(
            u'/%s/%s/%s' %
            (userrole['base'], progs[0].getUrlBase(), userrole['reg']))
    else:
        if len(progs) > 0:
            #   Sort available programs newest first
            progs.sort(key=lambda x: -x.id)
            ctxt['progs'] = progs
            ctxt['prog'] = progs[0]
        return render_to_response('users/profile_complete.html', request, ctxt)
Example #10
0
def _checkDeadline_helper(method, extension, moduleObj, request, tl, *args, **kwargs):
    if tl != 'learn' and tl != 'teach':
        return (True, None)
    response = None
    canView = False
    if not_logged_in(request):
        response = HttpResponseRedirect('%s?%s=%s' % (LOGIN_URL, REDIRECT_FIELD_NAME, quote(request.get_full_path())))
    else:
        canView = request.user.updateOnsite(request)
        if not canView:
            perm_name = {'learn':'Student','teach':'Teacher'}[tl]+extension
            canView = Permission.user_has_perm(request.user,
                                               perm_name,
                                               program=request.program)
            #   For now, allow an exception if the user is of the wrong type
            #   This is because we are used to UserBits having a null user affecting everyone, regardless of user type.
            if not canView and Permission.valid_objects().filter(permission_type=perm_name, program=request.program, user__isnull=True).exists():
                canView = True

    return (canView, response)
    def lottery(self, prog, role):
        # Run lottery algorithm.
        # Get grade caps
        grade_caps_str = prog.grade_caps()
        grade_caps = {
            int(key[0]): value
            for key, value in grade_caps_str.iteritems()
        }

        #Get lottery records and randomize them
        records = PhaseZeroRecord.objects.filter(program=prog).order_by('?')

        ###############################################################################
        # The lottery algorithm is run, with randomization and processing in order.
        # If any one in the group doesn't get in (due to cap size), no one in that group gets in.
        counts = {key: 0 for key in grade_caps}
        winners, _ = Group.objects.get_or_create(name=role)

        for i in records:
            sibs = i.user.all()
            newcounts = copy.copy(counts)
            for j in sibs:
                newcounts[j.getGrade(prog)] += 1

            cpass = not any(newcounts[c] > grade_caps[c] for c in counts)

            if cpass:
                winners.user_set.add(*sibs)
                counts = newcounts

        ###############################################################################
        # Post lottery, assign permissions to people in the lottery winners group
        # Assign OverridePhaseZero permission and Student/All permissions

        override_perm = Permission(permission_type='OverridePhaseZero',
                                   role=winners,
                                   start_date=datetime.datetime.now(),
                                   program=prog)
        studentAll_perm = Permission(permission_type='Student/All',
                                     role=winners,
                                     start_date=datetime.datetime.now(),
                                     program=prog)
        override_perm.save()
        studentAll_perm.save()
        # Add tag to indicate student lottery has been run
        Tag.setTag('student_lottery_run', target=prog, value='True')

        return True
    def ajax_schedule(self, request, tl, one, two, module, extra, prog):
        import json as json
        from django.template.loader import render_to_string
        context = self.prepare({})
        context['prog'] = self.program
        context['one'] = one
        context['two'] = two
        context['reg_open'] = bool(Permission.user_has_perm(request.user, {'learn':'Student','teach':'Teacher'}[tl]+"/Classes",prog))

        schedule_str = render_to_string('users/student_schedule_inline.html', context)
        script_str = render_to_string('users/student_schedule_inline.js', context)
        json_data = {'student_schedule_html': schedule_str, 'script': script_str}

        #   Look at the 'extra' data and act appropriately:
        #   -   List, query set, or comma-separated ID list of class sections:
        #       Add the buttons for those class sections to the returned data.
        #   -   String 'all':
        #       Add the buttons for all of the student's class sections to the returned data
        #   -   Anything else:
        #       Don't do anything.
        #   Rewrite registration button if a particular section was named.  (It will be in extra).
        sec_ids = []
        if extra == 'all':
            # TODO(benkraft): this branch of the if was broken for 5 years and
            # nobody noticed, so we may be able to remove it entirely.
            sec_ids = self.user.getSections(self.program).values_list('id', flat=True)
        elif isinstance(extra, list) or isinstance(extra, QuerySet):
            sec_ids = list(extra)
        else:
            try:
                sec_ids = [int(x) for x in extra.split(',')]
            except:
                pass

        for sec_id in sec_ids:
            try:
                section = ClassSection.objects.get(id=sec_id)
                cls = section.parent_class
                button_context = {'sec': section, 'cls': cls}
                if section in request.user.getEnrolledSections(self.program):
                    button_context['label'] = 'Registered!'
                    button_context['disabled'] = True
                addbutton_str1 = render_to_string(self.baseDir()+'addbutton_fillslot.html', button_context)
                addbutton_str2 = render_to_string(self.baseDir()+'addbutton_catalog.html', button_context)
                json_data['addbutton_fillslot_sec%d_html' % sec_id] = addbutton_str1
                json_data['addbutton_catalog_sec%d_html' % sec_id] = addbutton_str2
            except Exception, inst:
                raise AjaxError('Encountered an error retrieving updated buttons: %s' % inst)
Example #13
0
    def _checkGrade(moduleObj, request, tl, *args, **kwargs):
        errorpage = 'errors/program/wronggrade.html'

        # if there's grade override we can just skip everything
        if Permission.user_has_perm(request.user, 'GradeOverride', moduleObj.program):
            return method(moduleObj, request, tl, *args, **kwargs)

        # now we have to use the grade..

        # get the last grade...
        cur_grade = request.user.getGrade(moduleObj.program)
        if cur_grade != 0 and (cur_grade < moduleObj.program.grade_min or \
                               cur_grade > moduleObj.program.grade_max):
            return render_to_response(errorpage, request, {'yog': request.user.getYOG(moduleObj.program)})

        return method(moduleObj, request, tl, *args, **kwargs)
Example #14
0
    def _checkGrade(moduleObj, request, tl, *args, **kwargs):
        errorpage = 'errors/program/wronggrade.html'

        # if there's grade override we can just skip everything
        if Permission.user_has_perm(request.user, 'GradeOverride', moduleObj.program):
            return method(moduleObj, request, tl, *args, **kwargs)

        # now we have to use the grade..

        # get the last grade...
        cur_grade = request.user.getGrade(moduleObj.program)
        if cur_grade != 0 and (cur_grade < moduleObj.program.grade_min or \
                               cur_grade > moduleObj.program.grade_max):
            return render_to_response(errorpage, request, {'yog': request.user.getYOG(moduleObj.program)})

        return method(moduleObj, request, tl, *args, **kwargs)
Example #15
0
def myesp_onsite(request):
    user = request.user
    if not user.isOnsite():
        raise ESPError('You are not a valid on-site user, please go away.', log=False)

    progs = Permission.program_by_perm(user,"Onsite")

    # Order them decreasing by id
    # - Currently reverse the list in Python, otherwise fbap's cache is ignored
    # TODO: Fix this
    progs = list(progs)
    progs.reverse()

    if len(progs) == 1:
        return HttpResponseRedirect('/onsite/%s/main' % progs[0].getUrlBase())
    else:
        return render_to_response('program/pickonsite.html', request, {'progs': progs})
Example #16
0
def registration_redirect(request):
    """ A view which returns:
        - A redirect to the currently open registration if exactly one registration is open
        - A list of open registration links otherwise
    """
    from esp.users.models import ESPUser
    from esp.program.models import Program

    user = request.user

    # prepare the rendered page so it points them to open student/teacher reg's
    ctxt = {}
    userrole = {}
    regperm = None
    if user.isStudent():
        userrole['name'] = 'Student'
        userrole['base'] = 'learn'
        userrole['reg'] = 'studentreg'
        regperm = 'Student/Classes'
    elif user.isTeacher():
        userrole['name'] = 'Teacher'
        userrole['base'] = 'teach'
        userrole['reg'] = 'teacherreg'
        regperm = 'Teacher/Classes'
    ctxt['userrole'] = userrole

    if regperm:
        progs = list(Permission.program_by_perm(user,regperm))
    else:
        progs = []

    #   If we have 1 program, automatically redirect to registration for that program.
    #   Most chapters will want this, but it can be disabled by a Tag.
    if len(progs) == 1 and Tag.getBooleanTag('automatic_registration_redirect', default=True):
        ctxt['prog'] = progs[0]
        return HttpResponseRedirect(u'/%s/%s/%s' % (userrole['base'], progs[0].getUrlBase(), userrole['reg']))
    else:
        if len(progs) > 0:
            #   Sort available programs newest first
            progs.sort(key=lambda x: -x.id)
            ctxt['progs'] = progs
            ctxt['prog'] = progs[0]
        return render_to_response('users/profile_complete.html', request, ctxt)
Example #17
0
    def deadline_met(self, extension=''):

        #   Short-circuit the request middleware during testing, when we call
        #   this function without an actual request.
        if hasattr(self, 'user'):
            user = self.user
        else:
            request = get_current_request()
            user = request.user

        if not user or not self.program:
            raise ESPError(False), "There is no user or program object!"

        if self.module.module_type != 'learn' and self.module.module_type != 'teach':
            return True

        canView = user.isOnsite(self.program) or user.isAdministrator(self.program)

        if not canView:
            deadline = {'learn':'Student', 'teach':'Teacher'}[self.module.module_type]+extension
            canView = Permission.user_has_perm(user, deadline, program=self.program)

        return canView
Example #18
0
    def render(self, context):
        try:
            user = self.user_variable.resolve(context) if self.user_variable is not None else None
        except template.VariableDoesNotExist:
            user = None
        try:
            program = self.program_variable.resolve(context) if self.program_variable is not None else None
        except template.VariableDoesNotExist:
            program = None
        #   Accept literal string url argument if it is quoted; otherwise expect a template variable.
        if not self.url.startswith('"'):
            url_resolved = template.Variable(self.url).resolve(context)
        else:
            url_resolved = self.url.strip('"')
        if program is not None:
            url = QuasiStaticData.prog_qsd_url(program,url_resolved)
        else:
            url = url_resolved
        #probably should have an error message if variable was not None and prog was

        edit_bits = Permission.user_can_edit_qsd(user, url)

        qsd_obj = QuasiStaticData.objects.get_by_url(url)
        if qsd_obj == None:
            new_qsd = QuasiStaticData()
            new_qsd.url = url
            new_qsd.title = url
            new_qsd.content = self.nodelist.render(context)
            
            if getattr(user, 'id', False):
                new_qsd.author = user
                new_qsd.save()

            qsd_obj = new_qsd

        return render_to_response("inclusion/qsd/render_qsd_inline.html", {'qsdrec': qsd_obj, 'edit_bits': edit_bits}, context_instance=context).content
Example #19
0
    def deadline_management(self, request, tl, one, two, module, extra, prog):
        #   Define a formset for editing multiple perms simultaneously.
        EditPermissionFormset = formset_factory(EditPermissionForm)

        #   Define a status message
        message = ''

        #   Handle 'open' / 'close' actions
        if extra == 'open' and 'id' in request.GET:
            perm = Permission.objects.get(id=request.GET['id'])
            #   Clear any duplicate user permissions
            Permission.objects.filter(
                permission_type=perm.permission_type,
                program=perm.program,
                user__isnull=True,
                role=perm.role).exclude(id=perm.id).delete()
            perm.end_date = None
            perm.save()
            message = 'Deadline opened: %s.' % perm.nice_name()

        elif extra == 'close' and 'id' in request.GET:
            perm = Permission.objects.get(id=request.GET['id'])
            #   Clear any duplicate user permissions
            Permission.objects.filter(
                permission_type=perm.permission_type,
                program=perm.program,
                user__isnull=True,
                role=perm.role).exclude(id=perm.id).delete()
            perm.end_date = datetime.now()
            perm.save()
            message = 'Deadline closed: %s.' % perm.nice_name()

        #   Check incoming form data
        if request.method == 'POST':
            edit_formset = EditPermissionFormset(request.POST.copy(),
                                                 prefix='edit')
            create_form = NewPermissionForm(request.POST.copy())
            if edit_formset.is_valid():
                num_forms = 0
                for form in edit_formset.forms:
                    #   Check if the permission with the specified ID exists.
                    #   It may have been deleted by previous iterations of this loop
                    #   deleting duplicate permissions.
                    if 'id' in form.cleaned_data and Permission.objects.filter(
                            id=form.cleaned_data['id']).exists():
                        num_forms += 1
                        perm = Permission.objects.get(
                            id=form.cleaned_data['id'])
                        #   Clear any duplicate perms
                        Permission.objects.filter(
                            permission_type=perm.permission_type,
                            program=perm.program,
                            user__isnull=True,
                            role=perm.role).exclude(id=perm.id).delete()
                        perm.start_date = form.cleaned_data['start_date']
                        perm.end_date = form.cleaned_data['end_date']
                        perm.save()
                if num_forms > 0:
                    message = 'Changes saved.'
            if create_form.is_valid():
                perm, created = Permission.objects.get_or_create(
                    user=None,
                    permission_type=create_form.
                    cleaned_data['permission_type'],
                    role=Group.objects.get(
                        name=create_form.cleaned_data['role']),
                    program=prog)
                if not created:
                    message = 'Deadline already exists: %s.  Please modify the existing deadline.' % perm.nice_name(
                    )
                else:
                    perm.start_date = create_form.cleaned_data['start_date']
                    perm.end_date = create_form.cleaned_data['end_date']
                    perm.save()
                    message = 'Deadline created: %s.' % perm.nice_name()
            else:
                message = 'No activities selected.  Please select a deadline type from the list before creating a deadline.'

        #   find all the existing permissions with this program
        #   Only consider global permissions -- those that apply to all users
        #   of a particular role.  Permissions added for individual users
        #   should be managed in the admin interface.
        perms = Permission.deadlines().filter(program=self.program,
                                              user__isnull=True)
        perm_map = {p.permission_type: p for p in perms}

        #   Populate template context to render page with forms
        context = {}

        #   Set a flag on each perm for whether it has ended
        #   TODO(benkraft): refactor users to just call is_valid themselves.
        for perm in perms:
            perm.open_now = perm.is_valid()

        #   For each permission, determine which other ones it implies
        for perm in perms:
            includes = Permission.implications.get(perm.permission_type, [])
            perm.includes = []
            perm.name = perm.nice_name()
            for p in includes:
                if p == perm.permission_type: continue
                perm.includes.append({
                    'type':
                    p,
                    'nice_name':
                    Permission.nice_name_lookup(p)
                })
                if p in perm_map:
                    perm.includes[-1].update({
                        'overridden': True,
                        'overridden_by': perm_map[p],
                        'bit_open': perm_map[p].open_now
                    })

        #   Supply initial data for forms
        formset = EditPermissionFormset(
            initial=[perm.__dict__ for perm in perms], prefix='edit')
        for i in range(len(perms)):
            perms[i].form = formset.forms[i]

        context['message'] = message
        context['manage_form'] = formset.management_form
        context['perms'] = perms
        context['create_form'] = NewPermissionForm()

        return render_to_response(self.baseDir() + 'deadlines.html', request,
                                  context)
Example #20
0
 def user_has_perm(self, name, *args, **kwargs):
     """Checks for Permission object with user=self.user."""
     return Permission.user_has_perm(self.user, name, *args, **kwargs)
Example #21
0
def qsd(request, url):

    #   Extract the 'action' from the supplied URL if there is one
    url_parts = url.split('/')
    page_name = url_parts[-1]
    page_name_parts = page_name.split('.')
    if len(page_name_parts) > 1:
        action = page_name_parts[-1]
        page_name_base = '.'.join(page_name_parts[:-1])
    else:
        action = 'read'
        page_name_base = page_name
    base_url = '/'.join(url_parts[:-1] + [page_name_base])

    # Detect edit authorizations
    have_read = True

    if not have_read and action == 'read':
        raise Http403, "You do not have permission to access this page."

    # Fetch the QSD object
    try:
        qsd_rec = QuasiStaticData.objects.get_by_url(base_url)
        if qsd_rec == None:
            raise QuasiStaticData.DoesNotExist
        if qsd_rec.disabled:
            raise QuasiStaticData.DoesNotExist

    except QuasiStaticData.DoesNotExist:
        have_edit = Permission.user_can_edit_qsd(request.user, base_url)

        if have_edit:
            if action in (
                    'edit',
                    'create',
            ):
                qsd_rec = QuasiStaticData()
                qsd_rec.url = base_url
                qsd_rec.nav_category = NavBarCategory.default()
                qsd_rec.title = 'New Page'
                qsd_rec.content = 'Please insert your text here'
                qsd_rec.create_date = datetime.now()
                qsd_rec.keywords = ''
                qsd_rec.description = ''
                action = 'edit'

            if (action == 'read'):
                edit_link = '/' + base_url + '.edit.html'
                return render_to_response('qsd/nopage_create.html',
                                          request, {'edit_link': edit_link},
                                          use_request_context=False)
        else:
            if action == 'read':
                raise Http404, 'This page does not exist.'
            else:
                raise Http403, 'Sorry, you can not modify <tt>%s</tt>.' % request.path

    if action == 'create':
        action = 'edit'

    # Detect the standard read verb
    if action == 'read':
        if not have_read:
            raise Http403, 'You do not have permission to read this page.'

        # Render response
        response = render_to_response(
            'qsd/qsd.html',
            request,
            {
                'title': qsd_rec.title,
                'nav_category': qsd_rec.nav_category,
                'content': qsd_rec.html(),
                'settings': settings,
                'qsdrec': qsd_rec,
                'have_edit':
                True,  ## Edit-ness is determined client-side these days
                'edit_url': '/' + base_url + ".edit.html"
            },
            use_request_context=False)

        #        patch_vary_headers(response, ['Cookie'])
        #        if have_edit:
        #            add_never_cache_headers(response)
        #            patch_cache_control(response, no_cache=True, no_store=True)
        #        else:
        patch_cache_control(response, max_age=3600, public=True)

        return response

    # Detect POST
    if request.POST.has_key('post_edit'):
        have_edit = Permission.user_can_edit_qsd(request.user, base_url)

        if not have_edit:
            raise Http403, "Sorry, you do not have permission to edit this page."

        nav_category_target = NavBarCategory.objects.get(
            id=request.POST['nav_category'])

        # Since QSD now uses reversion, we want to only modify the data if we've actually changed something
        # The revision will automatically be created upon calling the save function of the model object
        if qsd_rec.url != base_url or qsd_rec.nav_category != nav_category_target or qsd_rec.content != request.POST[
                'content'] or qsd_rec.description != request.POST[
                    'description'] or qsd_rec.keywords != request.POST[
                        'keywords']:
            qsd_rec.url = base_url
            qsd_rec.nav_category = NavBarCategory.objects.get(
                id=request.POST['nav_category'])
            qsd_rec.content = request.POST['content']
            qsd_rec.title = request.POST['title']
            qsd_rec.description = request.POST['description']
            qsd_rec.keywords = request.POST['keywords']

            qsd_rec.load_cur_user_time(request)
            qsd_rec.save()

            # We should also purge the cache
            purge_page(qsd_rec.url + ".html")

        # If any files were uploaded, save them
        for name, file in request.FILES.iteritems():
            m = Media()

            # Strip "media/" from FILE, and strip the file name; just return the path
            path = dirname(name[9:])

            # Do we want a better/manual mechanism for setting friendly_name?
            m.friendly_name = basename(name)

            m.format = ''

            local_filename = name
            if name[:9] == 'qsdmedia/':
                local_filename = name[9:]

            m.handle_file(file, local_filename)
            m.save()

    # Detect the edit verb
    if action == 'edit':
        have_edit = Permission.user_can_edit_qsd(request.user, base_url)

        # Enforce authorizations (FIXME: SHOW A REAL ERROR!)
        if not have_edit:
            raise ESPError(
                False), "You don't have permission to edit this page."

        m = ESPMarkdown(qsd_rec.content, media={})

        m.toString()
        #        assert False, m.BrokenLinks()

        # Render an edit form
        return render_to_response(
            'qsd/qsd_edit.html',
            request, {
                'title': qsd_rec.title,
                'content': qsd_rec.content,
                'keywords': qsd_rec.keywords,
                'description': qsd_rec.description,
                'nav_category': qsd_rec.nav_category,
                'nav_categories': NavBarCategory.objects.all(),
                'qsdrec': qsd_rec,
                'qsd': True,
                'missing_files': m.BrokenLinks(),
                'target_url': base_url.split("/")[-1] + ".edit.html",
                'return_to_view': base_url.split("/")[-1] + ".html#refresh"
            },
            use_request_context=False)

    # Operation Complete!
    raise Http404('Unexpected QSD operation')
Example #22
0
def qsd(request, url):

    #   Extract the 'action' from the supplied URL if there is one
    url_parts = url.split('/')
    page_name = url_parts[-1]
    page_name_parts = page_name.split('.')
    if len(page_name_parts) > 1:
        action = page_name_parts[-1]
        page_name_base = '.'.join(page_name_parts[:-1])
    else:
        action = 'read'
        page_name_base = page_name
    base_url = '/'.join(url_parts[:-1] + [page_name_base])

    # Detect edit authorizations
    have_read = True

    if not have_read and action == 'read':
        raise Http403, "You do not have permission to access this page."

    # Fetch the QSD object
    try:
        qsd_rec = QuasiStaticData.objects.get_by_url(base_url)
        if qsd_rec == None:
            raise QuasiStaticData.DoesNotExist
        if qsd_rec.disabled:
            raise QuasiStaticData.DoesNotExist

    except QuasiStaticData.DoesNotExist:
        have_edit = Permission.user_can_edit_qsd(request.user, base_url)

        if have_edit:
            if action in ('edit','create',):
                qsd_rec = QuasiStaticData()
                qsd_rec.url = base_url
                qsd_rec.nav_category = default_navbarcategory()
                qsd_rec.title = 'New Page'
                qsd_rec.content = 'Please insert your text here'
                qsd_rec.create_date = datetime.now()
                qsd_rec.keywords = ''
                qsd_rec.description = ''
                action = 'edit'

            if (action == 'read'):
                edit_link = '/' + base_url + '.edit.html'
                response = render_to_response('qsd/nopage_create.html', request, {'edit_link': edit_link}, use_request_context=False)
                response.status_code = 404 # Make sure we actually 404, so that if there is a redirect the middleware can catch it.
                return response
        else:
            if action == 'read':
                raise Http404, 'This page does not exist.'
            else:
                raise Http403, 'Sorry, you can not modify <tt>%s</tt>.' % request.path

    if action == 'create':
        action = 'edit'

    # Detect the standard read verb
    if action == 'read':
        if not have_read:
            raise Http403, 'You do not have permission to read this page.'

        # Render response
        response = render_to_response('qsd/qsd.html', request, {
            'title': qsd_rec.title,
            'nav_category': qsd_rec.nav_category,
            'content': qsd_rec.html(),
            'settings': settings,
            'qsdrec': qsd_rec,
            'have_edit': True,  ## Edit-ness is determined client-side these days
            'edit_url': '/' + base_url + ".edit.html" }, use_request_context=False)

#        patch_vary_headers(response, ['Cookie'])
#        if have_edit:
#            add_never_cache_headers(response)
#            patch_cache_control(response, no_cache=True, no_store=True)
#        else:
        patch_cache_control(response, max_age=3600, public=True)

        return response


    # Detect POST
    if 'post_edit' in request.POST:
        have_edit = Permission.user_can_edit_qsd(request.user, base_url)

        if not have_edit:
            raise Http403, "Sorry, you do not have permission to edit this page."

        nav_category_target = NavBarCategory.objects.get(id=request.POST['nav_category'])

        # Since QSD now uses reversion, we want to only modify the data if we've actually changed something
        # The revision will automatically be created upon calling the save function of the model object
        copy_map = {
            'url': base_url,
            'nav_category': nav_category_target,
            'content': request.POST['content'],
            'title': request.POST['title'],
            'description': request.POST['description'],
            'keywords': request.POST['keywords'],
        }
        diff_found = False
        for field, new_value in copy_map.items():
            if getattr(qsd_rec, field) != new_value:
                setattr(qsd_rec, field, new_value)
                diff_found = True

        if diff_found:
            qsd_rec.load_cur_user_time(request)
            qsd_rec.save()

            # We should also purge the cache
            purge_page(qsd_rec.url+".html")


    # Detect the edit verb
    if action == 'edit':
        have_edit = Permission.user_can_edit_qsd(request.user, base_url)

        # Enforce authorizations (FIXME: SHOW A REAL ERROR!)
        if not have_edit:
            raise Http403, "You don't have permission to edit this page."

        # Render an edit form
        return render_to_response('qsd/qsd_edit.html', request, {
            'title'        : qsd_rec.title,
            'content'      : qsd_rec.content,
            'keywords'     : qsd_rec.keywords,
            'description'  : qsd_rec.description,
            'nav_category' : qsd_rec.nav_category,
            'nav_categories': NavBarCategory.objects.all(),
            'qsdrec'       : qsd_rec,
            'qsd'          : True,
            'target_url'   : base_url.split("/")[-1] + ".edit.html",
            'return_to_view': base_url.split("/")[-1] + ".html#refresh" },
            use_request_context=False)

    # Operation Complete!
    raise Http404('Unexpected QSD operation')
Example #23
0
    def studentregphasezero(self, request, tl, one, two, module, extra, prog):
        """
        Serves the Phase Zero student reg page. The initial page includes a button
        to enter the student lottery. Following entering the lottery, students are
        served a confirmation page.
        """
        context = {}
        context['program'] = prog
        context['one'] = one
        context['two'] = two
        user = request.user
        in_lottery = PhaseZeroRecord.objects.filter(user=user,
                                                    program=prog).exists()

        if Permission.user_has_perm(user,
                                    'Student/Classes/PhaseZero',
                                    program=prog):
            if in_lottery:
                context['lottery_group'] = PhaseZeroRecord.objects.get(
                    user=user, program=prog)
                context['lottery_size'] = context['lottery_group'].user.count()
                return render_to_response(
                    'program/modules/studentregphasezero/confirmation.html',
                    request, context)
            else:
                if request.method == 'POST':
                    form = SubmitForm(request.POST, program=prog)
                    if form.is_valid():
                        form.save(user, prog)
                    context['lottery_group'] = PhaseZeroRecord.objects.get(
                        user=user, program=prog)
                    context['lottery_size'] = context[
                        'lottery_group'].user.count()
                    self.send_confirmation_email(user)
                    return render_to_response(
                        'program/modules/studentregphasezero/confirmation.html',
                        request, context)
                else:
                    form = SubmitForm(program=prog)
                    context['form'] = form
                    return render_to_response(
                        'program/modules/studentregphasezero/submit.html',
                        request, context)
        else:
            if in_lottery:
                if Tag.getBooleanTag('student_lottery_run',
                                     prog,
                                     default=False):
                    #Sorry page
                    return render_to_response(
                        'program/modules/studentregphasezero/sorry.html',
                        request, context)
                else:
                    #Lottery has not yet been run page
                    return render_to_response(
                        'program/modules/studentregphasezero/notyet.html',
                        request, context)
            else:
                #Generic error page
                return render_to_response(
                    'errors/program/phasezero_closed.html', request, context)
Example #24
0
 def testRolePerm(self):
     perm = 'Student/MainPage'
     other_user = ESPUser.objects.create(username='******')
     self.create_role_perm_for_program(perm)
     self.assertTrue(self.user_has_perm_for_program(perm))
     self.assertFalse(Permission.user_has_perm(other_user, perm, program=self.program))
Example #25
0
def qsd(request, url):

    #   Extract the 'action' from the supplied URL if there is one
    url_parts = url.split('/')
    page_name = url_parts[-1]
    page_name_parts = page_name.split('.')
    if len(page_name_parts) > 1:
        action = page_name_parts[-1]
        page_name_base = '.'.join(page_name_parts[:-1])
    else:
        action = 'read'
        page_name_base = page_name
    base_url = '/'.join(url_parts[:-1] + [page_name_base])

    # Detect edit authorizations
    have_read = True

    if not have_read and action == 'read':
        raise Http403, "You do not have permission to access this page."

    # Fetch the QSD object
    try:
        qsd_rec = QuasiStaticData.objects.get_by_url(base_url)
        if qsd_rec == None:
            raise QuasiStaticData.DoesNotExist
        if qsd_rec.disabled:
            raise QuasiStaticData.DoesNotExist

    except QuasiStaticData.DoesNotExist:
        have_edit = Permission.user_can_edit_qsd(request.user, base_url)

        if have_edit:
            if action in ('edit','create',):
                qsd_rec = QuasiStaticData()
                qsd_rec.url = base_url
                qsd_rec.nav_category = default_navbarcategory()
                qsd_rec.title = 'New Page'
                qsd_rec.content = 'Please insert your text here'
                qsd_rec.create_date = datetime.now()
                qsd_rec.keywords = ''
                qsd_rec.description = ''
                action = 'edit'

            if (action == 'read'):
                edit_link = '/' + base_url + '.edit.html'
                response = render_to_response('qsd/nopage_create.html', request, {'edit_link': edit_link}, use_request_context=False)
                response.status_code = 404 # Make sure we actually 404, so that if there is a redirect the middleware can catch it.
                return response
        else:
            if action == 'read':
                raise Http404, 'This page does not exist.'
            else:
                raise Http403, 'Sorry, you can not modify <tt>%s</tt>.' % request.path

    if action == 'create':
        action = 'edit'

    # Detect the standard read verb
    if action == 'read':
        if not have_read:
            raise Http403, 'You do not have permission to read this page.'

        # Render response
        response = render_to_response('qsd/qsd.html', request, {
            'title': qsd_rec.title,
            'nav_category': qsd_rec.nav_category,
            'content': qsd_rec.html(),
            'settings': settings,
            'qsdrec': qsd_rec,
            'have_edit': True,  ## Edit-ness is determined client-side these days
            'edit_url': '/' + base_url + ".edit.html" }, use_request_context=False)

#        patch_vary_headers(response, ['Cookie'])
#        if have_edit:
#            add_never_cache_headers(response)
#            patch_cache_control(response, no_cache=True, no_store=True)
#        else:
        patch_cache_control(response, max_age=3600, public=True)

        return response


    # Detect POST
    if 'post_edit' in request.POST:
        have_edit = Permission.user_can_edit_qsd(request.user, base_url)

        if not have_edit:
            raise Http403, "Sorry, you do not have permission to edit this page."

        nav_category_target = NavBarCategory.objects.get(id=request.POST['nav_category'])

        # Since QSD now uses reversion, we want to only modify the data if we've actually changed something
        # The revision will automatically be created upon calling the save function of the model object
        copy_map = {
            'url': base_url,
            'nav_category': nav_category_target,
            'content': request.POST['content'],
            'title': request.POST['title'],
            'description': request.POST['description'],
            'keywords': request.POST['keywords'],
        }
        diff_found = False
        for field, new_value in copy_map.items():
            if getattr(qsd_rec, field) != new_value:
                setattr(qsd_rec, field, new_value)
                diff_found = True

        if diff_found:
            qsd_rec.load_cur_user_time(request)
            qsd_rec.save()

            # We should also purge the cache
            purge_page(qsd_rec.url+".html")


    # Detect the edit verb
    if action == 'edit':
        have_edit = Permission.user_can_edit_qsd(request.user, base_url)

        # Enforce authorizations (FIXME: SHOW A REAL ERROR!)
        if not have_edit:
            raise Http403, "You don't have permission to edit this page."

        # Render an edit form
        return render_to_response('qsd/qsd_edit.html', request, {
            'title'        : qsd_rec.title,
            'content'      : qsd_rec.content,
            'keywords'     : qsd_rec.keywords,
            'description'  : qsd_rec.description,
            'nav_category' : qsd_rec.nav_category,
            'nav_categories': NavBarCategory.objects.all(),
            'qsdrec'       : qsd_rec,
            'qsd'          : True,
            'target_url'   : base_url.split("/")[-1] + ".edit.html",
            'return_to_view': base_url.split("/")[-1] + ".html#refresh" },
            use_request_context=False)

    # Operation Complete!
    raise Http404('Unexpected QSD operation')
Example #26
0
 def user_has_perm(self, name, *args, **kwargs):
     """Checks for Permission object with user=self.user."""
     return Permission.user_has_perm(self.user, name, *args, **kwargs)
    def deadline_management(self, request, tl, one, two, module, extra, prog):
        #   Define a formset for editing multiple perms simultaneously.
        EditPermissionFormset = formset_factory(EditPermissionForm)

        #   Define a status message
        message = ''

        #   Handle 'open' / 'close' actions
        if extra == 'open' and 'id' in request.GET:
            perm = Permission.objects.get(id=request.GET['id'])
            #   Clear any duplicate user permissions
            Permission.objects.filter(permission_type=perm.permission_type, program=perm.program, user__isnull=True, role=perm.role).exclude(id=perm.id).delete()
            perm.end_date = None
            perm.save()
            message = 'Deadline opened: %s.' % perm.nice_name()

        elif extra == 'close' and 'id' in request.GET:
            perm = Permission.objects.get(id=request.GET['id'])
            #   Clear any duplicate user permissions
            Permission.objects.filter(permission_type=perm.permission_type, program=perm.program, user__isnull=True, role=perm.role).exclude(id=perm.id).delete()
            perm.end_date = datetime.now()
            perm.save()
            message = 'Deadline closed: %s.' % perm.nice_name()

        #   Check incoming form data
        if request.method == 'POST':
            edit_formset = EditPermissionFormset(request.POST.copy(), prefix='edit')
            create_form = NewPermissionForm(request.POST.copy())
            if edit_formset.is_valid():
                num_forms = 0
                for form in edit_formset.forms:
                    #   Check if the permission with the specified ID exists.
                    #   It may have been deleted by previous iterations of this loop
                    #   deleting duplicate permissions.
                    if 'id' in form.cleaned_data and Permission.objects.filter(id=form.cleaned_data['id']).exists():
                        num_forms += 1
                        perm = Permission.objects.get(id=form.cleaned_data['id'])
                        #   Clear any duplicate perms
                        Permission.objects.filter(permission_type=perm.permission_type, program=perm.program, user__isnull=True, role=perm.role).exclude(id=perm.id).delete()
                        perm.start_date = form.cleaned_data['start_date']
                        perm.end_date = form.cleaned_data['end_date']
                        perm.save()
                if num_forms > 0:
                    message = 'Changes saved.'
            if create_form.is_valid():
                perm, created = Permission.objects.get_or_create(user=None, permission_type=create_form.cleaned_data['permission_type'], role=Group.objects.get(name=create_form.cleaned_data['role']),program=prog)
                if not created:
                    message = 'Deadline already exists: %s.  Please modify the existing deadline.' % perm.nice_name()
                else:
                    perm.start_date = create_form.cleaned_data['start_date']
                    perm.end_date = create_form.cleaned_data['end_date']
                    perm.save()
                    message = 'Deadline created: %s.' % perm.nice_name()
            else:
                message = 'No activities selected.  Please select a deadline type from the list before creating a deadline.'

        #   find all the existing permissions with this program
        #   Only consider global permissions -- those that apply to all users
        #   of a particular role.  Permissions added for individual users
        #   should be managed in the admin interface.
        perms = Permission.deadlines().filter(program=self.program, user__isnull=True)
        perm_map = {p.permission_type: p for p in perms}

        #   Populate template context to render page with forms
        context = {}

        #   Set a flag on each perm for whether it has ended
        #   TODO(benkraft): refactor users to just call is_valid themselves.
        for perm in perms:
            perm.open_now = perm.is_valid()

        #   For each permission, determine which other ones it implies
        for perm in perms:
            includes = Permission.implications.get(perm.permission_type, [])
            perm.includes = []
            perm.name = perm.nice_name()
            for p in includes:
                if p == perm.permission_type: continue
                perm.includes.append({'type':p,'nice_name':Permission.nice_name_lookup(p)})
                if p in perm_map:
                    perm.includes[-1].update({'overridden':True,
                                              'overridden_by':perm_map[p],
                                              'bit_open':perm_map[p].open_now})

        #   Supply initial data for forms
        formset = EditPermissionFormset(initial = [perm.__dict__ for perm in perms], prefix = 'edit')
        for i in range(len(perms)):
            perms[i].form = formset.forms[i]


        context['message'] = message
        context['manage_form'] = formset.management_form
        context['perms'] = perms
        context['create_form'] = NewPermissionForm()

        return render_to_response(self.baseDir()+'deadlines.html', request, context)
Example #28
0
    def gen_perm(tup):
        new_perm=Permission(permission_type=tup[0], program=prog)

        if tup[2]:
            new_perm.start_date = tup[2]
        if tup[3]:
            new_perm.end_date = tup[3]

        if tup[1] is not None:
            new_perm.user=tup[1]
            new_perm.save()
            return
        elif tup[1] is None and tup[0].startswith("Student"):
            new_perm.role=Group.objects.get(name="Student")
            new_perm.save()
            return
        elif tup[1] is None and tup[0].startswith("Teacher"):
            new_perm.role=Group.objects.get(name="Teacher")
            new_perm.save()
            return

        #It's not for a specific user and not a teacher or student deadline
        for x in ESPUser.getTypes():
            newnew_perm=Permission(permission_type=new_perm.permission_type, role=Group.objects.get(name=x), start_date=new_perm.start_date, end_date=new_perm.end_date, program=prog)
            newnew_perm.save()
    def addclass_logic(self, request, tl, one, two, module, extra, prog):
        """ Pre-register the student for the class section in POST['section_id'].
            Return True if there are no errors.
        """
        reg_perm = 'Student/Classes'
        scrmi = self.program.getModuleExtension('StudentClassRegModuleInfo')

        if 'prereg_verb' in request.POST:
            proposed_verb = "V/Flags/Registration/%s" % request.POST[
                'prereg_verb']
            if scrmi.use_priority:
                available_verbs = [
                    "%s/%d" % (scrmi.signup_verb.get_uri(), x)
                    for x in xrange(1, scrmi.priority_limit + 1)
                ]
            else:
                available_verbs = [scrmi.signup_verb.get_uri()]

            if proposed_verb in available_verbs:
                prereg_verb = proposed_verb
            else:
                prereg_verb = None

        else:
            prereg_verb = None

        #   Explicitly set the user's onsiteness, since we refer to it soon.
        if not hasattr(request.user, "onsite_local"):
            request.user.onsite_local = False

        if request.POST.has_key('class_id'):
            classid = request.POST['class_id']
            sectionid = request.POST['section_id']
        else:
            raise ESPError(
                False
            ), "We've lost track of your chosen class's ID!  Please try again; make sure that you've clicked the \"Add Class\" button, rather than just typing in a URL.  Also, please make sure that your Web browser has JavaScript enabled."

        # Can we register for more than one class yet?
        if (not request.user.onsite_local) and (not Permission.user_has_perm(
                request.user, reg_perm, prog)):
            enrolled_classes = ESPUser(request.user).getEnrolledClasses(
                prog, request)
            # Some classes automatically register people for enforced prerequisites (i.e. HSSP ==> Spark). Don't penalize people for these...
            classes_registered = 0
            for cls in enrolled_classes:
                reg_verbs = cls.getRegVerbs(request.user)
                is_auto = 0
                for r in reg_verbs:
                    if r == 'Automatic':
                        is_auto = 1
                if not is_auto:
                    classes_registered += 1

            if classes_registered >= 1:
                datestring = ''
                sreg_perms = Permission.objects.filter(
                    user__isnull=True,
                    role__name="Student",
                    permission_type=reg_perm,
                    program=prog)
                if sreg_perms.count() > 0:
                    d = sreg_perms[0].start_date
                    if d.date() == d.today().date():
                        datestring = ' later today'
                    else:
                        datestring = d.strftime(' on %B %d')
                raise ESPError(
                    False
                ), "Currently, you are only allowed to register for one %s class.  Please come back after student registration fully opens%s!" % (
                    prog.niceName(), datestring)

        section = ClassSection.objects.get(id=sectionid)
        if not scrmi.use_priority:
            error = section.cannotAdd(request.user, self.enforce_max)
        if scrmi.use_priority or not error:
            cobj = ClassSubject.objects.get(id=classid)
            error = cobj.cannotAdd(request.user,
                                   self.enforce_max) or section.cannotAdd(
                                       request.user, self.enforce_max)

        if scrmi.use_priority:
            priority = request.user.getRegistrationPriority(
                prog, section.meeting_times.all())
        else:
            priority = 1

        # autoregister for implied classes one level deep. XOR is currently not implemented, but we're not using it yet either.
        auto_classes = []
        blocked_class = None
        cannotadd_error = ''

        for implication in ClassImplication.objects.filter(
                cls__id=classid, parent__isnull=True):
            if implication.fails_implication(request.user):
                for cls in ClassSubject.objects.filter(
                        id__in=implication.member_id_ints):
                    #   Override size limits on subprogram classes (checkFull=False). -Michael P
                    sec = cls.default_section()
                    if sec.cannotAdd(request.user, checkFull=False):
                        blocked_class = cls
                        cannotadd_error = sec.cannotAdd(request.user,
                                                        checkFull=False)
                    else:
                        if sec.preregister_student(request.user,
                                                   overridefull=True,
                                                   automatic=True,
                                                   priority=priority,
                                                   prereg_verb=prereg_verb):
                            auto_classes.append(sec)
                            if implication.operation != 'AND':
                                break
                        else:
                            blocked_class = cls
                    if (blocked_class
                            is not None) and implication.operation == 'AND':
                        break
                if implication.fails_implication(request.user):
                    for sec in auto_classes:
                        sec.unpreregister_student(request.user,
                                                  prereg_verb=prereg_verb)
                    if blocked_class is not None:
                        raise ESPError(
                            False
                        ), 'You have no class blocks free for this class during %s! Please go to <a href="%sstudentreg">%s Student Registration</a> and make sure you have time on your schedule for the class "%s." (%s)' % (
                            blocked_class.parent_program.niceName(),
                            blocked_class.parent_program.get_learn_url(),
                            blocked_class.parent_program.niceName(),
                            blocked_class.title(), cannotadd_error)
                    else:
                        raise ESPError(
                            False
                        ), 'You have no class blocks free for this class during %s! Please go to <a href="%sstudentreg">%s Student Registration</a> and make sure you have time on your schedule for the class. (%s)' % (
                            prog.niceName(), prog.get_learn_url(),
                            prog.niceName(), cannotadd_error)

        if error and not request.user.onsite_local:
            raise ESPError(False), error

        #   Desired priority level is 1 above current max
        if section.preregister_student(request.user,
                                       request.user.onsite_local,
                                       priority,
                                       prereg_verb=prereg_verb):
            regs = Record.objects.filter(user=request.user,
                                         program=prog,
                                         event="reg_confirmed")
            if regs.count() == 0 and Tag.getTag('confirm_on_addclass'):
                r = Record.objects.create(user=request.user,
                                          program=prog,
                                          event="reg_confirmed")
            return True
        else:
            raise ESPError(
                False
            ), 'According to our latest information, this class is full. Please go back and choose another class.'
Example #30
0
    def forwards(self, orm):
        def end(bit):
            date = bit.enddate
            if date > datetime.datetime(3000, 1, 1):
                return None
            return date

        #Administer
        adm_bits = UserBit.objects.filter(verb__uri="V/Administer",
                                          qsc__uri__startswith="Q/Programs")
        for bit in adm_bits:
            try:
                p = Program.objects.get(anchor=bit.qsc)
            except Program.DoesNotExist:
                continue
            Permission(permission_type="Administer",
                       program=p,
                       user=bit.user,
                       startdate=bit.startdate,
                       enddate=end(bit)).save()

        # Administer all programs, but with an enddate.
        # Adds users that we didn't add to the Administrator group in 0019_userrole.
        for bit in UserBit.objects.filter(verb__uri="V/Administer",
                                          qsc__uri="Q",
                                          user__isnull=False,
                                          enddate__lt=datetime.datetime(
                                              3000, 1, 1)):
            Permission(permission_type="Administer",
                       program=None,
                       user=bit.user,
                       startdate=bit.startdate,
                       enddate=end(bit)).save()

        #view programs
        program_anchors = Program.objects.all().values_list("anchor",
                                                            flat=True)
        view_program_bits = UserBit.objects.filter(verb__uri="V/Flags/Public",
                                                   qsc__id__in=program_anchors)
        for bit in view_program_bits:
            try:
                p = Program.objects.get(anchor=bit.qsc)
            except Program.DoesNotExist:
                continue
            if bit.user is not None:
                Permission(permission_type=bit.verb.uri[24:],
                           user=bit.user,
                           program=p,
                           startdate=bit.startdate,
                           enddate=end(bit)).save()
            else:
                for x in ESPUser.getTypes():
                    Permission(permission_type=bit.verb.uri[24:],
                               role=Group.objects.get(name=x),
                               program=p,
                               startdate=bit.startdate,
                               enddate=end(bit)).save()

        #gradeoverride
        go_bits = UserBit.objects.filter(
            verb__uri="V/Flags/Registration/GradeOverride",
            qsc__uri__startswith="Q/Programs")
        for bit in go_bits:
            try:
                p = Program.objects.get(anchor=bit.qsc)
            except Program.DoesNotExist:
                continue
            Permission(permission_type="GradeOverride",
                       program=p,
                       user=bit.user,
                       startdate=bit.startdate,
                       enddate=end(bit)).save()

        #onsite
        onsite_bits = UserBit.objects.filter(verb__uri="V/Registration/Onsite")
        for bit in onsite_bits:
            try:
                p = Program.objects.get(anchor=bit.qsc)
            except Program.DoesNotExist:
                continue
            Permission(permission_type="Onsite",
                       user=bit.user,
                       program=p,
                       startdate=bit.startdate,
                       enddate=end(bit)).save()

        #deadlines
        deadline_bits = UserBit.objects.filter(
            verb__uri__startswith="V/Deadline/Registration")
        for bit in deadline_bits:
            try:
                p = Program.objects.get(anchor=bit.qsc)
            except Program.DoesNotExist:
                continue

            name = bit.verb.uri[24:]
            if bit.recursive and bit.verb.name in [
                    "Classes", "Teacher", "Student"
            ]:
                name += "/All"
            if bit.user is not None:
                Permission(permission_type=name,
                           user=bit.user,
                           program=p,
                           startdate=bit.startdate,
                           enddate=end(bit)).save()
            elif bit.verb.uri[24:31] == "Teacher":
                Permission(permission_type=name,
                           role=Group.objects.get(name="Teacher"),
                           program=p,
                           startdate=bit.startdate,
                           enddate=end(bit)).save()
            elif bit.verb.uri[24:31] == "Student":
                Permission(permission_type=name,
                           role=Group.objects.get(name="Student"),
                           program=p,
                           startdate=bit.startdate,
                           enddate=end(bit)).save()
Example #31
0
def classchangerequest(request, tl, one, two):
    from esp.program.models import Program, StudentAppResponse, StudentRegistration, RegistrationType
    from esp.program.models.class_ import ClassSubject
    from urllib import quote
    try:
        prog = Program.by_prog_inst(one, two)  #DataTree.get_by_uri(treeItem)
    except Program.DoesNotExist:
        raise Http404("Program not found.")

    if tl != "learn":
        raise Http404

    if not request.user or not request.user.is_authenticated():
        return HttpResponseRedirect(
            '%s?%s=%s' %
            (LOGIN_URL, REDIRECT_FIELD_NAME, quote(request.get_full_path())))

    if not request.user.isStudent() and not request.user.isAdmin(prog):
        allowed_student_types = Tag.getTag("allowed_student_types",
                                           prog,
                                           default='')
        matching_user_types = any(
            x in request.user.groups.all().values_list("name", flat=True)
            for x in allowed_student_types.split(","))
        if not matching_user_types:
            return render_to_response('errors/program/notastudent.html',
                                      request, {})

    errorpage = 'errors/program/wronggrade.html'

    cur_grade = request.user.getGrade(prog)
    if (not Permission.user_has_perm(
            request.user, 'GradeOverride', program=prog)
            and (cur_grade != 0 and
                 (cur_grade < prog.grade_min or cur_grade > prog.grade_max))):
        return render_to_response(errorpage, request, {})

    setattr(request, "program", prog)
    setattr(request, "tl", tl)
    setattr(request, "module", "classchangerequest")

    from django import forms
    from datetime import datetime
    from esp.utils.scheduling import getRankInClass

    timeslots = prog.getTimeSlots()
    sections = prog.sections().filter(status=10)

    enrollments = {}
    for timeslot in timeslots:
        try:
            enrollments[timeslot] = ClassSubject.objects.get(
                nest_Q(StudentRegistration.is_valid_qobject(),
                       'sections__studentregistration'),
                sections__studentregistration__relationship__name="Enrolled",
                sections__studentregistration__user=request.user,
                sections__meeting_times=timeslot,
                parent_program=prog)
        except ClassSubject.DoesNotExist:
            enrollments[timeslot] = None

    context = {}
    context['timeslots'] = timeslots
    context['enrollments'] = enrollments
    context['user'] = request.user
    if 'success' in request.GET:
        context['success'] = True
    else:
        context['success'] = False

    if request.user.isStudent():
        sections_by_slot = dict([(timeslot, [
            (section, 1 == StudentRegistration.valid_objects().filter(
                user=context['user'],
                section=section,
                relationship__name="Request").count()) for section in sections
            if section.get_meeting_times()[0] == timeslot
            and section.parent_class.grade_min <= request.user.getGrade(
                prog) <= section.parent_class.grade_max
            and section.parent_class not in enrollments.values()
            and getRankInClass(request.user, section) in (5, 10)
        ]) for timeslot in timeslots])
    else:
        sections_by_slot = dict([(timeslot, [
            (section, False) for section in sections
            if section.get_meeting_times()[0] == timeslot
        ]) for timeslot in timeslots])

    fields = {}
    for i, timeslot in enumerate(sections_by_slot.keys()):
        choices = [('0', "I'm happy with my current enrollment.")]
        initial = '0'
        for section in sections_by_slot[timeslot]:
            choices.append(
                (section[0].emailcode(),
                 section[0].emailcode() + ": " + section[0].title()))
            if section[1]:
                initial = section[0].emailcode()
        fields['timeslot_' + str(i + 1)] = forms.ChoiceField(
            label="Timeslot " + str(i + 1) + " (" + timeslot.pretty_time() +
            ")",
            choices=choices,
            initial=initial)

    form = type('ClassChangeRequestForm', (forms.Form, ), fields)
    context['form'] = form()
    if request.method == "POST":
        old_requests = StudentRegistration.valid_objects().filter(
            user=context['user'],
            section__parent_class__parent_program=prog,
            relationship__name="Request")
        for r in old_requests:
            r.expire()
        form = form(request.POST)
        if form.is_valid():
            for value in form.cleaned_data.values():
                section = None
                for s in sections:
                    if s.emailcode() == value:
                        section = s
                        break
                if not section:
                    continue
                r = StudentRegistration.objects.get_or_create(
                    user=context['user'],
                    section=section,
                    relationship=RegistrationType.objects.get_or_create(
                        name="Request", category="student")[0])[0]
                r.end_date = datetime(9999, 1, 1, 0, 0, 0, 0)
                r.save()

            return HttpResponseRedirect(request.path.rstrip('/') + '/?success')
    else:
        return render_to_response('program/classchangerequest.html', request,
                                  context)
Example #32
0
    def ajax_schedule(self, request, tl, one, two, module, extra, prog):
        import json as json
        from django.template.loader import render_to_string
        context = self.prepare({})
        context['prog'] = self.program
        context['one'] = one
        context['two'] = two
        context['reg_open'] = bool(
            Permission.user_has_perm(request.user, {
                'learn': 'Student',
                'teach': 'Teacher'
            }[tl] + "/Classes", prog))

        schedule_str = render_to_string('users/student_schedule_inline.html',
                                        context)
        script_str = render_to_string('users/student_schedule_inline.js',
                                      context)
        json_data = {
            'student_schedule_html': schedule_str,
            'script': script_str
        }

        #   Look at the 'extra' data and act appropriately:
        #   -   List, query set, or comma-separated ID list of class sections:
        #       Add the buttons for those class sections to the returned data.
        #   -   String 'all':
        #       Add the buttons for all of the student's class sections to the returned data
        #   -   Anything else:
        #       Don't do anything.
        #   Rewrite registration button if a particular section was named.  (It will be in extra).
        sec_ids = []
        if extra == 'all':
            # TODO(benkraft): this branch of the if was broken for 5 years and
            # nobody noticed, so we may be able to remove it entirely.
            sec_ids = self.user.getSections(self.program).values_list(
                'id', flat=True)
        elif isinstance(extra, list) or isinstance(extra, QuerySet):
            sec_ids = list(extra)
        else:
            try:
                sec_ids = [int(x) for x in extra.split(',')]
            except:
                pass

        for sec_id in sec_ids:
            try:
                section = ClassSection.objects.get(id=sec_id)
                cls = section.parent_class
                button_context = {'sec': section, 'cls': cls}
                if section in request.user.getEnrolledSections(self.program):
                    button_context['label'] = 'Registered!'
                    button_context['disabled'] = True
                addbutton_str1 = render_to_string(
                    self.baseDir() + 'addbutton_fillslot.html', button_context)
                addbutton_str2 = render_to_string(
                    self.baseDir() + 'addbutton_catalog.html', button_context)
                json_data['addbutton_fillslot_sec%d_html' %
                          sec_id] = addbutton_str1
                json_data['addbutton_catalog_sec%d_html' %
                          sec_id] = addbutton_str2
            except Exception, inst:
                raise AjaxError(
                    'Encountered an error retrieving updated buttons: %s' %
                    inst)
Example #33
0
    def gen_perm(tup):
        new_perm = Permission(permission_type=tup[0], program=prog)

        if tup[2]:
            new_perm.start_date = tup[2]
        if tup[3]:
            new_perm.end_date = tup[3]

        if tup[1] is not None:
            new_perm.user = tup[1]
            new_perm.save()
            return
        elif tup[1] is None and tup[0].startswith("Student"):
            new_perm.role = Group.objects.get(name="Student")
            new_perm.save()
            return
        elif tup[1] is None and tup[0].startswith("Teacher"):
            new_perm.role = Group.objects.get(name="Teacher")
            new_perm.save()
            return

        #It's not for a specific user and not a teacher or student deadline
        for x in ESPUser.getTypes():
            newnew_perm = Permission(permission_type=new_perm.permission_type,
                                     role=Group.objects.get(name=x),
                                     start_date=new_perm.start_date,
                                     end_date=new_perm.end_date,
                                     program=prog)
            newnew_perm.save()