update user functionality and cleanup

This commit is contained in:
Dietrich 2021-05-15 19:20:18 +02:00 committed by Franz Dietrich
parent 6837495eba
commit d503d49917
10 changed files with 297 additions and 80 deletions

218
Cargo.lock generated
View File

@ -1,5 +1,7 @@
# This file is automatically @generated by Cargo. # This file is automatically @generated by Cargo.
# It is not intended for manual editing. # It is not intended for manual editing.
version = 3
[[package]] [[package]]
name = "Inflector" name = "Inflector"
version = "0.11.4" version = "0.11.4"
@ -22,8 +24,8 @@ dependencies = [
"futures-sink", "futures-sink",
"log", "log",
"pin-project 0.4.28", "pin-project 0.4.28",
"tokio", "tokio 0.2.25",
"tokio-util", "tokio-util 0.3.1",
] ]
[[package]] [[package]]
@ -91,7 +93,7 @@ dependencies = [
"futures-core", "futures-core",
"futures-util", "futures-util",
"fxhash", "fxhash",
"h2", "h2 0.2.7",
"http", "http",
"httparse", "httparse",
"indexmap", "indexmap",
@ -161,7 +163,7 @@ dependencies = [
"futures-channel", "futures-channel",
"futures-util", "futures-util",
"smallvec", "smallvec",
"tokio", "tokio 0.2.25",
] ]
[[package]] [[package]]
@ -177,11 +179,11 @@ dependencies = [
"futures-channel", "futures-channel",
"futures-util", "futures-util",
"log", "log",
"mio", "mio 0.6.23",
"mio-uds", "mio-uds",
"num_cpus", "num_cpus",
"slab", "slab",
"socket2", "socket2 0.3.19",
] ]
[[package]] [[package]]
@ -218,7 +220,7 @@ dependencies = [
"actix-server", "actix-server",
"actix-service", "actix-service",
"log", "log",
"socket2", "socket2 0.3.19",
] ]
[[package]] [[package]]
@ -301,7 +303,7 @@ dependencies = [
"serde", "serde",
"serde_json", "serde_json",
"serde_urlencoded", "serde_urlencoded",
"socket2", "socket2 0.3.19",
"time 0.2.26", "time 0.2.26",
"tinyvec", "tinyvec",
"url", "url",
@ -1749,12 +1751,31 @@ dependencies = [
"http", "http",
"indexmap", "indexmap",
"slab", "slab",
"tokio", "tokio 0.2.25",
"tokio-util", "tokio-util 0.3.1",
"tracing", "tracing",
"tracing-futures", "tracing-futures",
] ]
[[package]]
name = "h2"
version = "0.3.3"
source = "registry+https://github.com/rust-lang/crates.io-index"
checksum = "825343c4eef0b63f541f8903f395dc5beb362a979b5799a84062527ef1e37726"
dependencies = [
"bytes 1.0.1",
"fnv",
"futures-core",
"futures-sink",
"futures-util",
"http",
"indexmap",
"slab",
"tokio 1.6.0",
"tokio-util 0.6.7",
"tracing",
]
[[package]] [[package]]
name = "hashbrown" name = "hashbrown"
version = "0.1.8" version = "0.1.8"
@ -1851,12 +1872,13 @@ dependencies = [
[[package]] [[package]]
name = "http-body" name = "http-body"
version = "0.3.1" version = "0.4.2"
source = "registry+https://github.com/rust-lang/crates.io-index" source = "registry+https://github.com/rust-lang/crates.io-index"
checksum = "13d5ff830006f7646652e057693569bfe0d51760c0085a071769d142a205111b" checksum = "60daa14be0e0786db0f03a9e57cb404c9d756eed2b6c62b9ea98ec5743ec75a9"
dependencies = [ dependencies = [
"bytes 0.5.6", "bytes 1.0.1",
"http", "http",
"pin-project-lite 0.2.6",
] ]
[[package]] [[package]]
@ -1867,9 +1889,9 @@ checksum = "f3a87b616e37e93c22fb19bcd386f02f3af5ea98a25670ad0fce773de23c5e68"
[[package]] [[package]]
name = "httpdate" name = "httpdate"
version = "0.3.2" version = "1.0.0"
source = "registry+https://github.com/rust-lang/crates.io-index" source = "registry+https://github.com/rust-lang/crates.io-index"
checksum = "494b4d60369511e7dea41cf646832512a94e542f68bb9c49e54518e0f468eb47" checksum = "05842d0d43232b23ccb7060ecb0f0626922c21f30012e97b767b30afd4a5d4b9"
[[package]] [[package]]
name = "humansize" name = "humansize"
@ -1888,23 +1910,23 @@ dependencies = [
[[package]] [[package]]
name = "hyper" name = "hyper"
version = "0.13.10" version = "0.14.7"
source = "registry+https://github.com/rust-lang/crates.io-index" source = "registry+https://github.com/rust-lang/crates.io-index"
checksum = "8a6f157065790a3ed2f88679250419b5cdd96e714a0d65f7797fd337186e96bb" checksum = "1e5f105c494081baa3bf9e200b279e27ec1623895cd504c7dbef8d0b080fcf54"
dependencies = [ dependencies = [
"bytes 0.5.6", "bytes 1.0.1",
"futures-channel", "futures-channel",
"futures-core", "futures-core",
"futures-util", "futures-util",
"h2", "h2 0.3.3",
"http", "http",
"http-body", "http-body",
"httparse", "httparse",
"httpdate", "httpdate",
"itoa", "itoa",
"pin-project 1.0.7", "pin-project 1.0.7",
"socket2", "socket2 0.4.0",
"tokio", "tokio 1.6.0",
"tower-service", "tower-service",
"tracing", "tracing",
"want", "want",
@ -1912,15 +1934,15 @@ dependencies = [
[[package]] [[package]]
name = "hyper-tls" name = "hyper-tls"
version = "0.4.3" version = "0.5.0"
source = "registry+https://github.com/rust-lang/crates.io-index" source = "registry+https://github.com/rust-lang/crates.io-index"
checksum = "d979acc56dcb5b8dddba3917601745e877576475aa046df3226eabdecef78eed" checksum = "d6183ddfa99b85da61a140bea0efc93fdf56ceaa041b37d553518030827f9905"
dependencies = [ dependencies = [
"bytes 0.5.6", "bytes 1.0.1",
"hyper", "hyper",
"native-tls", "native-tls",
"tokio", "tokio 1.6.0",
"tokio-tls", "tokio-native-tls",
] ]
[[package]] [[package]]
@ -2031,7 +2053,7 @@ version = "0.2.2"
source = "registry+https://github.com/rust-lang/crates.io-index" source = "registry+https://github.com/rust-lang/crates.io-index"
checksum = "f7e2f18aece9709094573a9f24f483c4f65caa4298e2f7ae1b71cc65d853fad7" checksum = "f7e2f18aece9709094573a9f24f483c4f65caa4298e2f7ae1b71cc65d853fad7"
dependencies = [ dependencies = [
"socket2", "socket2 0.3.19",
"widestring", "widestring",
"winapi 0.3.9", "winapi 0.3.9",
"winreg 0.6.2", "winreg 0.6.2",
@ -2261,12 +2283,25 @@ dependencies = [
"kernel32-sys", "kernel32-sys",
"libc", "libc",
"log", "log",
"miow", "miow 0.2.2",
"net2", "net2",
"slab", "slab",
"winapi 0.2.8", "winapi 0.2.8",
] ]
[[package]]
name = "mio"
version = "0.7.11"
source = "registry+https://github.com/rust-lang/crates.io-index"
checksum = "cf80d3e903b34e0bd7282b218398aec54e082c840d9baf8339e0080a0c542956"
dependencies = [
"libc",
"log",
"miow 0.3.7",
"ntapi",
"winapi 0.3.9",
]
[[package]] [[package]]
name = "mio-uds" name = "mio-uds"
version = "0.6.8" version = "0.6.8"
@ -2275,7 +2310,7 @@ checksum = "afcb699eb26d4332647cc848492bbc15eafb26f08d0304550d5aa1f612e066f0"
dependencies = [ dependencies = [
"iovec", "iovec",
"libc", "libc",
"mio", "mio 0.6.23",
] ]
[[package]] [[package]]
@ -2290,6 +2325,15 @@ dependencies = [
"ws2_32-sys", "ws2_32-sys",
] ]
[[package]]
name = "miow"
version = "0.3.7"
source = "registry+https://github.com/rust-lang/crates.io-index"
checksum = "b9f1c5b025cda876f66ef43a113f91ebc9f4ccef34843000e0adf6ebbab84e21"
dependencies = [
"winapi 0.3.9",
]
[[package]] [[package]]
name = "nanorand" name = "nanorand"
version = "0.5.2" version = "0.5.2"
@ -2351,6 +2395,15 @@ dependencies = [
"version_check 0.9.3", "version_check 0.9.3",
] ]
[[package]]
name = "ntapi"
version = "0.3.6"
source = "registry+https://github.com/rust-lang/crates.io-index"
checksum = "3f6bb902e437b6d86e03cce10a7e2af662292c5dfef23b65899ea3ac9354ad44"
dependencies = [
"winapi 0.3.9",
]
[[package]] [[package]]
name = "num-integer" name = "num-integer"
version = "0.1.44" version = "0.1.44"
@ -2475,6 +2528,23 @@ dependencies = [
"thiserror", "thiserror",
] ]
[[package]]
name = "opentelemetry"
version = "0.14.0"
source = "registry+https://github.com/rust-lang/crates.io-index"
checksum = "492848ff47f11b7f9de0443b404e2c5775f695e1af6b7076ca25f999581d547a"
dependencies = [
"async-trait",
"crossbeam-channel",
"futures 0.3.15",
"js-sys",
"lazy_static",
"percent-encoding",
"pin-project 1.0.7",
"rand 0.8.3",
"thiserror",
]
[[package]] [[package]]
name = "opentelemetry-jaeger" name = "opentelemetry-jaeger"
version = "0.12.1" version = "0.12.1"
@ -2483,7 +2553,7 @@ checksum = "ddd4984441954f9ebbe3eebdfc6fd4fa95be6400d403171228779b949f3cd918"
dependencies = [ dependencies = [
"async-trait", "async-trait",
"lazy_static", "lazy_static",
"opentelemetry", "opentelemetry 0.13.0",
"thiserror", "thiserror",
"thrift", "thrift",
] ]
@ -2806,7 +2876,7 @@ dependencies = [
"fluent-langneg", "fluent-langneg",
"fluent-templates", "fluent-templates",
"image", "image",
"opentelemetry", "opentelemetry 0.14.0",
"opentelemetry-jaeger", "opentelemetry-jaeger",
"qrcode", "qrcode",
"rand 0.8.3", "rand 0.8.3",
@ -2819,7 +2889,7 @@ dependencies = [
"tera", "tera",
"test_bin", "test_bin",
"thiserror", "thiserror",
"tokio", "tokio 0.2.25",
"tracing", "tracing",
"tracing-actix-web", "tracing-actix-web",
"tracing-bunyan-formatter", "tracing-bunyan-formatter",
@ -3180,12 +3250,12 @@ dependencies = [
[[package]] [[package]]
name = "reqwest" name = "reqwest"
version = "0.10.10" version = "0.11.3"
source = "registry+https://github.com/rust-lang/crates.io-index" source = "registry+https://github.com/rust-lang/crates.io-index"
checksum = "0718f81a8e14c4dbb3b34cf23dc6aaf9ab8a0dfec160c534b3dbca1aaa21f47c" checksum = "2296f2fac53979e8ccbc4a1136b25dcefd37be9ed7e4a1f6b05a6029c84ff124"
dependencies = [ dependencies = [
"base64 0.13.0", "base64 0.13.0",
"bytes 0.5.6", "bytes 1.0.1",
"cookie", "cookie",
"cookie_store", "cookie_store",
"encoding_rs", "encoding_rs",
@ -3200,15 +3270,14 @@ dependencies = [
"lazy_static", "lazy_static",
"log", "log",
"mime", "mime",
"mime_guess",
"native-tls", "native-tls",
"percent-encoding", "percent-encoding",
"pin-project-lite 0.2.6", "pin-project-lite 0.2.6",
"serde", "serde",
"serde_urlencoded", "serde_urlencoded",
"time 0.2.26", "time 0.2.26",
"tokio", "tokio 1.6.0",
"tokio-tls", "tokio-native-tls",
"url", "url",
"wasm-bindgen", "wasm-bindgen",
"wasm-bindgen-futures", "wasm-bindgen-futures",
@ -3595,6 +3664,16 @@ dependencies = [
"winapi 0.3.9", "winapi 0.3.9",
] ]
[[package]]
name = "socket2"
version = "0.4.0"
source = "registry+https://github.com/rust-lang/crates.io-index"
checksum = "9e3dfc207c526015c632472a77be09cf1b6e46866581aecae5cc38fb4235dea2"
dependencies = [
"libc",
"winapi 0.3.9",
]
[[package]] [[package]]
name = "spin" name = "spin"
version = "0.5.2" version = "0.5.2"
@ -3710,7 +3789,7 @@ dependencies = [
"actix-rt", "actix-rt",
"actix-threadpool", "actix-threadpool",
"once_cell", "once_cell",
"tokio", "tokio 0.2.25",
"tokio-rustls", "tokio-rustls",
] ]
@ -4061,13 +4140,12 @@ source = "registry+https://github.com/rust-lang/crates.io-index"
checksum = "6703a273949a90131b290be1fe7b039d0fc884aa1935860dfcbe056f28cd8092" checksum = "6703a273949a90131b290be1fe7b039d0fc884aa1935860dfcbe056f28cd8092"
dependencies = [ dependencies = [
"bytes 0.5.6", "bytes 0.5.6",
"fnv",
"futures-core", "futures-core",
"iovec", "iovec",
"lazy_static", "lazy_static",
"libc", "libc",
"memchr", "memchr",
"mio", "mio 0.6.23",
"mio-uds", "mio-uds",
"num_cpus", "num_cpus",
"pin-project-lite 0.1.12", "pin-project-lite 0.1.12",
@ -4077,6 +4155,20 @@ dependencies = [
"winapi 0.3.9", "winapi 0.3.9",
] ]
[[package]]
name = "tokio"
version = "1.6.0"
source = "registry+https://github.com/rust-lang/crates.io-index"
checksum = "bd3076b5c8cc18138b8f8814895c11eb4de37114a5d127bafdc5e55798ceef37"
dependencies = [
"autocfg 1.0.1",
"bytes 1.0.1",
"libc",
"memchr",
"mio 0.7.11",
"pin-project-lite 0.2.6",
]
[[package]] [[package]]
name = "tokio-macros" name = "tokio-macros"
version = "0.2.6" version = "0.2.6"
@ -4088,6 +4180,16 @@ dependencies = [
"syn", "syn",
] ]
[[package]]
name = "tokio-native-tls"
version = "0.3.0"
source = "registry+https://github.com/rust-lang/crates.io-index"
checksum = "f7d995660bd2b7f8c1568414c1126076c13fbb725c40112dc0120b78eb9b717b"
dependencies = [
"native-tls",
"tokio 1.6.0",
]
[[package]] [[package]]
name = "tokio-rustls" name = "tokio-rustls"
version = "0.14.1" version = "0.14.1"
@ -4096,20 +4198,10 @@ checksum = "e12831b255bcfa39dc0436b01e19fea231a37db570686c06ee72c423479f889a"
dependencies = [ dependencies = [
"futures-core", "futures-core",
"rustls", "rustls",
"tokio", "tokio 0.2.25",
"webpki", "webpki",
] ]
[[package]]
name = "tokio-tls"
version = "0.3.1"
source = "registry+https://github.com/rust-lang/crates.io-index"
checksum = "9a70f4fcd7b3b24fb194f837560168208f669ca8cb70d0c4b862944452396343"
dependencies = [
"native-tls",
"tokio",
]
[[package]] [[package]]
name = "tokio-util" name = "tokio-util"
version = "0.3.1" version = "0.3.1"
@ -4121,7 +4213,21 @@ dependencies = [
"futures-sink", "futures-sink",
"log", "log",
"pin-project-lite 0.1.12", "pin-project-lite 0.1.12",
"tokio", "tokio 0.2.25",
]
[[package]]
name = "tokio-util"
version = "0.6.7"
source = "registry+https://github.com/rust-lang/crates.io-index"
checksum = "1caa0b0c8d94a049db56b5acf8cba99dc0623aab1b26d5b5f5e2d945846b3592"
dependencies = [
"bytes 1.0.1",
"futures-core",
"futures-sink",
"log",
"pin-project-lite 0.2.6",
"tokio 1.6.0",
] ]
[[package]] [[package]]
@ -4220,7 +4326,7 @@ version = "0.12.0"
source = "registry+https://github.com/rust-lang/crates.io-index" source = "registry+https://github.com/rust-lang/crates.io-index"
checksum = "99003208b647dae59dcefc49c98aecaa3512fbc29351685d4b9ef23a9218458e" checksum = "99003208b647dae59dcefc49c98aecaa3512fbc29351685d4b9ef23a9218458e"
dependencies = [ dependencies = [
"opentelemetry", "opentelemetry 0.13.0",
"tracing", "tracing",
"tracing-core", "tracing-core",
"tracing-log", "tracing-log",
@ -4275,7 +4381,7 @@ dependencies = [
"rand 0.7.3", "rand 0.7.3",
"smallvec", "smallvec",
"thiserror", "thiserror",
"tokio", "tokio 0.2.25",
"url", "url",
] ]
@ -4294,7 +4400,7 @@ dependencies = [
"resolv-conf", "resolv-conf",
"smallvec", "smallvec",
"thiserror", "thiserror",
"tokio", "tokio 0.2.25",
"trust-dns-proto", "trust-dns-proto",
] ]

View File

@ -52,12 +52,12 @@ impl Page {
let result = match url.next_path_part() { let result = match url.next_path_part() {
None | Some("list_links") => Self::Home(pages::list_links::init( None | Some("list_links") => Self::Home(pages::list_links::init(
url, url,
&mut orders.proxy(Msg::ListLinksMsg), &mut orders.proxy(Msg::ListLinks),
i18n, i18n,
)), )),
Some("list_users") => Self::ListUsers(pages::list_users::init( Some("list_users") => Self::ListUsers(pages::list_users::init(
url, url,
&mut orders.proxy(Msg::ListUsersMsg), &mut orders.proxy(Msg::ListUsers),
i18n, i18n,
)), )),
_other => Self::NotFound, _other => Self::NotFound,
@ -71,12 +71,11 @@ impl Page {
// ------ ------ // ------ ------
// Update // Update
// ------ ------ // ------ ------
#[allow(renamed_and_removed_lints, pub_enum_variant_names)]
#[derive(Clone)] #[derive(Clone)]
pub enum Msg { pub enum Msg {
UrlChanged(subs::UrlChanged), UrlChanged(subs::UrlChanged),
ListLinksMsg(list_links::Msg), ListLinks(list_links::Msg),
ListUsersMsg(list_users::Msg), ListUsers(list_users::Msg),
NoMessage, NoMessage,
} }
@ -87,14 +86,14 @@ fn update(msg: Msg, model: &mut Model, orders: &mut impl Orders<Msg>) {
model.page = Page::init(url.0, orders, model.i18n.clone()); model.page = Page::init(url.0, orders, model.i18n.clone());
} }
Msg::ListLinksMsg(msg) => { Msg::ListLinks(msg) => {
if let Page::Home(model) = &mut model.page { if let Page::Home(model) = &mut model.page {
list_links::update(msg, model, &mut orders.proxy(Msg::ListLinksMsg)) list_links::update(msg, model, &mut orders.proxy(Msg::ListLinks))
} }
} }
Msg::ListUsersMsg(msg) => { Msg::ListUsers(msg) => {
if let Page::ListUsers(model) = &mut model.page { if let Page::ListUsers(model) = &mut model.page {
list_users::update(msg, model, &mut orders.proxy(Msg::ListUsersMsg)) list_users::update(msg, model, &mut orders.proxy(Msg::ListUsers))
} }
} }
Msg::NoMessage => (), Msg::NoMessage => (),
@ -165,8 +164,8 @@ fn view_content(page: &Page, url: &Url) -> Node<Msg> {
div![ div![
C!["container"], C!["container"],
match page { match page {
Page::Home(model) => pages::list_links::view(model).map_msg(Msg::ListLinksMsg), Page::Home(model) => pages::list_links::view(model).map_msg(Msg::ListLinks),
Page::ListUsers(model) => pages::list_users::view(model).map_msg(Msg::ListUsersMsg), Page::ListUsers(model) => pages::list_users::view(model).map_msg(Msg::ListUsers),
Page::NotFound => div![div![url.to_string()], "Page not found!"], Page::NotFound => div![div![url.to_string()], "Page not found!"],
} }
] ]

View File

@ -26,7 +26,7 @@ pub fn navigation(i18n: &I18n, base_url: &Url) -> Node<Msg> {
li![a![ev(Ev::Click, |_| Msg::NoMessage), t!("add-link"),],], li![a![ev(Ev::Click, |_| Msg::NoMessage), t!("add-link"),],],
li![a![ li![a![
attrs! {At::Href => crate::Urls::new(base_url).create_user()}, attrs! {At::Href => crate::Urls::new(base_url).create_user()},
ev(Ev::Click, |_| Msg::ListUsersMsg( ev(Ev::Click, |_| Msg::ListUsers(
super::pages::list_users::Msg::Edit( super::pages::list_users::Msg::Edit(
super::pages::list_users::UserEditMsg::CreateNewUser super::pages::list_users::UserEditMsg::CreateNewUser
) )

View File

@ -49,6 +49,7 @@ struct FilterInput {
pub enum Msg { pub enum Msg {
Query(UserQueryMsg), Query(UserQueryMsg),
Edit(UserEditMsg), Edit(UserEditMsg),
ClearAll,
} }
/// All the messages on user Querying /// All the messages on user Querying
@ -81,6 +82,10 @@ pub fn update(msg: Msg, model: &mut Model, orders: &mut impl Orders<Msg>) {
match msg { match msg {
Msg::Query(msg) => process_query_messages(msg, model, orders), Msg::Query(msg) => process_query_messages(msg, model, orders),
Msg::Edit(msg) => process_user_edit_messages(msg, model, orders), Msg::Edit(msg) => process_user_edit_messages(msg, model, orders),
Msg::ClearAll => {
model.last_message = None;
model.user_edit = None;
}
} }
} }
@ -176,6 +181,7 @@ pub fn process_user_edit_messages(
match msg { match msg {
UserEditMsg::EditUserSelected(user) => { UserEditMsg::EditUserSelected(user) => {
log!("Editing user: ", user); log!("Editing user: ", user);
model.last_message = None;
model.user_edit = Some(RefCell::new(user)) model.user_edit = Some(RefCell::new(user))
} }
UserEditMsg::CreateNewUser => { UserEditMsg::CreateNewUser => {
@ -216,10 +222,13 @@ pub fn process_user_edit_messages(
orders.perform_cmd(async { orders.perform_cmd(async {
let data = data; let data = data;
let response = match fetch( let response = match fetch(
Request::new("/admin/json/create_user/") Request::new(match data.edit {
.method(Method::Post) EditMode::Create => "/admin/json/create_user/",
.json(&data) EditMode::Edit => "/admin/json/update_user/",
.expect("serialization failed"), })
.method(Method::Post)
.json(&data)
.expect("serialization failed"),
) )
.await .await
{ {
@ -256,11 +265,22 @@ pub fn view(model: &Model) -> Node<Msg> {
let lang = model.i18n.clone(); let lang = model.i18n.clone();
let t = move |key: &str| lang.translate(key, None); let t = move |key: &str| lang.translate(key, None);
section![ section![
keyboard_ev(Ev::KeyDown, |keyboard_event| {
IF!(keyboard_event.key() == "Escape" => Msg::ClearAll)
}),
h1!("List Users Page from list_users"), h1!("List Users Page from list_users"),
if let Some(message) = &model.last_message { if let Some(message) = &model.last_message {
div![C!("Message"), &message.message] div![
C!["message", "center"],
div![
C!["closebutton"],
a!["\u{d7}"],
ev(Ev::Click, |_| Msg::ClearAll)
],
&message.message
]
} else { } else {
section!() section![]
}, },
table![ table![
// Column Headlines // Column Headlines
@ -363,6 +383,11 @@ fn edit_or_create_user<F: Fn(&str) -> String>(l: &RefCell<UserDelta>, t: F) -> N
let user = l.borrow(); let user = l.borrow();
div![ div![
C!["editdialog", "center"], C!["editdialog", "center"],
div![
C!["closebutton"],
a!["\u{d7}"],
ev(Ev::Click, |_| Msg::ClearAll)
],
h1![match &user.edit { h1![match &user.edit {
EditMode::Edit => t("edit-user"), EditMode::Edit => t("edit-user"),
EditMode::Create => t("new-user"), EditMode::Create => t("new-user"),

View File

@ -26,7 +26,7 @@ clap = "2.33"
dotenv = "0.15.0" dotenv = "0.15.0"
fluent-langneg = "0.13" fluent-langneg = "0.13"
image = "0.23" image = "0.23"
opentelemetry = "0.13" opentelemetry = "0.14"
opentelemetry-jaeger = "0.12" opentelemetry-jaeger = "0.12"
qrcode = "0.12" qrcode = "0.12"
rand = "0.8" rand = "0.8"
@ -70,4 +70,4 @@ tokio = "0.2.25"
[dev-dependencies.reqwest] [dev-dependencies.reqwest]
features = ["cookies"] features = ["cookies"]
version = "0.10.10" version = "0.11.3"

View File

@ -20,7 +20,7 @@ use tracing::{error, info, trace, warn};
static MIGRATOR: Migrator = sqlx::migrate!(); static MIGRATOR: Migrator = sqlx::migrate!();
#[allow(clippy::clippy::too_many_lines)] #[allow(clippy::too_many_lines)]
fn generate_cli() -> App<'static, 'static> { fn generate_cli() -> App<'static, 'static> {
app_from_crate!() app_from_crate!()
.arg( .arg(

View File

@ -374,6 +374,10 @@ pub async fn webservice(
.route( .route(
"/create_user/", "/create_user/",
web::post().to(views::process_create_user_json), web::post().to(views::process_create_user_json),
)
.route(
"/update_user/",
web::post().to(views::process_update_user_json),
), ),
) )
// login to the admin area // login to the admin area

View File

@ -4,7 +4,7 @@ use enum_map::EnumMap;
use serde::Serialize; use serde::Serialize;
use shared::{ use shared::{
apirequests::{ apirequests::{
general::{Filter, Operation, Ordering}, general::{EditMode, Filter, Operation, Ordering},
links::{LinkOverviewColumns, LinkRequestForm}, links::{LinkOverviewColumns, LinkRequestForm},
users::{UserDelta, UserOverviewColumns, UserRequestForm}, users::{UserDelta, UserOverviewColumns, UserRequestForm},
}, },
@ -310,7 +310,7 @@ pub struct Item<T> {
/// ///
/// # Errors /// # Errors
/// Fails with [`ServerError`] if access to the database fails or this user does not have permissions. /// Fails with [`ServerError`] if access to the database fails or this user does not have permissions.
#[allow(clippy::clippy::missing_panics_doc)] #[allow(clippy::missing_panics_doc)]
#[instrument(skip(id))] #[instrument(skip(id))]
pub async fn get_user( pub async fn get_user(
id: &Identity, id: &Identity,
@ -400,6 +400,9 @@ pub async fn create_user_json(
server_config: &ServerConfig, server_config: &ServerConfig,
) -> Result<Item<User>, ServerError> { ) -> Result<Item<User>, ServerError> {
info!("Creating a User: {:?}", &data); info!("Creating a User: {:?}", &data);
if data.edit != EditMode::Create {
return Err(ServerError::User("Wrong Request".to_string()));
}
let auth = authenticate(id, server_config).await?; let auth = authenticate(id, server_config).await?;
// Require a password on user creation! // Require a password on user creation!
@ -440,7 +443,58 @@ pub async fn create_user_json(
/// ///
/// # Errors /// # Errors
/// Fails with [`ServerError`] if access to the database fails, this user does not have permissions, or the given data is malformed. /// Fails with [`ServerError`] if access to the database fails, this user does not have permissions, or the given data is malformed.
#[allow(clippy::clippy::missing_panics_doc)]
#[instrument(skip(id))]
pub async fn update_user_json(
id: &Identity,
data: &web::Json<UserDelta>,
server_config: &ServerConfig,
) -> Result<Item<User>, ServerError> {
let auth = authenticate(id, server_config).await?;
if let Some(uid) = data.id {
let unmodified_user = User::get_user(uid, server_config).await?;
if auth.admin_or_self(uid) {
match auth {
Role::Admin { .. } | Role::Regular { .. } => {
info!("Updating userinfo: ");
let password = match &data.password {
Some(password) => NewUser::hash_password(password, &server_config.secret)?,
None => unmodified_user.password,
};
let new_user = User {
id: uid,
username: data.username.clone(),
email: data.email.clone(),
password,
role: unmodified_user.role,
language: unmodified_user.language,
};
new_user.update_user(server_config).await?;
let changed_user = User::get_user(uid, server_config).await?;
Ok(Item {
user: changed_user.clone(),
item: changed_user,
})
}
Role::NotAuthenticated | Role::Disabled => {
unreachable!("Should be unreachable because of the `admin_or_self`")
}
}
} else {
Err(ServerError::User("Not a valid UID".to_owned()))
}
} else {
Err(ServerError::User("Not a valid UID".to_owned()))
}
}
/// Take a [`actix_web::web::Form<NewUser>`] and update the corresponding entry in the database.
/// The password is only updated if a new password of at least 4 characters is provided.
/// The `user_id` is never changed.
///
/// # Errors
/// Fails with [`ServerError`] if access to the database fails, this user does not have permissions, or the given data is malformed.
#[allow(clippy::missing_panics_doc)]
#[instrument(skip(id))] #[instrument(skip(id))]
pub async fn update_user( pub async fn update_user(
id: &Identity, id: &Identity,

View File

@ -365,6 +365,21 @@ pub async fn process_create_user_json(
} }
} }
#[instrument(skip(id))]
pub async fn process_update_user_json(
config: web::Data<crate::ServerConfig>,
form: web::Json<UserDelta>,
id: Identity,
) -> Result<HttpResponse, ServerError> {
info!("Listing Users to Json api");
match queries::update_user_json(&id, &form, &config).await {
Ok(item) => Ok(HttpResponse::Ok().json2(&SuccessMessage {
message: format!("Successfully saved user: {}", item.item.username),
})),
Err(e) => Err(e),
}
}
#[instrument(skip(id))] #[instrument(skip(id))]
pub async fn toggle_admin( pub async fn toggle_admin(
data: web::Path<String>, data: web::Path<String>,

View File

@ -170,4 +170,18 @@ div.actions input {
div.editdialog { div.editdialog {
background-color: aliceblue; background-color: aliceblue;
border: 5px solid rgb(90, 90, 90); border: 5px solid rgb(90, 90, 90);
}
div.closebutton a {
display: block;
position: absolute;
top: 10px;
right: 10px;
font-size: xx-large;
}
div.message {
background-color: aliceblue;
border: 5px solid rgb(90, 90, 90);
height: auto;
} }