diff options
Diffstat (limited to 'server/src/main.rs')
| -rw-r--r-- | server/src/main.rs | 64 |
1 files changed, 60 insertions, 4 deletions
diff --git a/server/src/main.rs b/server/src/main.rs index 9bdfeaf..973febe 100644 --- a/server/src/main.rs +++ b/server/src/main.rs @@ -36,6 +36,7 @@ struct Db(sqlx::MySqlPool); #[derive(OpenApi)] #[openapi( paths( + healthcheck, projects, project, project_new, @@ -107,6 +108,18 @@ async fn projects( }) } +fn abbrivate_key(key: &str) -> String { + let len = key.len(); + if len <= 24 { + // Realistically this will only happen for empty keys, + // but make sure to NEVER send the whole key if it is really short. + return String::new(); + } + let start = &key[0..8]; + let end = &key[len - 8..len]; + return format!("{start}...{end}"); +} + async fn get_project( db: &mut <<Db as Database>::Pool as Pool>::Connection, projectid: &str, @@ -129,7 +142,7 @@ async fn get_project( .unwrap(); let project = sqlx::query!( - "SELECT id,title,description,remote,main_branch FROM projects WHERE id=?", + "SELECT id,title,description,remote,remote_key,main_branch FROM projects WHERE id=?", projectid ) .fetch_one(&mut **db) @@ -138,6 +151,7 @@ async fn get_project( title: r.title, description: r.description, remote: r.remote, + remote_key_abbrev: abbrivate_key(r.remote_key.as_str()), main_branch: r.main_branch, users, }) @@ -166,6 +180,19 @@ async fn project( get_project(&mut conn, projectid).await } +// Remove linebreaks and potential openssh wrapper +fn cleanup_key(key: &str) -> String { + let mut ret = String::with_capacity(key.len()); + let mut lines = key.lines(); + while let Some(line) = lines.next() { + match line { + "-----BEGIN OPENSSH PRIVATE KEY-----" | "-----END OPENSSH PRIVATE KEY-----" => {} + _ => ret.push_str(line), + } + } + return ret; +} + #[utoipa::path( responses( (status = 200, description = "Project created", body = api_model::Project), @@ -185,6 +212,10 @@ async fn project_new( data: Json<api_model::ProjectData<'_>>, ) -> Result<Json<api_model::Project>, Custom<String>> { let remote = data.remote.unwrap_or(""); + let remote_key = match &data.remote_key { + Some(data) => cleanup_key(data.as_str()), + None => String::new(), + }; let main_branch = data.main_branch.unwrap_or("main"); let mut conn = db.get().await.unwrap(); @@ -192,11 +223,12 @@ async fn project_new( let mut tx = conn.begin().await.unwrap(); sqlx::query!( - "INSERT INTO projects (id, title, description, remote, main_branch) VALUES (?, ?, ?, ?, ?)", + "INSERT INTO projects (id, title, description, remote, remote_key, main_branch) VALUES (?, ?, ?, ?, ?, ?)", projectid, data.title.unwrap_or("Unnamed"), data.description.unwrap_or(""), remote, + remote_key, main_branch, ) .execute(&mut *tx) @@ -214,8 +246,15 @@ async fn project_new( } roots_state - .new_project(git_roots_config, db, projectid, remote, main_branch) - .map_err(|e| Custom(Status::InternalServerError, e.message)) + .new_project( + git_roots_config, + db, + projectid, + remote, + remote_key.as_str(), + main_branch, + ) + .map_err(|e| Custom(Status::InternalServerError, format!("{e}"))) .await?; Ok(get_project(&mut conn, projectid).await.unwrap()) @@ -278,6 +317,9 @@ async fn project_update( if let Some(remote) = &data.remote { update_builder.set("remote", remote); } + if let Some(remote_key) = &data.remote_key { + update_builder.set("remote_key", cleanup_key(remote_key)); + } if let Some(main_branch) = &data.main_branch { update_builder.set("main_branch", main_branch); } @@ -1060,6 +1102,19 @@ async fn user_keys( }) } +#[utoipa::path( + responses( + (status = 200, description = "All good"), + ), + security( + (), + ), +)] +#[get("/healthcheck")] +fn healthcheck() -> &'static str { + "" +} + async fn run_migrations(rocket: Rocket<Build>) -> fairing::Result { match Db::fetch(&rocket) { Some(db) => match sqlx::migrate!().run(&**db).await { @@ -1082,6 +1137,7 @@ fn rocket_from_config(figment: Figment) -> Rocket<Build> { basepath, // Remember to update openapi paths when you add something here. routes