limit users to proper role, Fixes #135
Some checks are pending
CI/CD Pipeline / deploy-staging (push) Blocked by required conditions
CI/CD Pipeline / deploy-main (push) Blocked by required conditions
CI/CD Pipeline / test (push) Successful in 15m47s

This commit is contained in:
2024-01-10 14:08:15 +01:00
parent c9e163c92c
commit 3e2e058bcc
12 changed files with 770 additions and 565 deletions

View File

@ -264,6 +264,10 @@ ORDER BY departure DESC
return Err(LogbookCreateError::BoatNotFound);
};
if boat.amount_seats == 1 && log.rowers.is_empty() {
log.rowers = vec![created_by_user.id];
}
if boat.amount_seats == 1 {
log.shipmaster = Some(log.rowers[0]);
log.steering_person = Some(log.rowers[0]);

View File

@ -440,23 +440,20 @@ impl<'r> FromRequest<'r> for User {
Ok(user_id) => {
let db = req.rocket().state::<SqlitePool>().unwrap();
let Some(user) = User::find_by_id(db, user_id).await else {
return Outcome::Error((Status::Unauthorized, LoginError::UserNotFound));
return Outcome::Error((Status::Forbidden, LoginError::UserNotFound));
};
if user.deleted {
return Outcome::Error((Status::Unauthorized, LoginError::UserDeleted));
return Outcome::Error((Status::Forbidden, LoginError::UserDeleted));
}
user.logged_in(db).await;
let mut cookie = Cookie::new("loggedin_user", format!("{}", user.id));
cookie.set_expires(OffsetDateTime::now_utc() + Duration::weeks(12));
cookie.set_expires(OffsetDateTime::now_utc() + Duration::weeks(2));
req.cookies().add_private(cookie);
Outcome::Success(user)
}
Err(_) => {
println!("{:?}", user_id.value());
Outcome::Error((Status::Unauthorized, LoginError::DeserializationError))
}
Err(_) => Outcome::Error((Status::Unauthorized, LoginError::DeserializationError)),
},
None => Outcome::Error((Status::Unauthorized, LoginError::NotLoggedIn)),
}
@ -487,7 +484,7 @@ impl<'r> FromRequest<'r> for TechUser {
if user.has_role(db, "tech").await {
Outcome::Success(TechUser { user })
} else {
Outcome::Error((Status::Unauthorized, LoginError::NotACox))
Outcome::Error((Status::Forbidden, LoginError::NotACox))
}
}
Outcome::Error(f) => Outcome::Error(f),
@ -530,7 +527,7 @@ impl<'r> FromRequest<'r> for CoxUser {
if user.has_role(db, "cox").await {
Outcome::Success(CoxUser { user })
} else {
Outcome::Error((Status::Unauthorized, LoginError::NotACox))
Outcome::Error((Status::Forbidden, LoginError::NotACox))
}
}
Outcome::Error(f) => Outcome::Error(f),
@ -555,7 +552,7 @@ impl<'r> FromRequest<'r> for AdminUser {
if user.has_role(db, "admin").await {
Outcome::Success(AdminUser { user })
} else {
Outcome::Error((Status::Unauthorized, LoginError::NotACox))
Outcome::Error((Status::Forbidden, LoginError::NotACox))
}
}
Outcome::Error(f) => Outcome::Error(f),
@ -565,22 +562,65 @@ impl<'r> FromRequest<'r> for AdminUser {
}
#[derive(Debug, Serialize, Deserialize)]
pub struct NonGuestUser {
pub(crate) user: User,
}
pub struct AllowedForPlannedTripsUser(pub(crate) User);
#[async_trait]
impl<'r> FromRequest<'r> for NonGuestUser {
impl<'r> FromRequest<'r> for AllowedForPlannedTripsUser {
type Error = LoginError;
async fn from_request(req: &'r Request<'_>) -> request::Outcome<Self, Self::Error> {
let db = req.rocket().state::<SqlitePool>().unwrap();
match User::from_request(req).await {
Outcome::Success(user) => {
if !user.has_role(db, "scheckbuch").await {
Outcome::Success(NonGuestUser { user })
if user.has_role(db, "Donau Linz").await {
Outcome::Success(AllowedForPlannedTripsUser(user))
} else if user.has_role(db, "scheckbuch").await {
Outcome::Success(AllowedForPlannedTripsUser(user))
} else {
Outcome::Error((Status::Unauthorized, LoginError::NotACox))
Outcome::Error((Status::Forbidden, LoginError::NotACox))
}
}
Outcome::Error(f) => Outcome::Error(f),
Outcome::Forward(f) => Outcome::Forward(f),
}
}
}
impl Into<User> for AllowedForPlannedTripsUser {
fn into(self) -> User {
self.0
}
}
#[derive(Debug, Serialize, Deserialize)]
pub struct DonauLinzUser(pub(crate) User);
impl Into<User> for DonauLinzUser {
fn into(self) -> User {
self.0
}
}
impl Deref for DonauLinzUser {
type Target = User;
fn deref(&self) -> &Self::Target {
&self.0
}
}
#[async_trait]
impl<'r> FromRequest<'r> for DonauLinzUser {
type Error = LoginError;
async fn from_request(req: &'r Request<'_>) -> request::Outcome<Self, Self::Error> {
let db = req.rocket().state::<SqlitePool>().unwrap();
match User::from_request(req).await {
Outcome::Success(user) => {
if user.has_role(db, "Donau Linz").await {
Outcome::Success(DonauLinzUser(user))
} else {
Outcome::Error((Status::Forbidden, LoginError::NotACox))
}
}
Outcome::Error(f) => Outcome::Error(f),