Skip to content
This repository has been archived by the owner on Nov 10, 2021. It is now read-only.

Commit

Permalink
input validation on irws put_name_by_netid(). Still need more tests a…
Browse files Browse the repository at this point in the history
…round the regex
  • Loading branch information
jeffFranklin committed Mar 26, 2015
1 parent 083881e commit 4951c6f
Show file tree
Hide file tree
Showing 3 changed files with 126 additions and 11 deletions.
4 changes: 4 additions & 0 deletions restclients/exceptions.py
Original file line number Diff line number Diff line change
Expand Up @@ -59,6 +59,10 @@ class InvalidGradebookID:
"""Exception for invalid gradebook id."""
pass

class InvalidIRWSName(Exception):
"""Exception for invalid IRWS name."""
pass

class DataFailureException(Exception):
"""
This exception means there was an error fetching content
Expand Down
42 changes: 32 additions & 10 deletions restclients/irws.py
Original file line number Diff line number Diff line change
Expand Up @@ -11,6 +11,7 @@
from restclients.exceptions import InvalidRegID, InvalidNetID, InvalidEmployeeID
from restclients.exceptions import InvalidIdCardPhotoSize
from restclients.exceptions import DataFailureException
from restclients.exceptions import InvalidIRWSName
from restclients.models.irws import Name, HeppsPerson, PersonIdentity
from StringIO import StringIO
from urllib import urlencode
Expand All @@ -27,7 +28,7 @@ def __init__(self, actas=None):
self._re_admin_netid = re.compile(r'^[a-z]adm_[a-z][a-z0-9]{0,7}$', re.I)
self._re_application_netid = re.compile(r'^a_[a-z0-9\-\_\.$.]{1,18}$', re.I)
self._re_employee_id = re.compile(r'^\d{9}$')

self._re_name_part = re.compile(r'^[\w !\"#$%&\'()*+,.\-:;<>?@\/`=]*$')
self._service_name = settings.RESTCLIENTS_IRWS_SERVICE_NAME


Expand Down Expand Up @@ -73,17 +74,10 @@ def put_name_by_netid(self, netid, data):
if not self.valid_uwnetid(netid):
raise InvalidNetID(netid)

pd = self.valid_irws_name_from_json(data)

dao = IRWS_DAO()
url = "/%s/v1/name/uwnetid=%s" % (self._service_name, netid.lower())
# construct the put data
dataname = json.loads(data)
putname = {}
putname['display_fname'] = dataname['display_fname']
putname['display_mname'] = dataname['display_mname']
putname['display_sname'] = dataname['display_lname']
pd = {}
pd['name'] = []
pd['name'].append(putname)
response = dao.putURL(url, {"Accept": "application/json"}, json.dumps(pd))

if response.status != 200:
Expand Down Expand Up @@ -117,6 +111,34 @@ def valid_uwregid(self, regid):
def valid_employee_id(self, employee_id):
return True if self._re_employee_id.match(str(employee_id)) else False

def valid_irws_name_from_json(self, data):
# construct and validate the put data
putname = {}
try:
dataname = json.loads(data)
putname['display_fname'] = dataname['display_fname']
putname['display_mname'] = dataname['display_mname']
putname['display_sname'] = dataname['display_lname']
except:
raise InvalidIRWSName('invalid json')

if any(not self.valid_name_part(x) for x in putname.values()):
raise InvalidIRWSName('name has invalid characters')
if any(putname[x] == '' for x in ('display_fname', 'display_sname')):
raise InvalidIRWSName('required fields cannot be empty')
if len(' '.join(x for x in putname.values() if x != '')) > 80:
raise InvalidIRWSName(
'complete display name cannot be longer than 80 characters')

pd = {}
pd['name'] = []
pd['name'].append(putname)

return pd

def valid_name_part(self, name):
return self._re_name_part.match(name) != None

def _hepps_person_from_json(self, data):
"""
Internal method, for creating the HeppsPerson object.
Expand Down
91 changes: 90 additions & 1 deletion restclients/test/irws.py
Original file line number Diff line number Diff line change
@@ -1,13 +1,102 @@
import json
from django.test import TestCase, override_settings
from django.conf import settings

from restclients.irws import IRWS
from restclients.exceptions import InvalidIRWSName

@override_settings(RESTCLIENTS_IRWS_DAO_CLASS='restclients.dao_implementation.irws.File',
RESTCLIENTS_IRWS_SERVICE_NAME='registry-dev')
class IRWSTest(TestCase):

def test_irws(self):
def test_get_name_by_netid(self):
irws = IRWS()
name = irws.get_name_by_netid('javerage')
self.assertEquals(name.display_cname, 'JAMES AVERAGE STUDENT')

def test_valid_name_part_good(self):
irws = IRWS()
self.assertTrue(irws.valid_name_part('james'))
self.assertTrue(irws.valid_name_part(' '))

def test_valid_name_part_bad(self):
irws = IRWS()
self.assertFalse(irws.valid_name_part('^'))
self.assertFalse(irws.valid_name_part(u'Jos\xe9')) # utf-8

def test_valid_irws_name_good(self):
irws = IRWS()
name = ('joe', 'average', 'user')
names = irws.valid_irws_name_from_json(
self. _json_name_from_tuple(name))
self.assertEquals({'name'}, set(names.keys()))
self.assertEquals(len(names['name']), 1)
name = names['name'][0]
self.assertEquals(name['display_fname'], 'joe')
self.assertEquals(name['display_mname'], 'average')
self.assertEquals(name['display_sname'], 'user')

def test_valid_irws_name_empty_middle_name(self):
irws = IRWS()
name = ('joe', '', 'user')
names = irws.valid_irws_name_from_json(
self._json_name_from_tuple(name))
self.assertEquals(names['name'][0]['display_mname'], '')

def test_valid_irws_name_bad_json(self):
irws = IRWS()
bad_data_list = [
('{"display_fname": "joe", "display_mname": "average", '
'"display_lname": "user"'), # not terminated
('{"display_mname": "average", '
'"display_lname": "user"}'), # missing attribute
]

for bad_data in bad_data_list:
self.assertRaises(InvalidIRWSName,
irws.valid_irws_name_from_json,
bad_data)

def test_valid_irws_name_required_fields_missing(self):
irws = IRWS()
bad_data_list = [
('', 'average', 'user'),
('joe', 'average', ''),
]

for bad_data in bad_data_list:
bad_json = self._json_name_from_tuple(bad_data)
self.assertRaises(InvalidIRWSName,
irws.valid_irws_name_from_json,
bad_json)

def test_valid_irws_name_too_long(self):
# 80 is the magic number
irws = IRWS()
bad_data_list = [
('012345678911234567892123456789',
'312345678941234567895123456789',
'6123456789712345678'),
('0123456789112345678921234567893123456789',
'',
'4123456789512345678961234567897123456789',
)
]

for bad_data in bad_data_list:
# one less character will pass
good_name = self._json_name_from_tuple(bad_data[0:2]
+ (bad_data[2][:-1],))
bad_name = self._json_name_from_tuple(bad_data)
names = irws.valid_irws_name_from_json(good_name)
# success
self.assertTrue(names.get('name', None) is not None)
# failure
self.assertRaises(InvalidIRWSName,
irws.valid_irws_name_from_json,
bad_name)

def _json_name_from_tuple(self, x):
return json.dumps({'display_fname': x[0],
'display_mname': x[1],
'display_lname': x[2]})

0 comments on commit 4951c6f

Please sign in to comment.