def add_postal_reply_attachment(request, slug, message_id): foirequest = get_object_or_404(FoiRequest, slug=slug) try: message = FoiMessage.objects.get(request=foirequest, pk=int(message_id)) except (ValueError, FoiMessage.DoesNotExist): raise Http404 if not request.user.is_authenticated(): return render_403(request) if request.user != foirequest.user: return render_403(request) if not message.is_postal: return render_400(request) form = PostalAttachmentForm(request.POST, request.FILES) if form.is_valid(): scan = request.FILES["scan"] scan_name = scan.name.rsplit(".", 1) scan_name = ".".join([slugify(n) for n in scan_name]) try: att = FoiAttachment.objects.get(belongs_to=message, name=scan_name) status_message = _( "Your document was added to the message and replaced " "an existing attachment with the same name." ) except FoiAttachment.DoesNotExist: att = FoiAttachment(belongs_to=message, name=scan_name) status_message = _("Your document was added to the message as a " "new attachment.") att.size = scan.size att.filetype = scan.content_type att.file.save(scan_name, scan) att.approved = False att.save() messages.add_message(request, messages.SUCCESS, status_message) return redirect(message) messages.add_message(request, messages.ERROR, form._errors["scan"][0]) return render_400(request)
def add_postal_reply_attachment(request, slug, message_id): foirequest = get_object_or_404(FoiRequest, slug=slug) try: message = FoiMessage.objects.get(request=foirequest, pk=int(message_id)) except (ValueError, FoiMessage.DoesNotExist): raise Http404 if not request.user.is_authenticated(): return render_403(request) if request.user != foirequest.user: return render_403(request) if not message.is_postal: return render_400(request) form = PostalAttachmentForm(request.POST, request.FILES) if form.is_valid(): scan = request.FILES['scan'] scan_name = scan.name.rsplit(".", 1) scan_name = ".".join([slugify(n) for n in scan_name]) att = FoiAttachment(belongs_to=message, name=scan_name, size=scan.size, filetype=scan.content_type) att.file.save(scan_name, scan) att.approved = True att.save() messages.add_message(request, messages.SUCCESS, _('Your document was attached to the message.')) return HttpResponseRedirect(message.get_absolute_url()) messages.add_message(request, messages.ERROR, form._errors['scan'][0]) return render_400(request)
def mark_checked(request, slug): foirequest = get_object_or_404(FoiRequest, slug=slug) if not request.user.is_authenticated(): return render_403(request) if not request.user.is_staff: return render_403(request) foirequest.checked = True foirequest.save() messages.add_message(request, messages.SUCCESS, _("Request marked as checked.")) return redirect(foirequest)
def mark_not_foi(request, slug): foirequest = get_object_or_404(FoiRequest, slug=slug) if not request.user.is_authenticated(): return render_403(request) if not request.user.is_staff: return render_403(request) foirequest.is_foi = False foirequest.save() messages.add_message(request, messages.SUCCESS, _("Request marked as not a FoI request.")) return redirect(foirequest)
def mark_checked(request, slug): foirequest = get_object_or_404(FoiRequest, slug=slug) if not request.user.is_authenticated(): return render_403(request) if not request.user.is_staff: return render_403(request) foirequest.checked = True foirequest.save() messages.add_message(request, messages.SUCCESS, _('Request marked as checked.')) return HttpResponseRedirect(foirequest.get_absolute_url())
def approve_message(request, slug, message): foirequest = get_object_or_404(FoiRequest, slug=slug) if not request.user.is_authenticated(): return render_403(request) if not request.user.is_staff and foirequest.user != request.user: return render_403(request) mes = get_object_or_404(FoiMessage, id=int(message)) mes.content_hidden = False mes.save() messages.add_message(request, messages.SUCCESS, _("Content published.")) return redirect(mes.get_absolute_url())
def approve_attachment(request, slug, attachment): foirequest = get_object_or_404(FoiRequest, slug=slug) if not request.user.is_authenticated(): return render_403(request) if not request.user.is_staff and foirequest.user != request.user: return render_403(request) att = get_object_or_404(FoiAttachment, id=int(attachment)) att.approved = True att.save() messages.add_message(request, messages.SUCCESS, _('Attachment approved.')) return HttpResponseRedirect(att.get_absolute_url())
def resend_message(request, slug): foirequest = get_object_or_404(FoiRequest, slug=slug) if not request.user.is_authenticated(): return render_403(request) if not request.user.is_staff: return render_403(request) try: mes = FoiMessage.objects.get(sent=False, request=foirequest, pk=int(request.POST.get('message', 0))) except FoiMessage.DoesNotExist: raise Http404 mes.send(notify=False) return redirect('admin:foirequest_foimessage_change', mes.id)
def send_message(request, slug): foirequest = get_object_or_404(FoiRequest, slug=slug) if not request.user.is_authenticated(): return render_403(request) if request.user != foirequest.user: return render_403(request) form = SendMessageForm(foirequest, request.POST) if form.is_valid(): mes = form.save(request.user) messages.add_message(request, messages.SUCCESS, _("Your Message has been sent.")) return redirect(mes) else: return show(request, slug, context={"send_message_form": form}, status=400)
def approve_attachment(request, slug, attachment): foirequest = get_object_or_404(FoiRequest, slug=slug) if not request.user.is_authenticated(): return render_403(request) if not request.user.is_staff and foirequest.user != request.user: return render_403(request) att = get_object_or_404(FoiAttachment, id=int(attachment)) if not att.can_approve and not request.user.is_staff: return render_403(request) att.approve() att.save() messages.add_message(request, messages.SUCCESS, _("Attachment approved.")) return redirect(att.get_anchor_url())
def resend_message(request, slug): foirequest = get_object_or_404(FoiRequest, slug=slug) if not request.user.is_authenticated(): return render_403(request) if not request.user.is_staff: return render_403(request) try: mes = FoiMessage.objects.get(sent=False, request=foirequest, pk=int(request.POST.get("message", 0))) except (FoiMessage.DoesNotExist, ValueError): messages.add_message(request, messages.ERROR, _("Invalid input!")) return render_400(request) mes.send(notify=False) return redirect("admin:foirequest_foimessage_change", mes.id)
def escalation_message(request, slug): foirequest = get_object_or_404(FoiRequest, slug=slug) if not request.user.is_authenticated(): return render_403(request) if request.user != foirequest.user: return render_403(request) form = EscalationMessageForm(foirequest, request.POST) if form.is_valid(): form.save() messages.add_message(request, messages.SUCCESS, _('Your Escalation Message has been sent.')) return HttpResponseRedirect(foirequest.get_absolute_url()) else: return show(request, slug, context={"escalation_form": form}, status=400)
def send_message(request, slug): foirequest = get_object_or_404(FoiRequest, slug=slug) if not request.user.is_authenticated(): return render_403(request) if request.user != foirequest.user: return render_403(request) form = SendMessageForm(request.POST) if form.is_valid() and foirequest.replyable(): foirequest.add_message(request.user, **form.cleaned_data) messages.add_message(request, messages.SUCCESS, _('Your Message has been sent.')) return HttpResponseRedirect(foirequest.get_absolute_url()) else: return render_400(request)
def mark_not_foi(request, slug): foirequest = get_object_or_404(FoiRequest, slug=slug) if not request.user.is_authenticated: return render_403(request) if not request.user.is_staff: return render_403(request) foirequest.is_foi = False foirequest.public = False foirequest.visibility = FoiRequest.VISIBLE_TO_REQUESTER foirequest.save() if request.is_ajax(): return HttpResponse() messages.add_message(request, messages.SUCCESS, _('Request marked as not a FoI request.')) return redirect(foirequest)
def extend_deadline(request, slug): foirequest = get_object_or_404(FoiRequest, slug=slug) if not request.user.is_authenticated(): return render_403(request) if not request.user.is_staff: return render_403(request) months = int(request.POST.get('months', 6)) foirequest.due_date = foirequest.law.calculate_due_date(foirequest.due_date, months) if foirequest.due_date > timezone.now() and foirequest.status == 'overdue': foirequest.status = 'awaiting_response' foirequest.save() messages.add_message(request, messages.INFO, _('Deadline has been extended.')) FoiEvent.objects.create_event('deadline_extended', foirequest) return redirect(foirequest)
def make_same_request(request, slug, message_id): foirequest = get_object_or_404(FoiRequest, slug=slug) message = get_object_or_404(FoiMessage, id=int(message_id)) if not request.user.is_authenticated(): return render_403(request) if not foirequest == message.request: return render_400(request) if not message.not_publishable: return render_400(request) if foirequest.same_as is not None: foirequest = foirequest.same_as same_requests = FoiRequest.objects.filter(user=request.user, same_as=foirequest).count() if same_requests: messages.add_message(request, messages.ERROR, _("You already made an identical request")) return render_400(request) body = u"%s\n\n%s" % (foirequest.description, _('Please see this request on FragDenStaat.de where you granted access to this information: %(url)s') % {'url': foirequest.get_absolute_domain_short_url()}) fr = FoiRequest.from_request_form( request.user, foirequest.public_body, foirequest.law, form_data=dict( subject=foirequest.title, body=body, public=foirequest.public )) # Don't pass post_data, get default letter of law fr.same_as = foirequest fr.save() messages.add_message(request, messages.SUCCESS, _('You successfully requested this document! Your request is displayed below.')) return HttpResponseRedirect(fr.get_absolute_url())
def dashboard(request): if not request.user.is_staff: return render_403(request) context = {} user = {} start_date = timezone.utc.localize(datetime.datetime(2011, 7, 30)) for u in User.objects.filter(is_active=True, date_joined__gte=start_date): d = u.date_joined.date().isoformat() user.setdefault(d, 0) user[d] += 1 context["user"] = sorted( [{"date": k, "num": v, "symbol": "user"} for k, v in user.items()], key=lambda x: x["date"] ) total = 0 for user in context["user"]: total += user["num"] user["total"] = total foirequest = {} foi_query = FoiRequest.objects.filter(is_foi=True, public_body__isnull=False, first_message__gte=start_date) if request.GET.get("notsameas"): foi_query = foi_query.filter(same_as__isnull=True) if request.GET.get("public"): foi_query = foi_query.filter(public=True) for u in foi_query: d = u.first_message.date().isoformat() foirequest.setdefault(d, 0) foirequest[d] += 1 context["foirequest"] = sorted( [{"date": k, "num": v, "symbol": "user"} for k, v in foirequest.items()], key=lambda x: x["date"] ) total = 0 for req in context["foirequest"]: total += req["num"] req["total"] = total return render(request, "foirequest/dashboard.html", {"data": json.dumps(context)})
def delete_account(request): if not request.user.is_authenticated(): messages.add_message(request, messages.ERROR, _('You are not currently logged in, you cannot delete your account.')) return render_403(request) form = UserDeleteForm(request.user, request.POST) if not form.is_valid(): messages.add_message(request, messages.ERROR, _('Password or confirmation phrase were wrong. Account was not deleted.')) return account_settings( request, context={ 'user_delete_form': form }, status=400 ) # Removing all personal data from account user = request.user user.organization = '' user.organization_url = '' user.private = True user.address = '' user.save() user.first_name = '' user.last_name = '' user.is_active = False user.email = '' user.username = '******' % user.pk user.save() auth.logout(request) messages.add_message(request, messages.INFO, _('Your account has been deleted and you have been logged out.')) return redirect('/')
def change_email(request): if not request.user.is_authenticated(): messages.add_message(request, messages.ERROR, _('You are not currently logged in, you cannot change your email address.')) return render_403(request) if request.POST: form = UserChangeEmailForm(request.POST) if not form.is_valid(): messages.add_message(request, messages.ERROR, _('Your email address could not be changed.')) return account_settings( request, context={ 'change_email_form': form }, status=400 ) AccountManager(request.user).send_email_change_mail( form.cleaned_data['email'] ) messages.add_message(request, messages.SUCCESS, _('We sent a confirmation email to your new address. Please click the link in there.')) return redirect('account-settings') form = UserEmailConfirmationForm(request.user, request.GET) if form.is_valid(): form.save() messages.add_message(request, messages.SUCCESS, _('Your email address has been changed.')) else: messages.add_message(request, messages.ERROR, _('The email confirmation link was invalid or expired.')) return redirect('account-settings')
def download_foirequest_zip(request, slug): foirequest = get_object_or_404(FoiRequest, slug=slug) if not can_read_foirequest_authenticated(foirequest, request): return render_403(request) response = HttpResponse(package_foirequest(foirequest), content_type='application/zip') response['Content-Disposition'] = 'attachment; filename="%s.zip"' % foirequest.pk return response
def escalation_message(request, slug): foirequest = get_object_or_404(FoiRequest, slug=slug) if not request.user.is_authenticated(): return render_403(request) if request.user != foirequest.user: return render_403(request) if not foirequest.can_be_escalated(): messages.add_message(request, messages.ERROR, _("Your request cannot be escalated.")) return show(request, slug, status=400) form = EscalationMessageForm(foirequest, request.POST) if form.is_valid(): form.save() messages.add_message(request, messages.SUCCESS, _("Your Escalation Message has been sent.")) return redirect(foirequest) else: return show(request, slug, context={"escalation_form": form}, status=400)
def show(request, slug, template_name="foirequest/show.html", context=None, status=200): try: obj = FoiRequest.objects.select_related("public_body", "user", "user__profile", "law", "law__combined").get(slug=slug) except FoiRequest.DoesNotExist: raise Http404 if not obj.is_visible(request.user, pb_auth=request.session.get('pb_auth')): return render_403(request) all_attachments = FoiAttachment.objects.filter(belongs_to__request=obj).all() for message in obj.messages: message.request = obj message.all_attachments = filter(lambda x: x.belongs_to_id == message.id, all_attachments) events = FoiEvent.objects.filter(request=obj).select_related( "user", "user__profile", "request", "public_body").order_by("timestamp") event_count = len(events) last_index = event_count for message in reversed(obj.messages): message.events = [ev for ev in events[:last_index] if ev.timestamp >= message.timestamp] last_index = last_index - len(message.events) if context is None: context = {} context.update({"object": obj}) return render(request, template_name, context, status=status)
def dashboard(request): if not request.user.is_staff: return render_403(request) context = {} user = {} start_date = timezone.utc.localize(datetime.datetime(2011, 7, 30)) for u in User.objects.filter( date_joined__gte=start_date): d = u.date_joined.date().isoformat() user.setdefault(d, 0) user[d] += 1 context['user'] = sorted([{'date': k, 'num': v, 'symbol': 'user'} for k, v in user.items()], key=lambda x: x['date']) total = 0 for user in context['user']: total += user['num'] user['total'] = total foirequest = {} for u in FoiRequest.objects.filter( is_foi=True, public_body__isnull=False, first_message__gte=start_date): d = u.first_message.date().isoformat() foirequest.setdefault(d, 0) foirequest[d] += 1 context['foirequest'] = sorted([{'date': k, 'num': v, 'symbol': 'user'} for k, v in foirequest.items()], key=lambda x: x['date']) total = 0 for req in context['foirequest']: total += req['num'] req['total'] = total return render(request, 'foirequest/dashboard.html', {'data': json.dumps(context)})
def set_public_body(request, slug): foirequest = get_object_or_404(FoiRequest, slug=slug) if not request.user.is_authenticated() or request.user != foirequest.user: return render_403(request) try: public_body_pk = int(request.POST.get('suggestion', '')) except ValueError: messages.add_message(request, messages.ERROR, _('Missing or invalid input!')) return HttpResponseRedirect(foirequest.get_absolute_url()) try: public_body = PublicBody.objects.get(pk=public_body_pk) except PublicBody.DoesNotExist: messages.add_message(request, messages.ERROR, _('Missing or invalid input!')) return render_400(request) if not foirequest.needs_public_body(): messages.add_message(request, messages.ERROR, _("This request doesn't need a Public Body!")) return render_400(request) # FIXME: make foilaw dynamic foilaw = public_body.default_law foirequest.set_public_body(public_body, foilaw) messages.add_message(request, messages.SUCCESS, _("Request was sent to: %(name)s.") % {"name": public_body.name}) return HttpResponseRedirect(foirequest.get_absolute_url())
def download_foirequest(request, slug): foirequest = get_object_or_404(FoiRequest, slug=slug) if not request.user.is_staff and not request.user == foirequest.user: return render_403(request) response = HttpResponse(package_foirequest(foirequest), content_type="application/zip") response["Content-Disposition"] = 'attachment; filename="%s.zip"' % foirequest.pk return response
def redact_attachment(request, slug, attachment_id): foirequest = get_object_or_404(FoiRequest, slug=slug) if not request.user.is_staff and not request.user == foirequest.user: return render_403(request) attachment = get_object_or_404(FoiAttachment, pk=int(attachment_id), belongs_to__request=foirequest) if not attachment.can_approve and not request.user.is_staff: return render_403(request) already = None if attachment.redacted: already = attachment.redacted elif attachment.is_redacted: already = attachment if already is not None and not already.can_approve and not request.user.is_staff: return render_403(request) if request.method == 'POST': path = convert_to_pdf(request.POST) if path is None: return render_400(request) name = attachment.name.rsplit('.', 1)[0] name = re.sub('[^\w\.\-]', '', name) pdf_file = File(open(path, 'rb')) if already: att = already else: att = FoiAttachment( belongs_to=attachment.belongs_to, name=_('%s_redacted.pdf') % name, is_redacted=True, filetype='application/pdf', approved=True, can_approve=True ) att.file = pdf_file att.size = pdf_file.size att.approve_and_save() if not attachment.is_redacted: attachment.redacted = att attachment.can_approve = False attachment.approved = False attachment.save() return redirect(att.get_anchor_url()) return render(request, 'foirequest/redact.html', { 'foirequest': foirequest, 'attachment': attachment })
def csrf_failure(request, reason=""): return render_403( request, message=_( "You probably do not have cookies enabled, but you need cookies to use this site! Cookies are only ever sent securely. The technical reason is: %(reason)s" ) % {"reason": reason}, )
def auth(request, obj_id, code): foirequest = get_object_or_404(FoiRequest, pk=obj_id) if check_foirequest_auth_code(foirequest, code): request.session['pb_auth'] = code return redirect(foirequest) if can_read_foirequest(foirequest, request): return redirect(foirequest) return render_403(request)
def list_unchecked(request): if not request.user.is_staff: return render_403(request) foirequests = FoiRequest.published.filter(checked=False).order_by("-id")[:30] attachments = FoiAttachment.objects.filter( is_redacted=False, redacted__isnull=True, approved=False, can_approve=True ).order_by("-id")[:30] return render(request, "foirequest/list_unchecked.html", {"foirequests": foirequests, "attachments": attachments})
def list_unchecked(request): if not request.user.is_staff: return render_403(request) foirequests = FoiRequest.published.filter(checked=False).order_by('-id') attachments = FoiAttachment.objects.filter(approved=False).order_by('-id') return render(request, 'foirequest/list_unchecked.html', { 'foirequests': foirequests, 'attachments': attachments })
def escalation_message(request, slug): foirequest = get_object_or_404(FoiRequest, slug=slug) if not request.user.is_authenticated: return render_403(request) if request.user != foirequest.user: return render_403(request) if not foirequest.can_be_escalated(): messages.add_message(request, messages.ERROR, _('Your request cannot be escalated.')) return show(request, slug, status=400) form = EscalationMessageForm(foirequest, request.POST) if form.is_valid(): form.save() messages.add_message(request, messages.SUCCESS, _('Your Escalation Message has been sent.')) return redirect(foirequest) else: return show(request, slug, context={"escalation_form": form}, status=400)
def delete_attachment(request, slug, attachment): foirequest = get_object_or_404(FoiRequest, slug=slug) if not can_write_foirequest(foirequest, request): return render_403(request) att = get_object_or_404(FoiAttachment, id=int(attachment)) message = att.belongs_to if not message.is_postal: return render_403(request) if not att.can_delete: return render_403(request) if att.is_redacted: FoiAttachment.objects.filter(redacted=att).update(can_approve=True) att.remove_file_and_delete() if request.is_ajax(): if request.content_type == 'application/json': return JsonResponse({}) return HttpResponse() messages.add_message(request, messages.SUCCESS, _('Attachment deleted.')) return redirect(message.get_absolute_url())
def create_document(request, slug, attachment): foirequest = get_object_or_404(FoiRequest, slug=slug) if not can_write_foirequest(foirequest, request): return render_403(request) att = get_object_or_404(FoiAttachment, id=int(attachment)) if not att.can_approve and not request.user.is_staff: return render_403(request) if att.document is not None: return render_400(request) att.create_document() messages.add_message(request, messages.SUCCESS, _('Document created.')) if request.is_ajax(): return render(request, 'foirequest/snippets/attachment.html', { 'attachment': att, 'object': foirequest }) return redirect(att.get_anchor_url())
def confirm(request): if not request.user.is_authenticated(): return render_403(request) if not request.user.is_staff and not request.user.is_superuser: return render_403(request) try: pb = get_object_or_404(PublicBody, pk=int(request.POST.get('public_body', ''))) except ValueError: return render_400(request) result = pb.confirm() if result is None: messages.add_message(request, messages.ERROR, _('This request was already confirmed.')) else: messages.add_message(request, messages.ERROR, ungettext('%(count)d message was sent.', '%(count)d messages were sent', result ) % {"count": result}) return HttpResponseRedirect( urlresolvers.reverse('admin:publicbody_publicbody_change', args=(pb.id,)))
def change_address(request): if not request.user.is_authenticated(): messages.add_message(request, messages.ERROR, _('You are not currently logged in, you cannot change your address.')) return render_403(request) form = UserChangeAddressForm(request.user.get_profile(), request.POST) if form.is_valid(): form.save() messages.add_message(request, messages.SUCCESS, _('Your address has been changed.')) return redirect('account-show') return show(request, context={"address_change_form": form}, status=400)
def show(request, slug, **kwargs): try: obj = FoiRequest.objects.select_related( "public_body", "user", "law").prefetch_related('tags').get(slug=slug) except FoiRequest.DoesNotExist: raise Http404 if not can_read_foirequest(obj, request): return render_403(request) return show_foirequest(request, obj, **kwargs)
def publicbody_upload(request, obj_id, code): from .message import get_uppy_i18n foirequest = get_object_or_404(FoiRequest, id=obj_id, closed=False) if not check_foirequest_upload_code(foirequest, code): return render_403(request) # Not for authenticated users if request.user.is_authenticated: # Don't leak slug, so go to short url return redirect(foirequest.get_absolute_short_url()) if request.method == 'POST': token = request.session.get('upload_auth') if not token: messages.add_message( request, messages.ERROR, _('A session error occurred while authenticating your ' 'uploads. Please contact administrators.')) return redirect(request.get_full_path()) uploader = PublicBodyUploader(foirequest, token) upload_list = request.POST.getlist('upload') att_count = uploader.create_upload_message(upload_list) messages.add_message( request, messages.SUCCESS, _('%s files were uploaded successfully. Thank you!') % att_count) return redirect(request.get_full_path()) if 'upload_auth' not in request.session: request.session['upload_auth'] = str(uuid.uuid4()) config = json.dumps({ 'settings': { 'tusChunkSize': settings.DATA_UPLOAD_MAX_MEMORY_SIZE - (500 * 1024) }, 'i18n': { 'uppy': get_uppy_i18n(), 'createResponse': _('Create response now'), 'sureCancel': _('You have not completed this process. ' 'Are you sure you want to cancel?') }, 'url': { 'tusEndpoint': reverse('api:upload-list'), } }) return render(request, 'foirequest/publicbody_upload.html', { 'foirequest': foirequest, 'config': config })
def reset_token(request): if not request.user.is_authenticated: return render_403(request) form = ResetTokenForm(data=request.POST, user=request.user) if form.is_valid(): message = form.save() messages.add_message(request, messages.SUCCESS, message) else: messages.add_message(request, messages.ERROR, _('Failed to reset token.')) return get_redirect(request)
def change_password(request): if not request.user.is_authenticated(): messages.add_message(request, messages.ERROR, _('You are not currently logged in, you cannot change your password.')) return render_403(request) form = request.user.get_password_change_form(request.POST) if form.is_valid(): form.save() messages.add_message(request, messages.SUCCESS, _('Your password has been changed.')) return redirect('account-show') return account_settings(request, context={"password_change_form": form}, status=400)
def send_message(request, slug): foirequest = get_object_or_404(FoiRequest, slug=slug) if not request.user.is_authenticated: return render_403(request) if request.user != foirequest.user: return render_403(request) form = SendMessageForm(foirequest, request.POST) throttle_message = check_throttle(foirequest.user, FoiMessage) if throttle_message: form.add_error(None, throttle_message) if form.is_valid(): mes = form.save(request.user) messages.add_message(request, messages.SUCCESS, _('Your Message has been sent.')) return redirect(mes) else: return show(request, slug, context={"send_message_form": form}, status=400)
def approve_attachment(request, slug, attachment): foirequest = get_object_or_404(FoiRequest, slug=slug) if not can_write_foirequest(foirequest, request): return render_403(request) att = get_object_or_404(FoiAttachment, id=int(attachment)) if not att.can_approve and not request.user.is_staff: return render_403(request) # hard guard against publishing of non publishable requests if not foirequest.not_publishable: att.approve_and_save() if request.is_ajax(): if request.content_type == 'application/json': return JsonResponse({}) return render(request, 'foirequest/snippets/attachment.html', { 'attachment': att, 'object': foirequest }) messages.add_message(request, messages.SUCCESS, _('Attachment approved.')) return redirect(att.get_anchor_url())
def set_summary(request, slug): foirequest = get_object_or_404(FoiRequest, slug=slug) if not request.user.is_authenticated() or request.user != foirequest.user: return render_403(request) if not foirequest.status_is_final(): return render_400(request) summary = request.POST.get('summary', None) if summary is None: return render_400(request) foirequest.summary = summary foirequest.save() messages.add_message(request, messages.SUCCESS, _('The outcome summary has been saved.')) return redirect(foirequest)
def set_status(request, slug): foirequest = get_object_or_404(FoiRequest, slug=slug) if not request.user.is_authenticated() or request.user != foirequest.user: return render_403(request) form = FoiRequestStatusForm(foirequest, request.POST) if form.is_valid(): form.set_status() messages.add_message(request, messages.SUCCESS, _('Status of request has been updated.')) else: messages.add_message(request, messages.ERROR, _('Invalid value for form submission!')) return show(request, slug, context={"status_form": form}, status=400) return redirect(foirequest.get_absolute_url() + '#-')
def auth_message_attachment(request, message_id, attachment_name): ''' nginx auth view ''' message = get_object_or_404(FoiMessage, id=int(message_id)) attachment = get_object_or_404(FoiAttachment, belongs_to=message, name=attachment_name) foirequest = message.request pb_auth = request.session.get('pb_auth') if not foirequest.is_visible(request.user, pb_auth=pb_auth): return render_403(request) if not attachment.is_visible(request.user, foirequest): return render_403(request) response = HttpResponse() response['Content-Type'] = "" response[ 'X-Accel-Redirect'] = X_ACCEL_REDIRECT_PREFIX + attachment.get_internal_url( ) return response
def report_problem(request, message_pk): message = get_object_or_404(FoiMessage, pk=message_pk) if not request.user.is_authenticated: return render_403(request) form = ProblemReportForm(data=request.POST, user=request.user, message=message) if form.is_valid(): form.save() else: messages.add_message(request, messages.ERROR, _('Your report could not be created.')) return redirect(message)
def list_unchecked(request): if not request.user.is_staff: return render_403(request) foirequests = FoiRequest.published.filter( checked=False).order_by('-id')[:30] attachments = FoiAttachment.objects.filter( is_redacted=False, redacted__isnull=True, approved=False, can_approve=True).order_by('-id')[:30] return render(request, 'foirequest/list_unchecked.html', { 'foirequests': foirequests, 'attachments': attachments })
def import_csv(request): if not request.user.is_authenticated: return render_403(request) if not request.user.is_staff and not request.user.is_superuser: return render_403(request) if not request.method == 'POST': return render_403(request) importer = CSVImporter() url = request.POST.get('url') csv_file = request.FILES.get('file') try: if not url and not csv_file: raise ValueError(_('You need to provide a url or a file.')) if url: importer.import_from_url(url) else: importer.import_from_file(csv_file) except Exception as e: messages.add_message(request, messages.ERROR, str(e)) else: messages.add_message(request, messages.SUCCESS, _('Public Bodies were imported.')) return redirect('admin:publicbody_publicbody_changelist')
def add_postal_reply_attachment(request, slug, message_id): foirequest = get_object_or_404(FoiRequest, slug=slug) try: message = FoiMessage.objects.get(request=foirequest, pk=int(message_id)) except (ValueError, FoiMessage.DoesNotExist): raise Http404 if not request.user.is_authenticated(): return render_403(request) if request.user != foirequest.user: return render_403(request) if not message.is_postal: return render_400(request) form = PostalAttachmentForm(request.POST, request.FILES) if form.is_valid(): scan = request.FILES['scan'] scan_name = scan.name.rsplit(".", 1) scan_name = ".".join([slugify(n) for n in scan_name]) try: att = FoiAttachment.objects.get(belongs_to=message, name=scan_name) status_message = _( 'Your document was added to the message and replaced ' 'an existing attachment with the same name.') except FoiAttachment.DoesNotExist: att = FoiAttachment(belongs_to=message, name=scan_name) status_message = _('Your document was added to the message as a ' 'new attachment.') att.size = scan.size att.filetype = scan.content_type att.file.save(scan_name, scan) att.approved = False att.save() messages.add_message(request, messages.SUCCESS, status_message) return redirect(message) messages.add_message(request, messages.ERROR, form._errors['scan'][0]) return render_400(request)
def change_email(request): if not request.user.is_authenticated(): messages.add_message(request, messages.ERROR, _('You are not currently logged in, you cannot change your email address.')) return render_403(request) form = UserEmailConfirmationForm(request.user, request.GET) if form.is_valid(): form.save() messages.add_message(request, messages.SUCCESS, _('Your email address has been changed.')) else: messages.add_message(request, messages.ERROR, _('The email confirmation link was invalid or expired.')) return redirect('account-settings')
def set_law(request, slug): foirequest = get_object_or_404(FoiRequest, slug=slug) if not request.user.is_authenticated() or request.user != foirequest.user: return render_403(request) if not foirequest.response_messages(): return render_400(request) if not foirequest.law.meta: return render_400(request) form = ConcreteLawForm(foirequest, request.POST) if not form.is_valid(): return render_400(request) form.save() messages.add_message(request, messages.SUCCESS, _('A concrete law has been set for this request.')) return redirect(foirequest)
def rerun_rules(request, message_id): if not request.user.is_staff: return render_403(request) message = get_object_or_404(FoiMessage, id=message_id) notify = False if request.POST.get('notify'): notify = True run_guidance(message, active_only=False, notify=notify) messages.add_message(request, messages.SUCCESS, _('Guidance refreshed for message.')) return redirect(message)
def add_postal_reply(request, slug): foirequest = get_object_or_404(FoiRequest, slug=slug) if not request.user.is_authenticated() or request.user != foirequest.user: return render_403(request) if not foirequest.public_body: return render_400(request) form = PostalReplyForm(request.POST, request.FILES) if form.is_valid(): message = FoiMessage(request=foirequest, is_response=True, is_postal=True, sender_name=form.cleaned_data['sender'], sender_public_body=foirequest.public_body) # TODO: Check if timezone support is correct date = datetime.datetime.combine(form.cleaned_data['date'], datetime.time()) message.timestamp = timezone.get_current_timezone().localize(date) message.subject = form.cleaned_data.get('subject', '') message.subject_redacted = message.redact_subject()[:250] message.plaintext = "" if form.cleaned_data.get('text'): message.plaintext = form.cleaned_data.get('text') message.plaintext_redacted = message.get_content() message.not_publishable = form.cleaned_data['not_publishable'] message.save() foirequest.last_message = message.timestamp foirequest.status = 'awaiting_classification' foirequest.save() foirequest.add_postal_reply.send(sender=foirequest) if form.cleaned_data.get('scan'): scan = request.FILES['scan'] scan_name = scan.name.rsplit(".", 1) scan_name = ".".join([slugify(n) for n in scan_name]) att = FoiAttachment(belongs_to=message, name=scan_name, size=scan.size, filetype=scan.content_type) att.file.save(scan_name, scan) att.approved = False att.save() messages.add_message(request, messages.SUCCESS, _('A postal reply was successfully added!')) return redirect(message) messages.add_message(request, messages.ERROR, _('There were errors with your form submission!')) return show(request, slug, context={"postal_reply_form": form}, status=400)
def dashboard(request): if not request.user.is_staff: return render_403(request) context = {} user = {} start_date = timezone.utc.localize(datetime.datetime(2011, 7, 30)) for u in User.objects.filter(is_active=True, date_joined__gte=start_date): d = u.date_joined.date().isoformat() d = '-'.join(d.split('-')[:2]) + '-01' user.setdefault(d, 0) user[d] += 1 context['user'] = sorted([{ 'date': k, 'num': v, 'symbol': 'user' } for k, v in user.items()], key=lambda x: x['date']) total = 0 for user in context['user']: total += user['num'] user['total'] = total foirequest = {} foi_query = FoiRequest.objects.filter(is_foi=True, public_body__isnull=False, first_message__gte=start_date) if request.GET.get('notsameas'): foi_query = foi_query.filter(same_as__isnull=True) if request.GET.get('public'): foi_query = foi_query.filter( visibility=FoiRequest.VISIBILITY.VISIBLE_TO_PUBLIC) for u in foi_query: d = u.first_message.date().isoformat() d = '-'.join(d.split('-')[:2]) + '-01' foirequest.setdefault(d, 0) foirequest[d] += 1 context['foirequest'] = sorted([{ 'date': k, 'num': v, 'symbol': 'user' } for k, v in foirequest.items()], key=lambda x: x['date']) total = 0 for req in context['foirequest']: total += req['num'] req['total'] = total return render(request, 'foirequest/dashboard.html', {'data': json.dumps(context)})
def add_postal_reply( request, slug, form_class=PostalReplyForm, success_message=_('A postal reply was successfully added!'), error_message=_('There were errors with your form submission!'), form_key='"postal_reply_form"'): foirequest = get_object_or_404(FoiRequest, slug=slug) if not request.user.is_authenticated or request.user != foirequest.user: return render_403(request) if not foirequest.public_body: return render_400(request) form = form_class(request.POST, request.FILES, foirequest=foirequest) if form.is_valid(): message = form.save() messages.add_message(request, messages.SUCCESS, success_message) return redirect(message) messages.add_message(request, messages.ERROR, error_message) return show(request, slug, context={form_key: form}, status=400)
def request_crowdfunding(request, pk): foirequest = get_object_or_404(FoiRequest, pk=pk) if not can_write_foirequest(foirequest, request): return render_403(request) if request.method == 'POST': form = CrowdfundingRequestStartForm(data=request.POST, user=request.user, foirequest=foirequest) if form.is_valid(): obj = form.save() messages.add_message( request, messages.SUCCESS, _('Your crowdfunding campaign ' 'has been submitted for approval.')) context = { 'user': obj.user, 'crowdfunding': obj, 'site_name': settings.SITE_NAME, } send_template_email( user=obj.user, subject=_('💸 Your crowdfunding project has been created'), template='froide_crowdfunding/emails/needs_approval.txt', context=context) mail_managers( _('Crowdfunding project needs approval'), settings.SITE_URL + reverse('admin:froide_crowdfunding_crowdfunding_change', args=(obj.pk, ))) return redirect(foirequest) else: messages.add_message(request, messages.ERROR, _('Your form contained errors.')) else: form = CrowdfundingRequestStartForm(user=request.user, foirequest=foirequest) return render(request, 'froide_crowdfunding/request_crowdfunding.html', context={ "crowdfunding_form": form, 'object': foirequest, })
def start_contribution(request, pk, form_class=ContributionForm, extra_context=None): crowdfunding = get_object_or_404(Crowdfunding, pk=pk) if crowdfunding.status != 'running': return render_403(request) user = None if request.user.is_authenticated: user = request.user form_kwargs = {'crowdfunding': crowdfunding, 'user': user} status = 200 if request.method == 'POST': form = form_class(data=request.POST, **form_kwargs) if form.is_valid(): order, contribution = form.save() data = form.cleaned_data payment_url = order.get_absolute_payment_url(data['method']) return redirect(payment_url) status = 400 else: form = form_class(**form_kwargs) context = { 'form': form, 'crowdfunding_contribute_urlname': ('crowdfunding:crowdfunding-start_contribution'), 'crowdfunding': crowdfunding } if extra_context is not None: context.update(extra_context) return render(request, 'froide_crowdfunding/contribute.html', context, status=status)
def auth_message_attachment(request, message_id, attachment_name): ''' nginx auth view ''' message = get_object_or_404(FoiMessage, id=int(message_id)) attachment = get_object_or_404(FoiAttachment, belongs_to=message, name=attachment_name) foirequest = message.request if settings.FOI_MEDIA_TOKENS: return auth_attachment_with_token(request, foirequest, attachment) if not has_attachment_access(request, foirequest, attachment): return render_403(request) if not settings.USE_X_ACCEL_REDIRECT: if not settings.DEBUG: logger.warn('Django should not serve files in production!') return serve(request, attachment.file.name, settings.MEDIA_ROOT) return send_attachment_file(attachment)
def change_password(request): if not request.user.is_authenticated: messages.add_message( request, messages.ERROR, _('You are not currently logged in, you cannot change your password.' )) return render_403(request) form = request.user.get_password_change_form(request.POST) if form.is_valid(): form.save() auth.update_session_auth_hash(request, form.user) messages.add_message(request, messages.SUCCESS, _('Your password has been changed.')) return get_redirect(request, default=reverse('account-show')) else: messages.add_message( request, messages.ERROR, _('Your password was NOT changed. Please fix the errors.')) return account_settings(request, context={"password_change_form": form}, status=400)
def show_attachment(request, slug, message_id, attachment_name): foirequest = get_object_or_404(FoiRequest, slug=slug) message = get_object_or_404(FoiMessage, id=int(message_id), request=foirequest) attachment = get_object_or_404(FoiAttachment, belongs_to=message, name=attachment_name) if not has_attachment_access(request, foirequest, attachment): return render_403(request) if attachment.document is not None and attachment.document.public: return redirect(attachment.document) attachment_url = get_accessible_attachment_url(foirequest, attachment) return render(request, 'foirequest/attachment/show.html', { 'attachment': attachment, 'attachment_url': attachment_url, 'message': message, 'foirequest': foirequest })
def create_document(request, foirequest, attachment): att = get_object_or_404( FoiAttachment, id=int(attachment), belongs_to__request=foirequest ) if not att.can_approve and not request.user.is_staff: return render_403(request) if (att.redacted or att.converted or att.document is not None or not att.is_pdf): return render_400(request) doc = att.create_document() if request.is_ajax(): return JsonResponse({ 'resource_uri': reverse('api:document-detail', kwargs={'pk': doc.id}), }) messages.add_message(request, messages.SUCCESS, _('Document created.')) return redirect(att.get_anchor_url())