fluidattacks-core 2.2.3__tar.gz → 2.2.4__tar.gz
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.
- {fluidattacks_core-2.2.3 → fluidattacks_core-2.2.4}/PKG-INFO +1 -1
- fluidattacks_core-2.2.4/fluidattacks_core/git/remote.py +199 -0
- {fluidattacks_core-2.2.3 → fluidattacks_core-2.2.4}/pyproject.toml +1 -1
- fluidattacks_core-2.2.3/fluidattacks_core/git/remote.py +0 -54
- {fluidattacks_core-2.2.3 → fluidattacks_core-2.2.4}/README.md +0 -0
- {fluidattacks_core-2.2.3 → fluidattacks_core-2.2.4}/fluidattacks_core/__init__.py +0 -0
- {fluidattacks_core-2.2.3 → fluidattacks_core-2.2.4}/fluidattacks_core/authz/__init__.py +0 -0
- {fluidattacks_core-2.2.3 → fluidattacks_core-2.2.4}/fluidattacks_core/authz/py.typed +0 -0
- {fluidattacks_core-2.2.3 → fluidattacks_core-2.2.4}/fluidattacks_core/authz/types.py +0 -0
- {fluidattacks_core-2.2.3 → fluidattacks_core-2.2.4}/fluidattacks_core/git/__init__.py +0 -0
- {fluidattacks_core-2.2.3 → fluidattacks_core-2.2.4}/fluidattacks_core/git/classes.py +0 -0
- {fluidattacks_core-2.2.3 → fluidattacks_core-2.2.4}/fluidattacks_core/git/clone.py +0 -0
- {fluidattacks_core-2.2.3 → fluidattacks_core-2.2.4}/fluidattacks_core/git/codecommit_utils.py +0 -0
- {fluidattacks_core-2.2.3 → fluidattacks_core-2.2.4}/fluidattacks_core/git/delete_files.py +0 -0
- {fluidattacks_core-2.2.3 → fluidattacks_core-2.2.4}/fluidattacks_core/git/download_file.py +0 -0
- {fluidattacks_core-2.2.3 → fluidattacks_core-2.2.4}/fluidattacks_core/git/download_repo.py +0 -0
- {fluidattacks_core-2.2.3 → fluidattacks_core-2.2.4}/fluidattacks_core/git/https_utils.py +0 -0
- {fluidattacks_core-2.2.3 → fluidattacks_core-2.2.4}/fluidattacks_core/git/py.typed +0 -0
- {fluidattacks_core-2.2.3 → fluidattacks_core-2.2.4}/fluidattacks_core/git/ssh_utils.py +0 -0
- {fluidattacks_core-2.2.3 → fluidattacks_core-2.2.4}/fluidattacks_core/git/utils.py +0 -0
- {fluidattacks_core-2.2.3 → fluidattacks_core-2.2.4}/fluidattacks_core/git/warp.py +0 -0
- {fluidattacks_core-2.2.3 → fluidattacks_core-2.2.4}/fluidattacks_core/http/__init__.py +0 -0
- {fluidattacks_core-2.2.3 → fluidattacks_core-2.2.4}/fluidattacks_core/http/client.py +0 -0
- {fluidattacks_core-2.2.3 → fluidattacks_core-2.2.4}/fluidattacks_core/http/validations.py +0 -0
- {fluidattacks_core-2.2.3 → fluidattacks_core-2.2.4}/fluidattacks_core/py.typed +0 -0
|
@@ -0,0 +1,199 @@
|
|
|
1
|
+
import base64
|
|
2
|
+
import logging
|
|
3
|
+
from contextlib import suppress
|
|
4
|
+
|
|
5
|
+
import aiohttp
|
|
6
|
+
from urllib3.exceptions import LocationParseError
|
|
7
|
+
from urllib3.util import Url, parse_url
|
|
8
|
+
|
|
9
|
+
from ..http.client import request
|
|
10
|
+
from ..http.validations import HTTPValidationError
|
|
11
|
+
from .classes import InvalidParameter
|
|
12
|
+
from .codecommit_utils import call_codecommit_ls_remote
|
|
13
|
+
from .https_utils import call_https_ls_remote
|
|
14
|
+
from .ssh_utils import call_ssh_ls_remote
|
|
15
|
+
|
|
16
|
+
LOGGER = logging.getLogger(__name__)
|
|
17
|
+
|
|
18
|
+
|
|
19
|
+
def _format_redirected_url(
|
|
20
|
+
original_url: Url,
|
|
21
|
+
redirect_url: Url,
|
|
22
|
+
) -> str:
|
|
23
|
+
return (
|
|
24
|
+
redirect_url._replace(
|
|
25
|
+
query=None,
|
|
26
|
+
path=(redirect_url.path or "").removesuffix("info/refs"),
|
|
27
|
+
).url
|
|
28
|
+
if original_url.host == redirect_url.host
|
|
29
|
+
else original_url.url
|
|
30
|
+
)
|
|
31
|
+
|
|
32
|
+
|
|
33
|
+
async def get_redirected_url(
|
|
34
|
+
url: str,
|
|
35
|
+
user: str | None,
|
|
36
|
+
password: str | None,
|
|
37
|
+
token: str | None,
|
|
38
|
+
is_pat: bool,
|
|
39
|
+
) -> str:
|
|
40
|
+
if user is not None and password is not None:
|
|
41
|
+
with suppress(LocationParseError):
|
|
42
|
+
return await _get_redirected_url(
|
|
43
|
+
parse_url(url)._replace(auth=None).url,
|
|
44
|
+
authorization="Basic "
|
|
45
|
+
+ base64.b64encode(f"{user}:{password}".encode()).decode(),
|
|
46
|
+
)
|
|
47
|
+
return await _get_redirected_url(
|
|
48
|
+
url,
|
|
49
|
+
authorization="Basic "
|
|
50
|
+
+ base64.b64encode(f"{user}:{password}".encode()).decode(),
|
|
51
|
+
)
|
|
52
|
+
if token is not None and is_pat:
|
|
53
|
+
return await _get_redirected_url(
|
|
54
|
+
url,
|
|
55
|
+
authorization=(
|
|
56
|
+
"Basic "
|
|
57
|
+
+ base64.b64encode(f":{token}".encode()).decode()
|
|
58
|
+
),
|
|
59
|
+
)
|
|
60
|
+
if token is not None and not is_pat:
|
|
61
|
+
return await _get_redirected_url(url, authorization=f"Bearer {token}")
|
|
62
|
+
if url.startswith("http"):
|
|
63
|
+
return await _get_redirected_url(url)
|
|
64
|
+
raise InvalidParameter()
|
|
65
|
+
|
|
66
|
+
|
|
67
|
+
async def _get_redirected_url(
|
|
68
|
+
url: str,
|
|
69
|
+
authorization: str | None = None,
|
|
70
|
+
) -> str:
|
|
71
|
+
try:
|
|
72
|
+
return await _get_url(url, authorization=authorization)
|
|
73
|
+
except (
|
|
74
|
+
TimeoutError,
|
|
75
|
+
ValueError,
|
|
76
|
+
aiohttp.ClientError,
|
|
77
|
+
HTTPValidationError,
|
|
78
|
+
) as exc:
|
|
79
|
+
LOGGER.warning(
|
|
80
|
+
"Failed to get redirected-url",
|
|
81
|
+
extra={"extra": {"url": url, "exc": exc}},
|
|
82
|
+
)
|
|
83
|
+
return url
|
|
84
|
+
|
|
85
|
+
|
|
86
|
+
async def _get_url(
|
|
87
|
+
original_url: str,
|
|
88
|
+
*,
|
|
89
|
+
redirect_url: str = "",
|
|
90
|
+
max_retries: int = 5,
|
|
91
|
+
authorization: str | None = None,
|
|
92
|
+
) -> str:
|
|
93
|
+
try:
|
|
94
|
+
original = parse_url(original_url.removesuffix("/"))
|
|
95
|
+
url = (
|
|
96
|
+
parse_url(redirect_url.removesuffix("/"))
|
|
97
|
+
if redirect_url else original
|
|
98
|
+
)
|
|
99
|
+
except LocationParseError as exc:
|
|
100
|
+
raise HTTPValidationError(f"Invalid URL {redirect_url}") from exc
|
|
101
|
+
|
|
102
|
+
if max_retries < 1:
|
|
103
|
+
return _format_redirected_url(original, url)
|
|
104
|
+
|
|
105
|
+
# https://git-scm.com/book/en/v2/Git-Internals-Transfer-Protocols
|
|
106
|
+
url = (
|
|
107
|
+
url._replace(path=(url.path or "") + "/info/refs")
|
|
108
|
+
if not (url.path or "").endswith("info/refs")
|
|
109
|
+
else url
|
|
110
|
+
)
|
|
111
|
+
url = url._replace(query="service=git-upload-pack")
|
|
112
|
+
|
|
113
|
+
result = await request(
|
|
114
|
+
url.url,
|
|
115
|
+
method="GET",
|
|
116
|
+
headers={
|
|
117
|
+
"Host": url.host or "",
|
|
118
|
+
"Accept": "*/*",
|
|
119
|
+
"Accept-Encoding": "deflate, gzip",
|
|
120
|
+
"Pragma": "no-cache",
|
|
121
|
+
"Accept-Language": "*",
|
|
122
|
+
**({"Authorization": authorization} if authorization else {}),
|
|
123
|
+
},
|
|
124
|
+
)
|
|
125
|
+
if result.status == 200:
|
|
126
|
+
return _format_redirected_url(original, url)
|
|
127
|
+
if (
|
|
128
|
+
result.status > 300
|
|
129
|
+
and result.status < 400
|
|
130
|
+
and "Location" in result.headers
|
|
131
|
+
):
|
|
132
|
+
with suppress(LocationParseError):
|
|
133
|
+
_url = parse_url(result.headers["Location"])
|
|
134
|
+
return await _get_url(
|
|
135
|
+
original_url,
|
|
136
|
+
redirect_url=result.headers["Location"],
|
|
137
|
+
max_retries=max_retries - 1,
|
|
138
|
+
authorization=authorization if _url.host == url.host else None,
|
|
139
|
+
)
|
|
140
|
+
|
|
141
|
+
return await _get_url(
|
|
142
|
+
original_url,
|
|
143
|
+
redirect_url=result.headers["Location"],
|
|
144
|
+
max_retries=max_retries - 1,
|
|
145
|
+
)
|
|
146
|
+
|
|
147
|
+
return _format_redirected_url(original, url)
|
|
148
|
+
|
|
149
|
+
|
|
150
|
+
async def ls_remote(
|
|
151
|
+
repo_url: str,
|
|
152
|
+
repo_branch: str,
|
|
153
|
+
*,
|
|
154
|
+
credential_key: str | None = None,
|
|
155
|
+
user: str | None = None,
|
|
156
|
+
password: str | None = None,
|
|
157
|
+
token: str | None = None,
|
|
158
|
+
provider: str | None = None,
|
|
159
|
+
is_pat: bool = False,
|
|
160
|
+
arn: str | None = None,
|
|
161
|
+
org_external_id: str | None = None,
|
|
162
|
+
follow_redirects: bool = True,
|
|
163
|
+
) -> str | None:
|
|
164
|
+
last_commit: str | None = None
|
|
165
|
+
if credential_key is not None:
|
|
166
|
+
last_commit = await call_ssh_ls_remote(
|
|
167
|
+
repo_url,
|
|
168
|
+
credential_key,
|
|
169
|
+
repo_branch,
|
|
170
|
+
)
|
|
171
|
+
elif arn is not None and org_external_id is not None:
|
|
172
|
+
last_commit = await call_codecommit_ls_remote(
|
|
173
|
+
repo_url,
|
|
174
|
+
arn,
|
|
175
|
+
repo_branch,
|
|
176
|
+
org_external_id=org_external_id,
|
|
177
|
+
follow_redirects=follow_redirects,
|
|
178
|
+
)
|
|
179
|
+
else:
|
|
180
|
+
if not follow_redirects:
|
|
181
|
+
repo_url = await get_redirected_url(
|
|
182
|
+
repo_url,
|
|
183
|
+
user=user,
|
|
184
|
+
password=password,
|
|
185
|
+
token=token,
|
|
186
|
+
is_pat=is_pat,
|
|
187
|
+
)
|
|
188
|
+
last_commit = await call_https_ls_remote(
|
|
189
|
+
repo_url=repo_url,
|
|
190
|
+
user=user,
|
|
191
|
+
password=password,
|
|
192
|
+
token=token,
|
|
193
|
+
branch=repo_branch,
|
|
194
|
+
provider=provider,
|
|
195
|
+
is_pat=is_pat,
|
|
196
|
+
follow_redirects=follow_redirects,
|
|
197
|
+
)
|
|
198
|
+
|
|
199
|
+
return last_commit
|
|
@@ -1,54 +0,0 @@
|
|
|
1
|
-
from .codecommit_utils import (
|
|
2
|
-
call_codecommit_ls_remote,
|
|
3
|
-
)
|
|
4
|
-
from .https_utils import (
|
|
5
|
-
call_https_ls_remote,
|
|
6
|
-
)
|
|
7
|
-
from .ssh_utils import (
|
|
8
|
-
call_ssh_ls_remote,
|
|
9
|
-
)
|
|
10
|
-
import logging
|
|
11
|
-
|
|
12
|
-
LOGGER = logging.getLogger(__name__)
|
|
13
|
-
|
|
14
|
-
|
|
15
|
-
async def ls_remote(
|
|
16
|
-
repo_url: str,
|
|
17
|
-
repo_branch: str,
|
|
18
|
-
*,
|
|
19
|
-
credential_key: str | None = None,
|
|
20
|
-
user: str | None = None,
|
|
21
|
-
password: str | None = None,
|
|
22
|
-
token: str | None = None,
|
|
23
|
-
provider: str | None = None,
|
|
24
|
-
is_pat: bool = False,
|
|
25
|
-
arn: str | None = None,
|
|
26
|
-
org_external_id: str | None = None,
|
|
27
|
-
follow_redirects: bool = True,
|
|
28
|
-
) -> str | None:
|
|
29
|
-
last_commit: str | None = None
|
|
30
|
-
if credential_key is not None:
|
|
31
|
-
last_commit = await call_ssh_ls_remote(
|
|
32
|
-
repo_url, credential_key, repo_branch
|
|
33
|
-
)
|
|
34
|
-
elif arn is not None and org_external_id is not None:
|
|
35
|
-
last_commit = await call_codecommit_ls_remote(
|
|
36
|
-
repo_url,
|
|
37
|
-
arn,
|
|
38
|
-
repo_branch,
|
|
39
|
-
org_external_id=org_external_id,
|
|
40
|
-
follow_redirects=follow_redirects,
|
|
41
|
-
)
|
|
42
|
-
else:
|
|
43
|
-
last_commit = await call_https_ls_remote(
|
|
44
|
-
repo_url=repo_url,
|
|
45
|
-
user=user,
|
|
46
|
-
password=password,
|
|
47
|
-
token=token,
|
|
48
|
-
branch=repo_branch,
|
|
49
|
-
provider=provider,
|
|
50
|
-
is_pat=is_pat,
|
|
51
|
-
follow_redirects=follow_redirects,
|
|
52
|
-
)
|
|
53
|
-
|
|
54
|
-
return last_commit
|
|
File without changes
|
|
File without changes
|
|
File without changes
|
|
File without changes
|
|
File without changes
|
|
File without changes
|
|
File without changes
|
|
File without changes
|
{fluidattacks_core-2.2.3 → fluidattacks_core-2.2.4}/fluidattacks_core/git/codecommit_utils.py
RENAMED
|
File without changes
|
|
File without changes
|
|
File without changes
|
|
File without changes
|
|
File without changes
|
|
File without changes
|
|
File without changes
|
|
File without changes
|
|
File without changes
|
|
File without changes
|
|
File without changes
|
|
File without changes
|
|
File without changes
|