diff --git a/hc/accounts/models.py b/hc/accounts/models.py index f4db9225..86802626 100644 --- a/hc/accounts/models.py +++ b/hc/accounts/models.py @@ -81,7 +81,7 @@ class Profile(models.Model): return self def prepare_token(self, salt): - token = urlsafe_b64encode(os.urandom(24)).decode("utf-8") + token = urlsafe_b64encode(os.urandom(24)).decode() self.token = make_password(token, salt) self.save() return token diff --git a/hc/accounts/urls.py b/hc/accounts/urls.py index af6a9a69..7485b442 100644 --- a/hc/accounts/urls.py +++ b/hc/accounts/urls.py @@ -1,36 +1,36 @@ -from django.conf.urls import url +from django.urls import path from hc.accounts import views urlpatterns = [ - url(r'^login/$', views.login, name="hc-login"), - url(r'^logout/$', views.logout, name="hc-logout"), - url(r'^login_link_sent/$', - views.login_link_sent, name="hc-login-link-sent"), + path('login/', views.login, name="hc-login"), + path('logout/', views.logout, name="hc-logout"), + path('login_link_sent/', + views.login_link_sent, name="hc-login-link-sent"), - url(r'^link_sent/$', - views.link_sent, name="hc-link-sent"), + path('link_sent/', + views.link_sent, name="hc-link-sent"), - url(r'^check_token/([\w-]+)/([\w-]+)/$', - views.check_token, name="hc-check-token"), + path('check_token///', + views.check_token, name="hc-check-token"), - url(r'^profile/$', views.profile, name="hc-profile"), - url(r'^profile/notifications/$', views.notifications, name="hc-notifications"), - url(r'^profile/badges/$', views.badges, name="hc-badges"), - url(r'^close/$', views.close, name="hc-close"), + path('profile/', views.profile, name="hc-profile"), + path('profile/notifications/', views.notifications, name="hc-notifications"), + path('profile/badges/', views.badges, name="hc-badges"), + path('close/', views.close, name="hc-close"), - url(r'^unsubscribe_reports/([\w\:-]+)/$', - views.unsubscribe_reports, name="hc-unsubscribe-reports"), + path('unsubscribe_reports//', + views.unsubscribe_reports, name="hc-unsubscribe-reports"), - url(r'^set_password/([\w-]+)/$', - views.set_password, name="hc-set-password"), + path('set_password//', + views.set_password, name="hc-set-password"), - url(r'^change_email/done/$', - views.change_email_done, name="hc-change-email-done"), + path('change_email/done/', + views.change_email_done, name="hc-change-email-done"), - url(r'^change_email/([\w-]+)/$', - views.change_email, name="hc-change-email"), + path('change_email//', + views.change_email, name="hc-change-email"), - url(r'^switch_team/([\w-]+)/$', - views.switch_team, name="hc-switch-team"), + path('switch_team//', + views.switch_team, name="hc-switch-team"), ] diff --git a/hc/accounts/views.py b/hc/accounts/views.py index 1e3b56e5..40e0fa4d 100644 --- a/hc/accounts/views.py +++ b/hc/accounts/views.py @@ -363,7 +363,7 @@ def unsubscribe_reports(request, username): # This is here for backwards compatibility and will be removed # at some point. try: - signing.Signer().unsign(request.GET.get("token")) + signing.Signer().unsign(request.GET.get("token", "")) except signing.BadSignature: return render(request, "bad_link.html") diff --git a/hc/api/decorators.py b/hc/api/decorators.py index ec4c7d8a..c93aa212 100644 --- a/hc/api/decorators.py +++ b/hc/api/decorators.py @@ -1,24 +1,10 @@ import json -import re from functools import wraps from django.contrib.auth.models import User -from django.http import (HttpResponseBadRequest, HttpResponseForbidden, - JsonResponse) +from django.http import HttpResponseForbidden, JsonResponse from hc.lib.jsonschema import ValidationError, validate -RE_UUID = re.compile("^[a-fA-F0-9]{8}-[a-fA-F0-9]{4}-4[a-fA-F0-9]{3}-[8|9|aA|bB][a-fA-F0-9]{3}-[a-fA-F0-9]{12}$") - - -def uuid_or_400(f): - @wraps(f) - def wrapper(request, *args, **kwds): - if not RE_UUID.match(args[0]): - return HttpResponseBadRequest() - - return f(request, *args, **kwds) - return wrapper - def make_error(msg): return JsonResponse({"error": msg}, status=400) @@ -30,7 +16,7 @@ def check_api_key(f): request.json = {} if request.body: try: - request.json = json.loads(request.body.decode("utf-8")) + request.json = json.loads(request.body.decode()) except ValueError: return make_error("could not parse request body") diff --git a/hc/api/models.py b/hc/api/models.py index 8cb7fde1..ac684940 100644 --- a/hc/api/models.py +++ b/hc/api/models.py @@ -231,7 +231,7 @@ class Channel(models.Model): def make_token(self): seed = "%s%s" % (self.code, settings.SECRET_KEY) - seed = seed.encode("utf8") + seed = seed.encode() return hashlib.sha1(seed).hexdigest() def send_verify_link(self): diff --git a/hc/api/tests/test_badge.py b/hc/api/tests/test_badge.py index e51232b3..955478fa 100644 --- a/hc/api/tests/test_badge.py +++ b/hc/api/tests/test_badge.py @@ -17,7 +17,7 @@ class BadgeTestCase(BaseTestCase): def test_it_returns_svg(self): sig = base64_hmac(str(self.alice.username), "foo", settings.SECRET_KEY) - sig = sig[:8].decode("utf-8") + sig = sig[:8] url = "/badge/%s/%s/foo.svg" % (self.alice.username, sig) r = self.client.get(url) diff --git a/hc/api/tests/test_notify.py b/hc/api/tests/test_notify.py index c66ad1d8..e1148ebb 100644 --- a/hc/api/tests/test_notify.py +++ b/hc/api/tests/test_notify.py @@ -102,7 +102,7 @@ class NotifyTestCase(BaseTestCase): self.assertEqual(args[1], "http://example.com") # spaces should not have been urlencoded: - payload = kwargs["data"].decode("utf-8") + payload = kwargs["data"].decode() self.assertTrue(payload.startswith("The Time Is 2")) @patch("hc.api.transports.requests.request") diff --git a/hc/api/tests/test_pause.py b/hc/api/tests/test_pause.py index 3e134be6..4ca67faf 100644 --- a/hc/api/tests/test_pause.py +++ b/hc/api/tests/test_pause.py @@ -38,7 +38,7 @@ class PauseTestCase(BaseTestCase): r = self.client.post(url, "", content_type="application/json", HTTP_X_API_KEY="abc") - self.assertEqual(r.status_code, 400) + self.assertEqual(r.status_code, 404) def test_it_handles_missing_check(self): url = "/api/v1/checks/07c2f548-9850-4b27-af5d-6c9dc157ec02/pause" diff --git a/hc/api/tests/test_ping.py b/hc/api/tests/test_ping.py index 66a5f1a6..eab31a9f 100644 --- a/hc/api/tests/test_ping.py +++ b/hc/api/tests/test_ping.py @@ -48,12 +48,12 @@ class PingTestCase(TestCase): def test_it_handles_bad_uuid(self): r = self.client.get("/ping/not-uuid/") - self.assertEqual(r.status_code, 400) + self.assertEqual(r.status_code, 404) def test_it_rejects_alternative_uuid_formats(self): # This uuid is missing separators. uuid.UUID() would accept it. r = self.client.get("/ping/07c2f54898504b27af5d6c9dc157ec02/") - self.assertEqual(r.status_code, 400) + self.assertEqual(r.status_code, 404) def test_it_handles_missing_check(self): r = self.client.get("/ping/07c2f548-9850-4b27-af5d-6c9dc157ec02/") diff --git a/hc/api/tests/test_update_check.py b/hc/api/tests/test_update_check.py index fd49739c..043c2de9 100644 --- a/hc/api/tests/test_update_check.py +++ b/hc/api/tests/test_update_check.py @@ -69,7 +69,7 @@ class UpdateCheckTestCase(BaseTestCase): def test_it_handles_invalid_uuid(self): r = self.post("not-an-uuid", {"api_key": "abc"}) - self.assertEqual(r.status_code, 400) + self.assertEqual(r.status_code, 404) def test_it_handles_missing_check(self): made_up_code = "07c2f548-9850-4b27-af5d-6c9dc157ec02" diff --git a/hc/api/transports.py b/hc/api/transports.py index aa3af302..58e27c50 100644 --- a/hc/api/transports.py +++ b/hc/api/transports.py @@ -184,7 +184,7 @@ class Webhook(HttpTransport): if self.channel.post_data: payload = self.prepare(self.channel.post_data, check) - return self.post(url, data=payload.encode("utf-8"), headers=headers) + return self.post(url, data=payload.encode(), headers=headers) else: return self.get(url, headers=headers) diff --git a/hc/api/urls.py b/hc/api/urls.py index dc974a77..fc1dceac 100644 --- a/hc/api/urls.py +++ b/hc/api/urls.py @@ -1,27 +1,27 @@ -from django.conf.urls import url +from django.urls import path from hc.api import views urlpatterns = [ - url(r'^ping/([\w-]+)/$', views.ping, name="hc-ping-slash"), - url(r'^ping/([\w-]+)$', views.ping, name="hc-ping"), - url(r'^api/v1/checks/$', views.checks), - url(r'^api/v1/checks/([\w-]+)$', views.update, name="hc-api-update"), - url(r'^api/v1/checks/([\w-]+)/pause$', views.pause, name="hc-api-pause"), - url(r'^api/v1/notifications/([\w-]+)/bounce$', views.bounce, - name="hc-api-bounce"), + path('ping//', views.ping, name="hc-ping-slash"), + path('ping/', views.ping, name="hc-ping"), + path('api/v1/checks/', views.checks), + path('api/v1/checks/', views.update, name="hc-api-update"), + path('api/v1/checks//pause', views.pause, name="hc-api-pause"), + path('api/v1/notifications//bounce', views.bounce, + name="hc-api-bounce"), - url(r'^badge/([\w-]+)/([\w-]{8})/([\w-]+).svg$', views.badge, - name="hc-badge"), + path('badge///.svg', views.badge, + name="hc-badge"), - url(r'^badge/([\w-]+)/([\w-]{8}).svg$', views.badge, - {"tag": "*"}, name="hc-badge-all"), + path('badge//.svg', views.badge, + {"tag": "*"}, name="hc-badge-all"), - url(r'^badge/([\w-]+)/([\w-]{8})/([\w-]+).json$', views.badge, - {"format": "json"}, name="hc-badge-json"), + path('badge///.json', views.badge, + {"format": "json"}, name="hc-badge-json"), - url(r'^badge/([\w-]+)/([\w-]{8}).json$', views.badge, - {"format": "json", "tag": "*"}, name="hc-badge-json-all"), + path('badge//.json', views.badge, + {"format": "json", "tag": "*"}, name="hc-badge-json-all"), - url(r'^api/v1/status/$', views.status), + path('api/v1/status/', views.status), ] diff --git a/hc/api/views.py b/hc/api/views.py index 9d9ae468..5df7d74c 100644 --- a/hc/api/views.py +++ b/hc/api/views.py @@ -11,13 +11,12 @@ from django.views.decorators.csrf import csrf_exempt from django.views.decorators.http import require_POST from hc.api import schemas -from hc.api.decorators import check_api_key, uuid_or_400, validate_json +from hc.api.decorators import check_api_key, validate_json from hc.api.models import Check, Notification from hc.lib.badges import check_signature, get_badge_svg @csrf_exempt -@uuid_or_400 @never_cache def ping(request, code): check = get_object_or_404(Check, code=code) @@ -28,8 +27,9 @@ def ping(request, code): scheme = headers.get("HTTP_X_FORWARDED_PROTO", "http") method = headers["REQUEST_METHOD"] ua = headers.get("HTTP_USER_AGENT", "") + body = request.body.decode() - check.ping(remote_addr, scheme, method, ua, request.body) + check.ping(remote_addr, scheme, method, ua, body) response = HttpResponse("OK") response["Access-Control-Allow-Origin"] = "*" @@ -127,7 +127,6 @@ def checks(request): @csrf_exempt -@uuid_or_400 @check_api_key @validate_json(schemas.check) def update(request, code): @@ -150,7 +149,6 @@ def update(request, code): @csrf_exempt @require_POST -@uuid_or_400 @check_api_key def pause(request, code): check = get_object_or_404(Check, code=code) @@ -194,7 +192,6 @@ def badge(request, username, signature, tag, format="svg"): @csrf_exempt -@uuid_or_400 def bounce(request, code): notification = get_object_or_404(Notification, code=code) @@ -203,7 +200,7 @@ def bounce(request, code): if td.total_seconds() > 600: return HttpResponseForbidden() - notification.error = request.body[:200] + notification.error = request.body.decode()[:200] notification.save() notification.channel.email_verified = False diff --git a/hc/front/tests/test_log.py b/hc/front/tests/test_log.py index 6697bf11..9a55127d 100644 --- a/hc/front/tests/test_log.py +++ b/hc/front/tests/test_log.py @@ -38,7 +38,7 @@ class LogTestCase(BaseTestCase): self.client.login(username="alice@example.org", password="password") r = self.client.get(url) - assert r.status_code == 400 + self.assertEqual(r.status_code, 404) def test_it_handles_missing_uuid(self): # Valid UUID but there is no check for it: diff --git a/hc/front/tests/test_remove_channel.py b/hc/front/tests/test_remove_channel.py index 9ba167d3..6189ebfb 100644 --- a/hc/front/tests/test_remove_channel.py +++ b/hc/front/tests/test_remove_channel.py @@ -31,7 +31,7 @@ class RemoveChannelTestCase(BaseTestCase): self.client.login(username="alice@example.org", password="password") r = self.client.post(url) - assert r.status_code == 400 + self.assertEqual(r.status_code, 404) def test_it_checks_owner(self): url = "/integrations/%s/remove/" % self.channel.code diff --git a/hc/front/tests/test_remove_check.py b/hc/front/tests/test_remove_check.py index a661782d..af3a9beb 100644 --- a/hc/front/tests/test_remove_check.py +++ b/hc/front/tests/test_remove_check.py @@ -32,7 +32,7 @@ class RemoveCheckTestCase(BaseTestCase): self.client.login(username="alice@example.org", password="password") r = self.client.post(url) - assert r.status_code == 400 + self.assertEqual(r.status_code, 404) def test_it_checks_owner(self): url = "/checks/%s/remove/" % self.check.code diff --git a/hc/front/tests/test_update_name.py b/hc/front/tests/test_update_name.py index f88b0b25..dfccaf5c 100644 --- a/hc/front/tests/test_update_name.py +++ b/hc/front/tests/test_update_name.py @@ -46,7 +46,7 @@ class UpdateNameTestCase(BaseTestCase): self.client.login(username="alice@example.org", password="password") r = self.client.post(url, data=payload) - assert r.status_code == 400 + self.assertEqual(r.status_code, 404) def test_it_handles_missing_uuid(self): # Valid UUID but there is no check for it: diff --git a/hc/front/tests/test_update_timeout.py b/hc/front/tests/test_update_timeout.py index e1578efa..c47b7a76 100644 --- a/hc/front/tests/test_update_timeout.py +++ b/hc/front/tests/test_update_timeout.py @@ -128,7 +128,7 @@ class UpdateTimeoutTestCase(BaseTestCase): self.client.login(username="alice@example.org", password="password") r = self.client.post(url, data=payload) - assert r.status_code == 400 + self.assertEqual(r.status_code, 404) def test_it_handles_missing_uuid(self): # Valid UUID but there is no check for it: diff --git a/hc/front/urls.py b/hc/front/urls.py index 8cb1b0f6..dfd2779a 100644 --- a/hc/front/urls.py +++ b/hc/front/urls.py @@ -1,55 +1,55 @@ -from django.conf.urls import include, url +from django.urls import include, path from hc.front import views check_urls = [ - url(r'^name/$', views.update_name, name="hc-update-name"), - url(r'^timeout/$', views.update_timeout, name="hc-update-timeout"), - url(r'^pause/$', views.pause, name="hc-pause"), - url(r'^remove/$', views.remove_check, name="hc-remove-check"), - url(r'^log/$', views.log, name="hc-log"), - url(r'^last_ping/$', views.ping_details, name="hc-last-ping"), - url(r'^pings/([\d]+)/$', views.ping_details, name="hc-ping-details"), + path('name/', views.update_name, name="hc-update-name"), + path('timeout/', views.update_timeout, name="hc-update-timeout"), + path('pause/', views.pause, name="hc-pause"), + path('remove/', views.remove_check, name="hc-remove-check"), + path('log/', views.log, name="hc-log"), + path('last_ping/', views.ping_details, name="hc-last-ping"), + path('pings//', views.ping_details, name="hc-ping-details"), ] channel_urls = [ - url(r'^$', views.channels, name="hc-channels"), - url(r'^add_email/$', views.add_email, name="hc-add-email"), - url(r'^add_webhook/$', views.add_webhook, name="hc-add-webhook"), - url(r'^add_pd/$', views.add_pd, name="hc-add-pd"), - url(r'^add_pd/([\w]{12})/$', views.add_pd, name="hc-add-pd-state"), - url(r'^add_pagertree/$', views.add_pagertree, name="hc-add-pagertree"), - url(r'^add_slack/$', views.add_slack, name="hc-add-slack"), - url(r'^add_slack_btn/$', views.add_slack_btn, name="hc-add-slack-btn"), - url(r'^add_hipchat/$', views.add_hipchat, name="hc-add-hipchat"), - url(r'^hipchat/capabilities/$', views.hipchat_capabilities, name="hc-hipchat-capabilities"), - url(r'^add_pushbullet/$', views.add_pushbullet, name="hc-add-pushbullet"), - url(r'^add_discord/$', views.add_discord, name="hc-add-discord"), - url(r'^add_pushover/$', views.add_pushover, name="hc-add-pushover"), - url(r'^add_opsgenie/$', views.add_opsgenie, name="hc-add-opsgenie"), - url(r'^add_victorops/$', views.add_victorops, name="hc-add-victorops"), - url(r'^telegram/bot/$', views.telegram_bot, name="hc-telegram-webhook"), - url(r'^add_telegram/$', views.add_telegram, name="hc-add-telegram"), - url(r'^add_sms/$', views.add_sms, name="hc-add-sms"), - url(r'^add_zendesk/$', views.add_zendesk, name="hc-add-zendesk"), - url(r'^([\w-]+)/checks/$', views.channel_checks, name="hc-channel-checks"), - url(r'^([\w-]+)/remove/$', views.remove_channel, name="hc-remove-channel"), - url(r'^([\w-]+)/verify/([\w-]+)/$', views.verify_email, - name="hc-verify-email"), - url(r'^([\w-]+)/unsub/([\w-]+)/$', views.unsubscribe_email, - name="hc-unsubscribe-alerts"), + path('', views.channels, name="hc-channels"), + path('add_email/', views.add_email, name="hc-add-email"), + path('add_webhook/', views.add_webhook, name="hc-add-webhook"), + path('add_pd/', views.add_pd, name="hc-add-pd"), + path('add_pd//', views.add_pd, name="hc-add-pd-state"), + path('add_pagertree/', views.add_pagertree, name="hc-add-pagertree"), + path('add_slack/', views.add_slack, name="hc-add-slack"), + path('add_slack_btn/', views.add_slack_btn, name="hc-add-slack-btn"), + path('add_hipchat/', views.add_hipchat, name="hc-add-hipchat"), + path('hipchat/capabilities/', views.hipchat_capabilities, name="hc-hipchat-capabilities"), + path('add_pushbullet/', views.add_pushbullet, name="hc-add-pushbullet"), + path('add_discord/', views.add_discord, name="hc-add-discord"), + path('add_pushover/', views.add_pushover, name="hc-add-pushover"), + path('add_opsgenie/', views.add_opsgenie, name="hc-add-opsgenie"), + path('add_victorops/', views.add_victorops, name="hc-add-victorops"), + path('telegram/bot/', views.telegram_bot, name="hc-telegram-webhook"), + path('add_telegram/', views.add_telegram, name="hc-add-telegram"), + path('add_sms/', views.add_sms, name="hc-add-sms"), + path('add_zendesk/', views.add_zendesk, name="hc-add-zendesk"), + path('/checks/', views.channel_checks, name="hc-channel-checks"), + path('/remove/', views.remove_channel, name="hc-remove-channel"), + path('/verify//', views.verify_email, + name="hc-verify-email"), + path('/unsub//', views.unsubscribe_email, + name="hc-unsubscribe-alerts"), ] urlpatterns = [ - url(r'^$', views.index, name="hc-index"), - url(r'^checks/$', views.my_checks, name="hc-checks"), - url(r'^checks/add/$', views.add_check, name="hc-add-check"), - url(r'^checks/cron_preview/$', views.cron_preview), - url(r'^checks/status/$', views.status), - url(r'^checks/([\w-]+)/', include(check_urls)), - url(r'^integrations/', include(channel_urls)), + path('', views.index, name="hc-index"), + path('checks/', views.my_checks, name="hc-checks"), + path('checks/add/', views.add_check, name="hc-add-check"), + path('checks/cron_preview/', views.cron_preview), + path('checks/status/', views.status), + path('checks//', include(check_urls)), + path('integrations/', include(channel_urls)), - url(r'^docs/$', views.docs, name="hc-docs"), - url(r'^docs/api/$', views.docs_api, name="hc-docs-api"), - url(r'^docs/cron/$', views.docs_cron, name="hc-docs-cron"), + path('docs/', views.docs, name="hc-docs"), + path('docs/api/', views.docs_api, name="hc-docs-api"), + path('docs/cron/', views.docs_cron, name="hc-docs-cron"), ] diff --git a/hc/front/views.py b/hc/front/views.py index b17c32ba..8c5976ae 100644 --- a/hc/front/views.py +++ b/hc/front/views.py @@ -17,7 +17,6 @@ from django.utils import timezone from django.utils.crypto import get_random_string from django.views.decorators.csrf import csrf_exempt from django.views.decorators.http import require_POST -from hc.api.decorators import uuid_or_400 from hc.api.models import (DEFAULT_GRACE, DEFAULT_TIMEOUT, Channel, Check, Ping, Notification) from hc.api.transports import Telegram @@ -178,7 +177,6 @@ def add_check(request): @require_POST @login_required -@uuid_or_400 def update_name(request, code): check = get_object_or_404(Check, code=code) if check.user_id != request.team.user.id: @@ -195,7 +193,6 @@ def update_name(request, code): @require_POST @login_required -@uuid_or_400 def update_timeout(request, code): check = get_object_or_404(Check, code=code) if check.user != request.team.user: @@ -273,7 +270,6 @@ def ping_details(request, code, n=None): @require_POST @login_required -@uuid_or_400 def pause(request, code): check = get_object_or_404(Check, code=code) if check.user_id != request.team.user.id: @@ -287,7 +283,6 @@ def pause(request, code): @require_POST @login_required -@uuid_or_400 def remove_check(request, code): check = get_object_or_404(Check, code=code) if check.user != request.team.user: @@ -299,7 +294,6 @@ def remove_check(request, code): @login_required -@uuid_or_400 def log(request, code): check = get_object_or_404(Check, code=code) if check.user != request.team.user: @@ -384,7 +378,6 @@ def channels(request): @login_required -@uuid_or_400 def channel_checks(request, code): channel = get_object_or_404(Channel, code=code) if channel.user_id != request.team.user.id: @@ -402,7 +395,6 @@ def channel_checks(request, code): return render(request, "front/channel_checks.html", ctx) -@uuid_or_400 def verify_email(request, code, token): channel = get_object_or_404(Channel, code=code) if channel.make_token() == token: @@ -413,7 +405,6 @@ def verify_email(request, code, token): return render(request, "bad_link.html") -@uuid_or_400 def unsubscribe_email(request, code, token): channel = get_object_or_404(Channel, code=code) if channel.make_token() != token: @@ -428,7 +419,6 @@ def unsubscribe_email(request, code, token): @require_POST @login_required -@uuid_or_400 def remove_channel(request, code): # user may refresh the page during POST and cause two deletion attempts channel = Channel.objects.filter(code=code).first() @@ -503,7 +493,7 @@ def add_pd(request, state=None): if settings.PD_VENDOR_KEY is None: raise Http404("pagerduty integration is not available") - if state and request.user.is_authenticated(): + if state and request.user.is_authenticated: if "pd" not in request.session: return HttpResponseBadRequest() @@ -537,6 +527,7 @@ def add_pd(request, state=None): ctx = {"page": "channels", "connect_url": connect_url} return render(request, "integrations/add_pd.html", ctx) + @login_required def add_pagertree(request): if request.method == "POST": @@ -840,7 +831,7 @@ def add_victorops(request): @require_POST def telegram_bot(request): try: - doc = json.loads(request.body.decode("utf-8")) + doc = json.loads(request.body.decode()) jsonschema.validate(doc, telegram_callback) except ValueError: return HttpResponseBadRequest() diff --git a/hc/lib/badges.py b/hc/lib/badges.py index 21777535..9fc06f4b 100644 --- a/hc/lib/badges.py +++ b/hc/lib/badges.py @@ -45,7 +45,7 @@ def get_badge_svg(tag, status): def check_signature(username, tag, sig): ours = base64_hmac(str(username), tag, settings.SECRET_KEY) - ours = ours[:8].decode("utf-8") + ours = ours[:8] return ours == sig diff --git a/hc/payments/admin.py b/hc/payments/admin.py index ade2c94a..70b21e7e 100644 --- a/hc/payments/admin.py +++ b/hc/payments/admin.py @@ -1,5 +1,5 @@ from django.contrib import admin -from django.core.urlresolvers import reverse +from django.urls import reverse from hc.accounts.models import Profile from hc.payments.models import Subscription diff --git a/hc/payments/urls.py b/hc/payments/urls.py index 0fdb0966..a6031796 100644 --- a/hc/payments/urls.py +++ b/hc/payments/urls.py @@ -1,39 +1,39 @@ -from django.conf.urls import url +from django.urls import path from . import views urlpatterns = [ - url(r'^pricing/$', - views.pricing, - name="hc-pricing"), + path('pricing/', + views.pricing, + name="hc-pricing"), - url(r'^accounts/profile/billing/$', - views.billing, - name="hc-billing"), + path('accounts/profile/billing/', + views.billing, + name="hc-billing"), - url(r'^accounts/profile/billing/history/$', - views.billing_history, - name="hc-billing-history"), + path('accounts/profile/billing/history/', + views.billing_history, + name="hc-billing-history"), - url(r'^accounts/profile/billing/address/$', - views.address, - name="hc-billing-address"), + path('accounts/profile/billing/address/', + views.address, + name="hc-billing-address"), - url(r'^accounts/profile/billing/payment_method/$', - views.payment_method, - name="hc-payment-method"), + path('accounts/profile/billing/payment_method/', + views.payment_method, + name="hc-payment-method"), - url(r'^invoice/pdf/([\w-]+)/$', - views.pdf_invoice, - name="hc-invoice-pdf"), + path('invoice/pdf//', + views.pdf_invoice, + name="hc-invoice-pdf"), - url(r'^pricing/set_plan/$', - views.set_plan, - name="hc-set-plan"), + path('pricing/set_plan/', + views.set_plan, + name="hc-set-plan"), - url(r'^pricing/get_client_token/$', - views.get_client_token, - name="hc-get-client-token"), + path('pricing/get_client_token/', + views.get_client_token, + name="hc-get-client-token"), - url(r'^pricing/charge/$', views.charge_webhook), + path('pricing/charge/', views.charge_webhook), ] diff --git a/hc/urls.py b/hc/urls.py index 090dc567..669df950 100644 --- a/hc/urls.py +++ b/hc/urls.py @@ -1,13 +1,13 @@ -from django.conf.urls import include, url from django.contrib import admin +from django.urls import include, path from hc.accounts.views import login as hc_login urlpatterns = [ - url(r'^admin/login/', hc_login, {"show_password": True}), - url(r'^admin/', admin.site.urls), - url(r'^accounts/', include('hc.accounts.urls')), - url(r'^', include('hc.api.urls')), - url(r'^', include('hc.front.urls')), - url(r'^', include('hc.payments.urls')) + path('admin/login/', hc_login, {"show_password": True}), + path('admin/', admin.site.urls), + path('accounts/', include('hc.accounts.urls')), + path('', include('hc.api.urls')), + path('', include('hc.front.urls')), + path('', include('hc.payments.urls')) ] diff --git a/requirements.txt b/requirements.txt index 2143d2fd..a008b4ca 100644 --- a/requirements.txt +++ b/requirements.txt @@ -1,5 +1,5 @@ croniter -Django==1.11.6 +Django==2.0.4 django_compressor==2.1 psycopg2==2.7.3.2 pytz==2016.7