mirror of
https://github.com/kanidm/kanidm.git
synced 2025-02-23 20:47:01 +01:00
Offer configuration of images for Oauth2 resources (#2665)
This commit is contained in:
parent
f9a77ee1f3
commit
4795541719
1
Cargo.lock
generated
1
Cargo.lock
generated
|
@ -3316,6 +3316,7 @@ dependencies = [
|
|||
name = "kanidm_tools"
|
||||
version = "1.3.0-dev"
|
||||
dependencies = [
|
||||
"anyhow",
|
||||
"async-recursion",
|
||||
"clap",
|
||||
"clap_complete",
|
||||
|
|
|
@ -140,6 +140,7 @@ kanidm_unix_common = { path = "./unix_integration/common", version = "=1.3.0-dev
|
|||
kanidm_utils_users = { path = "./libs/users", version = "=1.3.0-dev" }
|
||||
sketching = { path = "./libs/sketching", version = "=1.3.0-dev" }
|
||||
|
||||
anyhow = { version = "1.0.86" }
|
||||
argon2 = { version = "0.5.3", features = ["alloc"] }
|
||||
askama = { version = "0.12.1", features = ["serde"] }
|
||||
async-recursion = "1.1.0"
|
||||
|
|
|
@ -35,8 +35,8 @@ pub enum AppLink {
|
|||
name: String,
|
||||
display_name: String,
|
||||
redirect_url: Url,
|
||||
// Where the icon can be retrieved from.
|
||||
icon: Option<Url>,
|
||||
// Whether this oauth2 resource has an image.
|
||||
has_image: bool,
|
||||
},
|
||||
}
|
||||
|
||||
|
|
|
@ -51,11 +51,13 @@ impl<'a> IdmServerProxyReadTransaction<'a> {
|
|||
.get_ava_single_iname(Attribute::Name)
|
||||
.map(str::to_string)?;
|
||||
|
||||
let has_image = entry.get_ava_single_image(Attribute::Image).is_some();
|
||||
|
||||
Some(AppLink::Oauth2 {
|
||||
name,
|
||||
display_name,
|
||||
redirect_url,
|
||||
icon: None,
|
||||
has_image,
|
||||
})
|
||||
})
|
||||
.collect::<Vec<_>>();
|
||||
|
@ -181,14 +183,14 @@ mod tests {
|
|||
name,
|
||||
display_name,
|
||||
redirect_url,
|
||||
icon,
|
||||
has_image,
|
||||
} => {
|
||||
name == "test_resource_server"
|
||||
&& display_name == "test_resource_server"
|
||||
&& redirect_url
|
||||
== &Url::parse("https://demo.example.com/landing")
|
||||
.expect("Failed to parse URL")
|
||||
&& icon.is_none()
|
||||
&& !has_image
|
||||
} // _ => false,
|
||||
})
|
||||
}
|
||||
|
|
|
@ -121,7 +121,7 @@ impl AppsApp {
|
|||
name,
|
||||
display_name,
|
||||
redirect_url,
|
||||
icon: _,
|
||||
has_image: _,
|
||||
} => {
|
||||
let redirect_url = redirect_url.to_string();
|
||||
html!{
|
||||
|
|
|
@ -35,6 +35,7 @@ test = true
|
|||
doctest = false
|
||||
|
||||
[dependencies]
|
||||
anyhow = { workspace = true }
|
||||
async-recursion = { workspace = true }
|
||||
clap = { workspace = true, features = ["derive", "env"] }
|
||||
compact_jwt = { workspace = true, features = ["openssl"] }
|
||||
|
|
|
@ -1,10 +1,11 @@
|
|||
use anyhow::{Context, Error};
|
||||
use std::fs::read;
|
||||
use std::process::exit;
|
||||
|
||||
use crate::common::OpType;
|
||||
use crate::{handle_client_error, Oauth2Opt, OutputMode};
|
||||
|
||||
use crate::Oauth2ClaimMapJoin;
|
||||
use kanidm_proto::internal::Oauth2ClaimMapJoin as ProtoOauth2ClaimMapJoin;
|
||||
use kanidm_proto::internal::{ImageValue, Oauth2ClaimMapJoin as ProtoOauth2ClaimMapJoin};
|
||||
|
||||
impl Oauth2Opt {
|
||||
pub fn debug(&self) -> bool {
|
||||
|
@ -22,6 +23,8 @@ impl Oauth2Opt {
|
|||
Oauth2Opt::SetDisplayname(cbopt) => cbopt.nopt.copt.debug,
|
||||
Oauth2Opt::SetName { nopt, .. } => nopt.copt.debug,
|
||||
Oauth2Opt::SetLandingUrl { nopt, .. } => nopt.copt.debug,
|
||||
Oauth2Opt::SetImage { nopt, .. } => nopt.copt.debug,
|
||||
Oauth2Opt::RemoveImage(nopt) => nopt.copt.debug,
|
||||
Oauth2Opt::EnablePkce(nopt) => nopt.copt.debug,
|
||||
Oauth2Opt::DisablePkce(nopt) => nopt.copt.debug,
|
||||
Oauth2Opt::EnableLegacyCrypto(nopt) => nopt.copt.debug,
|
||||
|
@ -248,6 +251,64 @@ impl Oauth2Opt {
|
|||
Err(e) => handle_client_error(e, nopt.copt.output_mode),
|
||||
}
|
||||
}
|
||||
Oauth2Opt::SetImage {
|
||||
nopt,
|
||||
path,
|
||||
image_type,
|
||||
} => {
|
||||
let client = nopt.copt.to_client(OpType::Write).await;
|
||||
let img_res: Result<ImageValue, Error> = (move || {
|
||||
let file_name = path
|
||||
.file_name()
|
||||
.context("Please pass a file")?
|
||||
.to_str()
|
||||
.context("Path contains non utf-8")?
|
||||
.to_string();
|
||||
|
||||
let image_type = if let Some(image_type) = image_type {
|
||||
image_type.as_str().try_into().map_err(Error::msg)?
|
||||
} else {
|
||||
path
|
||||
.extension().context("Path has no extension so we can't infer the imageType, or you could pass the optional imageType argument yourself.")?
|
||||
.to_str().context("Path contains invalid utf-8")?
|
||||
.try_into()
|
||||
.map_err(Error::msg)?
|
||||
};
|
||||
|
||||
let read_res = read(path);
|
||||
match read_res {
|
||||
Ok(data) => Ok(ImageValue::new(file_name, image_type, data)),
|
||||
Err(err) => Err(err).context("Reading error"),
|
||||
}
|
||||
})();
|
||||
|
||||
let img = match img_res {
|
||||
Ok(img) => img,
|
||||
Err(err) => {
|
||||
eprintln!("{err}");
|
||||
return;
|
||||
}
|
||||
};
|
||||
|
||||
match client
|
||||
.idm_oauth2_rs_update_image(nopt.name.as_str(), img)
|
||||
.await
|
||||
{
|
||||
Ok(_) => println!("Success"),
|
||||
Err(e) => handle_client_error(e, nopt.copt.output_mode),
|
||||
}
|
||||
}
|
||||
Oauth2Opt::RemoveImage(nopt) => {
|
||||
let client = nopt.copt.to_client(OpType::Write).await;
|
||||
|
||||
match client
|
||||
.idm_oauth2_rs_delete_image(nopt.name.as_str())
|
||||
.await
|
||||
{
|
||||
Ok(_) => println!("Success"),
|
||||
Err(e) => handle_client_error(e, nopt.copt.output_mode),
|
||||
}
|
||||
}
|
||||
Oauth2Opt::EnablePkce(nopt) => {
|
||||
let client = nopt.copt.to_client(OpType::Write).await;
|
||||
match client.idm_oauth2_rs_enable_pkce(nopt.name.as_str()).await {
|
||||
|
|
|
@ -1048,6 +1048,19 @@ pub enum Oauth2Opt {
|
|||
#[clap(name = "landing-url")]
|
||||
url: Url,
|
||||
},
|
||||
/// The image presented on the Kanidm Apps Listing page for an oauth2 resource server.
|
||||
#[clap(name="set-image")]
|
||||
SetImage {
|
||||
#[clap(flatten)]
|
||||
nopt: Named,
|
||||
#[clap(name = "file-path")]
|
||||
path: PathBuf,
|
||||
#[clap(name = "image-type")]
|
||||
image_type: Option<String>,
|
||||
},
|
||||
/// Removes the custom image previously set.
|
||||
#[clap(name="remove-image")]
|
||||
RemoveImage(Named),
|
||||
|
||||
/// Add a supplemental origin as a redirection target. For example a phone app
|
||||
/// may use a redirect URL such as `app://my-cool-app` to trigger a native
|
||||
|
@ -1070,7 +1083,6 @@ pub enum Oauth2Opt {
|
|||
#[clap(flatten)]
|
||||
copt: CommonOpt,
|
||||
},
|
||||
|
||||
#[clap(name = "enable-pkce")]
|
||||
/// Enable PKCE on this oauth2 client. This defaults to being enabled.
|
||||
EnablePkce(Named),
|
||||
|
|
Loading…
Reference in a new issue