You've already forked AstralRinth
forked from didirus/AstralRinth
Initial Auth Impl + More Caching (#647)
* Port redis to staging * redis cache on staging * add back legacy auth callback * Begin work on new auth flows * Finish all auth flows * Finish base session authentication * run prep + fix clippy * make compilation work
This commit is contained in:
@@ -1,3 +1,4 @@
|
||||
use crate::auth::{get_user_from_headers, is_authorized};
|
||||
use crate::database::models::notification_item::NotificationBuilder;
|
||||
use crate::database::models::TeamMember;
|
||||
use crate::models::ids::ProjectId;
|
||||
@@ -5,7 +6,6 @@ use crate::models::notifications::NotificationBody;
|
||||
use crate::models::teams::{Permissions, TeamId};
|
||||
use crate::models::users::UserId;
|
||||
use crate::routes::ApiError;
|
||||
use crate::util::auth::{get_user_from_headers, is_authorized};
|
||||
use actix_web::{delete, get, patch, post, web, HttpRequest, HttpResponse};
|
||||
use rust_decimal::Decimal;
|
||||
use serde::{Deserialize, Serialize};
|
||||
@@ -30,25 +30,27 @@ pub async fn team_members_get_project(
|
||||
req: HttpRequest,
|
||||
info: web::Path<(String,)>,
|
||||
pool: web::Data<PgPool>,
|
||||
redis: web::Data<deadpool_redis::Pool>,
|
||||
) -> Result<HttpResponse, ApiError> {
|
||||
let string = info.into_inner().0;
|
||||
let project_data =
|
||||
crate::database::models::Project::get_from_slug_or_project_id(&string, &**pool).await?;
|
||||
let project_data = crate::database::models::Project::get(&string, &**pool, &redis).await?;
|
||||
|
||||
if let Some(project) = project_data {
|
||||
let current_user = get_user_from_headers(req.headers(), &**pool).await.ok();
|
||||
let current_user = get_user_from_headers(req.headers(), &**pool, &redis)
|
||||
.await
|
||||
.ok();
|
||||
|
||||
if !is_authorized(&project, ¤t_user, &pool).await? {
|
||||
let members_data =
|
||||
TeamMember::get_from_team_full(project.inner.team_id, &**pool, &redis).await?;
|
||||
|
||||
if !is_authorized(&project.inner, ¤t_user, &pool).await? {
|
||||
return Ok(HttpResponse::NotFound().body(""));
|
||||
}
|
||||
|
||||
let members_data = TeamMember::get_from_team_full(project.team_id, &**pool).await?;
|
||||
|
||||
if let Some(user) = ¤t_user {
|
||||
let team_member =
|
||||
TeamMember::get_from_user_id(project.team_id, user.id.into(), &**pool)
|
||||
.await
|
||||
.map_err(ApiError::Database)?;
|
||||
let team_member = members_data
|
||||
.iter()
|
||||
.find(|x| x.user.id == user.id.into() && x.accepted);
|
||||
|
||||
if team_member.is_some() {
|
||||
let team_members: Vec<_> = members_data
|
||||
@@ -83,16 +85,19 @@ pub async fn team_members_get(
|
||||
req: HttpRequest,
|
||||
info: web::Path<(TeamId,)>,
|
||||
pool: web::Data<PgPool>,
|
||||
redis: web::Data<deadpool_redis::Pool>,
|
||||
) -> Result<HttpResponse, ApiError> {
|
||||
let id = info.into_inner().0;
|
||||
let members_data = TeamMember::get_from_team_full(id.into(), &**pool).await?;
|
||||
let members_data = TeamMember::get_from_team_full(id.into(), &**pool, &redis).await?;
|
||||
|
||||
let current_user = get_user_from_headers(req.headers(), &**pool).await.ok();
|
||||
let current_user = get_user_from_headers(req.headers(), &**pool, &redis)
|
||||
.await
|
||||
.ok();
|
||||
|
||||
if let Some(user) = ¤t_user {
|
||||
let team_member = TeamMember::get_from_user_id(id.into(), user.id.into(), &**pool)
|
||||
.await
|
||||
.map_err(ApiError::Database)?;
|
||||
let team_member = members_data
|
||||
.iter()
|
||||
.find(|x| x.user.id == user.id.into() && x.accepted);
|
||||
|
||||
if team_member.is_some() {
|
||||
let team_members: Vec<_> = members_data
|
||||
@@ -129,6 +134,7 @@ pub async fn teams_get(
|
||||
req: HttpRequest,
|
||||
web::Query(ids): web::Query<TeamIds>,
|
||||
pool: web::Data<PgPool>,
|
||||
redis: web::Data<deadpool_redis::Pool>,
|
||||
) -> Result<HttpResponse, ApiError> {
|
||||
use itertools::Itertools;
|
||||
|
||||
@@ -137,34 +143,39 @@ pub async fn teams_get(
|
||||
.map(|x| x.into())
|
||||
.collect::<Vec<crate::database::models::ids::TeamId>>();
|
||||
|
||||
let teams_data = TeamMember::get_from_team_full_many(&team_ids, &**pool).await?;
|
||||
let teams_data = TeamMember::get_from_team_full_many(&team_ids, &**pool, &redis).await?;
|
||||
|
||||
let current_user = get_user_from_headers(req.headers(), &**pool).await.ok();
|
||||
let accepted = if let Some(user) = current_user {
|
||||
TeamMember::get_from_user_id_many(&team_ids, user.id.into(), &**pool)
|
||||
.await?
|
||||
.into_iter()
|
||||
.map(|m| m.team_id.0)
|
||||
.collect()
|
||||
} else {
|
||||
std::collections::HashSet::new()
|
||||
};
|
||||
let current_user = get_user_from_headers(req.headers(), &**pool, &redis)
|
||||
.await
|
||||
.ok();
|
||||
|
||||
let teams_groups = teams_data.into_iter().group_by(|data| data.team_id.0);
|
||||
|
||||
let mut teams: Vec<Vec<crate::models::teams::TeamMember>> = vec![];
|
||||
|
||||
for (id, member_data) in &teams_groups {
|
||||
if accepted.contains(&id) {
|
||||
let team_members =
|
||||
member_data.map(|data| crate::models::teams::TeamMember::from(data, false));
|
||||
for (_, member_data) in &teams_groups {
|
||||
let members = member_data.collect::<Vec<_>>();
|
||||
|
||||
let team_member = if let Some(user) = ¤t_user {
|
||||
members
|
||||
.iter()
|
||||
.find(|x| x.user.id == user.id.into() && x.accepted)
|
||||
} else {
|
||||
None
|
||||
};
|
||||
|
||||
if team_member.is_some() {
|
||||
let team_members = members
|
||||
.into_iter()
|
||||
.map(|data| crate::models::teams::TeamMember::from(data, false));
|
||||
|
||||
teams.push(team_members.collect());
|
||||
|
||||
continue;
|
||||
}
|
||||
|
||||
let team_members = member_data
|
||||
let team_members = members
|
||||
.into_iter()
|
||||
.filter(|x| x.accepted)
|
||||
.map(|data| crate::models::teams::TeamMember::from(data, true));
|
||||
|
||||
@@ -179,9 +190,10 @@ pub async fn join_team(
|
||||
req: HttpRequest,
|
||||
info: web::Path<(TeamId,)>,
|
||||
pool: web::Data<PgPool>,
|
||||
redis: web::Data<deadpool_redis::Pool>,
|
||||
) -> Result<HttpResponse, ApiError> {
|
||||
let team_id = info.into_inner().0.into();
|
||||
let current_user = get_user_from_headers(req.headers(), &**pool).await?;
|
||||
let current_user = get_user_from_headers(req.headers(), &**pool, &redis).await?;
|
||||
|
||||
let member =
|
||||
TeamMember::get_from_user_id_pending(team_id, current_user.id.into(), &**pool).await?;
|
||||
@@ -207,6 +219,8 @@ pub async fn join_team(
|
||||
)
|
||||
.await?;
|
||||
|
||||
TeamMember::clear_cache(team_id, &redis).await?;
|
||||
|
||||
transaction.commit().await?;
|
||||
} else {
|
||||
return Err(ApiError::InvalidInput(
|
||||
@@ -244,12 +258,13 @@ pub async fn add_team_member(
|
||||
info: web::Path<(TeamId,)>,
|
||||
pool: web::Data<PgPool>,
|
||||
new_member: web::Json<NewTeamMember>,
|
||||
redis: web::Data<deadpool_redis::Pool>,
|
||||
) -> Result<HttpResponse, ApiError> {
|
||||
let team_id = info.into_inner().0.into();
|
||||
|
||||
let mut transaction = pool.begin().await?;
|
||||
|
||||
let current_user = get_user_from_headers(req.headers(), &**pool).await?;
|
||||
let current_user = get_user_from_headers(req.headers(), &**pool, &redis).await?;
|
||||
let member = TeamMember::get_from_user_id(team_id, current_user.id.into(), &**pool)
|
||||
.await?
|
||||
.ok_or_else(|| {
|
||||
@@ -281,12 +296,8 @@ pub async fn add_team_member(
|
||||
));
|
||||
}
|
||||
|
||||
let request = crate::database::models::team_item::TeamMember::get_from_user_id_pending(
|
||||
team_id,
|
||||
new_member.user_id.into(),
|
||||
&**pool,
|
||||
)
|
||||
.await?;
|
||||
let request =
|
||||
TeamMember::get_from_user_id_pending(team_id, new_member.user_id.into(), &**pool).await?;
|
||||
|
||||
if let Some(req) = request {
|
||||
if req.accepted {
|
||||
@@ -300,7 +311,7 @@ pub async fn add_team_member(
|
||||
}
|
||||
}
|
||||
|
||||
crate::database::models::User::get(member.user_id, &**pool)
|
||||
crate::database::models::User::get_id(member.user_id, &**pool, &redis)
|
||||
.await?
|
||||
.ok_or_else(|| ApiError::InvalidInput("An invalid User ID specified".to_string()))?;
|
||||
|
||||
@@ -340,6 +351,8 @@ pub async fn add_team_member(
|
||||
.insert(new_member.user_id.into(), &mut transaction)
|
||||
.await?;
|
||||
|
||||
TeamMember::clear_cache(team_id, &redis).await?;
|
||||
|
||||
transaction.commit().await?;
|
||||
|
||||
Ok(HttpResponse::NoContent().body(""))
|
||||
@@ -359,12 +372,13 @@ pub async fn edit_team_member(
|
||||
info: web::Path<(TeamId, UserId)>,
|
||||
pool: web::Data<PgPool>,
|
||||
edit_member: web::Json<EditTeamMember>,
|
||||
redis: web::Data<deadpool_redis::Pool>,
|
||||
) -> Result<HttpResponse, ApiError> {
|
||||
let ids = info.into_inner();
|
||||
let id = ids.0.into();
|
||||
let user_id = ids.1.into();
|
||||
|
||||
let current_user = get_user_from_headers(req.headers(), &**pool).await?;
|
||||
let current_user = get_user_from_headers(req.headers(), &**pool, &redis).await?;
|
||||
let member = TeamMember::get_from_user_id(id, current_user.id.into(), &**pool)
|
||||
.await?
|
||||
.ok_or_else(|| {
|
||||
@@ -430,6 +444,8 @@ pub async fn edit_team_member(
|
||||
)
|
||||
.await?;
|
||||
|
||||
TeamMember::clear_cache(id, &redis).await?;
|
||||
|
||||
transaction.commit().await?;
|
||||
|
||||
Ok(HttpResponse::NoContent().body(""))
|
||||
@@ -446,10 +462,11 @@ pub async fn transfer_ownership(
|
||||
info: web::Path<(TeamId,)>,
|
||||
pool: web::Data<PgPool>,
|
||||
new_owner: web::Json<TransferOwnership>,
|
||||
redis: web::Data<deadpool_redis::Pool>,
|
||||
) -> Result<HttpResponse, ApiError> {
|
||||
let id = info.into_inner().0;
|
||||
|
||||
let current_user = get_user_from_headers(req.headers(), &**pool).await?;
|
||||
let current_user = get_user_from_headers(req.headers(), &**pool, &redis).await?;
|
||||
|
||||
if !current_user.role.is_admin() {
|
||||
let member = TeamMember::get_from_user_id(id.into(), current_user.id.into(), &**pool)
|
||||
@@ -505,6 +522,8 @@ pub async fn transfer_ownership(
|
||||
)
|
||||
.await?;
|
||||
|
||||
TeamMember::clear_cache(id.into(), &redis).await?;
|
||||
|
||||
transaction.commit().await?;
|
||||
|
||||
Ok(HttpResponse::NoContent().body(""))
|
||||
@@ -515,12 +534,13 @@ pub async fn remove_team_member(
|
||||
req: HttpRequest,
|
||||
info: web::Path<(TeamId, UserId)>,
|
||||
pool: web::Data<PgPool>,
|
||||
redis: web::Data<deadpool_redis::Pool>,
|
||||
) -> Result<HttpResponse, ApiError> {
|
||||
let ids = info.into_inner();
|
||||
let id = ids.0.into();
|
||||
let user_id = ids.1.into();
|
||||
|
||||
let current_user = get_user_from_headers(req.headers(), &**pool).await?;
|
||||
let current_user = get_user_from_headers(req.headers(), &**pool, &redis).await?;
|
||||
let member = TeamMember::get_from_user_id(id, current_user.id.into(), &**pool)
|
||||
.await?
|
||||
.ok_or_else(|| {
|
||||
@@ -566,6 +586,8 @@ pub async fn remove_team_member(
|
||||
));
|
||||
}
|
||||
|
||||
TeamMember::clear_cache(id, &redis).await?;
|
||||
|
||||
transaction.commit().await?;
|
||||
Ok(HttpResponse::NoContent().body(""))
|
||||
} else {
|
||||
|
||||
Reference in New Issue
Block a user