scmrepo 3.3.10__py3-none-any.whl → 3.3.11__py3-none-any.whl
This diff represents the content of publicly available package versions that have been released to one of the supported registries. The information contained in this diff is provided for informational purposes only and reflects changes between package versions as they appear in their respective public registries.
- scmrepo/git/backend/dulwich/asyncssh_vendor.py +19 -65
- scmrepo/git/backend/pygit2/__init__.py +3 -1
- scmrepo/git/backend/pygit2/callbacks.py +2 -0
- scmrepo/git/objects.py +1 -1
- {scmrepo-3.3.10.dist-info → scmrepo-3.3.11.dist-info}/METADATA +4 -3
- {scmrepo-3.3.10.dist-info → scmrepo-3.3.11.dist-info}/RECORD +9 -9
- {scmrepo-3.3.10.dist-info → scmrepo-3.3.11.dist-info}/WHEEL +1 -1
- {scmrepo-3.3.10.dist-info → scmrepo-3.3.11.dist-info/licenses}/LICENSE +0 -0
- {scmrepo-3.3.10.dist-info → scmrepo-3.3.11.dist-info}/top_level.txt +0 -0
|
@@ -2,7 +2,7 @@
|
|
|
2
2
|
|
|
3
3
|
import asyncio
|
|
4
4
|
import os
|
|
5
|
-
from collections.abc import Coroutine, Iterator
|
|
5
|
+
from collections.abc import Coroutine, Iterator
|
|
6
6
|
from typing import (
|
|
7
7
|
TYPE_CHECKING,
|
|
8
8
|
Any,
|
|
@@ -18,6 +18,7 @@ from scmrepo.asyn import BaseAsyncObject, sync_wrapper
|
|
|
18
18
|
from scmrepo.exceptions import AuthError
|
|
19
19
|
|
|
20
20
|
if TYPE_CHECKING:
|
|
21
|
+
from collections.abc import Sequence
|
|
21
22
|
from pathlib import Path
|
|
22
23
|
|
|
23
24
|
from asyncssh.auth import KbdIntPrompts, KbdIntResponse
|
|
@@ -40,6 +41,12 @@ async def _read_all(read: Callable[[int], Coroutine], n: Optional[int] = None) -
|
|
|
40
41
|
return b"".join(result)
|
|
41
42
|
|
|
42
43
|
|
|
44
|
+
async def _getpass(*args, **kwargs) -> str:
|
|
45
|
+
from getpass import getpass
|
|
46
|
+
|
|
47
|
+
return await asyncio.to_thread(getpass, *args, **kwargs)
|
|
48
|
+
|
|
49
|
+
|
|
43
50
|
class _StderrWrapper:
|
|
44
51
|
def __init__(self, stderr: "SSHReader", loop: asyncio.AbstractEventLoop) -> None:
|
|
45
52
|
self.stderr = stderr
|
|
@@ -97,45 +104,6 @@ class AsyncSSHWrapper(BaseAsyncObject):
|
|
|
97
104
|
close = sync_wrapper(_close)
|
|
98
105
|
|
|
99
106
|
|
|
100
|
-
# NOTE: Github's SSH server does not strictly comply with the SSH protocol.
|
|
101
|
-
# When validating a public key using the rsa-sha2-256 or rsa-sha2-512
|
|
102
|
-
# signature algorithms, RFC4252 + RFC8332 state that the server should respond
|
|
103
|
-
# with the same algorithm in SSH_MSG_USERAUTH_PK_OK. Github's server always
|
|
104
|
-
# returns "ssh-rsa" rather than the correct sha2 algorithm name (likely for
|
|
105
|
-
# backwards compatibility with old SSH client reasons). This behavior causes
|
|
106
|
-
# asyncssh to fail with a key-mismatch error (since asyncssh expects the server
|
|
107
|
-
# to behave properly).
|
|
108
|
-
#
|
|
109
|
-
# See also:
|
|
110
|
-
# https://www.ietf.org/rfc/rfc4252.txt
|
|
111
|
-
# https://www.ietf.org/rfc/rfc8332.txt
|
|
112
|
-
def _process_public_key_ok_gh(self, _pkttype, _pktid, packet):
|
|
113
|
-
from asyncssh.misc import ProtocolError
|
|
114
|
-
|
|
115
|
-
algorithm = packet.get_string()
|
|
116
|
-
key_data = packet.get_string()
|
|
117
|
-
packet.check_end()
|
|
118
|
-
|
|
119
|
-
# pylint: disable=protected-access
|
|
120
|
-
if (
|
|
121
|
-
(
|
|
122
|
-
algorithm == b"ssh-rsa"
|
|
123
|
-
and self._keypair.algorithm
|
|
124
|
-
not in (
|
|
125
|
-
b"ssh-rsa",
|
|
126
|
-
b"rsa-sha2-256",
|
|
127
|
-
b"rsa-sha2-512",
|
|
128
|
-
)
|
|
129
|
-
)
|
|
130
|
-
or (algorithm not in (b"ssh-rsa", self._keypair.algorithm))
|
|
131
|
-
or key_data != self._keypair.public_data
|
|
132
|
-
):
|
|
133
|
-
raise ProtocolError("Key mismatch")
|
|
134
|
-
|
|
135
|
-
self.create_task(self._send_signed_request())
|
|
136
|
-
return True
|
|
137
|
-
|
|
138
|
-
|
|
139
107
|
class InteractiveSSHClient(SSHClient):
|
|
140
108
|
_conn: Optional["SSHClientConnection"] = None
|
|
141
109
|
_keys_to_try: Optional[list["FilePath"]] = None
|
|
@@ -171,7 +139,7 @@ class InteractiveSSHClient(SSHClient):
|
|
|
171
139
|
self._keys_to_try = []
|
|
172
140
|
options = self._conn._options # pylint: disable=protected-access
|
|
173
141
|
config = options.config
|
|
174
|
-
client_keys = cast(Sequence[
|
|
142
|
+
client_keys = cast("Sequence[FilePath]", config.get("IdentityFile", ()))
|
|
175
143
|
if not client_keys:
|
|
176
144
|
client_keys = [
|
|
177
145
|
os.path.expanduser(os.path.join("~", ".ssh", path))
|
|
@@ -202,8 +170,6 @@ class InteractiveSSHClient(SSHClient):
|
|
|
202
170
|
return None
|
|
203
171
|
|
|
204
172
|
async def _read_private_key_interactive(self, path: "FilePath") -> "SSHKey":
|
|
205
|
-
from getpass import getpass
|
|
206
|
-
|
|
207
173
|
from asyncssh.public_key import (
|
|
208
174
|
KeyEncryptionError,
|
|
209
175
|
KeyImportError,
|
|
@@ -215,11 +181,8 @@ class InteractiveSSHClient(SSHClient):
|
|
|
215
181
|
if passphrase:
|
|
216
182
|
return read_private_key(path, passphrase=passphrase)
|
|
217
183
|
|
|
218
|
-
loop = asyncio.get_running_loop()
|
|
219
184
|
for _ in range(3):
|
|
220
|
-
passphrase = await
|
|
221
|
-
None, getpass, f"Enter passphrase for key '{path}': "
|
|
222
|
-
)
|
|
185
|
+
passphrase = await _getpass(f"Enter passphrase for key {path!r}: ")
|
|
223
186
|
if passphrase:
|
|
224
187
|
try:
|
|
225
188
|
key = read_private_key(path, passphrase=passphrase)
|
|
@@ -239,23 +202,20 @@ class InteractiveSSHClient(SSHClient):
|
|
|
239
202
|
lang: str,
|
|
240
203
|
prompts: "KbdIntPrompts",
|
|
241
204
|
) -> Optional["KbdIntResponse"]:
|
|
242
|
-
from getpass import getpass
|
|
243
|
-
|
|
244
205
|
if os.environ.get("GIT_TERMINAL_PROMPT") == "0":
|
|
245
206
|
return None
|
|
246
207
|
|
|
247
|
-
def _getpass(prompt: str) -> str:
|
|
248
|
-
return getpass(prompt=prompt).rstrip()
|
|
249
|
-
|
|
250
208
|
if instructions:
|
|
251
209
|
pass
|
|
252
|
-
|
|
253
|
-
|
|
254
|
-
|
|
255
|
-
|
|
256
|
-
)
|
|
257
|
-
|
|
258
|
-
|
|
210
|
+
|
|
211
|
+
response: list[str] = []
|
|
212
|
+
for prompt, _echo in prompts:
|
|
213
|
+
p = await _getpass(f"({name}) {prompt}" if name else prompt)
|
|
214
|
+
response.append(p.rstrip())
|
|
215
|
+
return response
|
|
216
|
+
|
|
217
|
+
async def password_auth_requested(self) -> str:
|
|
218
|
+
return await _getpass()
|
|
259
219
|
|
|
260
220
|
|
|
261
221
|
class AsyncSSHVendor(BaseAsyncObject, SSHVendor):
|
|
@@ -286,12 +246,6 @@ class AsyncSSHVendor(BaseAsyncObject, SSHVendor):
|
|
|
286
246
|
key_filename: Optional path to private keyfile
|
|
287
247
|
"""
|
|
288
248
|
import asyncssh
|
|
289
|
-
from asyncssh.auth import MSG_USERAUTH_PK_OK, _ClientPublicKeyAuth
|
|
290
|
-
|
|
291
|
-
# pylint: disable=protected-access
|
|
292
|
-
_ClientPublicKeyAuth._packet_handlers[MSG_USERAUTH_PK_OK] = (
|
|
293
|
-
_process_public_key_ok_gh
|
|
294
|
-
)
|
|
295
249
|
|
|
296
250
|
try:
|
|
297
251
|
conn = await asyncssh.connect(
|
|
@@ -289,7 +289,9 @@ class Pygit2Backend(BaseGitBackend): # pylint:disable=abstract-method
|
|
|
289
289
|
bare = True
|
|
290
290
|
try:
|
|
291
291
|
with RemoteCallbacks(progress=progress) as cb:
|
|
292
|
-
repo = clone_repository(
|
|
292
|
+
repo = clone_repository(
|
|
293
|
+
url, os.fspath(to_path), callbacks=cb, bare=bare
|
|
294
|
+
)
|
|
293
295
|
if mirror:
|
|
294
296
|
cls._set_mirror(repo, progress=progress)
|
|
295
297
|
except GitError as exc:
|
|
@@ -66,6 +66,8 @@ class RemoteCallbacks(_RemoteCallbacks, AbstractContextManager):
|
|
|
66
66
|
else:
|
|
67
67
|
creds = Credential(username=username_from_url, url=url).fill()
|
|
68
68
|
self._store_credentials = creds
|
|
69
|
+
assert creds.username is not None
|
|
70
|
+
assert creds.password is not None
|
|
69
71
|
return UserPass(creds.username, creds.password)
|
|
70
72
|
except CredentialNotFoundError:
|
|
71
73
|
pass
|
scmrepo/git/objects.py
CHANGED
|
@@ -1,6 +1,6 @@
|
|
|
1
|
-
Metadata-Version: 2.
|
|
1
|
+
Metadata-Version: 2.4
|
|
2
2
|
Name: scmrepo
|
|
3
|
-
Version: 3.3.
|
|
3
|
+
Version: 3.3.11
|
|
4
4
|
Summary: scmrepo
|
|
5
5
|
Author-email: Iterative <support@dvc.org>
|
|
6
6
|
License: Apache-2.0
|
|
@@ -38,12 +38,13 @@ Requires-Dist: pytest-sugar; extra == "tests"
|
|
|
38
38
|
Requires-Dist: pytest-test-utils<0.2,>=0.1.0; extra == "tests"
|
|
39
39
|
Requires-Dist: proxy.py; extra == "tests"
|
|
40
40
|
Provides-Extra: dev
|
|
41
|
-
Requires-Dist: mypy==1.
|
|
41
|
+
Requires-Dist: mypy==1.15.0; extra == "dev"
|
|
42
42
|
Requires-Dist: scmrepo[tests]; extra == "dev"
|
|
43
43
|
Requires-Dist: types-certifi; extra == "dev"
|
|
44
44
|
Requires-Dist: types-mock; extra == "dev"
|
|
45
45
|
Requires-Dist: types-paramiko; extra == "dev"
|
|
46
46
|
Requires-Dist: types-tqdm; extra == "dev"
|
|
47
|
+
Dynamic: license-file
|
|
47
48
|
|
|
48
49
|
scmrepo
|
|
49
50
|
=======
|
|
@@ -11,16 +11,16 @@ scmrepo/utils.py,sha256=_F3rVvPhES-A2JxLGob0RV8BOnHzxbA9aDPClA7_V8M,1512
|
|
|
11
11
|
scmrepo/git/__init__.py,sha256=elQErQSqekg-XWfxjNmEV0X00xtvy0LDFvy9nmv71Ls,17187
|
|
12
12
|
scmrepo/git/config.py,sha256=0t0OBmJ9SIa5tf22QdcGzhZfdMzzppvEmceUDg8ZPyE,943
|
|
13
13
|
scmrepo/git/credentials.py,sha256=tn8TlyCJUz8HOF7eL6F5Yj4n9vREsFwXrjLU1isi13s,22312
|
|
14
|
-
scmrepo/git/objects.py,sha256=
|
|
14
|
+
scmrepo/git/objects.py,sha256=qx8zAHZIrr0SDbZGD9wVShlMZK57nef8stIeRVqYdCU,4676
|
|
15
15
|
scmrepo/git/stash.py,sha256=wKWnYj_xpdT_3pvHiXtE7_I_By4S-Zbxf4Lv-ZY2sxI,2785
|
|
16
16
|
scmrepo/git/backend/__init__.py,sha256=47DEQpj8HBSa-_TImW-5JCeuQeRkm5NMpJWZG3hSuFU,0
|
|
17
17
|
scmrepo/git/backend/base.py,sha256=nVMkUIeSVu-ZLCd2QPxMfTgrjnTOejM1UET9R7qKJRc,13560
|
|
18
18
|
scmrepo/git/backend/gitpython.py,sha256=myfZY2x27DbDvIBUXzDjswXEViR5MKH0qgowwzcn7aY,25340
|
|
19
19
|
scmrepo/git/backend/dulwich/__init__.py,sha256=7UJJyEPqgc2tfPs1WN_XdvRkMsGyFA1HVgTf7mrgLNE,35098
|
|
20
|
-
scmrepo/git/backend/dulwich/asyncssh_vendor.py,sha256=
|
|
20
|
+
scmrepo/git/backend/dulwich/asyncssh_vendor.py,sha256=E3AyXok4S4FwsG9cMdswklf1bYRMmcmQM7Unri2fSVo,9882
|
|
21
21
|
scmrepo/git/backend/dulwich/client.py,sha256=XjNBfOp0L8M3iPpqcX_4bmXsO7hwrkyqg5wMbZULD-I,2358
|
|
22
|
-
scmrepo/git/backend/pygit2/__init__.py,sha256=
|
|
23
|
-
scmrepo/git/backend/pygit2/callbacks.py,sha256=
|
|
22
|
+
scmrepo/git/backend/pygit2/__init__.py,sha256=7meRePoB_bUx0UY2wPm2nxI4DFabn5nenVP8Cyf7AZc,36366
|
|
23
|
+
scmrepo/git/backend/pygit2/callbacks.py,sha256=Mk-2e5dfJPNLsczRiK4rTnjHd5ZyonmegdwiFwM9Anc,2849
|
|
24
24
|
scmrepo/git/backend/pygit2/filter.py,sha256=8Ibn_2oXM32YRpyovxGKYhtPZLUYTBLDi9--bScOP00,2198
|
|
25
25
|
scmrepo/git/lfs/__init__.py,sha256=at5blRIKnKpg_g5dLRDsGWBFi6SbucRlF_DX6aAkGtE,257
|
|
26
26
|
scmrepo/git/lfs/client.py,sha256=64u5lJijUASNJ4H_Eg7aEb8j3z3eluuNUWGnYvfNnvo,10187
|
|
@@ -31,8 +31,8 @@ scmrepo/git/lfs/pointer.py,sha256=BcVbtjoOUG9cEzyJSJDeweqehGZvq43P6NNLDYUGYEI,31
|
|
|
31
31
|
scmrepo/git/lfs/progress.py,sha256=AcWvygDG0ee__Jec5BlRr58F-lAj3d4Z_j7JbW3OUcI,4733
|
|
32
32
|
scmrepo/git/lfs/smudge.py,sha256=1O_fznptWo4CKXqcJgUoWP6cgWWhvGAZ3d87kasG3cQ,1610
|
|
33
33
|
scmrepo/git/lfs/storage.py,sha256=nx_HvHHC1sf15Qgbsj8jEOkdHXkZ8VUEh8QBtt9sLwI,2348
|
|
34
|
-
scmrepo-3.3.
|
|
35
|
-
scmrepo-3.3.
|
|
36
|
-
scmrepo-3.3.
|
|
37
|
-
scmrepo-3.3.
|
|
38
|
-
scmrepo-3.3.
|
|
34
|
+
scmrepo-3.3.11.dist-info/licenses/LICENSE,sha256=-1jhbPjoIVHR0cEgahL4Zhct75Ff4MzYCR_jOaJDPq8,11340
|
|
35
|
+
scmrepo-3.3.11.dist-info/METADATA,sha256=2edjOxEKBOCfYNiG_cFDExx5Q8P1eXQfrMTAtSlOzZ8,4815
|
|
36
|
+
scmrepo-3.3.11.dist-info/WHEEL,sha256=ooBFpIzZCPdw3uqIQsOo4qqbA4ZRPxHnOH7peeONza0,91
|
|
37
|
+
scmrepo-3.3.11.dist-info/top_level.txt,sha256=iunjod6w3GogERsAYfLRupnANXnqzX3jbIfbeIQG5cc,8
|
|
38
|
+
scmrepo-3.3.11.dist-info/RECORD,,
|
|
File without changes
|
|
File without changes
|