This file is indexed.

/usr/share/pyshared/zope/testbrowser/cookies.py is in python-zope.testbrowser 4.0.2-1.

This file is owned by root:root, with mode 0o644.

The actual contents of the file can be viewed below.

  1
  2
  3
  4
  5
  6
  7
  8
  9
 10
 11
 12
 13
 14
 15
 16
 17
 18
 19
 20
 21
 22
 23
 24
 25
 26
 27
 28
 29
 30
 31
 32
 33
 34
 35
 36
 37
 38
 39
 40
 41
 42
 43
 44
 45
 46
 47
 48
 49
 50
 51
 52
 53
 54
 55
 56
 57
 58
 59
 60
 61
 62
 63
 64
 65
 66
 67
 68
 69
 70
 71
 72
 73
 74
 75
 76
 77
 78
 79
 80
 81
 82
 83
 84
 85
 86
 87
 88
 89
 90
 91
 92
 93
 94
 95
 96
 97
 98
 99
100
101
102
103
104
105
106
107
108
109
110
111
112
113
114
115
116
117
118
119
120
121
122
123
124
125
126
127
128
129
130
131
132
133
134
135
136
137
138
139
140
141
142
143
144
145
146
147
148
149
150
151
152
153
154
155
156
157
158
159
160
161
162
163
164
165
166
167
168
169
170
171
172
173
174
175
176
177
178
179
180
181
182
183
184
185
186
187
188
189
190
191
192
193
194
195
196
197
198
199
200
201
202
203
204
205
206
207
208
209
210
211
212
213
214
215
216
217
218
219
220
221
222
223
224
225
226
227
228
229
230
231
232
233
234
235
236
237
238
239
240
241
242
243
244
245
246
247
248
249
250
251
252
253
254
255
256
257
258
259
260
261
262
263
264
265
266
267
268
269
270
271
272
273
274
275
276
277
278
279
280
281
282
283
284
285
286
287
288
289
290
291
292
293
294
295
296
297
298
299
300
301
302
303
304
305
306
307
308
309
310
311
312
313
314
315
316
317
318
319
320
321
322
323
324
325
326
327
328
329
330
331
332
333
334
335
336
337
338
339
340
341
342
343
344
345
346
347
348
349
350
351
352
353
354
355
356
357
358
359
360
361
362
363
364
365
366
367
368
369
370
371
372
373
374
375
376
377
378
379
##############################################################################
#
# Copyright (c) 2008 Zope Foundation and Contributors.
# All Rights Reserved.
#
# This software is subject to the provisions of the Zope Public License,
# Version 2.1 (ZPL).  A copy of the ZPL should accompany this distribution.
# THIS SOFTWARE IS PROVIDED "AS IS" AND ANY AND ALL EXPRESS OR IMPLIED
# WARRANTIES ARE DISCLAIMED, INCLUDING, BUT NOT LIMITED TO, THE IMPLIED
# WARRANTIES OF TITLE, MERCHANTABILITY, AGAINST INFRINGEMENT, AND FITNESS
# FOR A PARTICULAR PURPOSE.
#
##############################################################################

import Cookie
import datetime
import time
import urllib
import urlparse
import UserDict

import mechanize
import pytz
import zope.interface
from zope.testbrowser import interfaces

# Cookies class helpers


class _StubHTTPMessage(object):
    def __init__(self, cookies):
        self._cookies = cookies

    def getheaders(self, name):
        if name.lower() != 'set-cookie':
            return []
        else:
            return self._cookies


class _StubResponse(object):
    def __init__(self, cookies):
        self.message = _StubHTTPMessage(cookies)

    def info(self):
        return self.message

def expiration_string(expires): # this is not protected so usable in tests.
    if isinstance(expires, datetime.datetime):
        if expires.tzinfo is not None:
            expires = expires.astimezone(pytz.UTC)
        expires = expires.strftime('%a, %d %b %Y %H:%M:%S GMT')
    return expires

if getattr(property, 'setter', None) is None:
    # hack on Python 2.6 spelling of the only part we use here
    class property(property):
        __slots__ = ()
        def setter(self, f):
            return property(self.fget, f, self.fdel, self.__doc__)

# end Cookies class helpers


class Cookies(object, UserDict.DictMixin):
    """Cookies for mechanize browser.
    """

    zope.interface.implements(interfaces.ICookies)

    def __init__(self, mech_browser, url=None):
        self.mech_browser = mech_browser
        self._url = url
        for handler in self.mech_browser.handlers:
            if getattr(handler, 'cookiejar', None) is not None:
                self._jar = handler.cookiejar
                break
        else:
            raise RuntimeError('no cookiejar found')

    @property
    def strict_domain_policy(self):
        policy = self._jar.get_policy()
        flags = (policy.DomainStrictNoDots | policy.DomainRFC2965Match |
                 policy.DomainStrictNonDomain)
        return policy.strict_ns_domain & flags == flags

    @strict_domain_policy.setter
    def strict_domain_policy(self, value):
        jar = self._jar
        policy = jar.get_policy()
        flags = (policy.DomainStrictNoDots | policy.DomainRFC2965Match |
                 policy.DomainStrictNonDomain)
        policy.strict_ns_domain |= flags
        if not value:
            policy.strict_ns_domain  ^= flags

    def forURL(self, url):
        return self.__class__(self.mech_browser, url)

    @property
    def url(self):
        if self._url is not None:
            return self._url
        else:
            return self.mech_browser.geturl()

    @property
    def _request(self):
        if self._url is not None:
            return self.mech_browser.request_class(self._url)
        else:
            request = self.mech_browser.request
            if request is None:
                raise RuntimeError('no request found')
            return request

    @property
    def header(self):
        request = self.mech_browser.request_class(self.url)
        self._jar.add_cookie_header(request)
        return request.get_header('Cookie')

    def __str__(self):
        return self.header

    def __repr__(self):
        # get the cookies for the current url
        return '<%s.%s object at %r for %s (%s)>' % (
            self.__class__.__module__, self.__class__.__name__,
            id(self), self.url, self.header)

    def _raw_cookies(self):
        return self._jar.cookies_for_request(self._request)

    def _get_cookies(self, key=None):
        if key is None:
            seen = set()
            for ck in self._raw_cookies():
                if ck.name not in seen:
                    yield ck
                    seen.add(ck.name)
        else:
            for ck in self._raw_cookies():
                if ck.name == key:
                    yield ck

    _marker = object()

    def _get(self, key, default=_marker):
        for ck in self._raw_cookies():
            if ck.name == key:
                return ck
        if default is self._marker:
            raise KeyError(key)
        return default

    def __getitem__(self, key):
        return self._get(key).value

    def getinfo(self, key):
        return self._getinfo(self._get(key))

    def _getinfo(self, ck):
        res = {'name': ck.name,
               'value': ck.value,
               'port': ck.port,
               'domain': ck.domain,
               'path': ck.path,
               'secure': ck.secure,
               'expires': None,
               'comment': ck.comment,
               'commenturl': ck.comment_url}
        if ck.expires is not None:
            res['expires'] = datetime.datetime.fromtimestamp(
                ck.expires, pytz.UTC)
        return res

    def keys(self):
        return [ck.name for ck in self._get_cookies()]

    def __iter__(self):
        return (ck.name for ck in self._get_cookies())

    iterkeys = __iter__

    def iterinfo(self, key=None):
        return (self._getinfo(ck) for ck in self._get_cookies(key))

    def iteritems(self):
        return ((ck.name, ck.value) for ck in self._get_cookies())

    def has_key(self, key):
        return self._get(key, None) is not None

    __contains__ = has_key

    def __len__(self):
        return len(list(self._get_cookies()))

    def __delitem__(self, key):
        ck = self._get(key)
        self._jar.clear(ck.domain, ck.path, ck.name)

    def create(self, name, value,
               domain=None, expires=None, path=None, secure=None, comment=None,
               commenturl=None, port=None):
        if value is None:
            raise ValueError('must provide value')
        ck = self._get(name, None)
        if (ck is not None and
            (path is None or ck.path == path) and
            (domain is None or ck.domain == domain or
             ck.domain == domain) and
            (port is None or ck.port == port)):
            # cookie already exists
            raise ValueError('cookie already exists')
        if domain is not None:
            self._verifyDomain(domain, ck)
        if path is not None:
            self._verifyPath(path, ck)
        now = int(time.time())
        if expires is not None and self._is_expired(expires, now):
            raise zope.testbrowser.interfaces.AlreadyExpiredError(
                'May not create a cookie that is immediately expired')
        self._setCookie(name, value, domain, expires, path, secure, comment,
                        commenturl, port, now=now)

    def change(self, name, value=None,
            domain=None, expires=None, path=None, secure=None, comment=None,
            commenturl=None, port=None):
        now = int(time.time())
        if expires is not None and self._is_expired(expires, now):
            # shortcut
            del self[name]
        else:
            self._change(self._get(name), value, domain, expires, path, secure,
                         comment, commenturl, port, now)

    def _change(self, ck, value=None,
                domain=None, expires=None, path=None, secure=None,
                comment=None, commenturl=None, port=None, now=None):
        if value is None:
            value = ck.value
        if domain is None:
            domain = ck.domain
        else:
            self._verifyDomain(domain, None)
        if expires is None:
            expires = ck.expires
        if path is None:
            path = ck.path
        else:
            self._verifyPath(domain, None)
        if secure is None:
            secure = ck.secure
        if comment is None:
            comment = ck.comment
        if commenturl is None:
            commenturl = ck.comment_url
        if port is None:
            port = ck.port
        self._setCookie(ck.name, value, domain, expires, path, secure, comment,
                        commenturl, port, ck.version, ck=ck, now=now)

    def _verifyDomain(self, domain, ck):
        tmp_domain = domain
        if domain is not None and domain.startswith('.'):
            tmp_domain = domain[1:]
        self_host = mechanize.effective_request_host(self._request)
        if (self_host != tmp_domain and
            not self_host.endswith('.' + tmp_domain)):
            raise ValueError('current url must match given domain')
        if (ck is not None and ck.domain != tmp_domain and
            ck.domain.endswith(tmp_domain)):
            raise ValueError(
                'cannot set a cookie that will be hidden by another '
                'cookie for this url (%s)' % (self.url,))

    def _verifyPath(self, path, ck):
        self_path = urlparse.urlparse(self.url)[2]
        if not self_path.startswith(path):
            raise ValueError('current url must start with path, if given')
        if ck is not None and ck.path != path and ck.path.startswith(path):
            raise ValueError(
                'cannot set a cookie that will be hidden by another '
                'cookie for this url (%s)' % (self.url,))

    def _setCookie(self, name, value, domain, expires, path, secure, comment,
                   commenturl, port, version=None, ck=None, now=None):
        for nm, val in self.mech_browser.addheaders:
            if nm.lower() in ('cookie', 'cookie2'):
                raise ValueError('cookies are already set in `Cookie` header')
        if domain and not domain.startswith('.'):
            # we do a dance here so that we keep names that have been passed
            # in consistent (i.e., if we get an explicit 'example.com' it stays
            # 'example.com', rather than converting to '.example.com').
            tmp_domain = domain
            domain = None
            if secure:
                protocol = 'https'
            else:
                protocol = 'http'
            url = '%s://%s%s' % (protocol, tmp_domain, path or '/')
            request = self.mech_browser.request_class(url)
        else:
            request = self._request
            if request is None:
                raise mechanize.BrowserStateError(
                    'cannot create cookie without request or domain')
        c = Cookie.SimpleCookie()
        name = str(name)
        c[name] = value.encode('utf8')
        if secure:
            c[name]['secure'] = True
        if domain:
            c[name]['domain'] = domain
        if path:
            c[name]['path'] = path
        if expires:
            c[name]['expires'] = expiration_string(expires)
        if comment:
            c[name]['comment'] = urllib.quote(
                comment.encode('utf-8'), safe="/?:@&+")
        if port:
            c[name]['port'] = port
        if commenturl:
            c[name]['commenturl'] = commenturl
        if version:
            c[name]['version'] = version
        # this use of objects like _StubResponse and _StubHTTPMessage is in
        # fact supported by the documented client cookie API.
        cookies = self._jar.make_cookies(
            _StubResponse([c.output(header='').strip()]), request)
        assert len(cookies) == 1, (
            'programmer error: %d cookies made' % (len(cookies),))
        policy = self._jar._policy
        if now is None:
            now = int(time.time())
        policy._now = self._jar._now = now # TODO get mechanize to expose this
        if not policy.set_ok(cookies[0], request):
            raise ValueError('policy does not allow this cookie')
        if ck is not None:
            self._jar.clear(ck.domain, ck.path, ck.name)
        self._jar.set_cookie(cookies[0])

    def __setitem__(self, key, value):
        ck = self._get(key, None)
        if ck is None:
            self.create(key, value)
        else:
            self._change(ck, value)

    def _is_expired(self, value, now): # now = int(time.time())
        dnow = datetime.datetime.fromtimestamp(now, pytz.UTC)
        if isinstance(value, datetime.datetime):
            if value.tzinfo is None:
                 if value <= dnow.replace(tzinfo=None):
                    return True
            elif value <= dnow:
                return True
        elif isinstance(value, basestring):
            if datetime.datetime.fromtimestamp(
                mechanize.str2time(value),
                pytz.UTC) <= dnow:
                return True
        return False

    def clear(self):
        # to give expected mapping behavior of resulting in an empty dict,
        # we use _raw_cookies rather than _get_cookies.
        for ck in self._raw_cookies():
            self._jar.clear(ck.domain, ck.path, ck.name)

    def clearAllSession(self):
        self._jar.clear_session_cookies()

    def clearAll(self):
        self._jar.clear()