Пример #1
0
def edit_participation(pctx, participation_id):
    # type: (CoursePageContext, int) -> http.HttpResponse
    if not pctx.has_permission(pperm.edit_participation):
        raise PermissionDenied()

    request = pctx.request

    num_participation_id = int(participation_id)

    if num_participation_id == -1:
        participation = Participation(course=pctx.course,
                                      status=participation_status.active)
        add_new = True
    else:
        participation = get_object_or_404(Participation,
                                          id=num_participation_id)
        add_new = False

    if participation.course.id != pctx.course.id:
        raise SuspiciousOperation(
            "may not edit participation in different course")

    if request.method == 'POST':
        form = EditParticipationForm(add_new,
                                     pctx,
                                     request.POST,
                                     instance=participation)
        reset_form = False

        try:
            if form.is_valid():
                if "submit" in request.POST:
                    form.save()

                    messages.add_message(request, messages.SUCCESS,
                                         _("Changes saved."))

                elif "approve" in request.POST:

                    # FIXME: Double-saving
                    participation = form.save()
                    participation.status = participation_status.active
                    participation.save()
                    reset_form = True

                    send_enrollment_decision(participation, True, pctx.request)

                    messages.add_message(request, messages.SUCCESS,
                                         _("Successfully enrolled."))

                elif "deny" in request.POST:

                    # FIXME: Double-saving
                    participation = form.save()
                    participation.status = participation_status.denied
                    participation.save()
                    reset_form = True

                    send_enrollment_decision(participation, False,
                                             pctx.request)

                    messages.add_message(request, messages.SUCCESS,
                                         _("Successfully denied."))

                elif "drop" in request.POST:
                    # FIXME: Double-saving
                    participation = form.save()
                    participation.status = participation_status.dropped
                    participation.save()
                    reset_form = True

                    messages.add_message(request, messages.SUCCESS,
                                         _("Successfully dropped."))
        except IntegrityError as e:
            messages.add_message(
                request, messages.ERROR,
                _("A data integrity issue was detected when saving "
                  "this participation. Maybe a participation for "
                  "this user already exists? (%s)") % str(e))

        if reset_form:
            form = EditParticipationForm(add_new, pctx, instance=participation)
    else:
        form = EditParticipationForm(add_new, pctx, instance=participation)

    return render_course_page(pctx, "course/generic-course-form.html", {
        "form_description": _("Edit Participation"),
        "form": form
    })
Пример #2
0
def get_credits(request, project, subproject):
    """View for credits"""
    obj = get_subproject(request, project, subproject)

    if not can_view_reports(request.user, obj.project):
        raise PermissionDenied()

    form = ReportsForm(request.POST)

    if not form.is_valid():
        return redirect(obj)

    data = generate_credits(
        obj,
        form.cleaned_data['start_date'],
        form.cleaned_data['end_date'],
    )

    if form.cleaned_data['style'] == 'json':
        return HttpResponse(
            json.dumps(data),
            content_type='application/json'
        )

    if form.cleaned_data['style'] == 'html':
        start = '<table>'
        row_start = '<tr>'
        language_format = u'<th>{0}</th>'
        translator_start = '<td><ul>'
        translator_format = u'<li><a href="mailto:{0}">{1}</a></li>'
        translator_end = '</ul></td>'
        row_end = '</tr>'
        mime = 'text/html'
        end = '</table>'
    else:
        start = ''
        row_start = ''
        language_format = u'* {0}\n'
        translator_start = ''
        translator_format = u'    * {1} <{0}>'
        translator_end = ''
        row_end = ''
        mime = 'text/plain'
        end = ''

    result = []

    result.append(start)

    for language in data:
        name, translators = language.items()[0]
        result.append(row_start)
        result.append(language_format.format(name))
        result.append(
            u'{0}{1}{2}'.format(
                translator_start,
                '\n'.join(
                    [translator_format.format(*t) for t in translators]
                ),
                translator_end,
            )
        )
        result.append(row_end)

    result.append(end)

    return HttpResponse(
        '\n'.join(result),
        content_type='{0}; charset=utf-8'.format(mime),
    )
Пример #3
0
def playgame(request, game_id):
    game = get_object_or_404(Game, pk=game_id)
    # check if the user request.user belongs  to the game/profile.
    if game not in request.user.profile.games.all():
        raise PermissionDenied()
    return render(request, 'games/gamecontainer.html', {'game': game})
Пример #4
0
 def temp(req):
     raise PermissionDenied('bar')
Пример #5
0
def raise_delete_error(request, page):
    raise PermissionDenied('Deletion via POST is disabled')
Пример #6
0
 def is_in_group(user, group_name):
     if user:
         if user.groups.filter(name=group_name).count() == 1:
             return True
     # XXX: add template with logout form here
     raise PermissionDenied("You are not in group '%s'" % group_name)
Пример #7
0
 def get_object(self, queryset=None):
     article = get_object_or_404(BlogArticle, pk=self.kwargs['pk'])
     if article.blog.owner != self.request.user:
         raise PermissionDenied()
     return article
Пример #8
0
 def handle_no_permission(self):
     if self.raise_exception or is_logged_in(self.request):
         raise PermissionDenied(self.get_permission_denied_message())
     return redirect('login')
Пример #9
0
def board_article_list(request, board_name=None, page_num=1):
    if board_name is None:
        raise PermissionDenied()
    try:
        board = Board.objects.get(name=board_name)
    except:
        raise Http404()

    search_type = request.GET.get('search_type', '')
    query = request.GET.get('query', '')
    is_search = True
    if search_type == 'title':
        articles = Article.objects.filter(
            board=board,
            deleted=False,
            is_important=False,
            title__contains=query).order_by('-id')
    elif search_type == 'content':
        articles = Article.objects.filter(
            board=board,
            deleted=False,
            is_important=False,
            content__contains=query).order_by('-id')
    elif search_type == 'title.content':
        q = operator.and_(
            operator.or_(Q(title__contains=query), Q(content__contains=query)),
            Q(board=board, deleted=False, is_important=False))
        articles = Article.objects.filter(q).order_by('-id')
    elif search_type == 'username' and not board.is_anonymous:
        articles = Article.objects.filter(board=board,
                                          deleted=False,
                                          is_important=False,
                                          user__username=query).order_by('-id')
    elif search_type == 'name' and not board.is_anonymous:
        articles = Article.objects.filter(
            board=board,
            deleted=False,
            is_important=False,
            writer_name__contains=query).order_by('-id')
    else:
        articles = Article.objects.filter(board=board,
                                          deleted=False,
                                          is_important=False).order_by('-id')
        is_search = False

    count_per_page = board.article_per_page
    total_page_num = max((articles.count() - 1) / count_per_page + 1, 1)
    page_num = int(page_num)
    if page_num < 1 or page_num > total_page_num:
        raise Http404()
    start = (page_num - 1) * count_per_page
    end = page_num * count_per_page
    articles = articles[start:end]

    page_nums = get_page_nums(total_page_num, 5, page_num)

    important_articles = Article.objects.filter(
        board=board, deleted=False, is_important=True).order_by('-id')
    article_count = articles.count() + important_articles.count()

    return render_to_response(
        'board/article_list.html',
        RequestContext(
            request, {
                'board': board,
                'articles': articles,
                'page_num': page_num,
                'total_page_num': total_page_num,
                'page_nums': page_nums,
                'get_parameters': request.GET.urlencode(),
                'get_dict': request.GET,
                'article_count': article_count,
                'is_search': is_search,
                'important_articles': important_articles
            }))
Пример #10
0
 def get_object(self, queryset=None):
     submission = super().get_object(queryset)
     if not submission.can_see_detail(self.request.user):
         raise PermissionDenied()
     return submission
Пример #11
0
    def repository(self, request, **kwargs):
        obj = self.get_object()

        if isinstance(obj, Translation):
            project = obj.component.project
        elif isinstance(obj, Component):
            project = obj.project
        else:
            project = obj

        if request.method == 'POST':
            serializer = RepoRequestSerializer(data=request.data)
            serializer.is_valid(raise_exception=True)

            data = {
                'result':
                self.repository_operation(
                    request, obj, project,
                    serializer.validated_data['operation'])
            }

            storage = get_messages(request)
            if storage:
                data['detail'] = '\n'.join([m.message for m in storage])

            return Response(data)

        if not request.user.has_perm('meta:vcs.status', project):
            raise PermissionDenied()

        data = {
            'needs_commit': obj.repo_needs_commit(),
            'needs_merge': obj.repo_needs_merge(),
            'needs_push': obj.repo_needs_push(),
        }

        if isinstance(obj, Project):
            data['url'] = reverse('api:project-repository',
                                  kwargs={'slug': obj.slug},
                                  request=request)
        else:
            data['remote_commit'] = obj.get_last_remote_commit()

            if isinstance(obj, Translation):
                component = obj.component
                data['url'] = reverse('api:translation-repository',
                                      kwargs={
                                          'component__project__slug':
                                          component.project.slug,
                                          'component__slug':
                                          component.slug,
                                          'language__code':
                                          obj.language.code,
                                      },
                                      request=request)
                data['status'] = obj.component.repository.status()
                changes = Change.objects.filter(
                    action__in=Change.ACTIONS_REPOSITORY,
                    component=obj.component,
                )
            else:
                data['url'] = reverse('api:component-repository',
                                      kwargs={
                                          'project__slug': obj.project.slug,
                                          'slug': obj.slug,
                                      },
                                      request=request)
                data['status'] = obj.repository.status()
                changes = Change.objects.filter(
                    action__in=Change.ACTIONS_REPOSITORY,
                    component=obj,
                )

            if changes.exists() and changes[0].is_merge_failure():
                data['merge_failure'] = changes[0].target
            else:
                data['merge_failure'] = None

        return Response(data)
Пример #12
0
def http403_view(request):
    raise PermissionDenied()
Пример #13
0
def query_participations(pctx):
    if (not pctx.has_permission(pperm.query_participation)
            or pctx.has_permission(pperm.view_participant_masked_profile)):
        raise PermissionDenied(_("may not query participations"))

    request = pctx.request

    result = None

    if request.method == "POST":
        form = ParticipationQueryForm(request.POST)
        if form.is_valid():
            parsed_query = None
            try:
                for lineno, q in enumerate(
                        form.cleaned_data["queries"].split("\n")):
                    q = q.strip()

                    if not q:
                        continue

                    parsed_subquery = parse_query(pctx.course, q)
                    if parsed_query is None:
                        parsed_query = parsed_subquery
                    else:
                        parsed_query = parsed_query | parsed_subquery

            except Exception as e:
                messages.add_message(
                    request, messages.ERROR,
                    _("Error in line %(lineno)d: %(error_type)s: %(error)s") %
                    {
                        "lineno": lineno + 1,
                        "error_type": type(e).__name__,
                        "error": str(e),
                    })

                parsed_query = None

            if parsed_query is not None:
                result = list(
                    Participation.objects.filter(course=pctx.course).filter(
                        parsed_query).order_by("user__username").
                    select_related("user").prefetch_related("tags"))

                if "apply" in request.POST:

                    if form.cleaned_data["op"] == "apply_tag":
                        ptag, __ = ParticipationTag.objects.get_or_create(
                            course=pctx.course, name=form.cleaned_data["tag"])
                        for p in result:
                            p.tags.add(ptag)
                    elif form.cleaned_data["op"] == "remove_tag":
                        ptag, __ = ParticipationTag.objects.get_or_create(
                            course=pctx.course, name=form.cleaned_data["tag"])
                        for p in result:
                            p.tags.remove(ptag)
                    else:
                        assert form.cleaned_data["op"] == "drop"
                        for p in result:
                            p.status = participation_status.dropped
                            p.save()

                    messages.add_message(
                        request, messages.INFO,
                        "Operation successful on %d participations." %
                        len(result))

    else:
        form = ParticipationQueryForm()

    return render_course_page(pctx, "course/query-participations.html", {
        "form": form,
        "result": result,
    })
Пример #14
0
def create_preapprovals(pctx):
    if not pctx.has_permission(pperm.preapprove_participation):
        raise PermissionDenied(_("may not preapprove participation"))

    request = pctx.request

    if request.method == "POST":
        form = BulkPreapprovalsForm(pctx.course, request.POST)
        if form.is_valid():

            created_count = 0
            exist_count = 0
            pending_approved_count = 0

            roles = form.cleaned_data["roles"]
            preapp_type = form.cleaned_data["preapproval_type"]

            for ln in form.cleaned_data["preapproval_data"].split("\n"):
                ln = ln.strip()

                if not ln:
                    continue

                preapp_filter_kwargs = {"%s__iexact" % preapp_type: ln}

                try:
                    ParticipationPreapproval.objects.get(
                        course=pctx.course, **preapp_filter_kwargs)
                except ParticipationPreapproval.DoesNotExist:

                    # approve if ln is requesting enrollment
                    user_filter_kwargs = {"user__%s__iexact" % preapp_type: ln}
                    if preapp_type == "institutional_id":
                        if pctx.course.preapproval_require_verified_inst_id:
                            user_filter_kwargs.update(
                                {"user__institutional_id_verified": True})

                    try:
                        pending = Participation.objects.get(
                            course=pctx.course,
                            status=participation_status.requested,
                            **user_filter_kwargs)

                    except Participation.DoesNotExist:
                        pass

                    else:
                        pending.status = participation_status.active
                        pending.save()
                        send_enrollment_decision(pending, True, request)
                        pending_approved_count += 1

                else:
                    exist_count += 1
                    continue

                preapproval = ParticipationPreapproval()
                if preapp_type == "email":
                    preapproval.email = ln
                else:
                    assert preapp_type == "institutional_id"
                    preapproval.institutional_id = ln
                preapproval.course = pctx.course
                preapproval.creator = request.user
                preapproval.save()
                preapproval.roles.set(roles)

                created_count += 1

            messages.add_message(
                request, messages.INFO,
                _("%(n_created)d preapprovals created, "
                  "%(n_exist)d already existed, "
                  "%(n_requested_approved)d pending requests approved.") % {
                      'n_created': created_count,
                      'n_exist': exist_count,
                      'n_requested_approved': pending_approved_count
                  })
            return redirect("relate-course_page", pctx.course.identifier)

    else:
        form = BulkPreapprovalsForm(pctx.course)

    return render_course_page(
        pctx, "course/generic-course-form.html", {
            "form": form,
            "form_description": _("Create Participation Preapprovals"),
        })
Пример #15
0
def translate_page(request, units_queryset, store=None):
    if not check_permission("view", request):
        raise PermissionDenied(
            _("You do not have rights to access this translation project."))

    cantranslate = check_permission("translate", request)
    cansuggest = check_permission("suggest", request)
    canreview = check_permission("review", request)
    translation_project = request.translation_project
    language = translation_project.language
    # shouldn't we globalize profile context
    profile = get_profile(request.user)

    step_queryset = None

    # Process search first
    search_form = None
    if 'search' in request.GET and 'sfields' in request.GET:
        search_form = SearchForm(request.GET)
        if search_form.is_valid():
            step_queryset = get_search_step_query(request.translation_project,
                                                  search_form, units_queryset)
    else:
        search_form = SearchForm()

    # which units are we interested in?
    if step_queryset is None:
        step_queryset = get_step_query(request, units_queryset)

    prev_unit, edit_unit, pager = get_current_units(request, step_queryset,
                                                    units_queryset)

    # time to process POST submission
    form = None
    if prev_unit is not None and ('submit' in request.POST
                                  or 'suggest' in request.POST):
        # check permissions
        if 'submit'  in request.POST and not cantranslate or \
           'suggest' in request.POST and not cansuggest:
            raise PermissionDenied

        form_class = unit_form_factory(language, len(prev_unit.source.strings))
        form = form_class(request.POST, instance=prev_unit)
        if form.is_valid():
            if cantranslate and 'submit' in request.POST:
                if form.instance._target_updated or form.instance._translator_comment_updated or \
                       form.instance._state_updated:
                    form.save()
                    sub = Submission(translation_project=translation_project,
                                     submitter=get_profile(request.user))
                    sub.save()

            elif cansuggest and 'suggest' in request.POST:
                if form.instance._target_updated:
                    #HACKISH: django 1.2 stupidly modifies instance on
                    # model form validation, reload unit from db
                    prev_unit = Unit.objects.get(id=prev_unit.id)
                    sugg = prev_unit.add_suggestion(
                        form.cleaned_data['target_f'],
                        get_profile(request.user))
                    if sugg:
                        SuggestionStat.objects.get_or_create(
                            translation_project=translation_project,
                            suggester=get_profile(request.user),
                            state='pending',
                            unit=prev_unit.id)
        else:
            # form failed, don't skip to next unit
            edit_unit = prev_unit

    if edit_unit is None:
        # no more units to step through, display end of translation message
        return translate_end(request, translation_project)

    # only create form for edit_unit if prev_unit was processed successfully
    if form is None or form.is_valid():
        form_class = unit_form_factory(language, len(edit_unit.source.strings))
        form = form_class(instance=edit_unit)

    if store is None:
        store = edit_unit.store
        pager_query = units_queryset
        preceding = (pager_query.filter(store=store, index__lt=edit_unit.index) | \
                     pager_query.filter(store__pootle_path__lt=store.pootle_path)).count()
        store_preceding = store.units.filter(index__lt=edit_unit.index).count()
    else:
        pager_query = store.units
        preceding = pager_query.filter(index__lt=edit_unit.index).count()
        store_preceding = preceding

    unit_rows = profile.get_unit_rows()

    # regardless of the query used to step through units, we will
    # display units in their original context, and display a pager for
    # the store not for the unit_step query
    if pager is None:
        page = preceding / unit_rows + 1
        pager = paginate(request, pager_query, items=unit_rows, page=page)

    # we always display the active unit in the middle of the page to
    # provide context for translators
    context_rows = (unit_rows - 1) / 2
    if store_preceding > context_rows:
        unit_position = store_preceding % unit_rows
        if unit_position < context_rows:
            # units too close to the top of the batch
            offset = unit_rows - (context_rows - unit_position)
            units_query = store.units[offset:]
            page = store_preceding / unit_rows
            units = paginate(request, units_query, items=unit_rows,
                             page=page).object_list
        elif unit_position >= unit_rows - context_rows:
            # units too close to the bottom of the batch
            offset = context_rows - (unit_rows - unit_position - 1)
            units_query = store.units[offset:]
            page = store_preceding / unit_rows + 1
            units = paginate(request, units_query, items=unit_rows,
                             page=page).object_list
        else:
            units = pager.object_list
    else:
        units = store.units[:unit_rows]

    # caluclate url querystring so state is retained on POST
    # we can't just use request URL cause unit and page GET vars cancel state
    GET_vars = []
    for key, values in request.GET.lists():
        if key not in ('page', 'unit'):
            for value in values:
                GET_vars.append('%s=%s' % (key, value))

    # links for quality check documentation
    checks = []
    for check in request.GET.get('matchnames', '').split(','):
        if not check:
            continue
        safe_check = escape(check)
        link = '<a href="http://translate.sourceforge.net/wiki/toolkit/pofilter_tests#%s" target="_blank">%s</a>' % (
            safe_check, safe_check)
        checks.append(_('checking %s', link))

    # precalculate alternative source languages
    alt_src_langs = get_alt_src_langs(request, profile, translation_project)
    alt_src_codes = alt_src_langs.values_list('code', flat=True)

    context = {
        'unit_rows': unit_rows,
        'alt_src_langs': alt_src_langs,
        'alt_src_codes': alt_src_codes,
        'cantranslate': cantranslate,
        'cansuggest': cansuggest,
        'canreview': canreview,
        'form': form,
        'search_form': search_form,
        'edit_unit': edit_unit,
        'store': store,
        'pager': pager,
        'units': units,
        'language': language,
        'translation_project': translation_project,
        'project': translation_project.project,
        'profile': profile,
        'source_language': translation_project.project.source_language,
        'directory': store.parent,
        'GET_state': '&'.join(GET_vars),
        'checks': checks,
        'MT_BACKENDS': settings.MT_BACKENDS,
    }
    return render_to_response('store/translate.html',
                              context,
                              context_instance=RequestContext(request))
Пример #16
0
 def check_if_user_has_permissions(self, permission, user: User):
     if not user.has_perm(permission, self):
         raise PermissionDenied()
Пример #17
0
 def get_object(self, *args, **kwargs):
     obj = super(ProductDeleteView, self).get_object(*args, **kwargs)
     if obj.user != self.request.user:
         raise PermissionDenied()  #or Http404
     return obj
Пример #18
0
 def deny_permission_if_scheduler(self, user: User):
     if not user.is_scheduler:
         raise PermissionDenied()
Пример #19
0
def do_create_account(form, custom_form=None):
    """
    Given cleaned post variables, create the User and UserProfile objects, as well as the
    registration for this user.

    Returns a tuple (User, UserProfile, Registration).

    Note: this function is also used for creating test users.
    """
    # Check if ALLOW_PUBLIC_ACCOUNT_CREATION flag turned off to restrict user account creation
    if not configuration_helpers.get_value(
            'ALLOW_PUBLIC_ACCOUNT_CREATION',
            settings.FEATURES.get('ALLOW_PUBLIC_ACCOUNT_CREATION', True)):
        raise PermissionDenied()

    errors = {}
    errors.update(form.errors)
    if custom_form:
        errors.update(custom_form.errors)

    if errors:
        raise ValidationError(errors)

    proposed_username = form.cleaned_data["username"]
    user = User(username=proposed_username,
                email=form.cleaned_data["email"],
                is_active=False)
    password = normalize_password(form.cleaned_data["password"])
    user.set_password(password)
    registration = Registration()

    # TODO: Rearrange so that if part of the process fails, the whole process fails.
    # Right now, we can have e.g. no registration e-mail sent out and a zombie account
    try:
        with transaction.atomic():
            user.save()
            if custom_form:
                custom_model = custom_form.save(commit=False)
                custom_model.user = user
                custom_model.save()
    except IntegrityError:
        # Figure out the cause of the integrity error
        # TODO duplicate email is already handled by form.errors above as a ValidationError.
        # The checks for duplicate email/username should occur in the same place with an
        # AccountValidationError and a consistent user message returned (i.e. both should
        # return "It looks like {username} belongs to an existing account. Try again with a
        # different username.")
        if username_exists_or_retired(user.username):
            raise AccountValidationError(
                USERNAME_EXISTS_MSG_FMT.format(username=proposed_username),
                field="username")
        elif email_exists_or_retired(user.email):
            raise AccountValidationError(_(
                "An account with the Email '{email}' already exists.").format(
                    email=user.email),
                                         field="email")
        else:
            raise

    registration.register(user)

    profile_fields = [
        "name", "level_of_education", "gender", "mailing_address", "city",
        "country", "goals", "year_of_birth"
    ]
    profile = UserProfile(
        user=user,
        **{key: form.cleaned_data.get(key)
           for key in profile_fields})
    extended_profile = form.cleaned_extended_profile
    if extended_profile:
        profile.meta = json.dumps(extended_profile)
    try:
        profile.save()
    except Exception:
        log.exception(
            "UserProfile creation failed for user {id}.".format(id=user.id))
        raise

    return user, profile, registration
Пример #20
0
 def get(self, request):
     raise PermissionDenied("This is a test 403 error")
Пример #21
0
def batch_issue_exam_tickets(pctx):
    if pctx.role not in [
            participation_role.instructor,
    ]:
        raise PermissionDenied(
            _("must be instructor or TA to batch-issue tickets"))

    form_text = ""

    request = pctx.request
    if request.method == "POST":
        form = BatchIssueTicketsForm(pctx.course, request.user.editor_mode,
                                     request.POST)

        if form.is_valid():
            exam = form.cleaned_data["exam"]

            from jinja2 import TemplateSyntaxError
            from course.content import markup_to_html
            try:
                with transaction.atomic():
                    if form.cleaned_data["revoke_prior"]:
                        ExamTicket.objects.filter(
                            exam=exam,
                            state__in=(
                                exam_ticket_states.valid,
                                exam_ticket_states.used,
                            )).update(state=exam_ticket_states.revoked)

                    tickets = []
                    for participation in (Participation.objects.filter(
                            course=pctx.course,
                            status=participation_status.active).order_by(
                                "user__last_name")):
                        ticket = ExamTicket()
                        ticket.exam = exam
                        ticket.participation = participation
                        ticket.creator = request.user
                        ticket.state = exam_ticket_states.valid
                        ticket.code = gen_ticket_code()
                        ticket.save()

                        tickets.append(ticket)

                    checkin_uri = pctx.request.build_absolute_uri(
                        reverse("relate-check_in_for_exam"))
                    form_text = markup_to_html(pctx.course,
                                               pctx.repo,
                                               pctx.course_commit_sha,
                                               form.cleaned_data["format"],
                                               jinja_env={
                                                   "tickets": tickets,
                                                   "checkin_uri": checkin_uri,
                                               })
            except TemplateSyntaxError as e:
                messages.add_message(
                    request, messages.ERROR,
                    string_concat(_("Template rendering failed"),
                                  ": line %(lineno)d: %(err_str)s") % {
                                      "lineno": e.lineno,
                                      "err_str": e.message.decode("utf-8")
                                  })
            except Exception as e:
                messages.add_message(
                    request, messages.ERROR,
                    string_concat(_("Template rendering failed"),
                                  ": %(err_type)s: %(err_str)s") % {
                                      "err_type": type(e).__name__,
                                      "err_str": str(e)
                                  })
            else:
                messages.add_message(request, messages.SUCCESS,
                                     _("%d tickets issued.") % len(tickets))

    else:
        form = BatchIssueTicketsForm(pctx.course, request.user.editor_mode)

    return render_course_page(
        pctx, "course/batch-exam-tickets-form.html", {
            "form": form,
            "form_text": form_text,
            "form_description": ugettext("Batch-Issue Exam Tickets")
        })
Пример #22
0
def set_up_new_course(request):
    if not request.user.is_staff:
        raise PermissionDenied(_("only staff may create courses"))

    if request.method == "POST":
        form = CourseCreationForm(request.POST)

        if form.is_valid():
            new_course = form.save(commit=False)

            from course.content import get_course_repo_path
            repo_path = get_course_repo_path(new_course)

            try:
                import os
                os.makedirs(repo_path)

                try:
                    with transaction.atomic():
                        from dulwich.repo import Repo
                        repo = Repo.init(repo_path)

                        client, remote_path = \
                            get_dulwich_client_and_remote_path_from_course(
                                    new_course)

                        remote_refs = client.fetch(remote_path, repo)
                        new_sha = repo["HEAD"] = remote_refs["HEAD"]

                        vrepo = repo
                        if new_course.course_root_path:
                            from course.content import SubdirRepoWrapper
                            vrepo = SubdirRepoWrapper(
                                vrepo, new_course.course_root_path)

                        from course.validation import validate_course_content
                        validate_course_content(vrepo, new_course.course_file,
                                                new_course.events_file,
                                                new_sha)

                        del repo
                        del vrepo

                        new_course.valid = True
                        new_course.active_git_commit_sha = new_sha
                        new_course.save()

                        # {{{ set up a participation for the course creator

                        part = Participation()
                        part.user = request.user
                        part.course = new_course
                        part.role = participation_role.instructor
                        part.status = participation_status.active
                        part.save()

                        # }}}

                        messages.add_message(
                            request, messages.INFO,
                            _("Course content validated, creation "
                              "succeeded."))
                except:
                    # Don't coalesce this handler with the one below. We only want
                    # to delete the directory if we created it. Trust me.

                    # Work around read-only files on Windows.
                    # https://docs.python.org/3.5/library/shutil.html#rmtree-example

                    import os
                    import stat
                    import shutil

                    # Make sure files opened for 'repo' above are actually closed.
                    import gc
                    gc.collect()

                    def remove_readonly(func, path, _):  # noqa
                        "Clear the readonly bit and reattempt the removal"
                        os.chmod(path, stat.S_IWRITE)
                        func(path)

                    try:
                        shutil.rmtree(repo_path, onerror=remove_readonly)
                    except OSError:
                        messages.add_message(
                            request, messages.WARNING,
                            ugettext("Failed to delete unused "
                                     "repository directory '%s'.") % repo_path)

                    raise

            except Exception as e:
                from traceback import print_exc
                print_exc()

                messages.add_message(
                    request, messages.ERROR,
                    string_concat(_("Course creation failed"),
                                  ": %(err_type)s: %(err_str)s") % {
                                      "err_type": type(e).__name__,
                                      "err_str": str(e)
                                  })
            else:
                return redirect("relate-course_page", new_course.identifier)

    else:
        form = CourseCreationForm()

    return render(request, "generic-form.html", {
        "form_description": _("Set up new course"),
        "form": form
    })
Пример #23
0
def upload_file(request, directory, django_file, overwrite, store=None):
    translation_project = request.translation_project
    tp_pootle_path_length = len(translation_project.pootle_path)
    relative_root_dir = directory.pootle_path[tp_pootle_path_length:]

    # for some reason factory checks explicitly for file existance and
    # if file is open, which makes it difficult to work with Django's
    # in memory uploads.
    #
    # setting _closed to False should work around this
    #FIXME: hackish, does this have any undesirable side effect?
    if getattr(django_file, '_closed', None) is None:
        try:
            django_file._closed = False
        except AttributeError:
            pass
    # factory also checks for _mode
    if getattr(django_file, '_mode', None) is None:
        try:
            django_file._mode = 1
        except AttributeError:
            pass
    # mode is an attribute not a property in Django 1.1
    if getattr(django_file, 'mode', None) is None:
        django_file.mode = 1

    if store and store.file:
        # Uploading to an existing file.
        pootle_path = store.pootle_path
        upload_path = store.real_path
    elif store:
        # Uploading to a virtual store.
        pootle_path = store.pootle_path
        upload_path = get_upload_path(translation_project, relative_root_dir,
                                      store.name)
    else:
        local_filename = get_local_filename(translation_project,
                                            django_file.name)
        pootle_path = directory.pootle_path + local_filename
        # The full filesystem path to 'local_filename'.
        upload_path = get_upload_path(translation_project, relative_root_dir,
                                      local_filename)
        try:
            store = translation_project.stores.get(pootle_path=pootle_path)
        except Store.DoesNotExist:
            store = None

    if (store is not None and overwrite == 'overwrite'
            and not check_permission('overwrite', request)):
        raise PermissionDenied(
            _("You do not have rights to overwrite files "
              "here."))

    if store is None and not check_permission('administrate', request):
        raise PermissionDenied(
            _("You do not have rights to upload new files "
              "here."))

    if overwrite == 'merge' and not check_permission('translate', request):
        raise PermissionDenied(
            _("You do not have rights to upload files "
              "here."))

    if overwrite == 'suggest' and not check_permission('suggest', request):
        raise PermissionDenied(
            _("You do not have rights to upload files "
              "here."))

    if store is None or (overwrite == 'overwrite' and store.file != ""):
        overwrite_file(request, relative_root_dir, django_file, upload_path)
        return

    if store.file and store.file.read() == django_file.read():
        logging.debug(u"identical file uploaded to %s, not merging",
                      store.pootle_path)
        return

    django_file.seek(0)
    from translate.storage import factory
    newstore = factory.getobject(django_file, classes=factory_classes)

    #FIXME: are we sure this is what we want to do? shouldn't we
    # differentiate between structure changing uploads and mere
    # pretranslate uploads?
    suggestions = overwrite == 'merge'
    notranslate = overwrite == 'suggest'
    allownewstrings = overwrite == 'overwrite' and store.file == ''

    store.mergefile(newstore,
                    get_profile(request.user),
                    suggestions=suggestions,
                    notranslate=notranslate,
                    allownewstrings=allownewstrings,
                    obsoletemissing=allownewstrings)
Пример #24
0
def update_course(pctx):
    if pctx.role not in [
            participation_role.instructor,
            participation_role.teaching_assistant
    ]:
        raise PermissionDenied(_("must be instructor or TA to update course"))

    course = pctx.course
    request = pctx.request
    content_repo = pctx.repo

    from course.content import SubdirRepoWrapper
    if isinstance(content_repo, SubdirRepoWrapper):
        repo = content_repo.repo
    else:
        repo = content_repo

    participation = pctx.participation

    previewing = bool(participation is not None
                      and participation.preview_git_commit_sha)

    may_update = pctx.role == participation_role.instructor

    response_form = None
    if request.method == "POST":
        form = GitUpdateForm(may_update, previewing, request.POST,
                             request.FILES)
        commands = [
            "fetch", "fetch_update", "update", "fetch_preview", "preview",
            "end_preview"
        ]

        command = None
        for cmd in commands:
            if cmd in form.data:
                command = cmd
                break

        if command is None:
            raise SuspiciousOperation(_("invalid command"))

        if form.is_valid():
            new_sha = form.cleaned_data["new_sha"].encode()

            try:
                run_course_update_command(request, repo, content_repo, pctx,
                                          command, new_sha, may_update)
            except Exception as e:
                messages.add_message(
                    pctx.request, messages.ERROR,
                    string_concat(
                        pgettext("Starting of Error message", "Error"),
                        ": %(err_type)s %(err_str)s") % {
                            "err_type": type(e).__name__,
                            "err_str": str(e)
                        })

    if response_form is None:
        previewing = bool(participation is not None
                          and participation.preview_git_commit_sha)

        form = GitUpdateForm(may_update, previewing, {"new_sha": repo.head()})

    text_lines = [
        string_concat("<b>", ugettext("Current git HEAD"),
                      ":</b> %(commit)s (%(message)s)") %
        {
            'commit': repo.head(),
            'message': cgi.escape(repo[repo.head()].message.strip())
        },
        string_concat("<b>", ugettext("Public active git SHA"),
                      ":</b> %(commit)s (%(message)s)") %
        {
            'commit':
            course.active_git_commit_sha,
            'message': (cgi.escape(
                repo[course.active_git_commit_sha.encode()].message.strip()))
        },
    ]
    if participation is not None and participation.preview_git_commit_sha:
        text_lines.append(
            string_concat("<b>", ugettext("Current preview git SHA"),
                          ":</b> %(commit)s (%(message)s)") %
            {
                'commit':
                participation.preview_git_commit_sha,
                'message':
                (cgi.escape(repo[participation.preview_git_commit_sha.encode(
                )].message.strip())),
            })
    else:
        text_lines.append("".join([
            "<b>",
            ugettext("Current preview git SHA"), ":</b> ",
            ugettext("None")
        ]))

    return render_course_page(
        pctx, "course/generic-course-form.html", {
            "form": form,
            "form_text": "".join("<p>%s</p>" % line for line in text_lines),
            "form_description": ugettext("Update Course Revision"),
        })
Пример #25
0
def get_counts(request, project, subproject):
    """View for work counts"""
    obj = get_subproject(request, project, subproject)

    if not can_view_reports(request.user, obj.project):
        raise PermissionDenied()

    form = ReportsForm(request.POST)

    if not form.is_valid():
        return redirect(obj)

    data = generate_counts(
        obj,
        form.cleaned_data['start_date'],
        form.cleaned_data['end_date'],
    )

    if form.cleaned_data['style'] == 'json':
        return HttpResponse(
            json.dumps(data),
            content_type='application/json'
        )

    if form.cleaned_data['style'] == 'html':
        start = (
            '<table>\n<tr><th>Email</th><th>Name</th>'
            '<th>Words</th><th>Count</th></tr>'
        )
        row_start = '<tr>'
        cell_format = u'<td>{0}</td>\n'
        row_end = '</tr>'
        mime = 'text/html'
        end = '</table>'
    else:
        heading = ' '.join(['=' * 25] * 4)
        start = '{0}\n{1:25} {2:25} {3:25} {4:25}\n{0}'.format(
            heading,
            'Email',
            'Name',
            'Words',
            'Count'
        )
        row_start = ''
        cell_format = u'{0:25} '
        row_end = ''
        mime = 'text/plain'
        end = heading

    result = []

    result.append(start)

    for item in data:
        result.append(row_start)
        result.append(
            u'{0}{1}{2}{3}'.format(
                cell_format.format(item['name']),
                cell_format.format(item['email']),
                cell_format.format(item['words']),
                cell_format.format(item['count']),
            )
        )
        result.append(row_end)

    result.append(end)

    return HttpResponse(
        '\n'.join(result),
        content_type='{0}; charset=utf-8'.format(mime),
    )
Пример #26
0
 def unstash_state(cls, request):
     if 'socialaccount_state' not in request.session:
         raise PermissionDenied()
     state, verifier = request.session.pop('socialaccount_state')
     return state
Пример #27
0
def update_course(pctx):
    if not (pctx.has_permission(pperm.update_content)
            or pctx.has_permission(pperm.preview_content)):
        raise PermissionDenied()

    course = pctx.course
    request = pctx.request
    content_repo = pctx.repo

    from course.content import SubdirRepoWrapper
    if isinstance(content_repo, SubdirRepoWrapper):
        repo = content_repo.repo
    else:
        repo = content_repo

    participation = pctx.participation

    previewing = bool(participation is not None
                      and participation.preview_git_commit_sha)

    may_update = pctx.has_permission(pperm.update_content)

    response_form = None
    form = None
    if request.method == "POST":
        form = GitUpdateForm(may_update, previewing, repo, request.POST,
                             request.FILES)

        command = None
        for cmd in ALLOWED_COURSE_REVISIOIN_COMMANDS:
            if cmd in form.data:
                command = cmd
                break

        if command is None:
            raise SuspiciousOperation(_("invalid command"))

        if form.is_valid():
            new_sha = form.cleaned_data["new_sha"].encode()

            try:
                run_course_update_command(
                    request,
                    repo,
                    content_repo,
                    pctx,
                    command,
                    new_sha,
                    may_update,
                    prevent_discarding_revisions=form.
                    cleaned_data["prevent_discarding_revisions"])
            except Exception as e:
                import traceback
                traceback.print_exc()

                messages.add_message(
                    pctx.request, messages.ERROR,
                    string_concat(
                        pgettext("Starting of Error message", "Error"),
                        ": %(err_type)s %(err_str)s") % {
                            "err_type": type(e).__name__,
                            "err_str": str(e)
                        })
        else:
            response_form = form

    if response_form is None:
        previewing = bool(participation is not None
                          and participation.preview_git_commit_sha)

        form = GitUpdateForm(
            may_update, previewing, repo, {
                "new_sha": repo.head().decode(),
                "prevent_discarding_revisions": True,
            })

    from django.template.loader import render_to_string
    form_text = render_to_string(
        "course/git-sha-table.html", {
            "participation":
            participation,
            "is_previewing":
            previewing,
            "course":
            course,
            "repo":
            repo,
            "current_git_head":
            repo.head().decode(),
            "git_url":
            request.build_absolute_uri(
                reverse("relate-git_endpoint", args=(course.identifier, ""))),
            "token_url":
            reverse("relate-manage_authentication_tokens",
                    args=(course.identifier, )),
        })

    assert form is not None

    return render_course_page(
        pctx, "course/generic-course-form.html", {
            "form": form,
            "form_text": form_text,
            "form_description": gettext("Update Course Revision"),
        })
Пример #28
0
def get_screenshot(request, pk):
    obj = get_object_or_404(Screenshot, pk=pk)
    request.user.check_access(obj.component.project)
    if not request.user.has_perm('screenshot.edit', obj.component):
        raise PermissionDenied()
    return obj
Пример #29
0
    def process_request(self, request):  # noqa: C901
        """Process request for csrf checks.
        Args:
            request (object): The request object
        """
        connection.set_schema_to_public()

        if is_no_auth(request):
            request.user = User("", "")
            return

        try:
            rh_auth_header, json_rh_auth = extract_header(request, self.header)
        except (KeyError, JSONDecodeError):
            LOG.warning("Could not obtain identity on request.")
            return
        except binascii.Error as error:
            LOG.error("Error decoding authentication header: %s", str(error))
            raise PermissionDenied()

        is_cost_management = json_rh_auth.get("entitlements", {}).get(
            "cost_management", {}).get("is_entitled", False)
        skip_entitlement = is_no_entitled(request)
        if not skip_entitlement and not is_cost_management:
            LOG.warning("User is not entitled for Cost Management.")
            raise PermissionDenied()

        account = json_rh_auth.get("identity", {}).get("account_number")
        user = json_rh_auth.get("identity", {}).get("user", {})
        username = user.get("username")
        email = user.get("email")
        is_admin = user.get("is_org_admin")
        req_id = None

        if username and email and account:
            # Get request ID
            req_id = request.META.get("HTTP_X_RH_INSIGHTS_REQUEST_ID")
            # Check for customer creation & user creation
            query_string = ""
            if request.META["QUERY_STRING"]:
                query_string = "?{}".format(request.META["QUERY_STRING"])
            stmt = {
                "method": request.method,
                "path": request.path + query_string,
                "request_id": req_id,
                "account": account,
                "username": username,
                "is_admin": is_admin,
            }
            LOG.info(stmt)
            try:
                if account not in IdentityHeaderMiddleware.customer_cache:
                    IdentityHeaderMiddleware.customer_cache[
                        account] = Customer.objects.filter(
                            account_id=account).get()
                    LOG.debug(f"Customer added to cache: {account}")
                customer = IdentityHeaderMiddleware.customer_cache[account]
            except Customer.DoesNotExist:
                customer = IdentityHeaderMiddleware.create_customer(account)
            except OperationalError as err:
                LOG.error("IdentityHeaderMiddleware exception: %s", err)
                DB_CONNECTION_ERRORS_COUNTER.inc()
                return HttpResponseFailedDependency({
                    "source": "Database",
                    "exception": err
                })

            try:
                if username not in USER_CACHE:
                    user = User.objects.get(username=username)
                    USER_CACHE[username] = user
                    LOG.debug(f"User added to cache: {username}")
                else:
                    user = USER_CACHE[username]
            except User.DoesNotExist:
                user = IdentityHeaderMiddleware.create_user(
                    username, email, customer, request)

            user.identity_header = {
                "encoded": rh_auth_header,
                "decoded": json_rh_auth
            }
            user.admin = is_admin
            user.req_id = req_id

            cache = caches["rbac"]
            user_access = cache.get(user.uuid)

            if not user_access:
                if settings.DEVELOPMENT and request.user.req_id == "DEVELOPMENT":
                    # passthrough for DEVELOPMENT_IDENTITY env var.
                    LOG.warning(
                        "DEVELOPMENT is Enabled. Bypassing access lookup for user: %s",
                        json_rh_auth)
                    user_access = request.user.access
                else:
                    try:
                        user_access = self._get_access(user)
                    except RbacConnectionError as err:
                        return HttpResponseFailedDependency({
                            "source": "Rbac",
                            "exception": err
                        })
                cache.set(user.uuid, user_access, self.rbac.cache_ttl)
            user.access = user_access
            request.user = user
Пример #30
0
def get_page_context(page,
                     user,
                     resource_edit=False,
                     extended_metadata_layout=None,
                     request=None):
    """
    :param page: which page to get the template context for
    :param user: the user who is viewing the page
    :param resource_edit: True if and only if the page should render in edit mode
    :param extended_metadata_layout: layout information used to build an ExtendedMetadataForm
    :param request: the Django request associated with the page load
    :return: the basic template context (a python dict) used to render a resource page. can and
    should be extended by page/resource-specific page_processors


    TODO: refactor to make it clear that there are two different modes = EDITABLE | READONLY
                - split into two functions: get_readonly_page_context(...) and
                get_editable_page_context(...)
    """
    file_type_error = ''
    if request:
        file_type_error = request.session.get("file_type_error", None)
        if file_type_error:
            del request.session["file_type_error"]

    content_model = page.get_content_model()
    # whether the user has permission to view this resource
    can_view = content_model.can_view(request)
    if not can_view:
        raise PermissionDenied()

    discoverable = content_model.raccess.discoverable
    validation_error = None
    resource_is_mine = False
    if user.is_authenticated():
        resource_is_mine = content_model.rlabels.is_mine(user)

    metadata_status = _get_metadata_status(content_model)

    belongs_to_collections = content_model.collections.all()

    relevant_tools = None
    tool_homepage_url = None
    if not resource_edit:  # In view mode
        content_model_str = str(content_model.content_model).lower()
        if content_model_str.lower() == "toolresource":
            if content_model.metadata.homepage_url.exists():
                tool_homepage_url = content_model.metadata.homepage_url.first(
                ).value

        relevant_tools = []
        # loop through all SupportedResTypes objs (one webapp resources has one
        # SupportedResTypes obj)
        for res_type in SupportedResTypes.objects.all():
            supported_flag = False
            for supported_type in res_type.supported_res_types.all():
                if content_model_str == supported_type.description.lower():
                    supported_flag = True
                    break

            if supported_flag:
                # reverse lookup: metadata obj --> res obj
                tool_res_obj = ToolResource.objects.get(
                    object_id=res_type.object_id)
                if tool_res_obj:
                    sharing_status_supported = False

                    supported_sharing_status_obj = tool_res_obj.metadata.\
                        supported_sharing_status.first()
                    if supported_sharing_status_obj is not None:
                        suppored_sharing_status_str = supported_sharing_status_obj.\
                                                      get_sharing_status_str()
                        if len(suppored_sharing_status_str) > 0:
                            res_sharing_status = content_model.raccess.sharing_status
                            if suppored_sharing_status_str.lower().\
                                    find(res_sharing_status.lower()) != -1:
                                sharing_status_supported = True
                    else:
                        # backward compatible: webapp without supported_sharing_status metadata
                        # is considered to support all sharing status
                        sharing_status_supported = True

                    if sharing_status_supported:
                        is_authorized = authorize(
                            request,
                            tool_res_obj.short_id,
                            needed_permission=ACTION_TO_AUTHORIZE.
                            VIEW_RESOURCE,
                            raises_exception=False)[1]
                        if is_authorized:
                            tool_url = tool_res_obj.metadata.url_bases.first().value \
                                if tool_res_obj.metadata.url_bases.first() else None
                            tool_icon_url = tool_res_obj.metadata.tool_icon.first().value \
                                if tool_res_obj.metadata.tool_icon.first() else "raise-img-error"
                            hs_term_dict_user = {}
                            hs_term_dict_user["HS_USR_NAME"] = request.user.username if \
                                request.user.is_authenticated() else "anonymous"
                            tool_url_new = parse_app_url_template(
                                tool_url, [
                                    content_model.get_hs_term_dict(),
                                    hs_term_dict_user
                                ])
                            if tool_url_new is not None:
                                tl = {
                                    'title':
                                    str(tool_res_obj.metadata.title.value),
                                    'icon_url': tool_icon_url,
                                    'url': tool_url_new
                                }
                                relevant_tools.append(tl)

    just_created = False
    just_copied = False
    create_resource_error = None
    just_published = False
    if request:
        validation_error = check_for_validation(request)

        just_created = request.session.get('just_created', False)
        if 'just_created' in request.session:
            del request.session['just_created']

        just_copied = request.session.get('just_copied', False)
        if 'just_copied' in request.session:
            del request.session['just_copied']

        create_resource_error = request.session.get('resource_creation_error',
                                                    None)
        if 'resource_creation_error' in request.session:
            del request.session['resource_creation_error']

        just_published = request.session.get('just_published', False)
        if 'just_published' in request.session:
            del request.session['just_published']

    bag_url = AbstractResource.bag_url(content_model.short_id)

    if user.is_authenticated():
        show_content_files = user.uaccess.can_view_resource(content_model)
    else:
        # if anonymous user getting access to a private resource (since resource is discoverable),
        # then don't show content files
        show_content_files = content_model.raccess.public

    allow_copy = can_user_copy_resource(content_model, user)

    # user requested the resource in READONLY mode
    if not resource_edit:
        temporal_coverages = content_model.metadata.coverages.all().filter(
            type='period')
        if len(temporal_coverages) > 0:
            temporal_coverage_data_dict = {}
            temporal_coverage = temporal_coverages[0]
            temporal_coverage_data_dict[
                'start_date'] = temporal_coverage.value['start']
            temporal_coverage_data_dict['end_date'] = temporal_coverage.value[
                'end']
            temporal_coverage_data_dict['name'] = temporal_coverage.value.get(
                'name', '')
        else:
            temporal_coverage_data_dict = None

        spatial_coverages = content_model.metadata.coverages.all().exclude(
            type='period')

        if len(spatial_coverages) > 0:
            spatial_coverage_data_dict = {}
            spatial_coverage = spatial_coverages[0]
            spatial_coverage_data_dict['name'] = spatial_coverage.value.get(
                'name', None)
            spatial_coverage_data_dict['units'] = spatial_coverage.value[
                'units']
            spatial_coverage_data_dict['zunits'] = spatial_coverage.value.get(
                'zunits', None)
            spatial_coverage_data_dict[
                'projection'] = spatial_coverage.value.get('projection', None)
            spatial_coverage_data_dict['type'] = spatial_coverage.type
            if spatial_coverage.type == 'point':
                spatial_coverage_data_dict['east'] = spatial_coverage.value[
                    'east']
                spatial_coverage_data_dict['north'] = spatial_coverage.value[
                    'north']
                spatial_coverage_data_dict[
                    'elevation'] = spatial_coverage.value.get(
                        'elevation', None)
            else:
                spatial_coverage_data_dict[
                    'northlimit'] = spatial_coverage.value['northlimit']
                spatial_coverage_data_dict[
                    'eastlimit'] = spatial_coverage.value['eastlimit']
                spatial_coverage_data_dict[
                    'southlimit'] = spatial_coverage.value['southlimit']
                spatial_coverage_data_dict[
                    'westlimit'] = spatial_coverage.value['westlimit']
                spatial_coverage_data_dict[
                    'uplimit'] = spatial_coverage.value.get('uplimit', None)
                spatial_coverage_data_dict[
                    'downlimit'] = spatial_coverage.value.get(
                        'downlimit', None)
        else:
            spatial_coverage_data_dict = None

        keywords = ",".join(
            [sub.value for sub in content_model.metadata.subjects.all()])
        languages_dict = dict(languages_iso.languages)
        language = languages_dict[content_model.metadata.language.code] if \
            content_model.metadata.language else None
        title = content_model.metadata.title.value if content_model.metadata.title else None
        abstract = content_model.metadata.description.abstract if \
            content_model.metadata.description else None

        missing_metadata_elements = content_model.metadata.get_required_missing_elements(
        )
        context = {
            'resource_edit_mode': resource_edit,
            'metadata_form': None,
            'citation': content_model.get_citation(),
            'title': title,
            'abstract': abstract,
            'creators': content_model.metadata.creators.all(),
            'contributors': content_model.metadata.contributors.all(),
            'temporal_coverage': temporal_coverage_data_dict,
            'spatial_coverage': spatial_coverage_data_dict,
            'language': language,
            'keywords': keywords,
            'rights': content_model.metadata.rights,
            'sources': content_model.metadata.sources.all(),
            'relations': content_model.metadata.relations.all(),
            'show_relations_section': show_relations_section(content_model),
            'fundingagencies': content_model.metadata.funding_agencies.all(),
            'metadata_status': metadata_status,
            'missing_metadata_elements': missing_metadata_elements,
            'validation_error': validation_error if validation_error else None,
            'resource_creation_error': create_resource_error,
            'relevant_tools': relevant_tools,
            'tool_homepage_url': tool_homepage_url,
            'file_type_error': file_type_error,
            'just_created': just_created,
            'just_copied': just_copied,
            'just_published': just_published,
            'bag_url': bag_url,
            'show_content_files': show_content_files,
            'discoverable': discoverable,
            'resource_is_mine': resource_is_mine,
            'allow_resource_copy': allow_copy,
            'is_resource_specific_tab_active': False,
            'belongs_to_collections': belongs_to_collections
        }

        if 'task_id' in request.session:
            task_id = request.session.get('task_id', None)
            if task_id:
                context['task_id'] = task_id
            del request.session['task_id']

        if 'download_path' in request.session:
            download_path = request.session.get('download_path', None)
            if download_path:
                context['download_path'] = download_path
            del request.session['download_path']

        return context

    # user requested the resource in EDIT MODE

    # whether the user has permission to change the model
    can_change = content_model.can_change(request)
    if not can_change:
        raise PermissionDenied()

    add_creator_modal_form = CreatorForm(allow_edit=can_change,
                                         res_short_id=content_model.short_id)
    add_contributor_modal_form = ContributorForm(
        allow_edit=can_change, res_short_id=content_model.short_id)
    add_relation_modal_form = RelationForm(allow_edit=can_change,
                                           res_short_id=content_model.short_id)
    add_source_modal_form = SourceForm(allow_edit=can_change,
                                       res_short_id=content_model.short_id)
    add_fundingagency_modal_form = FundingAgencyForm(
        allow_edit=can_change, res_short_id=content_model.short_id)

    keywords = ",".join(
        [sub.value for sub in content_model.metadata.subjects.all()])
    subjects_form = SubjectsForm(initial={'value': keywords},
                                 allow_edit=can_change,
                                 res_short_id=content_model.short_id,
                                 element_id=None)

    abstract_form = AbstractForm(
        instance=content_model.metadata.description,
        allow_edit=can_change,
        res_short_id=content_model.short_id,
        element_id=content_model.metadata.description.id
        if content_model.metadata.description else None)

    CreatorFormSetEdit = formset_factory(wraps(CreatorForm)(partial(
        CreatorForm, allow_edit=can_change)),
                                         formset=BaseCreatorFormSet,
                                         extra=0)

    creator_formset = CreatorFormSetEdit(
        initial=content_model.metadata.creators.all().values(),
        prefix='creator')
    index = 0

    # TODO: dont track index manually. use enumerate, or zip

    for creator_form in creator_formset.forms:
        creator_form.action = "/hsapi/_internal/%s/creator/%s/update-metadata/" % \
                              (content_model.short_id, creator_form.initial['id'])
        creator_form.number = creator_form.initial['id']
        index += 1

    ContributorFormSetEdit = formset_factory(wraps(ContributorForm)(partial(
        ContributorForm, allow_edit=can_change)),
                                             formset=BaseContributorFormSet,
                                             extra=0)
    contributor_formset = ContributorFormSetEdit(
        initial=content_model.metadata.contributors.all().values(),
        prefix='contributor')

    index = 0
    # TODO: dont track index manually. use enumerate, or zip
    for contributor_form in contributor_formset.forms:
        contributor_form.action = "/hsapi/_internal/%s/contributor/%s/update-metadata/" % \
                                  (content_model.short_id, contributor_form.initial['id'])
        contributor_form.number = contributor_form.initial['id']
        index += 1

    RelationFormSetEdit = formset_factory(wraps(RelationForm)(partial(
        RelationForm, allow_edit=can_change)),
                                          formset=BaseFormSet,
                                          extra=0)
    relation_formset = RelationFormSetEdit(
        initial=content_model.metadata.relations.all().values(),
        prefix='relation')

    for relation_form in relation_formset.forms:
        relation_form.action = "/hsapi/_internal/%s/relation/%s/update-metadata/" % \
                               (content_model.short_id, relation_form.initial['id'])
        relation_form.number = relation_form.initial['id']

    SourceFormSetEdit = formset_factory(wraps(SourceForm)(partial(
        SourceForm, allow_edit=can_change)),
                                        formset=BaseFormSet,
                                        extra=0)
    source_formset = SourceFormSetEdit(
        initial=content_model.metadata.sources.all().values(), prefix='source')

    for source_form in source_formset.forms:
        source_form.action = "/hsapi/_internal/%s/source/%s/update-metadata/" % \
                             (content_model.short_id, source_form.initial['id'])
        source_form.delete_modal_form = MetaDataElementDeleteForm(
            content_model.short_id, 'source', source_form.initial['id'])
        source_form.number = source_form.initial['id']

    FundingAgencyFormSetEdit = formset_factory(wraps(FundingAgencyForm)(
        partial(FundingAgencyForm, allow_edit=can_change)),
                                               formset=BaseFormSet,
                                               extra=0)
    fundingagency_formset = FundingAgencyFormSetEdit(
        initial=content_model.metadata.funding_agencies.all().values(),
        prefix='fundingagency')

    for fundingagency_form in fundingagency_formset.forms:
        action = "/hsapi/_internal/{}/fundingagnecy/{}/update-metadata/"
        action = action.format(content_model.short_id,
                               fundingagency_form.initial['id'])
        fundingagency_form.action = action
        fundingagency_form.number = fundingagency_form.initial['id']

    temporal_coverages = content_model.metadata.coverages.all().filter(
        type='period')
    temporal_coverage_data_dict = {}
    if len(temporal_coverages) > 0:
        temporal_coverage = temporal_coverages[0]
        temporal_coverage_data_dict['start'] = temporal_coverage.value['start']
        temporal_coverage_data_dict['end'] = temporal_coverage.value['end']
        temporal_coverage_data_dict['name'] = temporal_coverage.value.get(
            'name', '')
        temporal_coverage_data_dict['id'] = temporal_coverage.id
    else:
        temporal_coverage = None

    coverage_temporal_form = CoverageTemporalForm(
        initial=temporal_coverage_data_dict,
        allow_edit=can_change,
        res_short_id=content_model.short_id,
        element_id=temporal_coverage.id if temporal_coverage else None)

    spatial_coverages = content_model.metadata.coverages.all().exclude(
        type='period')
    spatial_coverage_data_dict = {'type': 'point'}
    if len(spatial_coverages) > 0:
        spatial_coverage = spatial_coverages[0]
        spatial_coverage_data_dict['name'] = spatial_coverage.value.get(
            'name', None)
        spatial_coverage_data_dict['units'] = spatial_coverage.value['units']
        spatial_coverage_data_dict['zunits'] = spatial_coverage.value.get(
            'zunits', None)
        spatial_coverage_data_dict['projection'] = spatial_coverage.value.get(
            'projection', None)
        spatial_coverage_data_dict['type'] = spatial_coverage.type
        spatial_coverage_data_dict['id'] = spatial_coverage.id
        if spatial_coverage.type == 'point':
            spatial_coverage_data_dict['east'] = spatial_coverage.value['east']
            spatial_coverage_data_dict['north'] = spatial_coverage.value[
                'north']
            spatial_coverage_data_dict[
                'elevation'] = spatial_coverage.value.get('elevation', None)
        else:
            spatial_coverage_data_dict['northlimit'] = spatial_coverage.value[
                'northlimit']
            spatial_coverage_data_dict['eastlimit'] = spatial_coverage.value[
                'eastlimit']
            spatial_coverage_data_dict['southlimit'] = spatial_coverage.value[
                'southlimit']
            spatial_coverage_data_dict['westlimit'] = spatial_coverage.value[
                'westlimit']
            spatial_coverage_data_dict['uplimit'] = spatial_coverage.value.get(
                'uplimit', None)
            spatial_coverage_data_dict[
                'downlimit'] = spatial_coverage.value.get('downlimit', None)
    else:
        spatial_coverage = None

    coverage_spatial_form = CoverageSpatialForm(
        initial=spatial_coverage_data_dict,
        allow_edit=can_change,
        res_short_id=content_model.short_id,
        element_id=spatial_coverage.id if spatial_coverage else None)

    metadata_form = ExtendedMetadataForm(
        resource_mode='edit' if can_change else 'view',
        extended_metadata_layout=extended_metadata_layout)

    context = {
        'resource_edit_mode':
        resource_edit,
        'metadata_form':
        metadata_form,
        'creator_formset':
        creator_formset,
        'add_creator_modal_form':
        add_creator_modal_form,
        'creator_profilelink_formset':
        None,
        'title':
        content_model.metadata.title,
        'abstract_form':
        abstract_form,
        'contributor_formset':
        contributor_formset,
        'add_contributor_modal_form':
        add_contributor_modal_form,
        'relation_formset':
        relation_formset,
        'add_relation_modal_form':
        add_relation_modal_form,
        'source_formset':
        source_formset,
        'add_source_modal_form':
        add_source_modal_form,
        'fundingagnency_formset':
        fundingagency_formset,
        'add_fundinagency_modal_form':
        add_fundingagency_modal_form,
        'coverage_temporal_form':
        coverage_temporal_form,
        'coverage_spatial_form':
        coverage_spatial_form,
        'spatial_coverage':
        spatial_coverage_data_dict,
        'subjects_form':
        subjects_form,
        'metadata_status':
        metadata_status,
        'missing_metadata_elements':
        content_model.metadata.get_required_missing_elements(),
        'citation':
        content_model.get_citation(),
        'extended_metadata_layout':
        extended_metadata_layout,
        'bag_url':
        bag_url,
        'current_user':
        user,
        'show_content_files':
        show_content_files,
        'validation_error':
        validation_error if validation_error else None,
        'discoverable':
        discoverable,
        'resource_is_mine':
        resource_is_mine,
        'relation_source_types':
        tuple((type_value, type_display)
              for type_value, type_display in Relation.SOURCE_TYPES
              if type_value != 'isReplacedBy' and type_value != 'isVersionOf'
              and type_value != 'hasPart'),
        'is_resource_specific_tab_active':
        False,
        'belongs_to_collections':
        belongs_to_collections
    }

    return context