Skip to content

Commit

Permalink
Merge branch 'ietf-tools:main' into add-copyrights
Browse files Browse the repository at this point in the history
  • Loading branch information
richsalz authored Aug 6, 2024
2 parents b908971 + 9ef7bff commit 6291871
Show file tree
Hide file tree
Showing 32 changed files with 294 additions and 178 deletions.
2 changes: 1 addition & 1 deletion README.md
Original file line number Diff line number Diff line change
Expand Up @@ -81,7 +81,7 @@ Many developers are using [VS Code](https://code.visualstudio.com/) and taking a
If VS Code is not available to you, in your clone, type `cd docker; ./run`
Once the containers are started, run the tests to make sure your checkout is a good place to start from (all tests should pass - if any fail, ask for help at tools-develop@). Inside the app container's shell type:
Once the containers are started, run the tests to make sure your checkout is a good place to start from (all tests should pass - if any fail, ask for help at tools-help@). Inside the app container's shell type:
```sh
ietf/manage.py test --settings=settings_test
```
Expand Down
13 changes: 9 additions & 4 deletions ietf/api/views.py
Original file line number Diff line number Diff line change
Expand Up @@ -429,16 +429,19 @@ 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)
username = data.get('username', None)
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)
Expand All @@ -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)


Expand Down
7 changes: 7 additions & 0 deletions ietf/doc/tests.py
Original file line number Diff line number Diff line change
Expand Up @@ -3013,6 +3013,13 @@ def test_pdfized(self):
with (Path(dir) / f'{draft.name}-{r:02d}.txt').open('w') as f:
f.write('text content')

self.assertTrue(
login_testing_unauthorized(
self,
PersonFactory().user.username,
urlreverse(self.view, kwargs={"name": draft.name}),
)
)
self.should_succeed(dict(name=rfc.name))
self.should_succeed(dict(name=draft.name))
for r in range(0,2):
Expand Down
14 changes: 7 additions & 7 deletions ietf/doc/views_doc.py
Original file line number Diff line number Diff line change
Expand Up @@ -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))

Expand Down Expand Up @@ -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))

Expand Down Expand Up @@ -603,12 +607,7 @@ def document_main(request, name, rev=None, document_html=False):
additional_urls = doc.documenturl_set.exclude(tag_id='auth48')

# Stream description and name passing test
if doc.stream != None:
stream_desc = doc.stream.desc
stream = "draft-stream-" + doc.stream.slug
else:
stream_desc = "(None)"
stream = "(None)"
stream = ("draft-stream-" + doc.stream.slug) if doc.stream != None else "(None)"

html = None
js = None
Expand Down Expand Up @@ -647,7 +646,6 @@ def document_main(request, name, rev=None, document_html=False):
revisions=simple_diff_revisions if document_html else revisions,
snapshot=snapshot,
stream=stream,
stream_desc=stream_desc,
latest_revision=latest_revision,
latest_rev=latest_rev,
can_edit=can_edit,
Expand Down Expand Up @@ -1039,6 +1037,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)
Expand Down
79 changes: 65 additions & 14 deletions ietf/group/views.py
Original file line number Diff line number Diff line change
Expand Up @@ -334,35 +334,86 @@ def chartering_groups(request):
dict(charter_states=charter_states,
group_types=group_types))


def concluded_groups(request):
sections = OrderedDict()

sections['WGs'] = Group.objects.filter(type='wg', state="conclude").select_related("state", "charter").order_by("parent__name","acronym")
sections['RGs'] = Group.objects.filter(type='rg', state="conclude").select_related("state", "charter").order_by("parent__name","acronym")
sections['BOFs'] = Group.objects.filter(type='wg', state="bof-conc").select_related("state", "charter").order_by("parent__name","acronym")
sections['AGs'] = Group.objects.filter(type='ag', state="conclude").select_related("state", "charter").order_by("parent__name","acronym")
sections['RAGs'] = Group.objects.filter(type='rag', state="conclude").select_related("state", "charter").order_by("parent__name","acronym")
sections['Directorates'] = Group.objects.filter(type='dir', state="conclude").select_related("state", "charter").order_by("parent__name","acronym")
sections['Review teams'] = Group.objects.filter(type='review', state="conclude").select_related("state", "charter").order_by("parent__name","acronym")
sections['Teams'] = Group.objects.filter(type='team', state="conclude").select_related("state", "charter").order_by("parent__name","acronym")
sections['Programs'] = Group.objects.filter(type='program', state="conclude").select_related("state", "charter").order_by("parent__name","acronym")
sections["WGs"] = (
Group.objects.filter(type="wg", state="conclude")
.select_related("state", "charter")
.order_by("parent__name", "acronym")
)
sections["RGs"] = (
Group.objects.filter(type="rg", state="conclude")
.select_related("state", "charter")
.order_by("parent__name", "acronym")
)
sections["BOFs"] = (
Group.objects.filter(type="wg", state="bof-conc")
.select_related("state", "charter")
.order_by("parent__name", "acronym")
)
sections["AGs"] = (
Group.objects.filter(type="ag", state="conclude")
.select_related("state", "charter")
.order_by("parent__name", "acronym")
)
sections["RAGs"] = (
Group.objects.filter(type="rag", state="conclude")
.select_related("state", "charter")
.order_by("parent__name", "acronym")
)
sections["Directorates"] = (
Group.objects.filter(type="dir", state="conclude")
.select_related("state", "charter")
.order_by("parent__name", "acronym")
)
sections["Review teams"] = (
Group.objects.filter(type="review", state="conclude")
.select_related("state", "charter")
.order_by("parent__name", "acronym")
)
sections["Teams"] = (
Group.objects.filter(type="team", state="conclude")
.select_related("state", "charter")
.order_by("parent__name", "acronym")
)
sections["Programs"] = (
Group.objects.filter(type="program", state="conclude")
.select_related("state", "charter")
.order_by("parent__name", "acronym")
)

for name, groups in sections.items():

# add start/conclusion date
d = dict((g.pk, g) for g in groups)

for g in groups:
g.start_date = g.conclude_date = None

for e in ChangeStateGroupEvent.objects.filter(group__in=groups, state="active").order_by("-time"):
# Some older BOFs were created in the "active" state, so consider both "active" and "bof"
# ChangeStateGroupEvents when finding the start date. A group with _both_ "active" and "bof"
# events should not be in the "bof-conc" state so this shouldn't cause a problem (if it does,
# we'll need to clean up the data)
for e in ChangeStateGroupEvent.objects.filter(
group__in=groups,
state__in=["active", "bof"] if name == "BOFs" else ["active"],
).order_by("-time"):
d[e.group_id].start_date = e.time

for e in ChangeStateGroupEvent.objects.filter(group__in=groups, state="conclude").order_by("time"):
# Similarly, some older BOFs were concluded into the "conclude" state and the event was never
# fixed, so consider both "conclude" and "bof-conc" ChangeStateGroupEvents when finding the
# concluded date. A group with _both_ "conclude" and "bof-conc" events should not be in the
# "bof-conc" state so this shouldn't cause a problem (if it does, we'll need to clean up the
# data)
for e in ChangeStateGroupEvent.objects.filter(
group__in=groups,
state__in=["bof-conc", "conclude"] if name == "BOFs" else ["conclude"],
).order_by("time"):
d[e.group_id].conclude_date = e.time

return render(request, 'group/concluded_groups.html',
dict(sections=sections))
return render(request, "group/concluded_groups.html", dict(sections=sections))


def prepare_group_documents(request, group, clist):
found_docs, meta = prepare_document_table(request, docs_tracked_by_community_list(clist), request.GET, max_results=500)
Expand Down
9 changes: 9 additions & 0 deletions ietf/iesg/tests.py
Original file line number Diff line number Diff line change
Expand Up @@ -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'))
Expand Down
1 change: 1 addition & 0 deletions ietf/iesg/views.py
Original file line number Diff line number Diff line change
Expand Up @@ -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 = []
Expand Down
7 changes: 5 additions & 2 deletions ietf/meeting/forms.py
Original file line number Diff line number Diff line change
Expand Up @@ -489,9 +489,12 @@ class UploadAgendaForm(ApplyToAllFileUploadForm):
class UploadSlidesForm(ApplyToAllFileUploadForm):
doc_type = 'slides'
title = forms.CharField(max_length=255)
approved = forms.BooleanField(label='Auto-approve', initial=True, required=False)

def __init__(self, session, *args, **kwargs):
super().__init__(*args, **kwargs)
def __init__(self, session, show_apply_to_all_checkbox, can_manage, *args, **kwargs):
super().__init__(show_apply_to_all_checkbox, *args, **kwargs)
if not can_manage:
self.fields.pop('approved')
self.session = session

def clean_title(self):
Expand Down
Loading

0 comments on commit 6291871

Please sign in to comment.