From 3f8a57e733bdcc410c448f3600e0c0ffcb71feb0 Mon Sep 17 00:00:00 2001 From: Mike Bonnet Date: Thu, 30 Oct 2014 14:02:09 -0400 Subject: [PATCH 2/2] clean up Koji login, and properly support password auth --- src/pyrpkg/__init__.py | 148 +++++++++++++++++++++++++++++------------------- src/pyrpkg/cli.py | 4 + 2 files changed, 93 insertions(+), 59 deletions(-) diff --git a/src/pyrpkg/__init__.py b/src/pyrpkg/__init__.py index bb8d78c..0879622 100644 --- a/src/pyrpkg/__init__.py +++ b/src/pyrpkg/__init__.py @@ -70,8 +70,8 @@ class Commands(object): def __init__(self, path, lookaside, lookasidehash, lookaside_cgi, gitbaseurl, anongiturl, branchre, kojiconfig, - build_client, user=None, runas=None, dist=None, target=None, - quiet=False): + build_client, user=None, password=None, runas=None, + dist=None, target=None, quiet=False): """Init the object and some configuration details.""" # Path to operate on, most often pwd @@ -142,6 +142,8 @@ class Commands(object): self._topurl = None # The user to use or discover self._user = user + # The password to use + self._password = password # The alternate Koji user to run commands as self._runas = runas # The rpm version of the cloned module @@ -190,50 +192,71 @@ class Commands(object): # Stealing a bunch of code from /usr/bin/koji here, too bad it isn't # in a more usable library form defaults = { - 'server' : 'http://localhost/kojihub', - 'weburl' : 'http://localhost/koji', - 'pkgurl' : 'http://localhost/packages', - 'topdir' : '/mnt/koji', - 'cert': '~/.koji/client.crt', - 'ca': '~/.koji/clientca.crt', - 'serverca': '~/.koji/serverca.crt', - 'krbservice' : 'host', - 'authtype': None, - 'topurl': None - } - # Process the configs in order, global, user, then any option passed - for configfile in (self.kojiconfig, - os.path.expanduser('~/.koji/config')): - try: - f = open(configfile) - except IOError: - self.log.debug("Could not read %s for config values" % - configfile) + 'server': None, + 'topurl': 'http://localhost/kojiroot', + 'weburl' : 'http://localhost/koji', + 'cert': '~/.koji/client.crt', + 'ca': '~/.koji/clientca.crt', + 'serverca': '~/.koji/serverca.crt', + 'authtype': None, + 'krbservice': None, + 'timeout' : None, + 'keepalive' : True, + 'max_retries': None, + 'retry_interval': None, + 'anon_retry' : True, + 'offline_retry' : None, + 'offline_retry_interval' : None, + 'use_fast_upload': None, + 'debug': None, + 'debug_xmlrpc': None + } - else: - with f: - config = ConfigParser.ConfigParser() - config.readfp(f) - - if config.has_section(os.path.basename(self.build_client)): - for name, value in config.items(os.path.basename( - self.build_client)): - if defaults.has_key(name): - defaults[name] = value + # Process the configs in order, global, user, then any option passed + config = ConfigParser.ConfigParser() + confs = [self.kojiconfig, + os.path.expanduser('~/.koji/config')] + config.read(confs) + + if config.has_section(os.path.basename(self.build_client)): + for name, value in config.items(os.path.basename( + self.build_client)): + if name in defaults: + if name in ('keepalive', 'anon_retry', 'offline_retry', + 'use_fast_upload', + 'debug', 'debug_xmlrpc'): + defaults[name] = config.getboolean(os.path.basename( + self.build_client), name) + elif name in ('timeout', 'max_retries', 'retry_interval', + 'offline_retry_interval'): + defaults[name] = config.getint(os.path.basename( + self.build_client), name) + else: + defaults[name] = value + if not defaults['server']: + raise rpkgError('No server defined in: %s' % ', '.join(confs)) # Expand out the directory options - for name in ('topdir', 'cert', 'ca', 'serverca', 'topurl', 'krbservice'): + for name in ('cert', 'ca', 'serverca'): if defaults[name]: defaults[name] = os.path.expanduser(defaults[name]) self.log.debug('Initiating a %s session to %s' % (os.path.basename(self.build_client), defaults['server'])) + session_opts = {} + for name in ('krbservice', 'timeout', 'keepalive', + 'max_retries', 'retry_interval', 'anon_retry', + 'offline_retry', 'offline_retry_interval', + 'debug', 'debug_xmlrpc', + 'use_fast_upload'): + if defaults[name] is not None: + session_opts[name] = defaults[name] try: - if not anon: - session_opts = {'user': self.user} + if anon: + self._anon_kojisession = koji.ClientSession(defaults['server'], + session_opts) + else: self._kojisession = koji.ClientSession(defaults['server'], session_opts) - else: - self._anon_kojisession = koji.ClientSession(defaults['server']) except: raise rpkgError('Could not initiate %s session' % os.path.basename(self.build_client)) @@ -241,29 +264,30 @@ class Commands(object): self._kojiweburl = defaults['weburl'] self._topurl = defaults['topurl'] if not anon: - # Default to ssl if not otherwise specified and we have - # the cert - if defaults['authtype'] == 'ssl' or \ - os.path.isfile(defaults['cert']) and \ - defaults['authtype'] is None: - self._kojisession.ssl_login(defaults['cert'], - defaults['ca'], - defaults['serverca'], - proxyuser=self.runas) - # Or try password auth - elif defaults['authtype'] == 'password' or \ - 'user' in defaults and defaults['authtype'] is None: - if self.runas is not None: - raise rpkgError('--runas cannot be used with password auth') - self._kojisession.login() - # Or try kerberos - elif defaults['authtype'] == 'kerberos' or \ - self._has_krb_creds() and \ - defaults['authtype'] is None: - self._kojisession.krb_login(proxyuser=self.runas) - if not self._kojisession.logged_in: - raise rpkgError('Could not auth with koji as %s' % - self.user) + # Default to ssl if not otherwise specified and we have + # the cert + if defaults['authtype'] == 'ssl' or \ + (os.path.isfile(defaults['cert']) and \ + defaults['authtype'] is None): + self._kojisession.ssl_login(defaults['cert'], + defaults['ca'], + defaults['serverca'], + proxyuser=self.runas) + # Or try password auth + elif defaults['authtype'] == 'password' or \ + (self.password and defaults['authtype'] is None): + if self.runas: + raise rpkgError('--runas cannot be used with password auth') + self._kojisession.opts['user'] = self.user + self._kojisession.opts['password'] = self.password + self._kojisession.login() + # Or try kerberos + elif defaults['authtype'] == 'kerberos' or \ + (self._has_krb_creds() and \ + defaults['authtype'] is None): + self._kojisession.krb_login(proxyuser=self.runas) + if not self._kojisession.logged_in: + raise rpkgError('Could not login to %s' % defaults['server']) @property def branch_merge(self): @@ -660,6 +684,12 @@ class Commands(object): self._user = os.getlogin() @property + def password(self): + """This property ensures the password attribute""" + + return self._password + + @property def runas(self): """This property ensures the runas attribute""" diff --git a/src/pyrpkg/cli.py b/src/pyrpkg/cli.py index a6b02d4..e743850 100755 --- a/src/pyrpkg/cli.py +++ b/src/pyrpkg/cli.py @@ -104,6 +104,7 @@ class cliClient(object): items['kojiconfig'], items['build_client'], user=self.args.user, + password=self.args.password, runas=self.args.runas, dist=self.args.dist, target=target, @@ -158,6 +159,9 @@ class cliClient(object): # Override the discovered user name self.parser.add_argument('--user', default=None, help='Override the discovered user name') + # If using password auth + self.parser.add_argument('--password', default=None, + help='Password for Koji login') # Run Koji commands as a user other then the one you have # credentials for (requires configuration on the Koji hub) self.parser.add_argument('--runas', default=None, -- 1.7.1