Start role based access
This commit is contained in:
parent
754cac54e2
commit
038990ff85
|
|
@ -0,0 +1 @@
|
|||
-- Add down migration script here
|
||||
|
|
@ -0,0 +1,23 @@
|
|||
-- Add up migration script here
|
||||
|
||||
CREATE TABLE IF NOT EXISTS roles (
|
||||
"id" integer NOT NULL PRIMARY KEY AUTOINCREMENT,
|
||||
"created_at" DATETIME NOT NULL DEFAULT CURRENT_TIMESTAMP,
|
||||
"updated_at" DATETIME NOT NULL DEFAULT CURRENT_TIMESTAMP,
|
||||
"name" TEXT NOT NULL,
|
||||
"description" TEXT
|
||||
);
|
||||
|
||||
CREATE TABLE IF NOT EXISTS user_roles (
|
||||
"user_id" integer NOT NULL,
|
||||
"role_id" integer NOT NULL,
|
||||
"created_at" DATETIME NOT NULL DEFAULT CURRENT_TIMESTAMP,
|
||||
"updated_at" DATETIME NOT NULL DEFAULT CURRENT_TIMESTAMP
|
||||
);
|
||||
|
||||
create TABLE IF NOT EXISTS role_permissions (
|
||||
"role_id" integer NOT NULL,
|
||||
"item" text NOT NULL,
|
||||
"created_at" DATETIME NOT NULL DEFAULT CURRENT_TIMESTAMP,
|
||||
"updated_at" DATETIME NOT NULL DEFAULT CURRENT_TIMESTAMP
|
||||
);
|
||||
|
|
@ -83,16 +83,16 @@ async fn main() {
|
|||
// build our application with some routes
|
||||
let app = Router::new()
|
||||
//Routes that require authentication
|
||||
.route("/logout", get(logout))
|
||||
.route("/profile", get(profile))
|
||||
.route("/useradmin", get(useradmin))
|
||||
.route_layer(middleware::from_fn_with_state(app_state.clone(), check_auth))
|
||||
.route_layer(middleware::from_fn_with_state(app_state.db_pool.clone(), check_auth))
|
||||
|
||||
//Routes that don't require authentication
|
||||
.nest_service("/assets", ServeDir::new("templates/assets")
|
||||
.fallback(get_service(ServeDir::new("templates/assets"))))
|
||||
.route("/", get(index))
|
||||
.route("/login", get(login))
|
||||
.route("/logout", get(logout))
|
||||
.route("/google_auth", get(google_auth))
|
||||
.route("/google_auth_return", get(google_auth_return))
|
||||
.route_layer(middleware::from_fn_with_state(app_state.db_pool.clone(), inject_user_data))
|
||||
|
|
|
|||
|
|
@ -65,15 +65,52 @@ pub async fn inject_user_data(
|
|||
Ok(next.run(request).await)
|
||||
}
|
||||
|
||||
pub async fn check_auth(request: Request<Body>, next: Next) -> Result<impl IntoResponse, AppError> {
|
||||
pub async fn check_auth(State(app_state): State<SqlitePool>, request: Request<Body>, next: Next) -> Result<impl IntoResponse, AppError> {
|
||||
|
||||
if request
|
||||
.extensions()
|
||||
.get::<Option<UserData>>()
|
||||
.ok_or("check_auth: extensions have no UserData")?
|
||||
.is_some()
|
||||
{
|
||||
let path = &*request.uri().to_string();
|
||||
println!("{}", path);
|
||||
println!("{}",&*request.extensions().get::<Option<UserData>>().unwrap().as_ref().unwrap().email);
|
||||
|
||||
let query: Result<(i64,), _> = match path {
|
||||
"/profile" =>
|
||||
sqlx::query_as(r#"select u.id from users u where email =?"#)
|
||||
.bind(request.extensions().get::<Option<UserData>>().unwrap().as_ref().unwrap().email.as_str())
|
||||
.fetch_one(&app_state)
|
||||
.await,
|
||||
_ => sqlx::query_as(r#"select u.id from role_permissions r join user_roles ur on ur.role_id = r.role_id join users u on u.id = ur.user_id where item = ? and email =?"#)
|
||||
.bind(&*request.uri().to_string())
|
||||
.bind(request.extensions().get::<Option<UserData>>().unwrap().as_ref().unwrap().email.as_str())
|
||||
.fetch_one(&app_state)
|
||||
.await,
|
||||
};
|
||||
|
||||
// user is logged in
|
||||
// check if user has the proper role
|
||||
// if not, display banner and return to home page
|
||||
let user_id = if let Ok(query) = query {
|
||||
query.0
|
||||
} else {
|
||||
// user does not have the proper role
|
||||
0
|
||||
};
|
||||
|
||||
println!("{}", user_id);
|
||||
if user_id == 0 {
|
||||
// user does not have the proper role
|
||||
// display banner and return to home page
|
||||
return Ok(Redirect::to("/").into_response());
|
||||
}
|
||||
|
||||
Ok(next.run(request).await)
|
||||
} else {
|
||||
// user is not logged in
|
||||
// redirect to login page with return_url
|
||||
let login_url = "/login?return_url=".to_owned() + &*request.uri().to_string();
|
||||
Ok(Redirect::to(login_url.as_str()).into_response())
|
||||
}
|
||||
|
|
|
|||
|
|
@ -154,7 +154,6 @@ pub async fn google_auth_return(
|
|||
.map_err(|_| "OAuth: reqwest received invalid userinfo")?;
|
||||
let mut body: serde_json::Value =
|
||||
serde_json::from_str(body.as_str()).map_err(|_| "OAuth: Serde failed to parse userinfo")?;
|
||||
println!("body: {}", body);
|
||||
let email = body["email"]
|
||||
.take()
|
||||
.as_str()
|
||||
|
|
|
|||
Loading…
Reference in New Issue