From 99b81602da50082021dc2ecffb34fc4227e5adf5 Mon Sep 17 00:00:00 2001 From: Ryan Lerch Date: Feb 19 2018 09:23:42 +0000 Subject: add some basic link validation and error handling in library widget fixes #585 fixes #586 --- diff --git a/hubs/utils/validators.py b/hubs/utils/validators.py index 602770a..79b2953 100644 --- a/hubs/utils/validators.py +++ b/hubs/utils/validators.py @@ -11,6 +11,7 @@ will return the validated value. from __future__ import unicode_literals +import urllib import flask import kitchen.text.converters import requests @@ -50,8 +51,17 @@ def Integer(value): def Link(value): """Raises an error if the value doesn't look like a link.""" - # TODO -- verify that this is actually a link - return value + url = urllib.parse.urlparse(value) + if not url.scheme: + value = "http://"+value + url = urllib.parse.urlparse(value) + elif url.scheme not in ["http", "https"]: + raise ValueError("the {} protocol is not supported".format(url.scheme)) + + if url.netloc: + return value + else: + raise ValueError("{} is not valid URL".format(value)) def Username(value): diff --git a/hubs/widgets/library/views.py b/hubs/widgets/library/views.py index 6a58de6..c376a5e 100644 --- a/hubs/widgets/library/views.py +++ b/hubs/widgets/library/views.py @@ -7,6 +7,7 @@ from bs4 import BeautifulSoup from hubs.utils.pagination import paginate from hubs.widgets.view import WidgetView from hubs.utils.views import check_hub_access +from hubs.utils.validators import Link class LinkValidationError(Exception): @@ -77,12 +78,19 @@ class GetLinkView(WidgetView): def get_context(self, instance, *args, **kwargs): url = flask.request.values.get("url") + try: + url = Link(url) + except ValueError as e: + return dict(status="ERROR", message=str(e)) + if not url: return dict(status="ERROR", message="No URL.") try: response = requests.get(url, timeout=10) except requests.exceptions.Timeout: return dict(status="ERROR", message="Connection timed out.") + except requests.exceptions.ConnectionError: + return dict(status="ERROR", message="Could not fetch this URL") if not response.ok: return dict( status="ERROR",