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() {
55 resolve_local_admin(&db_pool, &profile.system_admin.username).await?
56 } else {
57 let user_email = resolve_credentialed_user_email(session_email_hint).await?;
58 resolve_admin_with_fallback(&db_pool, user_email.as_str(), session_email_hint, "local")
59 .await?
60 };
61
62 if config.is_interactive() {
63 CliService::key_value("User", &admin_user.email);
64 }
65
66 let session_id = create_local_session_row(
67 &db_pool,
68 &admin_user.id,
69 chrono::Duration::hours(crate::session::api::DEFAULT_CLI_SESSION_HOURS),
70 )
71 .await
72 .context("Failed to create local CLI session row in the database")?;
73
74 let context_id =
75 create_cli_context(db_pool, &admin_user, &session_id, profile_ctx.name).await?;
76 let session_token = generate_admin_token(&profile.security.issuer, &admin_user, &session_id)?;
77
78 if config.is_interactive() {
79 CliService::success("Local session created");
80 CliService::key_value("Session ID", session_id.as_str());
81 CliService::key_value("Context ID", context_id.as_str());
82 }
83
84 build_cli_session(
85 profile_ctx,
86 session_key,
87 SessionComponents {
88 session_token,
89 session_id,
90 context_id,
91 },
92 &admin_user,
93 &profile.security.issuer,
94 )
95}
96
97pub(super) struct TenantSessionParams<'a> {
98 pub creds: &'a CloudCredentials,
99 pub profile: &'a Profile,
100 pub profile_ctx: &'a ProfileContext<'a>,
101 pub session_key: &'a SessionKey,
102 pub config: &'a CliConfig,
103 pub session_email_hint: Option<&'a str>,
104}
105
106pub(super) async fn create_session_for_tenant(
107 params: TenantSessionParams<'_>,
108) -> Result<CliSession> {
109 let TenantSessionParams {
110 creds,
111 profile,
112 profile_ctx,
113 session_key,
114 config,
115 session_email_hint,
116 } = params;
117 profile
118 .validate()
119 .with_context(|| format!("Failed to validate profile: {}", profile_ctx.name))?;
120
121 let user_email = session_email_hint.unwrap_or(creds.user_email.as_str());
122 let secrets = load_secrets().context("Failed to load secrets")?;
123
124 if config.is_interactive() {
125 CliService::info("Creating CLI session...");
126 CliService::key_value("Profile", profile_ctx.name);
127 CliService::key_value("User", user_email);
128 }
129
130 let db_pool = connect_database(&secrets).await?;
131 let admin_user =
132 resolve_tenant_admin_with_fallback(&db_pool, creds, user_email, session_email_hint).await?;
133
134 let session_id = create_local_session_row(
135 &db_pool,
136 &admin_user.id,
137 chrono::Duration::hours(crate::session::api::DEFAULT_CLI_SESSION_HOURS),
138 )
139 .await
140 .context("Failed to create local tenant CLI session row in the database")?;
141
142 let context_id =
143 create_cli_context(db_pool, &admin_user, &session_id, profile_ctx.name).await?;
144 let session_token = generate_admin_token(&profile.security.issuer, &admin_user, &session_id)?;
145
146 if config.is_interactive() {
147 CliService::success("Session created");
148 CliService::key_value("Session ID", session_id.as_str());
149 CliService::key_value("Context ID", context_id.as_str());
150 }
151
152 build_cli_session(
153 profile_ctx,
154 session_key,
155 SessionComponents {
156 session_token,
157 session_id,
158 context_id,
159 },
160 &admin_user,
161 &profile.security.issuer,
162 )
163}