[ARVADOS] updated: 35a26ea6b98639a1313a5ece76c78b15964dde1f
git at public.curoverse.com
git at public.curoverse.com
Tue Aug 11 10:51:37 EDT 2015
Summary of changes:
sdk/pam/arvados_pam/__init__.py | 102 ++-------------------
sdk/pam/arvados_pam/{__init__.py => auth_event.py} | 53 +----------
sdk/pam/tests/mocker.py | 59 ++++++++++++
sdk/pam/tests/{test_pam.py => test_auth_event.py} | 73 ++-------------
sdk/pam/tests/test_pam_sm.py | 26 ++++++
5 files changed, 101 insertions(+), 212 deletions(-)
copy sdk/pam/arvados_pam/{__init__.py => auth_event.py} (71%)
create mode 100644 sdk/pam/tests/mocker.py
rename sdk/pam/tests/{test_pam.py => test_auth_event.py} (57%)
create mode 100644 sdk/pam/tests/test_pam_sm.py
via 35a26ea6b98639a1313a5ece76c78b15964dde1f (commit)
via 110f03773d2f1187f173c2615b583969b3baef6e (commit)
from 982a80e54bef92b3c942a1e7f6924980b74d1ef4 (commit)
Those revisions listed above that are new to this repository have
not appeared on any other notification email; so we list those
revisions in full, below.
commit 35a26ea6b98639a1313a5ece76c78b15964dde1f
Author: Tom Clegg <tom at curoverse.com>
Date: Tue Aug 11 10:46:28 2015 -0400
6934: Add pam_sm tests.
diff --git a/sdk/pam/tests/test_pam_sm.py b/sdk/pam/tests/test_pam_sm.py
new file mode 100644
index 0000000..a967493
--- /dev/null
+++ b/sdk/pam/tests/test_pam_sm.py
@@ -0,0 +1,26 @@
+import arvados_pam
+import mock
+from . import mocker
+
+class PamSMTest(mocker.Mocker):
+ def attempt(self):
+ return arvados_pam.pam_sm_authenticate(self.pamh, 0, self.argv)
+
+ def test_success(self):
+ self.assertEqual(self.pamh.PAM_SUCCESS, self.attempt())
+
+ def test_bad_user(self):
+ self.pamh.get_user = mock.MagicMock(return_value='badusername')
+ self.assertEqual(self.pamh.PAM_AUTH_ERR, self.attempt())
+
+ def test_bad_vm(self):
+ self.argv[2] = 'testvm22.shell'
+ self.assertEqual(self.pamh.PAM_AUTH_ERR, self.attempt())
+
+ def setUp(self):
+ super(PamSMTest, self).setUp()
+ self.pamh = mock.MagicMock()
+ self.pamh.get_user = mock.MagicMock(return_value='active')
+ self.pamh.PAM_SUCCESS = 12345
+ self.pamh.PAM_AUTH_ERR = 54321
+ self.argv = [__file__, 'zzzzz.arvadosapi.com', 'testvm2.shell']
commit 110f03773d2f1187f173c2615b583969b3baef6e
Author: Tom Clegg <tom at curoverse.com>
Date: Tue Aug 11 10:32:49 2015 -0400
6934: Split module
diff --git a/sdk/pam/arvados_pam/__init__.py b/sdk/pam/arvados_pam/__init__.py
index 1ec6a3a..087ea2e 100644
--- a/sdk/pam/arvados_pam/__init__.py
+++ b/sdk/pam/arvados_pam/__init__.py
@@ -1,96 +1,7 @@
import sys
sys.argv=['']
-import arvados
-import os
-import syslog
-
-def auth_log(msg):
- """Log an authentication result to syslogd"""
- syslog.openlog(facility=syslog.LOG_AUTH)
- syslog.syslog('arvados_pam: ' + msg)
- syslog.closelog()
-
-class AuthEvent(object):
- def __init__(self, config, service, client_host, username, token):
- self.config = config
- self.service = service
- self.client_host = client_host
- self.username = username
- self.token = token
-
- self.api_host = None
- self.vm_uuid = None
- self.user = None
-
- def can_login(self):
- """Return truthy IFF credentials should be accepted."""
- ok = False
- try:
- self.api_host = self.config['arvados_api_host']
- self.arv = arvados.api('v1', host=self.api_host, token=self.token,
- insecure=self.config.get('insecure'),
- cache=False)
-
- vmname = self.config['virtual_machine_hostname']
- vms = self.arv.virtual_machines().list(filters=[['hostname','=',vmname]]).execute()
- if vms['items_available'] > 1:
- raise Exception("lookup hostname %s returned %d records" % (vmname, vms['items_available']))
- if vms['items_available'] == 0:
- raise Exception("lookup hostname %s not found" % vmname)
- vm = vms['items'][0]
- if vm['hostname'] != vmname:
- raise Exception("lookup hostname %s returned hostname %s" % (vmname, vm['hostname']))
- self.vm_uuid = vm['uuid']
-
- self.user = self.arv.users().current().execute()
-
- filters = [
- ['link_class','=','permission'],
- ['name','=','can_login'],
- ['head_uuid','=',self.vm_uuid],
- ['tail_uuid','=',self.user['uuid']]]
- for l in self.arv.links().list(filters=filters, limit=10000).execute()['items']:
- if (l['properties']['username'] == self.username and
- l['tail_uuid'] == self.user['uuid'] and
- l['head_uuid'] == self.vm_uuid and
- l['link_class'] == 'permission' and
- l['name'] == 'can_login'):
- return self._report(True)
-
- return self._report(False)
-
- except Exception as e:
- return self._report(e)
-
- def _report(self, result):
- """Log the result. Return truthy IFF result is True.
-
- result must be True, False, or an exception.
- """
- self.result = result
- auth_log(self.message())
- return result == True
-
- def message(self):
- """Return a log message describing the event and its outcome."""
- if isinstance(self.result, Exception):
- outcome = 'Error: ' + repr(self.result)
- elif self.result == True:
- outcome = 'Allow'
- else:
- outcome = 'Deny'
-
- if len(self.token) > 40:
- log_token = self.token[0:15]
- else:
- log_token = '<invalid>'
-
- log_label = [self.service, self.api_host, self.vm_uuid, self.client_host, self.username, log_token]
- if self.user:
- log_label += [self.user.get('uuid'), self.user.get('full_name')]
- return str(log_label) + ': ' + outcome
-
+from . import auth_event
def pam_sm_authenticate(pamh, flags, argv):
config = {}
@@ -114,11 +25,12 @@ def pam_sm_authenticate(pamh, flags, argv):
except pamh.exception as e:
return e.pam_result
- if AuthEvent(config,
- service=pamh.service,
- client_host=pamh.rhost,
- username=username,
- token=token).can_login():
+ if auth_event.AuthEvent(
+ config=config,
+ service=pamh.service,
+ client_host=pamh.rhost,
+ username=username,
+ token=token).can_login():
return pamh.PAM_SUCCESS
else:
return pamh.PAM_AUTH_ERR
diff --git a/sdk/pam/arvados_pam/__init__.py b/sdk/pam/arvados_pam/auth_event.py
similarity index 71%
copy from sdk/pam/arvados_pam/__init__.py
copy to sdk/pam/arvados_pam/auth_event.py
index 1ec6a3a..8abd9c5 100644
--- a/sdk/pam/arvados_pam/__init__.py
+++ b/sdk/pam/arvados_pam/auth_event.py
@@ -1,8 +1,4 @@
-import sys
-sys.argv=['']
-
import arvados
-import os
import syslog
def auth_log(msg):
@@ -29,7 +25,7 @@ class AuthEvent(object):
try:
self.api_host = self.config['arvados_api_host']
self.arv = arvados.api('v1', host=self.api_host, token=self.token,
- insecure=self.config.get('insecure'),
+ insecure=self.config.get('insecure', False),
cache=False)
vmname = self.config['virtual_machine_hostname']
@@ -90,50 +86,3 @@ class AuthEvent(object):
if self.user:
log_label += [self.user.get('uuid'), self.user.get('full_name')]
return str(log_label) + ': ' + outcome
-
-
-def pam_sm_authenticate(pamh, flags, argv):
- config = {}
- config['arvados_api_host'] = argv[1]
- config['virtual_machine_hostname'] = argv[2]
- if len(argv) > 3:
- for k in argv[3:]:
- config[k] = True
-
- try:
- username = pamh.get_user(None)
- except pamh.exception, e:
- return e.pam_result
-
- if not username:
- return pamh.PAM_USER_UNKNOWN
-
- try:
- prompt = '' if config.get('noprompt') else 'Arvados API token: '
- token = pamh.conversation(pamh.Message(pamh.PAM_PROMPT_ECHO_OFF, prompt)).resp
- except pamh.exception as e:
- return e.pam_result
-
- if AuthEvent(config,
- service=pamh.service,
- client_host=pamh.rhost,
- username=username,
- token=token).can_login():
- return pamh.PAM_SUCCESS
- else:
- return pamh.PAM_AUTH_ERR
-
-def pam_sm_setcred(pamh, flags, argv):
- return pamh.PAM_SUCCESS
-
-def pam_sm_acct_mgmt(pamh, flags, argv):
- return pamh.PAM_SUCCESS
-
-def pam_sm_open_session(pamh, flags, argv):
- return pamh.PAM_SUCCESS
-
-def pam_sm_close_session(pamh, flags, argv):
- return pamh.PAM_SUCCESS
-
-def pam_sm_chauthtok(pamh, flags, argv):
- return pamh.PAM_SUCCESS
diff --git a/sdk/pam/tests/mocker.py b/sdk/pam/tests/mocker.py
new file mode 100644
index 0000000..76c1ea3
--- /dev/null
+++ b/sdk/pam/tests/mocker.py
@@ -0,0 +1,59 @@
+import mock
+import unittest
+
+class Mocker(unittest.TestCase):
+ ACTIVE_TOKEN = '3kg6k6lzmp9kj5cpkcoxie963cmvjahbt2fod9zru30k1jqdmi'
+
+ default_config = {
+ 'arvados_api_host': 'zzzzz.api_host.example',
+ 'virtual_machine_hostname': 'testvm2.shell',
+ }
+ default_request = {
+ 'client_host': '::1',
+ 'token': ACTIVE_TOKEN,
+ 'username': 'active',
+ }
+ default_response = {
+ 'links': {
+ 'items': [{
+ 'uuid': 'zzzzz-o0j2j-rah2ya1ohx9xaev',
+ 'tail_uuid': 'zzzzz-tpzed-xurymjxw79nv3jz',
+ 'head_uuid': 'zzzzz-2x53u-382brsig8rp3065',
+ 'link_class': 'permission',
+ 'name': 'can_login',
+ 'properties': {
+ 'username': 'active',
+ },
+ }],
+ },
+ 'users': {
+ 'uuid': 'zzzzz-tpzed-xurymjxw79nv3jz',
+ 'full_name': 'Active User',
+ },
+ 'virtual_machines': {
+ 'items': [{
+ 'uuid': 'zzzzz-2x53u-382brsig8rp3065',
+ 'hostname': 'testvm2.shell',
+ }],
+ 'items_available': 1,
+ },
+ }
+
+ def setUp(self):
+ self.config = self.default_config.copy()
+ self.request = self.default_request.copy()
+ self.response = self.default_response.copy()
+ self.api_client = mock.MagicMock(name='api_client')
+ self.api_client.users().current().execute.side_effect = lambda: self.response['users']
+ self.api_client.virtual_machines().list().execute.side_effect = lambda: self.response['virtual_machines']
+ self.api_client.links().list().execute.side_effect = lambda: self.response['links']
+ patcher = mock.patch('arvados.api')
+ self.api = patcher.start()
+ self.addCleanup(patcher.stop)
+ self.api.side_effect = [self.api_client]
+
+ self.syslogged = []
+ patcher = mock.patch('syslog.syslog')
+ self.syslog = patcher.start()
+ self.addCleanup(patcher.stop)
+ self.syslog.side_effect = lambda s: self.syslogged.append(s)
diff --git a/sdk/pam/tests/test_pam.py b/sdk/pam/tests/test_auth_event.py
similarity index 57%
rename from sdk/pam/tests/test_pam.py
rename to sdk/pam/tests/test_auth_event.py
index c9c0c36..3fb6d74 100644
--- a/sdk/pam/tests/test_pam.py
+++ b/sdk/pam/tests/test_auth_event.py
@@ -1,51 +1,10 @@
-import arvados
import arvados_pam
-import mock
-import os
import re
-import StringIO
-import unittest
-
-ACTIVE_TOKEN = '3kg6k6lzmp9kj5cpkcoxie963cmvjahbt2fod9zru30k1jqdmi'
-
-class AuthTest(unittest.TestCase):
- default_config = {
- 'ARVADOS_API_HOST': 'zzzzz.api_host.example',
- 'virtual_machine_hostname': 'testvm2.shell',
- }
- default_request = {
- 'client_host': '::1',
- 'token': ACTIVE_TOKEN,
- 'username': 'active',
- }
- default_response = {
- 'links': {
- 'items': [{
- 'uuid': 'zzzzz-o0j2j-rah2ya1ohx9xaev',
- 'tail_uuid': 'zzzzz-tpzed-xurymjxw79nv3jz',
- 'head_uuid': 'zzzzz-2x53u-382brsig8rp3065',
- 'link_class': 'permission',
- 'name': 'can_login',
- 'properties': {
- 'username': 'active',
- },
- }],
- },
- 'users': {
- 'uuid': 'zzzzz-tpzed-xurymjxw79nv3jz',
- 'full_name': 'Active User',
- },
- 'virtual_machines': {
- 'items': [{
- 'uuid': 'zzzzz-2x53u-382brsig8rp3065',
- 'hostname': 'testvm2.shell',
- }],
- 'items_available': 1,
- },
- }
+from . import mocker
+class AuthEventTest(mocker.Mocker):
def attempt(self):
- return arvados_pam.AuthEvent(config=self.config, service='test_service', **self.request).can_login()
+ return arvados_pam.auth_event.AuthEvent(config=self.config, service='test_service', **self.request).can_login()
def test_success(self):
self.assertTrue(self.attempt())
@@ -53,11 +12,14 @@ class AuthTest(unittest.TestCase):
self.api_client.virtual_machines().list.assert_called_with(
filters=[['hostname','=',self.config['virtual_machine_hostname']]])
self.api.assert_called_with(
- 'v1', host=self.config['ARVADOS_API_HOST'], token=self.request['token'], cache=None)
+ 'v1',
+ host=self.config['arvados_api_host'], token=self.request['token'],
+ insecure=False,
+ cache=False)
self.assertEqual(1, len(self.syslogged))
for i in ['test_service',
self.request['username'],
- self.config['ARVADOS_API_HOST'],
+ self.config['arvados_api_host'],
self.response['virtual_machines']['items'][0]['uuid']]:
self.assertRegexpMatches(self.syslogged[0], re.escape(i))
self.assertRegexpMatches(self.syslogged[0], re.escape(self.request['token'][0:15]), 'token prefix not logged')
@@ -131,22 +93,3 @@ class AuthTest(unittest.TestCase):
}],
}
self.assertFalse(self.attempt())
-
- def setUp(self):
- self.config = self.default_config.copy()
- self.request = self.default_request.copy()
- self.response = self.default_response.copy()
- self.api_client = mock.MagicMock(name='api_client')
- self.api_client.users().current().execute.side_effect = lambda: self.response['users']
- self.api_client.virtual_machines().list().execute.side_effect = lambda: self.response['virtual_machines']
- self.api_client.links().list().execute.side_effect = lambda: self.response['links']
- patcher = mock.patch('arvados.api')
- self.api = patcher.start()
- self.addCleanup(patcher.stop)
- self.api.side_effect = [self.api_client]
-
- self.syslogged = []
- patcher = mock.patch('syslog.syslog')
- self.syslog = patcher.start()
- self.addCleanup(patcher.stop)
- self.syslog.side_effect = lambda s: self.syslogged.append(s)
-----------------------------------------------------------------------
hooks/post-receive
--
More information about the arvados-commits
mailing list