Can update device general information
This commit is contained in:
@ -18,3 +18,40 @@ pub const MAX_SESSION_DURATION: u64 = 3600 * 24;
|
||||
/// List of routes that do not require authentication
|
||||
pub const ROUTES_WITHOUT_AUTH: [&str; 2] =
|
||||
["/web_api/server/config", "/web_api/auth/password_auth"];
|
||||
|
||||
#[derive(serde::Serialize)]
|
||||
pub struct SizeConstraint {
|
||||
/// Minimal string length
|
||||
min: usize,
|
||||
/// Maximal string length
|
||||
max: usize,
|
||||
}
|
||||
|
||||
impl SizeConstraint {
|
||||
pub fn new(min: usize, max: usize) -> Self {
|
||||
Self { min, max }
|
||||
}
|
||||
|
||||
pub fn validate(&self, val: &str) -> bool {
|
||||
let len = val.trim().len();
|
||||
len >= self.min && len <= self.max
|
||||
}
|
||||
}
|
||||
|
||||
/// Backend static constraints
|
||||
#[derive(serde::Serialize)]
|
||||
pub struct StaticConstraints {
|
||||
/// Device name constraint
|
||||
pub dev_name_len: SizeConstraint,
|
||||
/// Device description constraint
|
||||
pub dev_description_len: SizeConstraint,
|
||||
}
|
||||
|
||||
impl Default for StaticConstraints {
|
||||
fn default() -> Self {
|
||||
Self {
|
||||
dev_name_len: SizeConstraint::new(1, 50),
|
||||
dev_description_len: SizeConstraint::new(0, 100),
|
||||
}
|
||||
}
|
||||
}
|
||||
|
@ -1,5 +1,7 @@
|
||||
//! # Devices entities definition
|
||||
|
||||
use crate::constants::StaticConstraints;
|
||||
|
||||
/// Device information provided directly by the device during syncrhonisation.
|
||||
///
|
||||
/// It should not be editable fro the Web UI
|
||||
@ -100,3 +102,29 @@ pub struct DeviceRelay {
|
||||
/// Specify relays that must be turned off before this relay can be started
|
||||
conflicts_with: Vec<DeviceRelayID>,
|
||||
}
|
||||
|
||||
/// Device general information
|
||||
///
|
||||
/// This structure is used to update device information
|
||||
#[derive(serde::Deserialize, Debug, Clone)]
|
||||
pub struct DeviceGeneralInfo {
|
||||
pub name: String,
|
||||
pub description: String,
|
||||
pub enabled: bool,
|
||||
}
|
||||
|
||||
impl DeviceGeneralInfo {
|
||||
/// Check for errors in the structure
|
||||
pub fn error(&self) -> Option<&'static str> {
|
||||
let constraints = StaticConstraints::default();
|
||||
if !constraints.dev_name_len.validate(&self.name) {
|
||||
return Some("Invalid device name length!");
|
||||
}
|
||||
|
||||
if !constraints.dev_description_len.validate(&self.description) {
|
||||
return Some("Invalid device description length!");
|
||||
}
|
||||
|
||||
None
|
||||
}
|
||||
}
|
||||
|
@ -1,6 +1,6 @@
|
||||
use crate::app_config::AppConfig;
|
||||
use crate::crypto::pki;
|
||||
use crate::devices::device::{Device, DeviceId, DeviceInfo};
|
||||
use crate::devices::device::{Device, DeviceGeneralInfo, DeviceId, DeviceInfo};
|
||||
use crate::utils::time_utils::time_secs;
|
||||
use openssl::x509::{X509Req, X509};
|
||||
use std::collections::HashMap;
|
||||
@ -15,6 +15,8 @@ pub enum DevicesListError {
|
||||
ValidateDeviceFailedDeviceNotFound,
|
||||
#[error("Validated device failed: the device is already validated!")]
|
||||
ValidateDeviceFailedDeviceAlreadyValidated,
|
||||
#[error("Update device failed: the device does not exists!")]
|
||||
UpdateDeviceFailedDeviceNotFound,
|
||||
#[error("Requested device was not found")]
|
||||
DeviceNotFound,
|
||||
#[error("Requested device is not validated")]
|
||||
@ -133,6 +135,27 @@ impl DevicesList {
|
||||
Ok(())
|
||||
}
|
||||
|
||||
/// Update a device general information
|
||||
pub fn update_general_info(
|
||||
&mut self,
|
||||
id: &DeviceId,
|
||||
general_info: DeviceGeneralInfo,
|
||||
) -> anyhow::Result<()> {
|
||||
let dev = self
|
||||
.0
|
||||
.get_mut(id)
|
||||
.ok_or(DevicesListError::UpdateDeviceFailedDeviceNotFound)?;
|
||||
|
||||
dev.name = general_info.name;
|
||||
dev.description = general_info.description;
|
||||
dev.enabled = general_info.enabled;
|
||||
dev.time_update = time_secs();
|
||||
|
||||
self.persist_dev_config(id)?;
|
||||
|
||||
Ok(())
|
||||
}
|
||||
|
||||
/// Get single certificate information
|
||||
fn get_cert(&self, id: &DeviceId) -> anyhow::Result<X509> {
|
||||
let dev = self
|
||||
|
@ -1,5 +1,5 @@
|
||||
use crate::constants;
|
||||
use crate::devices::device::{Device, DeviceId, DeviceInfo};
|
||||
use crate::devices::device::{Device, DeviceGeneralInfo, DeviceId, DeviceInfo};
|
||||
use crate::devices::devices_list::DevicesList;
|
||||
use crate::energy::consumption;
|
||||
use crate::energy::consumption::EnergyConsumption;
|
||||
@ -109,6 +109,27 @@ impl Handler<ValidateDevice> for EnergyActor {
|
||||
}
|
||||
}
|
||||
|
||||
/// Update a device general information
|
||||
#[derive(Message)]
|
||||
#[rtype(result = "anyhow::Result<()>")]
|
||||
pub struct UpdateDeviceGeneralInfo(pub DeviceId, pub DeviceGeneralInfo);
|
||||
|
||||
impl Handler<UpdateDeviceGeneralInfo> for EnergyActor {
|
||||
type Result = anyhow::Result<()>;
|
||||
|
||||
fn handle(&mut self, msg: UpdateDeviceGeneralInfo, _ctx: &mut Context<Self>) -> Self::Result {
|
||||
log::info!(
|
||||
"Requested to update device general info {:?}... {:#?}",
|
||||
&msg.0,
|
||||
&msg.1
|
||||
);
|
||||
|
||||
self.devices.update_general_info(&msg.0, msg.1)?;
|
||||
|
||||
Ok(())
|
||||
}
|
||||
}
|
||||
|
||||
/// Delete a device
|
||||
#[derive(Message)]
|
||||
#[rtype(result = "anyhow::Result<()>")]
|
||||
|
@ -147,6 +147,10 @@ pub async fn secure_server(energy_actor: EnergyActorAddr) -> anyhow::Result<()>
|
||||
"/web_api/device/{id}/validate",
|
||||
web::post().to(devices_controller::validate_device),
|
||||
)
|
||||
.route(
|
||||
"/web_api/device/{id}",
|
||||
web::patch().to(devices_controller::update_device),
|
||||
)
|
||||
.route(
|
||||
"/web_api/device/{id}",
|
||||
web::delete().to(devices_controller::delete_device),
|
||||
|
@ -1,4 +1,4 @@
|
||||
use crate::devices::device::DeviceId;
|
||||
use crate::devices::device::{DeviceGeneralInfo, DeviceId};
|
||||
use crate::energy::energy_actor;
|
||||
use crate::server::custom_error::HttpResult;
|
||||
use crate::server::WebEnergyActor;
|
||||
@ -54,6 +54,26 @@ pub async fn validate_device(actor: WebEnergyActor, id: web::Path<DeviceInPath>)
|
||||
Ok(HttpResponse::Accepted().finish())
|
||||
}
|
||||
|
||||
/// Update a device information
|
||||
pub async fn update_device(
|
||||
actor: WebEnergyActor,
|
||||
id: web::Path<DeviceInPath>,
|
||||
update: web::Json<DeviceGeneralInfo>,
|
||||
) -> HttpResult {
|
||||
if let Some(e) = update.error() {
|
||||
return Ok(HttpResponse::BadRequest().json(e));
|
||||
}
|
||||
|
||||
actor
|
||||
.send(energy_actor::UpdateDeviceGeneralInfo(
|
||||
id.id.clone(),
|
||||
update.0.clone(),
|
||||
))
|
||||
.await??;
|
||||
|
||||
Ok(HttpResponse::Accepted().finish())
|
||||
}
|
||||
|
||||
/// Delete a device
|
||||
pub async fn delete_device(actor: WebEnergyActor, id: web::Path<DeviceInPath>) -> HttpResult {
|
||||
actor
|
||||
|
@ -1,4 +1,5 @@
|
||||
use crate::app_config::AppConfig;
|
||||
use crate::constants::StaticConstraints;
|
||||
use actix_web::HttpResponse;
|
||||
|
||||
pub async fn secure_home() -> HttpResponse {
|
||||
@ -10,12 +11,14 @@ pub async fn secure_home() -> HttpResponse {
|
||||
#[derive(serde::Serialize)]
|
||||
struct ServerConfig {
|
||||
auth_disabled: bool,
|
||||
constraints: StaticConstraints,
|
||||
}
|
||||
|
||||
impl Default for ServerConfig {
|
||||
fn default() -> Self {
|
||||
Self {
|
||||
auth_disabled: AppConfig::get().unsecure_disable_login,
|
||||
constraints: Default::default(),
|
||||
}
|
||||
}
|
||||
}
|
||||
|
Reference in New Issue
Block a user