~launchpad-pqm/launchpad/devel

14538.2.49 by Curtis Hovey
Updated copyright.
1
# Copyright 2009-2011 Canonical Ltd.  This software is licensed under the
8687.15.18 by Karl Fogel
Add the copyright header block to files under lib/canonical/.
2
# GNU Affero General Public License version 3 (see the file LICENSE).
1793 by Canonical.com Patch Queue Manager
SQL changes related to builders and chroots, for Soyuz 1.0 r=stevea,stub
3
4
__metaclass__ = type
5
12790.2.2 by Tim Penhey
Move the url validators into lp.app.validators.url.
6
__all__ = [
7
    'builder_url_validator',
8
    'valid_absolute_url',
9
    'valid_builder_url',
10
    'valid_webref',
11
    'validate_url',
12
    ]
13
3586.1.1 by Malcolm Cleaton
Fix bugs 3423, 41598 and 39124.
14
from textwrap import dedent
12790.2.2 by Tim Penhey
Move the url validators into lp.app.validators.url.
15
import urllib
3586.1.1 by Malcolm Cleaton
Fix bugs 3423, 41598 and 39124.
16
14600.1.12 by Curtis Hovey
Move i18n to lp.
17
from lp import _
12790.2.1 by Tim Penhey
Local import not needed now.
18
from canonical.launchpad.webapp.url import urlparse
12442.2.2 by j.c.sackett
Moved validators to app, which makes more sense.
19
from lp.app.validators import LaunchpadValidationError
3255.1.1 by Diogo Matsubara
Fix https://launchpad.net/products/malone/+bug/34768 (Unhelpful error message on linking cve) and some validation functions cleanup
20
11403.1.4 by Henning Eggers
Reformatted imports using format-imports script r32.
21
1793 by Canonical.com Patch Queue Manager
SQL changes related to builders and chroots, for Soyuz 1.0 r=stevea,stub
22
def valid_absolute_url(name):
12790.2.3 by Tim Penhey
Wrap the urlparse in a try block for those urls that aren't ascii.
23
    """Validate an absolute URL.
1793 by Canonical.com Patch Queue Manager
SQL changes related to builders and chroots, for Soyuz 1.0 r=stevea,stub
24
2976.2.3 by Stuart Bishop
Allow sftp: branch URLs (Bug 5573)
25
    It looks like this function has been deprecated by
14538.2.37 by Curtis Hovey
Moved lost validators to lp.services.validation
26
    lp.app.validators.validation.
2976.2.3 by Stuart Bishop
Allow sftp: branch URLs (Bug 5573)
27
1793 by Canonical.com Patch Queue Manager
SQL changes related to builders and chroots, for Soyuz 1.0 r=stevea,stub
28
    We define this as something that can be parsed into a URL that has both
29
    a protocol and a network address.
2976.2.3 by Stuart Bishop
Allow sftp: branch URLs (Bug 5573)
30
12790.2.3 by Tim Penhey
Wrap the urlparse in a try block for those urls that aren't ascii.
31
      >>> valid_absolute_url('sftp://chinstrap.ubuntu.com/foo/bar')
32
      True
33
      >>> valid_absolute_url('http://www.example.com')
34
      True
35
      >>> valid_absolute_url('whatever:/uxample.com/blah')
36
      False
37
      >>> valid_absolute_url('whatever://example.com/blah')
38
      True
39
12790.2.4 by Tim Penhey
typo
40
    Unicode urls are ascii encoded, and a failure here means it isn't valid.
12790.2.3 by Tim Penhey
Wrap the urlparse in a try block for those urls that aren't ascii.
41
42
      >>> valid_absolute_url(u'http://www.example.com/test...')
43
      True
44
      >>> valid_absolute_url(u'http://www.example.com/test\u2026')
45
      False
46
1793 by Canonical.com Patch Queue Manager
SQL changes related to builders and chroots, for Soyuz 1.0 r=stevea,stub
47
    """
12790.2.3 by Tim Penhey
Wrap the urlparse in a try block for those urls that aren't ascii.
48
    try:
49
        (scheme, netloc, path, params, query, fragment) = urlparse(name)
50
    except UnicodeEncodeError:
51
        return False
3691.356.1 by Elliot Murphy
Fix bug 76854 (allow bzr+ssh URL scheme)
52
    # note that URL checking is also done inside the database, in
53
    # trusted.sql, the valid_absolute_url function, and that code uses
54
    # stdlib urlparse, not our customized version.
2976.2.3 by Stuart Bishop
Allow sftp: branch URLs (Bug 5573)
55
    if not (scheme and netloc):
56
        return False
57
    return True
58
12790.2.2 by Tim Penhey
Move the url validators into lp.app.validators.url.
59
3586.1.1 by Malcolm Cleaton
Fix bugs 3423, 41598 and 39124.
60
def valid_builder_url(url):
61
    """validate a url for a builder.
62
63
    Builder urls must be http://host/ or http://host:port/
64
    (with or without the trailing slash) only.
65
66
    >>> valid_builder_url('http://example.com:54321/')
67
    True
68
    >>> valid_builder_url('http://example.com/foo')
69
    False
70
    >>> valid_builder_url('ftp://foo.com/')
71
    False
12790.2.3 by Tim Penhey
Wrap the urlparse in a try block for those urls that aren't ascii.
72
3586.1.1 by Malcolm Cleaton
Fix bugs 3423, 41598 and 39124.
73
    """
12790.2.3 by Tim Penhey
Wrap the urlparse in a try block for those urls that aren't ascii.
74
    try:
75
        (scheme, netloc, path, params, query, fragment) = urlparse(url)
76
    except UnicodeEncodeError:
77
        return False
3586.1.1 by Malcolm Cleaton
Fix bugs 3423, 41598 and 39124.
78
    if scheme != 'http':
79
        return False
80
    if params or query or fragment:
81
        return False
82
    if path and path != '/':
83
        return False
84
    return True
85
12790.2.2 by Tim Penhey
Move the url validators into lp.app.validators.url.
86
3586.1.1 by Malcolm Cleaton
Fix bugs 3423, 41598 and 39124.
87
def builder_url_validator(url):
88
    """Return True if the url is valid, or raise a LaunchpadValidationError"""
89
    if not valid_builder_url(url):
90
        raise LaunchpadValidationError(_(dedent("""
5985.6.11 by Maris Fogels
Updated many many LVE callsites to the new API.
91
            Invalid builder url '${url}'. Builder urls must be
3586.1.1 by Malcolm Cleaton
Fix bugs 3423, 41598 and 39124.
92
            http://host/ or http://host:port/ only.
5985.6.11 by Maris Fogels
Updated many many LVE callsites to the new API.
93
            """), mapping={'url': url}))
3586.1.1 by Malcolm Cleaton
Fix bugs 3423, 41598 and 39124.
94
    return True
12790.2.2 by Tim Penhey
Move the url validators into lp.app.validators.url.
95
96
97
def validate_url(url, valid_schemes):
98
    """Returns a boolean stating whether 'url' is a valid URL.
99
12790.2.3 by Tim Penhey
Wrap the urlparse in a try block for those urls that aren't ascii.
100
    A URL is valid if:
101
      - its URL scheme is in the provided 'valid_schemes' list, and
102
      - it has a non-empty host name.
103
104
    None and an empty string are not valid URLs::
105
106
      >>> validate_url(None, [])
107
      False
108
      >>> validate_url('', [])
109
      False
110
111
    The valid_schemes list is checked::
112
113
      >>> validate_url('http://example.com', ['http'])
114
      True
115
      >>> validate_url('http://example.com', ['https', 'ftp'])
116
      False
117
118
    A URL without a host name is not valid:
119
120
      >>> validate_url('http://', ['http'])
121
      False
122
123
    Unicode urls are converted to ascii for checking.  Failure to convert
124
    results in failure.
125
126
      >>> validate_url(u'http://example.com', ['http'])
127
      True
128
      >>> validate_url(u'http://example.com/test\u2026', ['http'])
129
      False
130
131
    """
12790.2.2 by Tim Penhey
Move the url validators into lp.app.validators.url.
132
    if not url:
133
        return False
134
    scheme, host = urllib.splittype(url)
135
    if not scheme in valid_schemes:
136
        return False
137
    if not valid_absolute_url(url):
138
        return False
139
    return True
140
141
142
def valid_webref(web_ref):
143
    """Returns True if web_ref is a valid download URL, or raises a
144
    LaunchpadValidationError.
145
146
    >>> valid_webref('http://example.com')
147
    True
148
    >>> valid_webref('https://example.com/foo/bar')
149
    True
150
    >>> valid_webref('ftp://example.com/~ming')
151
    True
152
    >>> valid_webref('sftp://example.com//absolute/path/maybe')
153
    True
154
    >>> valid_webref('other://example.com/moo')
155
    Traceback (most recent call last):
156
    ...
157
    LaunchpadValidationError: ...
158
    """
159
    if validate_url(web_ref, ['http', 'https', 'ftp', 'sftp']):
160
        # Allow ftp so valid_webref can be used for download_url, and so
161
        # it doesn't lock out weird projects where the site or
162
        # screenshots are kept on ftp.
163
        return True
164
    else:
165
        raise LaunchpadValidationError(_(dedent("""
166
            Not a valid URL. Please enter the full URL, including the
167
            scheme (for instance, http:// for a web URL), and ensure the
168
            URL uses either http, https or ftp.""")))