diff --git a/app/src/create_user.rs b/app/src/create_user.rs
index 32ead31..783c07a 100644
--- a/app/src/create_user.rs
+++ b/app/src/create_user.rs
@@ -67,6 +67,8 @@ impl Component for CreateUserForm {
display_name: Some(get_element("displayname")),
first_name: Some(get_element("firstname")),
last_name: Some(get_element("lastname")),
+ ssh_pub_key: Some(get_element("ssh_pub_key")),
+ wireguard_pub_key: Some(get_element("wireguard_pub_key")),
password: get_element("password"),
};
self.create_user(req);
@@ -111,6 +113,14 @@ impl Component for CreateUserForm {
+
+
+
+
+
+
+
+
diff --git a/app/src/user_table.rs b/app/src/user_table.rs
index 91fc798..f158283 100644
--- a/app/src/user_table.rs
+++ b/app/src/user_table.rs
@@ -75,6 +75,8 @@ impl Component for UserTable {
{&u.display_name.as_ref().unwrap_or(&String::new())} |
{&u.first_name.as_ref().unwrap_or(&String::new())} |
{&u.last_name.as_ref().unwrap_or(&String::new())} |
+ {&u.ssh_pub_key.as_ref().unwrap_or(&String::new())} |
+ {&u.wireguard_pub_key.as_ref().unwrap_or(&String::new())} |
{&u.creation_date} |
}
@@ -88,6 +90,8 @@ impl Component for UserTable {
{"Display name"} |
{"First name"} |
{"Last name"} |
+ {"SSH Public Key"} |
+ {"Wireguard Public Key"} |
{"Creation date"} |
{table_content}
diff --git a/model/src/lib.rs b/model/src/lib.rs
index c158e8d..1d0315d 100644
--- a/model/src/lib.rs
+++ b/model/src/lib.rs
@@ -30,7 +30,10 @@ pub struct User {
pub first_name: Option,
pub last_name: Option,
// pub avatar: ?,
+ pub ssh_pub_key: Option,
+ pub wireguard_pub_key: Option,
pub creation_date: chrono::NaiveDateTime,
+
}
impl Default for User {
@@ -41,6 +44,8 @@ impl Default for User {
display_name: None,
first_name: None,
last_name: None,
+ ssh_pub_key: None,
+ wireguard_pub_key: None,
creation_date: chrono::NaiveDateTime::from_timestamp(0, 0),
}
}
@@ -54,6 +59,8 @@ pub struct CreateUserRequest {
pub display_name: Option,
pub first_name: Option,
pub last_name: Option,
+ pub ssh_pub_key: Option,
+ pub wireguard_pub_key: Option,
pub password: String,
}
diff --git a/src/domain/sql_backend_handler.rs b/src/domain/sql_backend_handler.rs
index 30022fd..a94cf4c 100644
--- a/src/domain/sql_backend_handler.rs
+++ b/src/domain/sql_backend_handler.rs
@@ -108,6 +108,8 @@ impl BackendHandler for SqlBackendHandler {
.column(Users::DisplayName)
.column(Users::FirstName)
.column(Users::LastName)
+ .column(Users::SshPubKey)
+ .column(Users::WireguardPubKey)
.column(Users::Avatar)
.column(Users::CreationDate)
.from(Users::Table)
@@ -226,6 +228,8 @@ impl BackendHandler for SqlBackendHandler {
Users::DisplayName,
Users::FirstName,
Users::LastName,
+ Users::SshPubKey,
+ Users::WireguardPubKey,
Users::CreationDate,
Users::PasswordHash,
])
@@ -235,6 +239,8 @@ impl BackendHandler for SqlBackendHandler {
request.display_name.map(Into::into).unwrap_or(Value::Null),
request.first_name.map(Into::into).unwrap_or(Value::Null),
request.last_name.map(Into::into).unwrap_or(Value::Null),
+ request.ssh_pub_key.map(Into::into).unwrap_or(Value::Null),
+ request.wireguard_pub_key.map(Into::into).unwrap_or(Value::Null),
chrono::Utc::now().naive_utc().into(),
password_hash.into(),
])
diff --git a/src/domain/sql_tables.rs b/src/domain/sql_tables.rs
index 0c69b98..c154c62 100644
--- a/src/domain/sql_tables.rs
+++ b/src/domain/sql_tables.rs
@@ -14,6 +14,8 @@ pub enum Users {
FirstName,
LastName,
Avatar,
+ SshPubKey,
+ WireguardPubKey,
CreationDate,
PasswordHash,
TotpSecret,
@@ -52,6 +54,8 @@ pub async fn init_table(pool: &Pool) -> sqlx::Result<()> {
.col(ColumnDef::new(Users::DisplayName).string_len(255))
.col(ColumnDef::new(Users::FirstName).string_len(255))
.col(ColumnDef::new(Users::LastName).string_len(255))
+ .col(ColumnDef::new(Users::SshPubKey).string_len(768))
+ .col(ColumnDef::new(Users::WireguardPubKey).string_len(255))
.col(ColumnDef::new(Users::Avatar).binary())
.col(ColumnDef::new(Users::CreationDate).date_time().not_null())
.col(
@@ -130,8 +134,8 @@ mod tests {
let sql_pool = PoolOptions::new().connect("sqlite::memory:").await.unwrap();
init_table(&sql_pool).await.unwrap();
sqlx::query(r#"INSERT INTO users
- (user_id, email, display_name, first_name, last_name, creation_date, password_hash)
- VALUES ("bôb", "böb@bob.bob", "Bob Bobbersön", "Bob", "Bobberson", "1970-01-01 00:00:00", "bob00")"#).execute(&sql_pool).await.unwrap();
+ (user_id, email, display_name, first_name, last_name, ssh_pub_key, wireguard_pub_key, creation_date, password_hash)
+ VALUES ("bôb", "böb@bob.bob", "Bob Bobbersön", "Bob", "Bobberson", "ssh-rsa AAAAB3NzaC1yc2EAAAADAQABAAABgQCpGRD9/jaGg/aM4jbbumjqnIUT+wtyaeb2Z27AZUlsAo+4GdDGkxC0LnLSuLqQleoMWcVG6RvJrTsa5NWQwNJmnX4rS7bJ+6qZibXHhfyA5Kr6JybWZr4/mrPPKgBaio6kPEqKkfEzhrygpeXcNvxp847gu+Hn7IbI6eBr0sLfy/bJPkpzhyhSSt/kA5drLJvxdA9aNPv3Jr0kJQtlceH4f7334LH9EE18xy8dEX/w0iefFSEC8rXoV7svqINOQKULIhi14ibAX9a4ks9TjKXqEDrJWQe0gf6qNEQ2wS8j5d47mdKnxPG0d592FHO86LlGiIpWkJt2WmoNmJHnwR1LrUsJK6T3tgjZyL+plcnS9OlBDD74dA1DQSpXaGkcLADNui9+cA/T1nacrzR9V8BN6HIBmvtqaI0CKz9lbScJVkNpkmxKraj/TgcWNpSWKDOuo8kdQKOeGcsxcK9PtpoCB/+dHe5gCf7/QHY1BIoyrsM/sOi0f2+f9zHDg1OIh6U= test@example", "e1ofBntxh2mj8kvdfODOL19xJyqVczDybDQuJ3sW30o=", "1970-01-01 00:00:00", "bob00")"#).execute(&sql_pool).await.unwrap();
let row =
sqlx::query(r#"SELECT display_name, creation_date FROM users WHERE user_id = "bôb""#)
.fetch_one(&sql_pool)
diff --git a/src/infra/ldap_handler.rs b/src/infra/ldap_handler.rs
index 2585178..936f27d 100644
--- a/src/infra/ldap_handler.rs
+++ b/src/infra/ldap_handler.rs
@@ -75,6 +75,8 @@ fn get_attribute(user: &User, attribute: &str) -> Result> {
.display_name
.clone()
.unwrap_or_else(|| user.user_id.clone())]),
+ "sshPubKey" => Ok(vec![user.ssh_pub_key.clone().unwrap_or("".to_string())]),
+ "wireguardPubKey" => Ok(vec![user.wireguard_pub_key.clone().unwrap_or("".to_string())]),
_ => bail!("Unsupported attribute: {}", attribute),
}
}
@@ -124,6 +126,10 @@ fn map_field(field: &str) -> Result {
"last_name".to_string()
} else if field == "avatar" {
"avatar".to_string()
+ } else if field == "sshPubKey" {
+ "ssh_pub_key".to_string()
+ } else if field == "wireguardPubKey" {
+ "wireguard_pub_key".to_string()
} else if field == "creationDate" {
"creation_date".to_string()
} else {
@@ -512,6 +518,8 @@ mod tests {
"givenName".to_string(),
"sn".to_string(),
"cn".to_string(),
+ "sshPubkey".to_string(),
+ "wireguardPubKey".to_string(),
],
};
assert_eq!(
@@ -548,6 +556,14 @@ mod tests {
atype: "cn".to_string(),
vals: vec!["Bôb Böbberson".to_string()]
}
+ LdapPartialAttribute {
+ atype: "sshPubKey".to_string(),
+ vals: vec!["ssh-rsa AAAAB3NzaC1yc2EAAAADAQABAAABgQCpGRD9/jaGg/aM4jbbumjqnIUT+wtyaeb2Z27AZUlsAo+4GdDGkxC0LnLSuLqQleoMWcVG6RvJrTsa5NWQwNJmnX4rS7bJ+6qZibXHhfyA5Kr6JybWZr4/mrPPKgBaio6kPEqKkfEzhrygpeXcNvxp847gu+Hn7IbI6eBr0sLfy/bJPkpzhyhSSt/kA5drLJvxdA9aNPv3Jr0kJQtlceH4f7334LH9EE18xy8dEX/w0iefFSEC8rXoV7svqINOQKULIhi14ibAX9a4ks9TjKXqEDrJWQe0gf6qNEQ2wS8j5d47mdKnxPG0d592FHO86LlGiIpWkJt2WmoNmJHnwR1LrUsJK6T3tgjZyL+plcnS9OlBDD74dA1DQSpXaGkcLADNui9+cA/T1nacrzR9V8BN6HIBmvtqaI0CKz9lbScJVkNpkmxKraj/TgcWNpSWKDOuo8kdQKOeGcsxcK9PtpoCB/+dHe5gCf7/QHY1BIoyrsM/sOi0f2+f9zHDg1OIh6U= test@example".to_string()]
+ }
+ LdapPartialAttribute {
+ atype: "wireguardPubKey".to_string(),
+ vals: vec!["e1ofBntxh2mj8kvdfODOL19xJyqVczDybDQuJ3sW30o=".to_string()]
+ }
],
}),
request.gen_result_entry(LdapSearchResultEntry {
@@ -581,6 +597,15 @@ mod tests {
atype: "cn".to_string(),
vals: vec!["Jimminy Cricket".to_string()]
}
+ LdapPartialAttribute {
+ atype: "sshPubKey".to_string(),
+ vals: vec!["ssh-rsa AAAAB3NzaC1yc2EAAAADAQABAAABgQCpGRD9/jaGg/aM4jbbumjqnIUT+wtyaeb2Z27AZUlsAo+4GdDGkxC0LnLSuLqQleoMWcVG6RvJrTsa5NWQwNJmnX4rS7bJ+6qZibXHhfyA5Kr6JybWZr4/mrPPKgBaio6kPEqKkfEzhrygpeXcNvxp847gu+Hn7IbI6eBr0sLfy/bJPkpzhyhSSt/kA5drLJvxdA9aNPv3Jr0kJQtlceH4f7334LH9EE18xy8dEX/w0iefFSEC8rXoV7svqINOQKULIhi14ibAX9a4ks9TjKXqEDrJWQe0gf6qNEQ2wS8j5d47mdKnxPG0d592FHO86LlGiIpWkJt2WmoNmJHnwR1LrUsJK6T3tgjZyL+plcnS9OlBDD74dA1DQSpXaGkcLADNui9+cA/T1nacrzR9V8BN6HIBmvtqaI0CKz9lbScJVkNpkmxKraj/TgcWNpSWKDOuo8kdQKOeGcsxcK9PtpoCB/+dHe5gCf7/QHY1BIoyrsM/sOi0f2+f9zHDg1OIh6U= test@example".to_string()]
+ }
+ LdapPartialAttribute {
+ atype: "wireguardPubKey".to_string(),
+ vals: vec!["e1ofBntxh2mj8kvdfODOL19xJyqVczDybDQuJ3sW30o=".to_string()]
+ }
+
],
}),
request.gen_success()