Skip to content

Commit 554fb9b

Browse files
Merge pull request #4 from neutrons/client_id
Client id parameter
2 parents a93e158 + d1c5851 commit 554fb9b

File tree

3 files changed

+95
-8
lines changed

3 files changed

+95
-8
lines changed

docs/source/sample.rst

Lines changed: 6 additions & 0 deletions
Original file line numberDiff line numberDiff line change
@@ -72,7 +72,13 @@ ONCatLoginDialog
7272
The `ONCatLoginDialog` can be imported and used separate from the `ONCatLogin` widget to give developers
7373
the ability to customize the login process. In order to use the `ONCatLoginDialog`, you must have an
7474
instance of the `pyoncat.ONCat` agent.
75+
7576
If you chose to use the `ONCatLogin` widget instead, the agent is already created for you.
77+
In this case, a `key` or `client_id` are required to be passed by the user application. If `key` (application name)
78+
is passed, the client_id is retrieved from the configuration, provided it exists. If the client_id is
79+
provided, it uses this instead. If both are provided, client_id is used for oncat client id tasks, e.g. agent creation,
80+
and the key is only used to create a human-readbale filename for saving the user's authentication token.
81+
7682
The `ONCatLoginDialog` requires the agent to be passed in as an argument.
7783
The agent is used to authenticate the user and manage the connection to the ONCat server.
7884
At a minimum the agent must be initialized with the ONCat server URL, flow, and the client ID.

src/pyoncatqt/login.py

Lines changed: 20 additions & 7 deletions
Original file line numberDiff line numberDiff line change
@@ -151,7 +151,9 @@ class ONCatLogin(QGroupBox):
151151
152152
Params
153153
------
154-
key : str, required
154+
client_id : str, optional
155+
The client_id is an ONCat client ID. Defaults to None. client_id is required or key is required
156+
key : str, optional
155157
The key used to retrieve ONCat client ID from configuration. Defaults to None.
156158
parent : QWidget, optional
157159
The parent widget.
@@ -181,12 +183,16 @@ class ONCatLogin(QGroupBox):
181183

182184
connection_updated = Signal(bool)
183185

184-
def __init__(self: QGroupBox, key: str = None, parent: QWidget = None, **kwargs: Dict[str, Any]) -> None:
186+
def __init__(
187+
self: QGroupBox, *, client_id: str = None, key: str = None, parent: QWidget = None, **kwargs: Dict[str, Any]
188+
) -> None:
185189
"""
186190
Initialize the ONCatLogin widget.
187191
188192
Params
189193
------
194+
client_id : str, optional
195+
The client_id is an ONCat client ID. Defaults to None.
190196
key : str, optional
191197
The key used to retrieve ONCat client ID from configuration. Defaults to None.
192198
parent : QWidget, optional
@@ -215,11 +221,18 @@ def __init__(self: QGroupBox, key: str = None, parent: QWidget = None, **kwargs:
215221
# OnCat agent
216222

217223
self.oncat_url = get_data("login.oncat", "oncat_url")
218-
self.client_id = get_data("login.oncat", f"{key}_id")
219-
if not self.client_id:
220-
raise ValueError(f"Invalid module {key}. No OnCat client Id is found for this application.")
224+
if client_id is not None:
225+
self.client_id = client_id
226+
elif key is not None:
227+
self.client_id = get_data("login.oncat", f"{key}_id")
228+
else:
229+
raise ValueError(f"Invalid module {key}. No OnCat client Id is found or provided for this application.")
221230

222-
self.token_path = os.path.abspath(f"{os.path.expanduser('~')}/.pyoncatqt/{key}_token.json")
231+
# use the partial client id to generate the filename
232+
token_filename = f"{self.client_id[0:8]}_token.json"
233+
if key:
234+
token_filename = f"{key}_token.json"
235+
self.token_path = os.path.abspath(f"{os.path.expanduser('~')}/.pyoncatqt/{token_filename}")
223236

224237
self.agent = pyoncat.ONCat(
225238
self.oncat_url,
@@ -241,7 +254,6 @@ def update_connection_status(self: QGroupBox) -> None:
241254
else:
242255
self.status_label.setText("ONCat: Disconnected")
243256
self.status_label.setStyleSheet("color: red")
244-
245257
self.connection_updated.emit(self.is_connected)
246258

247259
@property
@@ -254,6 +266,7 @@ def is_connected(self: QGroupBox) -> bool:
254266
bool
255267
True if connected, False otherwise.
256268
"""
269+
257270
try:
258271
self.agent.Facility.list()
259272
return True

tests/test_login_dialog.py

Lines changed: 69 additions & 1 deletion
Original file line numberDiff line numberDiff line change
@@ -30,13 +30,81 @@ def test_login_dialog_creation() -> None:
3030
assert isinstance(dialog.button_cancel, QPushButton)
3131

3232

33-
def test_login(qtbot: pytest.fixture) -> None:
33+
def test_login_key(qtbot: pytest.fixture) -> None:
3434
dialog = ONCatLogin(key="test")
3535
dialog.login_dialog = ONCatLoginDialog(agent=MagicMock(), parent=dialog)
3636
dialog.login_dialog.login_status.connect(check_status)
3737
qtbot.addWidget(dialog)
3838
dialog.show()
3939

40+
assert dialog.client_id == "0123456489"
41+
assert dialog.token_path.endswith("test_token.json")
42+
43+
completed = False
44+
45+
def handle_dialog() -> None:
46+
nonlocal completed
47+
48+
qtbot.keyClicks(dialog.login_dialog.user_pwd, "password")
49+
qtbot.wait(2000)
50+
qtbot.mouseClick(dialog.login_dialog.button_login, QtCore.Qt.LeftButton)
51+
completed = True
52+
53+
def dialog_completed() -> None:
54+
nonlocal completed
55+
assert completed is True
56+
57+
QtCore.QTimer.singleShot(500, functools.partial(handle_dialog))
58+
qtbot.mouseClick(dialog.oncat_button, QtCore.Qt.LeftButton)
59+
60+
qtbot.waitUntil(dialog_completed, timeout=5000)
61+
62+
63+
def test_login_client_id(qtbot: pytest.fixture) -> None:
64+
client_id = "12cnfjejsfsdf3456789ab"
65+
dialog = ONCatLogin(client_id=client_id)
66+
dialog.login_dialog = ONCatLoginDialog(agent=MagicMock(), parent=dialog)
67+
dialog.login_dialog.login_status.connect(check_status)
68+
qtbot.addWidget(dialog)
69+
dialog.show()
70+
71+
assert dialog.client_id == client_id
72+
# token_12cnf.json
73+
assert dialog.token_path.endswith(f"{client_id[0:8]}_token.json")
74+
completed = False
75+
76+
def handle_dialog() -> None:
77+
nonlocal completed
78+
79+
qtbot.keyClicks(dialog.login_dialog.user_pwd, "password")
80+
qtbot.wait(2000)
81+
qtbot.mouseClick(dialog.login_dialog.button_login, QtCore.Qt.LeftButton)
82+
completed = True
83+
84+
def dialog_completed() -> None:
85+
nonlocal completed
86+
assert completed is True
87+
88+
QtCore.QTimer.singleShot(500, functools.partial(handle_dialog))
89+
qtbot.mouseClick(dialog.oncat_button, QtCore.Qt.LeftButton)
90+
91+
qtbot.waitUntil(dialog_completed, timeout=5000)
92+
93+
94+
def test_login_client_id_key(qtbot: pytest.fixture) -> None:
95+
client_id = "12cnfjejsfsdf3456789ab"
96+
key = "test"
97+
98+
dialog = ONCatLogin(client_id=client_id, key=key)
99+
dialog.login_dialog = ONCatLoginDialog(agent=MagicMock(), parent=dialog)
100+
dialog.login_dialog.login_status.connect(check_status)
101+
qtbot.addWidget(dialog)
102+
dialog.show()
103+
104+
# client id provided as parameter
105+
assert dialog.client_id == client_id
106+
# key used for filename only token_shiver.json
107+
assert dialog.token_path.endswith(f"{key}_token.json")
40108
completed = False
41109

42110
def handle_dialog() -> None:

0 commit comments

Comments
 (0)