mirror of
https://github.com/samsonjs/vdirsyncer.git
synced 2026-03-25 08:55:50 +00:00
parent
f4f8f6858f
commit
2a2e4dd04d
3 changed files with 82 additions and 2 deletions
3
setup.py
3
setup.py
|
|
@ -25,5 +25,6 @@ setup(
|
|||
entry_points={
|
||||
'console_scripts': ['vdirsyncer = vdirsyncer.cli:main']
|
||||
},
|
||||
install_requires=['argvard', 'requests', 'lxml']
|
||||
install_requires=['argvard', 'requests', 'lxml'],
|
||||
extras_require={'keyring': ['keyring']}
|
||||
)
|
||||
|
|
|
|||
|
|
@ -12,7 +12,7 @@ import requests
|
|||
import urlparse
|
||||
import hashlib
|
||||
from .base import Storage, Item
|
||||
from vdirsyncer.utils import expand_path
|
||||
from vdirsyncer.utils import expand_path, get_password
|
||||
|
||||
|
||||
def split_collection(text):
|
||||
|
|
@ -81,6 +81,9 @@ class HttpStorageBase(Storage):
|
|||
'''
|
||||
super(HttpStorageBase, self).__init__(**kwargs)
|
||||
|
||||
if username and not password:
|
||||
password = get_password(username, url)
|
||||
|
||||
self._settings = {
|
||||
'verify': prepare_verify(verify),
|
||||
'auth': prepare_auth(auth, username, password)
|
||||
|
|
|
|||
|
|
@ -9,6 +9,7 @@
|
|||
|
||||
import os
|
||||
|
||||
import vdirsyncer.log
|
||||
|
||||
def expand_path(p):
|
||||
p = os.path.expanduser(p)
|
||||
|
|
@ -39,3 +40,78 @@ def parse_options(items):
|
|||
except ValueError:
|
||||
pass
|
||||
yield key, value
|
||||
|
||||
|
||||
def get_password(username, resource):
|
||||
"""tries to access saved password or asks user for it
|
||||
|
||||
will try the following in this order:
|
||||
1. read password from netrc (and only the password, username
|
||||
in netrc will be ignored)
|
||||
2. read password from keyring (keyring needs to be installed)
|
||||
3a ask user for the password
|
||||
b save in keyring if installed and user agrees
|
||||
|
||||
:param username: user's name on the server
|
||||
:type username: str/unicode
|
||||
:param resource: a resource to which the user has access via password,
|
||||
it will be shortened to just the hostname. It is assumed
|
||||
that each unique username/hostname combination only ever
|
||||
uses the same password.
|
||||
:type resource: str/unicode
|
||||
:return: password
|
||||
:rtype: str/unicode
|
||||
|
||||
|
||||
"""
|
||||
import getpass
|
||||
from netrc import netrc
|
||||
try:
|
||||
from urlparse import urlsplit
|
||||
except ImportError:
|
||||
from urllib.parse import urlsplit
|
||||
|
||||
sync_logger = vdirsyncer.log.get('sync')
|
||||
|
||||
# XXX is it save to asume that a password is always the same for
|
||||
# any given (hostname, username) combination?
|
||||
hostname = urlsplit(resource).hostname
|
||||
|
||||
# netrc
|
||||
try:
|
||||
auths = netrc().authenticators(hostname)
|
||||
# auths = (user, password)
|
||||
except IOError:
|
||||
pass
|
||||
else:
|
||||
sync_logger.debug("Read password for user {0} on {1} in .netrc".format(
|
||||
auths[0], hostname))
|
||||
return auths[1]
|
||||
|
||||
# keyring
|
||||
try:
|
||||
import keyring
|
||||
except ImportError:
|
||||
keyring = None
|
||||
else:
|
||||
password = keyring.get_password(
|
||||
'vdirsyncer:' + hostname, username)
|
||||
if password is not None:
|
||||
sync_logger.debug("Got password for user {0}@{1} from keyring".format(
|
||||
username, hostname))
|
||||
return password
|
||||
|
||||
if password is None:
|
||||
prompt = 'Server password {0}@{1}: '.format(username, hostname)
|
||||
password = getpass.getpass(prompt=prompt)
|
||||
|
||||
if keyring:
|
||||
answer = 'x'
|
||||
while answer.lower() not in ['', 'y', 'n']:
|
||||
prompt = 'Save this password in the keyring? [y/N] '
|
||||
answer = raw_input(prompt)
|
||||
if answer.lower() == 'y':
|
||||
password = keyring.set_password(
|
||||
'vdirsyncer:' + hostname, username, password)
|
||||
|
||||
return password
|
||||
|
|
|
|||
Loading…
Reference in a new issue