Skip to content

Commit 1a107b3

Browse files
committed
base: Always deal with cookies in LWP format
That is the preferred one internally, and it's fairly trivial to convert from one form to another, so do it upfront.
1 parent 3e60ade commit 1a107b3

6 files changed

Lines changed: 87 additions & 45 deletions

File tree

bugzilla/base.py

Lines changed: 39 additions & 24 deletions
Original file line numberDiff line numberDiff line change
@@ -62,6 +62,39 @@ def _decode_rfc2231_value(val):
6262
for f in header.decode_header(val))
6363

6464

65+
def _build_cookiejar(cookiefile):
66+
cj = cookielib.LWPCookieJar(cookiefile)
67+
if cookiefile is None:
68+
return cj
69+
if not os.path.exists(cookiefile):
70+
# Make sure a new file has correct permissions
71+
open(cookiefile, 'a').close()
72+
os.chmod(cookiefile, 0600)
73+
cj.save()
74+
return cj
75+
76+
# We always want to use LWP cookies, but we previously accepted
77+
# Mozilla cookies. If we see Mozilla, convert it to LWP
78+
try:
79+
cj.load()
80+
return cj
81+
except cookielib.LoadError:
82+
pass
83+
84+
try:
85+
cj = cookielib.MozillaCookieJar(cookiefile)
86+
cj.load()
87+
except cookielib.LoadError:
88+
raise BugzillaError("cookiefile=%s not in LWP or Mozilla format" %
89+
cookiefile)
90+
91+
retcj = cookielib.LWPCookieJar(cookiefile)
92+
for cookie in cj:
93+
retcj.set_cookie(cookie)
94+
retcj.save()
95+
return retcj
96+
97+
6598
# CookieTransport code mostly borrowed from pybugz
6699
class _CookieTransport(xmlrpclib.Transport):
67100
def __init__(self, uri, cookiejar, use_datetime=0):
@@ -273,37 +306,19 @@ def _getcookiefile(self):
273306
'''
274307
return self._cookiejar.filename
275308

309+
def _delcookiefile(self):
310+
self._cookiejar = None
311+
276312
def _setcookiefile(self, cookiefile):
277-
if (self._cookiejar and
278-
cookiefile == self._cookiejar.filename):
313+
if (self._cookiejar and cookiefile == self._cookiejar.filename):
279314
return
280315

281316
if self._proxy is not None:
282317
raise RuntimeError("Can't set cookies with an open connection, "
283318
"disconnect() first.")
284319

285320
log.debug("Using cookiefile=%s", cookiefile)
286-
# It first tries to use the existing cookiejar object. If it fails, it
287-
# falls back to MozillaCookieJar.
288-
do_load = cookiefile is not None and os.path.exists(cookiefile)
289-
try:
290-
cj = cookielib.LWPCookieJar(cookiefile)
291-
if do_load:
292-
cj.load()
293-
except cookielib.LoadError:
294-
cj = cookielib.MozillaCookieJar(cookiefile)
295-
if do_load:
296-
cj.load()
297-
298-
if cookiefile is not None and not do_load:
299-
open(cookiefile, 'a').close()
300-
os.chmod(cookiefile, 0600)
301-
cj.save()
302-
303-
self._cookiejar = cj
304-
305-
def _delcookiefile(self):
306-
self._cookiejar = None
321+
self._cookiejar = _build_cookiejar(cookiefile)
307322

308323
cookiefile = property(_getcookiefile, _setcookiefile, _delcookiefile)
309324

@@ -416,7 +431,7 @@ def login(self, user=None, password=None):
416431
except xmlrpclib.Fault:
417432
r = False
418433

419-
if r and self._cookiejar.filename:
434+
if r and self._cookiejar.filename is not None:
420435
self._cookiejar.save()
421436
return r
422437

bugzilla/nvlbugzilla.py

Lines changed: 7 additions & 21 deletions
Original file line numberDiff line numberDiff line change
@@ -9,7 +9,6 @@
99
# option) any later version. See http://www.gnu.org/copyleft/gpl.html for
1010
# the full text of the license.
1111

12-
import cookielib
1312
import os
1413
import re
1514
import time
@@ -30,8 +29,7 @@ class NovellBugzilla(Bugzilla34):
3029
HTTP requests, NovellBugzilla caches the session cookies of bugzilla
3130
and IChain in a cookiejar to speedup a repeated connections.
3231
To avoid problems with cookie expiration, it set the expiration of cookie
33-
to 5 minutes. This expects cookies stored in LWPCookieJar format and
34-
login method warn if cookies are in MozillaCookieJar format.
32+
to 5 minutes.
3533
3634
It can also read a credentials from ~/.oscrc if exists, so it should not
3735
be duplicated in /etc/bugzillarc, or ~/.bugzillarc.
@@ -87,24 +85,13 @@ def _is_ichain_cookie(self):
8785
return len([c for c in self._iter_domain_cookies() if
8886
self.__class__.ichain_cookie_re.match(c.name)]) != 0
8987

90-
def _is_lwp_format(self):
91-
return isinstance(self._cookiejar, cookielib.LWPCookieJar)
92-
9388
def _login(self, user, password):
9489
cls = self.__class__
9590

9691
# remove /xmlrpc.cgi
9792
base_url = self.url[:-11]
9893

99-
lwp_format = self._is_lwp_format()
100-
if not lwp_format:
101-
log.warn("File `%s' is not in LWP format required for "
102-
"NovellBugzilla. If you want cache the cookies "
103-
"and speedup the repeated connections, remove it "
104-
"or use an another file for cookies.",
105-
self.cookiefile)
106-
107-
if lwp_format and not self._is_bugzilla_cookie():
94+
if not self._is_bugzilla_cookie():
10895
login_url = urlparse.urljoin(base_url, cls.login_path)
10996
log.info("GET %s" % login_url)
11097
login_resp = self._opener.open(login_url)
@@ -122,7 +109,7 @@ def _login(self, user, password):
122109
'password': password,
123110
}
124111

125-
if lwp_format and not self._is_ichain_cookie():
112+
if not self._is_ichain_cookie():
126113
auth_url = urlparse.urljoin(base_url, cls.auth_path)
127114
auth_params = urllib.urlencode(params)
128115
auth_req = urllib2.Request(auth_url, auth_params)
@@ -132,11 +119,10 @@ def _login(self, user, password):
132119
raise BugzillaError("The auth failed with code %d" %
133120
auth_resp.core)
134121

135-
if lwp_format:
136-
for cookie in self._cookiejar:
137-
# expires cookie in 15 minutes
138-
cookie.expires = time.time() + self._expires
139-
cookie.discard = False
122+
for cookie in self._cookiejar:
123+
# expires cookie in 15 minutes
124+
cookie.expires = time.time() + self._expires
125+
cookie.discard = False
140126

141127
return super(NovellBugzilla, self)._login(user, password)
142128

tests/data/cookies-bad.txt

Lines changed: 1 addition & 0 deletions
Original file line numberDiff line numberDiff line change
@@ -0,0 +1 @@
1+
foo this is invalid cookies

tests/data/cookies-lwp.txt

Lines changed: 3 additions & 0 deletions
Original file line numberDiff line numberDiff line change
@@ -0,0 +1,3 @@
1+
#LWP-Cookies-2.0
2+
Set-Cookie3: Bugzilla_login=notacookie; path="/"; domain=".partner-bugzilla.redhat.com"; domain_dot; expires="2038-01-01 00:00:00Z"; version=0
3+
Set-Cookie3: Bugzilla_logincookie=notacookie; path="/"; domain=".partner-bugzilla.redhat.com"; domain_dot; expires="2038-01-01 00:00:00Z"; version=0

tests/data/cookies-moz.txt

Lines changed: 6 additions & 0 deletions
Original file line numberDiff line numberDiff line change
@@ -0,0 +1,6 @@
1+
# Netscape HTTP Cookie File
2+
# http://www.netscape.com/newsref/std/cookie_spec.html
3+
# This is a generated file! Do not edit.
4+
5+
.partner-bugzilla.redhat.com TRUE / FALSE 2145916800 Bugzilla_login notacookie
6+
.partner-bugzilla.redhat.com TRUE / FALSE 2145916800 Bugzilla_logincookie notacookie

tests/misc.py

Lines changed: 31 additions & 0 deletions
Original file line numberDiff line numberDiff line change
@@ -9,6 +9,9 @@
99
Unit tests for building query strings with bin/bugzilla
1010
'''
1111

12+
import atexit
13+
import os
14+
import shutil
1215
import unittest
1316

1417
import bugzilla
@@ -61,6 +64,34 @@ def testUserAgent(self):
6164
self.assertTrue(b3.user_agent.endswith("Bugzilla3/0.1"))
6265
self.assertTrue(rhbz.user_agent.endswith("RHBugzilla/0.1"))
6366

67+
def testCookies(self):
68+
cookiesbad = os.path.join(os.getcwd(), "tests/data/cookies-bad.txt")
69+
cookieslwp = os.path.join(os.getcwd(), "tests/data/cookies-lwp.txt")
70+
cookiesmoz = os.path.join(os.getcwd(), "tests/data/cookies-moz.txt")
71+
cookiesnewmoz = os.path.join(os.getcwd(),
72+
"tests/data/cookies-moz.txt.new")
73+
74+
def cleanup():
75+
if os.path.exists(cookiesnewmoz):
76+
os.unlink(cookiesnewmoz)
77+
atexit.register(cleanup)
78+
shutil.copy(cookiesmoz, cookiesnewmoz)
79+
80+
# Mozilla should be converted inplace to LWP
81+
bugzilla.Bugzilla3(url=None, cookiefile=cookiesnewmoz)
82+
self.assertEquals(file(cookieslwp).read(), file(cookiesnewmoz).read())
83+
84+
# Make sure bad cookies raise an error
85+
try:
86+
bugzilla.Bugzilla3(url=None, cookiefile=cookiesbad)
87+
raise AssertionError("Expected BugzillaError from parsing %s" %
88+
os.path.basename(cookiesbad))
89+
except bugzilla.BugzillaError:
90+
# Expected result
91+
pass
92+
93+
# LWP should 'just work'
94+
bugzilla.Bugzilla3(url=None, cookiefile=cookieslwp)
6495

6596
def testPostTranslation(self):
6697
def _testPostCompare(bz, indict, outexpect):

0 commit comments

Comments
 (0)