Skip to content

Commit

Permalink
Merge pull request #53 from UWIT-IAM/EDS-480.v9
Browse files Browse the repository at this point in the history
Add irws entity.profile functions
  • Loading branch information
krlowe authored Feb 10, 2020
2 parents 054a917 + 68eec7c commit 2c84b66
Show file tree
Hide file tree
Showing 8 changed files with 268 additions and 1 deletion.
2 changes: 2 additions & 0 deletions .gitignore
Original file line number Diff line number Diff line change
Expand Up @@ -2,6 +2,8 @@
*.egg-info
*.o
*~
.*.swp

.coverage
.idea
tests.log
25 changes: 24 additions & 1 deletion resttools/dao_implementation/irws.py
Original file line number Diff line number Diff line change
Expand Up @@ -3,6 +3,7 @@
"""
from resttools.mock.mock_http import MockHTTP
import json
import re
from resttools.dao_implementation.live import get_con_pool, get_live_url
from resttools.dao_implementation.mock import get_mockdata_url

Expand Down Expand Up @@ -41,6 +42,14 @@ def getURL(self, url, headers):
def putURL(self, url, headers, body):
logger.debug('file irws put url: ' + url)

# eat an optional "?-reflect", it will affect our response
reflect = re.search(r'([?&])(-reflect)([&]*)', url)
if reflect:
if reflect.end(3) == reflect.start(3):
url = url[:reflect.start(1)]
else:
url = url[:reflect.start(1) + 1] + url[reflect.start(3) + 1:]

response = get_mockdata_url("irws", self._conf, url, headers)
if response.status != 404 or url in File._cache_db:
# try set in cache
Expand All @@ -56,9 +65,23 @@ def putURL(self, url, headers, body):
put_section['preferred_cname'] = ' '.join(x for x in name_parts if x)
# update the put data and leave everything else in place
cache_data[key][0].update(put_section)
if 'entity.profile' in cache_data and 'pronoun' in cache_data['entity.profile'][0]:
if cache_data['entity.profile'][0]['pronoun'] == 'attribute=101':
cache_data['entity.profile'][0]['pronoun'] = 'she/her/hers'
elif cache_data['entity.profile'][0]['pronoun'] == 'attribute=102':
cache_data['entity.profile'][0]['pronoun'] = 'he/him/his'
elif cache_data['entity.profile'][0]['pronoun'] == 'attribute=103':
cache_data['entity.profile'][0]['pronoun'] = 'they/them/theirs'
elif cache_data['entity.profile'][0]['pronoun'] == 'attribute=104':
cache_data['entity.profile'][0]['pronoun'] = 'use my name'
elif cache_data['entity.profile'][0]['pronoun'] == '':
del cache_data['entity.profile'][0]['pronoun']
File._cache_db[url] = json.dumps(cache_data)
# return an irws-style put response
response.data = '{"cached": {"code": "0000","message": "put cached in mock data"}}'
if reflect:
response.data = File._cache_db[url]
else:
response.data = '{"cached": {"code": "0000","message": "put cached in mock data"}}'
response.status = 200

return response
Expand Down
84 changes: 84 additions & 0 deletions resttools/irws.py
Original file line number Diff line number Diff line change
Expand Up @@ -46,6 +46,90 @@ def _clean(self, arg):
arg = quote(arg)
return arg

# v3 - different concept
# This whole module is a thorn in our side (imho). Rather than converting
# the IRWS responses into an arbitrary middle-man structure, we should
# simply pass them on to our client as opaque blobs. To wit...

def get_entity_profile(self, netid=None):
"""
Returns the entire entity profile as an opaque JSON dict blob.
"""
if netid is not None:
url = "/%s/v3/entity.profile/uwnetid=%s" % (self._service_name, netid)
else:
return None

response = self.dao.getURL(url, {"Accept": "application/json"})

if response.status == 404:
return None

if response.status != 200:
raise DataFailureException(url, response.status, response.data)

try:
profile = json.loads(response.data)['entity.profile'][0]
except ValueError as e:
raise DataFailureException(url, 500, "Bad json: " + str(e) + " in " + response.data)
except (KeyError, IndexError) as e:
raise DataFailureException(url, 500, "Missing key: " + str(e) + " in " + response.data)
except Exception as e:
raise DataFailureException(url, 500, repl(e) + " in " + response.data)
return profile

def put_entity_profile(self, netid=None, profile=None):
"""
Update an entity profile with just the updated hunk of the profile
NB: The pronoun, if not other fields, cannot be stuffed back into the profile w/o adjustment
so you cannot simply update the response from our 'get' counterpart.
"""
if profile is not None:
body = '{"entity.profile": [%s]}' % json.dumps(profile)
else:
return self.get_entity_profile(self, netid=netid)

if netid is not None:
url = "/%s/v3/entity.profile/uwnetid=%s?-reflect" % (self._service_name, netid)
else:
raise BadInput('Missing netid for entity profile')

response = self.dao.putURL(url, {"Content-type": "application/json", "Accept": "application/json"}, body)

if response.status != 200:
raise DataFailureException(url, response.status, response.data)

try:
profile = json.loads(response.data)['entity.profile'][0]
except ValueError as e:
raise DataFailureException(url, 500, "Bad json: " + str(e) + " in " + response.data)
except (KeyError, IndexError) as e:
raise DataFailureException(url, 500, "Missing key: " + str(e) + " in " + response.data)
except Exception as e:
raise DataFailureException(url, 500, repl(e) + " in " + response.data)
return profile

def get_verify_attributes(self):
"""
Fetch the verify attributes because they might change some day
"""
url = "/%s/v3/reference.verify.attribute" % self._service_name
response = self.dao.getURL(url, {"Accept": "application/json"})

if response.status != 200:
raise DataFailureException(url, response.status, response.data)

try:
attributes = json.loads(response.data)['reference.verify.attribute']
except ValueError as e:
raise DataFailureException(url, 500, "Bad json: " + str(e) + " in " + response.data)
except (KeyError, IndexError) as e:
raise DataFailureException(url, 500, "Missing key: " + str(e) + " in " + response.data)
except Exception as e:
raise DataFailureException(url, 500, repl(e) + " in " + response.data)
return attributes

# v2 - no change
def get_uwnetid(self, eid=None, regid=None, netid=None, source=None, status=None, ret_array=False):
"""
Expand Down
39 changes: 39 additions & 0 deletions resttools/mock/irws/registry-dev/v3/entity.profile/uwnetid_bart196
Original file line number Diff line number Diff line change
@@ -0,0 +1,39 @@
mock data for entity.profile/uwnetid=bart196

MOCKDATA-MOCKDATA-MOCKDATA
{
"entity.profile": [
{
"regid": "67CFDB1ED63A4F9A79C62580068A8FB5",
"type": {
"entity": "Person",
"is_test": "1"
},
"identifiers": {
"uwhr": "000211196"
},
"preferred_name": "Mel 'The Knife' Eastwood",
"preferred_fname": "Mel",
"preferred_mname": "'The Knife'",
"preferred_lname": "Eastwood",
"pronoun": "she/her/hers",
"recover_contacts": [
{
"type": "tnc_version",
"value": "20151019",
"validation_date": "2020-01-30T14:19:12-08:00"
},
{
"type": "email",
"value": "[email protected]",
"validation_date": "2020-01-30T14:22:39-08:00"
}
],
"logname": "registry1:setname:[email protected]",
"created": "2020-01-29 09:13:53.782867",
"updated": "2020-01-30 15:27:12.722930",
"post_url": "/registry-dev/v3/entity.profile/67CFDB1ED63A4F9A79C62580068A8FB5"
}
],
"totalcount": 1
}
19 changes: 19 additions & 0 deletions resttools/mock/irws/registry-dev/v3/entity.profile/uwnetid_bart197
Original file line number Diff line number Diff line change
@@ -0,0 +1,19 @@
mock data for entity.profile/uwnetid=bart197

MOCKDATA-MOCKDATA-MOCKDATA
{
"entity.profile": [
{
"regid": "4ABBB947D05B68AB687BE860BE98AB56",
"type": {
"entity": "Person",
"is_test": "1"
},
"identifiers": {
"uwhr": "000211197"
},
"post_url": "/registry-dev/v3/entity.profile/4ABBB947D05B68AB687BE860BE98AB56"
}
],
"totalcount": 1
}
31 changes: 31 additions & 0 deletions resttools/mock/irws/registry-dev/v3/entity.profile/uwnetid_bart198
Original file line number Diff line number Diff line change
@@ -0,0 +1,31 @@
mock data for entity.profile/uwnetid=bart198

MOCKDATA-MOCKDATA-MOCKDATA
{
"entity.profile": [
{
"regid": "EF89E7D06A7C11D5A4AE0004AC494FFE",
"type": {
"entity": "Person",
"is_test": "0"
},
"identifiers": {
"uwhr": "999008804",
"advance": "9900123733"
},
"preferred_name": "Millard P. Truman",
"preferred_fname": "Millard",
"preferred_mname": "P.",
"preferred_lname": "Truman",
"recover_contacts": [
{
"type": "tnc_version",
"value": "20151019",
"validation_date": "2015-11-30T11:01:01-08:00"
}
],
"post_url": "/registry-eval/v3/entity.profile/EF89E7D06A7C11D5A4AE0004AC494FFE"
}
],
"totalcount": 1
}
42 changes: 42 additions & 0 deletions resttools/mock/irws/registry-dev/v3/reference.verify.attribute
Original file line number Diff line number Diff line change
@@ -0,0 +1,42 @@
mock data for reference.verify.attribute

MOCKDATA-MOCKDATA-MOCKDATA
{
"reference.verify.attribute": [
{
"attribute_code": "0",
"attribute_name": "No Attribute",
"post_url": "/registry-eval/v3/reference.verify.attribute/0"
},
{
"attribute_code": "1",
"attribute_name": "Budget Data",
"post_url": "/registry-eval/v3/reference.verify.attribute/1"
},
{
"attribute_code": "101",
"attribute_name": "she/her/hers",
"attribute_data": "she/her/hers",
"post_url": "/registry-eval/v3/reference.verify.attribute/101"
},
{
"attribute_code": "102",
"attribute_name": "he/him/his",
"attribute_data": "he/him/his",
"post_url": "/registry-eval/v3/reference.verify.attribute/102"
},
{
"attribute_code": "103",
"attribute_name": "they/them/theirs",
"attribute_data": "they/them/theirs",
"post_url": "/registry-eval/v3/reference.verify.attribute/103"
},
{
"attribute_code": "104",
"attribute_name": "usemyname",
"attribute_data": "use my name",
"post_url": "/registry-eval/v3/reference.verify.attribute/104"
}
],
"totalcount": 6
}
27 changes: 27 additions & 0 deletions resttools/test/irws.py
Original file line number Diff line number Diff line change
Expand Up @@ -15,6 +15,33 @@ class IRWS_Test():
def __init__(self):
self.irws = IRWS(settings.IRWS_CONF)

def test_get_entity_profile(self):
profile = self.irws.get_entity_profile(netid='bart196')
eq_(profile['preferred_fname'], 'Mel')
eq_(profile['pronoun'], 'she/her/hers')

def test_put_entity_profile(self):
profile = {
'preferred_fname': 'Mack',
'pronoun': 'attribute=103'
}
profile = self.irws.put_entity_profile(netid='bart196', profile=profile)
eq_(profile['preferred_fname'], 'Mack')
eq_(profile['preferred_lname'], 'Eastwood')
eq_(profile['pronoun'], 'they/them/theirs')

def test_get_verify_attributes(self):
attributes = self.irws.get_verify_attributes()
got103 = False
got601 = False
for element in attributes:
if element['attribute_code'] == '103':
got103 = True
if element['attribute_code'] == '601':
got601 = True
eq_(got103, True, msg='Missing attribute 103')
eq_(got601, False, msg='Unexpected attribute 601')

def test_get_name_by_netid(self):
name = self.irws.get_name_by_netid('javerage')
eq_(name.preferred_cname, 'JAMES AVERAGE STUDENT-P')
Expand Down

0 comments on commit 2c84b66

Please sign in to comment.