Merge pull request #5575 from ietf-tools/main

chore: merge main to the release branch for next release
This commit is contained in:
Robert Sparks 2023-05-04 12:51:04 -05:00 committed by GitHub
commit e32b453c09
No known key found for this signature in database
GPG key ID: 4AEE18F83AFDEB23
8 changed files with 165 additions and 82 deletions

View file

@ -17,7 +17,7 @@
"luxon": "3.3.0"
},
"devDependencies": {
"eslint": "8.37.0",
"eslint": "8.39.0",
"eslint-config-standard": "17.0.0",
"eslint-plugin-import": "2.27.5",
"eslint-plugin-node": "11.1.0",
@ -111,9 +111,9 @@
}
},
"node_modules/@eslint/js": {
"version": "8.37.0",
"resolved": "https://registry.npmjs.org/@eslint/js/-/js-8.37.0.tgz",
"integrity": "sha512-x5vzdtOOGgFVDCUs81QRB2+liax8rFg3+7hqM+QhBG0/G3F1ZsoYl97UrqgHgQ9KKT7G6c4V+aTUCgu/n22v1A==",
"version": "8.39.0",
"resolved": "https://registry.npmjs.org/@eslint/js/-/js-8.39.0.tgz",
"integrity": "sha512-kf9RB0Fg7NZfap83B3QOqOGg9QmD9yBudqQXzzOtn3i4y7ZUXe5ONeW34Gwi+TxhH4mvj72R1Zc300KUMa9Bng==",
"dev": true,
"engines": {
"node": "^12.22.0 || ^14.17.0 || >=16.0.0"
@ -1641,15 +1641,15 @@
}
},
"node_modules/eslint": {
"version": "8.37.0",
"resolved": "https://registry.npmjs.org/eslint/-/eslint-8.37.0.tgz",
"integrity": "sha512-NU3Ps9nI05GUoVMxcZx1J8CNR6xOvUT4jAUMH5+z8lpp3aEdPVCImKw6PWG4PY+Vfkpr+jvMpxs/qoE7wq0sPw==",
"version": "8.39.0",
"resolved": "https://registry.npmjs.org/eslint/-/eslint-8.39.0.tgz",
"integrity": "sha512-mwiok6cy7KTW7rBpo05k6+p4YVZByLNjAZ/ACB9DRCu4YDRwjXI01tWHp6KAUWelsBetTxKK/2sHB0vdS8Z2Og==",
"dev": true,
"dependencies": {
"@eslint-community/eslint-utils": "^4.2.0",
"@eslint-community/regexpp": "^4.4.0",
"@eslint/eslintrc": "^2.0.2",
"@eslint/js": "8.37.0",
"@eslint/js": "8.39.0",
"@humanwhocodes/config-array": "^0.11.8",
"@humanwhocodes/module-importer": "^1.0.1",
"@nodelib/fs.walk": "^1.2.8",
@ -1659,7 +1659,7 @@
"debug": "^4.3.2",
"doctrine": "^3.0.0",
"escape-string-regexp": "^4.0.0",
"eslint-scope": "^7.1.1",
"eslint-scope": "^7.2.0",
"eslint-visitor-keys": "^3.4.0",
"espree": "^9.5.1",
"esquery": "^1.4.2",
@ -1990,9 +1990,9 @@
}
},
"node_modules/eslint-scope": {
"version": "7.1.1",
"resolved": "https://registry.npmjs.org/eslint-scope/-/eslint-scope-7.1.1.tgz",
"integrity": "sha512-QKQM/UXpIiHcLqJ5AOyIW7XZmzjkzQXYE54n1++wb0u9V/abW3l9uQnxX8Z5Xd18xyKIMTUAyQ0k1e8pz6LUrw==",
"version": "7.2.0",
"resolved": "https://registry.npmjs.org/eslint-scope/-/eslint-scope-7.2.0.tgz",
"integrity": "sha512-DYj5deGlHBfMt15J7rdtyKNq/Nqlv5KfU4iodrQ019XESsRnwXH9KAE0y3cwtUHDo2ob7CypAnCqefh6vioWRw==",
"dev": true,
"dependencies": {
"esrecurse": "^4.3.0",
@ -2000,6 +2000,9 @@
},
"engines": {
"node": "^12.22.0 || ^14.17.0 || >=16.0.0"
},
"funding": {
"url": "https://opencollective.com/eslint"
}
},
"node_modules/eslint-utils": {
@ -6161,9 +6164,9 @@
}
},
"@eslint/js": {
"version": "8.37.0",
"resolved": "https://registry.npmjs.org/@eslint/js/-/js-8.37.0.tgz",
"integrity": "sha512-x5vzdtOOGgFVDCUs81QRB2+liax8rFg3+7hqM+QhBG0/G3F1ZsoYl97UrqgHgQ9KKT7G6c4V+aTUCgu/n22v1A==",
"version": "8.39.0",
"resolved": "https://registry.npmjs.org/@eslint/js/-/js-8.39.0.tgz",
"integrity": "sha512-kf9RB0Fg7NZfap83B3QOqOGg9QmD9yBudqQXzzOtn3i4y7ZUXe5ONeW34Gwi+TxhH4mvj72R1Zc300KUMa9Bng==",
"dev": true
},
"@gar/promisify": {
@ -7311,15 +7314,15 @@
"dev": true
},
"eslint": {
"version": "8.37.0",
"resolved": "https://registry.npmjs.org/eslint/-/eslint-8.37.0.tgz",
"integrity": "sha512-NU3Ps9nI05GUoVMxcZx1J8CNR6xOvUT4jAUMH5+z8lpp3aEdPVCImKw6PWG4PY+Vfkpr+jvMpxs/qoE7wq0sPw==",
"version": "8.39.0",
"resolved": "https://registry.npmjs.org/eslint/-/eslint-8.39.0.tgz",
"integrity": "sha512-mwiok6cy7KTW7rBpo05k6+p4YVZByLNjAZ/ACB9DRCu4YDRwjXI01tWHp6KAUWelsBetTxKK/2sHB0vdS8Z2Og==",
"dev": true,
"requires": {
"@eslint-community/eslint-utils": "^4.2.0",
"@eslint-community/regexpp": "^4.4.0",
"@eslint/eslintrc": "^2.0.2",
"@eslint/js": "8.37.0",
"@eslint/js": "8.39.0",
"@humanwhocodes/config-array": "^0.11.8",
"@humanwhocodes/module-importer": "^1.0.1",
"@nodelib/fs.walk": "^1.2.8",
@ -7329,7 +7332,7 @@
"debug": "^4.3.2",
"doctrine": "^3.0.0",
"escape-string-regexp": "^4.0.0",
"eslint-scope": "^7.1.1",
"eslint-scope": "^7.2.0",
"eslint-visitor-keys": "^3.4.0",
"espree": "^9.5.1",
"esquery": "^1.4.2",
@ -7573,9 +7576,9 @@
"requires": {}
},
"eslint-scope": {
"version": "7.1.1",
"resolved": "https://registry.npmjs.org/eslint-scope/-/eslint-scope-7.1.1.tgz",
"integrity": "sha512-QKQM/UXpIiHcLqJ5AOyIW7XZmzjkzQXYE54n1++wb0u9V/abW3l9uQnxX8Z5Xd18xyKIMTUAyQ0k1e8pz6LUrw==",
"version": "7.2.0",
"resolved": "https://registry.npmjs.org/eslint-scope/-/eslint-scope-7.2.0.tgz",
"integrity": "sha512-DYj5deGlHBfMt15J7rdtyKNq/Nqlv5KfU4iodrQ019XESsRnwXH9KAE0y3cwtUHDo2ob7CypAnCqefh6vioWRw==",
"dev": true,
"requires": {
"esrecurse": "^4.3.0",

View file

@ -14,7 +14,7 @@
"luxon": "3.3.0"
},
"devDependencies": {
"eslint": "8.37.0",
"eslint": "8.39.0",
"eslint-config-standard": "17.0.0",
"eslint-plugin-import": "2.27.5",
"eslint-plugin-node": "11.1.0",

View file

@ -40,7 +40,7 @@ from ietf.doc.factories import ( DocumentFactory, DocEventFactory, CharterFactor
ConflictReviewFactory, WgDraftFactory, IndividualDraftFactory, WgRfcFactory,
IndividualRfcFactory, StateDocEventFactory, BallotPositionDocEventFactory,
BallotDocEventFactory, DocumentAuthorFactory, NewRevisionDocEventFactory,
StatusChangeFactory, BofreqFactory, DocExtResourceFactory)
StatusChangeFactory, BofreqFactory, DocExtResourceFactory, RgDraftFactory)
from ietf.doc.forms import NotifyForm
from ietf.doc.fields import SearchableDocumentsField
from ietf.doc.utils import create_ballot_if_not_open, uppercase_std_abbreviated_name
@ -2819,3 +2819,45 @@ class NotifyValidationTests(TestCase):
self.assertFalse(f.is_valid())
self.assertTrue("Invalid addresses" in f.errors["notify"][0])
self.assertTrue("Duplicate addresses" in f.errors["notify"][0])
class CanRequestConflictReviewTests(TestCase):
def test_gets_request_conflict_review_action_button(self):
ise_draft = IndividualDraftFactory(stream_id="ise")
irtf_draft = RgDraftFactory()
# This is blunt, trading off precision for time. A more thorough test would ensure
# that the text is in a button and that the correct link is absent/present as well.
target_string = "Begin IETF conflict review"
url = urlreverse("ietf.doc.views_doc.document_main", kwargs=dict(name=irtf_draft.name))
r = self.client.get(url)
self.assertNotContains(r, target_string)
self.client.login(username="secretary", password="secretary+password")
r = self.client.get(url)
self.assertContains(r, target_string)
self.client.logout()
self.client.login(username="irtf-chair", password="irtf-chair+password")
r = self.client.get(url)
self.assertContains(r, target_string)
self.client.logout()
self.client.login(username="ise-chair", password="ise-chair+password")
r = self.client.get(url)
self.assertNotContains(r, target_string)
self.client.logout()
url = urlreverse("ietf.doc.views_doc.document_main", kwargs=dict(name=ise_draft.name))
r = self.client.get(url)
self.assertNotContains(r, target_string)
self.client.login(username="secretary", password="secretary+password")
r = self.client.get(url)
self.assertContains(r, target_string)
self.client.logout()
self.client.login(username="irtf-chair", password="irtf-chair+password")
r = self.client.get(url)
self.assertNotContains(r, target_string)
self.client.logout()
self.client.login(username="ise-chair", password="ise-chair+password")
r = self.client.get(url)
self.assertContains(r, target_string)

View file

@ -427,12 +427,20 @@ def document_main(request, name, rev=None, document_html=False):
urlreverse('ietf.doc.views_ballot.close_rsab_ballot', kwargs=dict(name=doc.name))
))
if (doc.get_state_slug() not in ["rfc", "expired"] and doc.stream_id in ("ise", "irtf")
and has_role(request.user, ("Secretariat", "IRTF Chair")) and not conflict_reviews and not snapshot):
label = "Begin IETF Conflict Review"
if not doc.intended_std_level:
label += " (note that intended status is not set)"
actions.append((label, urlreverse('ietf.doc.views_conflict_review.start_review', kwargs=dict(name=doc.name))))
if (
doc.get_state_slug() not in ["rfc", "expired"]
and not conflict_reviews
and not snapshot
):
if (
doc.stream_id == "ise" and has_role(request.user, ("Secretariat", "ISE"))
) or (
doc.stream_id == "irtf" and has_role(request.user, ("Secretariat", "IRTF Chair"))
):
label = "Begin IETF conflict review" # Note that the template feeds this through capfirst_allcaps
if not doc.intended_std_level:
label += " (note that intended status is not set)"
actions.append((label, urlreverse('ietf.doc.views_conflict_review.start_review', kwargs=dict(name=doc.name))))
if doc.get_state_slug() not in ["rfc", "expired"] and not snapshot:
if can_request_rfc_publication(request.user, doc):

View file

@ -123,16 +123,42 @@ def create_account(request):
new_account_email = form.cleaned_data[
"email"
] # This will be lowercase if form.is_valid()
email_is_known = False # do we already know of the new_account_email address?
user = User.objects.filter(username__iexact=new_account_email)
email = Email.objects.filter(address__iexact=new_account_email)
if user.exists() or email.exists():
person_to_contact = user.first().person if user else email.first().person
to_email = person_to_contact.email_address()
if to_email:
send_account_creation_exists_email(request, new_account_email, to_email)
else:
raise ValidationError(f"Account for {new_account_email} exists, but cannot email it")
# Find an existing Person to contact, if one exists
person_to_contact = None
user = User.objects.filter(username__iexact=new_account_email).first()
if user is not None:
email_is_known = True
try:
person_to_contact = user.person
except User.person.RelatedObjectDoesNotExist:
# User.person is a OneToOneField so it raises an exception if the field is null
pass # leave person_to_contact as None
if person_to_contact is None:
email = Email.objects.filter(address__iexact=new_account_email).first()
if email is not None:
email_is_known = True
# Email.person is a ForeignKey, so its value is None if the field is null
person_to_contact = email.person
# Get a "good" email to contact the existing Person
to_email = person_to_contact.email_address() if person_to_contact else None
if to_email:
# We have a "good" email - send instructions to it
send_account_creation_exists_email(request, new_account_email, to_email)
elif email_is_known:
# Either a User or an Email matching new_account_email is in the system but we do not have a
# "good" email to use to contact its owner. Fail so the user can contact the secretariat to sort
# things out.
form.add_error(
"email",
ValidationError(
f"Unable to create account for {new_account_email}. Please contact "
f"the Secretariat at {settings.SECRETARIAT_SUPPORT_EMAIL} for assistance."
),
)
new_account_email = None # Indicate to the template that we failed to create the requested account
else:
# For the IETF 113 Registration period (at least) we are lowering the
# barriers for account creation to the simple email round-trip check

View file

@ -255,25 +255,26 @@ $(document)
// Bootstrap doesn't load modals via href anymore, so let's do it ourselves.
// See https://stackoverflow.com/a/48934494/2240756
// Instead of attaching to the modal elements as in that example, though,
// listen on document and filter with the .modal selector. This allows handling
// of modals that are added dynamically (e.g., list.js apparently replaces DOM
// elements with identical copies, minus any attached listeners).
$(document)
.ready(function () {
$('.modal')
.on('show.bs.modal', function (e) {
var button = $(e.relatedTarget);
if (!$(button)
.attr("href")) {
return;
}
var loc = $(button)
.attr("href")
.trim();
// load content from value of button href
if (loc !== undefined && loc !== "#") {
$(this)
.find('.modal-content')
.load(loc);
}
});
.on('show.bs.modal', '.modal', function (e) {
var button = $(e.relatedTarget);
if (!$(button)
.attr("href")) {
return;
}
var loc = $(button)
.attr("href")
.trim();
// load content from value of button href
if (loc !== undefined && loc !== "#") {
$(this)
.find('.modal-content')
.load(loc);
}
});
// Handle history snippet expansion.

View file

@ -16,7 +16,7 @@
},
"devDependencies": {
"@playwright/test": "1.32.3",
"eslint": "8.37.0",
"eslint": "8.39.0",
"eslint-config-standard": "17.0.0",
"eslint-plugin-import": "2.27.5",
"eslint-plugin-n": "15.7.0",
@ -83,9 +83,9 @@
}
},
"node_modules/@eslint/js": {
"version": "8.37.0",
"resolved": "https://registry.npmjs.org/@eslint/js/-/js-8.37.0.tgz",
"integrity": "sha512-x5vzdtOOGgFVDCUs81QRB2+liax8rFg3+7hqM+QhBG0/G3F1ZsoYl97UrqgHgQ9KKT7G6c4V+aTUCgu/n22v1A==",
"version": "8.39.0",
"resolved": "https://registry.npmjs.org/@eslint/js/-/js-8.39.0.tgz",
"integrity": "sha512-kf9RB0Fg7NZfap83B3QOqOGg9QmD9yBudqQXzzOtn3i4y7ZUXe5ONeW34Gwi+TxhH4mvj72R1Zc300KUMa9Bng==",
"dev": true,
"engines": {
"node": "^12.22.0 || ^14.17.0 || >=16.0.0"
@ -1457,15 +1457,15 @@
}
},
"node_modules/eslint": {
"version": "8.37.0",
"resolved": "https://registry.npmjs.org/eslint/-/eslint-8.37.0.tgz",
"integrity": "sha512-NU3Ps9nI05GUoVMxcZx1J8CNR6xOvUT4jAUMH5+z8lpp3aEdPVCImKw6PWG4PY+Vfkpr+jvMpxs/qoE7wq0sPw==",
"version": "8.39.0",
"resolved": "https://registry.npmjs.org/eslint/-/eslint-8.39.0.tgz",
"integrity": "sha512-mwiok6cy7KTW7rBpo05k6+p4YVZByLNjAZ/ACB9DRCu4YDRwjXI01tWHp6KAUWelsBetTxKK/2sHB0vdS8Z2Og==",
"dev": true,
"dependencies": {
"@eslint-community/eslint-utils": "^4.2.0",
"@eslint-community/regexpp": "^4.4.0",
"@eslint/eslintrc": "^2.0.2",
"@eslint/js": "8.37.0",
"@eslint/js": "8.39.0",
"@humanwhocodes/config-array": "^0.11.8",
"@humanwhocodes/module-importer": "^1.0.1",
"@nodelib/fs.walk": "^1.2.8",
@ -1475,7 +1475,7 @@
"debug": "^4.3.2",
"doctrine": "^3.0.0",
"escape-string-regexp": "^4.0.0",
"eslint-scope": "^7.1.1",
"eslint-scope": "^7.2.0",
"eslint-visitor-keys": "^3.4.0",
"espree": "^9.5.1",
"esquery": "^1.4.2",
@ -1797,9 +1797,9 @@
}
},
"node_modules/eslint-scope": {
"version": "7.1.1",
"resolved": "https://registry.npmjs.org/eslint-scope/-/eslint-scope-7.1.1.tgz",
"integrity": "sha512-QKQM/UXpIiHcLqJ5AOyIW7XZmzjkzQXYE54n1++wb0u9V/abW3l9uQnxX8Z5Xd18xyKIMTUAyQ0k1e8pz6LUrw==",
"version": "7.2.0",
"resolved": "https://registry.npmjs.org/eslint-scope/-/eslint-scope-7.2.0.tgz",
"integrity": "sha512-DYj5deGlHBfMt15J7rdtyKNq/Nqlv5KfU4iodrQ019XESsRnwXH9KAE0y3cwtUHDo2ob7CypAnCqefh6vioWRw==",
"dev": true,
"dependencies": {
"esrecurse": "^4.3.0",
@ -1807,6 +1807,9 @@
},
"engines": {
"node": "^12.22.0 || ^14.17.0 || >=16.0.0"
},
"funding": {
"url": "https://opencollective.com/eslint"
}
},
"node_modules/eslint-utils": {
@ -5858,9 +5861,9 @@
}
},
"@eslint/js": {
"version": "8.37.0",
"resolved": "https://registry.npmjs.org/@eslint/js/-/js-8.37.0.tgz",
"integrity": "sha512-x5vzdtOOGgFVDCUs81QRB2+liax8rFg3+7hqM+QhBG0/G3F1ZsoYl97UrqgHgQ9KKT7G6c4V+aTUCgu/n22v1A==",
"version": "8.39.0",
"resolved": "https://registry.npmjs.org/@eslint/js/-/js-8.39.0.tgz",
"integrity": "sha512-kf9RB0Fg7NZfap83B3QOqOGg9QmD9yBudqQXzzOtn3i4y7ZUXe5ONeW34Gwi+TxhH4mvj72R1Zc300KUMa9Bng==",
"dev": true
},
"@faker-js/faker": {
@ -6874,15 +6877,15 @@
"dev": true
},
"eslint": {
"version": "8.37.0",
"resolved": "https://registry.npmjs.org/eslint/-/eslint-8.37.0.tgz",
"integrity": "sha512-NU3Ps9nI05GUoVMxcZx1J8CNR6xOvUT4jAUMH5+z8lpp3aEdPVCImKw6PWG4PY+Vfkpr+jvMpxs/qoE7wq0sPw==",
"version": "8.39.0",
"resolved": "https://registry.npmjs.org/eslint/-/eslint-8.39.0.tgz",
"integrity": "sha512-mwiok6cy7KTW7rBpo05k6+p4YVZByLNjAZ/ACB9DRCu4YDRwjXI01tWHp6KAUWelsBetTxKK/2sHB0vdS8Z2Og==",
"dev": true,
"requires": {
"@eslint-community/eslint-utils": "^4.2.0",
"@eslint-community/regexpp": "^4.4.0",
"@eslint/eslintrc": "^2.0.2",
"@eslint/js": "8.37.0",
"@eslint/js": "8.39.0",
"@humanwhocodes/config-array": "^0.11.8",
"@humanwhocodes/module-importer": "^1.0.1",
"@nodelib/fs.walk": "^1.2.8",
@ -6892,7 +6895,7 @@
"debug": "^4.3.2",
"doctrine": "^3.0.0",
"escape-string-regexp": "^4.0.0",
"eslint-scope": "^7.1.1",
"eslint-scope": "^7.2.0",
"eslint-visitor-keys": "^3.4.0",
"espree": "^9.5.1",
"esquery": "^1.4.2",
@ -7117,9 +7120,9 @@
"requires": {}
},
"eslint-scope": {
"version": "7.1.1",
"resolved": "https://registry.npmjs.org/eslint-scope/-/eslint-scope-7.1.1.tgz",
"integrity": "sha512-QKQM/UXpIiHcLqJ5AOyIW7XZmzjkzQXYE54n1++wb0u9V/abW3l9uQnxX8Z5Xd18xyKIMTUAyQ0k1e8pz6LUrw==",
"version": "7.2.0",
"resolved": "https://registry.npmjs.org/eslint-scope/-/eslint-scope-7.2.0.tgz",
"integrity": "sha512-DYj5deGlHBfMt15J7rdtyKNq/Nqlv5KfU4iodrQ019XESsRnwXH9KAE0y3cwtUHDo2ob7CypAnCqefh6vioWRw==",
"dev": true,
"requires": {
"esrecurse": "^4.3.0",

View file

@ -8,7 +8,7 @@
},
"devDependencies": {
"@playwright/test": "1.32.3",
"eslint": "8.37.0",
"eslint": "8.39.0",
"eslint-config-standard": "17.0.0",
"eslint-plugin-import": "2.27.5",
"eslint-plugin-n": "15.7.0",