From c60142efda817f030a7495cd6fe4a19953e55afa Mon Sep 17 00:00:00 2001 From: Petr Viktorin Date: Tue, 21 May 2013 13:40:27 +0200 Subject: Make an ipa-tests package Rename the 'tests' directory to 'ipa-tests', and create an ipa-tests RPM containing the test suite Part of the work for: https://fedorahosted.org/freeipa/ticket/3654 --- ipatests/test_ipapython/test_cookie.py | 478 +++++++++++++++++++++++++++++++++ 1 file changed, 478 insertions(+) create mode 100644 ipatests/test_ipapython/test_cookie.py (limited to 'ipatests/test_ipapython/test_cookie.py') diff --git a/ipatests/test_ipapython/test_cookie.py b/ipatests/test_ipapython/test_cookie.py new file mode 100644 index 000000000..b8a2d36da --- /dev/null +++ b/ipatests/test_ipapython/test_cookie.py @@ -0,0 +1,478 @@ +# Authors: +# John Dennis +# +# Copyright (C) 2012 Red Hat +# see file 'COPYING' for use and warranty information +# +# This program is free software; you can redistribute it and/or modify +# it under the terms of the GNU General Public License as published by +# the Free Software Foundation, either version 3 of the License, or +# (at your option) any later version. +# +# This program is distributed in the hope that it will be useful, +# but WITHOUT ANY WARRANTY; without even the implied warranty of +# MERCHANTABILITY or FITNESS FOR A PARTICULAR PURPOSE. See the +# GNU General Public License for more details. +# +# You should have received a copy of the GNU General Public License +# along with this program. If not, see . + +import unittest +import time +import datetime +import email.utils +import calendar +from ipapython.cookie import Cookie + +class TestParse(unittest.TestCase): + + def test_parse(self): + # Empty string + s = '' + cookies = Cookie.parse(s) + self.assertEqual(len(cookies), 0) + + # Invalid single token + s = 'color' + with self.assertRaises(ValueError): + cookies = Cookie.parse(s) + + # Invalid single token that's keyword + s = 'HttpOnly' + with self.assertRaises(ValueError): + cookies = Cookie.parse(s) + + # Invalid key/value pair whose key is a keyword + s = 'domain=example.com' + with self.assertRaises(ValueError): + cookies = Cookie.parse(s) + + # 1 cookie with name/value + s = 'color=blue' + cookies = Cookie.parse(s) + self.assertEqual(len(cookies), 1) + cookie = cookies[0] + self.assertEqual(cookie.key, 'color') + self.assertEqual(cookie.value, 'blue') + self.assertEqual(cookie.domain, None) + self.assertEqual(cookie.path, None) + self.assertEqual(cookie.max_age, None) + self.assertEqual(cookie.expires, None) + self.assertEqual(cookie.secure, None) + self.assertEqual(cookie.httponly, None) + self.assertEqual(str(cookie), "color=blue") + self.assertEqual(cookie.http_cookie(), "color=blue;") + + # 1 cookie with whose value is quoted + # Use "get by name" utility to extract specific cookie + s = 'color="blue"' + cookie = Cookie.get_named_cookie_from_string(s, 'color') + self.assertIsNotNone(cookie) + self.assertIsNotNone(cookie, Cookie) + self.assertEqual(cookie.key, 'color') + self.assertEqual(cookie.value, 'blue') + self.assertEqual(cookie.domain, None) + self.assertEqual(cookie.path, None) + self.assertEqual(cookie.max_age, None) + self.assertEqual(cookie.expires, None) + self.assertEqual(cookie.secure, None) + self.assertEqual(cookie.httponly, None) + self.assertEqual(str(cookie), "color=blue") + self.assertEqual(cookie.http_cookie(), "color=blue;") + + # 1 cookie with name/value and domain, path attributes. + # Change up the whitespace a bit. + s = 'color =blue; domain= example.com ; path = /toplevel ' + cookies = Cookie.parse(s) + self.assertEqual(len(cookies), 1) + cookie = cookies[0] + self.assertEqual(cookie.key, 'color') + self.assertEqual(cookie.value, 'blue') + self.assertEqual(cookie.domain, 'example.com') + self.assertEqual(cookie.path, '/toplevel') + self.assertEqual(cookie.max_age, None) + self.assertEqual(cookie.expires, None) + self.assertEqual(cookie.secure, None) + self.assertEqual(cookie.httponly, None) + self.assertEqual(str(cookie), "color=blue; Domain=example.com; Path=/toplevel") + self.assertEqual(cookie.http_cookie(), "color=blue;") + + # 2 cookies, various attributes + s = 'color=blue; Max-Age=3600; temperature=hot; HttpOnly' + cookies = Cookie.parse(s) + self.assertEqual(len(cookies), 2) + cookie = cookies[0] + self.assertEqual(cookie.key, 'color') + self.assertEqual(cookie.value, 'blue') + self.assertEqual(cookie.domain, None) + self.assertEqual(cookie.path, None) + self.assertEqual(cookie.max_age, 3600) + self.assertEqual(cookie.expires, None) + self.assertEqual(cookie.secure, None) + self.assertEqual(cookie.httponly, None) + self.assertEqual(str(cookie), "color=blue; Max-Age=3600") + self.assertEqual(cookie.http_cookie(), "color=blue;") + cookie = cookies[1] + self.assertEqual(cookie.key, 'temperature') + self.assertEqual(cookie.value, 'hot') + self.assertEqual(cookie.domain, None) + self.assertEqual(cookie.path, None) + self.assertEqual(cookie.max_age, None) + self.assertEqual(cookie.expires, None) + self.assertEqual(cookie.secure, None) + self.assertEqual(cookie.httponly, True) + self.assertEqual(str(cookie), "temperature=hot; HttpOnly") + self.assertEqual(cookie.http_cookie(), "temperature=hot;") + +class TestExpires(unittest.TestCase): + + def setUp(self): + # Force microseconds to zero because cookie timestamps only have second resolution + self.now = datetime.datetime.utcnow().replace(microsecond=0) + self.now_timestamp = calendar.timegm(self.now.utctimetuple()) + self.now_string = email.utils.formatdate(self.now_timestamp, usegmt=True) + + self.max_age = 3600 # 1 hour + self.age_expiration = self.now + datetime.timedelta(seconds=self.max_age) + self.age_timestamp = calendar.timegm(self.age_expiration.utctimetuple()) + self.age_string = email.utils.formatdate(self.age_timestamp, usegmt=True) + + self.expires = self.now + datetime.timedelta(days=1) # 1 day + self.expires_timestamp = calendar.timegm(self.expires.utctimetuple()) + self.expires_string = email.utils.formatdate(self.expires_timestamp, usegmt=True) + + def test_expires(self): + # 1 cookie with name/value and no Max-Age and no Expires + s = 'color=blue;' + cookies = Cookie.parse(s) + self.assertEqual(len(cookies), 1) + cookie = cookies[0] + # Force timestamp to known value + cookie.timestamp = self.now + self.assertEqual(cookie.key, 'color') + self.assertEqual(cookie.value, 'blue') + self.assertEqual(cookie.domain, None) + self.assertEqual(cookie.path, None) + self.assertEqual(cookie.max_age, None) + self.assertEqual(cookie.expires, None) + self.assertEqual(cookie.secure, None) + self.assertEqual(cookie.httponly, None) + self.assertEqual(str(cookie), "color=blue") + self.assertEqual(cookie.get_expiration(), None) + # Normalize + self.assertEqual(cookie.normalize_expiration(), None) + self.assertEqual(cookie.max_age, None) + self.assertEqual(cookie.expires, None) + self.assertEqual(str(cookie), "color=blue") + + # 1 cookie with name/value and Max-Age + s = 'color=blue; max-age=%d' % (self.max_age) + cookies = Cookie.parse(s) + self.assertEqual(len(cookies), 1) + cookie = cookies[0] + # Force timestamp to known value + cookie.timestamp = self.now + self.assertEqual(cookie.key, 'color') + self.assertEqual(cookie.value, 'blue') + self.assertEqual(cookie.domain, None) + self.assertEqual(cookie.path, None) + self.assertEqual(cookie.max_age, self.max_age) + self.assertEqual(cookie.expires, None) + self.assertEqual(cookie.secure, None) + self.assertEqual(cookie.httponly, None) + self.assertEqual(str(cookie), "color=blue; Max-Age=%d" % (self.max_age)) + self.assertEqual(cookie.get_expiration(), self.age_expiration) + # Normalize + self.assertEqual(cookie.normalize_expiration(), self.age_expiration) + self.assertEqual(cookie.max_age, None) + self.assertEqual(cookie.expires, self.age_expiration) + self.assertEqual(str(cookie), "color=blue; Expires=%s" % (self.age_string)) + + + # 1 cookie with name/value and Expires + s = 'color=blue; Expires=%s' % (self.expires_string) + cookies = Cookie.parse(s) + self.assertEqual(len(cookies), 1) + cookie = cookies[0] + # Force timestamp to known value + cookie.timestamp = self.now + self.assertEqual(cookie.key, 'color') + self.assertEqual(cookie.value, 'blue') + self.assertEqual(cookie.domain, None) + self.assertEqual(cookie.path, None) + self.assertEqual(cookie.max_age, None) + self.assertEqual(cookie.expires, self.expires) + self.assertEqual(cookie.secure, None) + self.assertEqual(cookie.httponly, None) + self.assertEqual(str(cookie), "color=blue; Expires=%s" % (self.expires_string)) + self.assertEqual(cookie.get_expiration(), self.expires) + # Normalize + self.assertEqual(cookie.normalize_expiration(), self.expires) + self.assertEqual(cookie.max_age, None) + self.assertEqual(cookie.expires, self.expires) + self.assertEqual(str(cookie), "color=blue; Expires=%s" % (self.expires_string)) + + # 1 cookie with name/value witht both Max-Age and Expires, Max-Age takes precedence + s = 'color=blue; Expires=%s; max-age=%d' % (self.expires_string, self.max_age) + cookies = Cookie.parse(s) + self.assertEqual(len(cookies), 1) + cookie = cookies[0] + # Force timestamp to known value + cookie.timestamp = self.now + self.assertEqual(cookie.key, 'color') + self.assertEqual(cookie.value, 'blue') + self.assertEqual(cookie.domain, None) + self.assertEqual(cookie.path, None) + self.assertEqual(cookie.max_age, self.max_age) + self.assertEqual(cookie.expires, self.expires) + self.assertEqual(cookie.secure, None) + self.assertEqual(cookie.httponly, None) + self.assertEqual(str(cookie), "color=blue; Max-Age=%d; Expires=%s" % (self.max_age, self.expires_string)) + self.assertEqual(cookie.get_expiration(), self.age_expiration) + # Normalize + self.assertEqual(cookie.normalize_expiration(), self.age_expiration) + self.assertEqual(cookie.max_age, None) + self.assertEqual(cookie.expires, self.age_expiration) + self.assertEqual(str(cookie), "color=blue; Expires=%s" % (self.age_string)) + + # Verify different types can be assigned to the timestamp and + # expires attribute. + + cookie = Cookie('color', 'blue') + cookie.timestamp = self.now + self.assertEqual(cookie.timestamp, self.now) + cookie.timestamp = self.now_timestamp + self.assertEqual(cookie.timestamp, self.now) + cookie.timestamp = self.now_string + self.assertEqual(cookie.timestamp, self.now) + + self.assertEqual(cookie.expires, None) + + cookie.expires = self.expires + self.assertEqual(cookie.expires, self.expires) + cookie.expires = self.expires_timestamp + self.assertEqual(cookie.expires, self.expires) + cookie.expires = self.expires_string + self.assertEqual(cookie.expires, self.expires) + +class TestInvalidAttributes(unittest.TestCase): + def test_invalid(self): + # Invalid Max-Age + s = 'color=blue; Max-Age=over-the-hill' + with self.assertRaises(ValueError): + cookies = Cookie.parse(s) + + cookie = Cookie('color', 'blue') + with self.assertRaises(ValueError): + cookie.max_age = 'over-the-hill' + + # Invalid Expires + s = 'color=blue; Expires=Sun, 06 Xxx 1994 08:49:37 GMT' + with self.assertRaises(ValueError): + cookies = Cookie.parse(s) + + cookie = Cookie('color', 'blue') + with self.assertRaises(ValueError): + cookie.expires = 'Sun, 06 Xxx 1994 08:49:37 GMT' + + +class TestAttributes(unittest.TestCase): + def test_attributes(self): + cookie = Cookie('color', 'blue') + self.assertEqual(cookie.key, 'color') + self.assertEqual(cookie.value, 'blue') + self.assertEqual(cookie.domain, None) + self.assertEqual(cookie.path, None) + self.assertEqual(cookie.max_age, None) + self.assertEqual(cookie.expires, None) + self.assertEqual(cookie.secure, None) + self.assertEqual(cookie.httponly, None) + + cookie.domain = 'example.com' + self.assertEqual(cookie.domain, 'example.com') + cookie.domain = None + self.assertEqual(cookie.domain, None) + + cookie.path = '/toplevel' + self.assertEqual(cookie.path, '/toplevel') + cookie.path = None + self.assertEqual(cookie.path, None) + + cookie.max_age = 400 + self.assertEqual(cookie.max_age, 400) + cookie.max_age = None + self.assertEqual(cookie.max_age, None) + + cookie.expires = 'Sun, 06 Nov 1994 08:49:37 GMT' + self.assertEqual(cookie.expires, datetime.datetime(1994, 11, 6, 8, 49, 37)) + cookie.expires = None + self.assertEqual(cookie.expires, None) + + cookie.secure = True + self.assertEqual(cookie.secure, True) + self.assertEqual(str(cookie), "color=blue; Secure") + cookie.secure = False + self.assertEqual(cookie.secure, False) + self.assertEqual(str(cookie), "color=blue") + cookie.secure = None + self.assertEqual(cookie.secure, None) + self.assertEqual(str(cookie), "color=blue") + + cookie.httponly = True + self.assertEqual(cookie.httponly, True) + self.assertEqual(str(cookie), "color=blue; HttpOnly") + cookie.httponly = False + self.assertEqual(cookie.httponly, False) + self.assertEqual(str(cookie), "color=blue") + cookie.httponly = None + self.assertEqual(cookie.httponly, None) + self.assertEqual(str(cookie), "color=blue") + + +class TestHTTPReturn(unittest.TestCase): + def setUp(self): + self.url = 'http://www.foo.bar.com/one/two' + + def test_no_attributes(self): + cookie = Cookie('color', 'blue') + self.assertTrue(cookie.http_return_ok(self.url)) + + def test_domain(self): + cookie = Cookie('color', 'blue', domain='www.foo.bar.com') + self.assertTrue(cookie.http_return_ok(self.url)) + + cookie = Cookie('color', 'blue', domain='.foo.bar.com') + self.assertTrue(cookie.http_return_ok(self.url)) + + cookie = Cookie('color', 'blue', domain='.bar.com') + self.assertTrue(cookie.http_return_ok(self.url)) + + cookie = Cookie('color', 'blue', domain='bar.com') + with self.assertRaises(Cookie.URLMismatch): + self.assertTrue(cookie.http_return_ok(self.url)) + + cookie = Cookie('color', 'blue', domain='bogus.com') + with self.assertRaises(Cookie.URLMismatch): + self.assertTrue(cookie.http_return_ok(self.url)) + + cookie = Cookie('color', 'blue', domain='www.foo.bar.com') + with self.assertRaises(Cookie.URLMismatch): + self.assertTrue(cookie.http_return_ok('http://192.168.1.1/one/two')) + + def test_path(self): + cookie = Cookie('color', 'blue') + self.assertTrue(cookie.http_return_ok(self.url)) + + cookie = Cookie('color', 'blue', path='/') + self.assertTrue(cookie.http_return_ok(self.url)) + + cookie = Cookie('color', 'blue', path='/one') + self.assertTrue(cookie.http_return_ok(self.url)) + + cookie = Cookie('color', 'blue', path='/oneX') + with self.assertRaises(Cookie.URLMismatch): + self.assertTrue(cookie.http_return_ok(self.url)) + + def test_expires(self): + now = datetime.datetime.utcnow().replace(microsecond=0) + + # expires 1 day from now + expires = now + datetime.timedelta(days=1) + + cookie = Cookie('color', 'blue', expires=expires) + self.assertTrue(cookie.http_return_ok(self.url)) + + # expired 1 day ago + expires = now + datetime.timedelta(days=-1) + cookie = Cookie('color', 'blue', expires=expires) + with self.assertRaises(Cookie.Expired): + self.assertTrue(cookie.http_return_ok(self.url)) + + + def test_httponly(self): + cookie = Cookie('color', 'blue', httponly=True) + self.assertTrue(cookie.http_return_ok('http://example.com')) + self.assertTrue(cookie.http_return_ok('https://example.com')) + + with self.assertRaises(Cookie.URLMismatch): + self.assertTrue(cookie.http_return_ok('ftp://example.com')) + + def test_secure(self): + cookie = Cookie('color', 'blue', secure=True) + self.assertTrue(cookie.http_return_ok('https://Xexample.com')) + + with self.assertRaises(Cookie.URLMismatch): + self.assertTrue(cookie.http_return_ok('http://Xexample.com')) + +class TestNormalization(unittest.TestCase): + def setUp(self): + # Force microseconds to zero because cookie timestamps only have second resolution + self.now = datetime.datetime.utcnow().replace(microsecond=0) + self.now_timestamp = calendar.timegm(self.now.utctimetuple()) + self.now_string = email.utils.formatdate(self.now_timestamp, usegmt=True) + + self.max_age = 3600 # 1 hour + self.age_expiration = self.now + datetime.timedelta(seconds=self.max_age) + self.age_timestamp = calendar.timegm(self.age_expiration.utctimetuple()) + self.age_string = email.utils.formatdate(self.age_timestamp, usegmt=True) + + self.expires = self.now + datetime.timedelta(days=1) # 1 day + self.expires_timestamp = calendar.timegm(self.expires.utctimetuple()) + self.expires_string = email.utils.formatdate(self.expires_timestamp, usegmt=True) + + def test_path_normalization(self): + self.assertEqual(Cookie.normalize_url_path(''), '/') + self.assertEqual(Cookie.normalize_url_path('foo'), '/') + self.assertEqual(Cookie.normalize_url_path('foo/'), '/') + self.assertEqual(Cookie.normalize_url_path('/foo'), '/') + self.assertEqual(Cookie.normalize_url_path('/foo/'), '/foo') + self.assertEqual(Cookie.normalize_url_path('/Foo/bar'), '/foo') + self.assertEqual(Cookie.normalize_url_path('/foo/baR/'), '/foo/bar') + + def test_normalization(self): + cookie = Cookie('color', 'blue', expires=self.expires) + cookie.timestamp = self.now_timestamp + + self.assertEqual(cookie.domain, None) + self.assertEqual(cookie.path, None) + + url = 'http://example.COM/foo' + cookie.normalize(url) + self.assertEqual(cookie.domain, 'example.com') + self.assertEqual(cookie.path, '/') + self.assertEqual(cookie.expires, self.expires) + + cookie = Cookie('color', 'blue', max_age=self.max_age) + cookie.timestamp = self.now_timestamp + + self.assertEqual(cookie.domain, None) + self.assertEqual(cookie.path, None) + + url = 'http://example.com/foo/' + cookie.normalize(url) + self.assertEqual(cookie.domain, 'example.com') + self.assertEqual(cookie.path, '/foo') + self.assertEqual(cookie.expires, self.age_expiration) + + cookie = Cookie('color', 'blue') + url = 'http://example.com/foo' + cookie.normalize(url) + self.assertEqual(cookie.domain, 'example.com') + self.assertEqual(cookie.path, '/') + + cookie = Cookie('color', 'blue') + url = 'http://example.com/foo/bar' + cookie.normalize(url) + self.assertEqual(cookie.domain, 'example.com') + self.assertEqual(cookie.path, '/foo') + + cookie = Cookie('color', 'blue') + url = 'http://example.com/foo/bar/' + cookie.normalize(url) + self.assertEqual(cookie.domain, 'example.com') + self.assertEqual(cookie.path, '/foo/bar') + + +#------------------------------------------------------------------------------- +if __name__ == '__main__': + unittest.main() -- cgit