make GET /api/ return current permissions

This is useful for e.g. deciding whether or not to present the user
admin UI in navigation.

As part of this change, I adjusted the casing in Permissions, and then
all the toml stuff for consistency. Noted in changelog.
This commit is contained in:
Scott Lamb
2022-12-31 12:08:26 -05:00
parent a6bdf0bd80
commit 42fe054d46
12 changed files with 103 additions and 47 deletions

View File

@@ -21,6 +21,7 @@ fn default_ui_dir() -> PathBuf {
/// Top-level configuration file object.
#[derive(Debug, Deserialize)]
#[serde(deny_unknown_fields)]
#[serde(rename_all = "camelCase")]
pub struct ConfigFile {
pub binds: Vec<BindConfig>,
@@ -42,6 +43,7 @@ pub struct ConfigFile {
/// Per-bind configuration.
#[derive(Debug, Deserialize)]
#[serde(deny_unknown_fields)]
#[serde(rename_all = "camelCase")]
pub struct BindConfig {
/// The address to bind to.
#[serde(flatten)]
@@ -70,8 +72,8 @@ pub struct BindConfig {
}
#[derive(Debug, Deserialize)]
#[serde(rename_all = "lowercase")]
#[serde(deny_unknown_fields)]
#[serde(rename_all = "camelCase")]
pub enum AddressConfig {
/// IPv4 address such as `0.0.0.0:8080` or `127.0.0.1:8080`.
Ipv4(std::net::SocketAddrV4),

View File

@@ -367,7 +367,7 @@ async fn inner(
ui_dir: Some(&config.ui_dir),
allow_unauthenticated_permissions: b
.allow_unauthenticated_permissions
.as_ref()
.clone()
.map(db::Permissions::from),
trust_forward_hdrs: b.trust_forward_headers,
time_zone_name: time_zone_name.clone(),

View File

@@ -25,6 +25,8 @@ pub struct TopLevel<'a> {
#[serde(serialize_with = "TopLevel::serialize_cameras")]
pub cameras: (&'a db::LockedDatabase, bool, bool),
pub permissions: Permissions,
#[serde(skip_serializing_if = "Option::is_none")]
pub user: Option<ToplevelUser>,
@@ -553,8 +555,9 @@ where
}
/// API/config analog of `Permissions` defined in `db/proto/schema.proto`.
#[derive(Debug, Default, Deserialize, Serialize, PartialEq, Eq)]
#[derive(Clone, Debug, Default, Deserialize, Serialize, PartialEq, Eq)]
#[serde(deny_unknown_fields)]
#[serde(rename_all = "camelCase")]
pub struct Permissions {
#[serde(default)]
view_video: bool,
@@ -569,8 +572,8 @@ pub struct Permissions {
admin_users: bool,
}
impl From<&Permissions> for db::schema::Permissions {
fn from(p: &Permissions) -> Self {
impl From<Permissions> for db::schema::Permissions {
fn from(p: Permissions) -> Self {
Self {
view_video: p.view_video,
read_camera_configs: p.read_camera_configs,
@@ -581,8 +584,8 @@ impl From<&Permissions> for db::schema::Permissions {
}
}
impl From<&db::schema::Permissions> for Permissions {
fn from(p: &db::schema::Permissions) -> Self {
impl From<db::schema::Permissions> for Permissions {
fn from(p: db::schema::Permissions) -> Self {
Self {
view_video: p.view_video,
read_camera_configs: p.read_camera_configs,

View File

@@ -347,6 +347,7 @@ impl Service {
user: caller.user,
signals: (&db, days),
signal_types: &db,
permissions: caller.permissions.into(),
},
)
}

View File

@@ -57,7 +57,7 @@ impl Service {
if let Some(preferences) = r.preferences.take() {
change.config.preferences = preferences;
}
if let Some(ref permissions) = r.permissions.take() {
if let Some(permissions) = r.permissions.take() {
change.permissions = permissions.into();
}
if r != Default::default() {
@@ -101,7 +101,7 @@ impl Service {
} else {
None
}),
permissions: Some((&user.permissions).into()),
permissions: Some(user.permissions.clone().into()),
};
serve_json(&req, &out)
}
@@ -145,7 +145,7 @@ impl Service {
(_, _) => {}
}
if let Some(mut precondition) = r.precondition {
if matches!(precondition.username.take(), Some(n) if n != &user.username) {
if matches!(precondition.username.take(), Some(n) if n != user.username) {
bail_t!(FailedPrecondition, "username mismatch");
}
if matches!(precondition.preferences.take(), Some(ref p) if p != &user.config.preferences)
@@ -158,7 +158,7 @@ impl Service {
}
}
if let Some(p) = precondition.permissions.take() {
if user.permissions != db::Permissions::from(&p) {
if user.permissions != db::Permissions::from(p) {
bail_t!(FailedPrecondition, "permissions mismatch");
}
}
@@ -193,7 +193,7 @@ impl Service {
change.username = n.to_string();
}
if let Some(permissions) = update.permissions.take() {
change.permissions = (&permissions).into();
change.permissions = permissions.into();
}
// Safety valve in case something is added to UserSubset and forgotten here.