From b00dfd3c9909cf6d1be5868fcf4b56d672b6fd04 Mon Sep 17 00:00:00 2001
From: Matthew Holloway
Date: Wed, 17 Jul 2024 12:31:00 +1200
Subject: [PATCH 01/17] feat: Overflow shadows
---
ietf/static/css/ietf.scss | 17 +++++++++++++++++
ietf/static/js/ietf.js | 25 ++++++++++++++++++++++++-
2 files changed, 41 insertions(+), 1 deletion(-)
diff --git a/ietf/static/css/ietf.scss b/ietf/static/css/ietf.scss
index 062358c0e2..5bd520f041 100644
--- a/ietf/static/css/ietf.scss
+++ b/ietf/static/css/ietf.scss
@@ -1188,3 +1188,20 @@ blockquote {
padding-left: 1rem;
border-left: solid 1px var(--bs-body-color);
}
+
+.overflow-shadows {
+ transition: box-shadow 0.5s;
+}
+
+.overflow-shadows--both {
+ box-shadow: inset 0px 21px 18px -20px var(--bs-body-color),
+ inset 0px -21px 18px -20px var(--bs-body-color);
+}
+
+.overflow-shadows--top-only {
+ box-shadow: inset 0px 21px 18px -20px var(--bs-body-color);
+}
+
+.overflow-shadows--bottom-only {
+ box-shadow: inset 0px -21px 18px -20px var(--bs-body-color);
+}
diff --git a/ietf/static/js/ietf.js b/ietf/static/js/ietf.js
index 74fd39a85f..dde00c6d1e 100644
--- a/ietf/static/js/ietf.js
+++ b/ietf/static/js/ietf.js
@@ -91,6 +91,27 @@ $(document)
// });
});
+function overflowShadows(el) {
+ function handleScroll(){
+ const canScrollUp = el.scrollTop > 0
+ const canScrollDown = el.offsetHeight + el.scrollTop < el.scrollHeight
+ el.classList.toggle("overflow-shadows--both", canScrollUp && canScrollDown)
+ el.classList.toggle("overflow-shadows--top-only", canScrollUp && !canScrollDown)
+ el.classList.toggle("overflow-shadows--bottom-only", !canScrollUp && canScrollDown)
+ }
+
+ el.addEventListener("scroll", handleScroll, {passive: true})
+ handleScroll()
+
+ const observer = new IntersectionObserver(handleScroll)
+ observer.observe(el) // el won't have scrollTop etc when hidden, so we need to recalculate when it's revealed
+
+ return () => {
+ el.removeEventListener("scroll", handleScroll)
+ observer.unobserve(el)
+ }
+}
+
$(document)
.ready(function () {
// load data for the menu
@@ -108,7 +129,7 @@ $(document)
}
attachTo.find(".dropdown-menu")
.remove();
- var menu = ['
If you enter the review below, the review will be sent
- to {% for addr in to %}{{ addr|linkify }}{% if not forloop.last %}, {% endif %}{% endfor %}{% if review_cc %}, with a CC to {% for addr in cc %}{{ addr|linkify }}{% if not forloop.last %}, {% endif %}{% endfor %}{% endif %}.
+ to {% for addr in review_to %}{{ addr|linkify }}{% if not forloop.last %}, {% endif %}{% endfor %}{% if review_cc %}, with a CC to {% for addr in review_cc %}{{ addr|linkify }}{% if not forloop.last %}, {% endif %}{% endfor %}{% endif %}.
{% elif assignment %}
From c5ca0ea40575d93c0963480c410c2c278e9fa068 Mon Sep 17 00:00:00 2001
From: Ryan Cross
Date: Sat, 20 Jul 2024 15:24:14 -0700
Subject: [PATCH 09/17] fix: force choice of From address in Announcement form.
Fixes #7679. (#7720)
---
ietf/secr/announcement/forms.py | 7 +++++--
ietf/secr/announcement/tests.py | 2 +-
2 files changed, 6 insertions(+), 3 deletions(-)
diff --git a/ietf/secr/announcement/forms.py b/ietf/secr/announcement/forms.py
index 3aacbfe622..3fe58bdaaa 100644
--- a/ietf/secr/announcement/forms.py
+++ b/ietf/secr/announcement/forms.py
@@ -42,8 +42,11 @@ def get_from_choices(user):
nomcom_choices = get_nomcom_choices(user)
if nomcom_choices:
addresses = list(addresses) + nomcom_choices
-
- return list(zip(addresses, addresses))
+
+ choices = list(zip(addresses, addresses))
+ if len(choices) > 1:
+ choices.insert(0, ('', '(Choose an option)'))
+ return choices
def get_nomcom_choices(user):
diff --git a/ietf/secr/announcement/tests.py b/ietf/secr/announcement/tests.py
index c50e997f97..c147c301b6 100644
--- a/ietf/secr/announcement/tests.py
+++ b/ietf/secr/announcement/tests.py
@@ -48,7 +48,7 @@ def test_main_announce_from(self):
r = self.client.get(url)
self.assertEqual(r.status_code, 200)
q = PyQuery(r.content)
- self.assertEqual(len(q('#id_frm option')),3)
+ self.assertEqual(len(q('#id_frm option')),4)
# IAB Chair
self.client.login(username="iab-chair", password="iab-chair+password")
From 363c01e711495cdfe8338c1c1de90255c7083243 Mon Sep 17 00:00:00 2001
From: Lars Eggert
Date: Sun, 21 Jul 2024 03:14:40 +0300
Subject: [PATCH 10/17] fix: Explicitly set `executable_path` for Selenium
(#7715)
* fix: Explicitly set `executable_path` for Selenium
So it finds `geckodriver` again.
* Minimize diff
* fix: use existing executable_name
Co-authored-by: Lars Eggert
---------
Co-authored-by: Robert Sparks
---
ietf/utils/jstest.py | 2 +-
1 file changed, 1 insertion(+), 1 deletion(-)
diff --git a/ietf/utils/jstest.py b/ietf/utils/jstest.py
index 07d6ed9dd0..157f97912b 100644
--- a/ietf/utils/jstest.py
+++ b/ietf/utils/jstest.py
@@ -30,7 +30,7 @@
print(" "+skip_message)
def start_web_driver():
- service = Service(log_output=f"{executable_name}.log", service_args=['--log-no-truncate'])
+ service = Service(executable_path=f"/usr/bin/{executable_name}", log_output=f"{executable_name}.log", service_args=['--log-no-truncate'])
options = Options()
options.add_argument("--headless")
os.environ["MOZ_REMOTE_SETTINGS_DEVTOOLS"] = "1"
From a3e4e634fce72ee1e9ef75f5f207408999f1a94b Mon Sep 17 00:00:00 2001
From: Sangho Na
Date: Mon, 22 Jul 2024 06:14:02 +1200
Subject: [PATCH 11/17] fix: Exclude replaced documents from IESG discusses
(#7712)
* fix: Exclude replaced documents from IESG discusses
* test: Add checks for filtering replaced IESG drafts
* chore: Improve replaced draft filter
---------
Co-authored-by: Paul Selkirk
---
ietf/iesg/tests.py | 9 +++++++++
ietf/iesg/views.py | 1 +
2 files changed, 10 insertions(+)
diff --git a/ietf/iesg/tests.py b/ietf/iesg/tests.py
index 7211a6bc06..4579316f22 100644
--- a/ietf/iesg/tests.py
+++ b/ietf/iesg/tests.py
@@ -52,6 +52,15 @@ def test_feed(self):
self.assertContains(r, draft.name)
self.assertContains(r, escape(pos.balloter.plain_name()))
+ # Mark draft as replaced
+ draft.set_state(State.objects.get(type="draft", slug="repl"))
+
+ r = self.client.get(urlreverse("ietf.iesg.views.discusses"))
+ self.assertEqual(r.status_code, 200)
+
+ self.assertNotContains(r, draft.name)
+ self.assertNotContains(r, escape(pos.balloter.plain_name()))
+
def test_milestones_needing_review(self):
draft = WgDraftFactory()
RoleFactory(name_id='ad',group=draft.group,person=Person.objects.get(user__username='ad'))
diff --git a/ietf/iesg/views.py b/ietf/iesg/views.py
index a219a6b5de..b67ef04a03 100644
--- a/ietf/iesg/views.py
+++ b/ietf/iesg/views.py
@@ -483,6 +483,7 @@ def discusses(request):
models.Q(states__type__in=("statchg", "conflrev"),
states__slug__in=("iesgeval", "defer")),
docevent__ballotpositiondocevent__pos__blocking=True)
+ possible_docs = possible_docs.exclude(states__in=State.objects.filter(type="draft", slug="repl"))
possible_docs = possible_docs.select_related("stream", "group", "ad").distinct()
docs = []
From aa36f481e13c99bc0865282a9e890e6b049cdb98 Mon Sep 17 00:00:00 2001
From: Sangho Na
Date: Mon, 22 Jul 2024 06:15:33 +1200
Subject: [PATCH 12/17] chore: Add additional log messages to directauth()
(#7716)
* chore: Add additional log messages to directauth()
* chore: Keep single log message for each successful response
---
ietf/api/views.py | 13 +++++++++----
1 file changed, 9 insertions(+), 4 deletions(-)
diff --git a/ietf/api/views.py b/ietf/api/views.py
index 6aaed4b6a9..62857bff54 100644
--- a/ietf/api/views.py
+++ b/ietf/api/views.py
@@ -429,6 +429,7 @@ def directauth(request):
data = None
if raw_data is None or data is None:
+ log.log("Request body is either missing or invalid")
return HttpResponse(json.dumps(dict(result="failure",reason="invalid post")), content_type='application/json')
authtoken = data.get('authtoken', None)
@@ -436,9 +437,11 @@ def directauth(request):
password = data.get('password', None)
if any([item is None for item in (authtoken, username, password)]):
+ log.log("One or more mandatory fields are missing: authtoken, username, password")
return HttpResponse(json.dumps(dict(result="failure",reason="invalid post")), content_type='application/json')
if not is_valid_token("ietf.api.views.directauth", authtoken):
+ log.log("Auth token provided is invalid")
return HttpResponse(json.dumps(dict(result="failure",reason="invalid authtoken")), content_type='application/json')
user_query = User.objects.filter(username__iexact=username)
@@ -449,18 +452,20 @@ def directauth(request):
# Note well that we are using user.username, not what was passed to the API.
- if user_query.count() == 1 and authenticate(username = user_query.first().username, password = password):
+ user_count = user_query.count()
+ if user_count == 1 and authenticate(username = user_query.first().username, password = password):
user = user_query.get()
if user_query.filter(person__isnull=True).count() == 1: # Can't inspect user.person direclty here
- log.log(f"Direct auth of personless user {user.pk}:{user.username}")
+ log.log(f"Direct auth success (personless user): {user.pk}:{user.username}")
else:
- log.log(f"Direct auth: {user.pk}:{user.person.plain_name()}")
+ log.log(f"Direct auth success: {user.pk}:{user.person.plain_name()}")
return HttpResponse(json.dumps(dict(result="success")), content_type='application/json')
- log.log(f"Direct auth failure: {username}")
+ log.log(f"Direct auth failure: {username} ({user_count} user(s) found)")
return HttpResponse(json.dumps(dict(result="failure", reason="authentication failed")), content_type='application/json')
else:
+ log.log(f"Request must be POST: {request.method} received")
return HttpResponse(status=405)
From d5ceb7b20d89ae0d5b8948c151f48c8ce4d546c9 Mon Sep 17 00:00:00 2001
From: Jennifer Richards
Date: Wed, 24 Jul 2024 14:20:18 -0700
Subject: [PATCH 13/17] fix: optional / for /person/merge/ URL (#7746)
---
ietf/person/urls.py | 2 +-
1 file changed, 1 insertion(+), 1 deletion(-)
diff --git a/ietf/person/urls.py b/ietf/person/urls.py
index f37d8b46cf..867646fe39 100644
--- a/ietf/person/urls.py
+++ b/ietf/person/urls.py
@@ -2,7 +2,7 @@
from ietf.utils.urls import url
urlpatterns = [
- url(r'^merge/$', views.merge),
+ url(r'^merge/?$', views.merge),
url(r'^search/(?P(person|email))/$', views.ajax_select2_search),
url(r'^(?P[0-9]+)/email.json$', ajax.person_email_json),
url(r'^(?P[^/]+)$', views.profile),
From b5ab4b66110ed0777dae170e87db9343876b2741 Mon Sep 17 00:00:00 2001
From: Robert Sparks
Date: Thu, 25 Jul 2024 15:31:53 -0700
Subject: [PATCH 14/17] chore: update test name fixture (#7751)
---
ietf/name/fixtures/names.json | 2 +-
1 file changed, 1 insertion(+), 1 deletion(-)
diff --git a/ietf/name/fixtures/names.json b/ietf/name/fixtures/names.json
index 913c6c987e..3eb2c38d6f 100644
--- a/ietf/name/fixtures/names.json
+++ b/ietf/name/fixtures/names.json
@@ -3464,7 +3464,7 @@
"parent_types": [],
"req_subm_approval": true,
"role_order": "[\n \"chair\",\n \"delegate\"\n]",
- "session_purposes": "[\n \"officehours\"\n]",
+ "session_purposes": "[\n \"officehours\",\n \"regular\"\n]",
"show_on_agenda": true
},
"model": "group.groupfeatures",
From 247361b7dd8550233991abaa289ca36241c8561f Mon Sep 17 00:00:00 2001
From: Jennifer Richards
Date: Tue, 30 Jul 2024 20:55:07 -0300
Subject: [PATCH 15/17] ci: better access logs+redirect auth URLs+fix
X-Request-Start header (#7700)
* fix: silence nginx healthcheck logs
* fix: nginx logs in JSON
* fix: typos in nginx conf
* refactor: repeat less nginx config
* fix: log more req headers from gunicorn
* fix: redirect auth->datatracker, not deny
* feat: log X-Forwarded-Proto
---
ietf/utils/jsonlogger.py | 8 ++++++++
k8s/auth.yaml | 3 +++
k8s/datatracker.yaml | 3 +++
k8s/kustomization.yaml | 1 +
k8s/nginx-auth.conf | 8 ++++++--
k8s/nginx-datatracker.conf | 6 +++++-
k8s/nginx-logging.conf | 20 ++++++++++++++++++++
7 files changed, 46 insertions(+), 3 deletions(-)
create mode 100644 k8s/nginx-logging.conf
diff --git a/ietf/utils/jsonlogger.py b/ietf/utils/jsonlogger.py
index a9eeb02ba9..9c7949fd58 100644
--- a/ietf/utils/jsonlogger.py
+++ b/ietf/utils/jsonlogger.py
@@ -24,3 +24,11 @@ def add_fields(self, log_record, record, message_dict):
log_record.setdefault("user_agent", record.args["a"])
log_record.setdefault("len_bytes", record.args["B"])
log_record.setdefault("duration_ms", record.args["M"])
+ log_record.setdefault("host", record.args["{host}i"])
+ log_record.setdefault("x_request_start", record.args["{x-request-start}i"])
+ log_record.setdefault("x_real_ip", record.args["{x-real-ip}i"])
+ log_record.setdefault("x_forwarded_for", record.args["{x-forwarded-for}i"])
+ log_record.setdefault("x_forwarded_proto", record.args["{x-forwarded-proto}i"])
+ log_record.setdefault("cf_connecting_ip", record.args["{cf-connecting-ip}i"])
+ log_record.setdefault("cf_connecting_ipv6", record.args["{cf-connecting-ipv6}i"])
+ log_record.setdefault("cf_ray", record.args["{cf-ray}i"])
diff --git a/k8s/auth.yaml b/k8s/auth.yaml
index 66627ed450..c35cdc8ac2 100644
--- a/k8s/auth.yaml
+++ b/k8s/auth.yaml
@@ -80,6 +80,9 @@ spec:
volumeMounts:
- name: nginx-tmp
mountPath: /tmp
+ - name: dt-cfg
+ mountPath: /etc/nginx/conf.d/00logging.conf
+ subPath: nginx-logging.conf
- name: dt-cfg
mountPath: /etc/nginx/conf.d/auth.conf
subPath: nginx-auth.conf
diff --git a/k8s/datatracker.yaml b/k8s/datatracker.yaml
index 9e1ead1a90..a8a9675687 100644
--- a/k8s/datatracker.yaml
+++ b/k8s/datatracker.yaml
@@ -80,6 +80,9 @@ spec:
volumeMounts:
- name: nginx-tmp
mountPath: /tmp
+ - name: dt-cfg
+ mountPath: /etc/nginx/conf.d/00logging.conf
+ subPath: nginx-logging.conf
- name: dt-cfg
mountPath: /etc/nginx/conf.d/datatracker.conf
subPath: nginx-datatracker.conf
diff --git a/k8s/kustomization.yaml b/k8s/kustomization.yaml
index ba8b8a5826..4b79f00753 100644
--- a/k8s/kustomization.yaml
+++ b/k8s/kustomization.yaml
@@ -3,6 +3,7 @@ namePrefix: dt-
configMapGenerator:
- name: files-cfgmap
files:
+ - nginx-logging.conf
- nginx-auth.conf
- nginx-datatracker.conf
- settings_local.py
diff --git a/k8s/nginx-auth.conf b/k8s/nginx-auth.conf
index 4cbc8a0a51..6dd5d6ed56 100644
--- a/k8s/nginx-auth.conf
+++ b/k8s/nginx-auth.conf
@@ -2,9 +2,13 @@ server {
listen 8080 default_server;
server_name _;
+ # Replace default "main" formatter with the ietfjson formatter from nginx-logging.conf
+ access_log /var/log/nginx/access.log ietfjson;
+
# Note that regex location matches take priority over non-regex "prefix" matches. Use regexes so that
# our deny all rule does not squelch the other locations.
location ~ ^/health/nginx$ {
+ access_log off;
return 200;
}
@@ -19,14 +23,14 @@ server {
# n.b. (?!...) is a negative lookahead group
location ~ ^(/(?!(api/openid/|accounts/login/|accounts/logout/|accounts/reset/|person/.*/photo|group/groupmenu.json)).*) {
- deny all;
+ return 302 https://datatracker.ietf.org$${keepempty}request_uri;
}
location / {
add_header Content-Security-Policy "default-src 'self' 'unsafe-inline' data: https://datatracker.ietf.org/ https://www.ietf.org/ http://ietf.org/ https://analytics.ietf.org https://static.ietf.org; frame-ancestors 'self' ietf.org *.ietf.org meetecho.com *.meetecho.com gather.town *.gather.town";
proxy_set_header Host $${keepempty}host;
proxy_set_header Connection close;
- proxy_set_header X-Request-Start "t=${msec}";
+ proxy_set_header X-Request-Start "t=$${keepempty}msec";
proxy_set_header X-Forwarded-For $${keepempty}proxy_add_x_forwarded_for;
proxy_set_header X-Real-IP $${keepempty}remote_addr;
proxy_pass http://localhost:8000;
diff --git a/k8s/nginx-datatracker.conf b/k8s/nginx-datatracker.conf
index 63c985463c..ff439fba6a 100644
--- a/k8s/nginx-datatracker.conf
+++ b/k8s/nginx-datatracker.conf
@@ -2,7 +2,11 @@ server {
listen 8080 default_server;
server_name _;
+ # Replace default "main" formatter with the ietfjson formatter from nginx-logging.conf
+ access_log /var/log/nginx/access.log ietfjson;
+
location /health/nginx {
+ access_log off;
return 200;
}
@@ -15,7 +19,7 @@ server {
add_header Content-Security-Policy "default-src 'self' 'unsafe-inline' data: https://datatracker.ietf.org/ https://www.ietf.org/ http://ietf.org/ https://analytics.ietf.org https://static.ietf.org; frame-ancestors 'self' ietf.org *.ietf.org meetecho.com *.meetecho.com";
proxy_set_header Host $${keepempty}host;
proxy_set_header Connection close;
- proxy_set_header X-Request-Start "t=${msec}";
+ proxy_set_header X-Request-Start "t=$${keepempty}msec";
proxy_set_header X-Forwarded-For $${keepempty}proxy_add_x_forwarded_for;
proxy_set_header X-Real-IP $${keepempty}remote_addr;
proxy_pass http://localhost:8000;
diff --git a/k8s/nginx-logging.conf b/k8s/nginx-logging.conf
new file mode 100644
index 0000000000..0938b0530e
--- /dev/null
+++ b/k8s/nginx-logging.conf
@@ -0,0 +1,20 @@
+# Define JSON log format - must be loaded before config that references it
+log_format ietfjson escape=json
+ '{'
+ '"time":"$${keepempty}time_iso8601",'
+ '"remote_ip":"$${keepempty}remote_addr",'
+ '"request":"$${keepempty}request",'
+ '"host":"$${keepempty}host",'
+ '"path":"$${keepempty}request_uri",'
+ '"method":"$${keepempty}request_method",'
+ '"status":"$${keepempty}status",'
+ '"len_bytes":"$${keepempty}body_bytes_sent",'
+ '"duration_ms":"$${keepempty}request_time",'
+ '"referer":"$${keepempty}http_referer",'
+ '"user_agent":"$${keepempty}http_user_agent",'
+ '"x_forwarded_for":"$${keepempty}http_x_forwarded_for",'
+ '"x_forwarded_proto":"$${keepempty}http_x_forwarded_proto",'
+ '"cf_connecting_ip":"$${keepempty}http_cf_connecting_ip",'
+ '"cf_connecting_ipv6":"$${keepempty}http_cf_connecting_ipv6",'
+ '"cf_ray":"$${keepempty}http_cf_ray"'
+ '}';
From fb1942a5386873eb48402fd274cc29c5877bf377 Mon Sep 17 00:00:00 2001
From: Matthew Holloway
Date: Fri, 2 Aug 2024 07:25:03 +1200
Subject: [PATCH 16/17] fix: Sort RFCs by date (#7766)
* fix: Sort RFCs by date
* fix: concluded wgs and bofs date sort #7350
---
ietf/static/js/list.js | 6 ++++--
ietf/templates/group/concluded_groups.html | 8 ++++----
ietf/templates/person/profile.html | 2 +-
3 files changed, 9 insertions(+), 7 deletions(-)
diff --git a/ietf/static/js/list.js b/ietf/static/js/list.js
index d7e9dc944b..c16111ba63 100644
--- a/ietf/static/js/list.js
+++ b/ietf/static/js/list.js
@@ -5,8 +5,10 @@ import {
function text_sort(a, b, options) {
function prep(e, options) {
- return $($.parseHTML(e.values()[options.valueName]))
- .text()
+ const el = $($.parseHTML(e.values()[options.valueName]));
+ const cell_el = e.elm.querySelector(`.${options.valueName}`)
+ const sort_by_number = cell_el?.getAttribute('data-sort-number')
+ return sort_by_number ?? el.text()
.trim()
.replaceAll(/\s+/g, ' ');
}
diff --git a/ietf/templates/group/concluded_groups.html b/ietf/templates/group/concluded_groups.html
index c748c2061b..725e8bd3cc 100644
--- a/ietf/templates/group/concluded_groups.html
+++ b/ietf/templates/group/concluded_groups.html
@@ -40,8 +40,8 @@ {{ label }}
Group |
Name |
- Start |
- Concluded |
+ Start |
+ Concluded |
@@ -51,8 +51,8 @@ {{ label }}
{{ g.acronym }}
{{ g.name }} |
- {{ g.start_date|date:"Y-m" }} |
- {{ g.conclude_date|date:"Y-m" }} |
+ {{ g.start_date|date:"Y-m" }} |
+ {{ g.conclude_date|date:"Y-m" }} |
{% endfor %}
diff --git a/ietf/templates/person/profile.html b/ietf/templates/person/profile.html
index 42e5d2e43a..1424f037a1 100644
--- a/ietf/templates/person/profile.html
+++ b/ietf/templates/person/profile.html
@@ -106,7 +106,7 @@
RFC {{ doc.rfc_number }}
|
- {{ doc.pub_date|date:"b Y"|title }} |
+ {{ doc.pub_date|date:"b Y"|title }} |
{{ doc.title|urlize_ietf_docs }} |
{% with doc.referenced_by_rfcs_as_rfc_or_draft.count as refbycount %}
From 06677a9863b541d2e322b2ec5fd1032035c175fd Mon Sep 17 00:00:00 2001
From: Jennifer Richards
Date: Thu, 1 Aug 2024 17:23:35 -0300
Subject: [PATCH 17/17] fix: require login to pdfize (#7775)
* fix: require login to pdfize
* fix: suppress "pdfized" button when it won't work
---
ietf/doc/views_doc.py | 6 ++++++
1 file changed, 6 insertions(+)
diff --git a/ietf/doc/views_doc.py b/ietf/doc/views_doc.py
index 42898d2098..dfef40e558 100644
--- a/ietf/doc/views_doc.py
+++ b/ietf/doc/views_doc.py
@@ -265,6 +265,8 @@ def document_main(request, name, rev=None, document_html=False):
can_change_stream = bool(can_edit or roles)
file_urls, found_types = build_file_urls(doc)
+ if not request.user.is_authenticated:
+ file_urls = [fu for fu in file_urls if fu[0] != "pdfized"]
content = doc.text_or_error() # pyflakes:ignore
content = markup_txt.markup(maybe_split(content, split=split_content))
@@ -406,6 +408,8 @@ def document_main(request, name, rev=None, document_html=False):
latest_revision = None
file_urls, found_types = build_file_urls(doc)
+ if not request.user.is_authenticated:
+ file_urls = [fu for fu in file_urls if fu[0] != "pdfized"]
content = doc.text_or_error() # pyflakes:ignore
content = markup_txt.markup(maybe_split(content, split=split_content))
@@ -1039,6 +1043,8 @@ def document_html(request, name, rev=None):
document_html=True,
)
+
+@login_required
def document_pdfized(request, name, rev=None, ext=None):
found = fuzzy_find_documents(name, rev)
|