From 5405fd7927ef68015c25632951a94bcddb60c33d Mon Sep 17 00:00:00 2001 From: Prashanth Pai Date: Mon, 18 Nov 2013 15:40:47 +0530 Subject: Feature: Support client outside domain Until now, all clients had to be part of Kerberos domain as authentication was done by mod_auth_kerb module of httpd by using Kerberos Ticket bundled with the request. To suport clients residing outside domain, we introduce a configurable option called "auth_mode". When auth_mode is set to 'passive', a client residing outside domain can authenticate itself by sending username(X-Auth-User) and password(X-Auth-Key) as request headers. This information is gleaned from the request and kinit is run against it. A successful kinit means the username and password exists on the Kerberos server. Change-Id: I1a165bd56bc3a425b00bcfdbf32150c14b5d9790 Signed-off-by: Prashanth Pai Reviewed-on: http://review.gluster.org/6296 Reviewed-by: Chetan Risbud Tested-by: Chetan Risbud Reviewed-by: Luis Pabon Tested-by: Luis Pabon --- test/unit/test_kerbauth.py | 87 +++++++++++++++++++++++++++++++++++++++++++++- 1 file changed, 86 insertions(+), 1 deletion(-) (limited to 'test/unit/test_kerbauth.py') diff --git a/test/unit/test_kerbauth.py b/test/unit/test_kerbauth.py index 1771314..471ff58 100644 --- a/test/unit/test_kerbauth.py +++ b/test/unit/test_kerbauth.py @@ -13,9 +13,11 @@ # See the License for the specific language governing permissions and # limitations under the License. +import os +import errno import unittest from time import time - +from mock import patch, Mock from swiftkerbauth import kerbauth as auth from test.unit import FakeMemcache from swift.common.swob import Request, Response @@ -79,6 +81,8 @@ class TestAuth(unittest.TestCase): def setUp(self): self.test_auth = auth.filter_factory({})(FakeApp()) + self.test_auth_passive = \ + auth.filter_factory({'auth_method': 'passive'})(FakeApp()) def _make_request(self, path, **kwargs): req = Request.blank(path, **kwargs) @@ -130,6 +134,19 @@ class TestAuth(unittest.TestCase): self.assertEquals(req.environ['swift.authorize'], self.test_auth.denied_response) + def test_passive_top_level_deny(self): + req = self._make_request('/') + resp = req.get_response(self.test_auth_passive) + self.assertEquals(resp.status_int, 401) + self.assertEquals(req.environ['swift.authorize'], + self.test_auth_passive.denied_response) + + def test_passive_deny_invalid_token(self): + req = self._make_request('/v1/AUTH_account', + headers={'X-Auth-Token': 'AUTH_t'}) + resp = req.get_response(self.test_auth_passive) + self.assertEquals(resp.status_int, 401) + def test_override_asked_for_and_allowed(self): self.test_auth = \ auth.filter_factory({'allow_overrides': 'true'})(FakeApp()) @@ -249,6 +266,74 @@ class TestAuth(unittest.TestCase): resp = self.test_auth.handle_get_token(req) self.assertEquals(resp.status_int, 404) + def test_passive_handle_get_token_no_user_or_key(self): + #No user and key + req = self._make_request('/auth/v1.0') + resp = self.test_auth_passive.handle_get_token(req) + self.assertEquals(resp.status_int, REDIRECT_STATUS) + #User given but no key + req = self._make_request('/auth/v1.0', + headers={'X-Auth-User': 'blah'}) + resp = self.test_auth_passive.handle_get_token(req) + self.assertEquals(resp.status_int, 401) + + def test_passive_handle_get_token_no_kinit(self): + req = self._make_request('/auth/v1.0', + headers={'X-Auth-User': 'user', + 'X-Auth-Key': 'password'}) + _mock_run_kinit = Mock(side_effect=OSError(errno.ENOENT, + os.strerror(errno.ENOENT))) + with patch('swiftkerbauth.kerbauth.run_kinit', _mock_run_kinit): + resp = self.test_auth_passive.handle_get_token(req) + self.assertEquals(resp.status_int, 500) + self.assertIn("kinit command not found", resp.body) + _mock_run_kinit.assert_called_once_with('user', 'password') + + def test_passive_handle_get_token_kinit_fail(self): + req = self._make_request('/auth/v1.0', + headers={'X-Auth-User': 'user', + 'X-Auth-Key': 'password'}) + _mock_run_kinit = Mock(return_value=1) + with patch('swiftkerbauth.kerbauth.run_kinit', _mock_run_kinit): + resp = self.test_auth_passive.handle_get_token(req) + self.assertEquals(resp.status_int, 401) + _mock_run_kinit.assert_called_once_with('user', 'password') + + def test_passive_handle_get_token_kinit_success_token_not_present(self): + req = self._make_request('/auth/v1.0', + headers={'X-Auth-User': 'user', + 'X-Auth-Key': 'password'}) + _mock_run_kinit = Mock(return_value=0) + _mock_get_groups = Mock(return_value="user,admins") + with patch('swiftkerbauth.kerbauth.run_kinit', _mock_run_kinit): + with patch('swiftkerbauth.kerbauth.get_groups_from_username', + _mock_get_groups): + resp = self.test_auth_passive.handle_get_token(req) + _mock_run_kinit.assert_called_once_with('user', 'password') + _mock_run_kinit.assert_called_once_with('user', 'password') + _mock_get_groups.assert_called_once_with('user') + self.assertEquals(resp.status_int, 200) + self.assertIsNotNone(resp.headers['X-Auth-Token']) + self.assertIsNotNone(resp.headers['X-Storage-Token']) + + def test_passive_handle_get_token_kinit_realm_and_memcache(self): + req = self._make_request('/auth/v1.0', + headers={'X-Auth-User': 'user', + 'X-Auth-Key': 'password'}) + req.environ['swift.cache'] = None + _auth_passive = \ + auth.filter_factory({'auth_method': 'passive', + 'realm_name': 'EXAMPLE.COM'})(FakeApp()) + _mock_run_kinit = Mock(return_value=0) + with patch('swiftkerbauth.kerbauth.run_kinit', _mock_run_kinit): + try: + _auth_passive.handle_get_token(req) + except Exception as e: + self.assertTrue(e.args[0].startswith("Memcache required")) + else: + self.fail("Expected Exception - Memcache required") + _mock_run_kinit.assert_called_once_with('user@EXAMPLE.COM', 'password') + def test_handle(self): req = self._make_request('/auth/v1.0') resp = req.get_response(self.test_auth) -- cgit