-
Notifications
You must be signed in to change notification settings - Fork 356
Commit
This commit does not belong to any branch on this repository, and may belong to a fork outside of the repository.
Browse files
Browse the repository at this point in the history
The authentication logic would drop expired tokens, and then ask for a password and, if that worked, add the fresh token back to the token store. However, the initial token drop had a side-effect of dropping the active user, which was not being restored. After this fix, the TokenStore doesn't try to be so smart. Instead, the logout-related CLI commands will explicitly clear the active user, but tokens dropped due to expiration are unaffected.
- Loading branch information
1 parent
9dc4fc8
commit fd4c1a0
Showing
6 changed files
with
119 additions
and
68 deletions.
There are no files selected for viewing
This file contains bidirectional Unicode text that may be interpreted or compiled differently than what appears below. To review, open the file in an editor that reveals hidden Unicode characters.
Learn more about bidirectional Unicode characters
This file contains bidirectional Unicode text that may be interpreted or compiled differently than what appears below. To review, open the file in an editor that reveals hidden Unicode characters.
Learn more about bidirectional Unicode characters
This file contains bidirectional Unicode text that may be interpreted or compiled differently than what appears below. To review, open the file in an editor that reveals hidden Unicode characters.
Learn more about bidirectional Unicode characters
File renamed without changes.
This file contains bidirectional Unicode text that may be interpreted or compiled differently than what appears below. To review, open the file in an editor that reveals hidden Unicode characters.
Learn more about bidirectional Unicode characters
Original file line number | Diff line number | Diff line change |
---|---|---|
@@ -0,0 +1,58 @@ | ||
import contextlib | ||
import json | ||
import pathlib | ||
import shutil | ||
from typing import Optional | ||
|
||
import pytest | ||
import responses | ||
from responses import registries | ||
|
||
from determined.common.api import authentication | ||
from tests import confdir | ||
from tests.cli import util | ||
|
||
MOCK_MASTER_URL = "http://localhost:8080" | ||
AUTH_V0_PATH = pathlib.Path(__file__).parent / "auth_v0.json" | ||
|
||
|
||
@pytest.mark.parametrize("active_user", ["alice", "bob", None]) | ||
def test_logout_clears_active_user(active_user: Optional[str]) -> None: | ||
with contextlib.ExitStack() as es: | ||
es.enter_context(util.setenv_optional("DET_MASTER", MOCK_MASTER_URL)) | ||
rsps = es.enter_context( | ||
responses.RequestsMock( | ||
registry=registries.OrderedRegistry, | ||
assert_all_requests_are_fired=True, | ||
) | ||
) | ||
mts = es.enter_context(util.MockTokenStore(strict=True)) | ||
|
||
mts.get_active_user(retval=active_user) | ||
if active_user == "alice": | ||
mts.clear_active() | ||
mts.get_token("alice", retval="token") | ||
mts.drop_user("alice") | ||
rsps.post(f"{MOCK_MASTER_URL}/api/v1/auth/logout", status=200) | ||
|
||
authentication.logout(MOCK_MASTER_URL, "alice", None) | ||
|
||
|
||
def test_auth_json_v0_upgrade() -> None: | ||
with confdir.use_test_config_dir() as config_dir: | ||
auth_json_path = config_dir / "auth.json" | ||
shutil.copy2(AUTH_V0_PATH, auth_json_path) | ||
ts = authentication.TokenStore(MOCK_MASTER_URL, auth_json_path) | ||
|
||
assert ts.get_active_user() == "determined" | ||
assert ts.get_token("determined") == "v2.public.this.is.a.test" | ||
|
||
ts.set_token("determined", "ai") | ||
|
||
ts2 = authentication.TokenStore(MOCK_MASTER_URL, auth_json_path) | ||
assert ts2.get_token("determined") == "ai" | ||
|
||
with auth_json_path.open() as fin: | ||
data = json.load(fin) | ||
assert data.get("version") == 1 | ||
assert "masters" in data and list(data["masters"].keys()) == [MOCK_MASTER_URL] |
This file contains bidirectional Unicode text that may be interpreted or compiled differently than what appears below. To review, open the file in an editor that reveals hidden Unicode characters.
Learn more about bidirectional Unicode characters
Original file line number | Diff line number | Diff line change |
---|---|---|
@@ -0,0 +1,33 @@ | ||
import pathlib | ||
import shutil | ||
|
||
from determined.common.api import certs | ||
from tests import confdir | ||
|
||
MOCK_MASTER_URL = "http://localhost:8080" | ||
UNTRUSTED_CERT_PATH = pathlib.Path(__file__).parents[1] / "untrusted-root" / "127.0.0.1-ca.crt" | ||
|
||
|
||
def test_cert_v0_upgrade() -> None: | ||
with confdir.use_test_config_dir() as config_dir: | ||
cert_path = config_dir / "master.crt" | ||
shutil.copy2(UNTRUSTED_CERT_PATH, cert_path) | ||
with cert_path.open() as fin: | ||
cert_data = fin.read() | ||
|
||
cert = certs.default_load(MOCK_MASTER_URL) | ||
assert isinstance(cert.bundle, str) | ||
with open(cert.bundle) as fin: | ||
loaded_cert_data = fin.read() | ||
assert loaded_cert_data.endswith(cert_data) | ||
assert not cert_path.exists() | ||
|
||
v1_certs_path = config_dir / "certs.json" | ||
assert v1_certs_path.exists() | ||
|
||
# Load once again from v1. | ||
cert2 = certs.default_load(MOCK_MASTER_URL) | ||
assert isinstance(cert2.bundle, str) | ||
with open(cert2.bundle) as fin: | ||
loaded_cert_data = fin.read() | ||
assert loaded_cert_data.endswith(cert_data) |