Skip to content

Commit 69a5d08

Browse files
committed
Refined the GUI for personal API endpoints so that endpoints for which one does not have the right Roles do not show in the GUI, and added a supporting method on Person objects. Updated tests accordingly.
- Legacy-Id: 17643
1 parent eedd48d commit 69a5d08

3 files changed

Lines changed: 29 additions & 19 deletions

File tree

ietf/ietfauth/tests.py

Lines changed: 12 additions & 10 deletions
Original file line numberDiff line numberDiff line change
@@ -21,7 +21,7 @@
2121
from ietf.group.factories import GroupFactory, RoleFactory
2222
from ietf.ietfauth.htpasswd import update_htpasswd_file
2323
from ietf.mailinglists.models import Subscribed
24-
from ietf.person.models import Person, Email, PersonalApiKey, PERSON_API_KEY_ENDPOINTS
24+
from ietf.person.models import Person, Email, PersonalApiKey
2525
from ietf.person.factories import PersonFactory, EmailFactory
2626
from ietf.review.factories import ReviewRequestFactory, ReviewAssignmentFactory
2727
from ietf.review.models import ReviewWish, UnavailablePeriod
@@ -531,18 +531,19 @@ def test_apikey_management(self):
531531
self.assertContains(r, 'Endpoint')
532532

533533
# Add 2 keys
534-
for endpoint, display in PERSON_API_KEY_ENDPOINTS:
534+
endpoints = person.available_api_endpoints()
535+
for endpoint, display in endpoints:
535536
r = self.client.post(url, {'endpoint': endpoint})
536537
self.assertRedirects(r, urlreverse('ietf.ietfauth.views.apikey_index'))
537538

538539
# Check api key list content
539540
url = urlreverse('ietf.ietfauth.views.apikey_index')
540541
r = self.client.get(url)
541-
for endpoint, display in PERSON_API_KEY_ENDPOINTS:
542+
for endpoint, display in endpoints:
542543
self.assertContains(r, endpoint)
543544
q = PyQuery(r.content)
544-
self.assertEqual(len(q('td code')), len(PERSON_API_KEY_ENDPOINTS)) # hash
545-
self.assertEqual(len(q('td a:contains("Disable")')), len(PERSON_API_KEY_ENDPOINTS))
545+
self.assertEqual(len(q('td code')), len(endpoints)) # hash
546+
self.assertEqual(len(q('td a:contains("Disable")')), len(endpoints))
546547

547548
# Get one of the keys
548549
key = person.apikeys.first()
@@ -562,8 +563,8 @@ def test_apikey_management(self):
562563
url = urlreverse('ietf.ietfauth.views.apikey_index')
563564
r = self.client.get(url)
564565
q = PyQuery(r.content)
565-
self.assertEqual(len(q('td code')), len(PERSON_API_KEY_ENDPOINTS)) # key hash
566-
self.assertEqual(len(q('td a:contains("Disable")')), len(PERSON_API_KEY_ENDPOINTS)-1)
566+
self.assertEqual(len(q('td code')), len(endpoints)) # key hash
567+
self.assertEqual(len(q('td a:contains("Disable")')), len(endpoints)-1)
567568

568569
def test_apikey_errors(self):
569570
BAD_KEY = "AAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAA"
@@ -577,7 +578,7 @@ def test_apikey_errors(self):
577578
login_testing_unauthorized(self, person.user.username, url)
578579

579580
# Add keys
580-
for endpoint, display in PERSON_API_KEY_ENDPOINTS:
581+
for endpoint, display in person.available_api_endpoints():
581582
r = self.client.post(url, {'endpoint': endpoint})
582583
self.assertRedirects(r, urlreverse('ietf.ietfauth.views.apikey_index'))
583584

@@ -620,7 +621,8 @@ def test_send_apikey_report(self):
620621
login_testing_unauthorized(self, person.user.username, url)
621622

622623
# Add keys
623-
for endpoint, display in PERSON_API_KEY_ENDPOINTS:
624+
endpoints = person.available_api_endpoints()
625+
for endpoint, display in endpoints:
624626
r = self.client.post(url, {'endpoint': endpoint})
625627
self.assertRedirects(r, urlreverse('ietf.ietfauth.views.apikey_index'))
626628

@@ -639,7 +641,7 @@ def test_send_apikey_report(self):
639641
cmd = Command()
640642
cmd.handle(verbosity=0, days=7)
641643

642-
self.assertEqual(len(outbox), len(PERSON_API_KEY_ENDPOINTS))
644+
self.assertEqual(len(outbox), len(endpoints))
643645
for mail in outbox:
644646
body = mail.get_payload(decode=True).decode('utf-8')
645647
self.assertIn("API key usage", mail['subject'])

ietf/ietfauth/views.py

Lines changed: 5 additions & 2 deletions
Original file line numberDiff line numberDiff line change
@@ -65,9 +65,9 @@
6565
WhitelistForm, ChangePasswordForm, get_person_form, RoleEmailForm,
6666
NewEmailForm, ChangeUsernameForm, PersonPasswordForm)
6767
from ietf.ietfauth.htpasswd import update_htpasswd_file
68-
from ietf.ietfauth.utils import role_required
68+
from ietf.ietfauth.utils import role_required, has_role
6969
from ietf.mailinglists.models import Subscribed, Whitelisted
70-
from ietf.person.models import Person, Email, Alias, PersonalApiKey
70+
from ietf.person.models import Person, Email, Alias, PersonalApiKey, PERSON_API_KEY_VALUES
7171
from ietf.review.models import ReviewerSettings, ReviewWish, ReviewAssignment
7272
from ietf.review.utils import unavailable_periods_to_list, get_default_filter_re
7373
from ietf.doc.fields import SearchableDocumentField
@@ -650,7 +650,10 @@ def apikey_index(request):
650650
@login_required
651651
@person_required
652652
def apikey_create(request):
653+
endpoints = [('', '----------')] + [ (v, n) for (v, n, r) in PERSON_API_KEY_VALUES if r==None or has_role(request.user, r) ]
653654
class ApiKeyForm(forms.ModelForm):
655+
endpoint = forms.ChoiceField(choices=endpoints)
656+
654657
class Meta:
655658
model = PersonalApiKey
656659
fields = ['endpoint']

ietf/person/models.py

Lines changed: 12 additions & 7 deletions
Original file line numberDiff line numberDiff line change
@@ -234,6 +234,11 @@ def json_dict(self, hostscheme):
234234
ct1['ascii'] = self.ascii
235235
return ct1
236236

237+
def available_api_endpoints(self):
238+
from ietf.ietfauth.utils import has_role
239+
return [ (v, n) for (v, n, r) in PERSON_API_KEY_VALUES if r==None or has_role(self.user, r) ]
240+
241+
237242
@python_2_unicode_compatible
238243
class Alias(models.Model):
239244
"""This is used for alternative forms of a name. This is the
@@ -328,13 +333,13 @@ def salt():
328333
return uuid.uuid4().bytes[:12]
329334

330335
# Manual maintenance: List all endpoints that use @require_api_key here
331-
PERSON_API_KEY_ENDPOINTS = [
332-
("/api/iesg/position", "/api/iesg/position"),
333-
# This requires secretariat role, and need not be listed generally:
334-
# ("/api/v2/person/person", "/api/v2/person/person"),
335-
("/api/meeting/session/video/url", "/api/meeting/session/video/url"),
336-
("/api/v2/person/access/meetecho", "/api/v2/person/access/meetecho"),
336+
PERSON_API_KEY_VALUES = [
337+
("/api/iesg/position", "/api/iesg/position", "Area Director"),
338+
("/api/v2/person/person", "/api/v2/person/person", "Secretariat"),
339+
("/api/meeting/session/video/url", "/api/meeting/session/video/url", "Recording Manager"),
340+
("/api/person/access/meetecho", "/api/person/access/meetecho", None),
337341
]
342+
PERSON_API_KEY_ENDPOINTS = [ (v, n) for (v, n, r) in PERSON_API_KEY_VALUES ]
338343

339344
@python_2_unicode_compatible
340345
class PersonalApiKey(models.Model):
@@ -375,7 +380,7 @@ def hash(self):
375380
return self._cached_hash
376381

377382
def __str__(self):
378-
return "%s (%s): %s ..." % (self.endpoint, self.created.strftime("%Y-%m-%d %H:%M"), self.hash()[:16])
383+
return "%s %-24s %-32s(%6d): %s ..." % (self.created.strftime("%Y-%m-%d %H:%M"), self.person.name, self.endpoint, self.count, self.hash()[:16])
379384

380385
PERSON_EVENT_CHOICES = [
381386
("apikey_login", "API key login"),

0 commit comments

Comments
 (0)