Skip to content

Commit bbb62d4

Browse files
committed
rust-sdk: use attributes instead of type name matching to detect principals
1 parent ba0a4a5 commit bbb62d4

20 files changed

Lines changed: 1105 additions & 921 deletions

File tree

Lines changed: 210 additions & 0 deletions
Original file line numberDiff line numberDiff line change
@@ -0,0 +1,210 @@
1+
// Copyright 2024-2026 Golem Cloud
2+
//
3+
// Licensed under the Golem Source License v1.1 (the "License");
4+
// you may not use this file except in compliance with the License.
5+
// You may obtain a copy of the License at
6+
//
7+
// http://license.golem.cloud/LICENSE
8+
//
9+
// Unless required by applicable law or agreed to in writing, software
10+
// distributed under the License is distributed on an "AS IS" BASIS,
11+
// WITHOUT WARRANTIES OR CONDITIONS OF ANY KIND, either express or implied.
12+
// See the License for the specific language governing permissions and
13+
// limitations under the License.
14+
15+
use crate::custom_api::http_test_context::{HttpTestContext, make_test_context};
16+
use golem_common::base_model::agent::AgentTypeName;
17+
use golem_common::base_model::http_api_deployment::HttpApiDeploymentAgentOptions;
18+
use golem_common::model::http_api_deployment::{
19+
HttpApiDeploymentAgentSecurity, TestSessionHeaderAgentSecurity,
20+
};
21+
use golem_test_framework::config::EnvBasedTestDependencies;
22+
use pretty_assertions::assert_eq;
23+
use serde_json::json;
24+
use test_r::test_dep;
25+
use test_r::{inherit_test_dep, test};
26+
27+
inherit_test_dep!(EnvBasedTestDependencies);
28+
29+
#[test_dep]
30+
async fn test_context(deps: &EnvBasedTestDependencies) -> HttpTestContext {
31+
make_test_context(
32+
deps,
33+
vec![(
34+
AgentTypeName("PrincipalAgent".to_string()),
35+
HttpApiDeploymentAgentOptions {
36+
security: Some(HttpApiDeploymentAgentSecurity::TestSessionHeader(
37+
TestSessionHeaderAgentSecurity {
38+
header_name: "x-golem-test-session".to_string(),
39+
},
40+
)),
41+
},
42+
)],
43+
"golem_it_agent_sdk_rust_release",
44+
"golem-it:agent-sdk-rust",
45+
)
46+
.await
47+
.unwrap()
48+
}
49+
50+
#[test]
51+
#[tracing::instrument]
52+
async fn principal_auto_injection(agent: &HttpTestContext) -> anyhow::Result<()> {
53+
let response = agent
54+
.client
55+
.get(
56+
agent
57+
.base_url
58+
.join("/principal-agent/test-agent/echo-principal")?,
59+
)
60+
.send()
61+
.await?;
62+
63+
assert_eq!(response.status(), reqwest::StatusCode::OK);
64+
65+
let body: serde_json::Value = response.json().await?;
66+
assert_eq!(body, json!({ "value": {"anonymous": null} }));
67+
68+
Ok(())
69+
}
70+
71+
#[test]
72+
#[tracing::instrument]
73+
async fn principal_auto_injection_middle_segment(agent: &HttpTestContext) -> anyhow::Result<()> {
74+
let response = agent
75+
.client
76+
.get(
77+
agent
78+
.base_url
79+
.join("/principal-agent/test-agent/echo-principal-mid/foo-value/1")?,
80+
)
81+
.send()
82+
.await?;
83+
84+
let body: serde_json::Value = response.json().await?;
85+
86+
assert_eq!(
87+
body,
88+
json!({ "value": {"anonymous": null}, "foo": "foo-value", "bar": 1 })
89+
);
90+
91+
Ok(())
92+
}
93+
94+
#[test]
95+
#[tracing::instrument]
96+
async fn principal_auto_injection_last_segment(agent: &HttpTestContext) -> anyhow::Result<()> {
97+
let response = agent
98+
.client
99+
.get(
100+
agent
101+
.base_url
102+
.join("/principal-agent/test-agent/echo-principal-last/foo-value/2")?,
103+
)
104+
.send()
105+
.await?;
106+
107+
let body: serde_json::Value = response.json().await?;
108+
109+
assert_eq!(
110+
body,
111+
json!({ "value": {"anonymous": null}, "foo": "foo-value", "bar": 2 })
112+
);
113+
114+
Ok(())
115+
}
116+
117+
#[test]
118+
#[tracing::instrument]
119+
async fn default_test_header_oidc_principal(agent: &HttpTestContext) -> anyhow::Result<()> {
120+
let response = agent
121+
.client
122+
.get(
123+
agent
124+
.base_url
125+
.join("/principal-agent/test-agent/authed-principal")?,
126+
)
127+
.header("x-golem-test-session", "{}")
128+
.send()
129+
.await?;
130+
131+
let mut body: serde_json::Value = response.json().await?;
132+
// claims include exp, which is not deterministic in tests
133+
if let Some(oidc) = body
134+
.get_mut("value")
135+
.and_then(|v| v.get_mut("oidc"))
136+
.and_then(|v| v.as_object_mut())
137+
{
138+
oidc.remove("claims");
139+
}
140+
141+
assert_eq!(
142+
body,
143+
json!({
144+
"value": {
145+
"oidc": {
146+
"email": null,
147+
"email_verified": null,
148+
"family_name": null,
149+
"given_name": null,
150+
"issuer": "http://test-idp.com",
151+
"name": null,
152+
"picture": null,
153+
"preferred_username": null,
154+
"sub": "test-user",
155+
}
156+
}
157+
})
158+
);
159+
160+
Ok(())
161+
}
162+
163+
#[test]
164+
#[tracing::instrument]
165+
async fn test_header_oidc_principal_with_overrides(agent: &HttpTestContext) -> anyhow::Result<()> {
166+
let response = agent
167+
.client
168+
.get(
169+
agent
170+
.base_url
171+
.join("/principal-agent/test-agent/authed-principal")?,
172+
)
173+
.header(
174+
"x-golem-test-session",
175+
"{ \"subject\": \"bob\", \"email\": \"bob@golem.cloud\"}",
176+
)
177+
.send()
178+
.await?;
179+
180+
let mut body: serde_json::Value = response.json().await?;
181+
// claims include exp, which is not deterministic in tests
182+
if let Some(oidc) = body
183+
.get_mut("value")
184+
.and_then(|v| v.get_mut("oidc"))
185+
.and_then(|v| v.as_object_mut())
186+
{
187+
oidc.remove("claims");
188+
}
189+
190+
assert_eq!(
191+
body,
192+
json!({
193+
"value": {
194+
"oidc": {
195+
"email": "bob@golem.cloud",
196+
"email_verified": null,
197+
"family_name": null,
198+
"given_name": null,
199+
"issuer": "http://test-idp.com",
200+
"name": null,
201+
"picture": null,
202+
"preferred_username": null,
203+
"sub": "bob",
204+
}
205+
}
206+
})
207+
);
208+
209+
Ok(())
210+
}

integration-tests/tests/custom_api/mod.rs

Lines changed: 1 addition & 0 deletions
Original file line numberDiff line numberDiff line change
@@ -12,6 +12,7 @@
1212
// See the License for the specific language governing permissions and
1313
// limitations under the License.
1414

15+
mod agent_http_principal_rust;
1516
mod agent_http_principal_ts;
1617
mod agent_http_routes_rust;
1718
mod agent_http_routes_ts;

sdks/rust/Cargo.lock

Lines changed: 3 additions & 1 deletion
Some generated files are not rendered by default. Learn more about customizing how changed files appear on GitHub.

0 commit comments

Comments
 (0)