Commit 804f6289 authored by MrMan's avatar MrMan

Changes after testing

parent a336f581
......@@ -6,6 +6,11 @@ COPY . .
# Install rsyslog configuration for postfix
COPY infra/docker/syslog/postfix-syslog.conf /etc/rsyslog.d/postfix.conf
# Add groups & users for use by postfix and/or dovecot
RUN groupadd -g 3000 submission
RUN groupadd -g 5000 vmail
RUN useradd -m -d /var/vmail -s /bin/false -u 5000 -g vmail vmail
# Set up entrypoint
COPY infra/docker/entrypoint.sh /bin/entrypoint.sh
RUN chmod =x /bin/entrypoint.sh
......
......@@ -5,11 +5,8 @@ COPY . .
# Install postfix
RUN apt-get update && DEBIAN_FRONTEND=noninteractive apt-get -y install pkg-config libssl-dev ca-certificates make \
rsyslog telnet postfix \
rsyslog telnet sqlite postfix \
dovecot-imapd dovecot-pop3d dovecot-sqlite dovecot-pgsql
RUN ln -s /usr/sbin/postfix /usr/bin/postfix
# Add submission group for postfix to use
RUN groupadd -g 3000 submission
RUN cargo install
......@@ -280,7 +280,7 @@ impl SupportsVMailboxLookup for SQLiteDB {
// FIXME: mailbox_users table name is hardcoded here
const DEFAULT_USERDB_QUERY: &'static str = "SELECT home, uid, gid \
FROM users \
FROM mailbox_users \
WHERE username = '%n' AND domain = '%d'
";
......@@ -290,8 +290,8 @@ FROM mailbox_users \
WHERE username = '%n' AND domain = '%d'
";
// FIXME: users table is hardcoded here
const DEFAULT_ITERATE_QUERY: &'static str = "SELECT username, domain FROM users";
// FIXME: mailbox_users table is hardcoded here
const DEFAULT_ITERATE_QUERY: &'static str = "SELECT username, domain FROM mailbox_users";
impl SupportsDovecotAuth for SQLiteDB {
fn dovecot_userdb_settings(&self) -> Result<DovecotDBSettings, Error> {
......
......@@ -6,7 +6,7 @@ use rusqlite::Row;
use rusqlite::types::ToSql;
use super::super::*;
const COLUMNS: &'static [&'static str] = &["uuid", "username", "domain", "password", "quota_gb"];
const COLUMNS: &'static [&'static str] = &["uuid", "username", "domain", "home", "password", "quota_gb"];
impl HasSQLTable<SQLiteDB> for ModelWithUUID<MailboxUser> {
fn sql_tbl_name() -> &'static str { "mailbox_users" }
......@@ -18,9 +18,10 @@ impl<'a, 'stmt> DBEntity<SQLiteDB, Row<'a, 'stmt>> for ModelWithUUID<MailboxUser
let uuid = row.get_checked("uuid")?;
let username = row.get_checked("username")?;
let domain = row.get_checked("domain")?;
let home = row.get_checked("home")?;
let password = row.get_checked("password")?;
let quota_gb = row.get_checked("quota_gb")?;
let model = MailboxUser { username, domain, password, quota_gb };
let model = MailboxUser { username, domain, password, home, quota_gb };
Ok(ModelWithUUID { uuid, model })
}
......@@ -32,6 +33,7 @@ impl<'a, 'stmt> DBEntity<SQLiteDB, Row<'a, 'stmt>> for ModelWithUUID<MailboxUser
&self.uuid as &ToSql,
&self.model.username,
&self.model.domain,
&self.model.home,
&self.model.password,
&self.model.quota_gb
])?;
......@@ -104,24 +106,40 @@ mod tests {
use models::user::MailboxUser;
use models::{DBEntity, ModelWithUUID, PaginationOptions};
const TEST_USER_EMAIL: &'static str = "/var/mail/test";
const TEST_USER_EMAIL: &'static str = "[email protected]";
const TEST_USER_DOMAIN: &'static str = "localhost";
const TEST_USER_PASSWORD: &'static str = "test";
const ADMIN_USER_HOME: &'static str = "/var/mail/admin";
const ADMIN_USER_EMAIL: &'static str = "[email protected]";
const ADMIN_USER_DOMAIN: &'static str = "localhost";
const ADMIN_USER_PASSWORD: &'static str = "admin";
fn make_test_user() -> MailboxUser {
MailboxUser::new(
String::from(TEST_USER_HOME),
String::from(TEST_USER_DOMAIN),
String::from(TEST_USER_EMAIL),
String::from(TEST_USER_PASSWORD)
)
}
fn make_admin_user() -> MailboxUser {
MailboxUser::new(
String::from(ADMIN_USER_DOMAIN),
String::from(ADMIN_USER_HOME),
String::from(ADMIN_USER_EMAIL),
String::from(ADMIN_USER_PASSWORD),
);
}
#[test]
fn models_user_insert() {
let mut db = SQLiteDB::new(SQLiteDBCfg::in_memory());
let _ = db.connect();
let model = MailboxUser::new(
String::from(TEST_USER_EMAIL),
String::from(TEST_USER_DOMAIN),
String::from(TEST_USER_PASSWORD)
);
let model = make_test_user();
let entity = ModelWithUUID::from_model(model);
let create_result = entity.insert(&db);
......@@ -133,11 +151,7 @@ mod tests {
let mut db = SQLiteDB::new(SQLiteDBCfg::in_memory());
let _ = db.connect();
let model = MailboxUser::new(
String::from(TEST_USER_EMAIL),
String::from(TEST_USER_DOMAIN),
String::from(TEST_USER_PASSWORD)
);
let model = make_test_user();
let entity = ModelWithUUID::from_model(model);
let create_result = entity.insert(&db);
......@@ -156,11 +170,7 @@ mod tests {
let mut db = SQLiteDB::new(SQLiteDBCfg::in_memory());
let _ = db.connect();
let model = MailboxUser::new(
String::from(TEST_USER_EMAIL),
String::from(TEST_USER_DOMAIN),
String::from(TEST_USER_PASSWORD)
);
let model = make_test_user();
let entity = ModelWithUUID::from_model(model);
// create the user
......@@ -182,11 +192,7 @@ mod tests {
let mut db = SQLiteDB::new(SQLiteDBCfg::in_memory());
let _ = db.connect();
let model = MailboxUser::new(
String::from(TEST_USER_EMAIL),
String::from(TEST_USER_DOMAIN),
String::from(TEST_USER_PASSWORD)
);
let model = make_test_user();
let entity = ModelWithUUID::from_model(model);
// create the user
......@@ -209,19 +215,11 @@ mod tests {
let mut db = SQLiteDB::new(SQLiteDBCfg::in_memory());
let _ = db.connect();
let test_model = MailboxUser::new(
String::from(TEST_USER_EMAIL),
String::from(TEST_USER_DOMAIN),
String::from(TEST_USER_PASSWORD)
);
let test_model = make_test_user();
let test_entity = ModelWithUUID::from_model(test_model);
let admin_model = MailboxUser::new(
String::from(ADMIN_USER_EMAIL),
String::from(ADMIN_USER_DOMAIN),
String::from(ADMIN_USER_PASSWORD),
);
let admin_model = make_admin_user();
let admin_entity = ModelWithUUID::from_model(admin_model);
// create the user
......@@ -246,11 +244,7 @@ mod tests {
let _ = db.connect();
// create the user
let model = MailboxUser::new(
String::from(TEST_USER_EMAIL),
String::from(TEST_USER_DOMAIN),
String::from(TEST_USER_PASSWORD)
);
let model = make_test_user();
let entity = ModelWithUUID::from_model(model);
let _ = entity.insert(&db).expect("test entity create failed");
......
......@@ -14,6 +14,7 @@ CREATE TABLE mailbox_users (
uuid TEXT PRIMARY KEY,
username TEXT NOT NULL,
domain TEXT NOT NULL,
home TEXT NOT NULL,
password TEXT NOT NULL,
quota_gb INTEGER DEFAULT 0,
......
......@@ -19,6 +19,9 @@ const DOVECOT_CONF_FILENAME: &'static str = "dovecot.conf";
const DOVECOT_USERDB_CONF_FILENAME: &'static str = "dovecot-sql-userdb.conf.ext";
const DOVECOT_PASSDB_CONF_FILENAME: &'static str = "dovecot-sql-passdb.conf.ext";
const DEFAULT_SHARED_UID_USER: &'static str = "vmail";
const DEFAULT_SHARED_GID_USER: &'static str = "vmail";
#[derive(Clone, Debug, Deserialize, Serialize)]
pub enum DovecotCmd {
Lifecycle(ComponentCmd),
......@@ -189,6 +192,9 @@ struct DovecotConfTemplate<'a> {
mail_location: &'a String,
unix_socket_path: &'a String,
shared_uid_user: &'a String,
shared_gid_user: &'a String,
userdb: &'a Option<DovecotDBSettings>,
userdb_conf_abs_path: String,
......@@ -227,8 +233,8 @@ impl FileConfigurable<DovecotCfg> for Dovecot {
// Generate *possible* file path for userdb/passdb configuration
let userdb_conf_path = output_dir.join(DOVECOT_USERDB_CONF_FILENAME);
let passdb_conf_path = output_dir.join(DOVECOT_PASSDB_CONF_FILENAME);
let userdb_conf_abs_path = make_absolute_path(userdb_conf_path.to_path_buf())?;
let passdb_conf_path = output_dir.join(DOVECOT_PASSDB_CONF_FILENAME);
let passdb_conf_abs_path = make_absolute_path(passdb_conf_path.to_path_buf())?;
// Build dovecot conf template
......@@ -239,6 +245,9 @@ impl FileConfigurable<DovecotCfg> for Dovecot {
mail_location: &self.cfg.mail_location,
unix_socket_path: &self.cfg.unix_socket_path,
shared_uid_user: &self.cfg.shared_uid_user.clone().unwrap_or(DEFAULT_SHARED_UID_USER.to_string()),
shared_gid_user: &self.cfg.shared_gid_user.clone().unwrap_or(DEFAULT_SHARED_GID_USER.to_string()),
userdb: &self.cfg.userdb_settings,
userdb_conf_abs_path: userdb_conf_abs_path,
......@@ -315,9 +324,14 @@ impl FileConfigurable<DovecotCfg> for Dovecot {
// Copy dovecot userdb conf
let userdb_conf_from = config_dir_path.clone().join(DOVECOT_USERDB_CONF_FILENAME);
let userdb_conf_to = config_output_dir_path.clone().join(DOVECOT_PASSDB_CONF_FILENAME);
let userdb_conf_to = config_output_dir_path.clone().join(DOVECOT_USERDB_CONF_FILENAME);
if userdb_conf_from != userdb_conf_to {
debug!("copying dovecot-sql.conf.ext from [{:?}] to [{:?}]", userdb_conf_from, userdb_conf_to);
debug!(
"copying {} from [{:?}] to [{:?}]",
DOVECOT_USERDB_CONF_FILENAME,
userdb_conf_from,
userdb_conf_to,
);
copy(&userdb_conf_from, &userdb_conf_to)?;
}
......@@ -325,7 +339,12 @@ impl FileConfigurable<DovecotCfg> for Dovecot {
let passdb_conf_from = config_dir_path.clone().join(DOVECOT_PASSDB_CONF_FILENAME);
let passdb_conf_to = config_output_dir_path.clone().join(DOVECOT_PASSDB_CONF_FILENAME);
if passdb_conf_from != passdb_conf_to {
debug!("copying dovecot-sql.conf.ext from [{:?}] to [{:?}]", passdb_conf_from, passdb_conf_to);
debug!(
"copying {} from [{:?}] to [{:?}]",
DOVECOT_PASSDB_CONF_FILENAME,
passdb_conf_from,
passdb_conf_to,
);
copy(&passdb_conf_from, &passdb_conf_to)?;
}
......
......@@ -55,6 +55,11 @@ impl Postfix {
db: db,
})
}
pub fn mail_directory(&self) -> String {
self.cfg.mail_spool_directory.clone()
}
}
impl Component for Postfix {
......
......@@ -233,6 +233,9 @@ pub struct DovecotCfg {
pub doveadm_bin_path: String,
pub config_output_dir: String,
pub shared_uid_user: Option<String>,
pub shared_gid_user: Option<String>,
pub unix_socket_path: String,
pub userdb_settings: Option<DovecotDBSettings>,
......
......@@ -127,11 +127,14 @@ fn main() {
let password = postfix_add_mailbox_user_m.value_of("password").expect("password missing");
let quota_gb = postfix_add_mailbox_user_m.value_of("mailbox_quota_gb").unwrap_or("0").parse().expect("invalid quota");
let new_user = MailboxUser{
username: String::from(username),
let home = format!("{}/{}", &postfix.mail_directory(), &username);
let new_user = MailboxUser {
domain: String::from(domain),
password: String::from(password),
quota_gb
username: String::from(username),
home,
quota_gb,
};
let _ = postfix.db.connect().expect("failed to connect to db");
......
......@@ -2,16 +2,18 @@
pub struct MailboxUser {
pub username: String,
pub domain: String,
pub home: String,
pub password: String,
pub quota_gb: i32
}
impl MailboxUser {
pub fn new(username: String, domain: String, password: String) -> MailboxUser {
pub fn new(domain: String, home: String, username: String, password: String) -> MailboxUser {
MailboxUser {
username,
domain,
password,
home,
quota_gb: 0
}
}
......
......@@ -148,7 +148,7 @@
driver = {{ settings.driver.clone().dovecot_setting_name() }}
connect = {{ settings.connect }}
pass_query = {{ settings.query }}
password_query = {{ settings.query }}
# For using doveadm -A:
iterate_query = {{ settings.iterate_query }}
\ No newline at end of file
......@@ -24,4 +24,9 @@ service auth {
}
}
auth_mechanisms = plain login
\ No newline at end of file
auth_mechanisms = plain login
mail_uid = {{ shared_uid_user }}
mail_gid = {{ shared_gid_user }}
mail_location = maildir:{{ mail_location }}
\ No newline at end of file
Markdown is supported
0% or
You are about to add 0 people to the discussion. Proceed with caution.
Finish editing this message first!
Please register or to comment