systemprompt_cli/session/creation/
mod.rs1pub mod helpers;
12
13use anyhow::{Context, Result};
14use systemprompt_cloud::{CliSession, CloudCredentials, SessionKey};
15use systemprompt_logging::CliService;
16use systemprompt_manifest::Profile;
17
18use super::api::create_local_session_row;
19use super::resolution::ProfileContext;
20use crate::CliConfig;
21use helpers::{
22 SessionComponents, build_cli_session, connect_database, create_cli_context,
23 generate_admin_token, load_secrets, resolve_admin_with_fallback,
24 resolve_credentialed_user_email, resolve_local_admin, resolve_tenant_admin_with_fallback,
25};
26
27pub(super) async fn create_local_session(
28 profile: &Profile,
29 profile_ctx: &ProfileContext<'_>,
30 session_key: &SessionKey,
31 config: &CliConfig,
32 session_email_hint: Option<&str>,
33) -> Result<CliSession> {
34 profile
35 .validate()
36 .with_context(|| format!("Failed to validate profile: {}", profile_ctx.name))?;
37
38 let secrets = load_secrets().context("Failed to load secrets")?;
39
40 if config.is_interactive() {
41 CliService::info("Creating local CLI session...");
42 CliService::key_value("Profile", profile_ctx.name.as_str());
43 }
44
45 let db_pool = connect_database(&secrets).await?;
46
47 let admin_user = if profile.is_local_trial() && session_email_hint.is_none() {
48 resolve_local_admin(&db_pool, &profile.system_admin.username).await?
49 } else {
50 let user_email = resolve_credentialed_user_email(session_email_hint).await?;
51 resolve_admin_with_fallback(&db_pool, user_email.as_str(), session_email_hint, "local")
52 .await?
53 };
54
55 if config.is_interactive() {
56 CliService::key_value("User", &admin_user.email);
57 }
58
59 let session_id = create_local_session_row(
60 &db_pool,
61 &admin_user.id,
62 chrono::Duration::hours(crate::session::api::DEFAULT_CLI_SESSION_HOURS),
63 )
64 .await
65 .context("Failed to create local CLI session row in the database")?;
66
67 let context_id =
68 create_cli_context(db_pool, &admin_user, &session_id, profile_ctx.name).await?;
69 let session_token = generate_admin_token(&profile.security.issuer, &admin_user, &session_id)?;
70
71 if config.is_interactive() {
72 CliService::success("Local session created");
73 CliService::key_value("Session ID", session_id.as_str());
74 CliService::key_value("Context ID", context_id.as_str());
75 }
76
77 build_cli_session(
78 profile_ctx,
79 session_key,
80 SessionComponents {
81 session_token,
82 session_id,
83 context_id,
84 },
85 &admin_user,
86 &profile.security.issuer,
87 )
88}
89
90pub(super) struct TenantSessionParams<'a> {
91 pub creds: &'a CloudCredentials,
92 pub profile: &'a Profile,
93 pub profile_ctx: &'a ProfileContext<'a>,
94 pub session_key: &'a SessionKey,
95 pub config: &'a CliConfig,
96 pub session_email_hint: Option<&'a str>,
97}
98
99pub(super) async fn create_session_for_tenant(
100 params: TenantSessionParams<'_>,
101) -> Result<CliSession> {
102 let TenantSessionParams {
103 creds,
104 profile,
105 profile_ctx,
106 session_key,
107 config,
108 session_email_hint,
109 } = params;
110 profile
111 .validate()
112 .with_context(|| format!("Failed to validate profile: {}", profile_ctx.name))?;
113
114 let user_email = session_email_hint.unwrap_or(creds.user_email.as_str());
115 let secrets = load_secrets().context("Failed to load secrets")?;
116
117 if config.is_interactive() {
118 CliService::info("Creating CLI session...");
119 CliService::key_value("Profile", profile_ctx.name.as_str());
120 CliService::key_value("User", user_email);
121 }
122
123 let db_pool = connect_database(&secrets).await?;
124 let admin_user =
125 resolve_tenant_admin_with_fallback(&db_pool, creds, user_email, session_email_hint).await?;
126
127 let session_id = create_local_session_row(
128 &db_pool,
129 &admin_user.id,
130 chrono::Duration::hours(crate::session::api::DEFAULT_CLI_SESSION_HOURS),
131 )
132 .await
133 .context("Failed to create local tenant CLI session row in the database")?;
134
135 let context_id =
136 create_cli_context(db_pool, &admin_user, &session_id, profile_ctx.name).await?;
137 let session_token = generate_admin_token(&profile.security.issuer, &admin_user, &session_id)?;
138
139 if config.is_interactive() {
140 CliService::success("Session created");
141 CliService::key_value("Session ID", session_id.as_str());
142 CliService::key_value("Context ID", context_id.as_str());
143 }
144
145 build_cli_session(
146 profile_ctx,
147 session_key,
148 SessionComponents {
149 session_token,
150 session_id,
151 context_id,
152 },
153 &admin_user,
154 &profile.security.issuer,
155 )
156}