1
0
mirror of https://github.com/openSUSE/osc.git synced 2025-01-26 22:56:15 +01:00

osc can now store credentials in Gnome keyring if it is available (bnc#460540)

This commit is contained in:
Michal Cihar 2009-05-11 07:46:01 +00:00
parent 72532fb016
commit 7074362e90
4 changed files with 94 additions and 13 deletions

1
NEWS
View File

@ -12,6 +12,7 @@
- osc rlog now works with srcmd5 also
- plugins now should be placed in /usr/lib/osc-plugins to match FHS (the /var path is still supported though)
- osc now includes automatically generated man page
- osc can now store credentials in Gnome keyring if it is available
0.117:
- support checkout of single package via "osc co PACKAGE" when local dir is project

9
README
View File

@ -115,6 +115,15 @@ described above. So basically just adjust all apiurl sections (it might be the
case that some sections already have the correct format).
KEYRING USAGE
Osc now can store passwords in Gnome keyring instead of ~/.oscrc. To use it,
you need python-gnomekeyring and keyring daemon running.
If you want to switch to using Gnome keyring you need to delete apiurl section
from ~/.oscrc and you will be asked for credentials again, which will be then
stored in Gnome keyring.
USAGE EXAMPLES:
(online at http://en.opensuse.org/Build_Service/CLI )

View File

@ -88,6 +88,8 @@ class Osc(cmdln.Cmdln):
optparser.add_option('-c', '--config', dest='conffile',
metavar='FILE',
help='specify alternate configuration file')
optparser.add_option('--no-gnome-keyring', action='store_true',
help='disable usage of GNOME Keyring')
return optparser
@ -99,7 +101,8 @@ class Osc(cmdln.Cmdln):
override_debug = self.options.debug,
override_http_debug = self.options.http_debug,
override_traceback = self.options.traceback,
override_post_mortem = self.options.post_mortem)
override_post_mortem = self.options.post_mortem,
override_no_gnome_keyring = self.options.no_gnome_keyring)
except oscerr.NoConfigfile, e:
print >>sys.stderr, e.msg
print >>sys.stderr, 'Creating osc configuration file %s ...' % e.file
@ -118,13 +121,7 @@ class Osc(cmdln.Cmdln):
import getpass
user = raw_input('Username: ')
passwd = getpass.getpass()
cp = conf.get_configParser()
cp.add_section(e.url)
cp.set(e.url, 'user', user)
cp.set(e.url, 'pass', passwd)
file = open(e.file, 'w')
cp.write(file, True)
if file: file.close()
conf.add_section(e.file, e.url, user, passwd)
if try_again: self.postoptparse(try_again = False)
self.conf = conf

View File

@ -32,6 +32,14 @@ The configuration dictionary could look like this:
import OscConfigParser
from osc import oscerr
try:
import gobject
gobject.set_application_name('osc')
import gnomekeyring
GNOME_KEYRING = gnomekeyring.is_available()
except:
GNOME_KEYRING = False
# being global to this module, this dict can be accessed from outside
# it will hold the parsed configuration
config = { }
@ -54,6 +62,7 @@ DEFAULTS = { 'apiurl': 'https://api.opensuse.org',
'http_debug': '0',
'traceback': '0',
'post_mortem': '0',
'gnome_keyring': '1',
'cookiejar': '~/.osc_cookiejar',
# enable project tracking by default
'do_package_tracking': '1',
@ -104,6 +113,9 @@ apiurl = %(apiurl)s
# print call traces in case of errors
#traceback = 1
# use GNOME keyring for credentials if available
#gnome_keyring = 0
[%(apiurl)s]
user = %(user)s
pass = %(pass)s
@ -114,6 +126,8 @@ pass = %(pass)s
# additional headers to pass to a request, e.g. for special authentication
#http_headers = Host: foofoobar,
# User: mumblegack
# Force using of keyring for this API
#keyring = 1
"""
@ -261,6 +275,16 @@ def write_initial_config(conffile, entries, custom_template = ''):
conf_template = custom_template or new_conf_template
config = DEFAULTS.copy()
config.update(entries)
if config['gnome_keyring'] and GNOME_KEYRING:
protocol, host = \
parse_apisrv_url(None, config['apisrv'])
gnomekeyring.set_network_password_sync(
user = config['user'],
password = config['pass'],
protocol = protocol,
server = host)
config['user'] = ''
config['pass'] = ''
sio = StringIO.StringIO(conf_template.strip() % config)
cp = OscConfigParser.OscConfigParser(DEFAULTS)
cp.readfp(sio)
@ -279,13 +303,41 @@ def write_initial_config(conffile, entries, custom_template = ''):
finally:
if file: file.close()
def add_section(filename, url, user, passwd):
"""
Add a section to config file for new api url.
"""
global config
cp = get_configParser(filename)
try:
cp.add_section(url)
except OscConfigParser.ConfigParser.DuplicateSectionError:
# Section might have existed, but was empty
pass
if config['gnome_keyring'] and GNOME_KEYRING:
protocol, host = \
parse_apisrv_url(None, url)
gnomekeyring.set_network_password_sync(
user = user,
password = passwd,
protocol = protocol,
server = host)
cp.set(url, 'keyring', '1')
else:
cp.set(url, 'user', user)
cp.set(url, 'pass', passwd)
file = open(filename, 'w')
cp.write(file, True)
if file: file.close()
def get_config(override_conffile = None,
override_apiurl = None,
override_debug = None,
override_http_debug = None,
override_traceback = None,
override_post_mortem = None):
override_post_mortem = None,
override_no_gnome_keyring = None):
"""do the actual work (see module documentation)"""
import os
import sys
@ -346,16 +398,38 @@ def get_config(override_conffile = None,
# the following regexp does _not_ support quoted commas within the value.
http_header_regexp = re.compile(r"\s*(.*?)\s*:\s*(.*?)\s*(?:,\s*|\Z)")
# override values which we were called with
# This needs to be done before processing API sections as it might be already used there
if override_no_gnome_keyring:
config['gnome_keyring'] = False
aliases = {}
for url in [ x for x in cp.sections() if x != 'general' ]:
# backward compatiblity
scheme, host = \
parse_apisrv_url(config.get('scheme', 'https'), url)
apiurl = urljoin(scheme, host)
#FIXME: this could actually be the ideal spot to take defaults
#from the general section.
user = cp.get(url, 'user')
password = cp.get(url, 'pass')
user = None
# Read from gnome keyring if available
if config['gnome_keyring'] and GNOME_KEYRING:
try:
gk_data = gnomekeyring.find_network_password_sync(
protocol = scheme,
server = host)
password = gk_data[0]['password']
user = gk_data[0]['user']
except gnomekeyring.NoMatchError:
# Fallback to file based auth.
pass
# Read credentials from config
if user is None:
#FIXME: this could actually be the ideal spot to take defaults
#from the general section.
user = cp.get(url, 'user')
password = cp.get(url, 'pass')
if cp.has_option(url, 'keyring') and cp.get(url, 'keyring'):
# This APIURL was configured to use keyring by
continue
email = ''
if cp.has_option(url, 'email'):
email = cp.get(url, 'email')