Chromium Code Reviews
chromiumcodereview-hr@appspot.gserviceaccount.com (chromiumcodereview-hr) | Please choose your nickname with Settings | Help | Chromium Project | Gerrit Changes | Sign out
(289)

Side by Side Diff: Tools/Scripts/webkitpy/common/net/credentials.py

Issue 27055003: Remove a bunch of unused webkitpy code from tool/, common/checkout/ and common/config/ (Closed) Base URL: svn://svn.chromium.org/blink/trunk
Patch Set: Created 7 years, 2 months ago
Use n/p to move between diff chunks; N/P to move between comments. Draft comments are only viewable by you.
Jump to:
View unified diff | Download patch | Annotate | Revision Log
OLDNEW
(Empty)
1 # Copyright (c) 2009 Google Inc. All rights reserved.
2 # Copyright (c) 2009 Apple Inc. All rights reserved.
3 #
4 # Redistribution and use in source and binary forms, with or without
5 # modification, are permitted provided that the following conditions are
6 # met:
7 #
8 # * Redistributions of source code must retain the above copyright
9 # notice, this list of conditions and the following disclaimer.
10 # * Redistributions in binary form must reproduce the above
11 # copyright notice, this list of conditions and the following disclaimer
12 # in the documentation and/or other materials provided with the
13 # distribution.
14 # * Neither the name of Google Inc. nor the names of its
15 # contributors may be used to endorse or promote products derived from
16 # this software without specific prior written permission.
17 #
18 # THIS SOFTWARE IS PROVIDED BY THE COPYRIGHT HOLDERS AND CONTRIBUTORS
19 # "AS IS" AND ANY EXPRESS OR IMPLIED WARRANTIES, INCLUDING, BUT NOT
20 # LIMITED TO, THE IMPLIED WARRANTIES OF MERCHANTABILITY AND FITNESS FOR
21 # A PARTICULAR PURPOSE ARE DISCLAIMED. IN NO EVENT SHALL THE COPYRIGHT
22 # OWNER OR CONTRIBUTORS BE LIABLE FOR ANY DIRECT, INDIRECT, INCIDENTAL,
23 # SPECIAL, EXEMPLARY, OR CONSEQUENTIAL DAMAGES (INCLUDING, BUT NOT
24 # LIMITED TO, PROCUREMENT OF SUBSTITUTE GOODS OR SERVICES; LOSS OF USE,
25 # DATA, OR PROFITS; OR BUSINESS INTERRUPTION) HOWEVER CAUSED AND ON ANY
26 # THEORY OF LIABILITY, WHETHER IN CONTRACT, STRICT LIABILITY, OR TORT
27 # (INCLUDING NEGLIGENCE OR OTHERWISE) ARISING IN ANY WAY OUT OF THE USE
28 # OF THIS SOFTWARE, EVEN IF ADVISED OF THE POSSIBILITY OF SUCH DAMAGE.
29 #
30 # Python module for reading stored web credentials from the OS.
31
32 import logging
33 import os
34 import platform
35 import re
36
37 from webkitpy.common.checkout.scm import Git
38 from webkitpy.common.system.executive import Executive, ScriptError
39 from webkitpy.common.system.user import User
40
41 try:
42 # Use keyring, a cross platform keyring interface, as a fallback:
43 # http://pypi.python.org/pypi/keyring
44 import keyring
45 except ImportError:
46 keyring = None
47
48 _log = logging.getLogger(__name__)
49
50
51 class Credentials(object):
52 _environ_prefix = "webkit_bugzilla_"
53
54 def __init__(self, host, git_prefix=None, executive=None, cwd=os.getcwd(),
55 keyring=keyring):
56 self.host = host
57 self.git_prefix = "%s." % git_prefix if git_prefix else ""
58 self.executive = executive or Executive()
59 self.cwd = cwd
60 self._keyring = keyring
61
62 def _credentials_from_git(self):
63 try:
64 if not Git.in_working_directory(self.cwd):
65 return (None, None)
66 return (Git.read_git_config(self.git_prefix + "username"),
67 Git.read_git_config(self.git_prefix + "password"))
68 except OSError, e:
69 # Catch and ignore OSError exceptions such as "no such file
70 # or directory" (OSError errno 2), which imply that the Git
71 # command cannot be found/is not installed.
72 pass
73 return (None, None)
74
75 def _keychain_value_with_label(self, label, source_text):
76 match = re.search("%s\"(?P<value>.+)\"" % label,
77 source_text,
78 re.MULTILINE)
79 if match:
80 return match.group('value')
81
82 def _is_mac_os_x(self):
83 return platform.mac_ver()[0]
84
85 def _parse_security_tool_output(self, security_output):
86 username = self._keychain_value_with_label("^\s*\"acct\"<blob>=",
87 security_output)
88 password = self._keychain_value_with_label("^password: ",
89 security_output)
90 return [username, password]
91
92 def _run_security_tool(self, username=None):
93 security_command = [
94 "/usr/bin/security",
95 "find-internet-password",
96 "-g",
97 "-s",
98 self.host,
99 ]
100 if username:
101 security_command += ["-a", username]
102
103 _log.info("Reading Keychain for %s account and password. "
104 "Click \"Allow\" to continue..." % self.host)
105 try:
106 return self.executive.run_command(security_command)
107 except ScriptError:
108 # Failed to either find a keychain entry or somekind of OS-related
109 # error occured (for instance, couldn't find the /usr/sbin/security
110 # command).
111 _log.error("Could not find a keychain entry for %s." % self.host)
112 return None
113
114 def _credentials_from_keychain(self, username=None):
115 if not self._is_mac_os_x():
116 return [username, None]
117
118 security_output = self._run_security_tool(username)
119 if security_output:
120 return self._parse_security_tool_output(security_output)
121 else:
122 return [None, None]
123
124 def _read_environ(self, key):
125 environ_key = self._environ_prefix + key
126 return os.environ.get(environ_key.upper())
127
128 def _credentials_from_environment(self):
129 return (self._read_environ("username"), self._read_environ("password"))
130
131 def _offer_to_store_credentials_in_keyring(self, username, password):
132 if not self._keyring:
133 return
134 if not User().confirm("Store password in system keyring?", User.DEFAULT_ NO):
135 return
136 try:
137 self._keyring.set_password(self.host, username, password)
138 except:
139 pass
140
141 def read_credentials(self, user=User):
142 username, password = self._credentials_from_environment()
143 # FIXME: We don't currently support pulling the username from one
144 # source and the password from a separate source.
145 if not username or not password:
146 username, password = self._credentials_from_git()
147 if not username or not password:
148 username, password = self._credentials_from_keychain(username)
149
150 if not username:
151 username = user.prompt("%s login: " % self.host)
152
153 if username and not password and self._keyring:
154 try:
155 password = self._keyring.get_password(self.host, username)
156 except:
157 pass
158
159 if not password:
160 password = user.prompt_password("%s password for %s: " % (self.host, username))
161 self._offer_to_store_credentials_in_keyring(username, password)
162
163 return (username, password)
OLDNEW
« no previous file with comments | « Tools/Scripts/webkitpy/common/host_mock.py ('k') | Tools/Scripts/webkitpy/common/net/credentials_unittest.py » ('j') | no next file with comments »

Powered by Google App Engine
This is Rietveld 408576698