def get(self, request, project, platform): if platform not in PLATFORMS: raise ResourceDoesNotExist cache_key = "docs:{}".format(platform) result = cache.get(cache_key) if result is None: session = http.build_session() result = session.get(DOC_URL.format(platform=platform)).json() cache.set(cache_key, result, 3600) try: project_key = ProjectKey.objects.filter( project=project, roles=ProjectKey.roles.store, status=ProjectKeyStatus.ACTIVE )[0] except IndexError: project_key = None return Response( { "name": result["name"], "html": replace_keys(result["body"], project_key), "sdk": result["client_lib"], "isFramework": result["is_framework"], "link": result["doc_link"], } )
def get_user_info(access_token): session = http.build_session() resp = session.get( 'https://app.vssps.visualstudio.com/_apis/profile/profiles/me?api-version=1.0', headers={ 'Accept': 'application/json', 'Authorization': 'bearer %s' % access_token, }, ) resp.raise_for_status() user = resp.json() resp = session.get( 'https://app.vssps.visualstudio.com/_apis/connectionData/', headers={ 'Accept': 'application/json', 'Authorization': 'bearer %s' % access_token, }, ) resp.raise_for_status() # NOTE (from Microsoft PM): # The "descriptor" is the universal identifier for a given user and is consistent across # all VSTS accounts (organizations). The "id" field for the same user can be different for # the same user in different places, so the "descriptor" is the best identifier for a user. # This is returned in most/all of the VSTS REST APIs at this point (except for the # profiles/me API above). To get the current user's descriptor, we call the "connection data" # REST API (this assumes we are authenticating with an access token issued to the user). # We will also see descriptors returned for every user in the "Get users" (Graph) REST API. user['id'] = resp.json()['authenticatedUser']['subjectDescriptor'] return user
def load_mapping(self): key = 'javascript.errormapping:%s' % self.vendor mapping = cache.get(key) cached_rv = None if mapping is not None: ts, cached_rv = json.loads(mapping) if not is_expired(ts): return cached_rv try: http_session = http.build_session() response = http_session.get( self.mapping_url, allow_redirects=True, timeout=settings.SENTRY_SOURCE_FETCH_TIMEOUT, ) # Make sure we only get a 2xx to prevent caching bad data response.raise_for_status() data = response.json() cache.set(key, json.dumps([time.time(), data]), HARD_TIMEOUT) except Exception: if cached_rv is None: raise return cached_rv return data
def open_resolve_dialog(self, data, group, integration): # XXX(epurkhiser): In order to update the original message we have to # keep track of the response_url in the callback_id. Definitely hacky, # but seems like there's no other solutions [1]: # # [1]: https://stackoverflow.com/questions/46629852/update-a-bot-message-after-responding-to-a-slack-dialog#comment80795670_46629852 callback_id = json.dumps({ 'issue': group.id, 'orig_response_url': data['response_url'], 'is_message': self.is_message(data), }) dialog = { 'callback_id': callback_id, 'title': u'Resolve Issue', 'submit_label': 'Resolve', 'elements': [RESOLVE_SELECTOR], } payload = { 'dialog': json.dumps(dialog), 'trigger_id': data['trigger_id'], 'token': integration.metadata['access_token'], } session = http.build_session() req = session.post('https://slack.com/api/dialog.open', data=payload) resp = req.json() if not resp.get('ok'): logger.error('slack.action.response-error', extra={'response': resp})
def get_installation_info(self, access_token, installation_id): session = http.build_session() resp = session.get( 'https://api.github.com/app/installations/%s' % installation_id, headers={ 'Authorization': 'Bearer %s' % get_jwt(), 'Accept': 'application/vnd.github.machine-man-preview+json', } ) resp.raise_for_status() installation_resp = resp.json() resp = session.get( 'https://api.github.com/user/installations', params={'access_token': access_token}, headers={'Accept': 'application/vnd.github.machine-man-preview+json'} ) resp.raise_for_status() user_installations_resp = resp.json() # verify that user actually has access to the installation for installation in user_installations_resp['installations']: if installation['id'] == installation_resp['id']: return installation_resp return None
def get_installation_info(self, installation_data, access_token, installation_id): session = http.build_session() resp = session.get( u'https://{}/api/v3/app/installations/{}'.format( installation_data['url'], installation_id), headers={ 'Authorization': 'Bearer %s' % get_jwt(github_id=installation_data['id'], github_private_key=installation_data['private_key']), 'Accept': 'application/vnd.github.machine-man-preview+json', }, verify=installation_data['verify_ssl'] ) resp.raise_for_status() installation_resp = resp.json() resp = session.get( u'https://{}/api/v3/user/installations'.format(installation_data['url']), params={'access_token': access_token}, headers={'Accept': 'application/vnd.github.machine-man-preview+json'}, verify=installation_data['verify_ssl'] ) resp.raise_for_status() user_installations_resp = resp.json() # verify that user actually has access to the installation for installation in user_installations_resp['installations']: if installation['id'] == installation_resp['id']: return installation_resp return None
def make_request(self, method, url, payload=None): if url[:4] != "http": url = self.instance_url + url auth = self.username, self.password session = build_session() try: if method == 'get': r = session.get( url, params=payload, auth=auth, verify=False, timeout=self.HTTP_TIMEOUT) else: r = session.post( url, json=payload, auth=auth, verify=False, timeout=self.HTTP_TIMEOUT) except ConnectionError as e: raise JIRAError(unicode(e)) except RequestException as e: resp = e.response if not resp: raise JIRAError('Internal Error') if resp.status_code == 401: raise JIRAUnauthorized.from_response(resp) raise JIRAError.from_response(resp) except Exception as e: logging.error('Error in request to %s: %s', url, e.message[:128], exc_info=True) raise JIRAError('Internal error', 500) if r.status_code == 401: raise JIRAUnauthorized.from_response(r) elif r.status_code < 200 or r.status_code >= 300: raise JIRAError.from_response(r) return JIRAResponse.from_response(r)
def _request(self, method, path, headers=None, data=None, params=None, auth=None, json=True, allow_text=None, allow_redirects=None, timeout=None): if allow_text is None: allow_text = self.allow_text if allow_redirects is None: allow_redirects = self.allow_redirects if allow_redirects is None: # is still None allow_redirects = method.upper() == 'GET' if timeout is None: timeout = 30 full_url = self.build_url(path) host = urlparse(full_url).netloc session = build_session() try: resp = getattr(session, method.lower())( url=full_url, headers=headers, json=data if json else None, data=data if not json else None, params=params, auth=auth, verify=self.verify_ssl, allow_redirects=allow_redirects, timeout=timeout, ) resp.raise_for_status() except ConnectionError as e: metrics.incr('integrations.http_response', tags={ 'host': host, 'status': 'connection_error' }) raise ApiHostError.from_exception(e) except Timeout as e: metrics.incr('integrations.http_response', tags={ 'host': host, 'status': 'timeout' }) raise ApiTimeoutError.from_exception(e) except HTTPError as e: resp = e.response if resp is None: track_response_code(host, 'unknown') self.logger.exception('request.error', extra={ 'url': full_url, }) raise ApiError('Internal Error') track_response_code(host, resp.status_code) raise ApiError.from_response(resp) track_response_code(host, resp.status_code) if resp.status_code == 204: return {} return BaseApiResponse.from_response(resp, allow_text=allow_text)
def create_webhook(self, base_url, access_token, verify_ssl): webhook_secret = generate_token() session = http.build_session() uri = GitLabApiClientPath.build_api_url( base_url=base_url, path=GitLabApiClientPath.hooks ) resp = session.post( uri, headers={ 'Accept': 'application/json', 'Authorization': 'Bearer %s' % access_token, }, verify=verify_ssl, data={ 'url': absolute_uri('/extensions/gitlab/webhooks/'), 'token': webhook_secret, 'merge_requests_events': True, 'push_events': True, }, ) resp.raise_for_status() return resp.json()['id'], webhook_secret
def sync_docs(): from sentry import http, options session = http.build_session() logger.info('Syncing documentation (platform index)') data = session.get(BASE_URL.format('_index.json')).json() platform_list = [] for platform_id, integrations in data['platforms'].iteritems(): platform_list.append({ 'id': platform_id, 'name': integrations['_self']['name'], 'integrations': [ { 'id': get_integration_id(platform_id, i_id), 'name': i_data['name'], 'type': i_data['type'], 'link': i_data['doc_link'], } for i_id, i_data in sorted( integrations.iteritems(), key=lambda x: x[1]['name'] ) ], }) platform_list.sort(key=lambda x: x['name']) options.set('sentry:docs', {'platforms': platform_list}) for platform_id, platform_data in data['platforms'].iteritems(): for integration_id, integration in platform_data.iteritems(): logger.info('Syncing documentation for %s integration', integration_id) sync_integration(platform_id, integration_id, integration['details'])
def notify(self, notification): event = notification.event group = event.group project = group.project if not self.is_configured(project): return apiurl = self.get_option('apiurl', project) username = self.get_option('username', project).strip().encode('utf-8') apikey = self.get_option('apikey', project).encode('utf-8') stream = self.get_option('stream', project).strip().encode('utf-8') level = group.get_level_display() title = event.message_short.encode('utf-8') project_name = get_project_full_name(project).encode('utf-8') values = { 'type': 'stream', 'to': stream, 'subject': title, 'content': "[%s] **%s** %s [view](%s)" % ( level.upper(), project_name, title, group.get_absolute_url() ) } # Apparently we've stored some bad data from before we used `URLField`. apiurl = apiurl.strip(' ') session = build_session() return session.request(method='POST', url=apiurl, data=values, auth=(username, apikey))
def forward_event(self, event, payload, **kwargs): # TODO(dcramer): we currently only support authenticated events, as the # value of anonymous errors/crashes/etc is much less meaningful in the # context of Segment # we currently only support errors if event.get_event_type() != 'error': return # we avoid instantiating interfaces here as they're only going to be # used if there's a User present user_interface = event.data.get('sentry.interfaces.User') if not user_interface: return user_id = user_interface.get('id') if not user_id: return write_key = self.get_option('write_key', event.project) if not write_key: return session = http.build_session() session.post(self.endpoint, json=payload, auth=(write_key, ''))
def get_channel_id(self, integration_id, name): try: integration = Integration.objects.get( provider='slack', organizations=self.project.organization, id=integration_id, ) except Integration.DoesNotExist: return None session = http.build_session() token_payload = { 'token': integration.metadata['access_token'], } # Look for channel ID channels_payload = dict(token_payload, **{ 'exclude_archived': False, 'exclude_members': True, }) resp = session.get('https://slack.com/api/channels.list', params=channels_payload) resp = resp.json() if not resp.get('ok'): self.logger.info('rule.slack.channel_list_failed', extra={'error': resp.get('error')}) return None channel_id = {c['name']: c['id'] for c in resp['channels']}.get(name) if channel_id: return (CHANNEL_PREFIX, channel_id) # Channel may be private resp = session.get('https://slack.com/api/groups.list', params=channels_payload) resp = resp.json() if not resp.get('ok'): self.logger.info('rule.slack.group_list_failed', extra={'error': resp.get('error')}) return None group_id = {c['name']: c['id'] for c in resp['groups']}.get(name) if group_id: return (CHANNEL_PREFIX, group_id) # Channel may actually be a user resp = session.get('https://slack.com/api/users.list', params=token_payload) resp = resp.json() if not resp.get('ok'): self.logger.info('rule.slack.user_list_failed', extra={'error': resp.get('error')}) return None member_id = {c['name']: c['id'] for c in resp['members']}.get(name) if member_id: return (MEMBER_PREFIX, member_id) return None
def request(self, method, path, data=None): headers = { 'X-Redmine-API-Key': self.key, 'Content-Type': "application/json", } url = '{}{}'.format(self.host, path) session = http.build_session() req = getattr(session, method.lower())(url, json=data, headers=headers) return json.loads(req.text)
def get_team_info(self, access_token): payload = { 'token': access_token, } session = http.build_session() resp = session.get('https://slack.com/api/team.info', params=payload) resp.raise_for_status() resp = resp.json() return resp['team']
def get_user_info(access_token): session = http.build_session() resp = session.get( 'https://api.github.com/user', params={'access_token': access_token}, headers={'Accept': 'application/vnd.github.machine-man-preview+json'} ) resp.raise_for_status() resp = resp.json() return resp
def get_team_info(self, access_token): payload = {"token": access_token} session = http.build_session() resp = session.get("https://slack.com/api/team.info", params=payload) resp.raise_for_status() status_code = resp.status_code resp = resp.json() track_response_code(status_code, resp.get("ok")) return resp["team"]
def get_identity(self, user_token): payload = {"token": user_token} session = http.build_session() resp = session.get("https://slack.com/api/auth.test", params=payload) resp.raise_for_status() status_code = resp.status_code resp = resp.json() track_response_code(status_code, resp.get("ok")) return resp["user_id"]
def _request(self, path, access_token): session = http.build_session() headers = {'Authorization': 'Bearer {0}'.format(access_token)} url = '{0}/{1}'.format(API_BASE_URL, path.lstrip('/')) try: req = session.get(url, headers=headers) except RequestException as e: raise GitLabApiError(unicode(e), status=getattr(e, 'status_code', None)) return json.loads(req.content)
def get_user_info(access_token): with http.build_session() as session: resp = session.get( "https://api.github.com/user", headers={ "Accept": "application/vnd.github.machine-man-preview+json", "Authorization": f"token {access_token}", }, ) resp.raise_for_status() return resp.json()
def request(self, method, path, data=None): headers = { "X-Redmine-API-Key": self.key, "Content-Type": "application/json" } url = f"{self.host}{path}" with http.build_session() as session: req = getattr(session, method.lower())(url, json=data, headers=headers) return json.loads(req.text)
def get_user_info(access_token): session = http.build_session() resp = session.get( "https://api.github.com/user", params={"access_token": access_token}, headers={"Accept": "application/vnd.github.machine-man-preview+json"}, ) resp.raise_for_status() resp = resp.json() return resp
def get_identity(self, user_token): payload = { 'token': user_token, } session = http.build_session() resp = session.get('https://slack.com/api/auth.test', params=payload) resp.raise_for_status() resp = resp.json() return resp['user_id']
def get_user_info(url, access_token): session = http.build_session() resp = session.get( u'https://{}/api/v3/user'.format(url), params={'access_token': access_token}, headers={'Accept': 'application/vnd.github.machine-man-preview+json'}, verify=False ) resp.raise_for_status() resp = resp.json() return resp
def get_channel_id_with_timeout(integration, name, timeout): """ Fetches the internal slack id of a channel. :param organization: The organization that is using this integration :param integration_id: The integration id of this slack integration :param name: The name of the channel :return: a tuple of three values 1. prefix: string (`"#"` or `"@"`) 2. channel_id: string or `None` 3. timed_out: boolean (whether we hit our self-imposed time limit) """ token_payload = {"token": integration.metadata["access_token"]} # Look for channel ID payload = dict(token_payload, **{ "exclude_archived": False, "exclude_members": True }) time_to_quit = time.time() + timeout session = http.build_session() for list_type, result_name, prefix in LIST_TYPES: cursor = "" while True: items = session.get( "https://slack.com/api/%s.list" % list_type, # Slack limits the response of `<list_type>.list` to 1000 channels params=dict(payload, **{ "cursor": cursor, "limit": 1000 }), ) items = items.json() if not items.get("ok"): logger.info("rule.slack.%s_list_failed" % list_type, extra={"error": items.get("error")}) return (prefix, None, False) item_id = {c["name"]: c["id"] for c in items[result_name]}.get(name) if item_id: return (prefix, item_id, False) cursor = items.get("response_metadata", {}).get("next_cursor", None) if time.time() > time_to_quit: return (prefix, None, True) if not cursor: break return (prefix, None, False)
def get_user_info(url, access_token): session = http.build_session() resp = session.get( u"https://{}/api/v3/user".format(url), params={"access_token": access_token}, headers={"Accept": "application/vnd.github.machine-man-preview+json"}, verify=False, ) resp.raise_for_status() resp = resp.json() return resp
def get_projects(instance, access_token): session = http.build_session() url = 'https://%s/DefaultCollection/_apis/projects' % instance response = session.get( url, headers={ 'Content-Type': 'application/json', 'Authorization': 'Bearer %s' % access_token, } ) response.raise_for_status() return response.json()
def get_group_info(self, access_token, installation_data): session = http.build_session() resp = session.get(u'https://{}/api/v4/groups/{}'.format( installation_data['url'], installation_data['group']), headers={ 'Accept': 'application/json', 'Authorization': 'Bearer %s' % access_token, }, verify=installation_data['verify_ssl']) resp.raise_for_status() return resp.json()
def request(self, method, path, data=None): headers = { 'X-Redmine-API-Key': self.key, 'Content-Type': "application/json", } url = '{}{}'.format(self.host, path) session = http.build_session() req = getattr(session, method.lower())(url, json=data, headers=headers, verify=False) return json.loads(req.text)
def on_link_shared(self, request, integration, token, data): issue_map = {} for item in data['links']: issue_id = self._parse_issue_id_from_url(item['url']) if not issue_id: continue issue_map[issue_id] = item['url'] if not issue_map: return results = { g.id: g for g in Group.objects.filter( id__in=set(issue_map.keys()), project__in=Project.objects.filter( organization__in=integration.organizations.all(), )) } if not results: return if settings.SLACK_INTEGRATION_USE_WST: access_token = integration.metadata['access_token'], else: access_token = integration.metadata['user_access_token'], payload = { 'token': access_token, 'channel': data['channel'], 'ts': data['message_ts'], 'unfurls': json.dumps({ v: build_attachment(results[k]) for k, v in six.iteritems(issue_map) if k in results }), # 'user_auth_required': False, # 'user_auth_message': 'You can enable automatic unfurling of Sentry URLs by having a Sentry admin configure the Slack integration.', # we dont have a generic URL that this will work for your # 'user_auth_url': '...', } session = http.build_session() req = session.post('https://slack.com/api/chat.unfurl', data=payload) req.raise_for_status() resp = req.json() if not resp.get('ok'): logger.error('slack.event.unfurl-error', extra={'response': resp}) return self.respond()
def get_user_info(access_token): session = http.build_session() resp = session.get( 'https://app.vssps.visualstudio.com/_apis/profile/profiles/me?api-version=1.0', headers={ 'Accept': 'application/json', 'Authorization': 'bearer %s' % access_token, }, ) resp.raise_for_status() resp = resp.json() return resp
def get_accounts(self, access_token, user_id): url = f"https://app.vssps.visualstudio.com/_apis/accounts?ownerId={user_id}&api-version=4.1" with http.build_session() as session: response = session.get( url, headers={ "Content-Type": "application/json", "Authorization": f"Bearer {access_token}", }, ) if response.status_code == 200: return response.json() return None
def _request(self, path, method="GET", params=None, data=None): path = path.lstrip("/") url = u"%s/%s" % (self.base_url, path) if not params: params = {} session = http.build_session() resp = getattr(session, method.lower())( url, auth=(self._token, ""), params=params, json=data, timeout=self._timeout ) resp.raise_for_status() return json.loads(resp.content)
def get_user_info(access_token, installation_data): session = http.build_session() resp = session.get( u'{}/api/v4/user'.format(installation_data['url']), headers={ 'Accept': 'application/json', 'Authorization': 'Bearer %s' % access_token, }, verify=installation_data['verify_ssl'] ) resp.raise_for_status() return resp.json()
def get_base_url(cls, access_token, account_id): session = http.build_session() url = VstsIntegrationProvider.VSTS_ACCOUNT_LOOKUP_URL % account_id response = session.get( url, headers={ "Content-Type": "application/json", "Authorization": "Bearer %s" % access_token, }, ) if response.status_code == 200: return response.json()["locationUrl"] return None
def get_base_url(cls, access_token, account_id): session = http.build_session() url = VstsIntegrationProvider.VSTS_ACCOUNT_LOOKUP_URL % account_id response = session.get( url, headers={ 'Content-Type': 'application/json', 'Authorization': 'Bearer %s' % access_token, }, ) if response.status_code == 200: return response.json()['locationUrl'] return None
def get_accounts(self, access_token): session = http.build_session() url = 'https://app.vssps.visualstudio.com/_apis/accounts' response = session.get( url, headers={ 'Content-Type': 'application/json', 'Authorization': 'Bearer %s' % access_token, }, ) if response.status_code == 200: return response.json() return None
def get_installation_info(self, installation_id): session = http.build_session() resp = session.get( "https://api.github.com/app/installations/%s" % installation_id, headers={ "Authorization": b"Bearer %s" % get_jwt(), "Accept": "application/vnd.github.machine-man-preview+json", }, ) resp.raise_for_status() installation_resp = resp.json() return installation_resp
def get_accounts(self, access_token, user_id): session = http.build_session() url = 'https://app.vssps.visualstudio.com/_apis/accounts?ownerId=%s&api-version=4.1' % user_id response = session.get( url, headers={ 'Content-Type': 'application/json', 'Authorization': 'Bearer %s' % access_token, }, ) if response.status_code == 200: return response.json() return None
def get_installation_info(self, installation_id): headers = { # TODO(jess): remove this whenever it's out of preview "Accept": "application/vnd.github.machine-man-preview+json", } headers.update(jwt.authorization_header(get_jwt())) with http.build_session() as session: resp = session.get( f"https://api.github.com/app/installations/{installation_id}", headers=headers) resp.raise_for_status() installation_resp = resp.json() return installation_resp
def get_team_info(self, access_token): payload = {"token": access_token} session = http.build_session() resp = session.get("https://slack.com/api/team.info", params=payload) resp.raise_for_status() status_code = resp.status_code resp = resp.json() # TODO: track_response_code won't hit if we have an error status code track_response_code(status_code, resp.get("ok")) # TODO: check for resp["ok"] return resp["team"]
def make_request(self, method, url, payload=None): if url[:4] != "http": url = self.instance_url + url auth = self.username, self.password session = build_session() try: if method == "get": r = session.get(url, params=payload, auth=auth, verify=False, timeout=self.HTTP_TIMEOUT) else: r = session.post(url, json=payload, auth=auth, verify=False, timeout=self.HTTP_TIMEOUT) return JIRAResponse(r.text, r.status_code) except Exception, e: logging.error("Error in request to %s: %s", url, e.message) return JIRAResponse("There was a problem reaching %s: %s" % (url, e.message), 500)
def get_group_info(self, access_token, installation_data): session = http.build_session() resp = session.get(GitLabApiClientPath.build_api_url( base_url=installation_data['url'], path=GitLabApiClientPath.group.format( group=installation_data['group'], )), headers={ 'Accept': 'application/json', 'Authorization': 'Bearer %s' % access_token, }, verify=installation_data['verify_ssl']) resp.raise_for_status() return resp.json()
def _request(self, method, path, headers=None, data=None, params=None, auth=None, json=True, allow_text=None, allow_redirects=None): if allow_text is None: allow_text = self.allow_text if allow_redirects is None: allow_redirects = self.allow_redirects if allow_redirects is None: # is still None allow_redirects = method.upper() == 'GET' full_url = self.build_url(path) session = build_session() try: resp = getattr(session, method.lower())( url=full_url, headers=headers, json=data if json else None, data=data if not json else None, params=params, auth=auth, verify=self.verify_ssl, allow_redirects=allow_redirects, ) resp.raise_for_status() except ConnectionError as e: raise ApiHostError.from_exception(e) except HTTPError as e: resp = e.response if resp is None: self.logger.exception('request.error', extra={ 'url': full_url, }) raise ApiError('Internal Error') raise ApiError.from_response(resp) if resp.status_code == 204: return {} return BaseApiResponse.from_response(resp, allow_text=allow_text)
def sync_integration(platform_id, integration_id, path): from sentry import http, options session = http.build_session() data = session.get(BASE_URL.format(path)).json() key = get_integration_id(platform_id, integration_id) options.set('sentry:docs:{}'.format(key), { 'id': key, 'name': data['name'], 'html': data['body'], 'link': data['doc_link'], })
def get_user_info(url, access_token): session = http.build_session() resp = session.get( f"https://{url}/api/v3/user", headers={ "Accept": "application/vnd.github.machine-man-preview+json", "Authorization": "token %s" % access_token, }, verify=False, ) resp.raise_for_status() resp = resp.json() return resp
def create_issue(self, request, group, form_data, **kwargs): auth = self.get_auth_for_user(user=request.user) if auth is None: raise forms.ValidationError( _('You have not yet associated Bitbucket with your account.')) repo = self.get_option('repo', group.project) url = u'https://api.bitbucket.org/1.0/repositories/%s/issues/' % ( repo, ) data = { "title": form_data['title'], "content": form_data['description'], "kind": form_data['issue_type'], "priority": form_data['priority'] } oauth = OAuth1(unicode(settings.BITBUCKET_CONSUMER_KEY), unicode(settings.BITBUCKET_CONSUMER_SECRET), auth.tokens['oauth_token'], auth.tokens['oauth_token_secret'], signature_type='auth_header') session = http.build_session() try: resp = session.post(url, data=data, auth=oauth) except Exception as e: raise forms.ValidationError( _('Error communicating with Bitbucket: %s') % (e, )) if resp.status_code == 404: BITBUCKET_ISSUES_SETTINGS = 'https://bitbucket.org/%s/admin/issues' % ( repo, ) raise forms.ValidationError( 'No Bitbucket issue tracker found. Please enable issue tracker at %s' % (BITBUCKET_ISSUES_SETTINGS)) if resp.status_code not in (200, 201): raise forms.ValidationError( _('Error creating the issue on Bitbucket: %s') % (data, )) try: data = resp.json() except Exception as e: raise forms.ValidationError( _('Error decoding response from Bitbucket: %s') % (e, )) return data['local_id']
def get_channel_id(self, integration_id, name): try: integration = Integration.objects.get( provider='slack', organizations=self.project.organization, id=integration_id, ) except Integration.DoesNotExist: return None # Look for channel ID payload = { 'token': integration.metadata['access_token'], 'exclude_archived': False, 'exclude_members': True, } session = http.build_session() resp = session.get('https://slack.com/api/channels.list', params=payload) resp = resp.json() if not resp.get('ok'): self.logger.info('rule.slack.channel_list_failed', extra={'error': resp.get('error')}) return None channel_id = {c['name']: c['id'] for c in resp['channels']}.get(name) if channel_id: return (CHANNEL_PREFIX, channel_id) # Look for user ID payload = { 'token': integration.metadata['access_token'], } resp = session.get('https://slack.com/api/users.list', params=payload) resp = resp.json() if not resp.get('ok'): self.logger.info('rule.slack.user_list_failed', extra={'error': resp.get('error')}) return None member_id = {c['name']: c['id'] for c in resp['members']}.get(name) if member_id: return (MEMBER_PREFIX, member_id) return None
def sync_integration(platform_id, integration_id, path): from sentry import http, options session = http.build_session() data = session.get(BASE_URL.format(path)).json() key = get_integration_id(platform_id, integration_id) options.set( 'sentry:docs:{}'.format(key), { 'id': key, 'name': data['name'], 'html': data['body'], 'link': data['doc_link'], })
class GitLabClient(object): http = http.build_session() def _request(self, path, access_token): headers = {'Authorization': 'Bearer {0}'.format(access_token)} url = '{0}/{1}'.format(API_BASE_URL, path.lstrip('/')) try: req = self.http.get(url, headers=headers) except RequestException as e: raise GitLabApiError(unicode(e), status=e.status_code) return json.loads(req.content) def get_user(self, access_token): return self._request('user', access_token)
def send_notification(event, futures): rules = [f.rule for f in futures] attachment = build_attachment(event.group, event=event, tags=tags, rules=rules) payload = { 'token': integration.metadata['access_token'], 'channel': channel, 'attachments': json.dumps([attachment]), } session = http.build_session() resp = session.post('https://slack.com/api/chat.postMessage', data=payload) resp.raise_for_status() resp = resp.json() if not resp.get('ok'): self.logger.info('rule.fail.slack_post', extra={'error': resp.get('error')})
def on_link_shared(self, request, integration, token, data): issue_map = {} for item in data['links']: issue_id = self._parse_issue_id_from_url(item['url']) if not issue_id: continue issue_map[issue_id] = item['url'] if not issue_map: return results = { g.id: g for g in Group.objects.filter( id__in=set(issue_map.keys()), project__in=Project.objects.filter( organization__in=integration.organizations.all(), ) ) } if not results: return payload = { 'token': integration.metadata['access_token'], 'channel': data['channel'], 'ts': data['message_ts'], 'unfurls': json.dumps({ v: self._attachment_for(results[k]) for k, v in six.iteritems(issue_map) if k in results }), # 'user_auth_required': False, # 'user_auth_message': 'You can enable automatic unfurling of Sentry URLs by having a Sentry admin configure the Slack integration.', # we dont have a generic URL that this will work for your # 'user_auth_url': '...', } session = http.build_session() req = session.post('https://slack.com/api/chat.unfurl', data=payload) req.raise_for_status() resp = req.json() if not resp.get('ok'): logger.error('slack.event.unfurl-error', extra={ 'error': resp.get('error'), }) return self.respond()
def request(self, method, path, data=None, params=None): headers = { 'Private-Token': self.token, } session = build_session() try: resp = getattr(session, method.lower())( url='{}/api/v4/{}'.format(self.url, path.lstrip('/')), headers=headers, json=data, params=params, allow_redirects=False, ) resp.raise_for_status() except HTTPError as e: raise ApiError.from_response(e.response) return resp.json()
def request(self, data): payload = { 'service_key': self.service_key, } payload.update(data) session = build_session() try: resp = session.post( url=INTEGRATION_API_URL, json=payload, allow_redirects=False, ) resp.raise_for_status() except HTTPError as e: raise ApiError.from_response(e.response) return resp.json()
def _request(self, method, path, headers=None, data=None, params=None, auth=None, json=True, allow_text=None, allow_redirects=None, timeout=None): if allow_text is None: allow_text = self.allow_text if allow_redirects is None: allow_redirects = self.allow_redirects if allow_redirects is None: # is still None allow_redirects = method.upper() == 'GET' if timeout is None: timeout = 30 full_url = self.build_url(path) session = build_session() try: resp = getattr(session, method.lower())( url=full_url, headers=headers, json=data if json else None, data=data if not json else None, params=params, auth=auth, verify=self.verify_ssl, allow_redirects=allow_redirects, timeout=timeout, ) resp.raise_for_status() except ConnectionError as e: raise ApiHostError.from_exception(e) except HTTPError as e: resp = e.response if resp is None: self.logger.exception('request.error', extra={ 'url': full_url, }) raise ApiError('Internal Error') raise ApiError.from_response(resp) if resp.status_code == 204: return {} return BaseApiResponse.from_response(resp, allow_text=allow_text)
def request(self, data): endpoint = 'https://alert.victorops.com/integrations/generic/20131114/alert/{}/{}'.format( self.api_key, self.routing_key, ) session = build_session() try: resp = session.post( url=endpoint, json=data, allow_redirects=False, ) resp.raise_for_status() except HTTPError as e: raise ApiError.from_response(e.response) return resp.json()
def _request(self, path, method="GET", params=None, data=None): path = path.lstrip('/') url = '%s/%s' % (self.base_url, path) if not params: params = {} session = http.build_session() resp = getattr(session, method.lower())( url, auth=(self._token, ''), params=params, json=data, timeout=self._timeout, ) resp.raise_for_status() return json.loads(resp.content)
def get_group_info(self, access_token, installation_data): session = http.build_session() resp = session.get( GitLabApiClientPath.build_api_url( base_url=installation_data['url'], path=GitLabApiClientPath.group.format( group=installation_data['group'], ) ), headers={ 'Accept': 'application/json', 'Authorization': 'Bearer %s' % access_token, }, verify=installation_data['verify_ssl'] ) resp.raise_for_status() return resp.json()