Add registration.type configuration option

This commit is contained in:
silverpill 2023-01-24 20:55:24 +00:00
parent b82c2f3fc6
commit 771f45baab
11 changed files with 92 additions and 17 deletions

View file

@ -9,6 +9,11 @@ The format is based on [Keep a Changelog](https://keepachangelog.com/en/1.0.0/).
### Added
- Added `approval_required` and `invites_enabled` flags to `/api/v1/instance` endpoint response.
- Added `registration.type` configuration option (replaces `registrations_open`).
### Deprecated
- `registrations_open` configuration option.
### Removed

View file

@ -9,7 +9,9 @@ instance_uri: 127.0.0.1:8380
instance_title: Mitra
instance_short_description: My instance
instance_description: My instance
registrations_open: true
registration:
type: open
blockchains:
# Parameters for hardhat local node

View file

@ -18,7 +18,9 @@ instance_short_description: my instance
# Long description can contain markdown syntax
instance_description: my instance
registrations_open: false
registration:
# Possible values: open, invite
type: invite
# EIP-4361 login message
#login_message: 'Do not sign this message on other sites!'

View file

@ -17,9 +17,13 @@ async fn main() {
SubCommand::GenerateEthereumAddress(cmd) => cmd.execute(),
subcmd => {
// Other commands require initialized app
let config = parse_config();
let (config, config_warnings) = parse_config();
configure_logger(config.log_level);
log::info!("config loaded from {}", config.config_path);
for warning in config_warnings {
log::warn!("{}", warning);
};
let db_config = config.database_url.parse().unwrap();
let db_client = &mut create_database_client(&db_config).await;
apply_migrations(db_client).await;

View file

@ -12,7 +12,7 @@ use crate::utils::crypto_rsa::{
use crate::utils::files::{set_file_permissions, write_file};
use super::environment::Environment;
use super::main::Config;
use super::main::{Config, RegistrationType};
struct EnvConfig {
config_path: String,
@ -78,12 +78,14 @@ fn read_instance_rsa_key(storage_dir: &Path) -> RsaPrivateKey {
}
}
pub fn parse_config() -> Config {
pub fn parse_config() -> (Config, Vec<&'static str>) {
let env = parse_env();
let config_yaml = std::fs::read_to_string(&env.config_path)
.expect("failed to load config file");
let mut config = serde_yaml::from_str::<Config>(&config_yaml)
.expect("invalid yaml data");
let mut warnings = vec![];
// Set parameters from environment
config.config_path = env.config_path;
if let Some(environment) = env.environment {
@ -109,8 +111,18 @@ pub fn parse_config() -> Config {
panic!("both ipfs_api_url and ipfs_gateway_url must be set");
};
if let Some(registrations_open) = config.registrations_open {
// Change type if 'registrations_open' parameter is used
warnings.push("'registrations_open' setting is deprecated, use 'registration' instead");
if registrations_open {
config.registration.registration_type = RegistrationType::Open;
} else {
config.registration.registration_type = RegistrationType::Invite;
};
};
// Insert instance RSA key
config.instance_rsa_key = Some(read_instance_rsa_key(&config.storage_dir));
config
(config, warnings)
}

View file

@ -2,7 +2,11 @@ use std::path::PathBuf;
use log::{Level as LogLevel};
use rsa::RsaPrivateKey;
use serde::Deserialize;
use serde::{
Deserialize,
Deserializer,
de::Error as DeserializerError,
};
use url::Url;
use crate::activitypub::constants::ACTOR_KEY_SUFFIX;
@ -14,6 +18,36 @@ use super::blockchain::BlockchainConfig;
use super::environment::Environment;
use super::MITRA_VERSION;
#[derive(Clone, PartialEq)]
pub enum RegistrationType {
Open,
Invite,
}
impl Default for RegistrationType {
fn default() -> Self { Self::Invite }
}
impl<'de> Deserialize<'de> for RegistrationType {
fn deserialize<D>(deserializer: D) -> Result<Self, D::Error>
where D: Deserializer<'de>
{
let registration_type_str = String::deserialize(deserializer)?;
let registration_type = match registration_type_str.as_str() {
"open" => Self::Open,
"invite" => Self::Invite,
_ => return Err(DeserializerError::custom("unknown registration type")),
};
Ok(registration_type)
}
}
#[derive(Clone, Default, Deserialize)]
pub struct RegistrationConfig {
#[serde(rename = "type")]
pub registration_type: RegistrationType,
}
fn default_log_level() -> LogLevel { LogLevel::Info }
fn default_login_message() -> String { "Do not sign this message on other sites!".to_string() }
@ -52,8 +86,10 @@ pub struct Config {
#[serde(skip)]
pub(super) instance_rsa_key: Option<RsaPrivateKey>,
pub(super) registrations_open: Option<bool>, // deprecated
#[serde(default)]
pub registrations_open: bool, // default is false
pub registration: RegistrationConfig,
// EIP-4361 login message
#[serde(default = "default_login_message")]

View file

@ -10,6 +10,6 @@ pub use blockchain::{
};
pub use environment::Environment;
pub use loader::parse_config;
pub use main::{Config, Instance};
pub use main::{Config, Instance, RegistrationType};
pub const MITRA_VERSION: &str = env!("CARGO_PKG_VERSION");

View file

@ -39,9 +39,12 @@ use mitra::web_client::views as web_client;
#[actix_web::main]
async fn main() -> std::io::Result<()> {
let config = parse_config();
let (config, config_warnings) = parse_config();
configure_logger(config.log_level);
log::info!("config loaded from {}", config.config_path);
for warning in config_warnings {
log::warn!("{}", warning);
};
let db_pool = create_pool(&config.database_url);
let mut db_client = get_database_client(&db_pool).await.unwrap();

View file

@ -12,7 +12,7 @@ use crate::activitypub::builders::{
prepare_update_person,
},
};
use crate::config::Config;
use crate::config::{Config, RegistrationType};
use crate::database::{get_database_client, DatabaseError, DbPool};
use crate::errors::{HttpError, ValidationError};
use crate::ethereum::contracts::ContractSet;
@ -111,7 +111,7 @@ pub async fn create_account(
let db_client = &mut **get_database_client(&db_pool).await?;
// Validate
account_data.clean()?;
if !config.registrations_open {
if config.registration.registration_type == RegistrationType::Invite {
let invite_code = account_data.invite_code.as_ref()
.ok_or(ValidationError("invite code is required"))?;
if !is_valid_invite_code(db_client, invite_code).await? {

View file

@ -1,7 +1,12 @@
use serde::Serialize;
use serde_json::{to_value, Value};
use crate::config::{BlockchainConfig, Config, MITRA_VERSION};
use crate::config::{
BlockchainConfig,
Config,
RegistrationType,
MITRA_VERSION,
};
use crate::ethereum::contracts::ContractSet;
use crate::mastodon_api::{
MASTODON_API_VERSION,
@ -139,9 +144,13 @@ impl InstanceInfo {
description: markdown_to_html(&config.instance_description),
description_source: config.instance_description.clone(),
version: get_full_api_version(MITRA_VERSION),
registrations: config.registrations_open,
registrations:
config.registration.registration_type !=
RegistrationType::Invite,
approval_required: false,
invites_enabled: !config.registrations_open,
invites_enabled:
config.registration.registration_type ==
RegistrationType::Invite,
stats: InstanceStats {
user_count,
status_count: post_count,

View file

@ -2,7 +2,7 @@
use serde::Serialize;
use crate::config::{Config, MITRA_VERSION};
use crate::config::{Config, RegistrationType, MITRA_VERSION};
#[derive(Serialize)]
struct Software {
@ -66,7 +66,9 @@ impl NodeInfo20 {
software,
protocols: vec!["activitypub".to_string()],
services,
open_registrations: config.registrations_open,
open_registrations:
config.registration.registration_type !=
RegistrationType::Invite,
usage,
metadata,
}