Show More
@@ -1,8 +1,8 b'' | |||
|
1 | 1 | .. -*- mode: rst; compile-command: "rst2html README.txt README.html" -*- |
|
2 | 2 | |
|
3 | ================= | |
|
3 | ======================================================= | |
|
4 | 4 | Mercurial Keyring |
|
5 | ================= | |
|
5 | ======================================================= | |
|
6 | 6 | |
|
7 | 7 | Mercurial Keyring is a Mercurial_ extension used to securely save HTTP |
|
8 | 8 | and SMTP authentication passwords in password databases (Gnome |
@@ -25,7 +25,7 b' extension glues it to Mercurial.' | |||
|
25 | 25 | .. _Mercurial: http://mercurial.selenic.com |
|
26 | 26 | |
|
27 | 27 | How does it work |
|
28 | ================ | |
|
28 | ======================================================= | |
|
29 | 29 | |
|
30 | 30 | On your first pull or push to HTTP url (or first email sent via given |
|
31 | 31 | SMTP server), you are prompted for the password, just like bare |
@@ -35,15 +35,15 b' needed, ``mercurial_keyring`` checks for' | |||
|
35 | 35 | database, and uses it without troubling you. |
|
36 | 36 | |
|
37 | 37 | In case password turns out to be incorrect (for example, because you |
|
38 |
changed it, or entered it incorrectly), ``mercurial_keyring`` |
|
|
39 | it, and prompts you again. | |
|
38 | changed it, or entered it incorrectly), ``mercurial_keyring`` prompts | |
|
39 | you again, and overwrites the password. | |
|
40 | 40 | |
|
41 | 41 | You can use many passwords (for various remote urls). Saved passwords |
|
42 | 42 | are identified by pair of username and url prefix. See below for |
|
43 | 43 | information how to configure those properly. |
|
44 | 44 | |
|
45 | 45 | Installation |
|
46 | ============ | |
|
46 | ======================================================= | |
|
47 | 47 | |
|
48 | 48 | Prerequisites |
|
49 | 49 | ------------- |
@@ -108,7 +108,7 b' and configure Mercurial by telling it fu' | |||
|
108 | 108 | .. _mercurial_keyring.py: http://bitbucket.org/Mekk/mercurial_keyring/src/tip/mercurial_keyring.py |
|
109 | 109 | |
|
110 | 110 | Password backend configuration |
|
111 | ============================== | |
|
111 | ======================================================= | |
|
112 | 112 | |
|
113 | 113 | The library should usually pick the most appropriate password backend |
|
114 | 114 | without configuration. Still, if necessary, it can be configured using |
@@ -128,7 +128,7 b' without configuration. Still, if necessa' | |||
|
128 | 128 | |
|
129 | 129 | |
|
130 | 130 | ``hgrc`` configuration (HTTP) |
|
131 | =============================== | |
|
131 | ======================================================= | |
|
132 | 132 | |
|
133 | 133 | Mercurial Keyring uses standard Mercurial ``[auth]`` configuration to |
|
134 | 134 | detect your username (on given remote) and url prefix. You are |
@@ -214,7 +214,7 b' Additional advantage of this method is t' | |||
|
214 | 214 | |
|
215 | 215 | |
|
216 | 216 | ``hgrc`` configuration (SMTP) |
|
217 | =============================== | |
|
217 | ======================================================= | |
|
218 | 218 | |
|
219 | 219 | Edit either repository-local ``.hg/hgrc``, or ``~/.hgrc`` and set |
|
220 | 220 | there all standard email and smtp properties, including SMTP |
@@ -237,7 +237,10 b' password here to use the extension, in o' | |||
|
237 | 237 | the default behavior. |
|
238 | 238 | |
|
239 | 239 | Usage |
|
240 | ===== | |
|
240 | ====================================================== | |
|
241 | ||
|
242 | Saving and restoring passwords | |
|
243 | ------------------------------------------------------- | |
|
241 | 244 | |
|
242 | 245 | Configure the repository as above, then just ``hg pull``, ``hg push``, |
|
243 | 246 | etc. You should be asked for the password only once (per every |
@@ -247,27 +250,61 b' Similarly, for email, configure as above' | |||
|
247 | 250 | Again, you will be asked for the password once (per every username and |
|
248 | 251 | email server address combination). |
|
249 | 252 | |
|
253 | Checking password status (``hg keyring_check``) | |
|
254 | ------------------------------------------------------- | |
|
255 | ||
|
256 | The ``keyring_check`` command can be used to check whether/which | |
|
257 | password(s) are saved. It can be used in three ways: | |
|
258 | ||
|
259 | - without parameters, it prints info related to all HTTP paths | |
|
260 | defined for current repository (everything from ``hg paths`` | |
|
261 | that resolves to HTTP url):: | |
|
262 | ||
|
263 | hg keyring_check | |
|
264 | ||
|
265 | - given alias as param, it prints info about this alias:: | |
|
266 | ||
|
267 | hg keyring_check work | |
|
268 | ||
|
269 | - finally, any path can be checked:: | |
|
270 | ||
|
271 | hg keyring_check https://bitbucket.org/Mekk/mercurial_keyring | |
|
272 | ||
|
273 | Deleting saved password (``hg keyring_clear``) | |
|
274 | ------------------------------------------------------- | |
|
275 | ||
|
276 | The ``keyring_clear`` command removes saved password related to given | |
|
277 | path. It can be used in two ways: | |
|
278 | ||
|
279 | - given alias as param, it drops password used by this alias:: | |
|
280 | ||
|
281 | hg keyring_clear work | |
|
282 | ||
|
283 | - given full path, it drops password related to this path:: | |
|
284 | ||
|
285 | hg keyring_clear https://bitbucket.org/Mekk/mercurial_keyring | |
|
286 | ||
|
250 | 287 | Implementation details |
|
251 | ====================== | |
|
288 | ======================================================= | |
|
252 | 289 | |
|
253 | 290 | The extension is monkey-patching the mercurial ``passwordmgr`` class |
|
254 | 291 | to replace the ``find_user_password`` method. Detailed order of operations |
|
255 | 292 | is described in the comments inside `the code`_. |
|
256 | 293 | |
|
257 | 294 | History |
|
258 | ========== | |
|
295 | ======================================================= | |
|
259 | 296 | |
|
260 | 297 | See `HISTORY.txt`_. |
|
261 | 298 | |
|
262 | 299 | Development |
|
263 | =========== | |
|
300 | ======================================================= | |
|
264 | 301 | |
|
265 | 302 | Development is tracked on BitBucket, see |
|
266 | 303 | http://bitbucket.org/Mekk/mercurial_keyring/ |
|
267 | 304 | |
|
268 | 305 | |
|
269 | 306 | Additional notes |
|
270 | ================ | |
|
307 | ======================================================= | |
|
271 | 308 | |
|
272 | 309 | Information about this extension is also available |
|
273 | 310 | on Mercurial Wiki: http://mercurial.selenic.com/wiki/KeyringExtension |
@@ -64,6 +64,7 b' import smtplib' | |||
|
64 | 64 | import socket |
|
65 | 65 | import os |
|
66 | 66 | import sys |
|
67 | import re | |
|
67 | 68 | |
|
68 | 69 | # pylint: disable=invalid-name, line-too-long, protected-access, too-many-arguments |
|
69 | 70 | |
@@ -677,14 +678,17 b' def _smtp(ui):' | |||
|
677 | 678 | # Custom commands |
|
678 | 679 | ############################################################ |
|
679 | 680 | |
|
680 | def cmd_keyring_check(ui, repo, *path_args, **opts): | |
|
681 | _re_http_url = re.compile(r'^https?://') | |
|
682 | ||
|
683 | def is_http_path(url): | |
|
684 | return bool(_re_http_url.search(url)) | |
|
685 | ||
|
686 | ||
|
687 | def cmd_keyring_check(ui, repo, *path_args, **opts): # pylint: disable=unused-argument | |
|
681 | 688 | """ |
|
682 | 689 | Prints basic info (whether password is currently saved, and how is |
|
683 | 690 | it identified) for given path or for all defined repo paths which are HTTP. |
|
684 | 691 | """ |
|
685 | import re | |
|
686 | ||
|
687 | re_http_url = re.compile(r'^https?://') | |
|
688 | 692 | defined_paths = [(name, url) |
|
689 | 693 | for name, url in ui.configitems('paths')] |
|
690 | 694 | if path_args: |
@@ -696,17 +700,18 b' def cmd_keyring_check(ui, repo, *path_ar' | |||
|
696 | 700 | paths = [(name, url) for name, url in defined_paths] |
|
697 | 701 | |
|
698 | 702 | if not paths: |
|
699 | ui.status(_("keyring_check: no paths defined")) | |
|
703 | ui.status(_("keyring_check: no paths defined\n")) | |
|
700 | 704 | |
|
701 | 705 | handler = HTTPPasswordHandler() |
|
702 | 706 | |
|
703 | 707 | ui.status(_("keyring password save status:\n")) |
|
704 | 708 | for name, url in paths: |
|
705 |
if not |
|
|
709 | if not is_http_path(url): | |
|
706 | 710 | if path_args: |
|
707 | 711 | ui.status(_(" %s: non-http path (%s)\n") % (name, url)) |
|
708 | 712 | continue |
|
709 |
user, pwd, source, final_url = handler.get_credentials( |
|
|
713 | user, pwd, source, final_url = handler.get_credentials( | |
|
714 | passwordmgr(ui), name, url) | |
|
710 | 715 | if pwd: |
|
711 | 716 | ui.status(_(" %s: password available, source: %s, bound to user %s, url %s\n") % ( |
|
712 | 717 | name, source, user, final_url)) |
@@ -718,12 +723,38 b' def cmd_keyring_check(ui, repo, *path_ar' | |||
|
718 | 723 | name, final_url)) |
|
719 | 724 | |
|
720 | 725 | |
|
721 | def cmd_keyring_clear(ui, repo, path, **opts): | |
|
726 | def cmd_keyring_clear(ui, repo, path, **opts): # pylint: disable=unused-argument | |
|
727 | """ | |
|
728 | Drops password bound to given path (if any is saved). | |
|
722 | 729 |
|
|
723 | Drops password bound to given path (if any). | |
|
724 | """ | |
|
725 | # TODO | |
|
726 | ui.status(_("Not yet implemented")) | |
|
730 | path_url = path | |
|
731 | for name, url in ui.configitems('paths'): | |
|
732 | if name == path: | |
|
733 | path_url = url | |
|
734 | break | |
|
735 | if not is_http_path(path_url): | |
|
736 | ui.warn(_("%s is not a http path (%s)") % (path, path_url)) | |
|
737 | return | |
|
738 | ||
|
739 | handler = HTTPPasswordHandler() | |
|
740 | ||
|
741 | user, pwd, source, final_url = handler.get_credentials( | |
|
742 | passwordmgr(ui), path, path_url) | |
|
743 | if not user: | |
|
744 | ui.status(_("Username not configured for url %s\n") % final_url) | |
|
745 | return | |
|
746 | if not pwd: | |
|
747 | ui.status(_("No password is saved for user %s, url %s\n") % ( | |
|
748 | user, final_url)) | |
|
749 | return | |
|
750 | ||
|
751 | if source != handler.SRC_KEYRING: | |
|
752 | ui.status(_("Password for user %s, url %s is saved in %s, not in keyring\n") % ( | |
|
753 | user, final_url, source)) | |
|
754 | ||
|
755 | password_store.clear_http_password(final_url, user) | |
|
756 | ui.status(_("Password removed for user %s, url %s\n") % ( | |
|
757 | user, final_url)) | |
|
727 | 758 | |
|
728 | 759 | |
|
729 | 760 | cmdtable = { |
General Comments 0
You need to be logged in to leave comments.
Login now