Let people list their current consents.

This commit is contained in:
Condorra 2023-04-02 12:30:50 +10:00
parent a9693803ef
commit ff5e80398a
3 changed files with 86 additions and 1 deletions

View File

@ -744,6 +744,24 @@ impl DBTrans {
Ok(None)
}
pub async fn list_consents(&self, consenting: &str) -> DResult<Vec<(String, ConsentType, Consent)>> {
Ok(self.pg_trans()?
.query("SELECT consented_user, consent_type, details \
FROM user_consent \
WHERE consenting_user = $1",
&[&consenting.to_lowercase()])
.await?
.into_iter()
.filter_map(|row|
match serde_json::from_value(row.get(2)) {
Err(_) => None,
Ok(consent) =>
ConsentType::from_str(row.get(1)).map(
|consent_type| (row.get(0), consent_type, consent))
})
.collect())
}
pub async fn find_user_consent_by_parties_type(&self, consenting: &str, consented: &str,
consent_type: &ConsentType) -> DResult<Option<Consent>> {
match self.pg_trans()?.query_opt(

View File

@ -811,6 +811,24 @@ async fn handle_corp_consent(ctx: &mut VerbContext<'_>, source_player: &Item,
Ok(())
}
async fn handle_list_allows(ctx: &mut VerbContext<'_>, item: &Item) -> UResult<()> {
let consents = ctx.trans.list_consents(&item.item_code).await?;
let mut msg = String::new();
if consents.is_empty() {
msg.push_str(ansi!("You have no consents. Type <bold>help allow<reset> to learn how to consent."));
} else {
msg.push_str(ansi!("You are consenting to the following actions (type <bold>help allow<reset> to learn how to change):\n"));
msg.push_str(&format!(ansi!("<bgblue><white><bold>| {:20} | {:12} | {:40} |<reset>\n"),
"User", "Consent type", "Details"));
for (user, consent_type, details) in consents {
msg.push_str(&format!("| {:20} | {:12} | {:40} |\n",
user, consent_type.to_str(), details.to_str()));
}
}
ctx.trans.queue_for_session(&ctx.session, Some(&(msg + "\n"))).await?;
Ok(())
}
pub struct Verb;
#[async_trait]
impl UserVerb for Verb {
@ -820,7 +838,7 @@ impl UserVerb for Verb {
let remaining_trim = remaining.trim();
if remaining_trim == "" {
// TODO: List all allows
handle_list_allows(ctx, &player_item).await?;
} else {
let mut cmd = match parsing::parse_allow(remaining, !ctx.session_dat.less_explicit_mode) {
Err(msg) => user_error(msg)?,

View File

@ -1,5 +1,6 @@
use serde::{Serialize, Deserialize};
use chrono::{DateTime, Utc};
use itertools::Itertools;
#[derive(Serialize, Deserialize, PartialEq, Debug)]
pub enum ConsentType {
@ -81,3 +82,51 @@ impl Default for Consent {
}
}
}
impl Consent {
pub fn to_str(&self) -> String {
let mut details = vec!();
if let Some(ref fc) = self.fight_consent {
match fc.status {
ConsentStatus::PendingAdd => {
details.push("pending acceptance".to_owned());
},
ConsentStatus::PendingDelete => {
details.push("pending agreement to delete".to_owned());
},
_ => {}
}
match fc.pending_change.as_ref() {
None => {},
Some(new_self) => {
details.push(format!("pending amendment to [{}]",
&new_self.to_str()));
}
}
if fc.allow_pick {
details.push("allow pick".to_owned());
}
if fc.freely_revoke {
details.push("allow revoke".to_owned());
}
}
if self.allow_private {
details.push("allow private".to_owned());
} else {
details.push("disallow private".to_owned());
}
if self.until_death {
details.push("until death".to_owned());
}
for in_place in self.only_in.iter() {
details.push(format!("in {}", in_place))
}
if let Some(exp) = self.expires {
details.push(format!("valid for {}",
humantime::format_duration(std::time::Duration::from_secs(
(exp - Utc::now()).num_seconds() as u64
))));
}
return details.into_iter().join(", ");
}
}