Sign Up
Log In
Log In
or
Sign Up
Places
All Projects
Status Monitor
Collapse sidebar
openSUSE:11.4:Update
python-bugzilla
0002-NovellBugzilla-implementation.patch
Overview
Repositories
Revisions
Requests
Users
Attributes
Meta
File 0002-NovellBugzilla-implementation.patch of Package python-bugzilla
From 5347c9d17b0f8bb0430611b687b1389d0620c035 Mon Sep 17 00:00:00 2001 From: Michal Vyskocil <mvyskocil@suse.cz> Date: Tue, 21 Jul 2009 16:17:21 +0200 Subject: [PATCH 2/2] NovellBugzilla implementation. The NovellBugzilla implementation - is a subclass of Bugzilla32 with reimplemented _login and _logoout methods compatible with iChain. NovellBugzilla don't allow other self.url than bnc, because it should not be used for any other bugzilla. The url parameters in __init__ and connect() are overwritten and exists only for compatibility purposes. It can also read the username/password from ~/.oscrc, which is common for many SUSE users and contains a same iChain credentials as is necessary for bugzilla login. So when user use osc he don't need duplicate login informations to ~/.bugzillarc. --- bugzilla/__init__.py | 3 +- bugzilla/nvlbugzilla.py | 164 +++++++++++++++++++++++++++++++++++++++++++++++ 2 files changed, 166 insertions(+), 1 deletions(-) create mode 100644 bugzilla/nvlbugzilla.py diff --git a/bugzilla/__init__.py b/bugzilla/__init__.py index 902c996..a871f26 100644 --- a/bugzilla/__init__.py +++ b/bugzilla/__init__.py @@ -11,13 +11,14 @@ from bugzilla3 import Bugzilla3, Bugzilla32 from rhbugzilla import RHBugzilla, RHBugzilla3 +from nvlbugzilla import NovellBugzilla from base import version import xmlrpclib import logging log = logging.getLogger("bugzilla") # advertised class list -classlist = ['Bugzilla3', 'Bugzilla32', 'RHBugzilla3'] +classlist = ['Bugzilla3', 'Bugzilla32', 'RHBugzilla3', 'NovellBugzilla'] def getBugzillaClassForURL(url): log.debug("Choosing subclass for %s" % url) diff --git a/bugzilla/nvlbugzilla.py b/bugzilla/nvlbugzilla.py new file mode 100644 index 0000000..027bb19 --- /dev/null +++ b/bugzilla/nvlbugzilla.py @@ -0,0 +1,164 @@ +# nvlbugzilla.py - a Python interface to Novell Hat Bugzilla using xmlrpclib. +# +# Copyright (C) 2009 Novell Inc. +# Author: Michal Vyskocil <mvyskocil@suse.cz> +# +# This program is free software; you can redistribute it and/or modify it +# under the terms of the GNU General Public License as published by the +# Free Software Foundation; either version 2 of the License, or (at your +# option) any later version. See http://www.gnu.org/copyleft/gpl.html for +# the full text of the license. + +#from bugzilla.base import BugzillaError, log +import bugzilla.base +from bugzilla import Bugzilla32 + +import urllib +import urllib2 +import urlparse +import cookielib +import time +import re +import os + +class NovellBugzilla(Bugzilla32): + '''bugzilla.novell.com is a standard bugzilla 3.2 with some extensions, but + it uses an proprietary and non-standard IChain login system. This class + reimplements a login method which is compatible with iChain. + + Because login process takes relativelly long time, because it needs several + HTTP requests, NovellBugzilla caches the session cookies of bugzilla + (ZXXXXXXX-bugzilla) and IChain (IPCXXXXXXXXXXXXX) in a self._cookiefile to + speedup a repeated connections. To avoid problems with cookie expiration, + it set the expiration of cookie to 5 minutes. This expects cookies stored + in LWPCookieJar format and login method warn if cookies are in + MozillaCookieJar format. + + It can also read a credentials from ~/.oscrc if exists, so it should not + be duplicated in /etc/bugzillarc, or ~/.bugzillarc + ''' + + version = '0.1' + user_agent = bugzilla.base.user_agent + ' NovellBugzilla/%s' % version + + bnc_cookie_re = re.compile('^Z.*-bugzilla') + ichain_cookie_re = re.compile('^IPC.*') + cookie_domain_re = re.compile('.*\.novell\.com$') + + bugzilla_url = 'https://bugzilla.novell.com/xmlrpc.cgi' + logout_url = 'https://www.novell.com/cmd/ICSLogout' + obs_url = 'https://api.opensuse.org/' + #FIXME: is it really necessary to use all those paths??? + login_path = '/index.cgi?GoAheadAndLogIn=1' + auth_path = '/ICSLogin/auth-up' + ichainlogin_path = '/ichainlogin.cgi' + + def __init__(self, expires=300, **kwargs): + self._expires = expires + super(NovellBugzilla, self).__init__(**kwargs) + # url argument exists only for backward compatibility, but is always set to same url + self._url = self.__class__.bugzilla_url + + def __get_expiration(self): + return self._expires + def __set_expiration(self, expires): + self._expires = expires + expires = property(__get_expiration, __set_expiration) + + def _iter_domain_cookies(self): + '''Return an generator from all cookies matched a self.__class__.cookie_domain_re''' + return (c for c in self._cookiejar if self.__class__.cookie_domain_re.match(c.domain) and not c.is_expired()) + + def _is_bugzilla_cookie(self): + return len([c for c in self._iter_domain_cookies() if self.__class__.bnc_cookie_re.match(c.name)]) != 0 + + def _is_ichain_cookie(self): + return len([c for c in self._iter_domain_cookies() if self.__class__.ichain_cookie_re.match(c.name)]) != 0 + + def _is_lwp_format(self): + return isinstance(self._cookiejar, cookielib.LWPCookieJar) + + def _login(self, user, password): + #TODO: IChain is an openID provides - discover an ability of openID login + + # init some basic + cls = self.__class__ + base_url = self.url[:-11] # remove /xmlrpc.cgi + + lwp_format = self._is_lwp_format() + if not lwp_format: + bugzilla.base.log.warn("""File `%s' is not in LWP format required for NovellBugzilla. +If you want cache the cookies and speedup the repeated connections, remove it or use an another file for cookies.""" % self._cookiefile) + + #TODO: do some testing what will be if the cookie expires + if lwp_format and not self._is_bugzilla_cookie(): + login_url = urlparse.urljoin(base_url, cls.login_path) + bugzilla.base.log.info("GET %s" % login_url) + login_resp = self._opener.open(login_url) + if login_resp.code != 200: + raise BugzillaError("The login failed with code %d" % login_resp.core) + + params = { + 'url' : urlparse.urljoin(base_url, cls.ichainlogin_path), + 'target' : cls.login_path[1:], + 'context' : 'default', + 'proxypath' : 'reverse', + 'nlogin_submit_btn' : 'Log In', + 'username' : user, + 'password' : password + } + + if lwp_format and not self._is_ichain_cookie(): + auth_url = urlparse.urljoin(base_url, cls.auth_path) + auth_params = urllib.urlencode(params) + auth_req = urllib2.Request(auth_url, auth_params) + bugzilla.base.log.info("POST %s" % auth_url) + auth_resp = self._opener.open(auth_req) + if auth_resp.code != 200: + raise BugzillaError("The auth failed with code %d" % auth_resp.core) + + if lwp_format: + for cookie in self._cookiejar: + cookie.expires = time.time() + self._expires # expires cookie in 15 minutes + cookie.discard = False + + return super(NovellBugzilla, self)._login(user, password) + + def connect(self, url): + # NovellBugzilla should connect only to bnc, + return super(NovellBugzilla, self).connect(self.__class__.bugzilla_url) + + def _logout(self): + '''Novell bugzilla don't support xmlrpc logout, so let's implemtent it. + This method also set all domain cookies as expired. + ''' + + resp = self._opener.open(self.__class__.logout_url) + # expire cookies + for cookie in self._iter_domain_cookies(): + cookie.expires = 0 + + def readconfig(self, configpath=None): + super(NovellBugzilla, self).readconfig(configpath) + + oscrc=os.path.expanduser('~/.oscrc') + if not self.user and not self.password \ + and os.path.exists(oscrc): + from ConfigParser import SafeConfigParser, NoOptionError + c = SafeConfigParser() + r = c.read(oscrc) + if not r: + return + + obs_url = self.__class__.obs_url + if not c.has_section(obs_url): + return + + try: + self.user = c.get(obs_url, 'user') + self.password = c.get(obs_url, 'pass') + bugzilla.base.log.info("Read credentials from ~/.oscrc") + except NoOptionError, ne: + return + + -- 1.6.3.3
Locations
Projects
Search
Status Monitor
Help
OpenBuildService.org
Documentation
API Documentation
Code of Conduct
Contact
Support
@OBShq
Terms
openSUSE Build Service is sponsored by
The Open Build Service is an
openSUSE project
.
Sign Up
Log In
Places
Places
All Projects
Status Monitor