Skip to content
Draft
Show file tree
Hide file tree
Changes from all commits
Commits
File filter

Filter by extension

Filter by extension

Conversations
Failed to load comments.
Loading
Jump to
Jump to file
Failed to load files.
Loading
Diff view
Diff view
6 changes: 6 additions & 0 deletions identity/aziot-identity-client-async/src/lib.rs
Original file line number Diff line number Diff line change
Expand Up @@ -131,12 +131,14 @@ impl Client {
pub async fn create_module_identity(
&self,
module_name: &str,
managed_by: Option<String>,
) -> Result<Identity, std::io::Error> {
let uri = make_uri!("/identities/modules", self.api_version);

let body = create_module_identity::Request {
id_type: ID_TYPE_AZIOT.to_string(),
module_id: module_name.to_string(),
managed_by,
opts: None,
};

Expand All @@ -154,6 +156,7 @@ impl Client {
pub async fn create_local_identity(
&self,
module_name: &str,
managed_by: Option<String>,
opts: Option<aziot_identity_common::LocalIdOpts>,
) -> Result<Identity, std::io::Error> {
let uri = make_uri!("/identities/modules", self.api_version);
Expand All @@ -162,6 +165,7 @@ impl Client {
let body = create_module_identity::Request {
id_type: ID_TYPE_LOCAL.to_string(),
module_id: module_name.to_string(),
managed_by,
opts: opts.map(|opts| create_module_identity::CreateModuleOpts::LocalIdOpts(opts)),
};

Expand All @@ -179,6 +183,7 @@ impl Client {
pub async fn update_module_identity(
&self,
module_name: &str,
managed_by: Option<String>,
) -> Result<Identity, std::io::Error> {
let uri = make_uri!(
"/identities/modules",
Expand All @@ -190,6 +195,7 @@ impl Client {
let body = update_module_identity::Request {
id_type: ID_TYPE_AZIOT.to_string(),
module_id: module_name.to_string(),
managed_by,
};

let request = HttpRequest::put(self.connector.clone(), uri, body)
Expand Down
4 changes: 4 additions & 0 deletions identity/aziot-identity-common-http/src/lib.rs
Original file line number Diff line number Diff line change
Expand Up @@ -68,6 +68,8 @@ pub mod create_module_identity {
pub id_type: String,
#[serde(rename = "moduleId")]
pub module_id: String,
#[serde(rename = "managedBy", skip_serializing_if = "Option::is_none")]
pub managed_by: Option<String>,
#[serde(flatten)]
pub opts: Option<CreateModuleOpts>,
}
Expand All @@ -86,6 +88,8 @@ pub mod update_module_identity {
pub id_type: String,
#[serde(rename = "moduleId")]
pub module_id: String,
#[serde(rename = "managedBy", skip_serializing_if = "Option::is_none")]
pub managed_by: Option<String>,
}

#[derive(Clone, Debug, serde::Deserialize, serde::Serialize)]
Expand Down
2 changes: 2 additions & 0 deletions identity/aziot-identity-common/src/lib.rs
Original file line number Diff line number Diff line change
Expand Up @@ -38,6 +38,8 @@ pub struct AzureIoTSpec {
pub gen_id: Option<GenId>,
#[serde(rename = "auth", skip_serializing_if = "Option::is_none")]
pub auth: Option<AuthenticationInfo>,
#[serde(rename = "managedBy", skip_serializing_if = "Option::is_none")]
pub managed_by: Option<String>,
}

#[derive(Clone, Debug, serde::Deserialize, serde::Serialize)]
Expand Down
Original file line number Diff line number Diff line change
Expand Up @@ -77,7 +77,13 @@ impl http_common::server::Route for Route {
};

let identity = match api
.create_identity(auth_id, Some(&body.id_type), &body.module_id, body.opts)
.create_identity(
auth_id,
Some(&body.id_type),
&body.module_id,
body.managed_by,
body.opts,
)
.await
{
Ok(id) => id,
Expand Down
Original file line number Diff line number Diff line change
Expand Up @@ -13,6 +13,12 @@ pub(super) struct Route {
user: aziot_identityd_config::Credentials,
}

#[derive(Clone, Debug, serde::Deserialize, serde::Serialize)]
pub struct UpdateIdentityRequest {
#[serde(rename = "managedBy", skip_serializing_if = "Option::is_none")]
pub managed_by: Option<String>,
}

#[async_trait::async_trait]
impl http_common::server::Route for Route {
type ApiVersion = aziot_identity_common_http::ApiVersion;
Expand Down Expand Up @@ -96,14 +102,14 @@ impl http_common::server::Route for Route {

type PostBody = serde::de::IgnoredAny;

type PutBody = serde::de::IgnoredAny;
type PutBody = UpdateIdentityRequest;
// clippy fires this lint for the `_body` parameter of the inner fn in the `async-trait` expansion.
// It's not clear why clippy does this, especially since it doesn't raise it for other functions
// that also ignore their `_body` parameter like `fn delete` above.
//
// So suppress it manually.
#[allow(clippy::needless_pass_by_value)]
async fn put(self, _body: Self::PutBody) -> http_common::server::RouteResponse {
async fn put(self, body: Self::PutBody) -> http_common::server::RouteResponse {
let mut api = self.api.lock().await;
let api = &mut *api;

Expand All @@ -113,7 +119,12 @@ impl http_common::server::Route for Route {
};

let identity = match api
.update_identity(auth_id, self.id_type.as_deref(), &self.module_id)
.update_identity(
auth_id,
self.id_type.as_deref(),
&self.module_id,
body.managed_by,
)
.await
{
Ok(v) => v,
Expand Down
28 changes: 18 additions & 10 deletions identity/aziot-identityd/src/identity.rs
Original file line number Diff line number Diff line change
Expand Up @@ -106,6 +106,7 @@ impl IdentityManager {
pub async fn create_module_identity(
&self,
module_id: &str,
managed_by: Option<String>,
) -> Result<aziot_identity_common::Identity, Error> {
if module_id.trim().is_empty() {
return Err(Error::invalid_parameter(
Expand All @@ -126,7 +127,7 @@ impl IdentityManager {
.with_proxy(self.proxy_uri.clone());

let new_module = client
.create_module(module_id, None, None)
.create_module(module_id, None, managed_by.clone())
.await
.map_err(Error::HubClient)?;

Expand All @@ -148,7 +149,7 @@ impl IdentityManager {
x509_thumbprint: None,
type_: Some(aziot_identity_common::hub::AuthType::Sas),
}),
None,
managed_by,
)
.await
.map_err(Error::HubClient)?;
Expand Down Expand Up @@ -177,6 +178,7 @@ impl IdentityManager {
auth: Some(aziot_identity_common::AuthenticationInfo::from(
module_credentials,
)),
managed_by: response.managed_by,
});
Ok(identity)
}
Expand All @@ -187,6 +189,7 @@ impl IdentityManager {
pub async fn update_module_identity(
&self,
module_id: &str,
managed_by: Option<String>,
) -> Result<aziot_identity_common::Identity, Error> {
if module_id.trim().is_empty() {
return Err(Error::invalid_parameter(
Expand Down Expand Up @@ -229,7 +232,7 @@ impl IdentityManager {
x509_thumbprint: None,
type_: Some(aziot_identity_common::hub::AuthType::Sas),
}),
None,
managed_by,
)
.await
.map_err(Error::HubClient)?;
Expand Down Expand Up @@ -258,6 +261,7 @@ impl IdentityManager {
auth: Some(aziot_identity_common::AuthenticationInfo::from(
module_credentials,
)),
managed_by: response.managed_by,
});
Ok(identity)
}
Expand All @@ -275,6 +279,7 @@ impl IdentityManager {
module_id: None,
gen_id: None,
auth: Some(self.get_device_identity_key().await?),
managed_by: None,
},
)),
None => Err(Error::DeviceNotFound),
Expand Down Expand Up @@ -366,6 +371,7 @@ impl IdentityManager {
auth: Some(aziot_identity_common::AuthenticationInfo::from(
module_credentials,
)),
managed_by: module.managed_by,
});

Ok(identity)
Expand Down Expand Up @@ -415,6 +421,7 @@ impl IdentityManager {
module_id: Some(aziot_identity_common::ModuleId(module.module_id)),
gen_id: module.generation_id.map(aziot_identity_common::GenId),
auth: None, //Auth information can be requested via get_module_identity
managed_by: module.managed_by,
},
)
})
Expand Down Expand Up @@ -939,15 +946,15 @@ impl IdentityManager {

let hub_module_ids = self.get_module_identities().await?;

for m in hub_module_ids {
for m in &hub_module_ids {
if let aziot_identity_common::Identity::Aziot(m) = m {
if let Some(m) = m.module_id {
if !current_module_set.contains(&m) && prev_module_set.contains(&m) {
if let Some(m) = &m.module_id {
if !current_module_set.contains(m) && prev_module_set.contains(m) {
self.delete_module_identity(&m.0).await?;
log::info!("Hub identity {:?} removed", &m.0);
} else if current_module_set.contains(&m) {
if prev_module_set.contains(&m) {
current_module_set.remove(&m);
} else if current_module_set.contains(m) {
if prev_module_set.contains(m) {
current_module_set.remove(m);
log::info!("Hub identity {:?} already exists", &m.0);
} else {
self.delete_module_identity(&m.0).await?;
Expand All @@ -961,7 +968,8 @@ impl IdentityManager {
}

for m in current_module_set {
self.create_module_identity(&m.0).await?;
// TODO: do we need to take previous identity and pass along?
self.create_module_identity(&m.0, None).await?;
log::info!("Hub identity {:?} added", &m.0);
}

Expand Down
6 changes: 4 additions & 2 deletions identity/aziot-identityd/src/lib.rs
Original file line number Diff line number Diff line change
Expand Up @@ -445,6 +445,7 @@ impl Api {
auth_id: auth::AuthId,
id_type: Option<&str>,
module_id: &str,
managed_by: Option<String>,
opts: Option<aziot_identity_common_http::create_module_identity::CreateModuleOpts>,
) -> Result<aziot_identity_common::Identity, Error> {
if !self.authorizer.authorize(auth::Operation {
Expand All @@ -455,7 +456,7 @@ impl Api {
}

match_id_type!( id_type {
ID_TYPE_AZIOT => { self.id_manager.create_module_identity(module_id).await },
ID_TYPE_AZIOT => { self.id_manager.create_module_identity(module_id, managed_by).await },
ID_TYPE_LOCAL => {
if self.local_identities
.get(&aziot_identity_common::ModuleId(module_id.to_owned()))
Expand Down Expand Up @@ -485,6 +486,7 @@ impl Api {
auth_id: auth::AuthId,
id_type: Option<&str>,
module_id: &str,
managed_by: Option<String>,
) -> Result<aziot_identity_common::Identity, Error> {
if !self.authorizer.authorize(auth::Operation {
auth_id,
Expand All @@ -494,7 +496,7 @@ impl Api {
}

match_id_type!(id_type {
ID_TYPE_AZIOT => { self.id_manager.update_module_identity(module_id).await },
ID_TYPE_AZIOT => { self.id_manager.update_module_identity(module_id, managed_by).await },
})
}

Expand Down
9 changes: 6 additions & 3 deletions test-common/src/client/identity.rs
Original file line number Diff line number Diff line change
Expand Up @@ -26,7 +26,7 @@ pub struct IdentityClient {
impl Default for IdentityClient {
fn default() -> Self {
let mut identities = std::collections::BTreeMap::new();
identities.insert("testModule".to_string(), test_identity("testModule"));
identities.insert("testModule".to_string(), test_identity("testModule", None));

let identities = tokio::sync::Mutex::new(std::cell::RefCell::new(identities));

Expand Down Expand Up @@ -68,9 +68,10 @@ impl IdentityClient {
pub async fn create_module_identity(
&self,
module_name: &str,
managed_by: Option<String>,
) -> Result<Identity, std::io::Error> {
if self.get_identity_ok {
let identity = test_identity(module_name);
let identity = test_identity(module_name, managed_by);

let identities = self.identities.lock().await;

Expand Down Expand Up @@ -126,6 +127,7 @@ impl IdentityClient {
pub async fn update_module_identity(
&self,
module_name: &str,
_managed_by: Option<String>,
) -> Result<Identity, std::io::Error> {
if self.update_identity_ok {
// A real identity client would update the Idenitity in Hub. But this test
Expand Down Expand Up @@ -154,7 +156,7 @@ impl IdentityClient {
}

/// Generates an Identity struct for a given module name.
fn test_identity(module_name: &str) -> Identity {
fn test_identity(module_name: &str, managed_by: Option<String>) -> Identity {
Identity::Aziot(aziot_identity_common::AzureIoTSpec {
hub_name: "test-hub.test.net".to_string(),
gateway_host: "gateway-host.test.net".to_string(),
Expand All @@ -166,6 +168,7 @@ fn test_identity(module_name: &str) -> Identity {
key_handle: Some(aziot_key_common::KeyHandle(format!("{}-key", module_name))),
cert_id: Some(format!("{}-cert", module_name)),
}),
managed_by,
})
}

Expand Down