55 lines
1.8 KiB
Rust
55 lines
1.8 KiB
Rust
use anyhow::Result;
|
|
use deadpool_diesel::postgres::Connection;
|
|
use diesel::prelude::*;
|
|
use uuid::Uuid;
|
|
|
|
use crate::{
|
|
app_error::AppError, csrf::validate_csrf_token, team_memberships::TeamMembership, teams::Team,
|
|
users::User,
|
|
};
|
|
|
|
/// Returns a ForbiddenError if user is not a member of the indicated team.
|
|
/// Intended to be used in HTTP handlers to check authorization. The team
|
|
/// struct is often useful in such cases, so it is returned if the
|
|
/// authorization check is successful.
|
|
pub async fn require_team_membership(
|
|
current_user: &User,
|
|
team_id: &Uuid,
|
|
db_conn: &Connection,
|
|
) -> Result<Team, AppError> {
|
|
let maybe_team = {
|
|
let current_user_id = current_user.id;
|
|
let team_id = *team_id;
|
|
db_conn
|
|
.interact::<_, Result<Option<(Team, _)>>>(move |conn| {
|
|
TeamMembership::all()
|
|
.filter(TeamMembership::with_user_id(¤t_user_id))
|
|
.filter(TeamMembership::with_team_id(&team_id))
|
|
.first(conn)
|
|
.optional()
|
|
.map_err(Into::into)
|
|
})
|
|
.await
|
|
.unwrap()?
|
|
};
|
|
match maybe_team {
|
|
Some((team, _)) => Ok(team),
|
|
None => Err(AppError::ForbiddenError(
|
|
"not a member of requested team".to_string(),
|
|
)),
|
|
}
|
|
}
|
|
|
|
/// Returns a ForbiddenError if the CSRF token parameters do not match an entry
|
|
/// in the database. Do not expect this function to invalidate tokens after use.
|
|
pub async fn require_valid_csrf_token(
|
|
csrf_token: &str,
|
|
current_user: &User,
|
|
db_conn: &Connection,
|
|
) -> Result<(), AppError> {
|
|
if validate_csrf_token(db_conn, csrf_token, Some(current_user.id)).await? {
|
|
Ok(())
|
|
} else {
|
|
Err(AppError::ForbiddenError("invalid CSRF token".to_string()))
|
|
}
|
|
}
|