about summary refs log tree commit diff
path: root/knowing/src/lib.rs
diff options
context:
space:
mode:
authorgennyble <gen@nyble.dev>2026-09-25 03:56:11 -0500
committergennyble <gen@nyble.dev>2026-09-25 03:56:11 -0500
commitba592de54cd3dce52eb2096dabbe748107f5db2b (patch)
tree4a23377e9788630e09c669e9ed18aecd27673ee7 /knowing/src/lib.rs
parentf4d8e8d03c1b80d5c59ee85631d5a78048892a32 (diff)
splorm auth
Diffstat (limited to 'knowing/src/lib.rs')
-rw-r--r--knowing/src/lib.rs88
1 files changed, 88 insertions, 0 deletions
diff --git a/knowing/src/lib.rs b/knowing/src/lib.rs
new file mode 100644
index 0000000..2a92f25
--- /dev/null
+++ b/knowing/src/lib.rs
@@ -0,0 +1,88 @@
+mod db;
+mod id;
+mod password;
+
+use std::fmt;
+
+use db::AuthDatabase;
+pub use id::RandomId;
+use password::{IntoHashedPassword, PasswordVerifier};
+use somethings::{
+	DatabaseError, DatabaseHandle,
+	auth::{AsUserId, Session, SessionId, User, UserId},
+};
+
+pub async fn create_table(db: &DatabaseHandle) -> Result<(), Error> {
+	db.auth_create_tables().await?;
+	Ok(())
+}
+
+pub async fn user_register(
+	db: &DatabaseHandle,
+	name: &str,
+	plaintext_password: String,
+) -> Result<User, Error> {
+	let id = UserId::rand();
+	let hash = plaintext_password.hash_password();
+	db.insert_user(&id, name, hash).await?;
+
+	Ok(User::new(id, name.to_owned()))
+}
+
+pub async fn user_login(
+	db: &DatabaseHandle,
+	name: &str,
+	plaintext_password: String,
+) -> Result<Session, Error> {
+	let userauth = db.get_userauth_by_name(name).await?;
+	userauth.hash().verify_password(plaintext_password)?;
+
+	let session_id = SessionId::rand();
+	db.insert_session(&session_id, userauth.user().userid())
+		.await?;
+
+	Ok(Session::new(session_id, userauth.into()))
+}
+
+pub async fn get_session(db: &DatabaseHandle, sid_str: &str) -> Result<Session, Error> {
+	let sid = sid_str.parse().map_err(|_| Error::InvalidSessionId)?;
+	db.get_session_by_id(&sid).await
+}
+
+pub async fn remove_session(db: &DatabaseHandle, sid_str: &str) -> Result<(), Error> {
+	let sid = sid_str.parse().map_err(|_| Error::InvalidSessionId)?;
+	db.delete_session_by_id(&sid).await
+}
+
+#[derive(Debug)]
+pub enum Error {
+	AuthenticationFailed,
+	InvalidSessionId,
+	UserIsAnonymous,
+	UserIsRegistered,
+
+	DatabaseError(DatabaseError),
+}
+impl std::error::Error for Error {}
+
+impl From<DatabaseError> for Error {
+	fn from(dbe: DatabaseError) -> Self {
+		Self::DatabaseError(dbe)
+	}
+}
+
+impl fmt::Display for Error {
+	fn fmt(&self, f: &mut fmt::Formatter<'_>) -> fmt::Result {
+		match self {
+			Self::AuthenticationFailed => write!(f, "failed to authenticate user"),
+			Self::InvalidSessionId => write!(f, "SessionId invalid"),
+			Self::UserIsAnonymous => {
+				write!(f, "expected a registered user, but UserId is anonymous")
+			}
+			Self::UserIsRegistered => {
+				write!(f, "expected an anonymous user, but UserId is registered")
+			}
+			Self::DatabaseError(dbe) => write!(f, "{dbe}"),
+		}
+	}
+}