mirror of
https://github.com/dani-garcia/vaultwarden.git
synced 2024-11-26 06:46:13 +03:00
Fixed case problems, hopefully this time for real
This commit is contained in:
parent
538dc00234
commit
410ee9f1f7
3 changed files with 76 additions and 16 deletions
|
@ -6,8 +6,6 @@ use db::models::*;
|
||||||
use api::{PasswordData, JsonResult, EmptyResult, JsonUpcase};
|
use api::{PasswordData, JsonResult, EmptyResult, JsonUpcase};
|
||||||
use auth::Headers;
|
use auth::Headers;
|
||||||
|
|
||||||
use util;
|
|
||||||
|
|
||||||
use CONFIG;
|
use CONFIG;
|
||||||
|
|
||||||
#[derive(Deserialize, Debug)]
|
#[derive(Deserialize, Debug)]
|
||||||
|
@ -15,7 +13,6 @@ use CONFIG;
|
||||||
struct RegisterData {
|
struct RegisterData {
|
||||||
Email: String,
|
Email: String,
|
||||||
Key: String,
|
Key: String,
|
||||||
#[serde(deserialize_with = "util::upcase_deserialize")]
|
|
||||||
Keys: Option<KeysData>,
|
Keys: Option<KeysData>,
|
||||||
MasterPasswordHash: String,
|
MasterPasswordHash: String,
|
||||||
MasterPasswordHint: Option<String>,
|
MasterPasswordHint: Option<String>,
|
||||||
|
|
|
@ -363,7 +363,6 @@ fn post_collections_admin(uuid: String, data: JsonUpcase<CollectionsAdminData>,
|
||||||
#[derive(Deserialize)]
|
#[derive(Deserialize)]
|
||||||
#[allow(non_snake_case)]
|
#[allow(non_snake_case)]
|
||||||
struct ShareCipherData {
|
struct ShareCipherData {
|
||||||
#[serde(deserialize_with = "util::upcase_deserialize")]
|
|
||||||
Cipher: CipherData,
|
Cipher: CipherData,
|
||||||
CollectionIds: Vec<String>,
|
CollectionIds: Vec<String>,
|
||||||
}
|
}
|
||||||
|
|
88
src/util.rs
88
src/util.rs
|
@ -129,24 +129,88 @@ pub fn format_date(date: &NaiveDateTime) -> String {
|
||||||
/// Deserialization methods
|
/// Deserialization methods
|
||||||
///
|
///
|
||||||
|
|
||||||
use std::collections::BTreeMap as Map;
|
use std::fmt;
|
||||||
|
|
||||||
use serde::de::{self, Deserialize, DeserializeOwned, Deserializer};
|
use serde::de::{self, DeserializeOwned, Deserializer, MapAccess, SeqAccess, Visitor};
|
||||||
use serde_json::Value;
|
use serde_json::Value;
|
||||||
|
|
||||||
/// https://github.com/serde-rs/serde/issues/586
|
|
||||||
pub fn upcase_deserialize<'de, T, D>(deserializer: D) -> Result<T, D::Error>
|
|
||||||
where T: DeserializeOwned,
|
|
||||||
D: Deserializer<'de>
|
|
||||||
{
|
|
||||||
let map = Map::<String, Value>::deserialize(deserializer)?;
|
|
||||||
let lower = map.into_iter().map(|(k, v)| (upcase_first(&k), v)).collect();
|
|
||||||
T::deserialize(Value::Object(lower)).map_err(de::Error::custom)
|
|
||||||
}
|
|
||||||
|
|
||||||
#[derive(PartialEq, Serialize, Deserialize)]
|
#[derive(PartialEq, Serialize, Deserialize)]
|
||||||
pub struct UpCase<T: DeserializeOwned> {
|
pub struct UpCase<T: DeserializeOwned> {
|
||||||
#[serde(deserialize_with = "upcase_deserialize")]
|
#[serde(deserialize_with = "upcase_deserialize")]
|
||||||
#[serde(flatten)]
|
#[serde(flatten)]
|
||||||
pub data: T,
|
pub data: T,
|
||||||
}
|
}
|
||||||
|
|
||||||
|
/// https://github.com/serde-rs/serde/issues/586
|
||||||
|
pub fn upcase_deserialize<'de, T, D>(deserializer: D) -> Result<T, D::Error>
|
||||||
|
where T: DeserializeOwned,
|
||||||
|
D: Deserializer<'de>
|
||||||
|
{
|
||||||
|
let d = deserializer.deserialize_any(UpCaseVisitor)?;
|
||||||
|
T::deserialize(d).map_err(de::Error::custom)
|
||||||
|
}
|
||||||
|
|
||||||
|
struct UpCaseVisitor;
|
||||||
|
|
||||||
|
impl<'de> Visitor<'de> for UpCaseVisitor {
|
||||||
|
type Value = Value;
|
||||||
|
|
||||||
|
fn expecting(&self, formatter: &mut fmt::Formatter) -> fmt::Result {
|
||||||
|
formatter.write_str("an object or an array")
|
||||||
|
}
|
||||||
|
|
||||||
|
fn visit_map<A>(self, mut map: A) -> Result<Self::Value, A::Error>
|
||||||
|
where A: MapAccess<'de>
|
||||||
|
{
|
||||||
|
use serde_json::Map;
|
||||||
|
let mut result_map = Map::<String, Value>::new();
|
||||||
|
|
||||||
|
while let Some((key, value)) = map.next_entry()? {
|
||||||
|
result_map.insert(upcase_first(key), upcase_value(&value));
|
||||||
|
}
|
||||||
|
|
||||||
|
Ok(Value::Object(result_map))
|
||||||
|
}
|
||||||
|
|
||||||
|
fn visit_seq<A>(self, mut seq: A) -> Result<Self::Value, A::Error>
|
||||||
|
where A: SeqAccess<'de> {
|
||||||
|
let mut result_seq = Vec::<Value>::new();
|
||||||
|
|
||||||
|
while let Some(value) = seq.next_element()? {
|
||||||
|
result_seq.push(upcase_value(&value));
|
||||||
|
}
|
||||||
|
|
||||||
|
Ok(Value::Array(result_seq))
|
||||||
|
}
|
||||||
|
}
|
||||||
|
|
||||||
|
fn upcase_value(value: &Value) -> Value {
|
||||||
|
if let Some(map) = value.as_object() {
|
||||||
|
let mut new_value = json!({});
|
||||||
|
|
||||||
|
for (key, val) in map {
|
||||||
|
let processed_key = _process_key(key);
|
||||||
|
new_value[processed_key] = upcase_value(val);
|
||||||
|
}
|
||||||
|
new_value
|
||||||
|
|
||||||
|
} else if let Some(array) = value.as_array() {
|
||||||
|
// Initialize array with null values
|
||||||
|
let mut new_value = json!(vec![Value::Null; array.len()]);
|
||||||
|
|
||||||
|
for (index, val) in array.iter().enumerate() {
|
||||||
|
new_value[index] = upcase_value(val);
|
||||||
|
}
|
||||||
|
new_value
|
||||||
|
|
||||||
|
} else {
|
||||||
|
value.clone()
|
||||||
|
}
|
||||||
|
}
|
||||||
|
|
||||||
|
fn _process_key(key: &str) -> String {
|
||||||
|
match key.to_lowercase().as_ref() {
|
||||||
|
"ssn" => "SSN".into(),
|
||||||
|
_ => self::upcase_first(key)
|
||||||
|
}
|
||||||
|
}
|
||||||
|
|
Loading…
Reference in a new issue