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