Added a user system with no proper user validation but working authorisation. #1

Merged
Roflin merged 6 commits from user-system into main 2022-04-23 13:17:32 +02:00
3 changed files with 17 additions and 24 deletions
Showing only changes of commit b5e9420c1f - Show all commits

View File

@ -76,18 +76,12 @@ impl<'r> FromRequest<'r> for schema::User {
let header = match req.headers().get_one(AUTH_HEADER) {
Some(header) => header,
None => {
return Outcome::Failure((
Status::BadRequest,
ApiError::RequestError("No authorization header found".to_string()),
))
return Outcome::Forward(())
}
};
if !header.starts_with(BEARER) {
return Outcome::Failure((
Status::BadRequest,
ApiError::RequestError("Invalid Authorization header.".to_string()),
));
return Outcome::Forward(());
};
let app_config = req.guard::<&State<AppConfig>>().await.unwrap().inner();
@ -98,11 +92,8 @@ impl<'r> FromRequest<'r> for schema::User {
&Validation::default(),
) {
Ok(token) => token,
Err(error) => {
return Outcome::Failure((
Status::BadRequest,
ApiError::RequestError(error.to_string()),
))
Err(_) => {
return Outcome::Forward(())
}
};
let id = token.claims.uid;
@ -113,13 +104,14 @@ impl<'r> FromRequest<'r> for schema::User {
}
#[get("/gamenights")]
pub async fn gamenights(conn: DbConn, user: Option<schema::User>) -> ApiResponseVariant {
if user.is_some() {
let gamenights = schema::get_all_gamenights(conn).await;
ApiResponseVariant::Value(json!(gamenights))
} else {
ApiResponseVariant::Status(Status::Unauthorized)
}
pub async fn gamenights(conn: DbConn, _user: schema::User) -> ApiResponseVariant {
let gamenights = schema::get_all_gamenights(conn).await;
ApiResponseVariant::Value(json!(gamenights))
}
#[get("/gamenights", rank = 2)]
pub async fn gamenights_unauthorized() -> ApiResponseVariant {
ApiResponseVariant::Status(Status::Unauthorized)
}
Roflin marked this conversation as resolved
Review

I think you can use a Request Guard (see https://api.rocket.rs/v0.5-rc/rocket/request/trait.FromRequest.html) to authenticate the user and role: For example, endpoints that require admin privileges could accept a non-optional Admin struct containing a user id and the request guard that generates it would only return Success if the user is logged and has the admin role.

I think you can use a Request Guard (see https://api.rocket.rs/v0.5-rc/rocket/request/trait.FromRequest.html) to authenticate the user and role: For example, endpoints that require admin privileges could accept a non-optional `Admin` struct containing a user id and the request guard that generates it would only return `Success` if the user is logged and has the admin role.
Review

See also the examples under the header "Request-Local State" in the above link.

See also the examples under the header "Request-Local State" in the above link.
Review

Reading more carefully I see you're already doing this, just that you're accepting an Option<User> and then checking it's not None while you could accept a User and be sure.

Reading more carefully I see you're already doing this, just that you're accepting an `Option<User>` and then checking it's not `None` while you could accept a `User` and be sure.
#[post("/gamenight", format = "application/json", data = "<gamenight_json>")]

View File

@ -58,6 +58,7 @@ fn rocket() -> _ {
"/api",
routes![
api::gamenights,
api::gamenights_unauthorized,
api::gamenight_post_json,
api::register_post_json,
api::login_post_json

View File

@ -57,8 +57,8 @@ table! {
}
table! {
pwd(id) {
id -> Integer,
pwd(user_id) {
user_id -> Integer,
password -> Text,
}
}
@ -129,7 +129,7 @@ pub async fn insert_user(conn: DbConn, new_user: Register) -> Result<(), Databas
};
diesel::insert_into(pwd::table)
.values((pwd::id.eq(ids[0]), pwd::password.eq(&password_hash)))
.values((pwd::user_id.eq(ids[0]), pwd::password.eq(&password_hash)))
.execute(c)
})
})
@ -154,7 +154,7 @@ pub async fn login(conn: DbConn, login: Login) -> Result<LoginResult, DatabaseEr
};
let pwd: String = match pwd::table
.filter(pwd::id.eq(id))
.filter(pwd::user_id.eq(id))
.select(pwd::password)
.get_results::<String>(c)
{