AGC 作者预览切到 owner 媒体读路由
- resolve_preview_url 改走 /api/game-distribution/my-games/{gameId}/media/read-url,不再走素材库 /api/assets/read-url
- 新增 owner_media_read_url,复用 endpoint 的路径段转义并编码 objectKey
- 新增路由与编码单测,钉住不再回退素材库 ACL
This commit is contained in:
@@ -585,11 +585,27 @@ fn clear_publication_binding(root: &Path) {
|
||||
});
|
||||
}
|
||||
|
||||
fn asset_read_url(api_base_url: &str, object_key: &str) -> Result<String, String> {
|
||||
let mut url = Url::parse(&format!(
|
||||
"{}/api/assets/read-url",
|
||||
api_base_url.trim_end_matches('/')
|
||||
))
|
||||
/// owner 作用域媒体读地址:`/api/game-distribution/my-games/{gameId}/media/read-url`。
|
||||
///
|
||||
/// 不能再走 `/api/assets/read-url`:发布媒体是项目快照桶对象、不建 `asset_object`,素材库 ACL
|
||||
/// 不会给它授权;owner 路由按「objectKey 命中调用者自己作品当前行的媒体」放行,未发布 / 被驳回
|
||||
/// 的封面与截图也能预览。
|
||||
fn owner_media_read_url(
|
||||
snapshot: &PlatformSessionSnapshot,
|
||||
game_id: &str,
|
||||
object_key: &str,
|
||||
) -> Result<String, String> {
|
||||
let mut url = Url::parse(&endpoint(
|
||||
snapshot,
|
||||
&[
|
||||
"api",
|
||||
"game-distribution",
|
||||
"my-games",
|
||||
game_id,
|
||||
"media",
|
||||
"read-url",
|
||||
],
|
||||
)?)
|
||||
.map_err(|_| "陶泥儿服务地址无效".to_string())?;
|
||||
url.query_pairs_mut().append_pair("objectKey", object_key);
|
||||
Ok(url.to_string())
|
||||
@@ -599,13 +615,14 @@ fn asset_read_url(api_base_url: &str, object_key: &str) -> Result<String, String
|
||||
async fn resolve_preview_url(
|
||||
client: &reqwest::Client,
|
||||
snapshot: &PlatformSessionSnapshot,
|
||||
game_id: &str,
|
||||
object_key: Option<&str>,
|
||||
) -> Option<String> {
|
||||
let object_key = object_key?.trim();
|
||||
if object_key.is_empty() {
|
||||
return None;
|
||||
}
|
||||
let read_url = asset_read_url(&snapshot.api_base_url, object_key).ok()?;
|
||||
let read_url = owner_media_read_url(snapshot, game_id, object_key).ok()?;
|
||||
match crate::assets::resolve_external_asset_signed_url(
|
||||
client,
|
||||
snapshot.access_token.as_str(),
|
||||
@@ -797,7 +814,13 @@ async fn build_publication_draft(
|
||||
let cover = if cover_asset_id.is_some() || cover_object_key.is_some() {
|
||||
Some(GameDistributionPublicationImageDraft {
|
||||
asset_id: normalize_asset_id(cover_asset_id),
|
||||
preview_url: resolve_preview_url(client, snapshot, cover_object_key.as_deref()).await,
|
||||
preview_url: resolve_preview_url(
|
||||
client,
|
||||
snapshot,
|
||||
entry.id.as_str(),
|
||||
cover_object_key.as_deref(),
|
||||
)
|
||||
.await,
|
||||
})
|
||||
} else {
|
||||
None
|
||||
@@ -806,7 +829,13 @@ async fn build_publication_draft(
|
||||
for (asset_id, object_key) in screenshots {
|
||||
screenshot_drafts.push(GameDistributionPublicationImageDraft {
|
||||
asset_id: normalize_asset_id(asset_id),
|
||||
preview_url: resolve_preview_url(client, snapshot, object_key.as_deref()).await,
|
||||
preview_url: resolve_preview_url(
|
||||
client,
|
||||
snapshot,
|
||||
entry.id.as_str(),
|
||||
object_key.as_deref(),
|
||||
)
|
||||
.await,
|
||||
});
|
||||
}
|
||||
GameDistributionPublicationDraft {
|
||||
@@ -1499,6 +1528,33 @@ mod tests {
|
||||
assert!(endpoint(&snapshot, &["api", "bad?query"]).is_err());
|
||||
}
|
||||
|
||||
#[test]
|
||||
fn owner_media_read_url_targets_owner_route_and_encodes_object_key() {
|
||||
let snapshot = PlatformSessionSnapshot {
|
||||
user_id: "user-1".to_string(),
|
||||
access_token: "token".to_string(),
|
||||
api_base_url: "https://dev.genarrative.world".to_string(),
|
||||
identity_generation: 1,
|
||||
revision: 1,
|
||||
};
|
||||
let url = owner_media_read_url(
|
||||
&snapshot,
|
||||
"game-1",
|
||||
"agc/project-snapshots/v1/game-distribution/media/game-1/cover-1.png",
|
||||
)
|
||||
.expect("owner media read url");
|
||||
assert!(url.starts_with(
|
||||
"https://dev.genarrative.world/api/game-distribution/my-games/game-1/media/read-url?"
|
||||
));
|
||||
assert!(
|
||||
url.contains("objectKey=agc%2Fproject-snapshots%2Fv1%2F"),
|
||||
"objectKey 必须按查询参数编码:{url}"
|
||||
);
|
||||
// 作者预览不再回退到素材库 ACL 路由:发布媒体不是 asset_object。
|
||||
assert!(!url.contains("/api/assets/read-url"));
|
||||
assert!(owner_media_read_url(&snapshot, "bad/id", "cover.png").is_err());
|
||||
}
|
||||
|
||||
#[test]
|
||||
fn response_data_unwraps_v1_envelope_and_legacy_payload() {
|
||||
assert_eq!(
|
||||
|
||||
Reference in New Issue
Block a user