Note: The default ITS GitLab runner is a shared resource and is subject to slowdowns during heavy usage.
You can run your own GitLab runner that is dedicated just to your group if you need to avoid processing delays.

Commit f37e5fdc authored by John C Boufford's avatar John C Boufford
Browse files

added some documentation.

parent 148aeed8
......@@ -5,8 +5,10 @@ import logging
logger = logging.getLogger(__name__)
# Create Two Factor Authentication to the API Directory.
class ApiDirectory:
# Constructor
def __init__(self, client_id, secret, scope, token_url, timeout=10):
self.client_id = client_id
self.secret = secret
......@@ -14,6 +16,7 @@ class ApiDirectory:
self.token_url = token_url
self.timeout = timeout
# Validates that the minimal values have been set to connect to the API Directory.
def _validate_initialization(self):
if (self.client_id is None
or self.secret is None
......@@ -21,6 +24,7 @@ class ApiDirectory:
or self.token_url is None):
raise Exception("Invalid class configuration")
# internal method to request an access bearer token.
def _find_token(self):
data = {
'grant_type': 'client_credentials',
......@@ -43,7 +47,7 @@ class ApiDirectory:
return response.json()
# gets access token from find_token
# internal method to parse the access token.
def _find_access_token(self):
token = self._find_token()
if ('access_token' in token):
......@@ -63,6 +67,7 @@ class ApiDirectory:
return access_token
# public method for building the https header needed for calling the API Directory.
def build_headers(self):
self._validate_initialization()
bearer = self._find_access_token()
......
......@@ -2,12 +2,14 @@ import unittest
from apidirectory import ApiDirectory
# Test calling the API tirectory.
class ApiDirectoryTest(unittest.TestCase):
client_id = "e06fb405-c58e-4334-b746-dd5969575bf2"
secret = "G5oT3vL1uK8xS7rO5sJ4nH7bK5iB6hN5jN5dI0nL8tO5bG4tT5"
scope = "iamgroups"
token_url = "https://apigw-tst.it.umich.edu/um/inst/oauth2/token"
# Test the construtor.
def test_constructor(self):
api = ApiDirectory(self.client_id, self.secret, self.scope, self.token_url)
self.assertEqual(api.client_id, self.client_id)
......@@ -16,10 +18,10 @@ class ApiDirectoryTest(unittest.TestCase):
self.assertEqual(api.token_url, self.token_url)
self.assertEqual(api.timeout, 10)
# Test the header.
def test_build_header(self):
api = ApiDirectory(self.client_id, self.secret, self.scope, self.token_url)
header = api.build_headers()
map = header
self.assertEqual(map['x-ibm-client-id'], self.client_id)
self.assertTrue('authorization' in map)
self.assertTrue('authorization' in header)
......@@ -24,12 +24,9 @@ class IamGroupCRUDTests(unittest.TestCase):
# The url_endpoint is obtain from the API directory
# The api.build_headers builds the header needed for two factor oauth.
def test_1_create(self):
api = ApiDirectory(self.client_id, self.secret, self.scope, self.token_url)
url_endpoint = 'create'
url = IamGroupCRUDTests.url_base + '/' + url_endpoint
data = {'name': 'iamGroupTestJB'}
response = requests.post(
......@@ -43,14 +40,14 @@ class IamGroupCRUDTests(unittest.TestCase):
print('JSON: {}'.format(response.json()))
self.assertEqual(response.status_code, requests.codes.ok)
# The Read operation take a dn on the url. Because a dn contains spaces, commas and equals it
# The Read operation takes a dn on the url. Because a dn contains spaces, commas and equals it
# needs to url encode. Note the test at the bottom of the unit test.
def test_2_read(self):
api = ApiDirectory(self.client_id, self.secret, self.scope, self.token_url)
dn = "cn=iamGroupTestJB,ou=user groups,ou=groups,dc=umich,dc=edu"
encoded_dn = urllib.parse.quote(dn)
encoded = urllib.parse.quote(dn)
url_endpoint = 'profile/dn'
url = IamGroupCRUDTests.url_base + '/' + url_endpoint + "/" + encoded_dn
url = IamGroupCRUDTests.url_base + '/' + url_endpoint + "/" + encoded
response = requests.get(
url=url,
......@@ -62,7 +59,8 @@ class IamGroupCRUDTests(unittest.TestCase):
print('JSON: {}'.format(response.json()))
self.assertEqual(response.status_code, requests.codes.ok)
# note that the returned json is a group object which is a list.
# note that the returned json is a dictionary object with a key of group.
# the value is a list of groups and each group is a dictionary.
map = response.json()
list = map['group']
profile = list[0]
......@@ -71,7 +69,6 @@ class IamGroupCRUDTests(unittest.TestCase):
# update. There are many update operations. I am showing how to modifiy a moderator.
def test_3_update(self):
api = ApiDirectory(self.client_id, self.secret, self.scope, self.token_url)
url_endpoint = 'update/moderator'
url = IamGroupCRUDTests.url_base + '/' + url_endpoint
data = {'dn': 'cn=iamGroupTestJB,ou=user groups,ou=groups,dc=umich,dc=edu',
......@@ -93,15 +90,16 @@ class IamGroupCRUDTests(unittest.TestCase):
def test_4_delete(self):
api = ApiDirectory(self.client_id, self.secret, self.scope, self.token_url)
dn = "cn=iamGroupTestJB,ou=user groups,ou=groups,dc=umich,dc=edu"
encoded_dn = urllib.parse.quote(dn)
encoded = urllib.parse.quote(dn)
url_endpoint = 'delete'
url = IamGroupCRUDTests.url_base + '/' + url_endpoint + "/" + encoded_dn
url = IamGroupCRUDTests.url_base + '/' + url_endpoint + "/" + encoded
response = requests.get(
url=url,
headers=api.build_headers(),
timeout=10
)
print('Response: {}'.format(response))
print('JSON: {}'.format(response.json()))
self.assertEqual(response.status_code, requests.codes.ok)
......@@ -120,15 +118,16 @@ class IamGroupCRUDTests(unittest.TestCase):
def test_isValid(self):
api = ApiDirectory(self.client_id, self.secret, self.scope, self.token_url)
name = "iamGroupTestJB"
encoded_name = urllib.parse.quote(name)
encoded = urllib.parse.quote(name)
url_endpoint = 'mygroup/isValidName'
url = IamGroupCRUDTests.url_base + '/' + url_endpoint + "/" + encoded_name
url = IamGroupCRUDTests.url_base + '/' + url_endpoint + "/" + encoded
response = requests.get(
url=url,
headers=api.build_headers(),
timeout=10
)
print('Response: {}'.format(response))
print('JSON: {}'.format(response.json()))
self.assertEqual(response.status_code, requests.codes.ok)
......@@ -140,15 +139,16 @@ class IamGroupCRUDTests(unittest.TestCase):
def test_isValid_failed(self):
api = ApiDirectory(self.client_id, self.secret, self.scope, self.token_url)
name = "jbouffor"
encoded_name = urllib.parse.quote(name)
encoded = urllib.parse.quote(name)
url_endpoint = 'mygroup/isValidName'
url = IamGroupCRUDTests.url_base + '/' + url_endpoint + "/" + encoded_name
url = IamGroupCRUDTests.url_base + '/' + url_endpoint + "/" + encoded
response = requests.get(
url=url,
headers=api.build_headers(),
timeout=10
)
print('Response: {}'.format(response))
print('JSON: {}'.format(response.json()))
self.assertEqual(response.status_code, requests.codes.ok)
......
......@@ -90,12 +90,13 @@ class IamGroupSearchTests(unittest.TestCase):
headers=api.build_headers(),
timeout=10
)
print(api.build_headers())
print('Response: {}'.format(response))
print('JSON: {}'.format(response.json()))
self.assertEqual(response.status_code, requests.codes.ok)
# find a person using a uniqname. returns the persons dn in the json.
# often it is used in a type ahead feature.
def test_find_person_by_uniqname(self):
api = ApiDirectory(self.client_id, self.secret, self.scope, self.token_url)
url_endpoint = 'find/person'
......@@ -115,11 +116,12 @@ class IamGroupSearchTests(unittest.TestCase):
self.assertEqual(response.status_code, requests.codes.ok)
# Used to find if a name is a group dn or a person dn or places where it needs to be a person or group.
def test_find_group_by_name_or_person(self):
api = ApiDirectory(self.client_id, self.secret, self.scope, self.token_url)
url_endpoint = 'find/both'
uniqname = "post-its-notes"
# Since uniqname are alpha numeric without spaces this is not really needed.
# Since group names can contain spaces it should be encoded.
encoded = urllib.parse.quote(uniqname)
url = IamGroupSearchTests.url_base + '/' + url_endpoint + '/' + encoded
......@@ -134,9 +136,10 @@ class IamGroupSearchTests(unittest.TestCase):
self.assertEqual(response.status_code, requests.codes.ok)
# Finds a group by name. Often used in a type ahead feature.
def test_find_group_by_name(self):
api = ApiDirectory(self.client_id, self.secret, self.scope, self.token_url)
url_endpoint = 'find/typeahead'
url_endpoint = 'find/group'
uniqname = "post-its-notes"
# Since uniqname are alpha numeric without spaces this is not really needed.
encoded = urllib.parse.quote(uniqname)
......
......@@ -90,6 +90,7 @@ class IamGroupUpdateTests(unittest.TestCase):
# Adds an owner to the existing group.
# replace ErrorsTo attribute
# Adds a Request To attribute
# This is how the api was designed. First lookup the group. Make your modification. Then submit the changes.
def update_group_management_attributes(self):
# lookup the group.
......@@ -132,6 +133,7 @@ class IamGroupUpdateTests(unittest.TestCase):
self.apply_update(data, 'update/privacySetting')
# Sample update method to reduce the repetitiveness in the other examples.
def apply_update(self, data, url_endpoint):
print("updating " + url_endpoint)
api = ApiDirectory(self.client_id, self.secret, self.scope, self.token_url)
......@@ -151,6 +153,7 @@ class IamGroupUpdateTests(unittest.TestCase):
map = response.json()
return map
# Sample lookup based on dn to reduce repetitiveness of the other examples.
def lookup(self, dn):
api = ApiDirectory(self.client_id, self.secret, self.scope, self.token_url)
encoded = urllib.parse.quote(dn)
......
Markdown is supported
0% or .
You are about to add 0 people to the discussion. Proceed with caution.
Finish editing this message first!
Please register or to comment