Remove redis dependencies

Signed-off-by: trivernis <trivernis@protonmail.com>
pull/1/head
trivernis 4 years ago
parent 88d4c3966b
commit 9ad9379381
Signed by: Trivernis
GPG Key ID: DFFFCC2C7A02DB45

398
Cargo.lock generated

@ -33,92 +33,6 @@ version = "0.8.7"
source = "registry+https://github.com/rust-lang/crates.io-index"
checksum = "97be891acc47ca214468e09425d02cef3af2c94d0d82081cd02061f996802f14"
[[package]]
name = "async-channel"
version = "1.4.2"
source = "registry+https://github.com/rust-lang/crates.io-index"
checksum = "21279cfaa4f47df10b1816007e738ca3747ef2ee53ffc51cdbf57a8bb266fee3"
dependencies = [
"concurrent-queue",
"event-listener",
"futures-core",
]
[[package]]
name = "async-executor"
version = "0.1.2"
source = "registry+https://github.com/rust-lang/crates.io-index"
checksum = "90f47c78ea98277cb1f5e6f60ba4fc762f5eafe9f6511bc2f7dfd8b75c225650"
dependencies = [
"async-io",
"futures-lite",
"multitask",
"parking 1.0.6",
"scoped-tls",
"waker-fn",
]
[[package]]
name = "async-io"
version = "0.1.11"
source = "registry+https://github.com/rust-lang/crates.io-index"
checksum = "3ae22a338d28c75b53702b66f77979062cb29675db376d99e451af4fa79dedb3"
dependencies = [
"cfg-if",
"concurrent-queue",
"futures-lite",
"libc",
"once_cell",
"parking 2.0.0",
"polling",
"socket2",
"vec-arena",
"wepoll-sys-stjepang",
"winapi 0.3.9",
]
[[package]]
name = "async-mutex"
version = "1.3.0"
source = "registry+https://github.com/rust-lang/crates.io-index"
checksum = "66941c2577c4fa351e4ce5fdde8f86c69b88d623f3b955be1bc7362a23434632"
dependencies = [
"event-listener",
]
[[package]]
name = "async-std"
version = "1.6.3"
source = "registry+https://github.com/rust-lang/crates.io-index"
checksum = "46c8da367da62b8ff2313c406c9ac091c1b31d67a165becdd2de380d846260f7"
dependencies = [
"async-executor",
"async-io",
"async-mutex",
"async-task",
"blocking",
"crossbeam-utils",
"futures-channel",
"futures-core",
"futures-io",
"futures-lite",
"kv-log-macro",
"log 0.4.11",
"memchr",
"num_cpus",
"once_cell",
"pin-project-lite",
"pin-utils",
"slab",
"wasm-bindgen-futures",
]
[[package]]
name = "async-task"
version = "3.0.0"
source = "registry+https://github.com/rust-lang/crates.io-index"
checksum = "c17772156ef2829aadc587461c7753af20b7e8db1529bc66855add962a3b35d3"
[[package]]
name = "async-trait"
version = "0.1.40"
@ -130,12 +44,6 @@ dependencies = [
"syn",
]
[[package]]
name = "atomic-waker"
version = "1.0.0"
source = "registry+https://github.com/rust-lang/crates.io-index"
checksum = "065374052e7df7ee4047b1160cca5e1467a12351a40b3da123c870ba0b8eda2a"
[[package]]
name = "atty"
version = "0.2.14"
@ -222,19 +130,6 @@ dependencies = [
"generic-array",
]
[[package]]
name = "blocking"
version = "0.5.2"
source = "registry+https://github.com/rust-lang/crates.io-index"
checksum = "ea5800d29218fea137b0880387e5948694a23c93fcdde157006966693a865c7c"
dependencies = [
"async-channel",
"atomic-waker",
"futures-lite",
"once_cell",
"waker-fn",
]
[[package]]
name = "blowfish"
version = "0.6.0"
@ -282,12 +177,6 @@ version = "0.2.1"
source = "registry+https://github.com/rust-lang/crates.io-index"
checksum = "39092a32794787acd8525ee150305ff051b0aa6cc2abaf193924f5ab05425f39"
[[package]]
name = "bumpalo"
version = "3.4.0"
source = "registry+https://github.com/rust-lang/crates.io-index"
checksum = "2e8c087f005730276d1096a652e92a8bacee2e2472bcc9715a74d2bec38b5820"
[[package]]
name = "byteorder"
version = "1.3.4"
@ -300,12 +189,6 @@ version = "0.5.6"
source = "registry+https://github.com/rust-lang/crates.io-index"
checksum = "0e4cec68f03f32e44924783795810fa50a7035d8c8ebe78580ad7e6c703fba38"
[[package]]
name = "cache-padded"
version = "1.1.1"
source = "registry+https://github.com/rust-lang/crates.io-index"
checksum = "631ae5198c9be5e753e5cc215e1bd73c2b466a3565173db433f52bb9d3e66dba"
[[package]]
name = "cc"
version = "1.0.59"
@ -364,28 +247,6 @@ dependencies = [
"winapi 0.3.9",
]
[[package]]
name = "combine"
version = "4.3.2"
source = "registry+https://github.com/rust-lang/crates.io-index"
checksum = "2809f67365382d65fd2b6d9c22577231b954ed27400efeafbe687bda75abcc0b"
dependencies = [
"bytes",
"futures-util",
"memchr",
"pin-project-lite",
"tokio",
]
[[package]]
name = "concurrent-queue"
version = "1.2.2"
source = "registry+https://github.com/rust-lang/crates.io-index"
checksum = "30ed07550be01594c6026cff2a1d7fe9c8f683caa798e12b68694ac9e88286a3"
dependencies = [
"cache-padded",
]
[[package]]
name = "constant_time_eq"
version = "0.1.5"
@ -474,12 +335,6 @@ version = "0.15.0"
source = "registry+https://github.com/rust-lang/crates.io-index"
checksum = "77c90badedccf4105eca100756a0b1289e191f6fcbdadd3cee1d2f614f97da8f"
[[package]]
name = "dtoa"
version = "0.4.6"
source = "registry+https://github.com/rust-lang/crates.io-index"
checksum = "134951f4028bdadb9b84baf4232681efbf277da25144b9b0ad65df75946c422b"
[[package]]
name = "env_logger"
version = "0.7.1"
@ -493,24 +348,12 @@ dependencies = [
"termcolor",
]
[[package]]
name = "event-listener"
version = "2.4.0"
source = "registry+https://github.com/rust-lang/crates.io-index"
checksum = "e1cd41440ae7e4734bbd42302f63eaba892afc93a3912dad84006247f0dedb0e"
[[package]]
name = "fallible-iterator"
version = "0.2.0"
source = "registry+https://github.com/rust-lang/crates.io-index"
checksum = "4443176a9f2c162692bd3d352d745ef9413eec5782a80d8fd6f8a1ac692a07f7"
[[package]]
name = "fastrand"
version = "1.3.5"
source = "registry+https://github.com/rust-lang/crates.io-index"
checksum = "5c85295147490b8fcf2ea3d104080a105a8b2c63f9c319e82c02d8e952388919"
[[package]]
name = "filetime"
version = "0.2.12"
@ -539,7 +382,6 @@ dependencies = [
"msgrpc",
"postgres",
"rand 0.7.3",
"redis",
"rmp",
"rmp-serde",
"rouille",
@ -549,12 +391,6 @@ dependencies = [
"zeroize",
]
[[package]]
name = "fnv"
version = "1.0.7"
source = "registry+https://github.com/rust-lang/crates.io-index"
checksum = "3f9eec918d3f24069decb9af1554cad7c880e2da24a9afd88aca000531ab82c1"
[[package]]
name = "fuchsia-cprng"
version = "0.1.1"
@ -625,21 +461,6 @@ version = "0.3.5"
source = "registry+https://github.com/rust-lang/crates.io-index"
checksum = "de27142b013a8e869c14957e6d2edeef89e97c289e69d042ee3a49acd8b51789"
[[package]]
name = "futures-lite"
version = "0.1.11"
source = "registry+https://github.com/rust-lang/crates.io-index"
checksum = "97999970129b808f0ccba93211201d431fcc12d7e1ffae03a61b5cedd1a7ced2"
dependencies = [
"fastrand",
"futures-core",
"futures-io",
"memchr",
"parking 2.0.0",
"pin-project-lite",
"waker-fn",
]
[[package]]
name = "futures-macro"
version = "0.3.5"
@ -762,17 +583,6 @@ dependencies = [
"unicode-normalization",
]
[[package]]
name = "idna"
version = "0.2.0"
source = "registry+https://github.com/rust-lang/crates.io-index"
checksum = "02e2673c30ee86b5b96a9cb52ad15718aa1f966f5ab9ad54a8b95d5ca33120a9"
dependencies = [
"matches",
"unicode-bidi",
"unicode-normalization",
]
[[package]]
name = "instant"
version = "0.1.6"
@ -794,15 +604,6 @@ version = "0.4.6"
source = "registry+https://github.com/rust-lang/crates.io-index"
checksum = "dc6f3ad7b9d11a0c00842ff8de1b60ee58661048eb8049ed33c73594f359d7e6"
[[package]]
name = "js-sys"
version = "0.3.45"
source = "registry+https://github.com/rust-lang/crates.io-index"
checksum = "ca059e81d9486668f12d455a4ea6daa600bd408134cd17e3d3fb5a32d1f016f8"
dependencies = [
"wasm-bindgen",
]
[[package]]
name = "kernel32-sys"
version = "0.2.2"
@ -813,15 +614,6 @@ dependencies = [
"winapi-build",
]
[[package]]
name = "kv-log-macro"
version = "1.0.7"
source = "registry+https://github.com/rust-lang/crates.io-index"
checksum = "0de8b303297635ad57c9f5059fd9cee7a47f8e8daa09df0fcd07dd39fb22977f"
dependencies = [
"log 0.4.11",
]
[[package]]
name = "lazy_static"
version = "1.4.0"
@ -979,17 +771,6 @@ dependencies = [
"twoway",
]
[[package]]
name = "multitask"
version = "0.2.0"
source = "registry+https://github.com/rust-lang/crates.io-index"
checksum = "c09c35271e7dcdb5f709779111f2c8e8ab8e06c1b587c1c6a9e179d865aaa5b4"
dependencies = [
"async-task",
"concurrent-queue",
"fastrand",
]
[[package]]
name = "net2"
version = "0.2.35"
@ -1042,18 +823,6 @@ version = "0.3.0"
source = "registry+https://github.com/rust-lang/crates.io-index"
checksum = "624a8340c38c1b80fd549087862da4ba43e08858af025b236e509b6649fc13d5"
[[package]]
name = "parking"
version = "1.0.6"
source = "registry+https://github.com/rust-lang/crates.io-index"
checksum = "6cb300f271742d4a2a66c01b6b2fa0c83dfebd2e0bf11addb879a3547b4ed87c"
[[package]]
name = "parking"
version = "2.0.0"
source = "registry+https://github.com/rust-lang/crates.io-index"
checksum = "427c3892f9e783d91cc128285287e70a59e206ca452770ece88a76f7a3eddd72"
[[package]]
name = "parking_lot"
version = "0.11.0"
@ -1181,19 +950,6 @@ version = "0.1.0"
source = "registry+https://github.com/rust-lang/crates.io-index"
checksum = "8b870d8c151b6f2fb93e84a13146138f05d02ed11c7e7c54f8826aaaf7c9f184"
[[package]]
name = "polling"
version = "0.1.9"
source = "registry+https://github.com/rust-lang/crates.io-index"
checksum = "8fffa183f6bd5f1a8a3e1f60ce2f8d5621e350eed84a62d6daaa5b9d1aaf6fbd"
dependencies = [
"cfg-if",
"libc",
"log 0.4.11",
"wepoll-sys-stjepang",
"winapi 0.3.9",
]
[[package]]
name = "postgres"
version = "0.17.5"
@ -1461,27 +1217,6 @@ dependencies = [
"rand_core 0.3.1",
]
[[package]]
name = "redis"
version = "0.17.0"
source = "registry+https://github.com/rust-lang/crates.io-index"
checksum = "95357caf2640abc54651b93c98a8df4fe1ccbf44b8e601ccdf43d5c1451f29ac"
dependencies = [
"async-std",
"async-trait",
"bytes",
"combine",
"dtoa",
"futures-util",
"itoa",
"percent-encoding 2.1.0",
"pin-project-lite",
"sha1",
"tokio",
"tokio-util",
"url 2.1.1",
]
[[package]]
name = "redox_syscall"
version = "0.1.57"
@ -1569,7 +1304,7 @@ dependencies = [
"threadpool",
"time",
"tiny_http",
"url 1.7.2",
"url",
]
[[package]]
@ -1596,12 +1331,6 @@ version = "0.3.3"
source = "registry+https://github.com/rust-lang/crates.io-index"
checksum = "ef703b7cb59335eae2eb93ceb664c0eb7ea6bf567079d843e09420219668e072"
[[package]]
name = "scoped-tls"
version = "1.0.0"
source = "registry+https://github.com/rust-lang/crates.io-index"
checksum = "ea6a9290e3c9cf0f18145ef7ffa62d68ee0bf5fcd651017e586dc7fd5da448c2"
[[package]]
name = "scopeguard"
version = "1.1.0"
@ -1692,18 +1421,6 @@ version = "1.4.2"
source = "registry+https://github.com/rust-lang/crates.io-index"
checksum = "fbee7696b84bbf3d89a1c2eccff0850e3047ed46bfcd2e92c29a2d074d57e252"
[[package]]
name = "socket2"
version = "0.3.15"
source = "registry+https://github.com/rust-lang/crates.io-index"
checksum = "b1fa70dc5c8104ec096f4fe7ede7a221d35ae13dcd19ba1ad9a81d2cab9a1c44"
dependencies = [
"cfg-if",
"libc",
"redox_syscall",
"winapi 0.3.9",
]
[[package]]
name = "stringprep"
version = "0.1.2"
@ -1812,7 +1529,7 @@ dependencies = [
"chrono",
"chunked_transfer",
"log 0.4.11",
"url 1.7.2",
"url",
]
[[package]]
@ -1828,7 +1545,6 @@ source = "registry+https://github.com/rust-lang/crates.io-index"
checksum = "5d34ca54d84bf2b5b4d7d31e901a8464f7b60ac145a284fba25ceb801f2ddccd"
dependencies = [
"bytes",
"fnv",
"futures-core",
"iovec",
"lazy_static",
@ -1930,28 +1646,11 @@ version = "1.7.2"
source = "registry+https://github.com/rust-lang/crates.io-index"
checksum = "dd4e7c0d531266369519a4aa4f399d748bd37043b00bde1e4ff1f60a120b355a"
dependencies = [
"idna 0.1.5",
"idna",
"matches",
"percent-encoding 1.0.1",
]
[[package]]
name = "url"
version = "2.1.1"
source = "registry+https://github.com/rust-lang/crates.io-index"
checksum = "829d4a8476c35c9bf0bbce5a3b23f4106f79728039b726d292bb93bc106787cb"
dependencies = [
"idna 0.2.0",
"matches",
"percent-encoding 2.1.0",
]
[[package]]
name = "vec-arena"
version = "0.5.2"
source = "registry+https://github.com/rust-lang/crates.io-index"
checksum = "8cb18268690309760d59ee1a9b21132c126ba384f374c59a94db4bc03adeb561"
[[package]]
name = "version_check"
version = "0.1.5"
@ -1964,12 +1663,6 @@ version = "0.9.2"
source = "registry+https://github.com/rust-lang/crates.io-index"
checksum = "b5a972e5669d67ba988ce3dc826706fb0a8b01471c088cb0b6110b805cc36aed"
[[package]]
name = "waker-fn"
version = "1.1.0"
source = "registry+https://github.com/rust-lang/crates.io-index"
checksum = "9d5b2c62b4012a3e1eca5a7e077d13b3bf498c4073e33ccd58626607748ceeca"
[[package]]
name = "wasi"
version = "0.9.0+wasi-snapshot-preview1"
@ -1982,91 +1675,6 @@ version = "0.10.0+wasi-snapshot-preview1"
source = "registry+https://github.com/rust-lang/crates.io-index"
checksum = "1a143597ca7c7793eff794def352d41792a93c481eb1042423ff7ff72ba2c31f"
[[package]]
name = "wasm-bindgen"
version = "0.2.68"
source = "registry+https://github.com/rust-lang/crates.io-index"
checksum = "1ac64ead5ea5f05873d7c12b545865ca2b8d28adfc50a49b84770a3a97265d42"
dependencies = [
"cfg-if",
"wasm-bindgen-macro",
]
[[package]]
name = "wasm-bindgen-backend"
version = "0.2.68"
source = "registry+https://github.com/rust-lang/crates.io-index"
checksum = "f22b422e2a757c35a73774860af8e112bff612ce6cb604224e8e47641a9e4f68"
dependencies = [
"bumpalo",
"lazy_static",
"log 0.4.11",
"proc-macro2",
"quote",
"syn",
"wasm-bindgen-shared",
]
[[package]]
name = "wasm-bindgen-futures"
version = "0.4.18"
source = "registry+https://github.com/rust-lang/crates.io-index"
checksum = "b7866cab0aa01de1edf8b5d7936938a7e397ee50ce24119aef3e1eaa3b6171da"
dependencies = [
"cfg-if",
"js-sys",
"wasm-bindgen",
"web-sys",
]
[[package]]
name = "wasm-bindgen-macro"
version = "0.2.68"
source = "registry+https://github.com/rust-lang/crates.io-index"
checksum = "6b13312a745c08c469f0b292dd2fcd6411dba5f7160f593da6ef69b64e407038"
dependencies = [
"quote",
"wasm-bindgen-macro-support",
]
[[package]]
name = "wasm-bindgen-macro-support"
version = "0.2.68"
source = "registry+https://github.com/rust-lang/crates.io-index"
checksum = "f249f06ef7ee334cc3b8ff031bfc11ec99d00f34d86da7498396dc1e3b1498fe"
dependencies = [
"proc-macro2",
"quote",
"syn",
"wasm-bindgen-backend",
"wasm-bindgen-shared",
]
[[package]]
name = "wasm-bindgen-shared"
version = "0.2.68"
source = "registry+https://github.com/rust-lang/crates.io-index"
checksum = "1d649a3145108d7d3fbcde896a468d1bd636791823c9921135218ad89be08307"
[[package]]
name = "web-sys"
version = "0.3.45"
source = "registry+https://github.com/rust-lang/crates.io-index"
checksum = "4bf6ef87ad7ae8008e15a355ce696bed26012b7caa21605188cfd8214ab51e2d"
dependencies = [
"js-sys",
"wasm-bindgen",
]
[[package]]
name = "wepoll-sys-stjepang"
version = "1.0.6"
source = "registry+https://github.com/rust-lang/crates.io-index"
checksum = "6fd319e971980166b53e17b1026812ad66c6b54063be879eb182342b55284694"
dependencies = [
"cc",
]
[[package]]
name = "winapi"
version = "0.2.8"

@ -11,7 +11,6 @@ msgrpc = {path = "./msg-rpc"}
postgres = "0.17.5"
serde_postgres = "0.2.0"
dotenv = "0.15.0"
redis = "0.17.0"
serde = {version = "1.0.115", features = ["serde_derive"]}
rand = "0.7.3"
bcrypt = "0.8.2"

@ -3,18 +3,14 @@ use crate::database::role_permissions::RolePermissions;
use crate::database::roles::Roles;
use crate::database::user_roles::UserRoles;
use crate::database::users::Users;
use crate::utils::error::{
DBError, DatabaseClient, DatabaseResult, PostgresError, RedisClient, RedisConnection,
};
use crate::utils::error::{DBError, DatabaseClient, DatabaseResult, PostgresError};
use dotenv;
use postgres::{Client, NoTls};
use redis::RedisResult;
use std::sync::{Arc, Mutex};
pub mod database_error;
pub mod models;
pub mod permissions;
pub mod redis_operations;
pub mod role_permissions;
pub mod roles;
pub mod tokens;
@ -23,21 +19,15 @@ pub mod users;
const DB_CONNECTION_URL: &str = "POSTGRES_CONNECTION_URL";
const DEFAULT_CONNECTION: &str = "postgres://postgres:postgres@localhost/postgres";
const REDIS_CONNECTION_URL: &str = "REDIS_CONNECTION_URL";
const DEFAULT_REDIS_CONNECTION: &str = "redis:://127.0.0.1/";
pub trait Table {
fn new(
database_connection: Arc<Mutex<DatabaseClient>>,
redis_connection: Arc<Mutex<RedisConnection>>,
) -> Self;
fn new(database_connection: Arc<Mutex<DatabaseClient>>) -> Self;
fn init(&self) -> DatabaseResult<()>;
}
#[derive(Clone)]
pub struct Database {
database_connection: Arc<Mutex<Client>>,
redis_connection: Arc<Mutex<RedisConnection>>,
pub users: Users,
pub roles: Roles,
pub permissions: Permissions,
@ -50,32 +40,13 @@ impl Database {
let database_connection = Arc::new(Mutex::new(
get_database_connection().map_err(|e| DBError::Postgres(e))?,
));
let redis_connection = Arc::new(Mutex::new(
get_redis_connection().map_err(|e| DBError::Redis(e))?,
));
Ok(Self {
users: Users::new(
Arc::clone(&database_connection),
Arc::clone(&redis_connection),
),
roles: Roles::new(
Arc::clone(&database_connection),
Arc::clone(&redis_connection),
),
permissions: Permissions::new(
Arc::clone(&database_connection),
Arc::clone(&redis_connection),
),
user_roles: UserRoles::new(
Arc::clone(&database_connection),
Arc::clone(&redis_connection),
),
role_permission: RolePermissions::new(
Arc::clone(&database_connection),
Arc::clone(&redis_connection),
),
users: Users::new(Arc::clone(&database_connection)),
roles: Roles::new(Arc::clone(&database_connection)),
permissions: Permissions::new(Arc::clone(&database_connection)),
user_roles: UserRoles::new(Arc::clone(&database_connection)),
role_permission: RolePermissions::new(Arc::clone(&database_connection)),
database_connection,
redis_connection,
})
}
@ -95,10 +66,3 @@ fn get_database_connection() -> Result<DatabaseClient, PostgresError> {
let conn_url = dotenv::var(DB_CONNECTION_URL).unwrap_or(DEFAULT_CONNECTION.to_string());
Client::connect(conn_url.as_str(), NoTls)
}
fn get_redis_connection() -> RedisResult<RedisConnection> {
let conn_url =
dotenv::var(REDIS_CONNECTION_URL).unwrap_or(DEFAULT_REDIS_CONNECTION.to_string());
let client = RedisClient::open(conn_url)?;
client.get_connection()
}

@ -1,5 +1,5 @@
use crate::database::models::{CreatePermissionsEntry, Permission};
use crate::database::{DatabaseClient, DatabaseResult, RedisConnection, Table};
use crate::database::{DatabaseClient, DatabaseResult, Table};
use crate::utils::error::DBError;
use postgres::Client;
use std::sync::{Arc, Mutex};
@ -7,17 +7,12 @@ use std::sync::{Arc, Mutex};
#[derive(Clone)]
pub struct Permissions {
database_connection: Arc<Mutex<DatabaseClient>>,
redis_connection: Arc<Mutex<RedisConnection>>,
}
impl Table for Permissions {
fn new(
database_connection: Arc<Mutex<Client>>,
redis_connection: Arc<Mutex<RedisConnection>>,
) -> Self {
fn new(database_connection: Arc<Mutex<Client>>) -> Self {
Self {
database_connection,
redis_connection,
}
}

@ -1,5 +0,0 @@
pub const SET: &str = "SET";
pub const EXPIRE: &str = "EXPIRE";
pub const TTL: &str = "TTL";
pub const EX: &str = "EX";
pub const GET: &str = "GET";

@ -1,22 +1,17 @@
use crate::database::models::Permission;
use crate::database::{DatabaseClient, DatabaseResult, RedisConnection, Table};
use crate::database::{DatabaseClient, DatabaseResult, Table};
use crate::utils::error::DBError;
use std::sync::{Arc, Mutex};
#[derive(Clone)]
pub struct RolePermissions {
database_connection: Arc<Mutex<DatabaseClient>>,
redis_connection: Arc<Mutex<RedisConnection>>,
}
impl Table for RolePermissions {
fn new(
database_connection: Arc<Mutex<DatabaseClient>>,
redis_connection: Arc<Mutex<RedisConnection>>,
) -> Self {
fn new(database_connection: Arc<Mutex<DatabaseClient>>) -> Self {
Self {
database_connection,
redis_connection,
}
}

@ -1,6 +1,6 @@
use crate::database::models::Role;
use crate::database::role_permissions::RolePermissions;
use crate::database::{DatabaseResult, RedisConnection, Table};
use crate::database::{DatabaseResult, Table};
use crate::utils::error::DBError;
use postgres::Client;
use std::sync::{Arc, Mutex};
@ -8,22 +8,14 @@ use std::sync::{Arc, Mutex};
#[derive(Clone)]
pub struct Roles {
database_connection: Arc<Mutex<Client>>,
redis_connection: Arc<Mutex<RedisConnection>>,
role_permission: RolePermissions,
}
impl Table for Roles {
fn new(
database_connection: Arc<Mutex<Client>>,
redis_connection: Arc<Mutex<RedisConnection>>,
) -> Self {
fn new(database_connection: Arc<Mutex<Client>>) -> Self {
Self {
role_permission: RolePermissions::new(
Arc::clone(&database_connection),
Arc::clone(&redis_connection),
),
role_permission: RolePermissions::new(Arc::clone(&database_connection)),
database_connection,
redis_connection,
}
}

@ -1,13 +1,12 @@
use crate::database::redis_operations::{EX, GET, SET, TTL};
use crate::utils::error::RedisConnection;
use crate::utils::{create_user_token, get_user_id_from_token};
use byteorder::{BigEndian, ByteOrder};
use redis::{ErrorKind, RedisError, RedisResult};
use crate::utils::{create_user_token, get_user_id_from_token, TOKEN_LENGTH};
use serde::Serialize;
use std::cmp::{max, min};
use std::collections::HashMap;
use std::time::Instant;
use zeroize::Zeroize;
const REQUEST_TOKEN_EXPIRE_SECONDS: i32 = 60 * 10;
const REFRESH_TOKEN_EXPIRE_SECONDS: i32 = 60 * 60 * 24;
const REQUEST_TOKEN_EXPIRE_SECONDS: u32 = 60 * 10;
const REFRESH_TOKEN_EXPIRE_SECONDS: u32 = 60 * 60 * 24;
#[derive(Clone, Debug, Zeroize, Serialize)]
#[zeroize(drop)]
@ -23,8 +22,8 @@ impl SessionTokens {
Self {
request_token: base64::encode(create_user_token(user_id)),
refresh_token: base64::encode(create_user_token(user_id)),
request_ttl: REQUEST_TOKEN_EXPIRE_SECONDS,
refresh_ttl: REFRESH_TOKEN_EXPIRE_SECONDS,
request_ttl: REQUEST_TOKEN_EXPIRE_SECONDS as i32,
refresh_ttl: REFRESH_TOKEN_EXPIRE_SECONDS as i32,
}
}
@ -32,45 +31,19 @@ impl SessionTokens {
Self {
request_token,
refresh_token,
request_ttl: REQUEST_TOKEN_EXPIRE_SECONDS,
refresh_ttl: REFRESH_TOKEN_EXPIRE_SECONDS,
request_ttl: REQUEST_TOKEN_EXPIRE_SECONDS as i32,
refresh_ttl: REFRESH_TOKEN_EXPIRE_SECONDS as i32,
}
}
pub fn retrieve(user_id: i32, redis_connection: &mut RedisConnection) -> RedisResult<Self> {
let redis_request_key = format!("user-{}_request", user_id);
let request_token: String = redis::cmd(GET)
.arg(&redis_request_key)
.query(redis_connection)?;
let redis_refresh_key = format!("user-{}_refresh", user_id);
let refresh_token: String = redis::cmd(GET)
.arg(&redis_refresh_key)
.query(redis_connection)?;
if request_token.len() == 0 {
return Err(RedisError::from((
ErrorKind::ResponseError,
"No refresh token available",
)));
}
if refresh_token.len() == 0 {
return Err(RedisError::from((
ErrorKind::ResponseError,
"No refresh token available",
)));
}
let request_ttl: i32 = redis::cmd(TTL)
.arg(&redis_request_key)
.query(redis_connection)?;
let refresh_ttl: i32 = redis::cmd(TTL)
.arg(&redis_refresh_key)
.query(redis_connection)?;
Ok(Self {
request_token,
pub fn from_entry(other: &TokenStoreEntry) -> Option<Self> {
let request_token = other.request_token()?;
let refresh_token = other.refresh_token()?;
Some(Self {
refresh_token,
request_ttl,
refresh_ttl,
request_token,
request_ttl: other.request_ttl(),
refresh_ttl: other.refresh_ttl(),
})
}
@ -84,26 +57,167 @@ impl SessionTokens {
}
/// Saves the tokens into the database
pub fn store(&self, redis_connection: &mut RedisConnection) -> RedisResult<()> {
let id = self.get_user_id();
let redis_request_key = format!("user-{}_request", id);
redis::cmd(SET)
.arg(&redis_request_key)
.arg(&self.request_token)
.arg(EX)
.arg(REQUEST_TOKEN_EXPIRE_SECONDS)
.query(&mut *redis_connection)?;
let redis_refresh_key = format!("user-{}_refresh", id);
redis::cmd(SET)
.arg(&redis_refresh_key)
.arg(&self.refresh_token)
.arg(EX)
.arg(REFRESH_TOKEN_EXPIRE_SECONDS)
.query(&mut *redis_connection)?;
pub fn store(&self, token_store: &mut TokenStore) -> Result<(), String> {
token_store.insert(&self.request_token, &self.refresh_token)
}
}
#[derive(Clone, Debug)]
pub struct TokenStoreEntry {
request_token: [u8; TOKEN_LENGTH],
request_ttl: u32,
refresh_token: [u8; TOKEN_LENGTH],
refresh_ttl: u32,
ttl_start: Instant,
}
impl TokenStoreEntry {
pub fn new(request_token: &String, refresh_token: &String) -> Result<Self, String> {
let request_token = base64::decode(request_token).unwrap();
let refresh_token = &base64::decode(refresh_token).unwrap();
if request_token.len() != TOKEN_LENGTH || refresh_token.len() != TOKEN_LENGTH {
return Err("Invalid token length".to_string());
}
let mut req_token = [0u8; TOKEN_LENGTH];
let mut ref_token = [0u8; TOKEN_LENGTH];
req_token.copy_from_slice(&request_token);
ref_token.copy_from_slice(&refresh_token);
Ok(Self {
request_token: req_token,
refresh_token: ref_token,
request_ttl: REQUEST_TOKEN_EXPIRE_SECONDS,
refresh_ttl: REFRESH_TOKEN_EXPIRE_SECONDS,
ttl_start: Instant::now(),
})
}
pub fn request_ttl(&self) -> i32 {
max(
(self.request_ttl - self.ttl_start.elapsed().as_secs() as u32) as i32,
-1,
)
}
pub fn refresh_ttl(&self) -> i32 {
max(
(self.refresh_ttl - self.ttl_start.elapsed().as_secs() as u32) as i32,
-1,
)
}
pub fn request_token(&self) -> Option<String> {
if self.request_ttl() > 0 {
Some(base64::encode(&self.request_token))
} else {
None
}
}
pub fn refresh_token(&self) -> Option<String> {
if self.refresh_ttl() > 0 {
Some(base64::encode(&self.refresh_token))
} else {
None
}
}
pub fn set_request_token(&mut self, token: String) -> i32 {
self.request_token
.copy_from_slice(base64::decode(token).unwrap().as_slice());
self.reset_timer();
self.request_ttl = REQUEST_TOKEN_EXPIRE_SECONDS;
self.refresh_ttl = REFRESH_TOKEN_EXPIRE_SECONDS;
self.request_ttl as i32
}
fn reset_timer(&mut self) {
self.request_ttl = min(self.request_ttl(), 0) as u32;
self.refresh_ttl = min(self.refresh_ttl(), 0) as u32;
self.ttl_start = Instant::now();
}
}
#[derive(Debug)]
pub struct TokenStore {
tokens: HashMap<i32, Vec<TokenStoreEntry>>,
}
impl TokenStore {
pub fn new() -> Self {
Self {
tokens: HashMap::new(),
}
}
pub fn get_request_token(&self, request_token: &String) -> Option<&TokenStoreEntry> {
let user_id = get_user_id_from_token(&request_token);
if let Some(user_tokens) = self.tokens.get(&user_id) {
user_tokens.iter().find(|e| {
if let Some(token) = e.request_token() {
&token == request_token
} else {
false
}
})
} else {
None
}
}
pub fn get_refresh_token(&self, refresh_token: &String) -> Option<&TokenStoreEntry> {
let user_id = get_user_id_from_token(&refresh_token);
if let Some(user_tokens) = self.tokens.get(&user_id) {
user_tokens.iter().find(|e| {
if let Some(token) = e.refresh_token() {
&token == refresh_token
} else {
false
}
})
} else {
None
}
}
pub fn set_request_token(&mut self, refresh_token: &String, request_token: &String) {
self.clear_expired();
let user_id = get_user_id_from_token(&request_token);
if let Some(user_tokens) = self.tokens.get_mut(&user_id) {
user_tokens.iter_mut().for_each(|e| {
if let Some(ref_token) = &e.refresh_token() {
if ref_token == refresh_token {
e.set_request_token(request_token.to_string());
}
}
});
}
}
pub fn insert(&mut self, request_token: &String, refresh_token: &String) -> Result<(), String> {
let user_id = get_user_id_from_token(refresh_token);
let user_tokens = if let Some(user_tokens) = self.tokens.get_mut(&user_id) {
user_tokens
} else {
self.tokens.insert(user_id, Vec::new());
self.tokens.get_mut(&user_id).unwrap()
};
let entry = TokenStoreEntry::new(request_token, refresh_token)?;
user_tokens.push(entry);
Ok(())
}
pub fn clear_expired(&mut self) {
for (key, entry) in &self.tokens.clone() {
self.tokens.insert(
*key,
entry
.iter()
.cloned()
.filter(|e| e.refresh_ttl() > 0)
.collect(),
);
}
}
}

@ -1,5 +1,5 @@
use crate::database::models::Role;
use crate::database::{DatabaseResult, RedisConnection, Table};
use crate::database::{DatabaseResult, Table};
use crate::utils::error::DBError;
use postgres::Client;
use std::sync::{Arc, Mutex};
@ -7,17 +7,12 @@ use std::sync::{Arc, Mutex};
#[derive(Clone)]
pub struct UserRoles {
database_connection: Arc<Mutex<Client>>,
redis_connection: Arc<Mutex<RedisConnection>>,
}
impl Table for UserRoles {
fn new(
database_connection: Arc<Mutex<Client>>,
redis_connection: Arc<Mutex<RedisConnection>>,
) -> Self {
fn new(database_connection: Arc<Mutex<Client>>) -> Self {
Self {
database_connection,
redis_connection,
}
}

@ -1,9 +1,9 @@
use crate::database::models::UserRecord;
use crate::database::tokens::SessionTokens;
use crate::database::tokens::{SessionTokens, TokenStore};
use crate::database::user_roles::UserRoles;
use crate::database::{DatabaseResult, RedisConnection, Table};
use crate::database::{DatabaseResult, Table};
use crate::utils::error::DBError;
use crate::utils::{create_salt, get_user_id_from_token, hash_password, TOKEN_LENGTH};
use crate::utils::{create_salt, hash_password};
use postgres::Client;
use std::sync::{Arc, Mutex};
@ -12,22 +12,16 @@ use zeroize::{Zeroize, Zeroizing};
#[derive(Clone)]
pub struct Users {
database_connection: Arc<Mutex<Client>>,
redis_connection: Arc<Mutex<RedisConnection>>,
user_roles: UserRoles,
token_store: Arc<Mutex<TokenStore>>,
}
impl Table for Users {
fn new(
database_connection: Arc<Mutex<Client>>,
redis_connection: Arc<Mutex<RedisConnection>>,
) -> Self {
fn new(database_connection: Arc<Mutex<Client>>) -> Self {
Self {
user_roles: UserRoles::new(
Arc::clone(&database_connection),
Arc::clone(&redis_connection),
),
user_roles: UserRoles::new(Arc::clone(&database_connection)),
database_connection,
redis_connection,
token_store: Arc::new(Mutex::new(TokenStore::new())),
}
}
@ -75,7 +69,7 @@ impl Users {
Ok(UserRecord::from_ordered_row(&row))
}
pub fn create_get_tokens(
pub fn create_tokens(
&self,
email: &String,
password: &String,
@ -84,45 +78,44 @@ impl Users {
let mut connection = self.database_connection.lock().unwrap();
let row = connection.query_one("SELECT id FROM users WHERE email = $1", &[&email])?;
let id: i32 = row.get(0);
let mut redis_connection = self.redis_connection.lock().unwrap();
if let Ok(tokens) = SessionTokens::retrieve(id, &mut redis_connection) {
Ok(tokens)
} else {
let tokens = SessionTokens::new(id);
tokens.store(&mut redis_connection)?;
let tokens = SessionTokens::new(id);
tokens.store(&mut self.token_store.lock().unwrap())?;
Ok(tokens)
}
Ok(tokens)
} else {
Err(DBError::GenericError("Invalid password".to_string()))
}
}
pub fn validate_request_token(&self, token: &String) -> DatabaseResult<(bool, i32)> {
let id = get_user_id_from_token(token);
let mut redis_connection = self.redis_connection.lock().unwrap();
let tokens = SessionTokens::retrieve(id, &mut redis_connection)?;
let store = self.token_store.lock().unwrap();
let entry = store.get_request_token(&token);
Ok((tokens.request_token == *token, tokens.request_ttl))
if let Some(entry) = entry {
Ok((true, entry.request_ttl()))
} else {
Ok((false, -1))
}
}
pub fn validate_refresh_token(&self, token: &String) -> DatabaseResult<(bool, i32)> {
let id = get_user_id_from_token(token);
let mut redis_connection = self.redis_connection.lock().unwrap();
let tokens = SessionTokens::retrieve(id, &mut redis_connection)?;
let store = self.token_store.lock().unwrap();
let entry = store.get_refresh_token(&token);
Ok((tokens.refresh_token == *token, tokens.refresh_ttl))
if let Some(entry) = entry {
Ok((true, entry.refresh_ttl()))
} else {
Ok((false, -1))
}
}
pub fn refresh_tokens(&self, refresh_token: &String) -> DatabaseResult<SessionTokens> {
let id = get_user_id_from_token(&refresh_token);
let mut redis_connection = self.redis_connection.lock().unwrap();
let mut tokens = SessionTokens::retrieve(id, &mut redis_connection)?;
if tokens.refresh_token == *refresh_token {
let mut token_store = self.token_store.lock().unwrap();
let tokens = token_store.get_refresh_token(refresh_token);
if let Some(mut tokens) = tokens.and_then(|t| SessionTokens::from_entry(t)) {
tokens.refresh();
tokens.store(&mut redis_connection)?;
tokens.store(&mut token_store)?;
Ok(tokens)
} else {

@ -17,7 +17,7 @@ pub struct UserHttpServer {
#[derive(Debug)]
pub struct HTTPError {
message: String,
code: usize,
code: u16,
}
impl Display for HTTPError {
@ -36,8 +36,14 @@ impl From<DBError> for HTTPError {
}
}
impl Into<Response> for HTTPError {
fn into(self) -> Response {
Response::text(self.message).with_status_code(self.code)
}
}
impl HTTPError {
pub fn new(message: String, code: usize) -> Self {
pub fn new(message: String, code: u16) -> Self {
Self { message, code }
}
}
@ -58,10 +64,10 @@ impl UserHttpServer {
let server = Server::new(listen_address, move |request| {
router!(request,
(POST) (/login) => {
Self::login(&database, request).unwrap_or_else(|e|Response::text(e.to_string()))
Self::login(&database, request).unwrap_or_else(|e|e.into())
},
(POST) (/new-token) => {
Self::new_token(&database, request).unwrap_or_else(|e|Response::text(e.to_string()))
Self::new_token(&database, request).unwrap_or_else(|e|e.into())
},
_ => Response::empty_404()
)
@ -79,7 +85,7 @@ impl UserHttpServer {
.map_err(|e| HTTPError::new(e.to_string(), 400))?;
let tokens = database
.users
.create_get_tokens(&login_request.email, &login_request.password)?;
.create_tokens(&login_request.email, &login_request.password)?;
Ok(Response::json(&tokens))
} else {

@ -1,11 +1,9 @@
use redis::RedisError;
use serde_postgres::DeError;
use std::error;
use std::fmt::{self, Display, Formatter};
#[derive(Debug)]
pub enum DBError {
Redis(RedisError),
Postgres(PostgresError),
RecordExists,
BCryptError,
@ -27,7 +25,6 @@ impl DBError {
DBError::GenericError(g) => g.clone(),
DBError::RecordExists => "Record Exists".to_string(),
DBError::Postgres(p) => p.to_string(),
DBError::Redis(r) => r.to_string(),
DBError::DeserializeError(de) => de.to_string(),
DBError::BCryptError => "BCrypt Hash creation error".to_string(),
}
@ -42,19 +39,17 @@ impl From<PostgresError> for DBError {
}
}
impl From<RedisError> for DBError {
fn from(other: RedisError) -> Self {
Self::Redis(other)
}
}
impl From<serde_postgres::DeError> for DBError {
fn from(other: DeError) -> Self {
Self::DeserializeError(other)
}
}
impl From<String> for DBError {
fn from(other: String) -> Self {
Self::GenericError(other)
}
}
pub type DatabaseClient = postgres::Client;
pub type RedisClient = redis::Client;
pub type RedisConnection = redis::Connection;
pub type PostgresError = postgres::Error;

Loading…
Cancel
Save