conversions7

This commit is contained in:
Filipriec
2026-08-23 22:28:53 +02:00
parent 6666f7a5b1
commit 8dacb981bf
15 changed files with 75 additions and 47 deletions

View File

@@ -9,9 +9,8 @@ pub(crate) const STRUCT_USER: &str = "struct:user";
pub(crate) const MANAGE: &str = "manage";
pub(crate) const READ: &str = "read";
/// Every ECB object, which is what the pipeline status is checked against:
/// one importer feeds every profile, so reading its health is not a
/// per-profile question.
/// Every exchange-rate object. Provider pipeline health is a global rather
/// than per-profile concern.
pub(crate) const ALL_EXCHANGE_RATES: &str = "exchange-rates:*";
/// The two bulk-transfer actions, mirroring
@@ -43,7 +42,7 @@ pub(crate) fn can_manage(snapshot: &AuthorizationSnapshot, area: &str) -> bool {
}
/// Whether the caller may see the reference-rate pipeline. Mirrors the
/// server's own check in `server/src/ecb/grpc.rs`.
/// server's exchange-rate authorization check.
pub(crate) fn can_read_exchange_rates(snapshot: &AuthorizationSnapshot) -> bool {
permits(snapshot, ALL_EXCHANGE_RATES, READ)
}

View File

@@ -26,7 +26,7 @@ pub(crate) struct AdminPageState {
pub can_import: bool,
pub can_export: bool,
/// Whether the exchange-rate pipeline is visible to this caller. Not a
/// structural area: it is granted through the ECB object, like the
/// structural area: it is granted through the exchange-rate object, like the
/// conversions it reports on.
pub can_exchange_rates: bool,
}

View File

@@ -181,7 +181,7 @@ fn describe(locale: Locale, object: &GrantableObject) -> (String, String) {
tr!(locale, "grants-label-all-journals"),
tr!(locale, "grants-note-all-journals"),
),
"global_ecb" => (
"global_exchange_rates" => (
tr!(locale, "grants-label-all-rates"),
tr!(locale, "grants-note-all-rates"),
),
@@ -193,7 +193,7 @@ fn describe(locale: Locale, object: &GrantableObject) -> (String, String) {
tr!(locale, "grants-label-journal"),
tr!(locale, "grants-note-journal"),
),
"ecb" => (
"exchange_rates" => (
tr!(locale, "grants-label-rates"),
tr!(locale, "grants-note-rates"),
),

View File

@@ -229,7 +229,7 @@ mod tests {
},
ObjectRow {
object: "exchange-rates:acme".to_string(),
label: "ECB rates".to_string(),
label: "Exchange rates".to_string(),
note: String::new(),
wildcard: true,
cells: cells(&["read"], &[]),
@@ -249,7 +249,7 @@ mod tests {
fn a_profile_shortcut_grants_the_wildcards_and_never_an_action_the_server_refuses() {
let group = group();
// The table row is covered by data:acme/*, so it is not granted again,
// and ECB rates only ever offer read.
// and official rates only ever offer read.
assert_eq!(
group.all_pairs(),
vec![

View File

@@ -71,8 +71,8 @@ impl RoleRow {
///
/// These are wildcard objects on purpose: they keep covering profiles and
/// tables added later, which is what "everything" has to mean for a role
/// created before the data exists. ECB rates are written by the server, so they
/// are readable and nothing more.
/// created before the data exists. Official rates are written by the server,
/// so they are readable and nothing more.
pub(crate) fn starter_grants(
locale: Locale,
access: &str,
@@ -110,7 +110,7 @@ mod tests {
use super::*;
#[test]
fn starter_access_never_hands_out_a_write_on_ecb_rates() {
fn starter_access_never_hands_out_a_write_on_exchange_rates() {
let locale = Locale::default();
assert!(starter_grants(locale, "none").unwrap().is_empty());
assert!(starter_grants(locale, "nonsense").is_err());
@@ -121,12 +121,12 @@ mod tests {
grants
.iter()
.all(|(object, action)| *object != "exchange-rates:*" || *action == "read"),
"{level} granted a write on ECB rates"
"{level} granted a write on exchange rates"
);
}
assert_eq!(starter_grants(locale, "read").unwrap().len(), 3);
// Four row actions on two wildcard objects, ECB read, and the two
// Four row actions on two wildcard objects, rate read, and the two
// transfer actions, which apply to tables alone.
assert_eq!(starter_grants(locale, "full").unwrap().len(), 11);
}