oauth2-cli-auth 1.6.1__tar.gz → 2.0.0__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.
- {oauth2_cli_auth-1.6.1 → oauth2_cli_auth-2.0.0}/PKG-INFO +2 -3
- {oauth2_cli_auth-1.6.1 → oauth2_cli_auth-2.0.0}/oauth2_cli_auth/__init__.py +1 -1
- oauth2_cli_auth-2.0.0/oauth2_cli_auth/__version__.py +1 -0
- {oauth2_cli_auth-1.6.1 → oauth2_cli_auth-2.0.0}/oauth2_cli_auth/_urllib_util.py +2 -1
- {oauth2_cli_auth-1.6.1 → oauth2_cli_auth-2.0.0}/oauth2_cli_auth/code_grant.py +34 -3
- {oauth2_cli_auth-1.6.1 → oauth2_cli_auth-2.0.0}/oauth2_cli_auth/http_server.py +2 -2
- {oauth2_cli_auth-1.6.1 → oauth2_cli_auth-2.0.0}/pyproject.toml +3 -3
- oauth2_cli_auth-1.6.1/oauth2_cli_auth/__version__.py +0 -1
- {oauth2_cli_auth-1.6.1 → oauth2_cli_auth-2.0.0}/LICENSE +0 -0
- {oauth2_cli_auth-1.6.1 → oauth2_cli_auth-2.0.0}/README.md +0 -0
- {oauth2_cli_auth-1.6.1 → oauth2_cli_auth-2.0.0}/oauth2_cli_auth/_timeout.py +0 -0
- {oauth2_cli_auth-1.6.1 → oauth2_cli_auth-2.0.0}/oauth2_cli_auth/conftest.py +0 -0
- {oauth2_cli_auth-1.6.1 → oauth2_cli_auth-2.0.0}/oauth2_cli_auth/simplified_flow.py +0 -0
|
@@ -1,11 +1,11 @@
|
|
|
1
1
|
Metadata-Version: 2.3
|
|
2
2
|
Name: oauth2-cli-auth
|
|
3
|
-
Version:
|
|
3
|
+
Version: 2.0.0
|
|
4
4
|
Summary: Authenticate against OAuth2 Provider in Python CLIs
|
|
5
5
|
License: MIT
|
|
6
6
|
Author: Timo Reymann
|
|
7
7
|
Author-email: mail@timo-reymann.de
|
|
8
|
-
Requires-Python: >=3.
|
|
8
|
+
Requires-Python: >=3.10
|
|
9
9
|
Classifier: Development Status :: 5 - Production/Stable
|
|
10
10
|
Classifier: Environment :: Console
|
|
11
11
|
Classifier: Environment :: MacOS X
|
|
@@ -15,7 +15,6 @@ Classifier: License :: OSI Approved :: MIT License
|
|
|
15
15
|
Classifier: Operating System :: POSIX
|
|
16
16
|
Classifier: Operating System :: Unix
|
|
17
17
|
Classifier: Programming Language :: Python :: 3
|
|
18
|
-
Classifier: Programming Language :: Python :: 3.9
|
|
19
18
|
Classifier: Programming Language :: Python :: 3.10
|
|
20
19
|
Classifier: Programming Language :: Python :: 3.11
|
|
21
20
|
Classifier: Programming Language :: Python :: 3.12
|
|
@@ -3,5 +3,5 @@ Authenticate against OAuth2 Provider in Python CLIs
|
|
|
3
3
|
"""
|
|
4
4
|
from oauth2_cli_auth.__version__ import __version__
|
|
5
5
|
from oauth2_cli_auth.http_server import OAuthCallbackHttpServer
|
|
6
|
-
from oauth2_cli_auth.code_grant import OAuth2ClientInfo, exchange_code_for_access_token, get_auth_url, open_browser, load_oidc_config
|
|
6
|
+
from oauth2_cli_auth.code_grant import OAuth2ClientInfo, refresh_access_token, exchange_code_for_access_token, exchange_code_for_response, get_auth_url, open_browser, load_oidc_config
|
|
7
7
|
from oauth2_cli_auth.simplified_flow import get_access_token_with_browser_open
|
|
@@ -0,0 +1 @@
|
|
|
1
|
+
__version__ = "2.0.0"
|
|
@@ -2,6 +2,7 @@ import json
|
|
|
2
2
|
import time
|
|
3
3
|
import urllib
|
|
4
4
|
from urllib.error import URLError
|
|
5
|
+
from typing import Union
|
|
5
6
|
|
|
6
7
|
|
|
7
8
|
def _urlopen_with_backoff(url, max_retries=3, base_delay=1, timeout=15):
|
|
@@ -19,7 +20,7 @@ def _urlopen_with_backoff(url, max_retries=3, base_delay=1, timeout=15):
|
|
|
19
20
|
raise URLError(f"Failed to open URL after {max_retries} retries")
|
|
20
21
|
|
|
21
22
|
|
|
22
|
-
def _load_json(url_or_request: str
|
|
23
|
+
def _load_json(url_or_request: Union[str, urllib.request.Request]) -> dict:
|
|
23
24
|
with _urlopen_with_backoff(url_or_request) as response:
|
|
24
25
|
response_data = response.read().decode('utf-8')
|
|
25
26
|
json_response = json.loads(response_data)
|
|
@@ -7,6 +7,7 @@ import urllib.request
|
|
|
7
7
|
import webbrowser
|
|
8
8
|
from collections.abc import Callable
|
|
9
9
|
from dataclasses import dataclass
|
|
10
|
+
from typing import Optional
|
|
10
11
|
|
|
11
12
|
from oauth2_cli_auth._urllib_util import _load_json
|
|
12
13
|
|
|
@@ -25,11 +26,14 @@ class OAuth2ClientInfo:
|
|
|
25
26
|
client_id: str
|
|
26
27
|
"""Id of the client to request for"""
|
|
27
28
|
|
|
29
|
+
client_secret: str | None
|
|
30
|
+
"""Secret of the client to request for"""
|
|
31
|
+
|
|
28
32
|
scopes: list[str]
|
|
29
33
|
"""List of scopes to request"""
|
|
30
34
|
|
|
31
35
|
@staticmethod
|
|
32
|
-
def from_oidc_endpoint(oidc_config_endpoint: str, client_id: str, scopes: list[str]) -> "OAuth2ClientInfo":
|
|
36
|
+
def from_oidc_endpoint(oidc_config_endpoint: str, client_id: str, scopes: list[str] = [], client_secret: str | None = None) -> "OAuth2ClientInfo":
|
|
33
37
|
"""
|
|
34
38
|
Create client information object from well known endpoint in format as specified in
|
|
35
39
|
https://openid.net/specs/openid-connect-discovery-1_0.html#ProviderMetadata
|
|
@@ -44,6 +48,7 @@ class OAuth2ClientInfo:
|
|
|
44
48
|
authorization_url=config.get("authorization_endpoint"),
|
|
45
49
|
token_url=config.get("token_endpoint"),
|
|
46
50
|
client_id=client_id,
|
|
51
|
+
client_secret=client_secret,
|
|
47
52
|
scopes=scopes,
|
|
48
53
|
)
|
|
49
54
|
|
|
@@ -58,7 +63,7 @@ def load_oidc_config(odic_well_known_endpoint: str) -> dict:
|
|
|
58
63
|
return config
|
|
59
64
|
|
|
60
65
|
|
|
61
|
-
def open_browser(url: str, print_open_browser_instruction: Callable[[str], None]
|
|
66
|
+
def open_browser(url: str, print_open_browser_instruction: Optional[Callable[[str], None]] = print) -> None:
|
|
62
67
|
"""
|
|
63
68
|
Open browser using webbrowser module and show message about URL open
|
|
64
69
|
|
|
@@ -101,7 +106,7 @@ def exchange_code_for_response(
|
|
|
101
106
|
"""
|
|
102
107
|
headers = {
|
|
103
108
|
"Content-Type": "application/x-www-form-urlencoded",
|
|
104
|
-
"Authorization": "Basic " + base64.b64encode(f"{client_info.client_id}:".encode()).decode(),
|
|
109
|
+
"Authorization": "Basic " + base64.b64encode(f"{client_info.client_id}:{client_info.client_secret if client_info.client_secret is not None else ''}".encode()).decode(),
|
|
105
110
|
}
|
|
106
111
|
|
|
107
112
|
data = {
|
|
@@ -116,6 +121,32 @@ def exchange_code_for_response(
|
|
|
116
121
|
|
|
117
122
|
return json_response
|
|
118
123
|
|
|
124
|
+
def refresh_access_token(
|
|
125
|
+
client_info: OAuth2ClientInfo,
|
|
126
|
+
refresh_token: str,
|
|
127
|
+
) -> dict:
|
|
128
|
+
"""
|
|
129
|
+
Refresh an access token using the endpoints from client info
|
|
130
|
+
|
|
131
|
+
:param client_info: Info about oauth2 client
|
|
132
|
+
:param refresh_token: Refresh token to use
|
|
133
|
+
:return: Response from OAuth2 endpoint
|
|
134
|
+
"""
|
|
135
|
+
headers = {
|
|
136
|
+
"Content-Type": "application/x-www-form-urlencoded",
|
|
137
|
+
"Authorization": "Basic " + base64.b64encode(f"{client_info.client_id}:{client_info.client_secret if client_info.client_secret is not None else ''}".encode()).decode(),
|
|
138
|
+
}
|
|
139
|
+
|
|
140
|
+
data = {
|
|
141
|
+
"refresh_token": refresh_token,
|
|
142
|
+
"grant_type": "refresh_token",
|
|
143
|
+
}
|
|
144
|
+
encoded_data = urllib.parse.urlencode(data).encode('utf-8')
|
|
145
|
+
|
|
146
|
+
request = urllib.request.Request(client_info.token_url, data=encoded_data, headers=headers)
|
|
147
|
+
json_response = _load_json(request)
|
|
148
|
+
|
|
149
|
+
return json_response
|
|
119
150
|
|
|
120
151
|
def exchange_code_for_access_token(
|
|
121
152
|
client_info: OAuth2ClientInfo,
|
|
@@ -234,9 +234,9 @@ class OAuthCallbackHttpServer(HTTPServer):
|
|
|
234
234
|
def __init__(self, port):
|
|
235
235
|
super().__init__(("", port), OAuthRedirectHandler)
|
|
236
236
|
|
|
237
|
-
self._code: str
|
|
237
|
+
self._code: Optional[str] = None
|
|
238
238
|
|
|
239
|
-
def get_code(self) -> str
|
|
239
|
+
def get_code(self) -> Optional[str]:
|
|
240
240
|
"""
|
|
241
241
|
This method should only be called after the request was done and might be None when no token is given.
|
|
242
242
|
|
|
@@ -1,6 +1,6 @@
|
|
|
1
1
|
[tool.poetry]
|
|
2
2
|
name = "oauth2-cli-auth"
|
|
3
|
-
version = "
|
|
3
|
+
version = "2.0.0"
|
|
4
4
|
description = "Authenticate against OAuth2 Provider in Python CLIs"
|
|
5
5
|
authors = ["Timo Reymann <mail@timo-reymann.de>"]
|
|
6
6
|
license = "MIT"
|
|
@@ -26,7 +26,7 @@ include = [
|
|
|
26
26
|
"LICENSE"
|
|
27
27
|
]
|
|
28
28
|
[tool.poetry.dependencies]
|
|
29
|
-
python = ">=3.
|
|
29
|
+
python = ">=3.10"
|
|
30
30
|
|
|
31
31
|
[tool.poetry.urls]
|
|
32
32
|
"Bug Tracker" = "https://github.com/timo-reymann/python-oauth2-cli-auth/issues"
|
|
@@ -39,7 +39,7 @@ priority="explicit"
|
|
|
39
39
|
[tool.poetry.group.dev.dependencies]
|
|
40
40
|
pytest = "^8.0.0"
|
|
41
41
|
coverage = "^7.3.2"
|
|
42
|
-
setuptools = "^
|
|
42
|
+
setuptools = "^80.0.0"
|
|
43
43
|
pydoctor = "^24.0.0"
|
|
44
44
|
|
|
45
45
|
[tool.coverage.run]
|
|
@@ -1 +0,0 @@
|
|
|
1
|
-
__version__ = "1.6.1"
|
|
File without changes
|
|
File without changes
|
|
File without changes
|
|
File without changes
|
|
File without changes
|