-
Notifications
You must be signed in to change notification settings - Fork 0
Commit
This commit does not belong to any branch on this repository, and may belong to a fork outside of the repository.
Create auth-service, add actors, add getting token from auth0
- Loading branch information
Showing
16 changed files
with
534 additions
and
0 deletions.
There are no files selected for viewing
This file contains bidirectional Unicode text that may be interpreted or compiled differently than what appears below. To review, open the file in an editor that reveals hidden Unicode characters.
Learn more about bidirectional Unicode characters
This file contains bidirectional Unicode text that may be interpreted or compiled differently than what appears below. To review, open the file in an editor that reveals hidden Unicode characters.
Learn more about bidirectional Unicode characters
Original file line number | Diff line number | Diff line change |
---|---|---|
@@ -0,0 +1,30 @@ | ||
[package] | ||
name = "auth-service" | ||
version = "0.1.0" | ||
edition = "2021" | ||
|
||
# See more keys and their definitions at https://doc.rust-lang.org/cargo/reference/manifest.html | ||
|
||
[dependencies] | ||
actix = "0.13.3" | ||
serde = { version = "1.0.197", features = ["derive"] } | ||
serde_json = "1.0.114" | ||
actix-web = "4.0.0-beta.8" | ||
diesel = { version = "=2.1.4", features = [ | ||
"extras", | ||
"uuid", | ||
"numeric", | ||
"chrono", | ||
] } | ||
diesel-derive-enum = { version = "2.0.0-rc.0", features = ["postgres"] } | ||
diesel-async = { version = "0.4.1", features = ["postgres", "deadpool"] } | ||
tokio = "1.36.0" | ||
thiserror = "1.0.57" | ||
uuid = { version = "1.7.0", features = ["v4"] } | ||
chrono = "0.4.35" | ||
reqwest = { version = "0.11.25", features = ["json"] } | ||
log = "0.4.21" | ||
anyhow = "1.0.80" | ||
fern = "0.6.2" | ||
colored = "2.1.0" | ||
dotenv = "0.15.0" |
This file contains bidirectional Unicode text that may be interpreted or compiled differently than what appears below. To review, open the file in an editor that reveals hidden Unicode characters.
Learn more about bidirectional Unicode characters
Original file line number | Diff line number | Diff line change |
---|---|---|
@@ -0,0 +1 @@ | ||
DROP TABLE users; |
This file contains bidirectional Unicode text that may be interpreted or compiled differently than what appears below. To review, open the file in an editor that reveals hidden Unicode characters.
Learn more about bidirectional Unicode characters
Original file line number | Diff line number | Diff line change |
---|---|---|
@@ -0,0 +1,9 @@ | ||
CREATE TABLE users ( | ||
id UUID PRIMARY KEY, | ||
username VARCHAR(255), | ||
email VARCHAR(255) NOT NULL, | ||
password VARCHAR(255) NOT NULL, | ||
is_email_activate BOOLEAN DEFAULT FALSE, | ||
created_at TIMESTAMP DEFAULT CURRENT_TIMESTAMP, | ||
updated_at TIMESTAMP | ||
); |
This file contains bidirectional Unicode text that may be interpreted or compiled differently than what appears below. To review, open the file in an editor that reveals hidden Unicode characters.
Learn more about bidirectional Unicode characters
Original file line number | Diff line number | Diff line change |
---|---|---|
@@ -0,0 +1,146 @@ | ||
use crate::actors::messages::{ | ||
CreateUser, DeleteUser, UpdateActivateEmail, UpdateEmail, UpdatePassword, UpdateUsername, | ||
}; | ||
use crate::db::postgres_db::DbService; | ||
use crate::db::tables::Users; | ||
use actix::{AtomicResponse, Handler, WrapFuture}; | ||
use diesel::{ExpressionMethods, QueryDsl}; | ||
use diesel_async::RunQueryDsl; | ||
|
||
impl Handler<CreateUser> for DbService { | ||
type Result = AtomicResponse<Self, crate::errors::Result<()>>; | ||
|
||
fn handle(&mut self, msg: CreateUser, _: &mut Self::Context) -> Self::Result { | ||
let db = self.clone(); | ||
let conn = async move { db.pool.get().await }; | ||
let result = async move { | ||
let user = Users { | ||
id: msg.id, | ||
username: msg.username, | ||
email: msg.email, | ||
password: msg.password, | ||
is_email_activate: false, | ||
created_at: chrono::Utc::now(), | ||
updated_at: None, | ||
}; | ||
|
||
let _ = diesel::insert_into(crate::db::schema::users::table) | ||
.values(user) | ||
.execute(&mut conn.await?) | ||
.await?; | ||
Ok(()) | ||
}; | ||
log::info!("Creating user {}", msg.id); | ||
|
||
let db = self.clone(); | ||
|
||
AtomicResponse::new(Box::pin(result.into_actor(&db))) | ||
} | ||
} | ||
|
||
impl Handler<UpdateActivateEmail> for DbService { | ||
type Result = AtomicResponse<Self, crate::errors::Result<()>>; | ||
|
||
fn handle(&mut self, msg: UpdateActivateEmail, _: &mut Self::Context) -> Self::Result { | ||
let db = self.clone(); | ||
let conn = async move { db.pool.get().await }; | ||
|
||
let query = async move { | ||
let _ = diesel::update(crate::db::schema::users::table) | ||
.filter(crate::db::schema::users::id.eq(msg.user_id)) | ||
.set(crate::db::schema::users::is_email_activate.eq(true)) | ||
.execute(&mut conn.await?) | ||
.await?; | ||
Ok(()) | ||
}; | ||
log::info!("Updating user is_activate_email {}", msg.user_id); | ||
|
||
let db = self.clone(); | ||
AtomicResponse::new(Box::pin(query.into_actor(&db))) | ||
} | ||
} | ||
|
||
impl Handler<DeleteUser> for DbService { | ||
type Result = AtomicResponse<Self, crate::errors::Result<()>>; | ||
|
||
fn handle(&mut self, msg: DeleteUser, _: &mut Self::Context) -> Self::Result { | ||
let db = self.clone(); | ||
let conn = async move { db.pool.get().await }; | ||
let query = async move { | ||
let _ = diesel::delete( | ||
crate::db::schema::users::table | ||
.filter(crate::db::schema::users::id.eq(msg.user_id)), | ||
) | ||
.execute(&mut conn.await?) | ||
.await?; | ||
Ok(()) | ||
}; | ||
log::info!("Deleting user {}", msg.user_id); | ||
|
||
let db = self.clone(); | ||
AtomicResponse::new(Box::pin(query.into_actor(&db))) | ||
} | ||
} | ||
|
||
impl Handler<UpdatePassword> for DbService { | ||
type Result = AtomicResponse<Self, crate::errors::Result<()>>; | ||
|
||
fn handle(&mut self, msg: UpdatePassword, _: &mut Self::Context) -> Self::Result { | ||
let db = self.clone(); | ||
let conn = async move { db.pool.get().await }; | ||
let query = async move { | ||
let _ = diesel::update(crate::db::schema::users::table) | ||
.filter(crate::db::schema::users::id.eq(msg.user_id)) | ||
.set(crate::db::schema::users::password.eq(msg.password)) | ||
.execute(&mut conn.await?) | ||
.await?; | ||
Ok(()) | ||
}; | ||
log::info!("Updating user password {}", msg.user_id); | ||
|
||
let db = self.clone(); | ||
AtomicResponse::new(Box::pin(query.into_actor(&db))) | ||
} | ||
} | ||
|
||
impl Handler<UpdateEmail> for DbService { | ||
type Result = AtomicResponse<Self, crate::errors::Result<()>>; | ||
|
||
fn handle(&mut self, msg: UpdateEmail, _: &mut Self::Context) -> Self::Result { | ||
let db = self.clone(); | ||
let conn = async move { db.pool.get().await }; | ||
let query = async move { | ||
let _ = diesel::update(crate::db::schema::users::table) | ||
.filter(crate::db::schema::users::id.eq(msg.user_id)) | ||
.set(crate::db::schema::users::email.eq(msg.email)) | ||
.execute(&mut conn.await?) | ||
.await?; | ||
Ok(()) | ||
}; | ||
log::info!("Updating user email {}", msg.user_id); | ||
|
||
let db = self.clone(); | ||
AtomicResponse::new(Box::pin(query.into_actor(&db))) | ||
} | ||
} | ||
|
||
impl Handler<UpdateUsername> for DbService { | ||
type Result = AtomicResponse<Self, crate::errors::Result<()>>; | ||
|
||
fn handle(&mut self, msg: UpdateUsername, _: &mut Self::Context) -> Self::Result { | ||
let db = self.clone(); | ||
let conn = async move { db.pool.get().await }; | ||
let query = async move { | ||
let _ = diesel::update(crate::db::schema::users::table) | ||
.filter(crate::db::schema::users::id.eq(msg.user_id)) | ||
.set(crate::db::schema::users::username.eq(msg.username)) | ||
.execute(&mut conn.await?) | ||
.await?; | ||
Ok(()) | ||
}; | ||
log::info!("Updating user username {}", msg.user_id); | ||
|
||
let db = self.clone(); | ||
AtomicResponse::new(Box::pin(query.into_actor(&db))) | ||
} | ||
} |
This file contains bidirectional Unicode text that may be interpreted or compiled differently than what appears below. To review, open the file in an editor that reveals hidden Unicode characters.
Learn more about bidirectional Unicode characters
Original file line number | Diff line number | Diff line change |
---|---|---|
@@ -0,0 +1,44 @@ | ||
use actix::Message; | ||
use uuid::Uuid; | ||
|
||
#[derive(Message)] | ||
#[rtype(result = "crate::errors::Result<()>")] | ||
pub(crate) struct CreateUser { | ||
pub id: Uuid, | ||
pub username: String, | ||
pub password: String, | ||
pub email: String, | ||
} | ||
|
||
#[derive(Message)] | ||
#[rtype(result = "crate::errors::Result<()>")] | ||
pub(crate) struct UpdateActivateEmail { | ||
pub user_id: Uuid, | ||
} | ||
|
||
#[derive(Message)] | ||
#[rtype(result = "crate::errors::Result<()>")] | ||
pub(crate) struct DeleteUser { | ||
pub user_id: Uuid, | ||
} | ||
|
||
#[derive(Message)] | ||
#[rtype(result = "crate::errors::Result<()>")] | ||
pub(crate) struct UpdatePassword { | ||
pub user_id: Uuid, | ||
pub password: String, | ||
} | ||
|
||
#[derive(Message)] | ||
#[rtype(result = "crate::errors::Result<()>")] | ||
pub(crate) struct UpdateEmail { | ||
pub user_id: Uuid, | ||
pub email: String, | ||
} | ||
|
||
#[derive(Message)] | ||
#[rtype(result = "crate::errors::Result<()>")] | ||
pub(crate) struct UpdateUsername { | ||
pub user_id: Uuid, | ||
pub username: String, | ||
} |
This file contains bidirectional Unicode text that may be interpreted or compiled differently than what appears below. To review, open the file in an editor that reveals hidden Unicode characters.
Learn more about bidirectional Unicode characters
Original file line number | Diff line number | Diff line change |
---|---|---|
@@ -0,0 +1,2 @@ | ||
pub mod handlers; | ||
pub mod messages; |
This file contains bidirectional Unicode text that may be interpreted or compiled differently than what appears below. To review, open the file in an editor that reveals hidden Unicode characters.
Learn more about bidirectional Unicode characters
Original file line number | Diff line number | Diff line change |
---|---|---|
@@ -0,0 +1,7 @@ | ||
pub mod postgres_db; | ||
|
||
pub mod tables; | ||
|
||
pub mod schema; | ||
|
||
pub mod utils; |
This file contains bidirectional Unicode text that may be interpreted or compiled differently than what appears below. To review, open the file in an editor that reveals hidden Unicode characters.
Learn more about bidirectional Unicode characters
Original file line number | Diff line number | Diff line change |
---|---|---|
@@ -0,0 +1,17 @@ | ||
use crate::db::utils::DatabasePool; | ||
use actix::Actor; | ||
|
||
#[derive(Clone)] | ||
pub struct DbService { | ||
pub(crate) pool: DatabasePool, | ||
} | ||
|
||
impl DbService { | ||
pub fn new(pool: DatabasePool) -> Self { | ||
Self { pool } | ||
} | ||
} | ||
|
||
impl Actor for DbService { | ||
type Context = actix::Context<Self>; | ||
} |
This file contains bidirectional Unicode text that may be interpreted or compiled differently than what appears below. To review, open the file in an editor that reveals hidden Unicode characters.
Learn more about bidirectional Unicode characters
Original file line number | Diff line number | Diff line change |
---|---|---|
@@ -0,0 +1,9 @@ | ||
diesel::table!(users { | ||
id -> Uuid, | ||
username -> Varchar, | ||
email -> Varchar, | ||
password -> Varchar, | ||
is_email_activate -> Bool, | ||
created_at -> Timestamptz, | ||
updated_at -> Nullable<Timestamptz> | ||
}); |
This file contains bidirectional Unicode text that may be interpreted or compiled differently than what appears below. To review, open the file in an editor that reveals hidden Unicode characters.
Learn more about bidirectional Unicode characters
Original file line number | Diff line number | Diff line change |
---|---|---|
@@ -0,0 +1,16 @@ | ||
use crate::db::schema::users; | ||
use chrono::{DateTime, Utc}; | ||
use diesel::{Identifiable, Insertable, Queryable}; | ||
use uuid::Uuid; | ||
|
||
#[derive(Debug, Clone, Queryable, Insertable, Identifiable)] | ||
#[diesel(table_name = users)] | ||
pub struct Users { | ||
pub id: Uuid, | ||
pub username: String, | ||
pub email: String, | ||
pub password: String, | ||
pub is_email_activate: bool, | ||
pub created_at: DateTime<Utc>, | ||
pub updated_at: Option<DateTime<Utc>>, | ||
} |
This file contains bidirectional Unicode text that may be interpreted or compiled differently than what appears below. To review, open the file in an editor that reveals hidden Unicode characters.
Learn more about bidirectional Unicode characters
Original file line number | Diff line number | Diff line change |
---|---|---|
@@ -0,0 +1,40 @@ | ||
use crate::errors::{Error, Result}; | ||
use diesel_async::pooled_connection::deadpool::Pool; | ||
use diesel_async::pooled_connection::AsyncDieselConnectionManager; | ||
use diesel_async::AsyncPgConnection; | ||
use reqwest::{Client, Method}; | ||
use serde_json::Value; | ||
|
||
pub type DatabasePool = Pool<AsyncPgConnection>; | ||
|
||
pub async fn create_connection_pool(database_url: String) -> Result<DatabasePool> { | ||
let manager = AsyncDieselConnectionManager::new(database_url); | ||
let pool = Pool::builder(manager).build()?; | ||
|
||
Ok(pool) | ||
} | ||
|
||
pub async fn get_jwt_token() -> Result<String> { | ||
let client = Client::new(); | ||
let url = dotenv::var("CLIENT").unwrap_or_else(|_| "localhost:8080".to_string()); | ||
let client_id = dotenv::var("CLIENT_ID").unwrap_or_else(|_| "admin".to_string()); | ||
let client_secret = dotenv::var("CLIENT_SECRET").unwrap_or_else(|_| "admin".to_string()); | ||
let request = client | ||
.request(Method::POST, &url) | ||
.header("Content-Type", "application/json") | ||
.json(&serde_json::json!({ | ||
"client_id": client_id, | ||
"client_secret": client_secret, | ||
"audience":"https://someexample.com", | ||
"grant_type":"client_credentials" | ||
})) | ||
.send() | ||
.await?; | ||
let response = request.json::<Value>().await?; | ||
log::info!("Response: {:?}", response); | ||
let token = match response["access_token"].as_str() { | ||
Some(token) => token, | ||
None => return Err(Error::InvalidInput("Invalid token".to_string())), | ||
}; | ||
Ok(token.to_string()) | ||
} |
Oops, something went wrong.