Skip to content

Commit 584b0eb

Browse files
authored
Merge pull request #686 from UiPath/fix/auth-port-binding
2 parents bf8708d + 5282c74 commit 584b0eb

File tree

5 files changed

+926
-921
lines changed

5 files changed

+926
-921
lines changed

pyproject.toml

Lines changed: 1 addition & 1 deletion
Original file line numberDiff line numberDiff line change
@@ -1,6 +1,6 @@
11
[project]
22
name = "uipath"
3-
version = "2.1.81"
3+
version = "2.1.82"
44
description = "Python SDK and CLI for UiPath Platform, enabling programmatic interaction with automation services, process management, and deployment tools."
55
readme = { file = "README.md", content-type = "text/markdown" }
66
requires-python = ">=3.10"

src/uipath/_cli/_auth/_auth_server.py

Lines changed: 15 additions & 12 deletions
Original file line numberDiff line numberDiff line change
@@ -7,8 +7,6 @@
77
import time
88
from typing import Optional
99

10-
from ._oidc_utils import OidcUtils
11-
1210
# Server port
1311
PORT = 6234
1412

@@ -22,7 +20,9 @@ def __init__(self, token_data):
2220
super().__init__("Token received successfully")
2321

2422

25-
def make_request_handler_class(state, code_verifier, token_callback, domain):
23+
def make_request_handler_class(
24+
state, code_verifier, token_callback, domain, redirect_uri, client_id
25+
):
2626
class SimpleHTTPSRequestHandler(http.server.SimpleHTTPRequestHandler):
2727
"""Simple HTTPS request handler that serves static files."""
2828

@@ -73,16 +73,10 @@ def do_GET(self):
7373
with open(index_path, "r") as f:
7474
content = f.read()
7575

76-
# Get the redirect URI from auth config
77-
auth_config = OidcUtils.get_auth_config()
78-
redirect_uri = auth_config["redirect_uri"]
79-
8076
content = content.replace("__PY_REPLACE_EXPECTED_STATE__", state)
8177
content = content.replace("__PY_REPLACE_CODE_VERIFIER__", code_verifier)
8278
content = content.replace("__PY_REPLACE_REDIRECT_URI__", redirect_uri)
83-
content = content.replace(
84-
"__PY_REPLACE_CLIENT_ID__", auth_config["client_id"]
85-
)
79+
content = content.replace("__PY_REPLACE_CLIENT_ID__", client_id)
8680
content = content.replace("__PY_REPLACE_DOMAIN__", domain)
8781

8882
self.send_response(200)
@@ -107,14 +101,18 @@ def do_OPTIONS(self):
107101

108102

109103
class HTTPServer:
110-
def __init__(self, port=6234):
104+
def __init__(self, port=6234, redirect_uri=None, client_id=None):
111105
"""Initialize HTTP server with configurable parameters.
112106
113107
Args:
114108
port (int, optional): Port number to run the server on. Defaults to 6234.
109+
redirect_uri (str, optional): OAuth redirect URI. Defaults to None.
110+
client_id (str, optional): OAuth client ID. Defaults to None.
115111
"""
116112
self.current_path = os.path.dirname(os.path.abspath(__file__))
117113
self.port = port
114+
self.redirect_uri = redirect_uri
115+
self.client_id = client_id
118116
self.httpd: Optional[socketserver.TCPServer] = None
119117
self.token_data = None
120118
self.should_shutdown = False
@@ -145,7 +143,12 @@ def create_server(self, state, code_verifier, domain):
145143
# Create server with address reuse
146144
socketserver.TCPServer.allow_reuse_address = True
147145
handler = make_request_handler_class(
148-
state, code_verifier, self.token_received_callback, domain
146+
state,
147+
code_verifier,
148+
self.token_received_callback,
149+
domain,
150+
self.redirect_uri,
151+
self.client_id,
149152
)
150153
self.httpd = socketserver.TCPServer(("", self.port), handler)
151154
return self.httpd

src/uipath/_cli/_auth/_auth_service.py

Lines changed: 9 additions & 3 deletions
Original file line numberDiff line numberDiff line change
@@ -121,11 +121,17 @@ def _can_reuse_existing_token(self, portal_service: PortalService) -> bool:
121121
return False
122122

123123
def _perform_oauth_flow(self) -> TokenData:
124-
auth_url, code_verifier, state = OidcUtils.get_auth_url(self._domain)
124+
auth_config = OidcUtils.get_auth_config()
125+
auth_url, code_verifier, state = OidcUtils.get_auth_url(
126+
self._domain, auth_config
127+
)
125128
self._open_browser(auth_url)
126129

127-
auth_config = OidcUtils.get_auth_config()
128-
server = HTTPServer(port=auth_config["port"])
130+
server = HTTPServer(
131+
port=auth_config["port"],
132+
redirect_uri=auth_config["redirect_uri"],
133+
client_id=auth_config["client_id"],
134+
)
129135
token_data = asyncio.run(server.start(state, code_verifier, self._domain))
130136

131137
if not token_data:

src/uipath/_cli/_auth/_oidc_utils.py

Lines changed: 4 additions & 8 deletions
Original file line numberDiff line numberDiff line change
@@ -49,12 +49,8 @@ def get_auth_config(cls) -> AuthConfig:
4949
) as f:
5050
auth_config = json.load(f)
5151

52-
candidates = [
53-
int(auth_config.get("port", 8104)),
54-
int(auth_config.get("portOptionOne", 8104)),
55-
int(auth_config.get("portOptionTwo", 8055)),
56-
int(auth_config.get("portOptionThree", 42042)),
57-
]
52+
custom_port = os.getenv("UIPATH_AUTH_PORT")
53+
candidates = [int(custom_port)] if custom_port else [8104, 8055, 42042]
5854

5955
port = cls._find_free_port(candidates)
6056
if port is None:
@@ -75,19 +71,19 @@ def get_auth_config(cls) -> AuthConfig:
7571
)
7672

7773
@classmethod
78-
def get_auth_url(cls, domain: str) -> tuple[str, str, str]:
74+
def get_auth_url(cls, domain: str, auth_config: AuthConfig) -> tuple[str, str, str]:
7975
"""Get the authorization URL for OAuth2 PKCE flow.
8076
8177
Args:
8278
domain (str): The UiPath domain to authenticate against (e.g. 'alpha', 'cloud')
79+
auth_config (AuthConfig): The authentication configuration to use
8380
8481
Returns:
8582
tuple[str, str]: A tuple containing:
8683
- The authorization URL with query parameters
8784
- The code verifier for PKCE flow
8885
"""
8986
code_verifier, code_challenge = generate_code_verifier_and_challenge()
90-
auth_config = cls.get_auth_config()
9187
state = get_state_param()
9288
query_params = {
9389
"client_id": auth_config["client_id"],

0 commit comments

Comments
 (0)