feat: Add role-aware plugin share context APIs (#21867)

Expose discoverability and full share principals in share context, carry
roles through save/updateTargets, hydrate local shared plugin reads, and
keep share URLs only under plugin.shareContext.
This commit is contained in:
xl-openai
2026-05-08 20:46:39 -07:00
committed by GitHub
parent c579da41b1
commit 479491ed89
25 changed files with 826 additions and 221 deletions

View File

@@ -259,7 +259,6 @@ pub struct PluginShareDeleteResponse {}
#[ts(export_to = "v2/")]
pub struct PluginShareListItem {
pub plugin: PluginSummary,
pub share_url: String,
pub local_plugin_path: Option<AbsolutePathBuf>,
}
@@ -308,6 +307,7 @@ pub enum PluginSharePrincipalType {
pub struct PluginShareTarget {
pub principal_type: PluginSharePrincipalType,
pub principal_id: String,
pub role: PluginShareTargetRole,
}
#[derive(Serialize, Deserialize, Debug, Clone, PartialEq, Eq, JsonSchema, TS)]
@@ -316,9 +316,29 @@ pub struct PluginShareTarget {
pub struct PluginSharePrincipal {
pub principal_type: PluginSharePrincipalType,
pub principal_id: String,
pub role: PluginSharePrincipalRole,
pub name: String,
}
#[derive(Serialize, Deserialize, Debug, Clone, Copy, PartialEq, Eq, JsonSchema, TS)]
#[serde(rename_all = "lowercase")]
#[ts(rename_all = "lowercase")]
#[ts(export_to = "v2/")]
pub enum PluginShareTargetRole {
Reader,
Editor,
}
#[derive(Serialize, Deserialize, Debug, Clone, Copy, PartialEq, Eq, JsonSchema, TS)]
#[serde(rename_all = "lowercase")]
#[ts(rename_all = "lowercase")]
#[ts(export_to = "v2/")]
pub enum PluginSharePrincipalRole {
Reader,
Editor,
Owner,
}
#[derive(Serialize, Deserialize, Debug, Clone, Copy, PartialEq, Eq, JsonSchema, TS)]
#[serde(rename_all = "snake_case")]
#[ts(rename_all = "snake_case")]
@@ -539,10 +559,11 @@ pub struct PluginSummary {
#[ts(export_to = "v2/")]
pub struct PluginShareContext {
pub remote_plugin_id: String,
pub discoverability: Option<PluginShareDiscoverability>,
pub share_url: Option<String>,
pub creator_account_user_id: Option<String>,
pub creator_name: Option<String>,
pub share_targets: Option<Vec<PluginSharePrincipal>>,
pub share_principals: Option<Vec<PluginSharePrincipal>>,
}
#[derive(Serialize, Deserialize, Debug, Clone, PartialEq, JsonSchema, TS)]

View File

@@ -2896,10 +2896,12 @@ fn plugin_share_params_and_response_serialization_use_camel_case_fields() {
PluginShareTarget {
principal_type: PluginSharePrincipalType::User,
principal_id: "user-1".to_string(),
role: PluginShareTargetRole::Reader,
},
PluginShareTarget {
principal_type: PluginSharePrincipalType::Workspace,
principal_id: "workspace-1".to_string(),
principal_type: PluginSharePrincipalType::Group,
principal_id: "group-1".to_string(),
role: PluginShareTargetRole::Reader,
},
]),
})
@@ -2912,10 +2914,12 @@ fn plugin_share_params_and_response_serialization_use_camel_case_fields() {
{
"principalType": "user",
"principalId": "user-1",
"role": "reader",
},
{
"principalType": "workspace",
"principalId": "workspace-1",
"principalType": "group",
"principalId": "group-1",
"role": "reader",
},
],
}),
@@ -2940,6 +2944,7 @@ fn plugin_share_params_and_response_serialization_use_camel_case_fields() {
share_targets: vec![PluginShareTarget {
principal_type: PluginSharePrincipalType::Group,
principal_id: "group-1".to_string(),
role: PluginShareTargetRole::Editor,
}],
})
.unwrap(),
@@ -2949,6 +2954,7 @@ fn plugin_share_params_and_response_serialization_use_camel_case_fields() {
"shareTargets": [{
"principalType": "group",
"principalId": "group-1",
"role": "editor",
}],
}),
);
@@ -2958,6 +2964,7 @@ fn plugin_share_params_and_response_serialization_use_camel_case_fields() {
principals: vec![PluginSharePrincipal {
principal_type: PluginSharePrincipalType::User,
principal_id: "user-1".to_string(),
role: PluginSharePrincipalRole::Owner,
name: "Gavin".to_string(),
}],
discoverability: PluginShareDiscoverability::Unlisted,
@@ -2967,6 +2974,7 @@ fn plugin_share_params_and_response_serialization_use_camel_case_fields() {
"principals": [{
"principalType": "user",
"principalId": "user-1",
"role": "owner",
"name": "Gavin",
}],
"discoverability": "UNLISTED",
@@ -3007,7 +3015,6 @@ fn plugin_share_list_response_serializes_share_items() {
interface: None,
keywords: Vec::new(),
},
share_url: "https://chatgpt.example/plugins/share/share-key-1".to_string(),
local_plugin_path: None,
}],
})
@@ -3027,7 +3034,6 @@ fn plugin_share_list_response_serializes_share_items() {
"interface": null,
"keywords": [],
},
"shareUrl": "https://chatgpt.example/plugins/share/share-key-1",
"localPluginPath": null,
}],
}),