mirror of
https://github.com/kanidm/kanidm.git
synced 2025-02-23 04:27:02 +01:00
error handling and web server logging fixes (#1960)
* Fixing the setup_dev_environment script * clippy calming * handle_internalunixusertokenread throwing 500's without context Fixes #1958
This commit is contained in:
parent
aba9f6a724
commit
83f189fed3
|
@ -204,7 +204,7 @@ impl KanidmClientBuilder {
|
||||||
let verify_ca = kcc.verify_ca.unwrap_or(verify_ca);
|
let verify_ca = kcc.verify_ca.unwrap_or(verify_ca);
|
||||||
let verify_hostnames = kcc.verify_hostnames.unwrap_or(verify_hostnames);
|
let verify_hostnames = kcc.verify_hostnames.unwrap_or(verify_hostnames);
|
||||||
let ca = match kcc.ca_path {
|
let ca = match kcc.ca_path {
|
||||||
Some(ca_path) => Some(Self::parse_certificate(ca_path.as_str())?),
|
Some(ca_path) => Some(Self::parse_certificate(&ca_path)?),
|
||||||
None => ca,
|
None => ca,
|
||||||
};
|
};
|
||||||
|
|
||||||
|
@ -271,7 +271,7 @@ impl KanidmClientBuilder {
|
||||||
ClientError::ConfigParseIssue(format!("{:?}", e))
|
ClientError::ConfigParseIssue(format!("{:?}", e))
|
||||||
})?;
|
})?;
|
||||||
|
|
||||||
let config: KanidmClientConfig = toml::from_str(contents.as_str()).map_err(|e| {
|
let config: KanidmClientConfig = toml::from_str(&contents).map_err(|e| {
|
||||||
error!("{:?}", e);
|
error!("{:?}", e);
|
||||||
ClientError::ConfigParseIssue(format!("{:?}", e))
|
ClientError::ConfigParseIssue(format!("{:?}", e))
|
||||||
})?;
|
})?;
|
||||||
|
@ -396,7 +396,7 @@ impl KanidmClientBuilder {
|
||||||
}
|
}
|
||||||
};
|
};
|
||||||
|
|
||||||
self.display_warnings(address.as_str());
|
self.display_warnings(&address);
|
||||||
|
|
||||||
let client_builder = reqwest::Client::builder()
|
let client_builder = reqwest::Client::builder()
|
||||||
.user_agent(KanidmClientBuilder::user_agent())
|
.user_agent(KanidmClientBuilder::user_agent())
|
||||||
|
@ -442,13 +442,49 @@ impl KanidmClientBuilder {
|
||||||
}
|
}
|
||||||
}
|
}
|
||||||
|
|
||||||
|
#[test]
|
||||||
|
fn test_make_url() {
|
||||||
|
let client: KanidmClient = KanidmClientBuilder::new()
|
||||||
|
.address("https://localhost:8080".to_string())
|
||||||
|
.build()
|
||||||
|
.unwrap();
|
||||||
|
assert_eq!(
|
||||||
|
client.get_url(),
|
||||||
|
Url::parse("https://localhost:8080").unwrap()
|
||||||
|
);
|
||||||
|
assert_eq!(
|
||||||
|
client.make_url("/hello"),
|
||||||
|
Url::parse("https://localhost:8080/hello").unwrap()
|
||||||
|
);
|
||||||
|
|
||||||
|
let client: KanidmClient = KanidmClientBuilder::new()
|
||||||
|
.address("https://localhost:8080/cheese/".to_string())
|
||||||
|
.build()
|
||||||
|
.unwrap();
|
||||||
|
assert_eq!(
|
||||||
|
client.make_url("hello"),
|
||||||
|
Url::parse("https://localhost:8080/cheese/hello").unwrap()
|
||||||
|
);
|
||||||
|
}
|
||||||
|
|
||||||
impl KanidmClient {
|
impl KanidmClient {
|
||||||
pub fn get_origin(&self) -> &Url {
|
pub fn get_origin(&self) -> &Url {
|
||||||
&self.origin
|
&self.origin
|
||||||
}
|
}
|
||||||
|
|
||||||
pub fn get_url(&self) -> &str {
|
/// Returns the base URL of the server
|
||||||
self.addr.as_str()
|
pub fn get_url(&self) -> Url {
|
||||||
|
#[allow(clippy::panic)]
|
||||||
|
match self.addr.parse::<Url>() {
|
||||||
|
Ok(val) => val,
|
||||||
|
Err(err) => panic!("Failed to parse {} into URL: {:?}", self.addr, err),
|
||||||
|
}
|
||||||
|
}
|
||||||
|
|
||||||
|
/// Get a URL based on adding an endpoint to the base URL of the server
|
||||||
|
pub fn make_url(&self, endpoint: &str) -> Url {
|
||||||
|
#[allow(clippy::expect_used)]
|
||||||
|
self.get_url().join(endpoint).expect("Failed to join URL")
|
||||||
}
|
}
|
||||||
|
|
||||||
pub async fn set_token(&self, new_token: String) {
|
pub async fn set_token(&self, new_token: String) {
|
||||||
|
@ -474,6 +510,7 @@ impl KanidmClient {
|
||||||
Ok(())
|
Ok(())
|
||||||
}
|
}
|
||||||
|
|
||||||
|
/// Check that we're getting the right version back from the server.
|
||||||
async fn expect_version(&self, response: &reqwest::Response) {
|
async fn expect_version(&self, response: &reqwest::Response) {
|
||||||
let mut guard = self.check_version.lock().await;
|
let mut guard = self.check_version.lock().await;
|
||||||
|
|
||||||
|
@ -508,13 +545,11 @@ impl KanidmClient {
|
||||||
dest: &str,
|
dest: &str,
|
||||||
request: &R,
|
request: &R,
|
||||||
) -> Result<T, ClientError> {
|
) -> Result<T, ClientError> {
|
||||||
let dest = format!("{}{}", self.get_url(), dest);
|
|
||||||
|
|
||||||
let req_string = serde_json::to_string(request).map_err(ClientError::JsonEncode)?;
|
let req_string = serde_json::to_string(request).map_err(ClientError::JsonEncode)?;
|
||||||
|
|
||||||
let response = self
|
let response = self
|
||||||
.client
|
.client
|
||||||
.post(dest.as_str())
|
.post(self.make_url(dest))
|
||||||
.body(req_string)
|
.body(req_string)
|
||||||
.header(CONTENT_TYPE, APPLICATION_JSON);
|
.header(CONTENT_TYPE, APPLICATION_JSON);
|
||||||
|
|
||||||
|
@ -552,13 +587,12 @@ impl KanidmClient {
|
||||||
dest: &str,
|
dest: &str,
|
||||||
request: R,
|
request: R,
|
||||||
) -> Result<T, ClientError> {
|
) -> Result<T, ClientError> {
|
||||||
let dest = format!("{}{}", self.get_url(), dest);
|
|
||||||
trace!("perform_auth_post_request connecting to {}", dest);
|
trace!("perform_auth_post_request connecting to {}", dest);
|
||||||
let req_string = serde_json::to_string(&request).map_err(ClientError::JsonEncode)?;
|
let req_string = serde_json::to_string(&request).map_err(ClientError::JsonEncode)?;
|
||||||
|
|
||||||
let response = self
|
let response = self
|
||||||
.client
|
.client
|
||||||
.post(dest.as_str())
|
.post(self.make_url(dest))
|
||||||
.body(req_string)
|
.body(req_string)
|
||||||
.header(CONTENT_TYPE, APPLICATION_JSON);
|
.header(CONTENT_TYPE, APPLICATION_JSON);
|
||||||
|
|
||||||
|
@ -626,12 +660,10 @@ impl KanidmClient {
|
||||||
dest: &str,
|
dest: &str,
|
||||||
request: R,
|
request: R,
|
||||||
) -> Result<T, ClientError> {
|
) -> Result<T, ClientError> {
|
||||||
let dest = format!("{}{}", self.get_url(), dest);
|
|
||||||
|
|
||||||
let req_string = serde_json::to_string(&request).map_err(ClientError::JsonEncode)?;
|
let req_string = serde_json::to_string(&request).map_err(ClientError::JsonEncode)?;
|
||||||
let response = self
|
let response = self
|
||||||
.client
|
.client
|
||||||
.post(dest.as_str())
|
.post(self.make_url(dest))
|
||||||
.body(req_string)
|
.body(req_string)
|
||||||
.header(CONTENT_TYPE, APPLICATION_JSON);
|
.header(CONTENT_TYPE, APPLICATION_JSON);
|
||||||
|
|
||||||
|
@ -678,13 +710,11 @@ impl KanidmClient {
|
||||||
dest: &str,
|
dest: &str,
|
||||||
request: R,
|
request: R,
|
||||||
) -> Result<T, ClientError> {
|
) -> Result<T, ClientError> {
|
||||||
let dest = format!("{}{}", self.get_url(), dest);
|
|
||||||
|
|
||||||
let req_string = serde_json::to_string(&request).map_err(ClientError::JsonEncode)?;
|
let req_string = serde_json::to_string(&request).map_err(ClientError::JsonEncode)?;
|
||||||
|
|
||||||
let response = self
|
let response = self
|
||||||
.client
|
.client
|
||||||
.put(dest.as_str())
|
.put(self.make_url(dest))
|
||||||
.header(CONTENT_TYPE, APPLICATION_JSON);
|
.header(CONTENT_TYPE, APPLICATION_JSON);
|
||||||
let response = {
|
let response = {
|
||||||
let tguard = self.bearer_token.read().await;
|
let tguard = self.bearer_token.read().await;
|
||||||
|
@ -734,12 +764,10 @@ impl KanidmClient {
|
||||||
dest: &str,
|
dest: &str,
|
||||||
request: R,
|
request: R,
|
||||||
) -> Result<T, ClientError> {
|
) -> Result<T, ClientError> {
|
||||||
let dest = format!("{}{}", self.get_url(), dest);
|
|
||||||
|
|
||||||
let req_string = serde_json::to_string(&request).map_err(ClientError::JsonEncode)?;
|
let req_string = serde_json::to_string(&request).map_err(ClientError::JsonEncode)?;
|
||||||
let response = self
|
let response = self
|
||||||
.client
|
.client
|
||||||
.patch(dest.as_str())
|
.patch(self.make_url(dest))
|
||||||
.body(req_string)
|
.body(req_string)
|
||||||
.header(CONTENT_TYPE, APPLICATION_JSON);
|
.header(CONTENT_TYPE, APPLICATION_JSON);
|
||||||
|
|
||||||
|
@ -782,10 +810,11 @@ impl KanidmClient {
|
||||||
}
|
}
|
||||||
|
|
||||||
#[instrument(level = "debug", skip(self))]
|
#[instrument(level = "debug", skip(self))]
|
||||||
async fn perform_get_request<T: DeserializeOwned>(&self, dest: &str) -> Result<T, ClientError> {
|
pub async fn perform_get_request<T: DeserializeOwned>(
|
||||||
let dest = format!("{}{}", self.get_url(), dest);
|
&self,
|
||||||
let response = self.client.get(dest.as_str());
|
dest: &str,
|
||||||
|
) -> Result<T, ClientError> {
|
||||||
|
let response = self.client.get(self.make_url(dest));
|
||||||
let response = {
|
let response = {
|
||||||
let tguard = self.bearer_token.read().await;
|
let tguard = self.bearer_token.read().await;
|
||||||
if let Some(token) = &(*tguard) {
|
if let Some(token) = &(*tguard) {
|
||||||
|
@ -826,11 +855,9 @@ impl KanidmClient {
|
||||||
}
|
}
|
||||||
|
|
||||||
async fn perform_delete_request(&self, dest: &str) -> Result<(), ClientError> {
|
async fn perform_delete_request(&self, dest: &str) -> Result<(), ClientError> {
|
||||||
let dest = format!("{}{}", self.get_url(), dest);
|
|
||||||
|
|
||||||
let response = self
|
let response = self
|
||||||
.client
|
.client
|
||||||
.delete(dest.as_str())
|
.delete(self.make_url(dest))
|
||||||
.header(CONTENT_TYPE, APPLICATION_JSON);
|
.header(CONTENT_TYPE, APPLICATION_JSON);
|
||||||
|
|
||||||
let response = {
|
let response = {
|
||||||
|
@ -876,12 +903,10 @@ impl KanidmClient {
|
||||||
dest: &str,
|
dest: &str,
|
||||||
request: R,
|
request: R,
|
||||||
) -> Result<(), ClientError> {
|
) -> Result<(), ClientError> {
|
||||||
let dest = format!("{}{}", self.get_url(), dest);
|
|
||||||
|
|
||||||
let req_string = serde_json::to_string(&request).map_err(ClientError::JsonEncode)?;
|
let req_string = serde_json::to_string(&request).map_err(ClientError::JsonEncode)?;
|
||||||
let response = self
|
let response = self
|
||||||
.client
|
.client
|
||||||
.delete(dest.as_str())
|
.delete(self.make_url(dest))
|
||||||
.body(req_string)
|
.body(req_string)
|
||||||
.header(CONTENT_TYPE, APPLICATION_JSON);
|
.header(CONTENT_TYPE, APPLICATION_JSON);
|
||||||
|
|
||||||
|
@ -1352,10 +1377,7 @@ impl KanidmClient {
|
||||||
}
|
}
|
||||||
|
|
||||||
pub async fn whoami(&self) -> Result<Option<Entry>, ClientError> {
|
pub async fn whoami(&self) -> Result<Option<Entry>, ClientError> {
|
||||||
let whoami_dest = [self.addr.as_str(), "/v1/self"].concat();
|
let response = self.client.get(self.make_url("/v1/self"));
|
||||||
// format!("{}/v1/self", self.addr);
|
|
||||||
debug!("{:?}", whoami_dest);
|
|
||||||
let response = self.client.get(whoami_dest.as_str());
|
|
||||||
|
|
||||||
let response = {
|
let response = {
|
||||||
let tguard = self.bearer_token.read().await;
|
let tguard = self.bearer_token.read().await;
|
||||||
|
@ -1429,15 +1451,14 @@ impl KanidmClient {
|
||||||
}
|
}
|
||||||
|
|
||||||
pub async fn idm_group_get(&self, id: &str) -> Result<Option<Entry>, ClientError> {
|
pub async fn idm_group_get(&self, id: &str) -> Result<Option<Entry>, ClientError> {
|
||||||
self.perform_get_request(format!("/v1/group/{}", id).as_str())
|
self.perform_get_request(&format!("/v1/group/{}", id)).await
|
||||||
.await
|
|
||||||
}
|
}
|
||||||
|
|
||||||
pub async fn idm_group_get_members(
|
pub async fn idm_group_get_members(
|
||||||
&self,
|
&self,
|
||||||
id: &str,
|
id: &str,
|
||||||
) -> Result<Option<Vec<String>>, ClientError> {
|
) -> Result<Option<Vec<String>>, ClientError> {
|
||||||
self.perform_get_request(format!("/v1/group/{}/_attr/member", id).as_str())
|
self.perform_get_request(&format!("/v1/group/{}/_attr/member", id))
|
||||||
.await
|
.await
|
||||||
}
|
}
|
||||||
|
|
||||||
|
@ -1457,7 +1478,7 @@ impl KanidmClient {
|
||||||
members: &[&str],
|
members: &[&str],
|
||||||
) -> Result<(), ClientError> {
|
) -> Result<(), ClientError> {
|
||||||
let m: Vec<_> = members.iter().map(|v| (*v).to_string()).collect();
|
let m: Vec<_> = members.iter().map(|v| (*v).to_string()).collect();
|
||||||
self.perform_put_request(format!("/v1/group/{}/_attr/member", id).as_str(), m)
|
self.perform_put_request(&format!("/v1/group/{}/_attr/member", id), m)
|
||||||
.await
|
.await
|
||||||
}
|
}
|
||||||
|
|
||||||
|
@ -1467,7 +1488,7 @@ impl KanidmClient {
|
||||||
members: &[&str],
|
members: &[&str],
|
||||||
) -> Result<(), ClientError> {
|
) -> Result<(), ClientError> {
|
||||||
let m: Vec<_> = members.iter().map(|v| (*v).to_string()).collect();
|
let m: Vec<_> = members.iter().map(|v| (*v).to_string()).collect();
|
||||||
self.perform_post_request(["/v1/group/", id, "/_attr/member"].concat().as_str(), m)
|
self.perform_post_request(&format!("/v1/group/{}/_attr/member", id), m)
|
||||||
.await
|
.await
|
||||||
}
|
}
|
||||||
|
|
||||||
|
@ -1477,24 +1498,19 @@ impl KanidmClient {
|
||||||
members: &[&str],
|
members: &[&str],
|
||||||
) -> Result<(), ClientError> {
|
) -> Result<(), ClientError> {
|
||||||
debug!(
|
debug!(
|
||||||
"{}",
|
"Asked to remove members {} from {}",
|
||||||
&[
|
&members.join(","),
|
||||||
"Asked to remove members ",
|
group
|
||||||
&members.join(","),
|
|
||||||
" from ",
|
|
||||||
group
|
|
||||||
]
|
|
||||||
.concat()
|
|
||||||
);
|
);
|
||||||
self.perform_delete_request_with_body(
|
self.perform_delete_request_with_body(
|
||||||
["/v1/group/", group, "/_attr/member"].concat().as_str(),
|
&format!("/v1/group/{}/_attr/member", group),
|
||||||
&members,
|
&members,
|
||||||
)
|
)
|
||||||
.await
|
.await
|
||||||
}
|
}
|
||||||
|
|
||||||
pub async fn idm_group_purge_members(&self, id: &str) -> Result<(), ClientError> {
|
pub async fn idm_group_purge_members(&self, id: &str) -> Result<(), ClientError> {
|
||||||
self.perform_delete_request(format!("/v1/group/{}/_attr/member", id).as_str())
|
self.perform_delete_request(&format!("/v1/group/{}/_attr/member", id))
|
||||||
.await
|
.await
|
||||||
}
|
}
|
||||||
|
|
||||||
|
@ -1504,26 +1520,24 @@ impl KanidmClient {
|
||||||
gidnumber: Option<u32>,
|
gidnumber: Option<u32>,
|
||||||
) -> Result<(), ClientError> {
|
) -> Result<(), ClientError> {
|
||||||
let gx = GroupUnixExtend { gidnumber };
|
let gx = GroupUnixExtend { gidnumber };
|
||||||
self.perform_post_request(format!("/v1/group/{}/_unix", id).as_str(), gx)
|
self.perform_post_request(&format!("/v1/group/{}/_unix", id), gx)
|
||||||
.await
|
.await
|
||||||
}
|
}
|
||||||
|
|
||||||
pub async fn idm_group_unix_token_get(&self, id: &str) -> Result<UnixGroupToken, ClientError> {
|
pub async fn idm_group_unix_token_get(&self, id: &str) -> Result<UnixGroupToken, ClientError> {
|
||||||
self.perform_get_request(["/v1/group/", id, "/_unix/_token"].concat().as_str())
|
self.perform_get_request(&format!("/v1/group/{}/_unix/_token", id))
|
||||||
.await
|
.await
|
||||||
}
|
}
|
||||||
|
|
||||||
pub async fn idm_group_delete(&self, id: &str) -> Result<(), ClientError> {
|
pub async fn idm_group_delete(&self, id: &str) -> Result<(), ClientError> {
|
||||||
self.perform_delete_request(["/v1/group/", id].concat().as_str())
|
self.perform_delete_request(&format!("/v1/group/{}", id))
|
||||||
.await
|
.await
|
||||||
}
|
}
|
||||||
|
|
||||||
// ==== ACCOUNTS
|
// ==== ACCOUNTS
|
||||||
|
|
||||||
pub async fn idm_account_unix_token_get(&self, id: &str) -> Result<UnixUserToken, ClientError> {
|
pub async fn idm_account_unix_token_get(&self, id: &str) -> Result<UnixUserToken, ClientError> {
|
||||||
// Format doesn't work in async
|
self.perform_get_request(&format!("/v1/account/{}/_unix/_token", id))
|
||||||
// format!("/v1/account/{}/_unix/_token", id).as_str()
|
|
||||||
self.perform_get_request(["/v1/account/", id, "/_unix/_token"].concat().as_str())
|
|
||||||
.await
|
.await
|
||||||
}
|
}
|
||||||
|
|
||||||
|
@ -1535,15 +1549,14 @@ impl KanidmClient {
|
||||||
ttl: Option<u32>,
|
ttl: Option<u32>,
|
||||||
) -> Result<CUIntentToken, ClientError> {
|
) -> Result<CUIntentToken, ClientError> {
|
||||||
if let Some(ttl) = ttl {
|
if let Some(ttl) = ttl {
|
||||||
self.perform_get_request(
|
self.perform_get_request(&format!(
|
||||||
format!("/v1/person/{}/_credential/_update_intent?ttl={}", id, ttl).as_str(),
|
"/v1/person/{}/_credential/_update_intent?ttl={}",
|
||||||
)
|
id, ttl
|
||||||
|
))
|
||||||
.await
|
.await
|
||||||
} else {
|
} else {
|
||||||
self.perform_get_request(
|
self.perform_get_request(&format!("/v1/person/{}/_credential/_update_intent", id))
|
||||||
format!("/v1/person/{}/_credential/_update_intent", id).as_str(),
|
.await
|
||||||
)
|
|
||||||
.await
|
|
||||||
}
|
}
|
||||||
}
|
}
|
||||||
|
|
||||||
|
@ -1551,7 +1564,7 @@ impl KanidmClient {
|
||||||
&self,
|
&self,
|
||||||
id: &str,
|
id: &str,
|
||||||
) -> Result<(CUSessionToken, CUStatus), ClientError> {
|
) -> Result<(CUSessionToken, CUStatus), ClientError> {
|
||||||
self.perform_get_request(format!("/v1/person/{}/_credential/_update", id).as_str())
|
self.perform_get_request(&format!("/v1/person/{}/_credential/_update", id))
|
||||||
.await
|
.await
|
||||||
}
|
}
|
||||||
|
|
||||||
|
@ -1692,7 +1705,7 @@ impl KanidmClient {
|
||||||
&self,
|
&self,
|
||||||
id: &str,
|
id: &str,
|
||||||
) -> Result<RadiusAuthToken, ClientError> {
|
) -> Result<RadiusAuthToken, ClientError> {
|
||||||
self.perform_get_request(format!("/v1/account/{}/_radius/_token", id).as_str())
|
self.perform_get_request(&format!("/v1/account/{}/_radius/_token", id))
|
||||||
.await
|
.await
|
||||||
}
|
}
|
||||||
|
|
||||||
|
@ -1704,7 +1717,7 @@ impl KanidmClient {
|
||||||
let req = SingleStringRequest {
|
let req = SingleStringRequest {
|
||||||
value: cred.to_string(),
|
value: cred.to_string(),
|
||||||
};
|
};
|
||||||
self.perform_post_request(["/v1/account/", id, "/_unix/_auth"].concat().as_str(), req)
|
self.perform_post_request(&format!("/v1/account/{}/_unix/_auth", id), req)
|
||||||
.await
|
.await
|
||||||
}
|
}
|
||||||
|
|
||||||
|
@ -1714,12 +1727,12 @@ impl KanidmClient {
|
||||||
id: &str,
|
id: &str,
|
||||||
tag: &str,
|
tag: &str,
|
||||||
) -> Result<Option<String>, ClientError> {
|
) -> Result<Option<String>, ClientError> {
|
||||||
self.perform_get_request(format!("/v1/account/{}/_ssh_pubkeys/{}", id, tag).as_str())
|
self.perform_get_request(&format!("/v1/account/{}/_ssh_pubkeys/{}", id, tag))
|
||||||
.await
|
.await
|
||||||
}
|
}
|
||||||
|
|
||||||
pub async fn idm_account_get_ssh_pubkeys(&self, id: &str) -> Result<Vec<String>, ClientError> {
|
pub async fn idm_account_get_ssh_pubkeys(&self, id: &str) -> Result<Vec<String>, ClientError> {
|
||||||
self.perform_get_request(format!("/v1/account/{}/_ssh_pubkeys", id).as_str())
|
self.perform_get_request(&format!("/v1/account/{}/_ssh_pubkeys", id))
|
||||||
.await
|
.await
|
||||||
}
|
}
|
||||||
|
|
||||||
|
@ -1783,7 +1796,7 @@ impl KanidmClient {
|
||||||
&self,
|
&self,
|
||||||
id: &str,
|
id: &str,
|
||||||
) -> Result<Option<Entry>, ClientError> {
|
) -> Result<Option<Entry>, ClientError> {
|
||||||
self.perform_get_request(format!("/v1/schema/attributetype/{}", id).as_str())
|
self.perform_get_request(&format!("/v1/schema/attributetype/{}", id))
|
||||||
.await
|
.await
|
||||||
}
|
}
|
||||||
|
|
||||||
|
@ -1792,7 +1805,7 @@ impl KanidmClient {
|
||||||
}
|
}
|
||||||
|
|
||||||
pub async fn idm_schema_classtype_get(&self, id: &str) -> Result<Option<Entry>, ClientError> {
|
pub async fn idm_schema_classtype_get(&self, id: &str) -> Result<Option<Entry>, ClientError> {
|
||||||
self.perform_get_request(format!("/v1/schema/classtype/{}", id).as_str())
|
self.perform_get_request(&format!("/v1/schema/classtype/{}", id))
|
||||||
.await
|
.await
|
||||||
}
|
}
|
||||||
|
|
||||||
|
@ -1802,12 +1815,12 @@ impl KanidmClient {
|
||||||
}
|
}
|
||||||
|
|
||||||
pub async fn recycle_bin_get(&self, id: &str) -> Result<Option<Entry>, ClientError> {
|
pub async fn recycle_bin_get(&self, id: &str) -> Result<Option<Entry>, ClientError> {
|
||||||
self.perform_get_request(format!("/v1/recycle_bin/{}", id).as_str())
|
self.perform_get_request(&format!("/v1/recycle_bin/{}", id))
|
||||||
.await
|
.await
|
||||||
}
|
}
|
||||||
|
|
||||||
pub async fn recycle_bin_revive(&self, id: &str) -> Result<(), ClientError> {
|
pub async fn recycle_bin_revive(&self, id: &str) -> Result<(), ClientError> {
|
||||||
self.perform_post_request(format!("/v1/recycle_bin/{}/_revive", id).as_str(), ())
|
self.perform_post_request(&format!("/v1/recycle_bin/{}/_revive", id), ())
|
||||||
.await
|
.await
|
||||||
}
|
}
|
||||||
}
|
}
|
||||||
|
|
|
@ -6,7 +6,7 @@ use base64::{engine::general_purpose, Engine as _};
|
||||||
// We do this here so it's only actually run and checked once.
|
// We do this here so it's only actually run and checked once.
|
||||||
fn determine_git_rev() -> Option<String> {
|
fn determine_git_rev() -> Option<String> {
|
||||||
let path = PathBuf::from("../../");
|
let path = PathBuf::from("../../");
|
||||||
let repo = git2::Repository::open(&path).ok()?;
|
let repo = git2::Repository::open(path).ok()?;
|
||||||
let head = repo.head().ok()?;
|
let head = repo.head().ok()?;
|
||||||
let commit = head.peel_to_commit().ok()?;
|
let commit = head.peel_to_commit().ok()?;
|
||||||
let mut commit_id = commit.id().to_string();
|
let mut commit_id = commit.id().to_string();
|
||||||
|
|
|
@ -1,3 +1,5 @@
|
||||||
|
#![allow(non_upper_case_globals)]
|
||||||
|
|
||||||
use num_enum::TryFromPrimitive;
|
use num_enum::TryFromPrimitive;
|
||||||
use serde::{Deserialize, Serialize};
|
use serde::{Deserialize, Serialize};
|
||||||
use serde_with::skip_serializing_none;
|
use serde_with::skip_serializing_none;
|
||||||
|
@ -294,14 +296,6 @@ pub struct Claim {
|
||||||
// pub expiry: DateTime
|
// pub expiry: DateTime
|
||||||
}
|
}
|
||||||
|
|
||||||
/*
|
|
||||||
#[derive(Debug, Serialize, Deserialize, Clone)]
|
|
||||||
pub struct Application {
|
|
||||||
pub name: String,
|
|
||||||
pub uuid: String,
|
|
||||||
}
|
|
||||||
*/
|
|
||||||
|
|
||||||
#[derive(Debug, Serialize, Deserialize, Copy, Clone, Ord, PartialOrd, Eq, PartialEq, Hash)]
|
#[derive(Debug, Serialize, Deserialize, Copy, Clone, Ord, PartialOrd, Eq, PartialEq, Hash)]
|
||||||
#[serde(rename_all = "lowercase")]
|
#[serde(rename_all = "lowercase")]
|
||||||
#[derive(TryFromPrimitive)]
|
#[derive(TryFromPrimitive)]
|
||||||
|
|
|
@ -25,31 +25,34 @@ if [ -z "${REMOVE_TEST_DB}" ]; then
|
||||||
fi
|
fi
|
||||||
fi
|
fi
|
||||||
|
|
||||||
|
|
||||||
if [ ! -f run_insecure_dev_server.sh ]; then
|
if [ ! -f run_insecure_dev_server.sh ]; then
|
||||||
echo "Please run from the server/daemon dir!"
|
echo "Please run from the server/daemon dir!"
|
||||||
exit 1
|
exit 1
|
||||||
fi
|
fi
|
||||||
|
|
||||||
|
# defaults
|
||||||
|
KANIDM_CONFIG_FILE="../../examples/insecure_server.toml"
|
||||||
|
KANIDM_URL="$(rg origin "${KANIDM_CONFIG_FILE}" | awk '{print $NF}' | tr -d '"')"
|
||||||
|
KANIDM_CA_PATH="/tmp/kanidm/ca.pem"
|
||||||
|
|
||||||
# wait for them to shut down the server if it's running...
|
# wait for them to shut down the server if it's running...
|
||||||
while true
|
while true; do
|
||||||
do
|
if [ "$(pgrep kanidmd | wc -l)" -eq 1 ]; then
|
||||||
if [ "$(pgrep kanidmd | wc -l )" -eq 0 ]; then
|
|
||||||
break
|
break
|
||||||
fi
|
fi
|
||||||
echo "Stop the kanidmd server first please!"
|
echo "Start the kanidmd server first please!"
|
||||||
sleep 1
|
|
||||||
done
|
|
||||||
|
|
||||||
# defaults
|
while true; do
|
||||||
KANIDM_CONFIG="../../examples/insecure_server.toml"
|
echo "Waiting for you to start the server... testing ${KANIDM_URL}"
|
||||||
KANIDM_URL="$(rg origin "${KANIDM_CONFIG}" | awk '{print $NF}' | tr -d '"')"
|
curl --cacert "${KANIDM_CA_PATH}" -fs "${KANIDM_URL}" >/dev/null && break
|
||||||
KANIDM_CA_PATH="/tmp/kanidm/ca.pem"
|
sleep 2
|
||||||
|
done
|
||||||
|
done
|
||||||
|
|
||||||
# needed for the CLI tools to do their thing
|
# needed for the CLI tools to do their thing
|
||||||
export KANIDM_URL
|
export KANIDM_URL
|
||||||
export KANIDM_CA_PATH
|
export KANIDM_CA_PATH
|
||||||
export KANIDM_CONFIG
|
export KANIDM_CONFIG_FILE
|
||||||
|
|
||||||
# string things
|
# string things
|
||||||
TEST_USER_NAME="testuser"
|
TEST_USER_NAME="testuser"
|
||||||
|
@ -68,19 +71,20 @@ if [ "${REMOVE_TEST_DB}" -eq 1 ]; then
|
||||||
fi
|
fi
|
||||||
|
|
||||||
echo "Reset the admin user"
|
echo "Reset the admin user"
|
||||||
ADMIN_PASS=$(${KANIDMD} recover-account admin -o json 2>&1 | rg recovery | rg result | jq -r .result )
|
ADMIN_PASS=$(${KANIDMD} recover-account admin -o json 2>&1 | rg password | jq -r .password)
|
||||||
|
if [ -z "${ADMIN_PASS}" ] || [ "${ADMIN_PASS}" == "null " ]; then
|
||||||
|
echo "Failed to reset admin password!"
|
||||||
|
exit 1
|
||||||
|
fi
|
||||||
echo "admin pass: '${ADMIN_PASS}'"
|
echo "admin pass: '${ADMIN_PASS}'"
|
||||||
echo "Reset the idm_admin user"
|
echo "Reset the idm_admin user"
|
||||||
IDM_ADMIN_PASS=$(${KANIDMD} recover-account idm_admin -o json 2>&1 | rg recovery | rg result | jq -r .result)
|
IDM_ADMIN_PASS=$(${KANIDMD} recover-account idm_admin -o json 2>&1 | rg password | jq -r .password)
|
||||||
|
if [ -z "${IDM_ADMIN_PASS}" ] || [ "${IDM_ADMIN_PASS}" == "null " ]; then
|
||||||
|
echo "Failed to reset admin password!"
|
||||||
|
exit 1
|
||||||
|
fi
|
||||||
echo "idm_admin pass: '${IDM_ADMIN_PASS}'"
|
echo "idm_admin pass: '${IDM_ADMIN_PASS}'"
|
||||||
|
|
||||||
while true
|
|
||||||
do
|
|
||||||
echo "Waiting for you to start the server... testing ${KANIDM_URL}"
|
|
||||||
curl --cacert "${KANIDM_CA_PATH}" -fs "${KANIDM_URL}" > /dev/null && break
|
|
||||||
sleep 2
|
|
||||||
done
|
|
||||||
|
|
||||||
echo "login with admin"
|
echo "login with admin"
|
||||||
${KANIDM} login -D admin --password "${ADMIN_PASS}"
|
${KANIDM} login -D admin --password "${ADMIN_PASS}"
|
||||||
echo "login with idm_admin"
|
echo "login with idm_admin"
|
||||||
|
@ -96,7 +100,7 @@ echo "Adding ${TEST_USER_NAME} to ${TEST_GROUP}"
|
||||||
${KANIDM} group add-members "${TEST_GROUP}" "${TEST_USER_NAME}" -D idm_admin
|
${KANIDM} group add-members "${TEST_GROUP}" "${TEST_USER_NAME}" -D idm_admin
|
||||||
|
|
||||||
echo "Enable experimental UI for admin idm_admin ${TEST_USER_NAME}"
|
echo "Enable experimental UI for admin idm_admin ${TEST_USER_NAME}"
|
||||||
${KANIDM} group add-members idm_ui_enable_experimental_features admin idm_admin "${TEST_USER_NAME}" -D idm_admin
|
${KANIDM} group add-members idm_ui_enable_experimental_features admin idm_admin "${TEST_USER_NAME}" -D idm_admin
|
||||||
|
|
||||||
# create oauth2 rp
|
# create oauth2 rp
|
||||||
echo "Creating the OAuth2 RP"
|
echo "Creating the OAuth2 RP"
|
||||||
|
|
|
@ -2,12 +2,16 @@
|
||||||
|
|
||||||
# makes sure the repos are configured because the containers are derpy sometimes
|
# makes sure the repos are configured because the containers are derpy sometimes
|
||||||
|
|
||||||
|
set -e
|
||||||
|
|
||||||
#disable the openh264 repo
|
#disable the openh264 repo
|
||||||
if [ "$(zypper lr | grep -ci 'repo-openh264')" -eq 1 ]; then
|
if [ "$(zypper lr | grep -ci 'repo-openh264')" -eq 1 ]; then
|
||||||
zypper mr -d -f -n 'repo-openh264'
|
echo "Disabling openh264 repo"
|
||||||
|
zypper mr -d -f repo-openh264
|
||||||
fi
|
fi
|
||||||
|
|
||||||
# add the non-oss repo if it doesn't exist
|
# add the non-oss repo if it doesn't exist
|
||||||
|
echo "Adding the non-oss repo"
|
||||||
if [ "$(zypper lr | grep -c 'repo-non-oss')" -eq 0 ]; then
|
if [ "$(zypper lr | grep -c 'repo-non-oss')" -eq 0 ]; then
|
||||||
zypper ar -f -n 'Non-OSS' http://download.opensuse.org/tumbleweed/repo/non-oss/ repo-non-oss
|
zypper ar -f -n 'Non-OSS' http://download.opensuse.org/tumbleweed/repo/non-oss/ repo-non-oss
|
||||||
fi
|
fi
|
||||||
|
|
|
@ -618,10 +618,16 @@ impl QueryServerReadV1 {
|
||||||
.qs_read
|
.qs_read
|
||||||
.name_to_uuid(uuid_or_name.as_str())
|
.name_to_uuid(uuid_or_name.as_str())
|
||||||
.map_err(|e| {
|
.map_err(|e| {
|
||||||
|
// sometimes it comes back as empty which is bad, it's safe to start with `<empty` here
|
||||||
|
// because a valid username/uuid can never start with that and we're only logging it
|
||||||
|
let uuid_or_name_val = match uuid_or_name.is_empty() {
|
||||||
|
true => "<empty uuid_or_name>",
|
||||||
|
false => &uuid_or_name,
|
||||||
|
};
|
||||||
admin_info!(
|
admin_info!(
|
||||||
err = ?e,
|
err = ?e,
|
||||||
"Error resolving {} as gidnumber continuing ...",
|
"Error resolving {} as gidnumber continuing ...",
|
||||||
uuid_or_name
|
uuid_or_name_val
|
||||||
);
|
);
|
||||||
e
|
e
|
||||||
})?;
|
})?;
|
||||||
|
|
|
@ -70,7 +70,7 @@ pub async fn are_we_json_yet<B>(request: Request<B>, next: Next<B>) -> Response
|
||||||
}
|
}
|
||||||
|
|
||||||
/// This runs at the start of the request, adding an extension with `KOpId` which has useful things inside it.
|
/// This runs at the start of the request, adding an extension with `KOpId` which has useful things inside it.
|
||||||
#[instrument(name = "request", skip_all)]
|
#[instrument(name = "kopid_middleware", skip_all, level = "DEBUG")]
|
||||||
pub async fn kopid_middleware<B>(
|
pub async fn kopid_middleware<B>(
|
||||||
auth: Option<TypedHeader<Authorization<Bearer>>>,
|
auth: Option<TypedHeader<Authorization<Bearer>>>,
|
||||||
mut request: Request<B>,
|
mut request: Request<B>,
|
||||||
|
@ -86,10 +86,11 @@ pub async fn kopid_middleware<B>(
|
||||||
request.extensions_mut().insert(KOpId { eventid, uat });
|
request.extensions_mut().insert(KOpId { eventid, uat });
|
||||||
let mut response = next.run(request).await;
|
let mut response = next.run(request).await;
|
||||||
|
|
||||||
#[allow(clippy::unwrap_used)]
|
#[allow(clippy::expect_used)]
|
||||||
response.headers_mut().insert(
|
response.headers_mut().insert(
|
||||||
"X-KANIDM-OPID",
|
"X-KANIDM-OPID",
|
||||||
HeaderValue::from_str(&eventid.as_hyphenated().to_string()).unwrap(),
|
HeaderValue::from_str(&eventid.as_hyphenated().to_string())
|
||||||
|
.expect("Failed to set X-KANIDM-OPID header in response!"),
|
||||||
);
|
);
|
||||||
|
|
||||||
response
|
response
|
||||||
|
|
|
@ -5,6 +5,7 @@ mod manifest;
|
||||||
mod middleware;
|
mod middleware;
|
||||||
mod oauth2;
|
mod oauth2;
|
||||||
mod tests;
|
mod tests;
|
||||||
|
mod trace;
|
||||||
mod ui;
|
mod ui;
|
||||||
mod v1;
|
mod v1;
|
||||||
mod v1_scim;
|
mod v1_scim;
|
||||||
|
@ -37,6 +38,7 @@ use tokio_openssl::SslStream;
|
||||||
use futures_util::future::poll_fn;
|
use futures_util::future::poll_fn;
|
||||||
use serde::Serialize;
|
use serde::Serialize;
|
||||||
use tokio::net::TcpListener;
|
use tokio::net::TcpListener;
|
||||||
|
use tracing::Level;
|
||||||
|
|
||||||
use std::io::ErrorKind;
|
use std::io::ErrorKind;
|
||||||
use std::path::PathBuf;
|
use std::path::PathBuf;
|
||||||
|
@ -45,7 +47,7 @@ use std::sync::Arc;
|
||||||
use std::{net::SocketAddr, str::FromStr};
|
use std::{net::SocketAddr, str::FromStr};
|
||||||
use tokio::sync::broadcast;
|
use tokio::sync::broadcast;
|
||||||
use tower_http::services::ServeDir;
|
use tower_http::services::ServeDir;
|
||||||
use tower_http::trace::TraceLayer;
|
use tower_http::trace::{DefaultOnRequest, TraceLayer};
|
||||||
use uuid::Uuid;
|
use uuid::Uuid;
|
||||||
|
|
||||||
use crate::CoreAction;
|
use crate::CoreAction;
|
||||||
|
@ -235,6 +237,12 @@ pub async fn create_https_server(
|
||||||
}
|
}
|
||||||
};
|
};
|
||||||
|
|
||||||
|
// this sets up the default span which logs the URL etc.
|
||||||
|
let trace_layer = TraceLayer::new_for_http()
|
||||||
|
.make_span_with(trace::DefaultMakeSpanKanidmd::new())
|
||||||
|
// setting these to trace because all they do is print "started processing request", and we are already doing that enough!
|
||||||
|
.on_request(DefaultOnRequest::new().level(Level::TRACE));
|
||||||
|
|
||||||
let app = app
|
let app = app
|
||||||
.merge(static_routes)
|
.merge(static_routes)
|
||||||
.layer(from_fn_with_state(
|
.layer(from_fn_with_state(
|
||||||
|
@ -244,19 +252,19 @@ pub async fn create_https_server(
|
||||||
.layer(from_fn(middleware::version_middleware))
|
.layer(from_fn(middleware::version_middleware))
|
||||||
.layer(from_fn(
|
.layer(from_fn(
|
||||||
middleware::hsts_header::strict_transport_security_layer,
|
middleware::hsts_header::strict_transport_security_layer,
|
||||||
))
|
));
|
||||||
.layer(TraceLayer::new_for_http())
|
|
||||||
// This must be the LAST middleware.
|
|
||||||
// This is because the last middleware here is the first to be entered and the last
|
|
||||||
// to be exited, and this middleware sets up ids' and other bits for for logging
|
|
||||||
// coherence to be maintained.
|
|
||||||
.layer(from_fn(middleware::kopid_middleware));
|
|
||||||
|
|
||||||
// layer which checks the responses have a content-type of JSON when we're in debug mode
|
// layer which checks the responses have a content-type of JSON when we're in debug mode
|
||||||
#[cfg(debug_assertions)]
|
#[cfg(debug_assertions)]
|
||||||
let app = app.layer(from_fn(middleware::are_we_json_yet));
|
let app = app.layer(from_fn(middleware::are_we_json_yet));
|
||||||
|
|
||||||
let app = app
|
let app = app
|
||||||
|
.layer(trace_layer)
|
||||||
|
// This must be the LAST middleware.
|
||||||
|
// This is because the last middleware here is the first to be entered and the last
|
||||||
|
// to be exited, and this middleware sets up ids' and other bits for for logging
|
||||||
|
// coherence to be maintained.
|
||||||
|
.layer(from_fn(middleware::kopid_middleware))
|
||||||
.with_state(state)
|
.with_state(state)
|
||||||
// the connect_info bit here lets us pick up the remote address of the client
|
// the connect_info bit here lets us pick up the remote address of the client
|
||||||
.into_make_service_with_connect_info::<SocketAddr>();
|
.into_make_service_with_connect_info::<SocketAddr>();
|
||||||
|
@ -345,7 +353,6 @@ async fn server_loop(
|
||||||
}
|
}
|
||||||
}
|
}
|
||||||
|
|
||||||
// #[instrument(name = "handle-connection", level = "debug", skip_all)]
|
|
||||||
/// This handles an individual connection.
|
/// This handles an individual connection.
|
||||||
async fn handle_conn(
|
async fn handle_conn(
|
||||||
acceptor: SslAcceptor,
|
acceptor: SslAcceptor,
|
||||||
|
|
37
server/core/src/https/trace.rs
Normal file
37
server/core/src/https/trace.rs
Normal file
|
@ -0,0 +1,37 @@
|
||||||
|
//! Reimplementation of [`tower-http`]'s [`DefaultMakeSpan`] that only runs at "INFO" level for our own needs.
|
||||||
|
|
||||||
|
use http::Request;
|
||||||
|
use tracing::{Level, Span};
|
||||||
|
|
||||||
|
/// The default way [`Span`]s will be created for [`Trace`].
|
||||||
|
///
|
||||||
|
/// [`Span`]: tracing::Span
|
||||||
|
/// [`Trace`]: super::Trace
|
||||||
|
#[derive(Debug, Clone)]
|
||||||
|
pub struct DefaultMakeSpanKanidmd {}
|
||||||
|
|
||||||
|
impl DefaultMakeSpanKanidmd {
|
||||||
|
/// Create a new `DefaultMakeSpanKanidmd`.
|
||||||
|
pub fn new() -> Self {
|
||||||
|
Self {}
|
||||||
|
}
|
||||||
|
}
|
||||||
|
|
||||||
|
impl Default for DefaultMakeSpanKanidmd {
|
||||||
|
fn default() -> Self {
|
||||||
|
Self::new()
|
||||||
|
}
|
||||||
|
}
|
||||||
|
|
||||||
|
impl<B> tower_http::trace::MakeSpan<B> for DefaultMakeSpanKanidmd {
|
||||||
|
#[instrument(name = "handle_request", skip_all)]
|
||||||
|
fn make_span(&mut self, request: &Request<B>) -> Span {
|
||||||
|
tracing::span!(
|
||||||
|
Level::INFO,
|
||||||
|
"request",
|
||||||
|
method = %request.method(),
|
||||||
|
uri = %request.uri(),
|
||||||
|
version = ?request.version(),
|
||||||
|
)
|
||||||
|
}
|
||||||
|
}
|
|
@ -874,7 +874,7 @@ pub async fn account_delete_id_radius(
|
||||||
json_rest_event_delete_id_attr(state, id, attr, filter, None, kopid).await
|
json_rest_event_delete_id_attr(state, id, attr, filter, None, kopid).await
|
||||||
}
|
}
|
||||||
|
|
||||||
pub async fn account_get_id_radius_token(
|
pub async fn account_id_radius_token(
|
||||||
State(state): State<ServerState>,
|
State(state): State<ServerState>,
|
||||||
Path(id): Path<String>,
|
Path(id): Path<String>,
|
||||||
Extension(kopid): Extension<KOpId>,
|
Extension(kopid): Extension<KOpId>,
|
||||||
|
@ -893,6 +893,7 @@ pub async fn account_get_id_radius_token(
|
||||||
}
|
}
|
||||||
|
|
||||||
/// Expects an `AccountUnixExtend` object
|
/// Expects an `AccountUnixExtend` object
|
||||||
|
#[instrument(name = "account_post_id_unix", level = "INFO", skip(id, state, kopid))]
|
||||||
pub async fn account_post_id_unix(
|
pub async fn account_post_id_unix(
|
||||||
State(state): State<ServerState>,
|
State(state): State<ServerState>,
|
||||||
Path(id): Path<String>,
|
Path(id): Path<String>,
|
||||||
|
@ -906,15 +907,46 @@ pub async fn account_post_id_unix(
|
||||||
to_axum_response(res)
|
to_axum_response(res)
|
||||||
}
|
}
|
||||||
|
|
||||||
pub async fn account_get_id_unix_token(
|
#[instrument(name = "account_id_unix_token", level = "INFO", skip_all)]
|
||||||
|
pub async fn account_id_unix_token(
|
||||||
State(state): State<ServerState>,
|
State(state): State<ServerState>,
|
||||||
Extension(kopid): Extension<KOpId>,
|
Extension(kopid): Extension<KOpId>,
|
||||||
Path(id): Path<String>,
|
Path(id): Path<String>,
|
||||||
) -> impl IntoResponse {
|
) -> impl IntoResponse {
|
||||||
|
// no point asking for an empty id
|
||||||
|
if id.is_empty() {
|
||||||
|
#[allow(clippy::unwrap_used)]
|
||||||
|
return Response::builder()
|
||||||
|
.status(StatusCode::BAD_REQUEST)
|
||||||
|
.body(Body::empty())
|
||||||
|
.unwrap();
|
||||||
|
}
|
||||||
|
|
||||||
let res = state
|
let res = state
|
||||||
.qe_r_ref
|
.qe_r_ref
|
||||||
.handle_internalunixusertokenread(kopid.uat, id, kopid.eventid)
|
.handle_internalunixusertokenread(kopid.uat, id, kopid.eventid)
|
||||||
.await;
|
.await;
|
||||||
|
|
||||||
|
if let Err(OperationError::InvalidAccountState(val)) = &res {
|
||||||
|
// if they're not a posix user we should just hide them
|
||||||
|
if *val == format!("Missing class: {}", "posixaccount") {
|
||||||
|
#[allow(clippy::unwrap_used)]
|
||||||
|
return Response::builder()
|
||||||
|
.status(StatusCode::NOT_FOUND)
|
||||||
|
.body(Body::empty())
|
||||||
|
.unwrap();
|
||||||
|
}
|
||||||
|
};
|
||||||
|
|
||||||
|
// the was returning a 500 error which wasn't right
|
||||||
|
if let Err(OperationError::InvalidValueState) = &res {
|
||||||
|
#[allow(clippy::unwrap_used)]
|
||||||
|
return Response::builder()
|
||||||
|
.status(StatusCode::NOT_FOUND)
|
||||||
|
.body(Body::empty())
|
||||||
|
.unwrap();
|
||||||
|
};
|
||||||
|
|
||||||
to_axum_response(res)
|
to_axum_response(res)
|
||||||
}
|
}
|
||||||
|
|
||||||
|
@ -1480,8 +1512,8 @@ pub fn router(state: ServerState) -> Router<ServerState> {
|
||||||
)
|
)
|
||||||
.route(
|
.route(
|
||||||
"/v1/person/:id/_radius/_token",
|
"/v1/person/:id/_radius/_token",
|
||||||
get(account_get_id_radius_token),
|
get(account_id_radius_token),
|
||||||
) // TODO: make radius token cacheable
|
) // TODO: make this cacheable
|
||||||
.route("/v1/person/:id/_unix", post(account_post_id_unix))
|
.route("/v1/person/:id/_unix", post(account_post_id_unix))
|
||||||
.route(
|
.route(
|
||||||
"/v1/person/:id/_unix/_credential",
|
"/v1/person/:id/_unix/_credential",
|
||||||
|
@ -1551,11 +1583,11 @@ pub fn router(state: ServerState) -> Router<ServerState> {
|
||||||
)
|
)
|
||||||
.route(
|
.route(
|
||||||
"/v1/account/:id/_unix/_token",
|
"/v1/account/:id/_unix/_token",
|
||||||
post(account_get_id_unix_token).get(account_get_id_unix_token), // TODO: make this cacheable
|
post(account_id_unix_token).get(account_id_unix_token), // TODO: make this cacheable
|
||||||
)
|
)
|
||||||
.route(
|
.route(
|
||||||
"/v1/account/:id/_radius/_token",
|
"/v1/account/:id/_radius/_token",
|
||||||
post(account_get_id_radius_token).get(account_get_id_radius_token), // TODO: make this cacheable
|
post(account_id_radius_token).get(account_id_radius_token), // TODO: make this cacheable
|
||||||
)
|
)
|
||||||
.route(
|
.route(
|
||||||
"/v1/account/:id/_ssh_pubkeys",
|
"/v1/account/:id/_ssh_pubkeys",
|
||||||
|
|
|
@ -99,25 +99,24 @@ pub async fn create_user(rsclient: &KanidmClient, id: &str, group_name: &str) {
|
||||||
.expect("Failed to create the user");
|
.expect("Failed to create the user");
|
||||||
|
|
||||||
// Create group and add to user to test read attr: member_of
|
// Create group and add to user to test read attr: member_of
|
||||||
#[allow(clippy::expect_used)]
|
#[allow(clippy::panic)]
|
||||||
if rsclient
|
if rsclient
|
||||||
.idm_group_get(group_name)
|
.idm_group_get(group_name)
|
||||||
.await
|
.await
|
||||||
.expect("Failed to get group")
|
.unwrap_or_else(|_| panic!("Failed to get group {}", group_name))
|
||||||
.is_none()
|
.is_none()
|
||||||
{
|
{
|
||||||
#[allow(clippy::expect_used)]
|
#[allow(clippy::panic)]
|
||||||
rsclient
|
rsclient
|
||||||
.idm_group_create(group_name)
|
.idm_group_create(group_name)
|
||||||
.await
|
.await
|
||||||
.expect("Failed to create group");
|
.unwrap_or_else(|_| panic!("Failed to create group {}", group_name));
|
||||||
}
|
}
|
||||||
|
#[allow(clippy::panic)]
|
||||||
#[allow(clippy::expect_used)]
|
|
||||||
rsclient
|
rsclient
|
||||||
.idm_group_add_members(group_name, &[id])
|
.idm_group_add_members(group_name, &[id])
|
||||||
.await
|
.await
|
||||||
.expect("Failed to set group membership for user");
|
.unwrap_or_else(|_| panic!("Failed to add user {} to group {}", id, group_name));
|
||||||
}
|
}
|
||||||
|
|
||||||
pub async fn create_user_with_all_attrs(
|
pub async fn create_user_with_all_attrs(
|
||||||
|
|
|
@ -554,12 +554,15 @@ async fn test_self_write_mail_priv_people(rsclient: KanidmClient) {
|
||||||
#[kanidmd_testkit::test]
|
#[kanidmd_testkit::test]
|
||||||
async fn test_https_robots_txt(rsclient: KanidmClient) {
|
async fn test_https_robots_txt(rsclient: KanidmClient) {
|
||||||
// We need to do manual reqwests here.
|
// We need to do manual reqwests here.
|
||||||
let addr = rsclient.get_url();
|
|
||||||
|
|
||||||
let response = match reqwest::get(format!("{}/robots.txt", &addr)).await {
|
let response = match reqwest::get(rsclient.make_url("/robots.txt")).await {
|
||||||
Ok(value) => value,
|
Ok(value) => value,
|
||||||
Err(error) => {
|
Err(error) => {
|
||||||
panic!("Failed to query {:?} : {:#?}", addr, error);
|
panic!(
|
||||||
|
"Failed to query {:?} : {:#?}",
|
||||||
|
rsclient.make_url("/robots.txt"),
|
||||||
|
error
|
||||||
|
);
|
||||||
}
|
}
|
||||||
};
|
};
|
||||||
eprintln!("response: {:#?}", response);
|
eprintln!("response: {:#?}", response);
|
||||||
|
@ -577,9 +580,7 @@ async fn test_https_robots_txt(rsclient: KanidmClient) {
|
||||||
// #[kanidmd_testkit::test]
|
// #[kanidmd_testkit::test]
|
||||||
// async fn test_https_routemap(rsclient: KanidmClient) {
|
// async fn test_https_routemap(rsclient: KanidmClient) {
|
||||||
// // We need to do manual reqwests here.
|
// // We need to do manual reqwests here.
|
||||||
// let addr = rsclient.get_url();
|
// let response = match reqwest::get(rsclient.make_url("/v1/routemap")).await {
|
||||||
|
|
||||||
// let response = match reqwest::get(format!("{}/v1/routemap", &addr)).await {
|
|
||||||
// Ok(value) => value,
|
// Ok(value) => value,
|
||||||
// Err(error) => {
|
// Err(error) => {
|
||||||
// panic!("Failed to query {:?} : {:#?}", addr, error);
|
// panic!("Failed to query {:?} : {:#?}", addr, error);
|
||||||
|
@ -598,7 +599,7 @@ async fn test_https_robots_txt(rsclient: KanidmClient) {
|
||||||
#[kanidmd_testkit::test]
|
#[kanidmd_testkit::test]
|
||||||
async fn test_v1_raw_delete(rsclient: KanidmClient) {
|
async fn test_v1_raw_delete(rsclient: KanidmClient) {
|
||||||
// We need to do manual reqwests here.
|
// We need to do manual reqwests here.
|
||||||
let addr = rsclient.get_url();
|
|
||||||
let client = reqwest::ClientBuilder::new()
|
let client = reqwest::ClientBuilder::new()
|
||||||
.danger_accept_invalid_certs(true)
|
.danger_accept_invalid_certs(true)
|
||||||
.build()
|
.build()
|
||||||
|
@ -607,7 +608,7 @@ async fn test_v1_raw_delete(rsclient: KanidmClient) {
|
||||||
let post_body = serde_json::json!({"filter": "self"}).to_string();
|
let post_body = serde_json::json!({"filter": "self"}).to_string();
|
||||||
|
|
||||||
let response = match client
|
let response = match client
|
||||||
.post(format!("{}/v1/raw/delete", &addr))
|
.post(rsclient.make_url("/v1/raw/delete"))
|
||||||
.header(CONTENT_TYPE, APPLICATION_JSON)
|
.header(CONTENT_TYPE, APPLICATION_JSON)
|
||||||
.body(post_body)
|
.body(post_body)
|
||||||
.send()
|
.send()
|
||||||
|
@ -615,7 +616,11 @@ async fn test_v1_raw_delete(rsclient: KanidmClient) {
|
||||||
{
|
{
|
||||||
Ok(value) => value,
|
Ok(value) => value,
|
||||||
Err(error) => {
|
Err(error) => {
|
||||||
panic!("Failed to query {:?} : {:#?}", addr, error);
|
panic!(
|
||||||
|
"Failed to query {:?} : {:#?}",
|
||||||
|
rsclient.make_url("/v1/raw/delete"),
|
||||||
|
error
|
||||||
|
);
|
||||||
}
|
}
|
||||||
};
|
};
|
||||||
eprintln!("response: {:#?}", response);
|
eprintln!("response: {:#?}", response);
|
||||||
|
@ -629,16 +634,19 @@ async fn test_v1_raw_delete(rsclient: KanidmClient) {
|
||||||
#[kanidmd_testkit::test]
|
#[kanidmd_testkit::test]
|
||||||
async fn test_v1_raw_logout(rsclient: KanidmClient) {
|
async fn test_v1_raw_logout(rsclient: KanidmClient) {
|
||||||
// We need to do manual reqwests here.
|
// We need to do manual reqwests here.
|
||||||
let addr = rsclient.get_url();
|
|
||||||
let client = reqwest::ClientBuilder::new()
|
let client = reqwest::ClientBuilder::new()
|
||||||
.danger_accept_invalid_certs(true)
|
.danger_accept_invalid_certs(true)
|
||||||
.build()
|
.build()
|
||||||
.unwrap();
|
.unwrap();
|
||||||
|
|
||||||
let response = match client.get(format!("{}/v1/logout", &addr)).send().await {
|
let response = match client.get(rsclient.make_url("/v1/logout")).send().await {
|
||||||
Ok(value) => value,
|
Ok(value) => value,
|
||||||
Err(error) => {
|
Err(error) => {
|
||||||
panic!("Failed to query {:?} : {:#?}", addr, error);
|
panic!(
|
||||||
|
"Failed to query {:?} : {:#?}",
|
||||||
|
rsclient.make_url("/v1/logout"),
|
||||||
|
error
|
||||||
|
);
|
||||||
}
|
}
|
||||||
};
|
};
|
||||||
eprintln!("response: {:#?}", response);
|
eprintln!("response: {:#?}", response);
|
||||||
|
@ -652,16 +660,19 @@ async fn test_v1_raw_logout(rsclient: KanidmClient) {
|
||||||
#[kanidmd_testkit::test]
|
#[kanidmd_testkit::test]
|
||||||
async fn test_status_endpoint(rsclient: KanidmClient) {
|
async fn test_status_endpoint(rsclient: KanidmClient) {
|
||||||
// We need to do manual reqwests here.
|
// We need to do manual reqwests here.
|
||||||
let addr = rsclient.get_url();
|
|
||||||
let client = reqwest::ClientBuilder::new()
|
let client = reqwest::ClientBuilder::new()
|
||||||
.danger_accept_invalid_certs(true)
|
.danger_accept_invalid_certs(true)
|
||||||
.build()
|
.build()
|
||||||
.unwrap();
|
.unwrap();
|
||||||
|
|
||||||
let response = match client.get(format!("{}/status", &addr)).send().await {
|
let response = match client.get(rsclient.make_url("/status")).send().await {
|
||||||
Ok(value) => value,
|
Ok(value) => value,
|
||||||
Err(error) => {
|
Err(error) => {
|
||||||
panic!("Failed to query {:?} : {:#?}", addr, error);
|
panic!(
|
||||||
|
"Failed to query {:?} : {:#?}",
|
||||||
|
rsclient.make_url("/status"),
|
||||||
|
error
|
||||||
|
);
|
||||||
}
|
}
|
||||||
};
|
};
|
||||||
eprintln!("response: {:#?}", response);
|
eprintln!("response: {:#?}", response);
|
||||||
|
|
|
@ -3,13 +3,16 @@ use kanidm_client::KanidmClient;
|
||||||
#[kanidmd_testkit::test]
|
#[kanidmd_testkit::test]
|
||||||
async fn test_https_manifest(rsclient: KanidmClient) {
|
async fn test_https_manifest(rsclient: KanidmClient) {
|
||||||
// We need to do manual reqwests here.
|
// We need to do manual reqwests here.
|
||||||
let addr = rsclient.get_url();
|
|
||||||
|
|
||||||
// here we test the /ui/ endpoint which should have the headers
|
// here we test the /ui/ endpoint which should have the headers
|
||||||
let response = match reqwest::get(format!("{}/manifest.webmanifest", &addr)).await {
|
let response = match reqwest::get(rsclient.make_url("/manifest.webmanifest")).await {
|
||||||
Ok(value) => value,
|
Ok(value) => value,
|
||||||
Err(error) => {
|
Err(error) => {
|
||||||
panic!("Failed to query {:?} : {:#?}", addr, error);
|
panic!(
|
||||||
|
"Failed to query {:?} : {:#?}",
|
||||||
|
rsclient.make_url("/manifest.webmanifest"),
|
||||||
|
error
|
||||||
|
);
|
||||||
}
|
}
|
||||||
};
|
};
|
||||||
eprintln!("response: {:#?}", response);
|
eprintln!("response: {:#?}", response);
|
||||||
|
|
|
@ -3,13 +3,16 @@ use kanidm_client::KanidmClient;
|
||||||
#[kanidmd_testkit::test]
|
#[kanidmd_testkit::test]
|
||||||
async fn test_https_middleware_headers(rsclient: KanidmClient) {
|
async fn test_https_middleware_headers(rsclient: KanidmClient) {
|
||||||
// We need to do manual reqwests here.
|
// We need to do manual reqwests here.
|
||||||
let addr = rsclient.get_url();
|
|
||||||
|
|
||||||
// here we test the /ui/ endpoint which should have the headers
|
// here we test the /ui/ endpoint which should have the headers
|
||||||
let response = match reqwest::get(format!("{}/ui", &addr)).await {
|
let response = match reqwest::get(rsclient.make_url("/ui")).await {
|
||||||
Ok(value) => value,
|
Ok(value) => value,
|
||||||
Err(error) => {
|
Err(error) => {
|
||||||
panic!("Failed to query {:?} : {:#?}", addr, error);
|
panic!(
|
||||||
|
"Failed to query {:?} : {:#?}",
|
||||||
|
rsclient.make_url("/ui"),
|
||||||
|
error
|
||||||
|
);
|
||||||
}
|
}
|
||||||
};
|
};
|
||||||
eprintln!("response: {:#?}", response);
|
eprintln!("response: {:#?}", response);
|
||||||
|
@ -21,10 +24,14 @@ async fn test_https_middleware_headers(rsclient: KanidmClient) {
|
||||||
assert_ne!(response.headers().get("content-security-policy"), None);
|
assert_ne!(response.headers().get("content-security-policy"), None);
|
||||||
|
|
||||||
// here we test the /ui/login endpoint which should have the headers
|
// here we test the /ui/login endpoint which should have the headers
|
||||||
let response = match reqwest::get(format!("{}/ui/login", &addr)).await {
|
let response = match reqwest::get(rsclient.make_url("/ui/login")).await {
|
||||||
Ok(value) => value,
|
Ok(value) => value,
|
||||||
Err(error) => {
|
Err(error) => {
|
||||||
panic!("Failed to query {:?} : {:#?}", addr, error);
|
panic!(
|
||||||
|
"Failed to query {:?} : {:#?}",
|
||||||
|
rsclient.make_url("/ui/login"),
|
||||||
|
error
|
||||||
|
);
|
||||||
}
|
}
|
||||||
};
|
};
|
||||||
eprintln!("response: {:#?}", response);
|
eprintln!("response: {:#?}", response);
|
||||||
|
|
|
@ -82,7 +82,7 @@ async fn test_webdriver_user_login(rsclient: kanidm_client::KanidmClient) {
|
||||||
|
|
||||||
handle_error!(
|
handle_error!(
|
||||||
c,
|
c,
|
||||||
c.goto(rsclient.get_url().to_string()).await,
|
c.goto(&rsclient.get_url().to_string()).await,
|
||||||
"Couldn't get URL"
|
"Couldn't get URL"
|
||||||
);
|
);
|
||||||
|
|
||||||
|
|
|
@ -121,8 +121,6 @@ async fn test_oauth2_openid_basic_flow(rsclient: KanidmClient) {
|
||||||
.await
|
.await
|
||||||
.expect("No user auth token found");
|
.expect("No user auth token found");
|
||||||
|
|
||||||
let url = rsclient.get_url().to_string();
|
|
||||||
|
|
||||||
// We need a new reqwest client here.
|
// We need a new reqwest client here.
|
||||||
|
|
||||||
// from here, we can now begin what would be a "interaction" to the oauth server.
|
// from here, we can now begin what would be a "interaction" to the oauth server.
|
||||||
|
@ -137,10 +135,7 @@ async fn test_oauth2_openid_basic_flow(rsclient: KanidmClient) {
|
||||||
let response = client
|
let response = client
|
||||||
.request(
|
.request(
|
||||||
reqwest::Method::OPTIONS,
|
reqwest::Method::OPTIONS,
|
||||||
format!(
|
rsclient.make_url("/oauth2/openid/test_integration/.well-known/openid-configuration"),
|
||||||
"{}/oauth2/openid/test_integration/.well-known/openid-configuration",
|
|
||||||
url
|
|
||||||
),
|
|
||||||
)
|
)
|
||||||
.send()
|
.send()
|
||||||
.await
|
.await
|
||||||
|
@ -156,10 +151,7 @@ async fn test_oauth2_openid_basic_flow(rsclient: KanidmClient) {
|
||||||
assert!(cors_header.eq("*"));
|
assert!(cors_header.eq("*"));
|
||||||
|
|
||||||
let response = client
|
let response = client
|
||||||
.get(format!(
|
.get(rsclient.make_url("/oauth2/openid/test_integration/.well-known/openid-configuration"))
|
||||||
"{}/oauth2/openid/test_integration/.well-known/openid-configuration",
|
|
||||||
url
|
|
||||||
))
|
|
||||||
.send()
|
.send()
|
||||||
.await
|
.await
|
||||||
.expect("Failed to send request.");
|
.expect("Failed to send request.");
|
||||||
|
@ -176,36 +168,24 @@ async fn test_oauth2_openid_basic_flow(rsclient: KanidmClient) {
|
||||||
|
|
||||||
// Most values are checked in idm/oauth2.rs, but we want to sanity check
|
// Most values are checked in idm/oauth2.rs, but we want to sanity check
|
||||||
// the urls here as an extended function smoke test.
|
// the urls here as an extended function smoke test.
|
||||||
assert!(
|
assert!(discovery.issuer == rsclient.make_url("/oauth2/openid/test_integration"));
|
||||||
discovery.issuer == Url::parse(&format!("{}/oauth2/openid/test_integration", url)).unwrap()
|
|
||||||
);
|
|
||||||
|
|
||||||
assert!(discovery.authorization_endpoint == Url::parse(&format!("{}/ui/oauth2", url)).unwrap());
|
assert!(discovery.authorization_endpoint == rsclient.make_url("/ui/oauth2"));
|
||||||
|
|
||||||
assert!(discovery.token_endpoint == Url::parse(&format!("{}/oauth2/token", url)).unwrap());
|
assert!(discovery.token_endpoint == rsclient.make_url("/oauth2/token"));
|
||||||
|
|
||||||
assert!(
|
assert!(
|
||||||
discovery.userinfo_endpoint
|
discovery.userinfo_endpoint
|
||||||
== Some(
|
== Some(rsclient.make_url("/oauth2/openid/test_integration/userinfo"))
|
||||||
Url::parse(&format!("{}/oauth2/openid/test_integration/userinfo", url)).unwrap()
|
|
||||||
)
|
|
||||||
);
|
);
|
||||||
|
|
||||||
assert!(
|
assert!(
|
||||||
discovery.jwks_uri
|
discovery.jwks_uri == rsclient.make_url("/oauth2/openid/test_integration/public_key.jwk")
|
||||||
== Url::parse(&format!(
|
|
||||||
"{}/oauth2/openid/test_integration/public_key.jwk",
|
|
||||||
url
|
|
||||||
))
|
|
||||||
.unwrap()
|
|
||||||
);
|
);
|
||||||
|
|
||||||
// Step 0 - get the jwks public key.
|
// Step 0 - get the jwks public key.
|
||||||
let response = client
|
let response = client
|
||||||
.get(format!(
|
.get(rsclient.make_url("/oauth2/openid/test_integration/public_key.jwk"))
|
||||||
"{}/oauth2/openid/test_integration/public_key.jwk",
|
|
||||||
url
|
|
||||||
))
|
|
||||||
.send()
|
.send()
|
||||||
.await
|
.await
|
||||||
.expect("Failed to send request.");
|
.expect("Failed to send request.");
|
||||||
|
@ -231,7 +211,7 @@ async fn test_oauth2_openid_basic_flow(rsclient: KanidmClient) {
|
||||||
let (pkce_code_challenge, pkce_code_verifier) = PkceCodeChallenge::new_random_sha256();
|
let (pkce_code_challenge, pkce_code_verifier) = PkceCodeChallenge::new_random_sha256();
|
||||||
|
|
||||||
let response = client
|
let response = client
|
||||||
.get(format!("{}/oauth2/authorise", url))
|
.get(rsclient.make_url("/oauth2/authorise"))
|
||||||
.bearer_auth(oauth_test_uat.clone())
|
.bearer_auth(oauth_test_uat.clone())
|
||||||
.query(&[
|
.query(&[
|
||||||
("response_type", "code"),
|
("response_type", "code"),
|
||||||
|
@ -271,7 +251,7 @@ async fn test_oauth2_openid_basic_flow(rsclient: KanidmClient) {
|
||||||
// state and code.
|
// state and code.
|
||||||
|
|
||||||
let response = client
|
let response = client
|
||||||
.get(format!("{}/oauth2/authorise/permit", url))
|
.get(rsclient.make_url("/oauth2/authorise/permit"))
|
||||||
.bearer_auth(oauth_test_uat)
|
.bearer_auth(oauth_test_uat)
|
||||||
.query(&[("token", consent_token.as_str())])
|
.query(&[("token", consent_token.as_str())])
|
||||||
.send()
|
.send()
|
||||||
|
@ -312,7 +292,7 @@ async fn test_oauth2_openid_basic_flow(rsclient: KanidmClient) {
|
||||||
.into();
|
.into();
|
||||||
|
|
||||||
let response = client
|
let response = client
|
||||||
.post(format!("{}/oauth2/token", url))
|
.post(rsclient.make_url("/oauth2/token"))
|
||||||
.basic_auth("test_integration", Some(client_secret.clone()))
|
.basic_auth("test_integration", Some(client_secret.clone()))
|
||||||
.form(&form_req)
|
.form(&form_req)
|
||||||
.send()
|
.send()
|
||||||
|
@ -339,7 +319,7 @@ async fn test_oauth2_openid_basic_flow(rsclient: KanidmClient) {
|
||||||
};
|
};
|
||||||
|
|
||||||
let response = client
|
let response = client
|
||||||
.post(format!("{}/oauth2/token/introspect", url))
|
.post(rsclient.make_url("/oauth2/token/introspect"))
|
||||||
.basic_auth("test_integration", Some(client_secret))
|
.basic_auth("test_integration", Some(client_secret))
|
||||||
.form(&intr_request)
|
.form(&intr_request)
|
||||||
.send()
|
.send()
|
||||||
|
@ -381,13 +361,13 @@ async fn test_oauth2_openid_basic_flow(rsclient: KanidmClient) {
|
||||||
|
|
||||||
// This is mostly checked inside of idm/oauth2.rs. This is more to check the oidc
|
// This is mostly checked inside of idm/oauth2.rs. This is more to check the oidc
|
||||||
// token and the userinfo endpoints.
|
// token and the userinfo endpoints.
|
||||||
assert!(oidc.iss == Url::parse(&format!("{}/oauth2/openid/test_integration", url)).unwrap());
|
assert!(oidc.iss == rsclient.make_url("/oauth2/openid/test_integration"));
|
||||||
eprintln!("{:?}", oidc.s_claims.email);
|
eprintln!("{:?}", oidc.s_claims.email);
|
||||||
assert!(oidc.s_claims.email.as_deref() == Some("oauth_test@localhost"));
|
assert!(oidc.s_claims.email.as_deref() == Some("oauth_test@localhost"));
|
||||||
assert!(oidc.s_claims.email_verified == Some(true));
|
assert!(oidc.s_claims.email_verified == Some(true));
|
||||||
|
|
||||||
let response = client
|
let response = client
|
||||||
.get(format!("{}/oauth2/openid/test_integration/userinfo", url))
|
.get(rsclient.make_url("/oauth2/openid/test_integration/userinfo"))
|
||||||
.bearer_auth(atr.access_token.clone())
|
.bearer_auth(atr.access_token.clone())
|
||||||
.send()
|
.send()
|
||||||
.await
|
.await
|
||||||
|
@ -486,8 +466,6 @@ async fn test_oauth2_openid_public_flow(rsclient: KanidmClient) {
|
||||||
.await
|
.await
|
||||||
.expect("No user auth token found");
|
.expect("No user auth token found");
|
||||||
|
|
||||||
let url = rsclient.get_url().to_string();
|
|
||||||
|
|
||||||
// We need a new reqwest client here.
|
// We need a new reqwest client here.
|
||||||
|
|
||||||
// from here, we can now begin what would be a "interaction" to the oauth server.
|
// from here, we can now begin what would be a "interaction" to the oauth server.
|
||||||
|
@ -500,10 +478,7 @@ async fn test_oauth2_openid_public_flow(rsclient: KanidmClient) {
|
||||||
|
|
||||||
// Step 0 - get the jwks public key.
|
// Step 0 - get the jwks public key.
|
||||||
let response = client
|
let response = client
|
||||||
.get(format!(
|
.get(rsclient.make_url("/oauth2/openid/test_integration/public_key.jwk"))
|
||||||
"{}/oauth2/openid/test_integration/public_key.jwk",
|
|
||||||
url
|
|
||||||
))
|
|
||||||
.send()
|
.send()
|
||||||
.await
|
.await
|
||||||
.expect("Failed to send request.");
|
.expect("Failed to send request.");
|
||||||
|
@ -528,7 +503,7 @@ async fn test_oauth2_openid_public_flow(rsclient: KanidmClient) {
|
||||||
let (pkce_code_challenge, pkce_code_verifier) = PkceCodeChallenge::new_random_sha256();
|
let (pkce_code_challenge, pkce_code_verifier) = PkceCodeChallenge::new_random_sha256();
|
||||||
|
|
||||||
let response = client
|
let response = client
|
||||||
.get(format!("{}/oauth2/authorise", url))
|
.get(rsclient.make_url("/oauth2/authorise"))
|
||||||
.bearer_auth(oauth_test_uat.clone())
|
.bearer_auth(oauth_test_uat.clone())
|
||||||
.query(&[
|
.query(&[
|
||||||
("response_type", "code"),
|
("response_type", "code"),
|
||||||
|
@ -567,7 +542,7 @@ async fn test_oauth2_openid_public_flow(rsclient: KanidmClient) {
|
||||||
// Step 2 - we now send the consent get to the server which yields a redirect with a
|
// Step 2 - we now send the consent get to the server which yields a redirect with a
|
||||||
// state and code.
|
// state and code.
|
||||||
let response = client
|
let response = client
|
||||||
.get(format!("{}/oauth2/authorise/permit", url))
|
.get(rsclient.make_url("/oauth2/authorise/permit"))
|
||||||
.bearer_auth(oauth_test_uat)
|
.bearer_auth(oauth_test_uat)
|
||||||
.query(&[("token", consent_token.as_str())])
|
.query(&[("token", consent_token.as_str())])
|
||||||
.send()
|
.send()
|
||||||
|
@ -611,7 +586,7 @@ async fn test_oauth2_openid_public_flow(rsclient: KanidmClient) {
|
||||||
};
|
};
|
||||||
|
|
||||||
let response = client
|
let response = client
|
||||||
.post(format!("{}/oauth2/token", url))
|
.post(rsclient.make_url("/oauth2/token"))
|
||||||
.form(&form_req)
|
.form(&form_req)
|
||||||
.send()
|
.send()
|
||||||
.await
|
.await
|
||||||
|
@ -636,7 +611,7 @@ async fn test_oauth2_openid_public_flow(rsclient: KanidmClient) {
|
||||||
|
|
||||||
// This is mostly checked inside of idm/oauth2.rs. This is more to check the oidc
|
// This is mostly checked inside of idm/oauth2.rs. This is more to check the oidc
|
||||||
// token and the userinfo endpoints.
|
// token and the userinfo endpoints.
|
||||||
assert!(oidc.iss == Url::parse(&format!("{}/oauth2/openid/test_integration", url)).unwrap());
|
assert!(oidc.iss == rsclient.make_url("/oauth2/openid/test_integration"));
|
||||||
eprintln!("{:?}", oidc.s_claims.email);
|
eprintln!("{:?}", oidc.s_claims.email);
|
||||||
assert!(oidc.s_claims.email.as_deref() == Some("oauth_test@localhost"));
|
assert!(oidc.s_claims.email.as_deref() == Some("oauth_test@localhost"));
|
||||||
assert!(oidc.s_claims.email_verified == Some(true));
|
assert!(oidc.s_claims.email_verified == Some(true));
|
||||||
|
@ -645,7 +620,7 @@ async fn test_oauth2_openid_public_flow(rsclient: KanidmClient) {
|
||||||
let response = client
|
let response = client
|
||||||
.request(
|
.request(
|
||||||
reqwest::Method::OPTIONS,
|
reqwest::Method::OPTIONS,
|
||||||
format!("{}/oauth2/openid/test_integration/userinfo", url),
|
rsclient.make_url("/oauth2/openid/test_integration/userinfo"),
|
||||||
)
|
)
|
||||||
.send()
|
.send()
|
||||||
.await
|
.await
|
||||||
|
@ -661,7 +636,7 @@ async fn test_oauth2_openid_public_flow(rsclient: KanidmClient) {
|
||||||
assert!(cors_header.eq("*"));
|
assert!(cors_header.eq("*"));
|
||||||
|
|
||||||
let response = client
|
let response = client
|
||||||
.get(format!("{}/oauth2/openid/test_integration/userinfo", url))
|
.get(rsclient.make_url("/oauth2/openid/test_integration/userinfo"))
|
||||||
.bearer_auth(atr.access_token.clone())
|
.bearer_auth(atr.access_token.clone())
|
||||||
.send()
|
.send()
|
||||||
.await
|
.await
|
||||||
|
@ -695,7 +670,6 @@ async fn test_oauth2_token_post_bad_bodies(rsclient: KanidmClient) {
|
||||||
.await;
|
.await;
|
||||||
assert!(res.is_ok());
|
assert!(res.is_ok());
|
||||||
|
|
||||||
let url = rsclient.get_url().to_string();
|
|
||||||
let client = reqwest::Client::builder()
|
let client = reqwest::Client::builder()
|
||||||
.redirect(reqwest::redirect::Policy::none())
|
.redirect(reqwest::redirect::Policy::none())
|
||||||
.no_proxy()
|
.no_proxy()
|
||||||
|
@ -704,7 +678,7 @@ async fn test_oauth2_token_post_bad_bodies(rsclient: KanidmClient) {
|
||||||
|
|
||||||
// test for a bad-body request on token
|
// test for a bad-body request on token
|
||||||
let response = client
|
let response = client
|
||||||
.post(format!("{}/oauth2/token", url))
|
.post(rsclient.make_url("/oauth2/token"))
|
||||||
.form(&serde_json::json!({}))
|
.form(&serde_json::json!({}))
|
||||||
// .bearer_auth(atr.access_token.clone())
|
// .bearer_auth(atr.access_token.clone())
|
||||||
.send()
|
.send()
|
||||||
|
@ -715,7 +689,7 @@ async fn test_oauth2_token_post_bad_bodies(rsclient: KanidmClient) {
|
||||||
|
|
||||||
// test for a bad-auth request
|
// test for a bad-auth request
|
||||||
let response = client
|
let response = client
|
||||||
.post(format!("{}/oauth2/token/introspect", url))
|
.post(rsclient.make_url("/oauth2/token/introspect"))
|
||||||
.form(&serde_json::json!({ "token": "lol" }))
|
.form(&serde_json::json!({ "token": "lol" }))
|
||||||
.send()
|
.send()
|
||||||
.await
|
.await
|
||||||
|
@ -731,7 +705,6 @@ async fn test_oauth2_token_revoke_post(rsclient: KanidmClient) {
|
||||||
.await;
|
.await;
|
||||||
assert!(res.is_ok());
|
assert!(res.is_ok());
|
||||||
|
|
||||||
let url = rsclient.get_url().to_string();
|
|
||||||
let client = reqwest::Client::builder()
|
let client = reqwest::Client::builder()
|
||||||
.redirect(reqwest::redirect::Policy::none())
|
.redirect(reqwest::redirect::Policy::none())
|
||||||
.no_proxy()
|
.no_proxy()
|
||||||
|
@ -740,7 +713,7 @@ async fn test_oauth2_token_revoke_post(rsclient: KanidmClient) {
|
||||||
|
|
||||||
// test for a bad-body request on token
|
// test for a bad-body request on token
|
||||||
let response = client
|
let response = client
|
||||||
.post(format!("{}/oauth2/token/revoke", url))
|
.post(rsclient.make_url("/oauth2/token/revoke"))
|
||||||
.form(&serde_json::json!({}))
|
.form(&serde_json::json!({}))
|
||||||
.bearer_auth("lolol")
|
.bearer_auth("lolol")
|
||||||
.send()
|
.send()
|
||||||
|
@ -751,7 +724,7 @@ async fn test_oauth2_token_revoke_post(rsclient: KanidmClient) {
|
||||||
|
|
||||||
// test for a invalid format request on token
|
// test for a invalid format request on token
|
||||||
let response = client
|
let response = client
|
||||||
.post(format!("{}/oauth2/token/revoke", url))
|
.post(rsclient.make_url("/oauth2/token/revoke"))
|
||||||
.json("")
|
.json("")
|
||||||
.bearer_auth("lolol")
|
.bearer_auth("lolol")
|
||||||
.send()
|
.send()
|
||||||
|
@ -763,7 +736,7 @@ async fn test_oauth2_token_revoke_post(rsclient: KanidmClient) {
|
||||||
|
|
||||||
// test for a bad-body request on token
|
// test for a bad-body request on token
|
||||||
let response = client
|
let response = client
|
||||||
.post(format!("{}/oauth2/token/revoke", url))
|
.post(rsclient.make_url("/oauth2/token/revoke"))
|
||||||
.form(&serde_json::json!({}))
|
.form(&serde_json::json!({}))
|
||||||
.bearer_auth("Basic lolol")
|
.bearer_auth("Basic lolol")
|
||||||
.send()
|
.send()
|
||||||
|
@ -774,7 +747,7 @@ async fn test_oauth2_token_revoke_post(rsclient: KanidmClient) {
|
||||||
|
|
||||||
// test for a bad-body request on token
|
// test for a bad-body request on token
|
||||||
let response = client
|
let response = client
|
||||||
.post(format!("{}/oauth2/token/revoke", url))
|
.post(rsclient.make_url("/oauth2/token/revoke"))
|
||||||
.body(serde_json::json!({}).to_string())
|
.body(serde_json::json!({}).to_string())
|
||||||
.bearer_auth("Basic lolol")
|
.bearer_auth("Basic lolol")
|
||||||
.send()
|
.send()
|
||||||
|
|
|
@ -6,7 +6,6 @@ use reqwest::header::CONTENT_TYPE;
|
||||||
#[kanidmd_testkit::test]
|
#[kanidmd_testkit::test]
|
||||||
async fn test_v1_person_patch(rsclient: KanidmClient) {
|
async fn test_v1_person_patch(rsclient: KanidmClient) {
|
||||||
// We need to do manual reqwests here.
|
// We need to do manual reqwests here.
|
||||||
let addr = rsclient.get_url();
|
|
||||||
let client = reqwest::ClientBuilder::new()
|
let client = reqwest::ClientBuilder::new()
|
||||||
.danger_accept_invalid_certs(true)
|
.danger_accept_invalid_certs(true)
|
||||||
.build()
|
.build()
|
||||||
|
@ -15,7 +14,7 @@ async fn test_v1_person_patch(rsclient: KanidmClient) {
|
||||||
let post_body = serde_json::json!({"attrs": { "email" : "crab@example.com"}}).to_string();
|
let post_body = serde_json::json!({"attrs": { "email" : "crab@example.com"}}).to_string();
|
||||||
|
|
||||||
let response = match client
|
let response = match client
|
||||||
.patch(format!("{}/v1/person/foo", &addr))
|
.patch(rsclient.make_url("/v1/person/foo"))
|
||||||
.header(CONTENT_TYPE, APPLICATION_JSON)
|
.header(CONTENT_TYPE, APPLICATION_JSON)
|
||||||
.body(post_body)
|
.body(post_body)
|
||||||
.send()
|
.send()
|
||||||
|
@ -23,7 +22,11 @@ async fn test_v1_person_patch(rsclient: KanidmClient) {
|
||||||
{
|
{
|
||||||
Ok(value) => value,
|
Ok(value) => value,
|
||||||
Err(error) => {
|
Err(error) => {
|
||||||
panic!("Failed to query {:?} : {:#?}", addr, error);
|
panic!(
|
||||||
|
"Failed to query {:?} : {:#?}",
|
||||||
|
rsclient.make_url("/v1/person/foo"),
|
||||||
|
error
|
||||||
|
);
|
||||||
}
|
}
|
||||||
};
|
};
|
||||||
eprintln!("response: {:#?}", response);
|
eprintln!("response: {:#?}", response);
|
||||||
|
|
|
@ -120,6 +120,7 @@ async fn test_server_search(rsclient: KanidmClient) {
|
||||||
// First show we are un-authenticated.
|
// First show we are un-authenticated.
|
||||||
let pre_res = rsclient.whoami().await;
|
let pre_res = rsclient.whoami().await;
|
||||||
// This means it was okay whoami, but no uat attached.
|
// This means it was okay whoami, but no uat attached.
|
||||||
|
println!("Response: {:?}", pre_res);
|
||||||
assert!(pre_res.unwrap().is_none());
|
assert!(pre_res.unwrap().is_none());
|
||||||
|
|
||||||
let res = rsclient
|
let res = rsclient
|
||||||
|
|
|
@ -93,7 +93,6 @@ async fn test_sync_account_lifecycle(rsclient: KanidmClient) {
|
||||||
#[kanidmd_testkit::test]
|
#[kanidmd_testkit::test]
|
||||||
async fn test_scim_sync_get(rsclient: KanidmClient) {
|
async fn test_scim_sync_get(rsclient: KanidmClient) {
|
||||||
// We need to do manual reqwests here.
|
// We need to do manual reqwests here.
|
||||||
let addr = rsclient.get_url();
|
|
||||||
|
|
||||||
let mut headers = reqwest::header::HeaderMap::new();
|
let mut headers = reqwest::header::HeaderMap::new();
|
||||||
headers.insert(
|
headers.insert(
|
||||||
|
@ -107,10 +106,14 @@ async fn test_scim_sync_get(rsclient: KanidmClient) {
|
||||||
.build()
|
.build()
|
||||||
.unwrap();
|
.unwrap();
|
||||||
// here we test the /ui/ endpoint which should have the headers
|
// here we test the /ui/ endpoint which should have the headers
|
||||||
let response = match client.get(format!("{}/scim/v1/Sync", addr)).send().await {
|
let response = match client.get(rsclient.make_url("/scim/v1/Sync")).send().await {
|
||||||
Ok(value) => value,
|
Ok(value) => value,
|
||||||
Err(error) => {
|
Err(error) => {
|
||||||
panic!("Failed to query {:?} : {:#?}", addr, error);
|
panic!(
|
||||||
|
"Failed to query {:?} : {:#?}",
|
||||||
|
rsclient.make_url("/scim/v1/Sync"),
|
||||||
|
error
|
||||||
|
);
|
||||||
}
|
}
|
||||||
};
|
};
|
||||||
eprintln!("response: {:#?}", response);
|
eprintln!("response: {:#?}", response);
|
||||||
|
|
|
@ -4,20 +4,23 @@ use kanidm_client::KanidmClient;
|
||||||
#[kanidmd_testkit::test]
|
#[kanidmd_testkit::test]
|
||||||
async fn test_v1_self_applinks(rsclient: KanidmClient) {
|
async fn test_v1_self_applinks(rsclient: KanidmClient) {
|
||||||
// We need to do manual reqwests here.
|
// We need to do manual reqwests here.
|
||||||
let addr = rsclient.get_url();
|
|
||||||
let client = reqwest::ClientBuilder::new()
|
let client = reqwest::ClientBuilder::new()
|
||||||
.danger_accept_invalid_certs(true)
|
.danger_accept_invalid_certs(true)
|
||||||
.build()
|
.build()
|
||||||
.unwrap();
|
.unwrap();
|
||||||
|
|
||||||
let response = match client
|
let response = match client
|
||||||
.get(format!("{}/v1/self/_applinks", &addr))
|
.get(rsclient.make_url("/v1/self/_applinks"))
|
||||||
.send()
|
.send()
|
||||||
.await
|
.await
|
||||||
{
|
{
|
||||||
Ok(value) => value,
|
Ok(value) => value,
|
||||||
Err(error) => {
|
Err(error) => {
|
||||||
panic!("Failed to query {:?} : {:#?}", addr, error);
|
panic!(
|
||||||
|
"Failed to query {:?} : {:#?}",
|
||||||
|
rsclient.make_url("/v1/self/_applinks"),
|
||||||
|
error
|
||||||
|
);
|
||||||
}
|
}
|
||||||
};
|
};
|
||||||
eprintln!("response: {:#?}", response);
|
eprintln!("response: {:#?}", response);
|
||||||
|
@ -31,16 +34,19 @@ async fn test_v1_self_applinks(rsclient: KanidmClient) {
|
||||||
#[kanidmd_testkit::test]
|
#[kanidmd_testkit::test]
|
||||||
async fn test_v1_self_whoami_uat(rsclient: KanidmClient) {
|
async fn test_v1_self_whoami_uat(rsclient: KanidmClient) {
|
||||||
// We need to do manual reqwests here.
|
// We need to do manual reqwests here.
|
||||||
let addr = rsclient.get_url();
|
|
||||||
let client = reqwest::ClientBuilder::new()
|
let client = reqwest::ClientBuilder::new()
|
||||||
.danger_accept_invalid_certs(true)
|
.danger_accept_invalid_certs(true)
|
||||||
.build()
|
.build()
|
||||||
.unwrap();
|
.unwrap();
|
||||||
|
|
||||||
let response = match client.get(format!("{}/v1/self/_uat", &addr)).send().await {
|
let response = match client.get(rsclient.make_url("/v1/self/_uat")).send().await {
|
||||||
Ok(value) => value,
|
Ok(value) => value,
|
||||||
Err(error) => {
|
Err(error) => {
|
||||||
panic!("Failed to query {:?} : {:#?}", addr, error);
|
panic!(
|
||||||
|
"Failed to query {:?} : {:#?}",
|
||||||
|
rsclient.make_url("/v1/self/_uat"),
|
||||||
|
error
|
||||||
|
);
|
||||||
}
|
}
|
||||||
};
|
};
|
||||||
eprintln!("response: {:#?}", response);
|
eprintln!("response: {:#?}", response);
|
||||||
|
|
|
@ -4,7 +4,6 @@ use kanidm_client::KanidmClient;
|
||||||
#[kanidmd_testkit::test]
|
#[kanidmd_testkit::test]
|
||||||
async fn test_v1_service_account_id_attr_attr_delete(rsclient: KanidmClient) {
|
async fn test_v1_service_account_id_attr_attr_delete(rsclient: KanidmClient) {
|
||||||
// We need to do manual reqwests here.
|
// We need to do manual reqwests here.
|
||||||
let addr = rsclient.get_url();
|
|
||||||
let client = reqwest::ClientBuilder::new()
|
let client = reqwest::ClientBuilder::new()
|
||||||
.danger_accept_invalid_certs(true)
|
.danger_accept_invalid_certs(true)
|
||||||
.build()
|
.build()
|
||||||
|
@ -13,13 +12,17 @@ async fn test_v1_service_account_id_attr_attr_delete(rsclient: KanidmClient) {
|
||||||
// let post_body = serde_json::json!({"filter": "self"}).to_string();
|
// let post_body = serde_json::json!({"filter": "self"}).to_string();
|
||||||
|
|
||||||
let response = match client
|
let response = match client
|
||||||
.delete(format!("{}/v1/service_account/admin/_attr/email", &addr))
|
.delete(rsclient.make_url("/v1/service_account/admin/_attr/email"))
|
||||||
.send()
|
.send()
|
||||||
.await
|
.await
|
||||||
{
|
{
|
||||||
Ok(value) => value,
|
Ok(value) => value,
|
||||||
Err(error) => {
|
Err(error) => {
|
||||||
panic!("Failed to query {:?} : {:#?}", addr, error);
|
panic!(
|
||||||
|
"Failed to query {:?} : {:#?}",
|
||||||
|
rsclient.make_url("/v1/service_account/admin/_attr/email"),
|
||||||
|
error
|
||||||
|
);
|
||||||
}
|
}
|
||||||
};
|
};
|
||||||
eprintln!("response: {:#?}", response);
|
eprintln!("response: {:#?}", response);
|
||||||
|
|
|
@ -3,22 +3,24 @@ use kanidm_client::KanidmClient;
|
||||||
/// This literally tests that the thing exists and responds in a way we expect, probably worth testing it better...
|
/// This literally tests that the thing exists and responds in a way we expect, probably worth testing it better...
|
||||||
#[kanidmd_testkit::test]
|
#[kanidmd_testkit::test]
|
||||||
async fn test_v1_system_post_attr(rsclient: KanidmClient) {
|
async fn test_v1_system_post_attr(rsclient: KanidmClient) {
|
||||||
// We need to do manual reqwests here.
|
|
||||||
let addr = rsclient.get_url();
|
|
||||||
let client = reqwest::ClientBuilder::new()
|
let client = reqwest::ClientBuilder::new()
|
||||||
.danger_accept_invalid_certs(true)
|
.danger_accept_invalid_certs(true)
|
||||||
.build()
|
.build()
|
||||||
.unwrap();
|
.unwrap();
|
||||||
|
|
||||||
let response = match client
|
let response = match client
|
||||||
.post(format!("{}/v1/system/_attr/domain_name", &addr))
|
.post(rsclient.make_url("/v1/system/_attr/domain_name"))
|
||||||
.json(&serde_json::json!({"filter": "self"}))
|
.json(&serde_json::json!({"filter": "self"}))
|
||||||
.send()
|
.send()
|
||||||
.await
|
.await
|
||||||
{
|
{
|
||||||
Ok(value) => value,
|
Ok(value) => value,
|
||||||
Err(error) => {
|
Err(error) => {
|
||||||
panic!("Failed to query {:?} : {:#?}", addr, error);
|
panic!(
|
||||||
|
"Failed to query {:?} : {:#?}",
|
||||||
|
rsclient.make_url("v1/system/_attr/domain_name"),
|
||||||
|
error
|
||||||
|
);
|
||||||
}
|
}
|
||||||
};
|
};
|
||||||
eprintln!("response: {:#?}", response);
|
eprintln!("response: {:#?}", response);
|
||||||
|
|
46
server/testkit/tests/unix.rs
Normal file
46
server/testkit/tests/unix.rs
Normal file
|
@ -0,0 +1,46 @@
|
||||||
|
use kanidm_client::KanidmClient;
|
||||||
|
use kanidmd_testkit::*;
|
||||||
|
|
||||||
|
#[kanidmd_testkit::test]
|
||||||
|
async fn account_id_unix_token(rsclient: KanidmClient) {
|
||||||
|
login_put_admin_idm_admins(&rsclient).await;
|
||||||
|
|
||||||
|
create_user(&rsclient, "group_manager", "idm_group_manage_priv").await;
|
||||||
|
// create test user without creating new groups
|
||||||
|
create_user(&rsclient, NOT_ADMIN_TEST_USERNAME, "idm_admins").await;
|
||||||
|
login_account(&rsclient, "group_manager").await;
|
||||||
|
|
||||||
|
let response = rsclient
|
||||||
|
.idm_account_unix_token_get(NOT_ADMIN_TEST_USERNAME)
|
||||||
|
.await;
|
||||||
|
assert!(response.is_err());
|
||||||
|
if let Err(val) = response {
|
||||||
|
assert!(format!("{:?}", val).contains("404"));
|
||||||
|
}
|
||||||
|
|
||||||
|
let response = rsclient.idm_account_unix_token_get("lol").await;
|
||||||
|
assert!(response.is_err());
|
||||||
|
if let Err(val) = response {
|
||||||
|
assert!(format!("{:?}", val).contains("404"));
|
||||||
|
}
|
||||||
|
|
||||||
|
// testing empty results
|
||||||
|
let response = rsclient.idm_account_unix_token_get("").await;
|
||||||
|
assert!(response.is_err());
|
||||||
|
if let Err(val) = response {
|
||||||
|
assert!(format!("{:?}", val).contains("400"));
|
||||||
|
}
|
||||||
|
|
||||||
|
login_put_admin_idm_admins(&rsclient).await;
|
||||||
|
|
||||||
|
rsclient
|
||||||
|
.idm_person_account_unix_extend(NOT_ADMIN_TEST_USERNAME, None, None)
|
||||||
|
.await
|
||||||
|
.unwrap();
|
||||||
|
|
||||||
|
// testing NOT_ADMIN_TEST_USERNAME has a token result, since we just added one
|
||||||
|
assert!(rsclient
|
||||||
|
.idm_account_unix_token_get(NOT_ADMIN_TEST_USERNAME)
|
||||||
|
.await
|
||||||
|
.is_ok());
|
||||||
|
}
|
|
@ -16,7 +16,6 @@ use qrcode::render::unicode;
|
||||||
use qrcode::QrCode;
|
use qrcode::QrCode;
|
||||||
use time::format_description::well_known::Rfc3339;
|
use time::format_description::well_known::Rfc3339;
|
||||||
use time::OffsetDateTime;
|
use time::OffsetDateTime;
|
||||||
use url::Url;
|
|
||||||
use uuid::Uuid;
|
use uuid::Uuid;
|
||||||
|
|
||||||
use crate::webauthn::get_authenticator;
|
use crate::webauthn::get_authenticator;
|
||||||
|
@ -603,14 +602,7 @@ impl AccountCredential {
|
||||||
.await
|
.await
|
||||||
{
|
{
|
||||||
Ok(cuintent_token) => {
|
Ok(cuintent_token) => {
|
||||||
let mut url = match Url::parse(client.get_url()) {
|
let mut url = client.make_url("/ui/reset");
|
||||||
Ok(u) => u,
|
|
||||||
Err(e) => {
|
|
||||||
error!("Unable to parse url - {:?}", e);
|
|
||||||
return;
|
|
||||||
}
|
|
||||||
};
|
|
||||||
url.set_path("/ui/reset");
|
|
||||||
url.query_pairs_mut()
|
url.query_pairs_mut()
|
||||||
.append_pair("token", cuintent_token.token.as_str());
|
.append_pair("token", cuintent_token.token.as_str());
|
||||||
|
|
||||||
|
|
|
@ -78,11 +78,19 @@ pub struct DbTxn<'a> {
|
||||||
require_tpm: Option<&'a tpm::TpmConfig>,
|
require_tpm: Option<&'a tpm::TpmConfig>,
|
||||||
}
|
}
|
||||||
|
|
||||||
|
#[derive(Debug)]
|
||||||
|
/// Errors coming back from the `Db` struct
|
||||||
|
pub enum DbError {
|
||||||
|
Sqlite,
|
||||||
|
Tpm,
|
||||||
|
}
|
||||||
|
|
||||||
impl Db {
|
impl Db {
|
||||||
pub fn new(path: &str, tpm_policy: &TpmPolicy) -> Result<Self, ()> {
|
pub fn new(path: &str, tpm_policy: &TpmPolicy) -> Result<Self, DbError> {
|
||||||
let before = unsafe { umask(0o0027) };
|
let before = unsafe { umask(0o0027) };
|
||||||
let conn = Connection::open(path).map_err(|e| {
|
let conn = Connection::open(path).map_err(|e| {
|
||||||
error!(err = ?e, "rusqulite error");
|
error!(err = ?e, "rusqulite error");
|
||||||
|
DbError::Sqlite
|
||||||
})?;
|
})?;
|
||||||
let _ = unsafe { umask(before) };
|
let _ = unsafe { umask(before) };
|
||||||
// We only build a single thread. If we need more than one, we'll
|
// We only build a single thread. If we need more than one, we'll
|
||||||
|
@ -96,7 +104,9 @@ impl Db {
|
||||||
let require_tpm = match tpm_policy {
|
let require_tpm = match tpm_policy {
|
||||||
TpmPolicy::Ignore => None,
|
TpmPolicy::Ignore => None,
|
||||||
TpmPolicy::IfPossible(tcti_str) => Db::tpm_setup_context(tcti_str, &conn).ok(),
|
TpmPolicy::IfPossible(tcti_str) => Db::tpm_setup_context(tcti_str, &conn).ok(),
|
||||||
TpmPolicy::Required(tcti_str) => Some(Db::tpm_setup_context(tcti_str, &conn)?),
|
TpmPolicy::Required(tcti_str) => {
|
||||||
|
Some(Db::tpm_setup_context(tcti_str, &conn).map_err(|_| DbError::Tpm)?)
|
||||||
|
}
|
||||||
};
|
};
|
||||||
|
|
||||||
Ok(Db {
|
Ok(Db {
|
||||||
|
@ -784,16 +794,19 @@ impl<'a> Drop for DbTxn<'a> {
|
||||||
|
|
||||||
#[cfg(not(feature = "tpm"))]
|
#[cfg(not(feature = "tpm"))]
|
||||||
pub(crate) mod tpm {
|
pub(crate) mod tpm {
|
||||||
use super::Db;
|
use super::{Db, DbError};
|
||||||
|
|
||||||
use rusqlite::Connection;
|
use rusqlite::Connection;
|
||||||
|
|
||||||
pub struct TpmConfig {}
|
pub struct TpmConfig {}
|
||||||
|
|
||||||
impl Db {
|
impl Db {
|
||||||
pub fn tpm_setup_context(_tcti_str: &str, _conn: &Connection) -> Result<TpmConfig, ()> {
|
pub fn tpm_setup_context(
|
||||||
|
_tcti_str: &str,
|
||||||
|
_conn: &Connection,
|
||||||
|
) -> Result<TpmConfig, DbError> {
|
||||||
warn!("tpm feature is not available in this build");
|
warn!("tpm feature is not available in this build");
|
||||||
Err(())
|
Err(DbError::Tpm)
|
||||||
}
|
}
|
||||||
}
|
}
|
||||||
}
|
}
|
||||||
|
|
Loading…
Reference in a new issue