use lmrc_postgres::{PostgresConfig, PostgresManager, Privilege};
#[tokio::main]
async fn main() -> Result<(), Box<dyn std::error::Error>> {
tracing_subscriber::fmt::init();
println!("\n=== PostgreSQL User & Database Management Example ===\n");
let config = PostgresConfig::builder()
.version("15")
.database_name("postgres") .username("postgres")
.password("postgres")
.build()?;
let manager = PostgresManager::builder()
.config(config)
.server_ip("192.168.1.100")
.ssh_user("root")
.build()?;
println!("1. Listing existing users and databases\n");
println!("Current users:");
let users = manager.list_users().await?;
for user in &users {
println!(
" - {} (superuser: {}, can_create_db: {}, can_create_role: {}, connection_limit: {})",
user.name,
user.is_superuser,
user.can_create_db,
user.can_create_role,
user.connection_limit
);
}
println!("\nCurrent databases:");
let databases = manager.list_databases().await?;
for db in &databases {
let size_str = db.size.as_deref().unwrap_or("unknown");
println!(
" - {} (owner: {}, encoding: {}, size: {})",
db.name, db.owner, db.encoding, size_str
);
}
println!("\n2. Creating application database with custom settings\n");
let app_db = "myapp_db";
if !manager.database_exists(app_db).await? {
manager
.create_database_with_options(app_db, Some("postgres"), Some("UTF8"), Some("template0"))
.await?;
println!("✓ Created database: {}", app_db);
} else {
println!("✓ Database already exists: {}", app_db);
}
println!("\n3. Creating users with different permission levels\n");
let admin_user = "app_admin";
if !manager.user_exists(admin_user).await? {
manager
.create_user_with_options(
admin_user,
"admin_secure_password",
false, true, true, Some(10), )
.await?;
println!("✓ Created admin user: {}", admin_user);
} else {
println!("✓ User already exists: {}", admin_user);
}
let app_user = "app_user";
if !manager.user_exists(app_user).await? {
manager
.create_user_with_options(
app_user,
"app_secure_password",
false, false, false, Some(50), )
.await?;
println!("✓ Created application user: {}", app_user);
} else {
println!("✓ User already exists: {}", app_user);
}
let readonly_user = "app_readonly";
if !manager.user_exists(readonly_user).await? {
manager
.create_user_with_options(
readonly_user,
"readonly_password",
false,
false,
false,
Some(20),
)
.await?;
println!("✓ Created read-only user: {}", readonly_user);
} else {
println!("✓ User already exists: {}", readonly_user);
}
println!("\n4. Granting privileges to users\n");
manager
.grant_privileges(app_db, admin_user, &[Privilege::All])
.await?;
println!("✓ Granted ALL privileges on {} to {}", app_db, admin_user);
manager
.grant_privileges(
app_db,
app_user,
&[
Privilege::Select,
Privilege::Insert,
Privilege::Update,
Privilege::Delete,
],
)
.await?;
println!(
"✓ Granted SELECT, INSERT, UPDATE, DELETE on {} to {}",
app_db, app_user
);
manager
.grant_privileges(app_db, readonly_user, &[Privilege::Select])
.await?;
println!("✓ Granted SELECT only on {} to {}", app_db, readonly_user);
println!("\n5. Setting up role-based access control\n");
let analytics_role = "analytics";
manager.create_role(analytics_role, false, false).await?;
println!("✓ Created role: {}", analytics_role);
manager
.grant_privileges(app_db, analytics_role, &[Privilege::Select])
.await?;
println!("✓ Granted SELECT to role: {}", analytics_role);
manager.grant_role(analytics_role, readonly_user).await?;
println!(
"✓ Granted role '{}' to user '{}'",
analytics_role, readonly_user
);
println!("\n6. Updating user passwords\n");
manager
.update_user_password(app_user, "new_secure_password_2024")
.await?;
println!("✓ Updated password for user: {}", app_user);
println!("\n7. Verifying the setup\n");
println!("Final user list:");
let users = manager.list_users().await?;
for user in &users {
if user.name.starts_with("app_") || user.name == "analytics" {
println!(" - {} (superuser: {})", user.name, user.is_superuser);
}
}
println!("\nFinal database list:");
let databases = manager.list_databases().await?;
for db in &databases {
if db.name == app_db {
println!(" - {} (owner: {})", db.name, db.owner);
}
}
println!("\n8. Demonstrating privilege revocation\n");
manager
.revoke_privileges(app_db, app_user, &[Privilege::Delete])
.await?;
println!("✓ Revoked DELETE privilege from {} on {}", app_user, app_db);
println!("\n9. Cleanup example (commented out for safety)\n");
println!("To clean up, you would run:");
println!(
" manager.revoke_role(\"{}\", \"{}\").await?;",
analytics_role, readonly_user
);
println!(" manager.drop_user(\"{}\").await?;", readonly_user);
println!(" manager.drop_user(\"{}\").await?;", app_user);
println!(" manager.drop_user(\"{}\").await?;", admin_user);
println!(" manager.drop_database(\"{}\").await?;", app_db);
println!("\n=== Summary ===\n");
println!("This example demonstrated:");
println!(" ✓ Listing users and databases");
println!(" ✓ Creating databases with custom options (encoding, template, owner)");
println!(" ✓ Creating users with specific capabilities and connection limits");
println!(" ✓ Granting granular privileges (SELECT, INSERT, UPDATE, DELETE, ALL)");
println!(" ✓ Role-based access control (create role, grant to users)");
println!(" ✓ Password updates");
println!(" ✓ Privilege revocation");
println!(" ✓ Cleanup procedures (drop users and databases)");
println!("\nAll user and database management operations completed successfully!");
Ok(())
}