def put(self, key, value, data): restUrl = self.url + API_REST_BIND_PATH + '/' + key + '/' + value try: rsp = self.session.put(restUrl, json=data) except requests.exceptions.Timeout: raise ConfluenceTimeoutError(self.url) except requests.exceptions.SSLError as ex: raise ConfluenceSslError(self.url, ex) except requests.exceptions.ConnectionError as ex: raise ConfluenceBadServerUrlError(self.url, ex) if rsp.status_code == 401: raise ConfluenceAuthenticationFailedUrlError if rsp.status_code == 403: raise ConfluencePermissionError("REST PUT") if rsp.status_code == 407: raise ConfluenceProxyPermissionError if not rsp.ok: errdata = self._format_error(rsp, key) if self.verbosity > 0: errdata += "\n" errdata += json.dumps(data, indent=2) raise ConfluenceBadApiError(errdata) if not rsp.text: raise ConfluenceSeraphAuthenticationFailedUrlError try: rsp.encoding = self.CONFLUENCE_DEFAULT_ENCODING json_data = json.loads(rsp.text) except ValueError: raise ConfluenceBadServerUrlError( self.url, "REST reply did not provide valid JSON data.") return json_data
def get(self, key, params): restUrl = self.url + API_REST_BIND_PATH + '/' + key try: rsp = self.session.get(restUrl, params=params) except requests.exceptions.Timeout: raise ConfluenceTimeoutError(self.url) except requests.exceptions.SSLError as ex: raise ConfluenceSslError(self.url, ex) except requests.exceptions.ConnectionError as ex: raise ConfluenceBadServerUrlError(self.url, ex) if rsp.status_code == 401: raise ConfluenceAuthenticationFailedUrlError if rsp.status_code == 403: raise ConfluencePermissionError("REST GET") if rsp.status_code == 407: raise ConfluenceProxyPermissionError if not rsp.ok: raise ConfluenceBadApiError(self._format_error(rsp, key)) if not rsp.text: raise ConfluenceSeraphAuthenticationFailedUrlError try: rsp.encoding = self.CONFLUENCE_DEFAULT_ENCODING json_data = json.loads(rsp.text) except ValueError: raise ConfluenceBadServerUrlError( self.url, "REST reply did not provide valid JSON data.") return json_data
def post(self, key, data, files=None): restUrl = self.url + API_REST_BIND_PATH + '/' + key try: headers = dict(self.session.headers) # Atlassian's documenation indicates to the security token check # when publishing attachments [1][2]. If adding files, set a # 'nocheck' value to the token. # # [1]: https://developer.atlassian.com/cloud/confluence/rest/#api-content-id-child-attachment-post # [2]: https://developer.atlassian.com/server/jira/platform/form-token-handling/ if files: headers['X-Atlassian-Token'] = 'nocheck' rsp = self.session.post(restUrl, json=data, files=files, headers=headers) except requests.exceptions.Timeout: raise ConfluenceTimeoutError(self.url) except requests.exceptions.SSLError as ex: raise ConfluenceSslError(self.url, ex) except requests.exceptions.ConnectionError as ex: raise ConfluenceBadServerUrlError(self.url, ex) if rsp.status_code == 401: raise ConfluenceAuthenticationFailedUrlError if rsp.status_code == 403: raise ConfluencePermissionError("REST POST") if rsp.status_code == 407: raise ConfluenceProxyPermissionError if not rsp.ok: errdata = self._format_error(rsp, key) if self.verbosity > 0: errdata += "\n" errdata += json.dumps(data, indent=2) raise ConfluenceBadApiError(errdata) if not rsp.text: raise ConfluenceSeraphAuthenticationFailedUrlError try: rsp.encoding = self.CONFLUENCE_DEFAULT_ENCODING json_data = json.loads(rsp.text) except ValueError: raise ConfluenceBadServerUrlError( self.url, "REST reply did not provide valid JSON data.") return json_data
def _wrapper(self, *args, **kwargs): try: return func(self, *args, **kwargs) except requests.exceptions.Timeout: raise ConfluenceTimeoutError(self.url) except requests.exceptions.SSLError as ex: raise ConfluenceSslError(self.url, ex) except requests.exceptions.ConnectionError as ex: raise ConfluenceBadServerUrlError(self.url, ex)
def delete(self, key, value): restUrl = self.url + API_REST_BIND_PATH + '/' + key + '/' + value try: rsp = self.session.delete(restUrl) except requests.exceptions.Timeout: raise ConfluenceTimeoutError(self.url) except requests.exceptions.SSLError as ex: raise ConfluenceSslError(self.url, ex) except requests.exceptions.ConnectionError as ex: raise ConfluenceBadServerUrlError(self.url, ex) if rsp.status_code == 401: raise ConfluenceAuthenticationFailedUrlError if rsp.status_code == 403: raise ConfluencePermissionError("REST DELETE") if rsp.status_code == 407: raise ConfluenceProxyPermissionError if not rsp.ok: raise ConfluenceBadApiError(self._format_error(rsp, key))
def get(self, key, params): rest_url = self.url + self.bind_path + '/' + key rsp = self.session.get(rest_url, params=params, timeout=self.timeout) self._handle_common_request(rsp) if not rsp.ok: errdata = self._format_error(rsp, key) raise ConfluenceBadApiError(rsp.status_code, errdata) if not rsp.text: raise ConfluenceSeraphAuthenticationFailedUrlError try: rsp.encoding = self.CONFLUENCE_DEFAULT_ENCODING json_data = json.loads(rsp.text) except ValueError: raise ConfluenceBadServerUrlError(self.url, "REST reply did not provide valid JSON data.") return json_data
def put(self, key, value, data): rest_url = self.url + self.bind_path + '/' + key + '/' + str(value) rsp = self.session.put(rest_url, json=data, timeout=self.timeout) self._handle_common_request(rsp) if not rsp.ok: errdata = self._format_error(rsp, key) if self.verbosity > 0: errdata += "\n" errdata += json.dumps(data, indent=2) raise ConfluenceBadApiError(rsp.status_code, errdata) if not rsp.text: raise ConfluenceSeraphAuthenticationFailedUrlError try: rsp.encoding = self.CONFLUENCE_DEFAULT_ENCODING json_data = json.loads(rsp.text) except ValueError: raise ConfluenceBadServerUrlError(self.url, "REST reply did not provide valid JSON data.") return json_data
def connect(self): self.rest_client = Rest(self.config) server_url = self.config.confluence_server_url try: rsp = self.rest_client.get('space', { 'spaceKey': self.space_key, 'limit': 1 }) except ConfluenceBadApiError as e: raise ConfluenceBadServerUrlError(server_url, e) # if no size entry is provided, this a non-Confluence API server if 'size' not in rsp: raise ConfluenceBadServerUrlError( server_url, 'server did not provide an expected response (no size)') # handle if the provided space key was not found if rsp['size'] == 0: if self.debug: logger.info('''could not find the configured space (notice to debugging user) Either the space does not exist, or the user does not have permission to see the space. Another space search will be performed to sanity check the configuration to see if a similar space key exists, which can hint to a user that the space key may be misconfigured. If the following search request results in an access restriction, it is most likely that the authentication options are not properly configured, even if the previous search request reported a success (which can be permitted for anonymous users). ''') extra_desc = '' # If the space key was not found, attempt to search for the space # based off its descriptive name. If something is found, hint to the # user to use a space's key value instead. search_fields = { 'cql': 'type=space and space.title~"' + self.space_key + '"', 'limit': 2, } rsp = self.rest_client.get('search', search_fields) if rsp['size'] == 1: detected_space = rsp['results'][0] space_key = detected_space['space']['key'] space_name = detected_space['title'] extra_desc = \ '''\n\n''' \ '''There appears to be a space '{0}' which has a name ''' \ ''''{1}'. Did you mean to use this space?\n''' \ '''\n''' \ ''' confluence_space_key = '{0}'\n''' \ ''''''.format(space_key, space_name) elif rsp['size'] > 1: extra_desc = \ '''\n\n''' \ '''Multiple spaces have been detected which use the ''' \ '''name '{}'. The unique key of the space should be ''' \ '''used instead. See also:\n\n''' \ ''' https://support.atlassian.com/confluence-cloud/docs/choose-a-space-key/\n''' \ ''''''.format(self.space_key) pw_set = bool(self.config.confluence_server_pass) token_set = bool(self.config.confluence_publish_token) raise ConfluenceBadSpaceError(self.space_key, self.config.confluence_server_user, pw_set, token_set, extra_desc) # sanity check that we have any result if 'results' not in rsp or not rsp['results']: raise ConfluenceBadServerUrlError( server_url, 'server did not provide an expected response (no results)') result = rsp['results'][0] if not isinstance(result, dict) or not result.get('name'): raise ConfluenceBadServerUrlError( server_url, 'server did not provide an expected response (no name)') # track required space information self.space_display_name = result['name'] self.space_type = result['type']