198 lines
6.5 KiB
Rust
198 lines
6.5 KiB
Rust
use crate::{AppService, error::AppError};
|
|
use chrono::Utc;
|
|
use models::projects::{MemberRole, project_audit_log, project_history_name};
|
|
use models::repos::{Repo, repo};
|
|
use models::users::user;
|
|
use sea_orm::*;
|
|
use serde::{Deserialize, Serialize};
|
|
use session::Session;
|
|
|
|
#[derive(Deserialize, Serialize, Clone, Debug, utoipa::ToSchema)]
|
|
pub struct ExchangeProjectVisibility {
|
|
pub is_public: bool,
|
|
}
|
|
|
|
#[derive(Deserialize, Serialize, Clone, Debug, utoipa::ToSchema)]
|
|
pub struct ExchangeProjectTitle {
|
|
pub display_name: Option<String>,
|
|
pub description: Option<String>,
|
|
}
|
|
|
|
#[derive(Deserialize, Serialize, Clone, Debug, utoipa::ToSchema)]
|
|
pub struct ExchangeProjectName {
|
|
pub name: String,
|
|
}
|
|
|
|
impl AppService {
|
|
pub async fn project_exchange_name(
|
|
&self,
|
|
ctx: &Session,
|
|
project_name: String,
|
|
params: ExchangeProjectName,
|
|
) -> Result<(), AppError> {
|
|
let user_uid = ctx.user().ok_or(AppError::Unauthorized)?;
|
|
let project = self
|
|
.utils_find_project_by_name(project_name.clone())
|
|
.await?;
|
|
let oper = user::Entity::find()
|
|
.filter(user::Column::Uid.eq(user_uid))
|
|
.one(&self.db)
|
|
.await?
|
|
.ok_or(AppError::UserNotFound)?;
|
|
|
|
if let Ok(role) = self.utils_project_context_role(&ctx, project_name).await {
|
|
if role != MemberRole::Owner {
|
|
return Err(AppError::NoPower);
|
|
}
|
|
} else {
|
|
return Err(AppError::NoPower);
|
|
}
|
|
|
|
let txn = self.db.begin().await?;
|
|
|
|
let mut active = project.clone().into_active_model();
|
|
active.name = Set(params.name.clone());
|
|
active.update(&txn).await?;
|
|
|
|
// Update repo names for all repos in this project
|
|
let repos = Repo::find()
|
|
.filter(repo::Column::Project.eq(project.id))
|
|
.all(&txn)
|
|
.await?;
|
|
|
|
for r in repos {
|
|
let repo_name = r.repo_name.clone();
|
|
let mut ra: repo::ActiveModel = r.into();
|
|
ra.repo_name = Set(format!("{}/{}", params.name.clone(), repo_name));
|
|
ra.update(&txn).await?;
|
|
}
|
|
|
|
let log = project_audit_log::ActiveModel {
|
|
project: Set(project.id),
|
|
actor: Set(user_uid),
|
|
action: Set("exchange_name".to_string()),
|
|
details: Set(Some(serde_json::json!({
|
|
"name": params.name,
|
|
"old_name": project.name,
|
|
"username": oper.username,
|
|
"user_uid": user_uid,
|
|
}))),
|
|
created_at: Set(Utc::now()),
|
|
..Default::default()
|
|
};
|
|
let history = project_history_name::ActiveModel {
|
|
id: NotSet,
|
|
project_uid: Set(project.id),
|
|
history_name: Set(project.name),
|
|
changed_at: Set(Utc::now()),
|
|
};
|
|
history.insert(&txn).await?;
|
|
log.insert(&txn).await?;
|
|
txn.commit().await?;
|
|
Ok(())
|
|
}
|
|
|
|
pub async fn project_exchange_visibility(
|
|
&self,
|
|
ctx: &Session,
|
|
project_name: String,
|
|
params: ExchangeProjectVisibility,
|
|
) -> Result<(), AppError> {
|
|
let user_uid = ctx.user().ok_or(AppError::Unauthorized)?;
|
|
let project = self
|
|
.utils_find_project_by_name(project_name.clone())
|
|
.await?;
|
|
if let Ok(role) = self.utils_project_context_role(&ctx, project_name).await {
|
|
if role == MemberRole::Member {
|
|
return Err(AppError::NoPower);
|
|
}
|
|
} else {
|
|
return Err(AppError::NoPower);
|
|
}
|
|
|
|
if project.is_public != params.is_public {
|
|
let txn = self.db.begin().await?;
|
|
let mut active = project.clone().into_active_model();
|
|
active.is_public = Set(params.is_public);
|
|
active.update(&txn).await?;
|
|
|
|
let oper = user::Entity::find()
|
|
.filter(user::Column::Uid.eq(user_uid))
|
|
.one(&txn)
|
|
.await?
|
|
.ok_or(AppError::UserNotFound)?;
|
|
|
|
let log = project_audit_log::ActiveModel {
|
|
project: Set(project.id),
|
|
actor: Set(user_uid),
|
|
action: Set("exchange_visibility".to_string()),
|
|
details: Set(Some(serde_json::json!({
|
|
"is_public": params.is_public,
|
|
"old_is_public": project.is_public,
|
|
"username": oper.username,
|
|
"user_uid": user_uid,
|
|
}))),
|
|
created_at: Set(Utc::now()),
|
|
..Default::default()
|
|
};
|
|
log.insert(&txn).await?;
|
|
txn.commit().await?;
|
|
}
|
|
Ok(())
|
|
}
|
|
|
|
pub async fn project_exchange_title(
|
|
&self,
|
|
ctx: &Session,
|
|
project_name: String,
|
|
params: ExchangeProjectTitle,
|
|
) -> Result<(), AppError> {
|
|
let user_uid = ctx.user().ok_or(AppError::Unauthorized)?;
|
|
let project = self
|
|
.utils_find_project_by_name(project_name.clone())
|
|
.await?;
|
|
if let Ok(role) = self.utils_project_context_role(&ctx, project_name).await {
|
|
if role == MemberRole::Member {
|
|
return Err(AppError::NoPower);
|
|
}
|
|
} else {
|
|
return Err(AppError::NoPower);
|
|
}
|
|
|
|
let txn = self.db.begin().await?;
|
|
let mut active = project.clone().into_active_model();
|
|
if let Some(description) = params.description.clone() {
|
|
active.description = Set(Some(description));
|
|
}
|
|
if let Some(display_name) = params.display_name.clone() {
|
|
active.display_name = Set(display_name);
|
|
}
|
|
active.update(&txn).await?;
|
|
|
|
let oper = user::Entity::find()
|
|
.filter(user::Column::Uid.eq(user_uid))
|
|
.one(&txn)
|
|
.await?
|
|
.ok_or(AppError::UserNotFound)?;
|
|
|
|
let log = project_audit_log::ActiveModel {
|
|
project: Set(project.id),
|
|
actor: Set(user_uid),
|
|
action: Set("exchange_description".to_string()),
|
|
details: Set(Some(serde_json::json!({
|
|
"description": params.description,
|
|
"username": oper.username,
|
|
"user_uid": user_uid,
|
|
"old_description": project.description,
|
|
"display_name": params.display_name,
|
|
"old_display_name": project.display_name,
|
|
}))),
|
|
created_at: Set(Utc::now()),
|
|
..Default::default()
|
|
};
|
|
log.insert(&txn).await?;
|
|
txn.commit().await?;
|
|
Ok(())
|
|
}
|
|
}
|