mirror of
https://git.verdigado.com/NB-Public/simple-wkd.git
synced 2024-10-30 01:05:53 +01:00
Add allowed domains
This commit is contained in:
parent
6d65c5ffc3
commit
e621a735f5
6 changed files with 38 additions and 25 deletions
|
@ -1,12 +1,7 @@
|
||||||
<!DOCTYPE html>
|
<!DOCTYPE html>
|
||||||
<html lang="en">
|
<html lang="en">
|
||||||
|
|
||||||
<head>
|
<head></head>
|
||||||
<meta charset="UTF-8">
|
|
||||||
<meta http-equiv="X-UA-Compatible" content="IE=edge">
|
|
||||||
<meta name="viewport" content="width=device-width, initial-scale=1.0">
|
|
||||||
<title>Document</title>
|
|
||||||
</head>
|
|
||||||
|
|
||||||
<body>
|
<body>
|
||||||
<div style="width: 100%; text-align: center; display: flex; flex-direction: column;">
|
<div style="width: 100%; text-align: center; display: flex; flex-direction: column;">
|
||||||
|
|
|
@ -2,6 +2,7 @@ variant = "Advanced"
|
||||||
root_folder = "data"
|
root_folder = "data"
|
||||||
max_age = 900
|
max_age = 900
|
||||||
cleanup_interval = 21600
|
cleanup_interval = 21600
|
||||||
|
allowed_domains = ["example.org", "example.com"]
|
||||||
port = 8080
|
port = 8080
|
||||||
external_url = "http://localhost:8080"
|
external_url = "http://localhost:8080"
|
||||||
|
|
||||||
|
|
|
@ -3,32 +3,34 @@ use thiserror::Error;
|
||||||
|
|
||||||
#[derive(Error, Debug, Clone, Copy)]
|
#[derive(Error, Debug, Clone, Copy)]
|
||||||
pub enum Error {
|
pub enum Error {
|
||||||
#[error("EC1: Cert is invalid")]
|
#[error("(0x00) Cert is invalid")]
|
||||||
InvalidCert,
|
InvalidCert,
|
||||||
#[error("EP1: Error while parsing cert")]
|
#[error("(0x01) Error while parsing cert")]
|
||||||
ParseCert,
|
ParseCert,
|
||||||
#[error("EP2: Error while parsing an E-Mail address")]
|
#[error("(0x02) Error while parsing an E-Mail address")]
|
||||||
ParseEmail,
|
ParseEmail,
|
||||||
#[error("EM1: There is no pending request associated to this token")]
|
#[error("(0x03) There is no pending request associated to this token")]
|
||||||
MissingPending,
|
MissingPending,
|
||||||
#[error("EM2: Requested key does not exist")]
|
#[error("(0x04) Requested key does not exist")]
|
||||||
MissingKey,
|
MissingKey,
|
||||||
#[error("EM3: No E-Mail found in the certificate")]
|
#[error("(0x05) No E-Mail found in the certificate")]
|
||||||
MissingMail,
|
MissingMail,
|
||||||
#[error("EE1: Error while sending the E-Mail")]
|
#[error("(0x06) Error while sending the E-Mail")]
|
||||||
SendMail,
|
SendMail,
|
||||||
#[error("ES1: rror while serializing data")]
|
#[error("(0x07) rror while serializing data")]
|
||||||
SerializeData,
|
SerializeData,
|
||||||
#[error("ES2: Error while deserializing data")]
|
#[error("(0x08) Error while deserializing data")]
|
||||||
DeserializeData,
|
DeserializeData,
|
||||||
#[error("ES3: The file is inaccessible")]
|
#[error("(0x09) The file is inaccessible")]
|
||||||
Inaccessible,
|
Inaccessible,
|
||||||
#[error("ES4: Error while adding a key to the wkd")]
|
#[error("(0x0A) Error while adding a key to the wkd")]
|
||||||
AddingKey,
|
AddingKey,
|
||||||
#[error("EG1: Error while generating the wkd path")]
|
#[error("(0x0B) Error while generating the wkd path")]
|
||||||
PathGeneration,
|
PathGeneration,
|
||||||
#[error("EG2: Error while generating the email")]
|
#[error("(0x0C) Error while generating the email")]
|
||||||
MailGeneration,
|
MailGeneration,
|
||||||
|
#[error("(0x0D) Wrong email domain")]
|
||||||
|
WrongDomain,
|
||||||
}
|
}
|
||||||
|
|
||||||
impl actix_web::ResponseError for Error {
|
impl actix_web::ResponseError for Error {
|
||||||
|
@ -36,6 +38,7 @@ impl actix_web::ResponseError for Error {
|
||||||
match self {
|
match self {
|
||||||
Self::MissingPending => StatusCode::from_u16(404).unwrap(),
|
Self::MissingPending => StatusCode::from_u16(404).unwrap(),
|
||||||
Self::MissingKey => StatusCode::from_u16(404).unwrap(),
|
Self::MissingKey => StatusCode::from_u16(404).unwrap(),
|
||||||
|
Self::WrongDomain => StatusCode::from_u16(401).unwrap(),
|
||||||
_ => StatusCode::from_u16(500).unwrap(),
|
_ => StatusCode::from_u16(500).unwrap(),
|
||||||
}
|
}
|
||||||
}
|
}
|
||||||
|
|
|
@ -5,6 +5,7 @@ mod settings;
|
||||||
mod utils;
|
mod utils;
|
||||||
|
|
||||||
use crate::settings::SETTINGS;
|
use crate::settings::SETTINGS;
|
||||||
|
use crate::utils::is_email_allowed;
|
||||||
|
|
||||||
use self::confirmation::{confirm_action, send_confirmation_email};
|
use self::confirmation::{confirm_action, send_confirmation_email};
|
||||||
use self::management::{clean_stale, store_pending_addition, store_pending_deletion, Action};
|
use self::management::{clean_stale, store_pending_addition, store_pending_deletion, Action};
|
||||||
|
@ -69,6 +70,7 @@ async fn main() -> std::io::Result<()> {
|
||||||
async fn submit(pem: web::Form<Pem>) -> Result<String> {
|
async fn submit(pem: web::Form<Pem>) -> Result<String> {
|
||||||
let cert = parse_pem(&pem.key)?;
|
let cert = parse_pem(&pem.key)?;
|
||||||
let email = get_email_from_cert(&cert)?;
|
let email = get_email_from_cert(&cert)?;
|
||||||
|
is_email_allowed(&email)?;
|
||||||
let token = gen_random_token();
|
let token = gen_random_token();
|
||||||
store_pending_addition(pem.key.clone(), &email, &token)?;
|
store_pending_addition(pem.key.clone(), &email, &token)?;
|
||||||
send_confirmation_email(&email, &Action::Add, &token)?;
|
send_confirmation_email(&email, &Action::Add, &token)?;
|
||||||
|
|
|
@ -13,6 +13,7 @@ pub struct Settings {
|
||||||
pub root_folder: String,
|
pub root_folder: String,
|
||||||
pub max_age: i64,
|
pub max_age: i64,
|
||||||
pub cleanup_interval: u64,
|
pub cleanup_interval: u64,
|
||||||
|
pub allowed_domains: Vec<String>,
|
||||||
pub port: u16,
|
pub port: u16,
|
||||||
pub external_url: Url,
|
pub external_url: Url,
|
||||||
pub mail_settings: MailSettings,
|
pub mail_settings: MailSettings,
|
||||||
|
|
23
src/utils.rs
23
src/utils.rs
|
@ -4,7 +4,7 @@ use crate::settings::SETTINGS;
|
||||||
use flexi_logger::{style, DeferredNow, FileSpec, FlexiLoggerError, Logger, LoggerHandle, Record};
|
use flexi_logger::{style, DeferredNow, FileSpec, FlexiLoggerError, Logger, LoggerHandle, Record};
|
||||||
use rand::{distributions::Alphanumeric, thread_rng, Rng};
|
use rand::{distributions::Alphanumeric, thread_rng, Rng};
|
||||||
use sequoia_net::wkd::Url;
|
use sequoia_net::wkd::Url;
|
||||||
use sequoia_openpgp::{parse::Parse, Cert, policy::NullPolicy};
|
use sequoia_openpgp::{parse::Parse, policy::StandardPolicy, Cert};
|
||||||
use std::path::{Path, PathBuf};
|
use std::path::{Path, PathBuf};
|
||||||
|
|
||||||
#[macro_export]
|
#[macro_export]
|
||||||
|
@ -14,15 +14,26 @@ macro_rules! pending_path {
|
||||||
};
|
};
|
||||||
}
|
}
|
||||||
|
|
||||||
|
pub fn is_email_allowed(email: &str) -> Result<(), Error> {
|
||||||
|
let allowed = match email.split('@').last() {
|
||||||
|
Some(domain) => SETTINGS.allowed_domains.contains(&domain.to_string()),
|
||||||
|
None => return Err(Error::ParseEmail),
|
||||||
|
};
|
||||||
|
if !allowed {
|
||||||
|
return Err(Error::WrongDomain);
|
||||||
|
}
|
||||||
|
Ok(())
|
||||||
|
}
|
||||||
|
|
||||||
pub fn parse_pem(pemfile: &str) -> Result<Cert, Error> {
|
pub fn parse_pem(pemfile: &str) -> Result<Cert, Error> {
|
||||||
let cert = match sequoia_openpgp::Cert::from_bytes(pemfile.as_bytes()) {
|
let cert = match sequoia_openpgp::Cert::from_bytes(pemfile.as_bytes()) {
|
||||||
Ok(cert) => cert,
|
Ok(cert) => cert,
|
||||||
Err(_) => return Err(Error::ParseCert),
|
Err(_) => return Err(Error::ParseCert),
|
||||||
};
|
};
|
||||||
let policy = NullPolicy::new();
|
let policy = StandardPolicy::new();
|
||||||
if cert.with_policy(&policy, None).is_err() {
|
if cert.with_policy(&policy, None).is_err() {
|
||||||
return Err(Error::InvalidCert)
|
return Err(Error::InvalidCert);
|
||||||
}
|
};
|
||||||
Ok(cert)
|
Ok(cert)
|
||||||
}
|
}
|
||||||
|
|
||||||
|
@ -32,10 +43,10 @@ pub fn gen_random_token() -> String {
|
||||||
}
|
}
|
||||||
|
|
||||||
pub fn get_email_from_cert(cert: &Cert) -> Result<String, Error> {
|
pub fn get_email_from_cert(cert: &Cert) -> Result<String, Error> {
|
||||||
let policy = NullPolicy::new();
|
let policy = StandardPolicy::new();
|
||||||
let validcert = match cert.with_policy(&policy, None) {
|
let validcert = match cert.with_policy(&policy, None) {
|
||||||
Ok(validcert) => validcert,
|
Ok(validcert) => validcert,
|
||||||
Err(_) => return Err(Error::InvalidCert)
|
Err(_) => return Err(Error::InvalidCert),
|
||||||
};
|
};
|
||||||
let userid_opt = match validcert.primary_userid() {
|
let userid_opt = match validcert.primary_userid() {
|
||||||
Ok(userid_opt) => userid_opt,
|
Ok(userid_opt) => userid_opt,
|
||||||
|
|
Loading…
Reference in a new issue