Skip to content

Commit 39f8efa

Browse files
committed
Adding tests for csrf protection for rest. Also test disabling of
pretty printing.
1 parent c8d7108 commit 39f8efa

File tree

2 files changed

+72
-0
lines changed

2 files changed

+72
-0
lines changed

test/mocknull.py

Lines changed: 5 additions & 0 deletions
Original file line numberDiff line numberDiff line change
@@ -26,3 +26,8 @@ def __str__(self): return ''
2626
def __repr__(self): return '<MockNull 0x%x>'%id(self)
2727
def gettext(self, str): return str
2828
_ = gettext
29+
def get(self, name, default=None):
30+
try:
31+
return self.__dict__[name.lower()]
32+
except KeyError:
33+
return default

test/test_cgi.py

Lines changed: 67 additions & 0 deletions
Original file line numberDiff line numberDiff line change
@@ -1030,6 +1030,73 @@ def hasPermission(s, p, classname=None, d=None, e=None, **kw):
10301030
os.remove(SENDMAILDEBUG)
10311031
#raise ValueError
10321032

1033+
def testRestCsrfProtection(self):
1034+
# set the password for admin so we can log in.
1035+
passwd=password.Password('admin')
1036+
self.db.user.set('1', password=passwd)
1037+
1038+
out = []
1039+
def wh(s):
1040+
out.append(s)
1041+
1042+
# rest has no form content
1043+
form = cgi.FieldStorage()
1044+
form.list = [
1045+
cgi.MiniFieldStorage('title', 'A new issue'),
1046+
cgi.MiniFieldStorage('status', '1'),
1047+
cgi.MiniFieldStorage('pretty', 'false'),
1048+
cgi.MiniFieldStorage('@apiver', '1'),
1049+
]
1050+
cl = client.Client(self.instance, None,
1051+
{'REQUEST_METHOD':'POST',
1052+
'PATH_INFO':'rest/data/issue',
1053+
'CONTENT_TYPE': 'application/x-www-form-urlencoded',
1054+
'HTTP_AUTHORIZATION': 'Basic YWRtaW46YWRtaW4=',
1055+
'HTTP_REFERER': 'http://whoami.com/path/',
1056+
'HTTP_ACCEPT': "application/json;version=1"
1057+
}, form)
1058+
cl.db = self.db
1059+
cl.base = 'http://whoami.com/path/'
1060+
cl._socket_op = lambda *x : True
1061+
cl._error_message = []
1062+
cl.request = MockNull()
1063+
h = { 'content-type': 'application/json',
1064+
'accept': 'application/json' }
1065+
cl.request.headers = MockNull(**h)
1066+
1067+
cl.write = wh # capture output
1068+
1069+
# Should return explanation because content type is text/plain
1070+
# and not text/xml
1071+
cl.handle_rest()
1072+
self.assertEqual(out[0], "<class 'roundup.exceptions.UsageError'>: Required Header Missing\n")
1073+
del(out[0])
1074+
1075+
cl = client.Client(self.instance, None,
1076+
{'REQUEST_METHOD':'POST',
1077+
'PATH_INFO':'rest/data/issue',
1078+
'CONTENT_TYPE': 'application/x-www-form-urlencoded',
1079+
'HTTP_AUTHORIZATION': 'Basic YWRtaW46YWRtaW4=',
1080+
'HTTP_REFERER': 'http://whoami.com/path/',
1081+
'HTTP_X_REQUESTED_WITH': 'rest',
1082+
'HTTP_ACCEPT': "application/json;version=1"
1083+
}, form)
1084+
cl.db = self.db
1085+
cl.base = 'http://whoami.com/path/'
1086+
cl._socket_op = lambda *x : True
1087+
cl._error_message = []
1088+
cl.request = MockNull()
1089+
h = { 'content-type': 'application/json',
1090+
'accept': 'application/json;version=1' }
1091+
cl.request.headers = MockNull(**h)
1092+
1093+
cl.write = wh # capture output
1094+
1095+
# Should work as all required headers are present.
1096+
cl.handle_rest()
1097+
self.assertEqual(out[0], '{"data": {"link": "http://tracker.example/cgi-bin/roundup.cgi/bugs/rest/data/issue/1", "id": "1"}}\n')
1098+
del(out[0])
1099+
10331100
def testXmlrpcCsrfProtection(self):
10341101
# set the password for admin so we can log in.
10351102
passwd=password.Password('admin')

0 commit comments

Comments
 (0)