mirror of
https://github.com/mikedilger/chorus.git
synced 2026-08-01 07:21:39 +00:00
[BREAKING] Switch to database user pubkeys, remove config user pubkeys
This commit is contained in:
parent
f02c071474
commit
cb431b6b00
@ -58,7 +58,7 @@ fn main() -> Result<(), Error> {
|
||||
}
|
||||
|
||||
// Skip if the author is authorized user
|
||||
if config.user_keys.contains(&event.pubkey()) {
|
||||
if chorus::is_authorized_user(event.pubkey()) {
|
||||
continue;
|
||||
}
|
||||
|
||||
|
||||
@ -23,8 +23,6 @@ pub struct FriendlyConfig {
|
||||
pub contact: Option<String>,
|
||||
pub public_key_hex: Option<String>,
|
||||
pub open_relay: bool,
|
||||
pub user_hex_keys: Vec<String>,
|
||||
pub moderator_hex_keys: Vec<String>,
|
||||
pub verify_events: bool,
|
||||
pub allow_scraping: bool,
|
||||
pub allow_scrape_if_limited_to: u32,
|
||||
@ -64,8 +62,6 @@ impl Default for FriendlyConfig {
|
||||
contact: None,
|
||||
public_key_hex: None,
|
||||
open_relay: false,
|
||||
user_hex_keys: vec![],
|
||||
moderator_hex_keys: vec![],
|
||||
verify_events: true,
|
||||
allow_scraping: false,
|
||||
allow_scrape_if_limited_to: 100,
|
||||
@ -107,8 +103,6 @@ impl FriendlyConfig {
|
||||
contact,
|
||||
public_key_hex,
|
||||
open_relay,
|
||||
user_hex_keys,
|
||||
moderator_hex_keys,
|
||||
verify_events,
|
||||
allow_scraping,
|
||||
allow_scrape_if_limited_to,
|
||||
@ -135,16 +129,6 @@ impl FriendlyConfig {
|
||||
public_key = Some(Pubkey::read_hex(pkh.as_bytes())?);
|
||||
};
|
||||
|
||||
let mut user_keys: Vec<Pubkey> = Vec::with_capacity(user_hex_keys.len());
|
||||
for pkh in user_hex_keys.iter() {
|
||||
user_keys.push(Pubkey::read_hex(pkh.as_bytes())?);
|
||||
}
|
||||
|
||||
let mut moderator_keys: Vec<Pubkey> = Vec::with_capacity(moderator_hex_keys.len());
|
||||
for pkh in moderator_hex_keys.iter() {
|
||||
moderator_keys.push(Pubkey::read_hex(pkh.as_bytes())?);
|
||||
}
|
||||
|
||||
let hostname = Host::parse(&hostname)?;
|
||||
|
||||
let server_log_level =
|
||||
@ -170,10 +154,6 @@ impl FriendlyConfig {
|
||||
contact,
|
||||
public_key,
|
||||
open_relay,
|
||||
user_keys,
|
||||
user_hex_keys,
|
||||
moderator_keys,
|
||||
moderator_hex_keys,
|
||||
verify_events,
|
||||
allow_scraping,
|
||||
allow_scrape_if_limited_to,
|
||||
@ -214,10 +194,6 @@ pub struct Config {
|
||||
pub contact: Option<String>,
|
||||
pub public_key: Option<Pubkey>,
|
||||
pub open_relay: bool,
|
||||
pub user_keys: Vec<Pubkey>,
|
||||
pub user_hex_keys: Vec<String>,
|
||||
pub moderator_keys: Vec<Pubkey>,
|
||||
pub moderator_hex_keys: Vec<String>,
|
||||
pub verify_events: bool,
|
||||
pub allow_scraping: bool,
|
||||
pub allow_scrape_if_limited_to: u32,
|
||||
|
||||
23
src/lib.rs
23
src/lib.rs
@ -478,7 +478,7 @@ impl WebSocketService {
|
||||
.get_event_by_offset(new_event_offset)?;
|
||||
|
||||
let event_flags = nostr::event_flags(event, &self.user);
|
||||
let authorized_user = nostr::authorized_user(&self.user);
|
||||
let authorized_user = self.user.map(|pk| is_authorized_user(pk)).unwrap_or(false);
|
||||
|
||||
'subs: for (subid, filters) in self.subscriptions.iter() {
|
||||
for filter in filters.iter() {
|
||||
@ -756,8 +756,9 @@ pub fn get_event_approval(store: &Store, id: Id) -> Result<Option<bool>, Error>
|
||||
"approved-events",
|
||||
)))?;
|
||||
let txn = store.read_txn()?;
|
||||
Ok(approved_events.get(&txn, id.as_slice())?
|
||||
.map(|u| !u.is_empty() && u[0] != 0))
|
||||
Ok(approved_events
|
||||
.get(&txn, id.as_slice())?
|
||||
.map(|u| !u.is_empty() && u[0] != 0))
|
||||
}
|
||||
|
||||
/// Dump all event approval statuses
|
||||
@ -839,9 +840,7 @@ pub fn dump_pubkey_approvals(store: &Store) -> Result<Vec<(Pubkey, bool)>, Error
|
||||
pub fn add_authorized_user(store: &Store, pubkey: Pubkey, moderator: bool) -> Result<(), Error> {
|
||||
let users = store
|
||||
.extra_table("users")
|
||||
.ok_or(Into::<Error>::into(ChorusError::MissingTable(
|
||||
"users",
|
||||
)))?;
|
||||
.ok_or(Into::<Error>::into(ChorusError::MissingTable("users")))?;
|
||||
let mut txn = store.write_txn()?;
|
||||
users.put(&mut txn, pubkey.as_slice(), &[moderator as u8])?;
|
||||
txn.commit()?;
|
||||
@ -852,9 +851,7 @@ pub fn add_authorized_user(store: &Store, pubkey: Pubkey, moderator: bool) -> Re
|
||||
pub fn rm_authorized_user(store: &Store, pubkey: Pubkey) -> Result<(), Error> {
|
||||
let users = store
|
||||
.extra_table("users")
|
||||
.ok_or(Into::<Error>::into(ChorusError::MissingTable(
|
||||
"users",
|
||||
)))?;
|
||||
.ok_or(Into::<Error>::into(ChorusError::MissingTable("users")))?;
|
||||
let mut txn = store.write_txn()?;
|
||||
users.delete(&mut txn, pubkey.as_slice())?;
|
||||
txn.commit()?;
|
||||
@ -865,9 +862,7 @@ pub fn rm_authorized_user(store: &Store, pubkey: Pubkey) -> Result<(), Error> {
|
||||
pub fn get_authorized_user(store: &Store, pubkey: Pubkey) -> Result<Option<bool>, Error> {
|
||||
let users = store
|
||||
.extra_table("users")
|
||||
.ok_or(Into::<Error>::into(ChorusError::MissingTable(
|
||||
"users",
|
||||
)))?;
|
||||
.ok_or(Into::<Error>::into(ChorusError::MissingTable("users")))?;
|
||||
let txn = store.read_txn()?;
|
||||
Ok(users
|
||||
.get(&txn, pubkey.as_slice())?
|
||||
@ -879,9 +874,7 @@ pub fn dump_authorized_users(store: &Store) -> Result<Vec<(Pubkey, bool)>, Error
|
||||
let mut output: Vec<(Pubkey, bool)> = Vec::new();
|
||||
let users = store
|
||||
.extra_table("users")
|
||||
.ok_or(Into::<Error>::into(ChorusError::MissingTable(
|
||||
"users",
|
||||
)))?;
|
||||
.ok_or(Into::<Error>::into(ChorusError::MissingTable("users")))?;
|
||||
let txn = store.read_txn()?;
|
||||
for i in users.iter(&txn)? {
|
||||
let (key, val) = i?;
|
||||
|
||||
32
src/nostr.rs
32
src/nostr.rs
@ -124,7 +124,10 @@ impl WebSocketService {
|
||||
}
|
||||
|
||||
let user = self.user;
|
||||
let authorized_user = authorized_user(&user);
|
||||
let authorized_user = self
|
||||
.user
|
||||
.map(|pk| crate::is_authorized_user(pk))
|
||||
.unwrap_or(false);
|
||||
|
||||
if user.is_none() {
|
||||
for filter in filters.iter() {
|
||||
@ -292,7 +295,10 @@ impl WebSocketService {
|
||||
|
||||
async fn event_inner(&mut self) -> Result<(), Error> {
|
||||
let user = self.user;
|
||||
let authorized_user = authorized_user(&user);
|
||||
let authorized_user = self
|
||||
.user
|
||||
.map(|pk| crate::is_authorized_user(pk))
|
||||
.unwrap_or(false);
|
||||
|
||||
// Delineate the event back out of the session buffer
|
||||
let event = unsafe { Event::delineate(&self.buffer)? };
|
||||
@ -519,7 +525,10 @@ impl WebSocketService {
|
||||
}
|
||||
|
||||
let user = self.user;
|
||||
let authorized_user = authorized_user(&user);
|
||||
let authorized_user = self
|
||||
.user
|
||||
.map(|pk| crate::is_authorized_user(pk))
|
||||
.unwrap_or(false);
|
||||
|
||||
// Find all matching events
|
||||
let mut events: Vec<&Event> = Vec::new();
|
||||
@ -742,7 +751,7 @@ async fn screen_incoming_event(
|
||||
}
|
||||
|
||||
// If the author is one of our users, always accept it
|
||||
if GLOBALS.config.read().user_keys.contains(&event.pubkey()) {
|
||||
if crate::is_authorized_user(event.pubkey()) {
|
||||
return Ok(true);
|
||||
}
|
||||
|
||||
@ -750,8 +759,8 @@ async fn screen_incoming_event(
|
||||
for mut tag in event.tags()?.iter() {
|
||||
if tag.next() == Some(b"p") {
|
||||
if let Some(value) = tag.next() {
|
||||
for ukhex in &GLOBALS.config.read().user_hex_keys {
|
||||
if value == ukhex.as_bytes() {
|
||||
if let Ok(pk) = Pubkey::read_hex(value) {
|
||||
if crate::is_authorized_user(pk) {
|
||||
return Ok(true);
|
||||
}
|
||||
}
|
||||
@ -821,13 +830,6 @@ pub fn screen_outgoing_event(
|
||||
false
|
||||
}
|
||||
|
||||
pub fn authorized_user(user: &Option<Pubkey>) -> bool {
|
||||
match user {
|
||||
None => false,
|
||||
Some(pk) => GLOBALS.config.read().user_keys.contains(pk),
|
||||
}
|
||||
}
|
||||
|
||||
pub struct EventFlags {
|
||||
pub author_is_an_authorized_user: bool,
|
||||
pub author_is_current_user: bool,
|
||||
@ -836,7 +838,7 @@ pub struct EventFlags {
|
||||
}
|
||||
|
||||
pub fn event_flags(event: &Event, user: &Option<Pubkey>) -> EventFlags {
|
||||
let author_is_an_authorized_user = GLOBALS.config.read().user_keys.contains(&event.pubkey());
|
||||
let author_is_an_authorized_user = crate::is_authorized_user(event.pubkey());
|
||||
|
||||
let author_is_current_user = match user {
|
||||
None => false,
|
||||
@ -857,7 +859,7 @@ pub fn event_flags(event: &Event, user: &Option<Pubkey>) -> EventFlags {
|
||||
}
|
||||
}
|
||||
|
||||
if GLOBALS.config.read().user_keys.contains(&tagged_pk) {
|
||||
if crate::is_authorized_user(tagged_pk) {
|
||||
tags_an_authorized_user = true;
|
||||
}
|
||||
}
|
||||
|
||||
@ -1,5 +1,4 @@
|
||||
use crate::error::{ChorusError, Error};
|
||||
use crate::globals::GLOBALS;
|
||||
use base64::prelude::*;
|
||||
use http::header::AUTHORIZATION;
|
||||
use hyper::body::Incoming;
|
||||
@ -68,7 +67,7 @@ fn verify_auth_inner(request: &Request<Incoming>) -> Result<AuthData, Error> {
|
||||
}
|
||||
|
||||
// Nostr event must be signed by a chorus user
|
||||
if !GLOBALS.config.read().user_keys.contains(&event.pubkey()) {
|
||||
if !crate::is_authorized_user(event.pubkey()) {
|
||||
return s_err("You are not an authorized user");
|
||||
}
|
||||
|
||||
|
||||
@ -56,12 +56,7 @@ pub async fn check_auth(request: Request<Incoming>) -> Result<Value, Error> {
|
||||
}
|
||||
|
||||
// Nostr event must be signed by a moderator
|
||||
if !GLOBALS
|
||||
.config
|
||||
.read()
|
||||
.moderator_keys
|
||||
.contains(&event.pubkey())
|
||||
{
|
||||
if !crate::is_moderator(event.pubkey()) {
|
||||
return s_err("Authorization failed as user is not a moderator");
|
||||
}
|
||||
|
||||
|
||||
Loading…
x
Reference in New Issue
Block a user