Skip to content

Commit acbdf19

Browse files
committed
test showing expired session delete doesn't work
1 parent 9ba7e6c commit acbdf19

File tree

1 file changed

+59
-1
lines changed

1 file changed

+59
-1
lines changed

nexus/tests/integration_tests/console_api.rs

Lines changed: 59 additions & 1 deletion
Original file line numberDiff line numberDiff line change
@@ -8,6 +8,7 @@ use dropshot::ResultsPage;
88
use dropshot::test_util::ClientTestContext;
99
use http::header::HeaderName;
1010
use http::{StatusCode, header, method::Method};
11+
use nexus_auth::context::OpContext;
1112
use std::env::current_dir;
1213

1314
use crate::integration_tests::saml::SAML_RESPONSE_IDP_DESCRIPTOR;
@@ -30,7 +31,7 @@ use nexus_test_utils_macros::nexus_test;
3031
use nexus_types::external_api::params::{self, ProjectCreate};
3132
use nexus_types::external_api::shared::{SiloIdentityMode, SiloRole};
3233
use nexus_types::external_api::{shared, views};
33-
use omicron_common::api::external::IdentityMetadataCreateParams;
34+
use omicron_common::api::external::{Error, IdentityMetadataCreateParams};
3435
use omicron_sled_agent::sim;
3536
use omicron_test_utils::dev::poll::{CondCheckError, wait_for_condition};
3637

@@ -918,3 +919,60 @@ async fn expect_redirect(testctx: &ClientTestContext, from: &str, to: &str) {
918919
.await
919920
.expect("did not find expected redirect");
920921
}
922+
923+
/// Make sure an expired session gets deleted when you try to use it
924+
///
925+
/// This is not the best kind of test because it breaks the API abstraction
926+
/// boundary, but in this case it's necessary because by design we do not
927+
/// expose through the API why authn failed, i.e., whether it's because
928+
/// the session was found but is expired. vs not found at all
929+
#[tokio::test]
930+
async fn test_session_idle_timeout_deletes_session() {
931+
// set idle timeout to 1 second so we can test expiration
932+
let mut config = load_test_config();
933+
config.pkg.console.session_idle_timeout_minutes = 0;
934+
let cptestctx = test_setup_with_config::<omicron_nexus::Server>(
935+
"test_session_idle_timeout_deletes_session",
936+
&mut config,
937+
sim::SimMode::Explicit,
938+
None,
939+
0,
940+
)
941+
.await;
942+
let testctx = &cptestctx.external_client;
943+
944+
// Start session
945+
let session_cookie = log_in_and_extract_token(&cptestctx).await;
946+
947+
// sleep here not necessary given TTL of 0
948+
949+
// Make a request with the expired session cookie
950+
let me_response = RequestBuilder::new(testctx, Method::GET, "/v1/me")
951+
.header(header::COOKIE, &session_cookie)
952+
.expect_status(Some(StatusCode::UNAUTHORIZED))
953+
.execute()
954+
.await
955+
.expect("first request with expired cookie did not 401");
956+
957+
let error_body: dropshot::HttpErrorResponseBody =
958+
me_response.parsed_body().unwrap();
959+
assert_eq!(error_body.message, "credentials missing or invalid");
960+
961+
// check that the session actually got deleted
962+
963+
let nexus = &cptestctx.server.server_context().nexus;
964+
let datastore = nexus.datastore();
965+
let opctx =
966+
OpContext::for_tests(cptestctx.logctx.log.new(o!()), datastore.clone());
967+
968+
let token = session_cookie.strip_prefix("session=").unwrap();
969+
let db_token_error = nexus
970+
.datastore()
971+
.session_lookup_by_token(&opctx, token.to_string())
972+
.await
973+
.expect_err("session should be deleted");
974+
assert_matches::assert_matches!(
975+
db_token_error,
976+
Error::ObjectNotFound { .. }
977+
);
978+
}

0 commit comments

Comments
 (0)