diff options
-rw-r--r-- | docs/api-usage.rst | 10 | ||||
-rw-r--r-- | gitlab/__init__.py | 57 | ||||
-rw-r--r-- | gitlab/tests/test_gitlab.py | 49 |
3 files changed, 89 insertions, 27 deletions
diff --git a/docs/api-usage.rst b/docs/api-usage.rst index edd41d0..f60c0dc 100644 --- a/docs/api-usage.rst +++ b/docs/api-usage.rst @@ -20,11 +20,17 @@ To connect to a GitLab server, create a ``gitlab.Gitlab`` object: import gitlab # private token authentication - gl = gitlab.Gitlab('http://10.0.0.1', 'JVNSESs8EwWRx5yDxM5q') + gl = gitlab.Gitlab('http://10.0.0.1', private_token='JVNSESs8EwWRx5yDxM5q') - # or username/password authentication + # oauth token authentication + gl = gitlab.Gitlab('http://10.0.0.1', oauth_token='my_long_token_here') + + # username/password authentication gl = gitlab.Gitlab('http://10.0.0.1', email='jdoe', password='s3cr3t') + # anonymous gitlab instance, read-only for public resources + gl = gitlab.Gitlab('http://10.0.0.1') + # make an API request to create the gl.user object. This is mandatory if you # use the username/password authentication. gl.auth() diff --git a/gitlab/__init__.py b/gitlab/__init__.py index 905c4cd..5099349 100644 --- a/gitlab/__init__.py +++ b/gitlab/__init__.py @@ -59,6 +59,7 @@ class Gitlab(object): Args: url (str): The URL of the GitLab server. private_token (str): The user private token + oauth_token (str): An oauth token email (str): The user email or login. password (str): The user password (associated with email). ssl_verify (bool|str): Whether SSL certificates should be validated. If @@ -82,7 +83,6 @@ class Gitlab(object): self.timeout = timeout #: Headers that will be used in request to GitLab self.headers = {} - self._set_token(private_token, oauth_token) #: The user email self.email = email @@ -90,8 +90,12 @@ class Gitlab(object): self.password = password #: Whether SSL certificates should be validated self.ssl_verify = ssl_verify + + self.private_token = private_token self.http_username = http_username self.http_password = http_password + self.oauth_token = oauth_token + self._set_auth_info() #: Create a session object for requests self.session = session or requests.Session() @@ -192,15 +196,12 @@ class Gitlab(object): The `user` attribute will hold a `gitlab.objects.CurrentUser` object on success. """ - if self.private_token: + if self.private_token or self.oauth_token: self._token_auth() else: self._credentials_auth() def _credentials_auth(self): - if not self.email or not self.password: - raise GitlabAuthenticationError("Missing email/password") - data = {'email': self.email, 'password': self.password} if self.api_version == '3': r = self._raw_post('/session', json.dumps(data), @@ -211,8 +212,8 @@ class Gitlab(object): r = self.http_post('/session', data) manager = self._objects.CurrentUserManager(self) self.user = self._objects.CurrentUser(manager, r) - - self._set_token(self.user.private_token) + self.private_token = self.user.private_token + self._set_auth_info() def _token_auth(self): if self.api_version == '3': @@ -267,18 +268,30 @@ class Gitlab(object): else: return url - def _set_token(self, private_token, oauth_token=None): - self.private_token = private_token if private_token else None - self.oauth_token = oauth_token if oauth_token else None + def _set_auth_info(self): + if self.private_token and self.oauth_token: + raise ValueError("Only one of private_token or oauth_token should " + "be defined") + if ((self.http_username and not self.http_password) + or (not self.http_username and self.http_password)): + raise ValueError("Both http_username and http_password should " + "be defined") + if self.oauth_token and self.http_username: + raise ValueError("Only one of oauth authentication or http " + "authentication should be defined") + + self._http_auth = None + if self.private_token: + self.headers['PRIVATE-TOKEN'] = self.private_token + self.headers.pop('Authorization', None) + + if self.oauth_token: + self.headers['Authorization'] = "Bearer %s" % self.oauth_token + self.headers.pop('PRIVATE-TOKEN', None) - if private_token: - self.headers["PRIVATE-TOKEN"] = private_token - if 'Authorization' in self.headers: - del self.headers["Authorization"] - elif oauth_token: - self.headers['Authorization'] = "Bearer %s" % oauth_token - if "PRIVATE-TOKEN" in self.headers: - del self.headers["PRIVATE-TOKEN"] + if self.http_username: + self._http_auth = requests.auth.HTTPBasicAuth(self.http_username, + self.http_password) def enable_debug(self): import logging @@ -300,16 +313,10 @@ class Gitlab(object): request_headers['Content-type'] = content_type return request_headers - def _create_auth(self): - if self.http_username and self.http_password: - return requests.auth.HTTPBasicAuth(self.http_username, - self.http_password) - return None - def _get_session_opts(self, content_type): return { 'headers': self._create_headers(content_type), - 'auth': self._create_auth(), + 'auth': self._http_auth, 'timeout': self.timeout, 'verify': self.ssl_verify } diff --git a/gitlab/tests/test_gitlab.py b/gitlab/tests/test_gitlab.py index 027de0c..d9853d0 100644 --- a/gitlab/tests/test_gitlab.py +++ b/gitlab/tests/test_gitlab.py @@ -27,6 +27,7 @@ except ImportError: from httmock import HTTMock # noqa from httmock import response # noqa from httmock import urlmatch # noqa +import requests import six import gitlab @@ -884,6 +885,54 @@ class TestGitlabMethods(unittest.TestCase): self.assertRaises(GitlabUpdateError, self.gl.update, obj) +class TestGitlabAuth(unittest.TestCase): + def test_invalid_auth_args(self): + self.assertRaises(ValueError, + Gitlab, + "http://localhost", api_version='4', + private_token='private_token', oauth_token='bearer') + self.assertRaises(ValueError, + Gitlab, + "http://localhost", api_version='4', + oauth_token='bearer', http_username='foo', + http_password='bar') + self.assertRaises(ValueError, + Gitlab, + "http://localhost", api_version='4', + private_token='private_token', http_password='bar') + self.assertRaises(ValueError, + Gitlab, + "http://localhost", api_version='4', + private_token='private_token', http_username='foo') + + def test_private_token_auth(self): + gl = Gitlab('http://localhost', private_token='private_token', + api_version='4') + self.assertEqual(gl.private_token, 'private_token') + self.assertEqual(gl.oauth_token, None) + self.assertEqual(gl._http_auth, None) + self.assertEqual(gl.headers['PRIVATE-TOKEN'], 'private_token') + self.assertNotIn('Authorization', gl.headers) + + def test_oauth_token_auth(self): + gl = Gitlab('http://localhost', oauth_token='oauth_token', + api_version='4') + self.assertEqual(gl.private_token, None) + self.assertEqual(gl.oauth_token, 'oauth_token') + self.assertEqual(gl._http_auth, None) + self.assertEqual(gl.headers['Authorization'], 'Bearer oauth_token') + self.assertNotIn('PRIVATE-TOKEN', gl.headers) + + def test_http_auth(self): + gl = Gitlab('http://localhost', private_token='private_token', + http_username='foo', http_password='bar', api_version='4') + self.assertEqual(gl.private_token, 'private_token') + self.assertEqual(gl.oauth_token, None) + self.assertIsInstance(gl._http_auth, requests.auth.HTTPBasicAuth) + self.assertEqual(gl.headers['PRIVATE-TOKEN'], 'private_token') + self.assertNotIn('Authorization', gl.headers) + + class TestGitlab(unittest.TestCase): def setUp(self): |