From 998db8626d668c412e6d1cbc2cbc633e4418e10d Mon Sep 17 00:00:00 2001 From: Jordan Doyle Date: Tue, 07 Sep 2021 16:19:49 +0100 Subject: [PATCH] Implement user permissions as bitflags --- Cargo.lock | 1 + chartered-db/Cargo.toml | 1 + chartered-db/src/users.rs | 49 +++++++++++++++++++++++++++++++++++++++++++++++-- 3 files changed, 48 insertions(+), 3 deletions(-) diff --git a/Cargo.lock b/Cargo.lock index c1ff201..e59057b 100644 --- a/Cargo.lock +++ a/Cargo.lock @@ -186,6 +186,7 @@ name = "chartered-db" version = "0.1.0" dependencies = [ + "bitflags", "chartered-fs", "diesel", "displaydoc", diff --git a/chartered-db/Cargo.toml b/chartered-db/Cargo.toml index f22b0af..d458b17 100644 --- a/chartered-db/Cargo.toml +++ a/chartered-db/Cargo.toml @@ -8,6 +8,7 @@ [dependencies] chartered-fs = { path = "../chartered-fs" } +bitflags = "1" diesel = { version = "1", features = ["sqlite", "r2d2"] } displaydoc = "0.2" itertools = "0.10" diff --git a/chartered-db/src/users.rs b/chartered-db/src/users.rs index 34dec2e..5be434e 100644 --- a/chartered-db/src/users.rs +++ a/chartered-db/src/users.rs @@ -1,8 +1,9 @@ use super::{ schema::{user_api_keys, user_crate_permissions, user_ssh_keys, users}, ConnectionPool, Result, }; use diesel::{prelude::*, Associations, Identifiable, Queryable}; +use std::sync::Arc; #[derive(Identifiable, Queryable, Associations, PartialEq, Eq, Hash, Debug)] pub struct User { @@ -36,8 +37,6 @@ ) -> Result> { use crate::schema::user_ssh_keys::dsl::ssh_key; - eprintln!("looking up by ssh key: {:x?}", given_ssh_key); - tokio::task::spawn_blocking(move || { let conn = conn.get()?; @@ -47,6 +46,26 @@ .select((users::dsl::id, users::dsl::username)) .get_result(&conn) .optional()?) + }) + .await? + } + + pub async fn accessible_crates( + self: Arc, + conn: ConnectionPool, + ) -> Result> { + use crate::schema::crates; + + tokio::task::spawn_blocking(move || { + let conn = conn.get()?; + + Ok(UserCratePermission::belonging_to(&*self) + .inner_join(crate::schema::crates::table) + .select(( + user_crate_permissions::permissions, + (crates::dsl::id, crates::dsl::name), + )) + .load(&conn)?) }) .await? } @@ -58,6 +77,30 @@ pub id: i32, pub user_id: i32, pub api_key: String, +} + +bitflags::bitflags! { + #[derive(FromSqlRow, AsExpression)] + pub struct UserCratePermissionValue: i32 { + const VISIBLE = 0b0000_0000_0000_0000_0000_0000_0000_0001; + const PUBLISH_VERSION = 0b0000_0000_0000_0000_0000_0000_0000_0010; + const YANK_VERSION = 0b0000_0000_0000_0000_0000_0000_0000_0100; + const MANAGE_USERS = 0b0000_0000_0000_0000_0000_0000_0000_1000; + } +} + +impl diesel::deserialize::FromSql + for UserCratePermissionValue +where + i32: diesel::deserialize::FromSql, +{ + fn from_sql( + bytes: Option<&B::RawValue>, + ) -> std::result::Result> + { + let val = i32::from_sql(bytes)?; + Ok(UserCratePermissionValue::from_bits_truncate(val)) + } } #[derive(Identifiable, Queryable, Associations, PartialEq, Eq, Hash, Debug)] @@ -66,7 +109,7 @@ pub id: i32, pub user_id: i32, pub crate_id: i32, - pub permissions: i32, + pub permissions: UserCratePermissionValue, } #[derive(Identifiable, Queryable, Associations, PartialEq, Eq, Hash, Debug)] -- rgit 0.1.3