##// END OF EJS Templates
Working in-process cache
Marcin Kasperski -
r2:f4014c71 default
parent child Browse files
Show More
@@ -1,74 +1,105 b''
1 1 # -*- coding: utf-8 -*-
2 2
3 3 """
4 4 Storing HTTP authentication passwords in keyring database.
5 5
6 6 Installation method(s):
7 7
8 8 1) in ~/.hgrc (or /etc/hgext/...)
9 9
10 10 [extensions]
11 11 ...
12 12 hgext.mercurial_keyring = /path/to/mercurial_keyring.py
13 13
14 14
15 15 2) Drop this file to hgext directory and in ~/.hgrc
16 16
17 17 [extensions]
18 18 hgext.mercurial_keyring =
19 19
20 20 """
21 21
22 22 from mercurial import hg, repo, util
23 23 from mercurial.i18n import _
24 24 try:
25 25 from mercurial.url import passwordmgr
26 26 except:
27 27 from mercurial.httprepo import passwordmgr
28 28
29 29 import keyring
30 30 import getpass
31 31 from urlparse import urlparse
32 32
33 33 KEYRING_SERVICE = "Mercurial"
34 34
35 ############################################################
36
37 def monkeypatch_class(name, bases, namespace):
38 """http://mail.python.org/pipermail/python-dev/2008-January/076194.html"""
39 assert len(bases) == 1, "Exactly one base class required"
40 base = bases[0]
41 for name, value in namespace.iteritems():
42 if name != "__metaclass__":
43 setattr(base, name, value)
44 return base
45
35 46 def monkeypatch_method(cls):
36 47 def decorator(func):
37 48 setattr(cls, func.__name__, func)
38 49 return func
39 50 return decorator
40 51
52 ############################################################
53
54 class PasswordStore(object):
55 """
56 Helper object handling password save&restore. Passwords
57 are saved both in local memory cache, and keyring, and are
58 restored from those.
59 """
60 def __init__(self):
61 self.cache = dict()
62 def save_password(self, url, username, password):
63 self.cache[url] = (username, password)
64 # TODO: keyring save
65 def get_password(self, url):
66 r = self.cache.get(url)
67 if r:
68 return r
69 # TODO: keyring restore
70 return None, None
71
72 password_store = PasswordStore()
73
74 ############################################################
75
41 76 @monkeypatch_method(passwordmgr)
42 77 def find_user_password(self, realm, authuri):
43 78 """
44 79 keyring-based implementation of username/password query
45 80
46 81 Passwords are saved in gnome keyring, OSX/Chain or other platform
47 82 specific storage and keyed by the repository url
48 83 """
49 84 # Calculate the true url. authuri happens to contain things like
50 85 # https://repo.machine.com/repos/apps/module?pairs=0000000000000000000000000000000000000000-0000000000000000000000000000000000000000&cmd=between
51 86 parsed_url = urlparse(authuri)
52 87 base_url = "%s://%s%s" % (parsed_url.scheme, parsed_url.netloc, parsed_url.path)
53 88 print "find_user_password", realm, base_url
54 89
55
56 # TODO: odczyt danych z cache w procesie
57
58 # TODO: odczyt danych już obecnych w keyring-u
90 user, pwd = password_store.get_password(base_url)
91 if user and pwd:
92 return user, pwd
59 93
60 94 if not self.ui.interactive():
61 95 raise util.Abort(_('mercurial_keyring: http authorization required'))
62 96 self.ui.write(_("http authorization required\n"))
63 97 self.ui.status(_("realm: %s, url: %s\n" % (realm, base_url)))
64 username = self.ui.prompt(_("user:"), default = None)
65 password = self.ui.getpass(_("password for user %s:" % username))
66
67 # TODO: zapis w keyringu
98 user = self.ui.prompt(_("user:"), default = user)
99 pwd = self.ui.getpass(_("password: "))
68 100
69 # TODO: zapis w cache w procesie
101 password_store.save_password(base_url, user, pwd)
70 102
71
72 return username, password
103 return user, pwd
73 104 #return None, None
74 105
General Comments 0
You need to be logged in to leave comments. Login now