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:
parent
72532fb016
commit
7074362e90
1
NEWS
1
NEWS
@ -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
9
README
@ -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 )
|
||||
|
@ -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
|
||||
|
84
osc/conf.py
84
osc/conf.py
@ -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')
|
||||
|
Loading…
Reference in New Issue
Block a user