0
0
Fork 0
mirror of https://github.com/healthchecks/healthchecks.git synced 2025-03-15 20:54:53 +00:00

Switch from requests to pycurl in integration onboarding views

This commit is contained in:
Pēteris Caune 2022-08-17 12:02:06 +03:00
parent 86e364eb24
commit 3a50396806
No known key found for this signature in database
GPG key ID: E28D7679E9A9EDE2
15 changed files with 76 additions and 88 deletions

View file

@ -1,10 +1,10 @@
# Changelog
All notable changes to this project will be documented in this file.
## v2.4 - Unreleased
## v2.4-dev - Unreleased
### Improvements
- Add support for EMAIL_USE_SSL environment variable (#685)
- Switch from requests to pycurl in hc.api.transports.
- Switch from requests to pycurl
### Bug Fixes
- Fix the handling of TooManyRedirects exceptions

View file

@ -2,7 +2,7 @@ from django.conf import settings
from django.core.management.base import BaseCommand
from django.urls import reverse
import requests
from hc.lib import curl
SETWEBHOOK_TMPL = "https://api.telegram.org/bot%s/setWebhook"
@ -20,7 +20,7 @@ class Command(BaseCommand):
}
url = SETWEBHOOK_TMPL % settings.TELEGRAM_TOKEN
r = requests.post(url, json=form)
r = curl.post(url, json=form)
if r.status_code != 200:
return "Fail: status=%d, %s" % (r.status_code, r.content)

View file

@ -41,7 +41,7 @@ class NotifyWebhookTestCase(BaseTestCase):
mock_get.assert_called_with(
"get",
"http://example",
headers={"User-Agent": "healthchecks.io"},
headers={},
timeout=10,
)
@ -125,7 +125,7 @@ class NotifyWebhookTestCase(BaseTestCase):
args, kwargs = mock_get.call_args
self.assertEqual(args[0], "get")
self.assertEqual(args[1], url)
self.assertEqual(kwargs["headers"], {"User-Agent": "healthchecks.io"})
self.assertEqual(kwargs["headers"], {})
self.assertEqual(kwargs["timeout"], 10)
@patch("hc.api.transports.curl.request")
@ -187,9 +187,7 @@ class NotifyWebhookTestCase(BaseTestCase):
self.channel.notify(self.check)
url = "http://host/%24TAG1"
mock_get.assert_called_with(
"get", url, headers={"User-Agent": "healthchecks.io"}, timeout=10
)
mock_get.assert_called_with("get", url, headers={}, timeout=10)
@patch("hc.api.transports.curl.request")
def test_webhooks_handle_up_events(self, mock_get):
@ -203,9 +201,7 @@ class NotifyWebhookTestCase(BaseTestCase):
self.channel.notify(self.check)
mock_get.assert_called_with(
"get", "http://bar", headers={"User-Agent": "healthchecks.io"}, timeout=10
)
mock_get.assert_called_with("get", "http://bar", headers={}, timeout=10)
@patch("hc.api.transports.curl.request")
def test_webhooks_handle_noop_up_events(self, mock_get):
@ -252,7 +248,7 @@ class NotifyWebhookTestCase(BaseTestCase):
self._setup_data(json.dumps(definition))
self.channel.notify(self.check)
headers = {"User-Agent": "healthchecks.io", "Content-Type": "application/json"}
headers = {"Content-Type": "application/json"}
mock_request.assert_called_with(
"post", "http://foo.com", data=b"data", headers=headers, timeout=10
)
@ -269,7 +265,7 @@ class NotifyWebhookTestCase(BaseTestCase):
self._setup_data(json.dumps(definition))
self.channel.notify(self.check)
headers = {"User-Agent": "healthchecks.io", "Content-Type": "application/json"}
headers = {"Content-Type": "application/json"}
mock_request.assert_called_with(
"get", "http://foo.com", headers=headers, timeout=10
)
@ -306,7 +302,7 @@ class NotifyWebhookTestCase(BaseTestCase):
self.channel.notify(self.check)
headers = {"User-Agent": "healthchecks.io", "X-Message": "Foo is DOWN"}
headers = {"X-Message": "Foo is DOWN"}
mock_request.assert_called_with(
"get", "http://foo.com", headers=headers, timeout=10
)

View file

@ -217,9 +217,6 @@ class HttpTransport(Transport):
@classmethod
def _request(cls, method, url, **kwargs) -> None:
kwargs["timeout"] = 10
kwargs.setdefault("headers", {})
if "User-Agent" not in kwargs["headers"]:
kwargs["headers"]["User-Agent"] = "healthchecks.io"
try:
r = curl.request(method, url, **kwargs)

View file

@ -12,7 +12,7 @@ from hc.front.validators import (
TimezoneValidator,
WebhookValidator,
)
import requests
from hc.lib import curl
def _is_latin1(s):
@ -270,7 +270,7 @@ class AddMatrixForm(forms.Form):
url = settings.MATRIX_HOMESERVER
url += "/_matrix/client/r0/join/%s?" % quote(v)
url += urlencode({"access_token": settings.MATRIX_ACCESS_TOKEN})
r = requests.post(url, {})
r = curl.post(url, {})
if r.status_code == 429:
raise forms.ValidationError(
"Matrix server returned status code 429 (Too Many Requests), "

View file

@ -10,7 +10,7 @@ from hc.test import BaseTestCase
class AddDiscordCompleteTestCase(BaseTestCase):
url = "/integrations/add_discord/"
@patch("hc.front.views.requests.post")
@patch("hc.front.views.curl.post")
def test_it_handles_oauth_response(self, mock_post):
session = self.client.session
session["add_discord"] = ("foo", str(self.project.code))

View file

@ -9,18 +9,18 @@ from hc.test import BaseTestCase
class AddLineNotifyCompleteTestCase(BaseTestCase):
url = "/integrations/add_linenotify/"
@patch("hc.front.views.requests")
def test_it_handles_oauth_response(self, mock_requests):
@patch("hc.front.views.curl")
def test_it_handles_oauth_response(self, mock_curl):
session = self.client.session
session["add_linenotify"] = ("foo", str(self.project.code))
session.save()
mock_requests.post.return_value.json.return_value = {
mock_curl.post.return_value.json.return_value = {
"status": 200,
"access_token": "test-token",
}
mock_requests.get.return_value.json.return_value = {"target": "Alice"}
mock_curl.get.return_value.json.return_value = {"target": "Alice"}
url = self.url + "?code=12345678&state=foo"

View file

@ -18,7 +18,7 @@ class AddMatrixTestCase(BaseTestCase):
r = self.client.get(self.url)
self.assertContains(r, "Integration Settings", status_code=200)
@patch("hc.front.forms.requests.post")
@patch("hc.front.forms.curl.post")
def test_it_works(self, mock_post):
mock_post.return_value.status_code = 200
mock_post.return_value.json.return_value = {"room_id": "fake-room-id"}
@ -39,7 +39,7 @@ class AddMatrixTestCase(BaseTestCase):
r = self.client.get(self.url)
self.assertEqual(r.status_code, 404)
@patch("hc.front.forms.requests.post")
@patch("hc.front.forms.curl.post")
def test_it_handles_429(self, mock_post):
mock_post.return_value.status_code = 429
@ -50,7 +50,7 @@ class AddMatrixTestCase(BaseTestCase):
self.assertContains(r, "Matrix server returned status code 429")
self.assertFalse(Channel.objects.exists())
@patch("hc.front.forms.requests.post")
@patch("hc.front.forms.curl.post")
def test_it_handles_502(self, mock_post):
mock_post.return_value.status_code = 502

View file

@ -10,7 +10,7 @@ from hc.test import BaseTestCase
class AddPushbulletTestCase(BaseTestCase):
url = "/integrations/add_pushbullet/"
@patch("hc.front.views.requests.post")
@patch("hc.front.views.curl.post")
def test_it_handles_oauth_response(self, mock_post):
session = self.client.session
session["add_pushbullet"] = ("foo", str(self.project.code))
@ -46,7 +46,7 @@ class AddPushbulletTestCase(BaseTestCase):
r = self.client.get(url)
self.assertEqual(r.status_code, 403)
@patch("hc.front.views.requests.post")
@patch("hc.front.views.curl.post")
def test_it_handles_denial(self, mock_post):
session = self.client.session
session["add_pushbullet"] = ("foo", str(self.project.code))

View file

@ -8,7 +8,7 @@ from hc.test import BaseTestCase
@override_settings(SLACK_CLIENT_ID="fake-client-id")
class AddSlackCompleteTestCase(BaseTestCase):
@patch("hc.front.views.requests.post")
@patch("hc.front.views.curl.post")
def test_it_handles_oauth_response(self, mock_post):
session = self.client.session
session["add_slack"] = ("foo", str(self.project.code))
@ -50,7 +50,7 @@ class AddSlackCompleteTestCase(BaseTestCase):
r = self.client.get(url)
self.assertEqual(r.status_code, 403)
@patch("hc.front.views.requests.post")
@patch("hc.front.views.curl.post")
def test_it_handles_oauth_error(self, mock_post):
session = self.client.session
session["add_slack"] = ("foo", str(self.project.code))

View file

@ -90,7 +90,7 @@ class SendTestNotificationTestCase(BaseTestCase):
mock_get.assert_called_with(
"get",
"http://example-url",
headers={"User-Agent": "healthchecks.io"},
headers={},
timeout=10,
)

View file

@ -8,7 +8,7 @@ from hc.test import BaseTestCase
class AddTrelloTestCase(BaseTestCase):
url = "/integrations/add_trello/settings/"
@patch("hc.front.views.requests.get")
@patch("hc.front.views.curl.get")
def test_it_works(self, mock_get):
mock_get.return_value.json.return_value = [
{"name": "My Board", "lists": [{"name": "Alerts"}]}
@ -25,7 +25,7 @@ class AddTrelloTestCase(BaseTestCase):
r = self.client.get(self.url)
self.assertEqual(r.status_code, 404)
@patch("hc.front.views.requests.get")
@patch("hc.front.views.curl.get")
def test_it_handles_no_lists(self, mock_get):
mock_get.return_value.json.return_value = []

View file

@ -35,7 +35,6 @@ from hc.api.models import (
MAX_DELTA,
Channel,
Check,
Flip,
Ping,
Notification,
)
@ -49,10 +48,9 @@ from hc.front.templatetags.hc_extras import (
sortchecks,
site_hostname,
)
from hc.lib import jsonschema
from hc.lib import curl, jsonschema
from hc.lib.badges import get_badge_url
from hc.lib.tz import all_timezones
import requests
try:
from zoneinfo import ZoneInfo
@ -1333,14 +1331,12 @@ def add_slack_complete(request):
if request.GET.get("state") != state:
return HttpResponseForbidden()
result = requests.post(
"https://slack.com/api/oauth.v2.access",
{
"client_id": settings.SLACK_CLIENT_ID,
"client_secret": settings.SLACK_CLIENT_SECRET,
"code": request.GET.get("code"),
},
)
data = {
"client_id": settings.SLACK_CLIENT_ID,
"client_secret": settings.SLACK_CLIENT_SECRET,
"code": request.GET.get("code"),
}
result = curl.post("https://slack.com/api/oauth.v2.access", data)
doc = result.json()
if doc.get("ok"):
@ -1418,15 +1414,13 @@ def add_pushbullet_complete(request):
if request.GET.get("state") != state:
return HttpResponseForbidden()
result = requests.post(
"https://api.pushbullet.com/oauth2/token",
{
"client_id": settings.PUSHBULLET_CLIENT_ID,
"client_secret": settings.PUSHBULLET_CLIENT_SECRET,
"code": request.GET.get("code"),
"grant_type": "authorization_code",
},
)
data = {
"client_id": settings.PUSHBULLET_CLIENT_ID,
"client_secret": settings.PUSHBULLET_CLIENT_SECRET,
"code": request.GET.get("code"),
"grant_type": "authorization_code",
}
result = curl.post("https://api.pushbullet.com/oauth2/token", data)
doc = result.json()
if "access_token" in doc:
@ -1478,16 +1472,14 @@ def add_discord_complete(request):
if request.GET.get("state") != state:
return HttpResponseForbidden()
result = requests.post(
"https://discordapp.com/api/oauth2/token",
{
"client_id": settings.DISCORD_CLIENT_ID,
"client_secret": settings.DISCORD_CLIENT_SECRET,
"code": request.GET.get("code"),
"grant_type": "authorization_code",
"redirect_uri": settings.SITE_ROOT + reverse(add_discord_complete),
},
)
data = {
"client_id": settings.DISCORD_CLIENT_ID,
"client_secret": settings.DISCORD_CLIENT_SECRET,
"code": request.GET.get("code"),
"grant_type": "authorization_code",
"redirect_uri": settings.SITE_ROOT + reverse(add_discord_complete),
}
result = curl.post("https://discordapp.com/api/oauth2/token", data)
doc = result.json()
if "access_token" in doc:
@ -1965,18 +1957,17 @@ def add_apprise(request, code):
def trello_settings(request):
token = request.POST.get("token")
url = "https://api.trello.com/1/members/me/boards?" + urlencode(
{
"key": settings.TRELLO_APP_KEY,
"token": token,
"filter": "open",
"fields": "id,name",
"lists": "open",
"list_fields": "id,name",
}
)
url = "https://api.trello.com/1/members/me/boards"
params = {
"key": settings.TRELLO_APP_KEY,
"token": token,
"filter": "open",
"fields": "id,name",
"lists": "open",
"list_fields": "id,name",
}
boards = requests.get(url).json()
boards = curl.get(url, params=params).json()
num_lists = sum(len(board["lists"]) for board in boards)
ctx = {"token": token, "boards": boards, "num_lists": num_lists}
@ -2134,16 +2125,14 @@ def add_linenotify_complete(request):
return redirect("hc-channels", project.code)
# Exchange code for access token
result = requests.post(
"https://notify-bot.line.me/oauth/token",
{
"grant_type": "authorization_code",
"code": request.GET.get("code"),
"redirect_uri": settings.SITE_ROOT + reverse(add_linenotify_complete),
"client_id": settings.LINENOTIFY_CLIENT_ID,
"client_secret": settings.LINENOTIFY_CLIENT_SECRET,
},
)
data = {
"grant_type": "authorization_code",
"code": request.GET.get("code"),
"redirect_uri": settings.SITE_ROOT + reverse(add_linenotify_complete),
"client_id": settings.LINENOTIFY_CLIENT_ID,
"client_secret": settings.LINENOTIFY_CLIENT_SECRET,
}
result = curl.post("https://notify-bot.line.me/oauth/token", data)
doc = result.json()
if doc.get("status") != 200:
@ -2152,7 +2141,7 @@ def add_linenotify_complete(request):
# Fetch notification target's name, will use it as channel name:
token = doc["access_token"]
result = requests.get(
result = curl.get(
"https://notify-api.line.me/api/status",
headers={"Authorization": "Bearer %s" % token},
)

View file

@ -58,6 +58,9 @@ def request(method, url, **kwargs):
data = json.dumps(kwargs["json"])
headers["Content-Type"] = "application/json"
if "User-Agent" not in headers:
headers["User-Agent"] = "healthchecks.io"
headers_list = [k + ":" + v for k, v in headers.items()]
c.setopt(pycurl.HTTPHEADER, headers_list)
@ -101,3 +104,7 @@ def request(method, url, **kwargs):
def post(url, data=None, **kwargs):
return request("post", url, data=data, **kwargs)
def get(url, **kwargs):
return request("get", url, **kwargs)

View file

@ -6,7 +6,6 @@ fido2==1.0.0
psycopg2==2.9.3
pycurl==7.45.1
pyotp==2.6.0
requests==2.28.1
segno==1.5.2
statsd==3.3.0
whitenoise==6.2.0