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
This commit is contained in:
parent
eedd48d455
commit
69a5d0817d
|
@ -21,7 +21,7 @@ from ietf.group.models import Group, Role, RoleName
|
|||
from ietf.group.factories import GroupFactory, RoleFactory
|
||||
from ietf.ietfauth.htpasswd import update_htpasswd_file
|
||||
from ietf.mailinglists.models import Subscribed
|
||||
from ietf.person.models import Person, Email, PersonalApiKey, PERSON_API_KEY_ENDPOINTS
|
||||
from ietf.person.models import Person, Email, PersonalApiKey
|
||||
from ietf.person.factories import PersonFactory, EmailFactory
|
||||
from ietf.review.factories import ReviewRequestFactory, ReviewAssignmentFactory
|
||||
from ietf.review.models import ReviewWish, UnavailablePeriod
|
||||
|
@ -531,18 +531,19 @@ class IetfAuthTests(TestCase):
|
|||
self.assertContains(r, 'Endpoint')
|
||||
|
||||
# Add 2 keys
|
||||
for endpoint, display in PERSON_API_KEY_ENDPOINTS:
|
||||
endpoints = person.available_api_endpoints()
|
||||
for endpoint, display in endpoints:
|
||||
r = self.client.post(url, {'endpoint': endpoint})
|
||||
self.assertRedirects(r, urlreverse('ietf.ietfauth.views.apikey_index'))
|
||||
|
||||
# Check api key list content
|
||||
url = urlreverse('ietf.ietfauth.views.apikey_index')
|
||||
r = self.client.get(url)
|
||||
for endpoint, display in PERSON_API_KEY_ENDPOINTS:
|
||||
for endpoint, display in endpoints:
|
||||
self.assertContains(r, endpoint)
|
||||
q = PyQuery(r.content)
|
||||
self.assertEqual(len(q('td code')), len(PERSON_API_KEY_ENDPOINTS)) # hash
|
||||
self.assertEqual(len(q('td a:contains("Disable")')), len(PERSON_API_KEY_ENDPOINTS))
|
||||
self.assertEqual(len(q('td code')), len(endpoints)) # hash
|
||||
self.assertEqual(len(q('td a:contains("Disable")')), len(endpoints))
|
||||
|
||||
# Get one of the keys
|
||||
key = person.apikeys.first()
|
||||
|
@ -562,8 +563,8 @@ class IetfAuthTests(TestCase):
|
|||
url = urlreverse('ietf.ietfauth.views.apikey_index')
|
||||
r = self.client.get(url)
|
||||
q = PyQuery(r.content)
|
||||
self.assertEqual(len(q('td code')), len(PERSON_API_KEY_ENDPOINTS)) # key hash
|
||||
self.assertEqual(len(q('td a:contains("Disable")')), len(PERSON_API_KEY_ENDPOINTS)-1)
|
||||
self.assertEqual(len(q('td code')), len(endpoints)) # key hash
|
||||
self.assertEqual(len(q('td a:contains("Disable")')), len(endpoints)-1)
|
||||
|
||||
def test_apikey_errors(self):
|
||||
BAD_KEY = "AAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAA"
|
||||
|
@ -577,7 +578,7 @@ class IetfAuthTests(TestCase):
|
|||
login_testing_unauthorized(self, person.user.username, url)
|
||||
|
||||
# Add keys
|
||||
for endpoint, display in PERSON_API_KEY_ENDPOINTS:
|
||||
for endpoint, display in person.available_api_endpoints():
|
||||
r = self.client.post(url, {'endpoint': endpoint})
|
||||
self.assertRedirects(r, urlreverse('ietf.ietfauth.views.apikey_index'))
|
||||
|
||||
|
@ -620,7 +621,8 @@ class IetfAuthTests(TestCase):
|
|||
login_testing_unauthorized(self, person.user.username, url)
|
||||
|
||||
# Add keys
|
||||
for endpoint, display in PERSON_API_KEY_ENDPOINTS:
|
||||
endpoints = person.available_api_endpoints()
|
||||
for endpoint, display in endpoints:
|
||||
r = self.client.post(url, {'endpoint': endpoint})
|
||||
self.assertRedirects(r, urlreverse('ietf.ietfauth.views.apikey_index'))
|
||||
|
||||
|
@ -639,7 +641,7 @@ class IetfAuthTests(TestCase):
|
|||
cmd = Command()
|
||||
cmd.handle(verbosity=0, days=7)
|
||||
|
||||
self.assertEqual(len(outbox), len(PERSON_API_KEY_ENDPOINTS))
|
||||
self.assertEqual(len(outbox), len(endpoints))
|
||||
for mail in outbox:
|
||||
body = mail.get_payload(decode=True).decode('utf-8')
|
||||
self.assertIn("API key usage", mail['subject'])
|
||||
|
|
|
@ -65,9 +65,9 @@ from ietf.ietfauth.forms import ( RegistrationForm, PasswordForm, ResetPasswordF
|
|||
WhitelistForm, ChangePasswordForm, get_person_form, RoleEmailForm,
|
||||
NewEmailForm, ChangeUsernameForm, PersonPasswordForm)
|
||||
from ietf.ietfauth.htpasswd import update_htpasswd_file
|
||||
from ietf.ietfauth.utils import role_required
|
||||
from ietf.ietfauth.utils import role_required, has_role
|
||||
from ietf.mailinglists.models import Subscribed, Whitelisted
|
||||
from ietf.person.models import Person, Email, Alias, PersonalApiKey
|
||||
from ietf.person.models import Person, Email, Alias, PersonalApiKey, PERSON_API_KEY_VALUES
|
||||
from ietf.review.models import ReviewerSettings, ReviewWish, ReviewAssignment
|
||||
from ietf.review.utils import unavailable_periods_to_list, get_default_filter_re
|
||||
from ietf.doc.fields import SearchableDocumentField
|
||||
|
@ -650,7 +650,10 @@ def apikey_index(request):
|
|||
@login_required
|
||||
@person_required
|
||||
def apikey_create(request):
|
||||
endpoints = [('', '----------')] + [ (v, n) for (v, n, r) in PERSON_API_KEY_VALUES if r==None or has_role(request.user, r) ]
|
||||
class ApiKeyForm(forms.ModelForm):
|
||||
endpoint = forms.ChoiceField(choices=endpoints)
|
||||
|
||||
class Meta:
|
||||
model = PersonalApiKey
|
||||
fields = ['endpoint']
|
||||
|
|
|
@ -234,6 +234,11 @@ class Person(models.Model):
|
|||
ct1['ascii'] = self.ascii
|
||||
return ct1
|
||||
|
||||
def available_api_endpoints(self):
|
||||
from ietf.ietfauth.utils import has_role
|
||||
return [ (v, n) for (v, n, r) in PERSON_API_KEY_VALUES if r==None or has_role(self.user, r) ]
|
||||
|
||||
|
||||
@python_2_unicode_compatible
|
||||
class Alias(models.Model):
|
||||
"""This is used for alternative forms of a name. This is the
|
||||
|
@ -328,13 +333,13 @@ def salt():
|
|||
return uuid.uuid4().bytes[:12]
|
||||
|
||||
# Manual maintenance: List all endpoints that use @require_api_key here
|
||||
PERSON_API_KEY_ENDPOINTS = [
|
||||
("/api/iesg/position", "/api/iesg/position"),
|
||||
# This requires secretariat role, and need not be listed generally:
|
||||
# ("/api/v2/person/person", "/api/v2/person/person"),
|
||||
("/api/meeting/session/video/url", "/api/meeting/session/video/url"),
|
||||
("/api/v2/person/access/meetecho", "/api/v2/person/access/meetecho"),
|
||||
PERSON_API_KEY_VALUES = [
|
||||
("/api/iesg/position", "/api/iesg/position", "Area Director"),
|
||||
("/api/v2/person/person", "/api/v2/person/person", "Secretariat"),
|
||||
("/api/meeting/session/video/url", "/api/meeting/session/video/url", "Recording Manager"),
|
||||
("/api/person/access/meetecho", "/api/person/access/meetecho", None),
|
||||
]
|
||||
PERSON_API_KEY_ENDPOINTS = [ (v, n) for (v, n, r) in PERSON_API_KEY_VALUES ]
|
||||
|
||||
@python_2_unicode_compatible
|
||||
class PersonalApiKey(models.Model):
|
||||
|
@ -375,7 +380,7 @@ class PersonalApiKey(models.Model):
|
|||
return self._cached_hash
|
||||
|
||||
def __str__(self):
|
||||
return "%s (%s): %s ..." % (self.endpoint, self.created.strftime("%Y-%m-%d %H:%M"), self.hash()[:16])
|
||||
return "%s %-24s %-32s(%6d): %s ..." % (self.created.strftime("%Y-%m-%d %H:%M"), self.person.name, self.endpoint, self.count, self.hash()[:16])
|
||||
|
||||
PERSON_EVENT_CHOICES = [
|
||||
("apikey_login", "API key login"),
|
||||
|
|
Loading…
Reference in a new issue