1
2
3
4
5
6
7
8
9
10
11
12
13
14
15
16
17
18
19
20
21
22
23
24
25
26
27
28
29
30
31
32
33
34
35
36
37
38
39
40
41
42
43
44
45
46
47
48
49
50
51
52
53
54
55
56
57
58
59
60
61
62
63
64
65
66
67
68
69
70
71
72
73
74
75
76
77
78
79
80
81
82
83
84
85
86
87
88
89
90
91
92
93
94
95
96
97
98
99
100
101
102
103
104
105
106
107
108
109
110
//! Trusted publishing configuration endpoints.
use super::CratesIoClient;
use super::error::Error;
use super::types::{GitHubConfig, GitLabConfig, NewGitHubConfig, NewGitLabConfig};
use super::wire::{
CreateGitHubConfigRequest, CreateGitLabConfigRequest, GitHubConfigResponse,
GitHubConfigsResponse, GitLabConfigResponse, GitLabConfigsResponse, OidcExchangeRequest,
OidcExchangeResponse,
};
impl CratesIoClient {
// ── GitHub configs ──────────────────────────────────────────────────
/// List all GitHub trusted publishing configs for the authenticated user.
///
/// Requires authentication.
pub async fn list_github_configs(&self) -> Result<Vec<GitHubConfig>, Error> {
let resp: GitHubConfigsResponse = self
.get_json_auth("/trusted_publishing/github_configs")
.await?;
Ok(resp.github_configs)
}
/// Create a new GitHub trusted publishing config.
///
/// Requires authentication.
pub async fn create_github_config(
&self,
config: NewGitHubConfig,
) -> Result<GitHubConfig, Error> {
let body = CreateGitHubConfigRequest {
github_config: config,
};
let resp: GitHubConfigResponse = self
.post_json("/trusted_publishing/github_configs", &body)
.await?;
Ok(resp.github_config)
}
/// Delete a GitHub trusted publishing config.
///
/// Requires authentication.
pub async fn delete_github_config(&self, id: u64) -> Result<(), Error> {
self.delete_ok(&format!("/trusted_publishing/github_configs/{id}"))
.await
}
// ── GitLab configs ──────────────────────────────────────────────────
/// List all GitLab trusted publishing configs for the authenticated user.
///
/// Requires authentication.
pub async fn list_gitlab_configs(&self) -> Result<Vec<GitLabConfig>, Error> {
let resp: GitLabConfigsResponse = self
.get_json_auth("/trusted_publishing/gitlab_configs")
.await?;
Ok(resp.gitlab_configs)
}
/// Create a new GitLab trusted publishing config.
///
/// Requires authentication.
pub async fn create_gitlab_config(
&self,
config: NewGitLabConfig,
) -> Result<GitLabConfig, Error> {
let body = CreateGitLabConfigRequest {
gitlab_config: config,
};
let resp: GitLabConfigResponse = self
.post_json("/trusted_publishing/gitlab_configs", &body)
.await?;
Ok(resp.gitlab_config)
}
/// Delete a GitLab trusted publishing config.
///
/// Requires authentication.
pub async fn delete_gitlab_config(&self, id: u64) -> Result<(), Error> {
self.delete_ok(&format!("/trusted_publishing/gitlab_configs/{id}"))
.await
}
// ── OIDC token exchange ─────────────────────────────────────────────
/// Exchange a CI OIDC JWT for a crates.io publish token.
///
/// This endpoint does not require a crates.io API token; the OIDC JWT
/// itself provides authentication.
pub async fn exchange_oidc_token(&self, jwt: &str) -> Result<String, Error> {
let body = OidcExchangeRequest {
jwt: jwt.to_string(),
};
let resp: OidcExchangeResponse = self
.post_json_unauth("/trusted_publishing/tokens", &body)
.await?;
Ok(resp.token)
}
/// Revoke the current temporary trusted-publishing access token.
///
/// Per the crates.io API this revokes the temporary token previously
/// obtained from [`exchange_oidc_token`](Self::exchange_oidc_token); the
/// endpoint takes no id and is authenticated by that temporary token
/// itself (not a regular crates.io API token).
pub async fn revoke_trusted_token(&self) -> Result<(), Error> {
self.delete_ok("/trusted_publishing/tokens").await
}
}