remoting: Edit dev server (#11344)

This PR allows configuring existing dev server, right now you can:
- Change the dev servers name
- Generate a new token (and invalidate the old one)

<img width="563" alt="image"
src="https://github.com/zed-industries/zed/assets/53836821/9bc95042-c969-4293-90fd-0848d021b664">


Release Notes:

- N/A
This commit is contained in:
Bennet Bo Fenner 2024-05-06 12:58:11 +02:00 committed by GitHub
parent 6e2be283dd
commit 593f0e0c3e
No known key found for this signature in database
GPG key ID: B5690EEEBB952194
7 changed files with 697 additions and 209 deletions

View file

@ -433,6 +433,8 @@ impl Server {
.add_request_handler(user_handler(create_dev_server_project))
.add_request_handler(user_handler(delete_dev_server_project))
.add_request_handler(user_handler(create_dev_server))
.add_request_handler(user_handler(regenerate_dev_server_token))
.add_request_handler(user_handler(rename_dev_server))
.add_request_handler(user_handler(delete_dev_server))
.add_request_handler(dev_server_handler(share_dev_server_project))
.add_request_handler(dev_server_handler(shutdown_dev_server))
@ -2343,6 +2345,12 @@ async fn create_dev_server(
let access_token = auth::random_token();
let hashed_access_token = auth::hash_access_token(&access_token);
if request.name.is_empty() {
return Err(proto::ErrorCode::Forbidden
.message("Dev server name cannot be empty".to_string())
.anyhow())?;
}
let (dev_server, status) = session
.db()
.await
@ -2359,6 +2367,71 @@ async fn create_dev_server(
Ok(())
}
async fn regenerate_dev_server_token(
request: proto::RegenerateDevServerToken,
response: Response<proto::RegenerateDevServerToken>,
session: UserSession,
) -> Result<()> {
let dev_server_id = DevServerId(request.dev_server_id as i32);
let access_token = auth::random_token();
let hashed_access_token = auth::hash_access_token(&access_token);
let connection_id = session
.connection_pool()
.await
.dev_server_connection_id(dev_server_id);
if let Some(connection_id) = connection_id {
shutdown_dev_server_internal(dev_server_id, connection_id, &session).await?;
session
.peer
.send(connection_id, proto::ShutdownDevServer {})?;
let _ = remove_dev_server_connection(dev_server_id, &session).await;
}
let status = session
.db()
.await
.update_dev_server_token(dev_server_id, &hashed_access_token, session.user_id())
.await?;
send_dev_server_projects_update(session.user_id(), status, &session).await;
response.send(proto::RegenerateDevServerTokenResponse {
dev_server_id: dev_server_id.to_proto(),
access_token: auth::generate_dev_server_token(dev_server_id.0 as usize, access_token),
})?;
Ok(())
}
async fn rename_dev_server(
request: proto::RenameDevServer,
response: Response<proto::RenameDevServer>,
session: UserSession,
) -> Result<()> {
if request.name.trim().is_empty() {
return Err(proto::ErrorCode::Forbidden
.message("Dev server name cannot be empty".to_string())
.anyhow())?;
}
let dev_server_id = DevServerId(request.dev_server_id as i32);
let dev_server = session.db().await.get_dev_server(dev_server_id).await?;
if dev_server.user_id != session.user_id() {
return Err(anyhow!(ErrorCode::Forbidden))?;
}
let status = session
.db()
.await
.rename_dev_server(dev_server_id, &request.name, session.user_id())
.await?;
send_dev_server_projects_update(session.user_id(), status, &session).await;
response.send(proto::Ack {})?;
Ok(())
}
async fn delete_dev_server(
request: proto::DeleteDevServer,
response: Response<proto::DeleteDevServer>,
@ -2379,6 +2452,7 @@ async fn delete_dev_server(
session
.peer
.send(connection_id, proto::ShutdownDevServer {})?;
let _ = remove_dev_server_connection(dev_server_id, &session).await;
}
let status = session
@ -2551,7 +2625,8 @@ async fn shutdown_dev_server(
session: DevServerSession,
) -> Result<()> {
response.send(proto::Ack {})?;
shutdown_dev_server_internal(session.dev_server_id(), session.connection_id, &session).await
shutdown_dev_server_internal(session.dev_server_id(), session.connection_id, &session).await?;
remove_dev_server_connection(session.dev_server_id(), &session).await
}
async fn shutdown_dev_server_internal(
@ -2591,6 +2666,21 @@ async fn shutdown_dev_server_internal(
Ok(())
}
async fn remove_dev_server_connection(dev_server_id: DevServerId, session: &Session) -> Result<()> {
let dev_server_connection = session
.connection_pool()
.await
.dev_server_connection_id(dev_server_id);
if let Some(dev_server_connection) = dev_server_connection {
session
.connection_pool()
.await
.remove_connection(dev_server_connection)?;
}
Ok(())
}
/// Updates other participants with changes to the project
async fn update_project(
request: proto::UpdateProject,