annotate hgext/factotum.py @ 25262:5a809deb88e6

run-tests: python3.5 now supports mkdtemp using bytes for paths Now that http://bugs.python.org/issue24230 is fixed (thanks to Gregory Smith for that quick response!) we can drop one more ugly hack around path handling. Tests still pass in 3.5 with this cleaner version, as well as in 2.6.
author Augie Fackler <raf@durin42.com>
date Fri, 22 May 2015 21:19:08 -0400
parents e8348f1cc228
children 56b2bcea2529
Ignore whitespace changes - Everywhere: Within whitespace: At end of lines:
rev   line source
16383
f5dd179bfa4a plan9: initial support for plan 9 from bell labs
Steven Stallion <sstallion@gmail.com>
parents:
diff changeset
1 # factotum.py - Plan 9 factotum integration for Mercurial
f5dd179bfa4a plan9: initial support for plan 9 from bell labs
Steven Stallion <sstallion@gmail.com>
parents:
diff changeset
2 #
f5dd179bfa4a plan9: initial support for plan 9 from bell labs
Steven Stallion <sstallion@gmail.com>
parents:
diff changeset
3 # Copyright (C) 2012 Steven Stallion <sstallion@gmail.com>
f5dd179bfa4a plan9: initial support for plan 9 from bell labs
Steven Stallion <sstallion@gmail.com>
parents:
diff changeset
4 #
f5dd179bfa4a plan9: initial support for plan 9 from bell labs
Steven Stallion <sstallion@gmail.com>
parents:
diff changeset
5 # This program is free software; you can redistribute it and/or modify it
f5dd179bfa4a plan9: initial support for plan 9 from bell labs
Steven Stallion <sstallion@gmail.com>
parents:
diff changeset
6 # under the terms of the GNU General Public License as published by the
f5dd179bfa4a plan9: initial support for plan 9 from bell labs
Steven Stallion <sstallion@gmail.com>
parents:
diff changeset
7 # Free Software Foundation; either version 2 of the License, or (at your
f5dd179bfa4a plan9: initial support for plan 9 from bell labs
Steven Stallion <sstallion@gmail.com>
parents:
diff changeset
8 # option) any later version.
f5dd179bfa4a plan9: initial support for plan 9 from bell labs
Steven Stallion <sstallion@gmail.com>
parents:
diff changeset
9 #
f5dd179bfa4a plan9: initial support for plan 9 from bell labs
Steven Stallion <sstallion@gmail.com>
parents:
diff changeset
10 # This program is distributed in the hope that it will be useful, but
f5dd179bfa4a plan9: initial support for plan 9 from bell labs
Steven Stallion <sstallion@gmail.com>
parents:
diff changeset
11 # WITHOUT ANY WARRANTY; without even the implied warranty of
f5dd179bfa4a plan9: initial support for plan 9 from bell labs
Steven Stallion <sstallion@gmail.com>
parents:
diff changeset
12 # MERCHANTABILITY or FITNESS FOR A PARTICULAR PURPOSE. See the GNU General
f5dd179bfa4a plan9: initial support for plan 9 from bell labs
Steven Stallion <sstallion@gmail.com>
parents:
diff changeset
13 # Public License for more details.
f5dd179bfa4a plan9: initial support for plan 9 from bell labs
Steven Stallion <sstallion@gmail.com>
parents:
diff changeset
14 #
f5dd179bfa4a plan9: initial support for plan 9 from bell labs
Steven Stallion <sstallion@gmail.com>
parents:
diff changeset
15 # You should have received a copy of the GNU General Public License along
f5dd179bfa4a plan9: initial support for plan 9 from bell labs
Steven Stallion <sstallion@gmail.com>
parents:
diff changeset
16 # with this program; if not, write to the Free Software Foundation, Inc.,
f5dd179bfa4a plan9: initial support for plan 9 from bell labs
Steven Stallion <sstallion@gmail.com>
parents:
diff changeset
17 # 51 Franklin Street, Fifth Floor, Boston, MA 02110-1301 USA.
f5dd179bfa4a plan9: initial support for plan 9 from bell labs
Steven Stallion <sstallion@gmail.com>
parents:
diff changeset
18
f5dd179bfa4a plan9: initial support for plan 9 from bell labs
Steven Stallion <sstallion@gmail.com>
parents:
diff changeset
19 '''http authentication with factotum
f5dd179bfa4a plan9: initial support for plan 9 from bell labs
Steven Stallion <sstallion@gmail.com>
parents:
diff changeset
20
16582
cbb916e2d7c5 factotum: add man reference to help output
Steven Stallion <sstallion@gmail.com>
parents: 16463
diff changeset
21 This extension allows the factotum(4) facility on Plan 9 from Bell Labs
cbb916e2d7c5 factotum: add man reference to help output
Steven Stallion <sstallion@gmail.com>
parents: 16463
diff changeset
22 platforms to provide authentication information for HTTP access. Configuration
cbb916e2d7c5 factotum: add man reference to help output
Steven Stallion <sstallion@gmail.com>
parents: 16463
diff changeset
23 entries specified in the auth section as well as authentication information
cbb916e2d7c5 factotum: add man reference to help output
Steven Stallion <sstallion@gmail.com>
parents: 16463
diff changeset
24 provided in the repository URL are fully supported. If no prefix is specified,
cbb916e2d7c5 factotum: add man reference to help output
Steven Stallion <sstallion@gmail.com>
parents: 16463
diff changeset
25 a value of "*" will be assumed.
16383
f5dd179bfa4a plan9: initial support for plan 9 from bell labs
Steven Stallion <sstallion@gmail.com>
parents:
diff changeset
26
f5dd179bfa4a plan9: initial support for plan 9 from bell labs
Steven Stallion <sstallion@gmail.com>
parents:
diff changeset
27 By default, keys are specified as::
f5dd179bfa4a plan9: initial support for plan 9 from bell labs
Steven Stallion <sstallion@gmail.com>
parents:
diff changeset
28
f5dd179bfa4a plan9: initial support for plan 9 from bell labs
Steven Stallion <sstallion@gmail.com>
parents:
diff changeset
29 proto=pass service=hg prefix=<prefix> user=<username> !password=<password>
f5dd179bfa4a plan9: initial support for plan 9 from bell labs
Steven Stallion <sstallion@gmail.com>
parents:
diff changeset
30
f5dd179bfa4a plan9: initial support for plan 9 from bell labs
Steven Stallion <sstallion@gmail.com>
parents:
diff changeset
31 If the factotum extension is unable to read the required key, one will be
f5dd179bfa4a plan9: initial support for plan 9 from bell labs
Steven Stallion <sstallion@gmail.com>
parents:
diff changeset
32 requested interactively.
f5dd179bfa4a plan9: initial support for plan 9 from bell labs
Steven Stallion <sstallion@gmail.com>
parents:
diff changeset
33
f5dd179bfa4a plan9: initial support for plan 9 from bell labs
Steven Stallion <sstallion@gmail.com>
parents:
diff changeset
34 A configuration section is available to customize runtime behavior. By
f5dd179bfa4a plan9: initial support for plan 9 from bell labs
Steven Stallion <sstallion@gmail.com>
parents:
diff changeset
35 default, these entries are::
f5dd179bfa4a plan9: initial support for plan 9 from bell labs
Steven Stallion <sstallion@gmail.com>
parents:
diff changeset
36
f5dd179bfa4a plan9: initial support for plan 9 from bell labs
Steven Stallion <sstallion@gmail.com>
parents:
diff changeset
37 [factotum]
16463
cef755f86d5c factotum: rename mount and path configuration entries
Steven Stallion <sstallion@gmail.com>
parents: 16383
diff changeset
38 executable = /bin/auth/factotum
cef755f86d5c factotum: rename mount and path configuration entries
Steven Stallion <sstallion@gmail.com>
parents: 16383
diff changeset
39 mountpoint = /mnt/factotum
16383
f5dd179bfa4a plan9: initial support for plan 9 from bell labs
Steven Stallion <sstallion@gmail.com>
parents:
diff changeset
40 service = hg
f5dd179bfa4a plan9: initial support for plan 9 from bell labs
Steven Stallion <sstallion@gmail.com>
parents:
diff changeset
41
16463
cef755f86d5c factotum: rename mount and path configuration entries
Steven Stallion <sstallion@gmail.com>
parents: 16383
diff changeset
42 The executable entry defines the full path to the factotum binary. The
cef755f86d5c factotum: rename mount and path configuration entries
Steven Stallion <sstallion@gmail.com>
parents: 16383
diff changeset
43 mountpoint entry defines the path to the factotum file service. Lastly, the
cef755f86d5c factotum: rename mount and path configuration entries
Steven Stallion <sstallion@gmail.com>
parents: 16383
diff changeset
44 service entry controls the service name used when reading keys.
16383
f5dd179bfa4a plan9: initial support for plan 9 from bell labs
Steven Stallion <sstallion@gmail.com>
parents:
diff changeset
45
f5dd179bfa4a plan9: initial support for plan 9 from bell labs
Steven Stallion <sstallion@gmail.com>
parents:
diff changeset
46 '''
f5dd179bfa4a plan9: initial support for plan 9 from bell labs
Steven Stallion <sstallion@gmail.com>
parents:
diff changeset
47
f5dd179bfa4a plan9: initial support for plan 9 from bell labs
Steven Stallion <sstallion@gmail.com>
parents:
diff changeset
48 from mercurial.i18n import _
f5dd179bfa4a plan9: initial support for plan 9 from bell labs
Steven Stallion <sstallion@gmail.com>
parents:
diff changeset
49 from mercurial.url import passwordmgr
18647
c1d23b4a66d5 factotum: fix urllib2 import so it no longer relies on a demandimport bug
Mads Kiilerich <mads@kiilerich.com>
parents: 16582
diff changeset
50 from mercurial import httpconnection, util
c1d23b4a66d5 factotum: fix urllib2 import so it no longer relies on a demandimport bug
Mads Kiilerich <mads@kiilerich.com>
parents: 16582
diff changeset
51 import os, urllib2
16383
f5dd179bfa4a plan9: initial support for plan 9 from bell labs
Steven Stallion <sstallion@gmail.com>
parents:
diff changeset
52
f5dd179bfa4a plan9: initial support for plan 9 from bell labs
Steven Stallion <sstallion@gmail.com>
parents:
diff changeset
53 ERRMAX = 128
f5dd179bfa4a plan9: initial support for plan 9 from bell labs
Steven Stallion <sstallion@gmail.com>
parents:
diff changeset
54
21228
be561a622100 factotum: initialize global variables to suppress pyflakes warning
Yuya Nishihara <yuya@tcha.org>
parents: 19614
diff changeset
55 _executable = _mountpoint = _service = None
be561a622100 factotum: initialize global variables to suppress pyflakes warning
Yuya Nishihara <yuya@tcha.org>
parents: 19614
diff changeset
56
16383
f5dd179bfa4a plan9: initial support for plan 9 from bell labs
Steven Stallion <sstallion@gmail.com>
parents:
diff changeset
57 def auth_getkey(self, params):
f5dd179bfa4a plan9: initial support for plan 9 from bell labs
Steven Stallion <sstallion@gmail.com>
parents:
diff changeset
58 if not self.ui.interactive():
f5dd179bfa4a plan9: initial support for plan 9 from bell labs
Steven Stallion <sstallion@gmail.com>
parents:
diff changeset
59 raise util.Abort(_('factotum not interactive'))
f5dd179bfa4a plan9: initial support for plan 9 from bell labs
Steven Stallion <sstallion@gmail.com>
parents:
diff changeset
60 if 'user=' not in params:
f5dd179bfa4a plan9: initial support for plan 9 from bell labs
Steven Stallion <sstallion@gmail.com>
parents:
diff changeset
61 params = '%s user?' % params
f5dd179bfa4a plan9: initial support for plan 9 from bell labs
Steven Stallion <sstallion@gmail.com>
parents:
diff changeset
62 params = '%s !password?' % params
16463
cef755f86d5c factotum: rename mount and path configuration entries
Steven Stallion <sstallion@gmail.com>
parents: 16383
diff changeset
63 os.system("%s -g '%s'" % (_executable, params))
16383
f5dd179bfa4a plan9: initial support for plan 9 from bell labs
Steven Stallion <sstallion@gmail.com>
parents:
diff changeset
64
f5dd179bfa4a plan9: initial support for plan 9 from bell labs
Steven Stallion <sstallion@gmail.com>
parents:
diff changeset
65 def auth_getuserpasswd(self, getkey, params):
f5dd179bfa4a plan9: initial support for plan 9 from bell labs
Steven Stallion <sstallion@gmail.com>
parents:
diff changeset
66 params = 'proto=pass %s' % params
f5dd179bfa4a plan9: initial support for plan 9 from bell labs
Steven Stallion <sstallion@gmail.com>
parents:
diff changeset
67 while True:
16463
cef755f86d5c factotum: rename mount and path configuration entries
Steven Stallion <sstallion@gmail.com>
parents: 16383
diff changeset
68 fd = os.open('%s/rpc' % _mountpoint, os.O_RDWR)
16383
f5dd179bfa4a plan9: initial support for plan 9 from bell labs
Steven Stallion <sstallion@gmail.com>
parents:
diff changeset
69 try:
25078
e8348f1cc228 factotum: use try/except/finally
Matt Mackall <mpm@selenic.com>
parents: 23393
diff changeset
70 os.write(fd, 'start %s' % params)
e8348f1cc228 factotum: use try/except/finally
Matt Mackall <mpm@selenic.com>
parents: 23393
diff changeset
71 l = os.read(fd, ERRMAX).split()
e8348f1cc228 factotum: use try/except/finally
Matt Mackall <mpm@selenic.com>
parents: 23393
diff changeset
72 if l[0] == 'ok':
e8348f1cc228 factotum: use try/except/finally
Matt Mackall <mpm@selenic.com>
parents: 23393
diff changeset
73 os.write(fd, 'read')
e8348f1cc228 factotum: use try/except/finally
Matt Mackall <mpm@selenic.com>
parents: 23393
diff changeset
74 status, user, passwd = os.read(fd, ERRMAX).split(None, 2)
e8348f1cc228 factotum: use try/except/finally
Matt Mackall <mpm@selenic.com>
parents: 23393
diff changeset
75 if status == 'ok':
e8348f1cc228 factotum: use try/except/finally
Matt Mackall <mpm@selenic.com>
parents: 23393
diff changeset
76 if passwd.startswith("'"):
e8348f1cc228 factotum: use try/except/finally
Matt Mackall <mpm@selenic.com>
parents: 23393
diff changeset
77 if passwd.endswith("'"):
e8348f1cc228 factotum: use try/except/finally
Matt Mackall <mpm@selenic.com>
parents: 23393
diff changeset
78 passwd = passwd[1:-1].replace("''", "'")
e8348f1cc228 factotum: use try/except/finally
Matt Mackall <mpm@selenic.com>
parents: 23393
diff changeset
79 else:
e8348f1cc228 factotum: use try/except/finally
Matt Mackall <mpm@selenic.com>
parents: 23393
diff changeset
80 raise util.Abort(_('malformed password string'))
e8348f1cc228 factotum: use try/except/finally
Matt Mackall <mpm@selenic.com>
parents: 23393
diff changeset
81 return (user, passwd)
e8348f1cc228 factotum: use try/except/finally
Matt Mackall <mpm@selenic.com>
parents: 23393
diff changeset
82 except (OSError, IOError):
e8348f1cc228 factotum: use try/except/finally
Matt Mackall <mpm@selenic.com>
parents: 23393
diff changeset
83 raise util.Abort(_('factotum not responding'))
16383
f5dd179bfa4a plan9: initial support for plan 9 from bell labs
Steven Stallion <sstallion@gmail.com>
parents:
diff changeset
84 finally:
f5dd179bfa4a plan9: initial support for plan 9 from bell labs
Steven Stallion <sstallion@gmail.com>
parents:
diff changeset
85 os.close(fd)
f5dd179bfa4a plan9: initial support for plan 9 from bell labs
Steven Stallion <sstallion@gmail.com>
parents:
diff changeset
86 getkey(self, params)
f5dd179bfa4a plan9: initial support for plan 9 from bell labs
Steven Stallion <sstallion@gmail.com>
parents:
diff changeset
87
f5dd179bfa4a plan9: initial support for plan 9 from bell labs
Steven Stallion <sstallion@gmail.com>
parents:
diff changeset
88 def monkeypatch_method(cls):
f5dd179bfa4a plan9: initial support for plan 9 from bell labs
Steven Stallion <sstallion@gmail.com>
parents:
diff changeset
89 def decorator(func):
f5dd179bfa4a plan9: initial support for plan 9 from bell labs
Steven Stallion <sstallion@gmail.com>
parents:
diff changeset
90 setattr(cls, func.__name__, func)
f5dd179bfa4a plan9: initial support for plan 9 from bell labs
Steven Stallion <sstallion@gmail.com>
parents:
diff changeset
91 return func
f5dd179bfa4a plan9: initial support for plan 9 from bell labs
Steven Stallion <sstallion@gmail.com>
parents:
diff changeset
92 return decorator
f5dd179bfa4a plan9: initial support for plan 9 from bell labs
Steven Stallion <sstallion@gmail.com>
parents:
diff changeset
93
f5dd179bfa4a plan9: initial support for plan 9 from bell labs
Steven Stallion <sstallion@gmail.com>
parents:
diff changeset
94 @monkeypatch_method(passwordmgr)
f5dd179bfa4a plan9: initial support for plan 9 from bell labs
Steven Stallion <sstallion@gmail.com>
parents:
diff changeset
95 def find_user_password(self, realm, authuri):
f5dd179bfa4a plan9: initial support for plan 9 from bell labs
Steven Stallion <sstallion@gmail.com>
parents:
diff changeset
96 user, passwd = urllib2.HTTPPasswordMgrWithDefaultRealm.find_user_password(
f5dd179bfa4a plan9: initial support for plan 9 from bell labs
Steven Stallion <sstallion@gmail.com>
parents:
diff changeset
97 self, realm, authuri)
f5dd179bfa4a plan9: initial support for plan 9 from bell labs
Steven Stallion <sstallion@gmail.com>
parents:
diff changeset
98 if user and passwd:
f5dd179bfa4a plan9: initial support for plan 9 from bell labs
Steven Stallion <sstallion@gmail.com>
parents:
diff changeset
99 self._writedebug(user, passwd)
f5dd179bfa4a plan9: initial support for plan 9 from bell labs
Steven Stallion <sstallion@gmail.com>
parents:
diff changeset
100 return (user, passwd)
f5dd179bfa4a plan9: initial support for plan 9 from bell labs
Steven Stallion <sstallion@gmail.com>
parents:
diff changeset
101
f5dd179bfa4a plan9: initial support for plan 9 from bell labs
Steven Stallion <sstallion@gmail.com>
parents:
diff changeset
102 prefix = ''
f5dd179bfa4a plan9: initial support for plan 9 from bell labs
Steven Stallion <sstallion@gmail.com>
parents:
diff changeset
103 res = httpconnection.readauthforuri(self.ui, authuri, user)
f5dd179bfa4a plan9: initial support for plan 9 from bell labs
Steven Stallion <sstallion@gmail.com>
parents:
diff changeset
104 if res:
f5dd179bfa4a plan9: initial support for plan 9 from bell labs
Steven Stallion <sstallion@gmail.com>
parents:
diff changeset
105 _, auth = res
f5dd179bfa4a plan9: initial support for plan 9 from bell labs
Steven Stallion <sstallion@gmail.com>
parents:
diff changeset
106 prefix = auth.get('prefix')
f5dd179bfa4a plan9: initial support for plan 9 from bell labs
Steven Stallion <sstallion@gmail.com>
parents:
diff changeset
107 user, passwd = auth.get('username'), auth.get('password')
f5dd179bfa4a plan9: initial support for plan 9 from bell labs
Steven Stallion <sstallion@gmail.com>
parents:
diff changeset
108 if not user or not passwd:
f5dd179bfa4a plan9: initial support for plan 9 from bell labs
Steven Stallion <sstallion@gmail.com>
parents:
diff changeset
109 if not prefix:
19614
1d50c69c1f0a factotum: clean up keychain for multiple hg repository authentication
Jeff Sickel <jas@corpus-callosum.com>
parents: 18647
diff changeset
110 prefix = realm.split(' ')[0].lower()
16383
f5dd179bfa4a plan9: initial support for plan 9 from bell labs
Steven Stallion <sstallion@gmail.com>
parents:
diff changeset
111 params = 'service=%s prefix=%s' % (_service, prefix)
f5dd179bfa4a plan9: initial support for plan 9 from bell labs
Steven Stallion <sstallion@gmail.com>
parents:
diff changeset
112 if user:
f5dd179bfa4a plan9: initial support for plan 9 from bell labs
Steven Stallion <sstallion@gmail.com>
parents:
diff changeset
113 params = '%s user=%s' % (params, user)
f5dd179bfa4a plan9: initial support for plan 9 from bell labs
Steven Stallion <sstallion@gmail.com>
parents:
diff changeset
114 user, passwd = auth_getuserpasswd(self, auth_getkey, params)
f5dd179bfa4a plan9: initial support for plan 9 from bell labs
Steven Stallion <sstallion@gmail.com>
parents:
diff changeset
115
f5dd179bfa4a plan9: initial support for plan 9 from bell labs
Steven Stallion <sstallion@gmail.com>
parents:
diff changeset
116 self.add_password(realm, authuri, user, passwd)
f5dd179bfa4a plan9: initial support for plan 9 from bell labs
Steven Stallion <sstallion@gmail.com>
parents:
diff changeset
117 self._writedebug(user, passwd)
f5dd179bfa4a plan9: initial support for plan 9 from bell labs
Steven Stallion <sstallion@gmail.com>
parents:
diff changeset
118 return (user, passwd)
f5dd179bfa4a plan9: initial support for plan 9 from bell labs
Steven Stallion <sstallion@gmail.com>
parents:
diff changeset
119
f5dd179bfa4a plan9: initial support for plan 9 from bell labs
Steven Stallion <sstallion@gmail.com>
parents:
diff changeset
120 def uisetup(ui):
16463
cef755f86d5c factotum: rename mount and path configuration entries
Steven Stallion <sstallion@gmail.com>
parents: 16383
diff changeset
121 global _executable
cef755f86d5c factotum: rename mount and path configuration entries
Steven Stallion <sstallion@gmail.com>
parents: 16383
diff changeset
122 _executable = ui.config('factotum', 'executable', '/bin/auth/factotum')
cef755f86d5c factotum: rename mount and path configuration entries
Steven Stallion <sstallion@gmail.com>
parents: 16383
diff changeset
123 global _mountpoint
cef755f86d5c factotum: rename mount and path configuration entries
Steven Stallion <sstallion@gmail.com>
parents: 16383
diff changeset
124 _mountpoint = ui.config('factotum', 'mountpoint', '/mnt/factotum')
16383
f5dd179bfa4a plan9: initial support for plan 9 from bell labs
Steven Stallion <sstallion@gmail.com>
parents:
diff changeset
125 global _service
f5dd179bfa4a plan9: initial support for plan 9 from bell labs
Steven Stallion <sstallion@gmail.com>
parents:
diff changeset
126 _service = ui.config('factotum', 'service', 'hg')