diff --git a/doc/source/examples.rst b/doc/source/examples.rst index 83911b4..8077fb6 100644 --- a/doc/source/examples.rst +++ b/doc/source/examples.rst @@ -18,10 +18,13 @@ retrieve the Jenkins server version. import jenkins server = jenkins.Jenkins('http://localhost:8080', username='myuser', password='mypassword') + user = server.get_whoami() version = server.get_version() - print version + print('Hello %s from Jenkins %s' % (user['fullName'], jenkins_version)) -The above code prints the version of the Jenkins master running on 'localhost:8080' +The above code prints the the fullName attribute of the user and the version of +the Jenkins master running on 'localhost:8080'. For example, it may print +"Hello John from Jenkins 2.0". From Jenkins vesion 1.426 onward you can specify an API token instead of your real password while authenticating the user against the Jenkins instance. diff --git a/jenkins/__init__.py b/jenkins/__init__.py index ee9dc7d..6bc09c7 100644 --- a/jenkins/__init__.py +++ b/jenkins/__init__.py @@ -90,6 +90,7 @@ DEFAULT_HEADERS = {'Content-Type': 'text/xml; charset=utf-8'} INFO = 'api/json' PLUGIN_INFO = 'pluginManager/api/json?depth=%(depth)s' CRUMB_URL = 'crumbIssuer/api/json' +WHOAMI_URL = 'me/api/json' JOBS_QUERY = '?tree=jobs[url,color,name,jobs]' JOB_INFO = '%(folder_url)sjob/%(short_name)s/api/json?depth=%(depth)s' JOB_NAME = '%(folder_url)sjob/%(short_name)s/api/json?tree=name' @@ -514,6 +515,33 @@ class Jenkins(object): raise JenkinsException("Could not parse JSON info for server[%s]" % self.server) + def get_whoami(self): + """Get information about the user account that authenticated to + Jenkins. This is a simple way to verify that your credentials are + correct. + + :returns: Information about the current user ``dict`` + + Example:: + + >>> me = server.get_whoami() + >>> print me['fullName'] + >>> 'John' + + """ + try: + response = self.jenkins_open(Request(self._build_url(WHOAMI_URL))) + if response is None: + raise EmptyResponseException( + "Error communicating with server[%s]: " + "empty response" % self.server) + + return json.loads(response) + + except (HTTPError, BadStatusLine): + raise BadHTTPException("Error communicating with server[%s]" + % self.server) + def get_version(self): """Get the version of this Master. diff --git a/tests/test_whoami.py b/tests/test_whoami.py new file mode 100644 index 0000000..e449011 --- /dev/null +++ b/tests/test_whoami.py @@ -0,0 +1,50 @@ +import json +from mock import patch + +import jenkins +from tests.base import JenkinsTestBase + + +class JenkinsWhoamiTest(JenkinsTestBase): + + @patch.object(jenkins.Jenkins, 'jenkins_open') + def test_simple(self, jenkins_mock): + user_to_return = \ + {u'absoluteUrl': u'https://example.com/jenkins/user/jsmith', + u'description': None, + u'fullName': u'John Smith', + u'id': u'jsmith', + u'property': [{}, + {}, + {}, + {u'address': u'jsmith@example.com'}, + {}, + {}, + {u'insensitiveSearch': False}, + {}]} + + jenkins_mock.return_value = json.dumps(user_to_return) + + user = self.j.get_whoami() + + self.assertEqual(user, user_to_return) + self.assertEqual( + jenkins_mock.call_args[0][0].get_full_url(), + self.make_url('me/api/json')) + self._check_requests(jenkins_mock.call_args_list) + + @patch.object(jenkins.Jenkins, 'jenkins_open') + def test_raise_HTTPError(self, jenkins_mock): + jenkins_mock.side_effect = jenkins.HTTPError( + self.make_url('me/api/json'), + code=401, + msg='basic auth failed', + hdrs=[], + fp=None) + + with self.assertRaises(jenkins.JenkinsException): + self.j.get_whoami() + self.assertEqual( + jenkins_mock.call_args[0][0].get_full_url(), + self.make_url('me/api/json')) + self._check_requests(jenkins_mock.call_args_list)