Add config parameter that specifies instance actor's private key

This commit is contained in:
silverpill 2021-11-18 00:22:41 +00:00
parent d94e3d610d
commit 52b51501d5
5 changed files with 48 additions and 4 deletions

View file

@ -129,6 +129,12 @@ GET /api/v1/statuses/{status_id}/signature
## CLI commands ## CLI commands
Generate RSA private key:
```
mitractl generate-rsa-key
```
Generate invite code: Generate invite code:
``` ```

View file

@ -10,6 +10,7 @@ instance_title: myserver
instance_short_description: my fedi instance instance_short_description: my fedi instance
# Long description can contain markdown syntax # Long description can contain markdown syntax
instance_description: my fedi instance instance_description: my fedi instance
instance_rsa_key: null
registrations_open: false registrations_open: false
# Login message must contain instance URL # Login message must contain instance URL
login_message: 'Sign this message to log in to https://myserver.net. Do not sign this message on other sites!' login_message: 'Sign this message to log in to https://myserver.net. Do not sign this message on other sites!'

View file

@ -12,6 +12,7 @@ use mitra::models::users::queries::{
create_invite_code, create_invite_code,
get_invite_codes, get_invite_codes,
}; };
use mitra::utils::crypto::{generate_private_key, serialize_private_key};
/// Admin CLI tool /// Admin CLI tool
#[derive(Clap)] #[derive(Clap)]
@ -22,6 +23,7 @@ struct Opts {
#[derive(Clap)] #[derive(Clap)]
enum SubCommand { enum SubCommand {
GenerateRsaKey(GenerateRsaKey),
GenerateEthereumAddress(GenerateEthereumAddress), GenerateEthereumAddress(GenerateEthereumAddress),
GenerateInviteCode(GenerateInviteCode), GenerateInviteCode(GenerateInviteCode),
@ -30,6 +32,18 @@ enum SubCommand {
DeletePost(DeletePost), DeletePost(DeletePost),
} }
/// Generate RSA private key
#[derive(Clap)]
struct GenerateRsaKey;
impl GenerateRsaKey {
fn execute(&self) -> () {
let private_key = generate_private_key().unwrap();
let private_key_str = serialize_private_key(private_key).unwrap();
println!("{}", private_key_str);
}
}
/// Generate ethereum address /// Generate ethereum address
#[derive(Clap)] #[derive(Clap)]
struct GenerateEthereumAddress; struct GenerateEthereumAddress;
@ -61,6 +75,7 @@ async fn main() {
let opts: Opts = Opts::parse(); let opts: Opts = Opts::parse();
match opts.subcmd { match opts.subcmd {
SubCommand::GenerateRsaKey(cmd) => cmd.execute(),
SubCommand::GenerateEthereumAddress(_) => { SubCommand::GenerateEthereumAddress(_) => {
let (private_key, address) = generate_ethereum_address(); let (private_key, address) = generate_ethereum_address();
println!( println!(

View file

@ -1,10 +1,12 @@
use std::path::PathBuf; use std::path::PathBuf;
use std::str::FromStr; use std::str::FromStr;
use rsa::RsaPrivateKey;
use serde::{de, Deserialize, Deserializer}; use serde::{de, Deserialize, Deserializer};
use url::Url; use url::Url;
use crate::errors::ConversionError; use crate::errors::ConversionError;
use crate::utils::crypto::deserialize_private_key;
#[derive(Clone, Debug)] #[derive(Clone, Debug)]
pub enum Environment { pub enum Environment {
@ -86,6 +88,7 @@ pub struct Config {
pub instance_title: String, pub instance_title: String,
pub instance_short_description: String, pub instance_short_description: String,
pub instance_description: String, pub instance_description: String,
instance_rsa_key: String,
#[serde(default)] #[serde(default)]
pub registrations_open: bool, // default is false pub registrations_open: bool, // default is false
@ -114,8 +117,15 @@ impl Config {
Ok(url) Ok(url)
} }
fn try_instance_rsa_key(&self) -> Result<RsaPrivateKey, rsa::pkcs8::Error> {
deserialize_private_key(&self.instance_rsa_key)
}
pub fn instance(&self) -> Instance { pub fn instance(&self) -> Instance {
Instance { _url: self.try_instance_url().unwrap() } Instance {
_url: self.try_instance_url().unwrap(),
actor_key: self.try_instance_rsa_key().unwrap(),
}
} }
pub fn instance_url(&self) -> String { pub fn instance_url(&self) -> String {
@ -129,6 +139,8 @@ impl Config {
pub struct Instance { pub struct Instance {
_url: Url, _url: Url,
// Instance actor
pub actor_key: RsaPrivateKey,
} }
impl Instance { impl Instance {
@ -162,18 +174,24 @@ pub fn parse_config() -> Config {
}; };
}; };
config.try_instance_url().expect("invalid instance URI"); config.try_instance_url().expect("invalid instance URI");
config.try_instance_rsa_key().expect("invalid RSA private key");
config config
} }
#[cfg(test)] #[cfg(test)]
mod tests { mod tests {
use rand::rngs::OsRng;
use super::*; use super::*;
#[test] #[test]
fn test_instance_url_https_dns() { fn test_instance_url_https_dns() {
let instance_url = Url::parse("https://example.com/").unwrap(); let instance_url = Url::parse("https://example.com/").unwrap();
let instance = Instance { _url: instance_url }; let instance_rsa_key = RsaPrivateKey::new(&mut OsRng, 512).unwrap();
let instance = Instance {
_url: instance_url,
actor_key: instance_rsa_key,
};
assert_eq!(instance.url(), "https://example.com"); assert_eq!(instance.url(), "https://example.com");
assert_eq!(instance.host(), "example.com"); assert_eq!(instance.host(), "example.com");
@ -182,7 +200,11 @@ mod tests {
#[test] #[test]
fn test_instance_url_http_ipv4() { fn test_instance_url_http_ipv4() {
let instance_url = Url::parse("http://1.2.3.4:3777/").unwrap(); let instance_url = Url::parse("http://1.2.3.4:3777/").unwrap();
let instance = Instance { _url: instance_url }; let instance_rsa_key = RsaPrivateKey::new(&mut OsRng, 512).unwrap();
let instance = Instance {
_url: instance_url,
actor_key: instance_rsa_key,
};
assert_eq!(instance.url(), "http://1.2.3.4:3777"); assert_eq!(instance.url(), "http://1.2.3.4:3777");
assert_eq!(instance.host(), "1.2.3.4"); assert_eq!(instance.host(), "1.2.3.4");

View file

@ -11,5 +11,5 @@ pub mod mastodon_api;
pub mod models; pub mod models;
pub mod nodeinfo; pub mod nodeinfo;
pub mod scheduler; pub mod scheduler;
mod utils; pub mod utils;
pub mod webfinger; pub mod webfinger;