feat: integrate pi rust lab runtime

This commit is contained in:
Agent Board
2026-07-10 10:54:34 +08:00
parent c8472bb898
commit 896c94b696
73 changed files with 19852 additions and 1152 deletions
+51 -78
View File
@@ -3,11 +3,10 @@ use crate::context::RequestContext;
use crate::error::WebError;
use crate::provider_identity_sync::sync_provider_identities;
use crate::routes::local_folder_source::{
control_plane_status_display, create_default_local_workspace_for_actor,
ensure_local_workspace_read_access_with_state, is_local_access_policy_admin_context,
load_local_folder_file_tree_children_snapshot, load_local_folder_file_tree_snapshot,
load_local_folder_page_tree_scope_snapshot, load_local_folder_page_tree_snapshot,
load_local_trash_entries,
create_default_local_workspace_for_actor, ensure_local_workspace_read_access_with_state,
is_local_access_policy_admin_context, load_local_folder_file_tree_children_snapshot,
load_local_folder_file_tree_snapshot, load_local_folder_page_tree_scope_snapshot,
load_local_folder_page_tree_snapshot, load_local_trash_entries,
};
use crate::routes::snapshot_support::load_sidebar_dataset;
use crate::routes::web_shell::{
@@ -197,28 +196,11 @@ pub async fn admin_access_policy_entry(
)
.with_context(&context));
}
let workspace_name = default_workspace_name_for_context(&state, &context);
let share_grants_path = control_plane_status_display();
let content = crate::ssr::render_view(leptos::view! {
<crate::ssr::pages::admin::AdminAccessPolicyPanel workspace_name={workspace_name} share_grants_path={share_grants_path} is_admin=true />
});
let mut response = Html(format!(
r#"<!doctype html>
<html lang="zh-CN">
<head>
<meta charset="utf-8">
<title>授权管理</title>
<style>{}</style>
</head>
<body data-mnote-web-owner="mnote-web" data-mnote-shell="admin" data-mnote-actor-id="{}">
{}
</body>
</html>"#,
crate::ssr::MNOTE_CSS,
escape_html(context.auth.actor_id.as_str()),
content
))
.into_response();
let mut response = Response::builder()
.status(StatusCode::SEE_OTHER)
.header(header::LOCATION, "/admin/ai#ai-admin-access")
.body(Body::empty())
.map_err(|error| WebError::internal(format!("授权管理跳转响应构造失败: {error}")))?;
stamp_gateway_headers(response.headers_mut(), false);
Ok(response)
}
@@ -236,27 +218,11 @@ pub async fn user_access_policy_entry(
stamp_gateway_headers(response.headers_mut(), false);
return Ok(response);
}
let workspace_name = default_workspace_name_for_context(&state, &context);
let content = crate::ssr::render_view(leptos::view! {
<crate::ssr::pages::admin::AdminAccessPolicyPanel workspace_name={workspace_name} is_admin=false />
});
let mut response = Html(format!(
r#"<!doctype html>
<html lang="zh-CN">
<head>
<meta charset="utf-8">
<title>授权管理</title>
<style>{}</style>
</head>
<body data-mnote-web-owner="mnote-web" data-mnote-shell="user-access-policy" data-mnote-actor-id="{}">
{}
</body>
</html>"#,
crate::ssr::MNOTE_CSS,
escape_html(context.auth.actor_id.as_str()),
content
))
.into_response();
let mut response = Response::builder()
.status(StatusCode::SEE_OTHER)
.header(header::LOCATION, "/user/ai#ai-admin-access")
.body(Body::empty())
.map_err(|error| WebError::internal(format!("授权管理跳转响应构造失败: {error}")))?;
stamp_gateway_headers(response.headers_mut(), false);
Ok(response)
}
@@ -285,6 +251,26 @@ pub async fn admin_ai_entry(
ai_management_response(&state, &context, true)
}
pub async fn settings_entry(
State(state): State<AppState>,
Extension(context): Extension<RequestContext>,
) -> Result<Response, WebError> {
if !has_real_auth_context(&state, &context) {
let mut response = Response::builder()
.status(StatusCode::SEE_OTHER)
.header(header::LOCATION, "/auth")
.body(Body::empty())
.map_err(|error| WebError::internal(format!("认证入口跳转响应构造失败: {error}")))?;
stamp_gateway_headers(response.headers_mut(), false);
return Ok(response);
}
ai_management_response(
&state,
&context,
is_local_access_policy_admin_context(&context),
)
}
pub async fn user_ai_entry(
State(state): State<AppState>,
Extension(context): Extension<RequestContext>,
@@ -313,7 +299,7 @@ fn ai_management_response(
is_admin={is_admin}
/>
});
let title = if is_admin { "AI 管理" } else { "AI 设置" };
let title = "MNote 设置";
let shell = if is_admin {
"admin-ai"
} else {
@@ -3144,10 +3130,11 @@ mod tests {
.expect("body");
let admin_html = String::from_utf8(admin_body.to_vec()).expect("utf8");
assert!(!admin_html.contains(r#"data-testid="mnote-admin-access-policy-entry""#));
assert!(!admin_html.contains(r#"data-testid="mnote-account-access-policy""#));
assert!(admin_html.contains(r#"data-mnote-action="open-account-menu""#));
assert!(admin_html.contains("/api/mnote-browser-runtime/sidebar-tree-runtime.js"));
assert!(admin_html.contains(r#"data-testid="mnote-admin-access-policy-template-admin""#));
assert!(admin_html.contains(r#"data-testid="mnote-admin-access-policy-template-user""#));
assert!(!admin_html.contains(r#"data-testid="mnote-admin-access-policy-template-admin""#));
assert!(!admin_html.contains(r#"data-testid="mnote-admin-access-policy-template-user""#));
let user_response =
app_with_query_fixtures("http://127.0.0.1:3100".into(), false, None, None)
@@ -3168,10 +3155,11 @@ mod tests {
.expect("body");
let user_html = String::from_utf8(user_body.to_vec()).expect("utf8");
assert!(!user_html.contains(r#"data-testid="mnote-admin-access-policy-entry""#));
assert!(!user_html.contains(r#"data-testid="mnote-account-access-policy""#));
assert!(user_html.contains(r#"data-mnote-action="open-account-menu""#));
assert!(user_html.contains("/api/mnote-browser-runtime/sidebar-tree-runtime.js"));
assert!(user_html.contains(r#"data-testid="mnote-admin-access-policy-template-admin""#));
assert!(user_html.contains(r#"data-testid="mnote-admin-access-policy-template-user""#));
assert!(!user_html.contains(r#"data-testid="mnote-admin-access-policy-template-admin""#));
assert!(!user_html.contains(r#"data-testid="mnote-admin-access-policy-template-user""#));
}
#[tokio::test]
@@ -3269,18 +3257,11 @@ mod tests {
.await
.expect("admin response");
assert_eq!(admin_response.status(), StatusCode::OK);
let body = to_bytes(admin_response.into_body(), usize::MAX)
.await
.expect("body");
let html = String::from_utf8(body.to_vec()).expect("utf8");
assert!(html.contains(r#"data-testid="mnote-admin-access-policy-page""#));
assert!(html.contains("文件夹授权"));
assert!(html.contains("管理员可以授权任意本地文件夹"));
assert!(html.contains(r#"data-testid="mnote-admin-create-share-grant-submit""#));
assert!(!html.contains(r#"data-testid="mnote-admin-validate-root-submit""#));
assert!(!html.contains(r#"data-testid="mnote-admin-create-grant-submit""#));
assert!(!html.contains(r#"data-testid="mnote-admin-delete-grant-submit""#));
assert_eq!(admin_response.status(), StatusCode::SEE_OTHER);
assert_eq!(
admin_response.headers().get(header::LOCATION).unwrap(),
"/admin/ai#ai-admin-access"
);
}
#[tokio::test]
@@ -3297,19 +3278,11 @@ mod tests {
.await
.expect("user access policy response");
assert_eq!(response.status(), StatusCode::OK);
let body = to_bytes(response.into_body(), usize::MAX)
.await
.expect("body");
let html = String::from_utf8(body.to_vec()).expect("utf8");
assert!(html.contains(r#"data-mnote-shell="user-access-policy""#));
assert!(html.contains("文件夹授权"));
assert!(html.contains("普通用户只能授权自己空间下的文件夹"));
assert!(html.contains(r#"data-testid="mnote-admin-create-share-grant-submit""#));
assert!(!html.contains("仅管理员可见"));
assert!(!html.contains(r#"data-testid="mnote-admin-validate-root-submit""#));
assert!(!html.contains(r#"data-testid="mnote-admin-create-grant-submit""#));
assert!(!html.contains(r#"data-testid="mnote-admin-delete-grant-submit""#));
assert_eq!(response.status(), StatusCode::SEE_OTHER);
assert_eq!(
response.headers().get(header::LOCATION).unwrap(),
"/user/ai#ai-admin-access"
);
}
#[tokio::test]