diff --git a/AUTHORS b/AUTHORS new file mode 100644 index 000000000..635ddd8d0 --- /dev/null +++ b/AUTHORS @@ -0,0 +1,11 @@ +Author +------ + +Gauvain Pocentek + +Contributors +------------ + +Daniel Kimsey +Erik Weatherwax +Andrew Austin diff --git a/ChangeLog b/ChangeLog new file mode 100644 index 000000000..d65ba934f --- /dev/null +++ b/ChangeLog @@ -0,0 +1,16 @@ +Version 0.3 + + * Use PRIVATE-TOKEN header for passing the auth token + * provide a AUTHORS file + * cli: support ssl_verify config option + * Add ssl_verify option to Gitlab object. Defauls to True + * Correct url for merge requests API. + +Version 0.2 + + * provide a pip requirements.txt + * drop some debug statements + +Version 0.1 + + * Initial release diff --git a/MANIFEST.in b/MANIFEST.in index b0befc4ce..3814b6fa6 100644 --- a/MANIFEST.in +++ b/MANIFEST.in @@ -1 +1 @@ -include README.md COPYING +include README.md COPYING AUTHORS ChangeLog diff --git a/README.md b/README.md index e12ff11a2..bee94e823 100644 --- a/README.md +++ b/README.md @@ -14,7 +14,12 @@ python-gitlab depends on: ## State -python-gitlab is a work in progress, although already usable. Changes in the API might happen. +python-gitlab >= 0.3 is considered stable. + +## Bugs reports + +Please report bugs and feature requests at +https://github.com/gpocentek/python-gitlab/issues ## ToDo @@ -69,6 +74,7 @@ Here's an example of the syntax: ````` [global] default = local +ssl_verify = true [local] url = http://10.0.3.2:8080 @@ -77,12 +83,16 @@ private_token = vTbFeqJYCY3sibBP7BZM [distant] url = https://some.whe.re private_token = thisisaprivatetoken +ssl_verify = false ````` The [global] section define which server is accesed by default. Each other section defines how to access a server. Only private token authentication is supported (not user/password). +The `ssl_verify` option defines if the server SSL certificate should be +validated (use false for self signed certificates, only useful with https). + Choosing a different server than the default one can be done at run time: ````` diff --git a/gitlab b/gitlab index 7365003e5..370cef170 100755 --- a/gitlab +++ b/gitlab @@ -126,7 +126,7 @@ def usage(): def do_auth(): try: - gl = gitlab.Gitlab(gitlab_url, private_token=gitlab_token) + gl = gitlab.Gitlab(gitlab_url, private_token=gitlab_token, ssl_verify=ssl_verify) gl.auth() except: die("Could not connect to GitLab (%s)" % gitlab_url) @@ -204,6 +204,7 @@ def do_update(cls, d): return o +ssl_verify = True gitlab_id = None verbose = False @@ -272,6 +273,15 @@ try: except: die("Impossible to get gitlab informations from configuration (%s)" % gitlab_id) +try: + ssl_verify = config.getboolean('global', 'ssl_verify') +except: + pass +try: + ssl_verify = config.getboolean(gitlab_id, 'ssl_verify') +except: + pass + try: what = args.pop(0) action = args.pop(0) diff --git a/gitlab.py b/gitlab.py index 106e9ff84..22e5a3b26 100644 --- a/gitlab.py +++ b/gitlab.py @@ -20,7 +20,7 @@ import requests __title__ = 'python-gitlab' -__version__ = '0.2' +__version__ = '0.3' __author__ = 'Gauvain Pocentek' __email__ = 'gauvain@pocentek.net' __license__ = 'LGPL3' @@ -74,7 +74,7 @@ class GitlabAuthenticationError(Exception): class Gitlab(object): """Represents a GitLab server connection""" - def __init__(self, url, private_token=None, email=None, password=None): + def __init__(self, url, private_token=None, email=None, password=None, ssl_verify=True): """Stores informations about the server url: the URL of the Gitlab server @@ -83,9 +83,10 @@ def __init__(self, url, private_token=None, email=None, password=None): password: the user password (associated with email) """ self._url = '%s/api/v3' % url - self.private_token = private_token + self.setToken(private_token) self.email = email self.password = password + self.ssl_verify = ssl_verify def auth(self): """Performs an authentication using either the private token, or the @@ -93,11 +94,9 @@ def auth(self): The user attribute will hold a CurrentUser object on success. """ - r = False if self.private_token: - r = self.token_auth() - - if not r: + self.token_auth() + else: self.credentials_auth() def credentials_auth(self): @@ -111,14 +110,10 @@ def credentials_auth(self): else: raise GitlabAuthenticationError(r.json()['message']) - self.private_token = self.user.private_token + self.setToken(self.user.private_token) def token_auth(self): - try: - self.user = CurrentUser(self) - return True - except: - return False + self.user = CurrentUser(self) def setUrl(self, url): """Updates the gitlab URL""" @@ -126,20 +121,22 @@ def setUrl(self, url): def setToken(self, token): """Sets the private token for authentication""" - self.private_token = token + if token: + self.private_token = token + self.headers = {"PRIVATE-TOKEN": token} + else: + self.private_token = None + self.headers = {} def setCredentials(self, email, password): """Sets the email/login and password for authentication""" self.email = email self.password = password - def rawGet(self, path, with_token=False): + def rawGet(self, path): url = '%s%s' % (self._url, path) - if with_token: - url += "?private_token=%s" % self.private_token - try: - r = requests.get(url) + r = requests.get(url, headers=self.headers, verify=self.ssl_verify) except: raise GitlabConnectionError( "Can't connect to GitLab server (%s)" % self._url) @@ -149,20 +146,20 @@ def rawGet(self, path, with_token=False): def rawPost(self, path, data): url = '%s%s' % (self._url, path) try: - r = requests.post(url, data) + r = requests.post(url, data, + headers=self.headers, + verify=self.ssl_verify) except: raise GitlabConnectionError( "Can't connect to GitLab server (%s)" % self._url) return r - def rawPut(self, path, with_token=False): + def rawPut(self, path): url = '%s%s' % (self._url, path) - if with_token: - url += "?private_token=%s" % self.private_token try: - r = requests.put(url) + r = requests.put(url, headers=self.headers, verify=self.ssl_verify) except: raise GitlabConnectionError( "Can't connect to GitLab server (%s)" % self._url) @@ -181,13 +178,13 @@ def list(self, obj_class, **kwargs): url = obj_class._url if kwargs: url = obj_class._url % kwargs - url = '%s%s?private_token=%s' % (self._url, url, self.private_token) + url = '%s%s' % (self._url, url) if kwargs: - url += "&%s" % ("&".join( + url += "?%s" % ("&".join( ["%s=%s" % (k, v) for k, v in kwargs.items()])) try: - r = requests.get(url) + r = requests.get(url, headers=self.headers, verify=self.ssl_verify) except: raise GitlabConnectionError( "Can't connect to GitLab server (%s)" % self._url) @@ -223,17 +220,17 @@ def get(self, obj_class, id=None, **kwargs): url = obj_class._url % kwargs if id is not None: try: - url = '%s%s/%d?private_token=%s' % \ - (self._url, url, id, self.private_token) + url = '%s%s/%d' % \ + (self._url, url, id) except TypeError: # id might be a str (ProjectBranch) - url = '%s%s/%s?private_token=%s' % \ - (self._url, url, id, self.private_token) + url = '%s%s/%s' % \ + (self._url, url, id) else: - url = '%s%s?private_token=%s' % \ - (self._url, url, self.private_token) + url = '%s%s' % \ + (self._url, url) try: - r = requests.get(url) + r = requests.get(url, headers=self.headers, verify=self.ssl_verify) except: raise GitlabConnectionError( "Can't connect to GitLab server (%s)" % self._url) @@ -249,11 +246,11 @@ def get(self, obj_class, id=None, **kwargs): def delete(self, obj): url = obj._url % obj.__dict__ - url = '%s%s/%d?private_token=%s' % \ - (self._url, url, obj.id, self.private_token) + url = '%s%s/%d' % \ + (self._url, url, obj.id) try: - r = requests.delete(url) + r = requests.delete(url, headers=self.headers, verify=self.ssl_verify) except: raise GitlabConnectionError( "Can't connect to GitLab server (%s)" % self._url) @@ -276,12 +273,12 @@ def create(self, obj): ", ".join(missing)) url = obj._url % obj.__dict__ - url = '%s%s?private_token=%s' % (self._url, url, self.private_token) + url = '%s%s' % (self._url, url) try: # TODO: avoid too much work on the server side by filtering the # __dict__ keys - r = requests.post(url, obj.__dict__) + r = requests.post(url, obj.__dict__, headers=self.headers, verify=self.ssl_verify) except: raise GitlabConnectionError( "Can't connect to GitLab server (%s)" % self._url) @@ -295,8 +292,8 @@ def create(self, obj): def update(self, obj): url = obj._url % obj.__dict__ - url = '%s%s/%d?private_token=%s' % \ - (self._url, url, obj.id, self.private_token) + url = '%s%s/%d' % \ + (self._url, url, obj.id) # build a dict of data that can really be sent to server d = {} @@ -305,7 +302,7 @@ def update(self, obj): d[k] = str(v) try: - r = requests.put(url, d) + r = requests.put(url, d, headers=self.headers, verify=self.ssl_verify) except: raise GitlabConnectionError( "Can't connect to GitLab server (%s)" % self._url) @@ -587,8 +584,8 @@ class Group(GitlabObject): shortPrintAttr = 'name' def transfer_project(self, id): - url = '/groups/%d/projects/%d?private_token=%s' % \ - (self.id, id, self.gitlab.private_token) + url = '/groups/%d/projects/%d' % \ + (self.id, id) r = self.gitlab.rawPost(url, None) if r.status_code != 201: raise GitlabTransferProjectError() @@ -627,7 +624,7 @@ def protect(self, protect=True): url = "%s/%s/protect" % (url, self.name) else: url = "%s/%s/unprotect" % (url, self.name) - r = self.gitlab.rawPut(url, True) + r = self.gitlab.rawPut(url) if r.status_code == 200: if protect: @@ -737,7 +734,7 @@ class ProjectMergeRequestNote(GitlabObject): class ProjectMergeRequest(GitlabObject): - _url = '/projects/%(project_id)s/merge_request' + _url = '/projects/%(project_id)s/merge_requests' _constructorTypes = {'author': 'User', 'assignee': 'User'} canDelete = False requiredListAttrs = ['project_id'] @@ -784,7 +781,7 @@ class ProjectSnippet(GitlabObject): def Content(self): url = "/projects/%(project_id)s/snippets/%(snippet_id)s/raw" % \ {'project_id': self.project_id, 'snippet_id': self.id} - r = self.gitlab.rawGet(url, True) + r = self.gitlab.rawGet(url) if r.status_code == 200: return r.content diff --git a/setup.py b/setup.py index 82fe24e50..4783ffe82 100644 --- a/setup.py +++ b/setup.py @@ -21,5 +21,14 @@ def get_version(): license='LGPLv3', url='https://github.com/gpocentek/python-gitlab', py_modules=['gitlab'], - scripts=['gitlab'] + scripts=['gitlab'], + classifiers=[ + 'Development Status :: 5 - Production/Stable', + 'Environment :: Console', + 'Intended Audience :: System Administrators', + 'License :: OSI Approved :: GNU General Public License v3 (GPLv3)', + 'Natural Language :: English', + 'Operating System :: POSIX', + 'Operating System :: Microsoft :: Windows' + ] )