aboutsummaryrefslogtreecommitdiff
path: root/planetwars-server/src
diff options
context:
space:
mode:
authorIlion Beyst <ilion.beyst@gmail.com>2022-08-09 23:27:22 +0200
committerIlion Beyst <ilion.beyst@gmail.com>2022-08-09 23:27:22 +0200
commit406c7266019c0c36cfe5069bfe5cf293badd3a30 (patch)
tree1f5d054add282f45d9ff14de7a62160ff7ca31b2 /planetwars-server/src
parent58c1c5f9fb48040ad6b0891d586543c219de74d2 (diff)
downloadplanetwars.dev-406c7266019c0c36cfe5069bfe5cf293badd3a30.tar.xz
planetwars.dev-406c7266019c0c36cfe5069bfe5cf293badd3a30.zip
create password reset utility
Co-authored-by: Wout Schellaert <wout.schellaert@gmail.com>
Diffstat (limited to 'planetwars-server/src')
-rw-r--r--planetwars-server/src/cli.rs54
-rw-r--r--planetwars-server/src/db/users.rs28
-rw-r--r--planetwars-server/src/lib.rs9
3 files changed, 83 insertions, 8 deletions
diff --git a/planetwars-server/src/cli.rs b/planetwars-server/src/cli.rs
new file mode 100644
index 0000000..f33506e
--- /dev/null
+++ b/planetwars-server/src/cli.rs
@@ -0,0 +1,54 @@
+extern crate planetwars_server;
+extern crate tokio;
+
+use clap::Parser;
+use planetwars_server::db;
+use planetwars_server::{create_db_pool, get_config};
+
+#[derive(clap::Parser)]
+struct Args {
+ #[clap(subcommand)]
+ action: Action,
+}
+
+#[derive(clap::Subcommand)]
+enum Action {
+ SetPassword(SetPassword),
+}
+
+impl Action {
+ async fn run(self) {
+ match self {
+ Action::SetPassword(set_password) => set_password.run().await,
+ }
+ }
+}
+
+#[derive(clap::Parser)]
+struct SetPassword {
+ #[clap(value_parser)]
+ username: String,
+
+ #[clap(value_parser)]
+ new_password: String,
+}
+
+impl SetPassword {
+ async fn run(self) {
+ let global_config = get_config().unwrap();
+ let pool = create_db_pool(&global_config).await;
+
+ let conn = pool.get().await.expect("could not get database connection");
+ let credentials = db::users::Credentials {
+ username: &self.username,
+ password: &self.new_password,
+ };
+ db::users::set_user_password(credentials, &conn).expect("could not set password");
+ }
+}
+
+#[tokio::main]
+pub async fn main() {
+ let args = Args::parse();
+ args.action.run().await;
+}
diff --git a/planetwars-server/src/db/users.rs b/planetwars-server/src/db/users.rs
index ebb2268..9676dae 100644
--- a/planetwars-server/src/db/users.rs
+++ b/planetwars-server/src/db/users.rs
@@ -42,11 +42,17 @@ fn argon2_config() -> argon2::Config<'static> {
}
}
-pub fn create_user(credentials: &Credentials, conn: &PgConnection) -> QueryResult<User> {
+pub fn hash_password(password: &str) -> (Vec<u8>, [u8; 32]) {
let argon_config = argon2_config();
-
let salt: [u8; 32] = rand::thread_rng().gen();
- let hash = argon2::hash_raw(credentials.password.as_bytes(), &salt, &argon_config).unwrap();
+ let hash = argon2::hash_raw(password.as_bytes(), &salt, &argon_config).unwrap();
+
+ (hash, salt)
+}
+
+pub fn create_user(credentials: &Credentials, conn: &PgConnection) -> QueryResult<User> {
+ let (hash, salt) = hash_password(&credentials.password);
+
let new_user = NewUser {
username: credentials.username,
password_salt: &salt,
@@ -69,6 +75,22 @@ pub fn find_user_by_name(username: &str, db_conn: &PgConnection) -> QueryResult<
.first::<User>(db_conn)
}
+pub fn set_user_password(credentials: Credentials, db_conn: &PgConnection) -> QueryResult<()> {
+ let (hash, salt) = hash_password(&credentials.password);
+
+ let n_changes = diesel::update(users::table.filter(users::username.eq(&credentials.username)))
+ .set((
+ users::password_salt.eq(salt.as_slice()),
+ users::password_hash.eq(hash.as_slice()),
+ ))
+ .execute(db_conn)?;
+ if n_changes == 0 {
+ Err(diesel::result::Error::NotFound)
+ } else {
+ Ok(())
+ }
+}
+
pub fn authenticate_user(credentials: &Credentials, db_conn: &PgConnection) -> Option<User> {
find_user_by_name(credentials.username, db_conn)
.optional()
diff --git a/planetwars-server/src/lib.rs b/planetwars-server/src/lib.rs
index 804dcd5..4950815 100644
--- a/planetwars-server/src/lib.rs
+++ b/planetwars-server/src/lib.rs
@@ -94,11 +94,9 @@ pub async fn seed_simplebot(config: &GlobalConfig, pool: &ConnectionPool) {
pub type DbPool = Pool<DieselConnectionManager<PgConnection>>;
-pub async fn prepare_db(config: &GlobalConfig) -> DbPool {
+pub async fn create_db_pool(config: &GlobalConfig) -> DbPool {
let manager = DieselConnectionManager::<PgConnection>::new(&config.database_url);
- let pool = bb8::Pool::builder().build(manager).await.unwrap();
- seed_simplebot(config, &pool).await;
- pool
+ bb8::Pool::builder().build(manager).await.unwrap()
}
// create all directories required for further operation
@@ -165,7 +163,8 @@ async fn run_registry(config: Arc<GlobalConfig>, db_pool: DbPool) {
pub async fn run_app() {
let global_config = Arc::new(get_config().unwrap());
- let db_pool = prepare_db(&global_config).await;
+ let db_pool = create_db_pool(&global_config).await;
+ seed_simplebot(&global_config, &db_pool).await;
init_directories(&global_config).unwrap();
if global_config.ranker_enabled {