lehen commita

This commit is contained in:
aitzol 2024-01-05 18:50:06 +01:00
parent 304fb740d8
commit 56f6e46c71
6 changed files with 79 additions and 7 deletions

View File

@ -36,6 +36,8 @@ once_cell = "1.12.0"
lettre = "0.9.6" lettre = "0.9.6"
native-tls = "0.2.10" native-tls = "0.2.10"
activitystreams = "=0.7.0-alpha.20" activitystreams = "=0.7.0-alpha.20"
ahash = "=0.8.6"
heck = "0.4.1"
[dependencies.chrono] [dependencies.chrono]
features = ["serde"] features = ["serde"]

View File

@ -1,3 +1,4 @@
use heck::ToUpperCamelCase;
use crate::{ use crate::{
instance::*, medias::Media, posts::Post, safe_string::SafeString, schema::blogs, users::User, instance::*, medias::Media, posts::Post, safe_string::SafeString, schema::blogs, users::User,
Connection, Error, PlumeRocket, Result, CONFIG, ITEMS_PER_PAGE, Connection, Error, PlumeRocket, Result, CONFIG, ITEMS_PER_PAGE,
@ -102,9 +103,18 @@ impl Blog {
find_by!(blogs, find_by_ap_url, ap_url as &str); find_by!(blogs, find_by_ap_url, ap_url as &str);
find_by!(blogs, find_by_name, actor_id as &str, instance_id as i32); find_by!(blogs, find_by_name, actor_id as &str, instance_id as i32);
/// Remove non alphanumeric characters and CamelCase a string
pub fn slug(title: &str) -> String {
title.to_upper_camel_case()
.chars()
.filter(|c| c.is_alphanumeric())
.collect()
}
/*
pub fn slug(title: &str) -> &str { pub fn slug(title: &str) -> &str {
title title
} }
*/
pub fn get_instance(&self, conn: &Connection) -> Result<Instance> { pub fn get_instance(&self, conn: &Connection) -> Result<Instance> {
Instance::get(conn, self.instance_id) Instance::get(conn, self.instance_id)

View File

@ -293,6 +293,7 @@ pub struct LdapConfig {
pub tls: bool, pub tls: bool,
pub user_name_attr: String, pub user_name_attr: String,
pub mail_attr: String, pub mail_attr: String,
pub user: Option<(String, String)>,
} }
fn get_ldap_config() -> Option<LdapConfig> { fn get_ldap_config() -> Option<LdapConfig> {
@ -304,16 +305,26 @@ fn get_ldap_config() -> Option<LdapConfig> {
let tls = string_to_bool(&tls, "LDAP_TLS"); let tls = string_to_bool(&tls, "LDAP_TLS");
let user_name_attr = var("LDAP_USER_NAME_ATTR").unwrap_or_else(|_| "cn".to_owned()); let user_name_attr = var("LDAP_USER_NAME_ATTR").unwrap_or_else(|_| "cn".to_owned());
let mail_attr = var("LDAP_USER_MAIL_ATTR").unwrap_or_else(|_| "mail".to_owned()); let mail_attr = var("LDAP_USER_MAIL_ATTR").unwrap_or_else(|_| "mail".to_owned());
//2023-12-30
let user = var("LDAP_USER").ok();
let password = var("LDAP_PASSWORD").ok();
let user = match (user, password) {
(Some(user), Some(password)) => Some((user, password)),
(None, None) => None,
_ => panic!("Invalid LDAP configuration both or neither of LDAP_USER and LDAP_PASSWORD must be set")
};
//
Some(LdapConfig { Some(LdapConfig {
addr, addr,
base_dn, base_dn,
tls, tls,
user_name_attr, user_name_attr,
mail_attr, mail_attr,
user,
}) })
} }
(None, None) => None, (None, None) => None,
(_, _) => { _ => {
panic!("Invalid LDAP configuration : both LDAP_ADDR and LDAP_BASE_DN must be set") panic!("Invalid LDAP configuration : both LDAP_ADDR and LDAP_BASE_DN must be set")
} }
} }

View File

@ -342,6 +342,42 @@ impl User {
bcrypt::hash(pass, 10).map_err(Error::from) bcrypt::hash(pass, 10).map_err(Error::from)
} }
// [[ LDAP non anonymous bind copied from ....
fn ldap_preconn(ldap_conn: &mut LdapConn) -> Result<()> {
let ldap = CONFIG.ldap.as_ref().unwrap();
if let Some((user, password)) = ldap.user.as_ref() {
let bind = ldap_conn
.simple_bind(user, password)
.map_err(|_| Error::NotFound)?;
if bind.success().is_err() {
return Err(Error::NotFound);
}
}
Ok(())
}
fn search_dn(ldap_conn: &mut LdapConn, fil: &str) -> Result<String> {
let mut cn: String = String::new();
let ldap = CONFIG.ldap.as_ref().unwrap();
let (rs, _res) = ldap_conn.search(
&ldap.base_dn,
Scope::Subtree,
fil,
vec!["cn"]
)
.map_err(|_| Error::NotFound)?
.success()
.map_err(|_| Error::NotFound)?;
for entry in rs {
println!("{:?}", SearchEntry::construct(entry.clone()).dn);
cn = SearchEntry::construct(entry).dn;
}
Ok(cn.to_owned())
}
fn ldap_register(conn: &Connection, name: &str, password: &str) -> Result<User> { fn ldap_register(conn: &Connection, name: &str, password: &str) -> Result<User> {
if CONFIG.ldap.is_none() { if CONFIG.ldap.is_none() {
return Err(Error::NotFound); return Err(Error::NotFound);
@ -349,7 +385,12 @@ impl User {
let ldap = CONFIG.ldap.as_ref().unwrap(); let ldap = CONFIG.ldap.as_ref().unwrap();
let mut ldap_conn = LdapConn::new(&ldap.addr).map_err(|_| Error::NotFound)?; let mut ldap_conn = LdapConn::new(&ldap.addr).map_err(|_| Error::NotFound)?;
let ldap_name = format!("{}={},{}", ldap.user_name_attr, name, ldap.base_dn);
User::ldap_preconn(&mut ldap_conn)?;
let _filter = format!("(&(objectClass=*)(uid={}))", name).to_owned();
let ldap_name = User::search_dn(&mut ldap_conn, &_filter).unwrap();
//let ldap_name = format!("{}={},{}", ldap.user_name_attr, name, ldap.base_dn);
let bind = ldap_conn let bind = ldap_conn
.simple_bind(&ldap_name, password) .simple_bind(&ldap_name, password)
.map_err(|_| Error::NotFound)?; .map_err(|_| Error::NotFound)?;
@ -395,10 +436,18 @@ impl User {
} else { } else {
return false; return false;
}; };
if User::ldap_preconn(&mut conn).is_err() {
return false;
}
//
let _filter = format!("(&(objectClass=*)(uid={}))", &self.username).to_owned();
let name = User::search_dn(&mut conn, &_filter).unwrap();
/*
let name = format!( let name = format!(
"{}={},{}", "{}={},{}",
ldap.user_name_attr, &self.username, ldap.base_dn ldap.user_name_attr, &self.username, ldap.base_dn
); );
*/
if let Ok(bind) = conn.simple_bind(&name, password) { if let Ok(bind) = conn.simple_bind(&name, password) {
bind.success().is_ok() bind.success().is_ok()
} else { } else {
@ -445,7 +494,7 @@ impl User {
} }
// if no user was found, and we were unable to auto-register from ldap // if no user was found, and we were unable to auto-register from ldap
// fake-verify a password, and return an error. // fake-verify a password, and return an error.
let other = User::get(conn, 1) let other = User::get(&*conn, 1)
.expect("No user is registered") .expect("No user is registered")
.hashed_password; .hashed_password;
other.map(|pass| bcrypt::verify(password, &pass)); other.map(|pass| bcrypt::verify(password, &pass));
@ -453,7 +502,7 @@ impl User {
} }
} }
} }
// ... ldap-non-anon PR https://git.joinplu.me/Plume/Plume/src/branch/ldap-non-anon ]].
pub fn reset_password(&self, conn: &Connection, pass: &str) -> Result<()> { pub fn reset_password(&self, conn: &Connection, pass: &str) -> Result<()> {
diesel::update(self) diesel::update(self)
.set(users::hashed_password.eq(User::hash_pass(pass)?)) .set(users::hashed_password.eq(User::hash_pass(pass)?))

View File

@ -1 +1 @@
nightly-2022-07-19 nightly-2023-04-14

View File

@ -101,7 +101,7 @@ pub fn create(
Ok(_) => ValidationErrors::new(), Ok(_) => ValidationErrors::new(),
Err(e) => e, Err(e) => e,
}; };
if Blog::find_by_fqn(&conn, slug).is_ok() { if Blog::find_by_fqn(&conn, &slug).is_ok() {
errors.add( errors.add(
"title", "title",
ValidationError { ValidationError {
@ -122,7 +122,7 @@ pub fn create(
let blog = Blog::insert( let blog = Blog::insert(
&conn, &conn,
NewBlog::new_local( NewBlog::new_local(
slug.into(), slug.clone().into(),
form.title.to_string(), form.title.to_string(),
String::from(""), String::from(""),
Instance::get_local() Instance::get_local()