diff options
| author | Joel Klinghed <the_jk@spawned.biz> | 2025-01-26 23:55:50 +0100 |
|---|---|---|
| committer | Joel Klinghed <the_jk@spawned.biz> | 2025-01-26 23:55:50 +0100 |
| commit | d1647b7a056f04ad5828976dd5a7e2e06b431feb (patch) | |
| tree | 11a4e1ad3f40bf653b7971bd40e54568f507ffb5 /server/src/git_root.rs | |
| parent | 4fe3e610d5697aca4dfdc1033261130ec2b431ee (diff) | |
Stop using current user in git hooks
Want to support any authentication for the git server, so use git
commiter as username for creating reviews instead of the local user
that logged in to git.
Also verify that pushed commits has a valid author in pre-receive.
This is tricky as pre-receive must do this check in the hook, because
pre-receive runs when before the objects are pushed so the server
can't read the commits, the hook must do this.
Diffstat (limited to 'server/src/git_root.rs')
| -rw-r--r-- | server/src/git_root.rs | 46 |
1 files changed, 37 insertions, 9 deletions
diff --git a/server/src/git_root.rs b/server/src/git_root.rs index c6ee1fb..8102b18 100644 --- a/server/src/git_root.rs +++ b/server/src/git_root.rs @@ -84,8 +84,6 @@ impl std::fmt::Display for IoError { impl std::error::Error for IoError {} -const EMPTY: &str = "0000000000000000000000000000000000000000"; - fn is_printable(name: &str) -> bool { name.as_bytes().iter().all(|c| c.is_ascii_graphic()) } @@ -116,7 +114,30 @@ async fn git_process_prehook( let branch = row.reference.strip_prefix("refs/heads/").unwrap(); - if row.old_value == EMPTY { + if row.new_value != git::EMPTY { + match row.commiter { + Some(ref commiter) => match sqlx::query!( + "SELECT id FROM users WHERE id=? AND dn IS NOT NULL", + commiter, + ) + .fetch_one(&mut *db) + .map_err(|_| IoError::new(format!("{branch}: Unknown commiter {}", commiter))) + .await + { + Ok(_) => {} + Err(e) => { + errors.push(e.message); + continue; + } + }, + None => { + errors.push(format!("{branch}: Missing commiter")); + continue; + } + } + } + + if row.old_value == git::EMPTY { // Creating new review, nothing to check (yet). continue; } @@ -136,7 +157,7 @@ async fn git_process_prehook( .map_err(|_| IoError::new(format!("{branch}: Unknown branch"))) .await; - if row.new_value == EMPTY { + if row.new_value == git::EMPTY { // Do not allow to delete branch if there is a review connected to the branch. // All branches should be connected to a branch, but in case of errors this might // be relevant. @@ -209,7 +230,6 @@ async fn git_process_prehook( async fn git_process_posthook( repo: &git::Repository, mut db: DbConnection, - user_id: &String, receive: &Vec<git_socket::GitReceive>, ) -> git_socket::GitHookResponse { let mut messages: Vec<String> = Vec::new(); @@ -218,12 +238,20 @@ async fn git_process_posthook( for row in receive { let branch = row.reference.strip_prefix("refs/heads/").unwrap(); - if row.old_value == EMPTY { + if row.old_value == git::EMPTY { + let commiter = match repo.get_commiter(row.reference.as_str()).await { + Ok(user) => user, + Err(e) => { + messages.push(format!("{branch}: {e}")); + continue; + } + }; + // Create review match sqlx::query!( "INSERT INTO reviews (project, owner, title, branch) VALUES (?, ?, ?, ?)", repo.project_id(), - user_id, + commiter.username, "Unnamed", branch ) @@ -242,7 +270,7 @@ async fn git_process_posthook( messages.push(format!("{branch}: Error {e}",)); } }; - } else if row.new_value == EMPTY { + } else if row.new_value == git::EMPTY { // Delete branch, prehook already checked that it is not connected to a branch. } else { match sqlx::query!( @@ -312,7 +340,7 @@ async fn git_socket_process( let response = if request.pre { git_process_prehook(repo, db, &request.receive).await? } else { - git_process_posthook(repo, db, &request.user, &request.receive).await + git_process_posthook(repo, db, &request.receive).await }; task::spawn_blocking(move || { |
