mirror of
https://github.com/encounter/decomp.dev.git
synced 2026-07-10 03:18:48 -07:00
Adjust disabled logic for admins
This commit is contained in:
+8
-2
@@ -1,6 +1,6 @@
|
|||||||
{
|
{
|
||||||
"db_name": "SQLite",
|
"db_name": "SQLite",
|
||||||
"query": "\n SELECT id AS \"id!\", owner, repo, name, short_name, default_category, default_version, platform, workflow_id, enable_pr_comments, pr_report_style AS \"pr_report_style!\", header_image_id, enabled\n FROM projects\n WHERE id = ?\n ",
|
"query": "\n SELECT id AS \"id!\", owner, repo, name, short_name, default_category, default_version, platform, workflow_id, enable_pr_comments, pr_report_style AS \"pr_report_style!\", header_image_id, enabled, permanently_disabled\n FROM projects\n WHERE id = ?\n ",
|
||||||
"describe": {
|
"describe": {
|
||||||
"columns": [
|
"columns": [
|
||||||
{
|
{
|
||||||
@@ -67,6 +67,11 @@
|
|||||||
"name": "enabled",
|
"name": "enabled",
|
||||||
"ordinal": 12,
|
"ordinal": 12,
|
||||||
"type_info": "Bool"
|
"type_info": "Bool"
|
||||||
|
},
|
||||||
|
{
|
||||||
|
"name": "permanently_disabled",
|
||||||
|
"ordinal": 13,
|
||||||
|
"type_info": "Bool"
|
||||||
}
|
}
|
||||||
],
|
],
|
||||||
"parameters": {
|
"parameters": {
|
||||||
@@ -85,8 +90,9 @@
|
|||||||
false,
|
false,
|
||||||
false,
|
false,
|
||||||
true,
|
true,
|
||||||
|
false,
|
||||||
false
|
false
|
||||||
]
|
]
|
||||||
},
|
},
|
||||||
"hash": "d6b5cfd0b352120901dad884ddae80e6b9e94c78d80511a885a8a336147cc57f"
|
"hash": "002db17df22e67f818c3ed30227ada0baad6d1715261d0421e5ea1942d1e8816"
|
||||||
}
|
}
|
||||||
-12
@@ -1,12 +0,0 @@
|
|||||||
{
|
|
||||||
"db_name": "SQLite",
|
|
||||||
"query": "\n INSERT INTO projects (id, owner, repo, name, short_name, default_category, default_version, platform, workflow_id, enable_pr_comments, pr_report_style, header_image_id, enabled, created_at, updated_at)\n VALUES (?, ?, ?, ?, ?, ?, ?, ?, ?, ?, ?, ?, ?, CURRENT_TIMESTAMP, CURRENT_TIMESTAMP)\n ON CONFLICT (id) DO NOTHING\n ",
|
|
||||||
"describe": {
|
|
||||||
"columns": [],
|
|
||||||
"parameters": {
|
|
||||||
"Right": 13
|
|
||||||
},
|
|
||||||
"nullable": []
|
|
||||||
},
|
|
||||||
"hash": "0a643e5596bd37e5ba8018e9decd2717ce8ed1a38d31a9f0652ed4ec9091b419"
|
|
||||||
}
|
|
||||||
+3
-3
@@ -1,12 +1,12 @@
|
|||||||
{
|
{
|
||||||
"db_name": "SQLite",
|
"db_name": "SQLite",
|
||||||
"query": "\n INSERT INTO projects (id, owner, repo, name, short_name, default_category, default_version, platform, workflow_id, enable_pr_comments, pr_report_style, header_image_id, enabled, created_at, updated_at)\n VALUES (?, ?, ?, ?, ?, ?, ?, ?, ?, ?, ?, ?, ?, CURRENT_TIMESTAMP, CURRENT_TIMESTAMP)\n ",
|
"query": "\n INSERT INTO projects (id, owner, repo, name, short_name, default_category, default_version, platform, workflow_id, enable_pr_comments, pr_report_style, header_image_id, enabled, permanently_disabled, created_at, updated_at)\n VALUES (?, ?, ?, ?, ?, ?, ?, ?, ?, ?, ?, ?, ?, ?, CURRENT_TIMESTAMP, CURRENT_TIMESTAMP)\n ",
|
||||||
"describe": {
|
"describe": {
|
||||||
"columns": [],
|
"columns": [],
|
||||||
"parameters": {
|
"parameters": {
|
||||||
"Right": 13
|
"Right": 14
|
||||||
},
|
},
|
||||||
"nullable": []
|
"nullable": []
|
||||||
},
|
},
|
||||||
"hash": "77fa30390ff028ea9fff086a695e87e65bba44f4344aa4575a081b8d1f6eddb3"
|
"hash": "3f80147d7d2c97a4713b2f84bbb4cbaf52686e958fc77bfe3be063babdabf4fd"
|
||||||
}
|
}
|
||||||
+12
@@ -0,0 +1,12 @@
|
|||||||
|
{
|
||||||
|
"db_name": "SQLite",
|
||||||
|
"query": "\n INSERT INTO projects (id, owner, repo, name, short_name, default_category, default_version, platform, workflow_id, enable_pr_comments, pr_report_style, header_image_id, enabled, permanently_disabled, created_at, updated_at)\n VALUES (?, ?, ?, ?, ?, ?, ?, ?, ?, ?, ?, ?, ?, ?, CURRENT_TIMESTAMP, CURRENT_TIMESTAMP)\n ON CONFLICT (id) DO NOTHING\n ",
|
||||||
|
"describe": {
|
||||||
|
"columns": [],
|
||||||
|
"parameters": {
|
||||||
|
"Right": 14
|
||||||
|
},
|
||||||
|
"nullable": []
|
||||||
|
},
|
||||||
|
"hash": "79caeee92f0cd249bf9326edcf0eface93792bad3cd55c8e1e49f4d5053a9236"
|
||||||
|
}
|
||||||
+13
-7
@@ -1,6 +1,6 @@
|
|||||||
{
|
{
|
||||||
"db_name": "SQLite",
|
"db_name": "SQLite",
|
||||||
"query": "\n SELECT\n projects.id AS \"project_id!\",\n owner AS \"owner!\",\n repo AS \"repo!\",\n name,\n short_name,\n default_category,\n default_version,\n platform,\n workflow_id,\n enable_pr_comments AS \"enable_pr_comments!\",\n pr_report_style AS \"pr_report_style!\",\n header_image_id,\n enabled AS \"enabled!\",\n git_commit,\n git_commit_message,\n MAX(timestamp) AS \"timestamp: time::OffsetDateTime\",\n JSON_GROUP_ARRAY(version ORDER BY version)\n FILTER (WHERE version IS NOT NULL) AS versions\n FROM projects LEFT JOIN reports ON (\n reports.project_id = projects.id\n AND reports.timestamp = (\n SELECT MAX(timestamp)\n FROM reports\n WHERE project_id = projects.id\n )\n )\n GROUP BY projects.id\n ORDER BY MAX(timestamp) DESC\n ",
|
"query": "\n SELECT\n projects.id AS \"project_id!\",\n owner AS \"owner!\",\n repo AS \"repo!\",\n name,\n short_name,\n default_category,\n default_version,\n platform,\n workflow_id,\n enable_pr_comments AS \"enable_pr_comments!\",\n pr_report_style AS \"pr_report_style!\",\n header_image_id,\n enabled AS \"enabled!\",\n permanently_disabled AS \"permanently_disabled!\",\n git_commit,\n git_commit_message,\n MAX(timestamp) AS \"timestamp: time::OffsetDateTime\",\n JSON_GROUP_ARRAY(version ORDER BY version)\n FILTER (WHERE version IS NOT NULL) AS versions\n FROM projects LEFT JOIN reports ON (\n reports.project_id = projects.id\n AND reports.timestamp = (\n SELECT MAX(timestamp)\n FROM reports\n WHERE project_id = projects.id\n )\n )\n GROUP BY projects.id\n ORDER BY MAX(timestamp) DESC\n ",
|
||||||
"describe": {
|
"describe": {
|
||||||
"columns": [
|
"columns": [
|
||||||
{
|
{
|
||||||
@@ -69,23 +69,28 @@
|
|||||||
"type_info": "Bool"
|
"type_info": "Bool"
|
||||||
},
|
},
|
||||||
{
|
{
|
||||||
"name": "git_commit",
|
"name": "permanently_disabled!",
|
||||||
"ordinal": 13,
|
"ordinal": 13,
|
||||||
"type_info": "Text"
|
"type_info": "Bool"
|
||||||
},
|
},
|
||||||
{
|
{
|
||||||
"name": "git_commit_message",
|
"name": "git_commit",
|
||||||
"ordinal": 14,
|
"ordinal": 14,
|
||||||
"type_info": "Text"
|
"type_info": "Text"
|
||||||
},
|
},
|
||||||
{
|
{
|
||||||
"name": "timestamp: time::OffsetDateTime",
|
"name": "git_commit_message",
|
||||||
"ordinal": 15,
|
"ordinal": 15,
|
||||||
|
"type_info": "Text"
|
||||||
|
},
|
||||||
|
{
|
||||||
|
"name": "timestamp: time::OffsetDateTime",
|
||||||
|
"ordinal": 16,
|
||||||
"type_info": "Datetime"
|
"type_info": "Datetime"
|
||||||
},
|
},
|
||||||
{
|
{
|
||||||
"name": "versions",
|
"name": "versions",
|
||||||
"ordinal": 16,
|
"ordinal": 17,
|
||||||
"type_info": "Text"
|
"type_info": "Text"
|
||||||
}
|
}
|
||||||
],
|
],
|
||||||
@@ -109,8 +114,9 @@
|
|||||||
true,
|
true,
|
||||||
true,
|
true,
|
||||||
true,
|
true,
|
||||||
|
true,
|
||||||
true
|
true
|
||||||
]
|
]
|
||||||
},
|
},
|
||||||
"hash": "86318ebdf4ce242b320f209e79ae7af307f061f92c8d284addfecfe5215476ea"
|
"hash": "9d3da451668e4ddfc83fac2bfffe6c6a3f18d290d110c41dd832abd86cdf94a8"
|
||||||
}
|
}
|
||||||
+8
-2
@@ -1,6 +1,6 @@
|
|||||||
{
|
{
|
||||||
"db_name": "SQLite",
|
"db_name": "SQLite",
|
||||||
"query": "\n SELECT id AS \"id!\", owner, repo, name, short_name, default_category, default_version, platform, workflow_id, enable_pr_comments, pr_report_style AS \"pr_report_style!\", header_image_id, enabled\n FROM projects\n WHERE owner = ? COLLATE NOCASE AND repo = ? COLLATE NOCASE\n ",
|
"query": "\n SELECT id AS \"id!\", owner, repo, name, short_name, default_category, default_version, platform, workflow_id, enable_pr_comments, pr_report_style AS \"pr_report_style!\", header_image_id, enabled, permanently_disabled\n FROM projects\n WHERE owner = ? COLLATE NOCASE AND repo = ? COLLATE NOCASE\n ",
|
||||||
"describe": {
|
"describe": {
|
||||||
"columns": [
|
"columns": [
|
||||||
{
|
{
|
||||||
@@ -67,6 +67,11 @@
|
|||||||
"name": "enabled",
|
"name": "enabled",
|
||||||
"ordinal": 12,
|
"ordinal": 12,
|
||||||
"type_info": "Bool"
|
"type_info": "Bool"
|
||||||
|
},
|
||||||
|
{
|
||||||
|
"name": "permanently_disabled",
|
||||||
|
"ordinal": 13,
|
||||||
|
"type_info": "Bool"
|
||||||
}
|
}
|
||||||
],
|
],
|
||||||
"parameters": {
|
"parameters": {
|
||||||
@@ -85,8 +90,9 @@
|
|||||||
false,
|
false,
|
||||||
false,
|
false,
|
||||||
true,
|
true,
|
||||||
|
false,
|
||||||
false
|
false
|
||||||
]
|
]
|
||||||
},
|
},
|
||||||
"hash": "3d625ccc90b0a896ab906107c60e784df93a969f7a381854eee2777370e90906"
|
"hash": "d8009000e3f563e32b08ec811de5c2c48f64e4f50a480002f9ec5f0df04f3563"
|
||||||
}
|
}
|
||||||
+3
-3
@@ -1,12 +1,12 @@
|
|||||||
{
|
{
|
||||||
"db_name": "SQLite",
|
"db_name": "SQLite",
|
||||||
"query": "\n UPDATE projects\n SET owner = ?, repo = ?, name = ?, short_name = ?, default_category = ?, default_version = ?, platform = ?, workflow_id = ?, enable_pr_comments = ?, pr_report_style = ?, header_image_id = ?, enabled = ?, updated_at = CURRENT_TIMESTAMP\n WHERE id = ?\n ",
|
"query": "\n UPDATE projects\n SET owner = ?, repo = ?, name = ?, short_name = ?, default_category = ?, default_version = ?, platform = ?, workflow_id = ?, enable_pr_comments = ?, pr_report_style = ?, header_image_id = ?, enabled = ?, permanently_disabled = ?, updated_at = CURRENT_TIMESTAMP\n WHERE id = ?\n ",
|
||||||
"describe": {
|
"describe": {
|
||||||
"columns": [],
|
"columns": [],
|
||||||
"parameters": {
|
"parameters": {
|
||||||
"Right": 13
|
"Right": 14
|
||||||
},
|
},
|
||||||
"nullable": []
|
"nullable": []
|
||||||
},
|
},
|
||||||
"hash": "66c72864237c9c44358e1d3a3333a11d00dd4a6d1bb30bc852aaa792089a3403"
|
"hash": "f664efe4589ab51c477c2104a878bc85eb5856032f6890048d51e1eeb6cd25a2"
|
||||||
}
|
}
|
||||||
@@ -11,6 +11,7 @@ use base64::{Engine as _, engine::general_purpose::URL_SAFE_NO_PAD};
|
|||||||
use decomp_dev_core::{
|
use decomp_dev_core::{
|
||||||
AppError,
|
AppError,
|
||||||
config::{Config, GitHubConfig},
|
config::{Config, GitHubConfig},
|
||||||
|
models::Project,
|
||||||
};
|
};
|
||||||
use decomp_dev_github::graphql::{
|
use decomp_dev_github::graphql::{
|
||||||
CurrentUserResponse, RepositoryPermission, fetch_current_user, fetch_simple_current_user,
|
CurrentUserResponse, RepositoryPermission, fetch_current_user, fetch_simple_current_user,
|
||||||
@@ -87,6 +88,10 @@ impl CurrentUser {
|
|||||||
pub fn can_manage_repo(&self, id: u64) -> bool {
|
pub fn can_manage_repo(&self, id: u64) -> bool {
|
||||||
matches!(self.permissions_for_repo(id), RepositoryPermission::Admin)
|
matches!(self.permissions_for_repo(id), RepositoryPermission::Admin)
|
||||||
}
|
}
|
||||||
|
|
||||||
|
pub fn can_manage_project(&self, project: &Project) -> bool {
|
||||||
|
self.super_admin || (!project.permanently_disabled && self.can_manage_repo(project.id))
|
||||||
|
}
|
||||||
}
|
}
|
||||||
|
|
||||||
pub fn generate_nonce() -> String {
|
pub fn generate_nonce() -> String {
|
||||||
|
|||||||
@@ -62,6 +62,7 @@ pub struct Project {
|
|||||||
pub pr_report_style: PullReportStyle,
|
pub pr_report_style: PullReportStyle,
|
||||||
pub header_image_id: Option<ImageId>,
|
pub header_image_id: Option<ImageId>,
|
||||||
pub enabled: bool,
|
pub enabled: bool,
|
||||||
|
pub permanently_disabled: bool,
|
||||||
}
|
}
|
||||||
|
|
||||||
impl Default for Project {
|
impl Default for Project {
|
||||||
@@ -80,6 +81,7 @@ impl Default for Project {
|
|||||||
pr_report_style: PullReportStyle::Comment,
|
pr_report_style: PullReportStyle::Comment,
|
||||||
header_image_id: None,
|
header_image_id: None,
|
||||||
enabled: true,
|
enabled: true,
|
||||||
|
permanently_disabled: false,
|
||||||
}
|
}
|
||||||
}
|
}
|
||||||
}
|
}
|
||||||
@@ -100,6 +102,8 @@ impl Project {
|
|||||||
pub fn repo_url(&self) -> String { format!("https://github.com/{}/{}", self.owner, self.repo) }
|
pub fn repo_url(&self) -> String { format!("https://github.com/{}/{}", self.owner, self.repo) }
|
||||||
|
|
||||||
pub fn default_category(&self) -> &str { self.default_category.as_deref().unwrap_or("all") }
|
pub fn default_category(&self) -> &str { self.default_category.as_deref().unwrap_or("all") }
|
||||||
|
|
||||||
|
pub fn reports_enabled(&self) -> bool { self.enabled && !self.permanently_disabled }
|
||||||
}
|
}
|
||||||
|
|
||||||
#[derive(Debug, Clone, Eq, PartialEq, Serialize)]
|
#[derive(Debug, Clone, Eq, PartialEq, Serialize)]
|
||||||
@@ -301,7 +305,7 @@ pub enum ProjectVisibility {
|
|||||||
|
|
||||||
pub fn project_visibility(project: &Project, measures: Option<&Measures>) -> ProjectVisibility {
|
pub fn project_visibility(project: &Project, measures: Option<&Measures>) -> ProjectVisibility {
|
||||||
// Hide projects with less than 0.5% matched code or if the project is disabled
|
// Hide projects with less than 0.5% matched code or if the project is disabled
|
||||||
if !project.enabled {
|
if !project.reports_enabled() {
|
||||||
ProjectVisibility::Disabled
|
ProjectVisibility::Disabled
|
||||||
} else if measures.is_none_or(|m| m.matched_code_percent < 0.5) {
|
} else if measures.is_none_or(|m| m.matched_code_percent < 0.5) {
|
||||||
ProjectVisibility::Hidden
|
ProjectVisibility::Hidden
|
||||||
|
|||||||
+14
-7
@@ -88,8 +88,8 @@ impl Database {
|
|||||||
let pr_report_style = project.pr_report_style.as_str();
|
let pr_report_style = project.pr_report_style.as_str();
|
||||||
sqlx::query!(
|
sqlx::query!(
|
||||||
r#"
|
r#"
|
||||||
INSERT INTO projects (id, owner, repo, name, short_name, default_category, default_version, platform, workflow_id, enable_pr_comments, pr_report_style, header_image_id, enabled, created_at, updated_at)
|
INSERT INTO projects (id, owner, repo, name, short_name, default_category, default_version, platform, workflow_id, enable_pr_comments, pr_report_style, header_image_id, enabled, permanently_disabled, created_at, updated_at)
|
||||||
VALUES (?, ?, ?, ?, ?, ?, ?, ?, ?, ?, ?, ?, ?, CURRENT_TIMESTAMP, CURRENT_TIMESTAMP)
|
VALUES (?, ?, ?, ?, ?, ?, ?, ?, ?, ?, ?, ?, ?, ?, CURRENT_TIMESTAMP, CURRENT_TIMESTAMP)
|
||||||
ON CONFLICT (id) DO NOTHING
|
ON CONFLICT (id) DO NOTHING
|
||||||
"#,
|
"#,
|
||||||
project_id,
|
project_id,
|
||||||
@@ -105,6 +105,7 @@ impl Database {
|
|||||||
pr_report_style,
|
pr_report_style,
|
||||||
header_image_id,
|
header_image_id,
|
||||||
project.enabled,
|
project.enabled,
|
||||||
|
project.permanently_disabled,
|
||||||
)
|
)
|
||||||
.execute(&mut *tx)
|
.execute(&mut *tx)
|
||||||
.await?;
|
.await?;
|
||||||
@@ -414,7 +415,7 @@ impl Database {
|
|||||||
) -> Result<Option<Project>> {
|
) -> Result<Option<Project>> {
|
||||||
Ok(sqlx::query!(
|
Ok(sqlx::query!(
|
||||||
r#"
|
r#"
|
||||||
SELECT id AS "id!", owner, repo, name, short_name, default_category, default_version, platform, workflow_id, enable_pr_comments, pr_report_style AS "pr_report_style!", header_image_id, enabled
|
SELECT id AS "id!", owner, repo, name, short_name, default_category, default_version, platform, workflow_id, enable_pr_comments, pr_report_style AS "pr_report_style!", header_image_id, enabled, permanently_disabled
|
||||||
FROM projects
|
FROM projects
|
||||||
WHERE owner = ? COLLATE NOCASE AND repo = ? COLLATE NOCASE
|
WHERE owner = ? COLLATE NOCASE AND repo = ? COLLATE NOCASE
|
||||||
"#,
|
"#,
|
||||||
@@ -438,6 +439,7 @@ impl Database {
|
|||||||
pr_report_style: row.pr_report_style.parse().unwrap_or_default(),
|
pr_report_style: row.pr_report_style.parse().unwrap_or_default(),
|
||||||
header_image_id: row.header_image_id.and_then(|b| b.try_into().ok()),
|
header_image_id: row.header_image_id.and_then(|b| b.try_into().ok()),
|
||||||
enabled: row.enabled,
|
enabled: row.enabled,
|
||||||
|
permanently_disabled: row.permanently_disabled,
|
||||||
}
|
}
|
||||||
}))
|
}))
|
||||||
}
|
}
|
||||||
@@ -450,7 +452,7 @@ impl Database {
|
|||||||
let project_id_db = project_id as i64;
|
let project_id_db = project_id as i64;
|
||||||
Ok(sqlx::query!(
|
Ok(sqlx::query!(
|
||||||
r#"
|
r#"
|
||||||
SELECT id AS "id!", owner, repo, name, short_name, default_category, default_version, platform, workflow_id, enable_pr_comments, pr_report_style AS "pr_report_style!", header_image_id, enabled
|
SELECT id AS "id!", owner, repo, name, short_name, default_category, default_version, platform, workflow_id, enable_pr_comments, pr_report_style AS "pr_report_style!", header_image_id, enabled, permanently_disabled
|
||||||
FROM projects
|
FROM projects
|
||||||
WHERE id = ?
|
WHERE id = ?
|
||||||
"#,
|
"#,
|
||||||
@@ -473,6 +475,7 @@ impl Database {
|
|||||||
pr_report_style: row.pr_report_style.parse().unwrap_or_default(),
|
pr_report_style: row.pr_report_style.parse().unwrap_or_default(),
|
||||||
header_image_id: row.header_image_id.and_then(|b| b.try_into().ok()),
|
header_image_id: row.header_image_id.and_then(|b| b.try_into().ok()),
|
||||||
enabled: row.enabled,
|
enabled: row.enabled,
|
||||||
|
permanently_disabled: row.permanently_disabled,
|
||||||
}
|
}
|
||||||
}))
|
}))
|
||||||
}
|
}
|
||||||
@@ -632,6 +635,7 @@ impl Database {
|
|||||||
pr_report_style AS "pr_report_style!",
|
pr_report_style AS "pr_report_style!",
|
||||||
header_image_id,
|
header_image_id,
|
||||||
enabled AS "enabled!",
|
enabled AS "enabled!",
|
||||||
|
permanently_disabled AS "permanently_disabled!",
|
||||||
git_commit,
|
git_commit,
|
||||||
git_commit_message,
|
git_commit_message,
|
||||||
MAX(timestamp) AS "timestamp: time::OffsetDateTime",
|
MAX(timestamp) AS "timestamp: time::OffsetDateTime",
|
||||||
@@ -667,6 +671,7 @@ impl Database {
|
|||||||
pr_report_style: row.pr_report_style.parse().unwrap_or_default(),
|
pr_report_style: row.pr_report_style.parse().unwrap_or_default(),
|
||||||
header_image_id: row.header_image_id.and_then(|b| b.try_into().ok()),
|
header_image_id: row.header_image_id.and_then(|b| b.try_into().ok()),
|
||||||
enabled: row.enabled,
|
enabled: row.enabled,
|
||||||
|
permanently_disabled: row.permanently_disabled,
|
||||||
},
|
},
|
||||||
commit: match (row.git_commit, row.timestamp) {
|
commit: match (row.git_commit, row.timestamp) {
|
||||||
(Some(sha), Some(timestamp)) => Some(Commit {
|
(Some(sha), Some(timestamp)) => Some(Commit {
|
||||||
@@ -1025,7 +1030,7 @@ impl Database {
|
|||||||
sqlx::query!(
|
sqlx::query!(
|
||||||
r#"
|
r#"
|
||||||
UPDATE projects
|
UPDATE projects
|
||||||
SET owner = ?, repo = ?, name = ?, short_name = ?, default_category = ?, default_version = ?, platform = ?, workflow_id = ?, enable_pr_comments = ?, pr_report_style = ?, header_image_id = ?, enabled = ?, updated_at = CURRENT_TIMESTAMP
|
SET owner = ?, repo = ?, name = ?, short_name = ?, default_category = ?, default_version = ?, platform = ?, workflow_id = ?, enable_pr_comments = ?, pr_report_style = ?, header_image_id = ?, enabled = ?, permanently_disabled = ?, updated_at = CURRENT_TIMESTAMP
|
||||||
WHERE id = ?
|
WHERE id = ?
|
||||||
"#,
|
"#,
|
||||||
project.owner,
|
project.owner,
|
||||||
@@ -1040,6 +1045,7 @@ impl Database {
|
|||||||
pr_report_style,
|
pr_report_style,
|
||||||
header_image_id,
|
header_image_id,
|
||||||
project.enabled,
|
project.enabled,
|
||||||
|
project.permanently_disabled,
|
||||||
project_id,
|
project_id,
|
||||||
)
|
)
|
||||||
.execute(&mut *conn)
|
.execute(&mut *conn)
|
||||||
@@ -1054,8 +1060,8 @@ impl Database {
|
|||||||
let pr_report_style = project.pr_report_style.as_str();
|
let pr_report_style = project.pr_report_style.as_str();
|
||||||
sqlx::query!(
|
sqlx::query!(
|
||||||
r#"
|
r#"
|
||||||
INSERT INTO projects (id, owner, repo, name, short_name, default_category, default_version, platform, workflow_id, enable_pr_comments, pr_report_style, header_image_id, enabled, created_at, updated_at)
|
INSERT INTO projects (id, owner, repo, name, short_name, default_category, default_version, platform, workflow_id, enable_pr_comments, pr_report_style, header_image_id, enabled, permanently_disabled, created_at, updated_at)
|
||||||
VALUES (?, ?, ?, ?, ?, ?, ?, ?, ?, ?, ?, ?, ?, CURRENT_TIMESTAMP, CURRENT_TIMESTAMP)
|
VALUES (?, ?, ?, ?, ?, ?, ?, ?, ?, ?, ?, ?, ?, ?, CURRENT_TIMESTAMP, CURRENT_TIMESTAMP)
|
||||||
"#,
|
"#,
|
||||||
project_id,
|
project_id,
|
||||||
project.owner,
|
project.owner,
|
||||||
@@ -1070,6 +1076,7 @@ impl Database {
|
|||||||
pr_report_style,
|
pr_report_style,
|
||||||
header_image_id,
|
header_image_id,
|
||||||
project.enabled,
|
project.enabled,
|
||||||
|
project.permanently_disabled,
|
||||||
)
|
)
|
||||||
.execute(&mut *conn)
|
.execute(&mut *conn)
|
||||||
.await?;
|
.await?;
|
||||||
|
|||||||
@@ -250,6 +250,14 @@ pub async fn refresh_project(
|
|||||||
.await
|
.await
|
||||||
.context("Failed to fetch project info")?
|
.context("Failed to fetch project info")?
|
||||||
.with_context(|| format!("Failed to fetch project info for ID {repo_id}"))?;
|
.with_context(|| format!("Failed to fetch project info for ID {repo_id}"))?;
|
||||||
|
if !project_info.project.reports_enabled() {
|
||||||
|
tracing::info!(
|
||||||
|
"Skipping disabled project {}/{}",
|
||||||
|
project_info.project.owner,
|
||||||
|
project_info.project.repo
|
||||||
|
);
|
||||||
|
return Ok(0);
|
||||||
|
}
|
||||||
let client = match client_override {
|
let client = match client_override {
|
||||||
Some(client) => client.clone(),
|
Some(client) => client.clone(),
|
||||||
None => github.client_for(repo_id).await?,
|
None => github.client_for(repo_id).await?,
|
||||||
|
|||||||
@@ -98,6 +98,15 @@ async fn process_workflow_run_push(ctx: &JobContext, job: &ProcessWorkflowRunJob
|
|||||||
tracing::warn!("No project found for repository ID {}", job.repository_id);
|
tracing::warn!("No project found for repository ID {}", job.repository_id);
|
||||||
return Ok(());
|
return Ok(());
|
||||||
};
|
};
|
||||||
|
if !project_info.project.reports_enabled() {
|
||||||
|
tracing::info!(
|
||||||
|
"Skipping disabled project {}/{} for workflow run {}",
|
||||||
|
project_info.project.owner,
|
||||||
|
project_info.project.repo,
|
||||||
|
job.run_id
|
||||||
|
);
|
||||||
|
return Ok(());
|
||||||
|
}
|
||||||
|
|
||||||
// Fetch repository info
|
// Fetch repository info
|
||||||
let client = ctx.github.client_for(job.repository_id.0).await?;
|
let client = ctx.github.client_for(job.repository_id.0).await?;
|
||||||
@@ -189,6 +198,15 @@ async fn process_workflow_run_pull_request(
|
|||||||
tracing::warn!("No project found for repository ID {}", job.repository_id);
|
tracing::warn!("No project found for repository ID {}", job.repository_id);
|
||||||
return Ok(());
|
return Ok(());
|
||||||
};
|
};
|
||||||
|
if !project_info.project.reports_enabled() {
|
||||||
|
tracing::info!(
|
||||||
|
"Skipping disabled project {}/{} for workflow run {}",
|
||||||
|
project_info.project.owner,
|
||||||
|
project_info.project.repo,
|
||||||
|
job.run_id
|
||||||
|
);
|
||||||
|
return Ok(());
|
||||||
|
}
|
||||||
|
|
||||||
if !project_info.project.enable_pr_comments {
|
if !project_info.project.enable_pr_comments {
|
||||||
return Ok(());
|
return Ok(());
|
||||||
|
|||||||
@@ -42,7 +42,7 @@ pub async fn manage(
|
|||||||
.get_projects()
|
.get_projects()
|
||||||
.await?
|
.await?
|
||||||
.into_iter()
|
.into_iter()
|
||||||
.filter(|p| current_user.can_manage_repo(p.project.id))
|
.filter(|p| current_user.can_manage_project(&p.project))
|
||||||
.sorted_by(|a, b| lexicmp::natural_lexical_cmp(&a.project.name(), &b.project.name()))
|
.sorted_by(|a, b| lexicmp::natural_lexical_cmp(&a.project.name(), &b.project.name()))
|
||||||
.collect::<Vec<_>>();
|
.collect::<Vec<_>>();
|
||||||
|
|
||||||
@@ -347,7 +347,7 @@ pub async fn manage_project(
|
|||||||
let Some(info) = state.db.get_project_info(¶ms.owner, ¶ms.repo, None).await? else {
|
let Some(info) = state.db.get_project_info(¶ms.owner, ¶ms.repo, None).await? else {
|
||||||
return Err(AppError::Status(StatusCode::NOT_FOUND));
|
return Err(AppError::Status(StatusCode::NOT_FOUND));
|
||||||
};
|
};
|
||||||
if !current_user.can_manage_repo(info.project.id) {
|
if !current_user.can_manage_project(&info.project) {
|
||||||
return Err(AppError::Status(StatusCode::FORBIDDEN));
|
return Err(AppError::Status(StatusCode::FORBIDDEN));
|
||||||
}
|
}
|
||||||
|
|
||||||
@@ -468,6 +468,15 @@ async fn render_manage_project(
|
|||||||
br;
|
br;
|
||||||
small.muted { "Disabled projects will not be listed, and reports will not be fetched." }
|
small.muted { "Disabled projects will not be listed, and reports will not be fetched." }
|
||||||
}
|
}
|
||||||
|
@if current_user.super_admin {
|
||||||
|
label {
|
||||||
|
input name="permanently_disabled" type="checkbox" role="switch"
|
||||||
|
checked[project_info.project.permanently_disabled];
|
||||||
|
"Permanently disable project"
|
||||||
|
br;
|
||||||
|
small.muted { "Project owners cannot manage permanently disabled projects." }
|
||||||
|
}
|
||||||
|
}
|
||||||
label {
|
label {
|
||||||
"Repository"
|
"Repository"
|
||||||
input type="text" readonly disabled value=(project_info.project.repo_url());
|
input type="text" readonly disabled value=(project_info.project.repo_url());
|
||||||
@@ -592,6 +601,7 @@ pub struct ProjectForm {
|
|||||||
pub header_image: Option<Bytes>,
|
pub header_image: Option<Bytes>,
|
||||||
pub clear_header_image: Option<String>,
|
pub clear_header_image: Option<String>,
|
||||||
pub enabled: Option<String>,
|
pub enabled: Option<String>,
|
||||||
|
pub permanently_disabled: Option<String>,
|
||||||
}
|
}
|
||||||
|
|
||||||
#[derive(Deserialize)]
|
#[derive(Deserialize)]
|
||||||
@@ -610,7 +620,7 @@ pub async fn manage_project_save(
|
|||||||
else {
|
else {
|
||||||
return Err(AppError::Status(StatusCode::NOT_FOUND));
|
return Err(AppError::Status(StatusCode::NOT_FOUND));
|
||||||
};
|
};
|
||||||
if !current_user.can_manage_repo(project_info.project.id) {
|
if !current_user.can_manage_project(&project_info.project) {
|
||||||
return Err(AppError::Status(StatusCode::FORBIDDEN));
|
return Err(AppError::Status(StatusCode::FORBIDDEN));
|
||||||
}
|
}
|
||||||
if !ALL_PLATFORMS.iter().any(|p| p.to_str() == form.platform) {
|
if !ALL_PLATFORMS.iter().any(|p| p.to_str() == form.platform) {
|
||||||
@@ -639,6 +649,11 @@ pub async fn manage_project_save(
|
|||||||
let short_name = form.short_name.trim();
|
let short_name = form.short_name.trim();
|
||||||
let platform = form.platform.trim();
|
let platform = form.platform.trim();
|
||||||
let workflow_id = form.workflow_id.trim();
|
let workflow_id = form.workflow_id.trim();
|
||||||
|
let permanently_disabled = if current_user.super_admin {
|
||||||
|
form.permanently_disabled.is_some_and(|v| v == "on")
|
||||||
|
} else {
|
||||||
|
project_info.project.permanently_disabled
|
||||||
|
};
|
||||||
let project = Project {
|
let project = Project {
|
||||||
id: project_info.project.id,
|
id: project_info.project.id,
|
||||||
owner: project_info.project.owner,
|
owner: project_info.project.owner,
|
||||||
@@ -661,7 +676,8 @@ pub async fn manage_project_save(
|
|||||||
project_info.project.pr_report_style
|
project_info.project.pr_report_style
|
||||||
},
|
},
|
||||||
header_image_id,
|
header_image_id,
|
||||||
enabled: form.enabled.is_some_and(|v| v == "on"),
|
enabled: form.enabled.is_some_and(|v| v == "on") && !permanently_disabled,
|
||||||
|
permanently_disabled,
|
||||||
};
|
};
|
||||||
state.db.update_project(&project).await?;
|
state.db.update_project(&project).await?;
|
||||||
let redirect_url = format!("/{}/{}", params.owner, params.repo);
|
let redirect_url = format!("/{}/{}", params.owner, params.repo);
|
||||||
@@ -677,7 +693,7 @@ pub async fn manage_project_refresh(
|
|||||||
let Some(info) = state.db.get_project_info(¶ms.owner, ¶ms.repo, None).await? else {
|
let Some(info) = state.db.get_project_info(¶ms.owner, ¶ms.repo, None).await? else {
|
||||||
return Err(AppError::Status(StatusCode::NOT_FOUND));
|
return Err(AppError::Status(StatusCode::NOT_FOUND));
|
||||||
};
|
};
|
||||||
if !current_user.can_manage_repo(info.project.id) {
|
if !current_user.can_manage_project(&info.project) {
|
||||||
return Err(AppError::Status(StatusCode::FORBIDDEN));
|
return Err(AppError::Status(StatusCode::FORBIDDEN));
|
||||||
}
|
}
|
||||||
|
|
||||||
@@ -713,7 +729,7 @@ pub async fn delete_commit(
|
|||||||
let Some(info) = state.db.get_project_info(¶ms.owner, ¶ms.repo, None).await? else {
|
let Some(info) = state.db.get_project_info(¶ms.owner, ¶ms.repo, None).await? else {
|
||||||
return Err(AppError::Status(StatusCode::NOT_FOUND));
|
return Err(AppError::Status(StatusCode::NOT_FOUND));
|
||||||
};
|
};
|
||||||
if !current_user.can_manage_repo(info.project.id) {
|
if !current_user.can_manage_project(&info.project) {
|
||||||
return Err(AppError::Status(StatusCode::FORBIDDEN));
|
return Err(AppError::Status(StatusCode::FORBIDDEN));
|
||||||
}
|
}
|
||||||
let num_reports_deleted =
|
let num_reports_deleted =
|
||||||
|
|||||||
@@ -722,7 +722,7 @@ async fn render_report(
|
|||||||
let project_manage_path =
|
let project_manage_path =
|
||||||
format!("/manage/{}/{}", project_info.project.owner, project_info.project.repo);
|
format!("/manage/{}/{}", project_info.project.owner, project_info.project.repo);
|
||||||
let can_manage =
|
let can_manage =
|
||||||
current_user.as_ref().is_some_and(|u| u.can_manage_repo(project_info.project.id));
|
current_user.as_ref().is_some_and(|u| u.can_manage_project(&project_info.project));
|
||||||
let default_category = project_info.project.default_category();
|
let default_category = project_info.project.default_category();
|
||||||
|
|
||||||
let is_default_version = project_info.default_version() == Some(report.version.as_str());
|
let is_default_version = project_info.default_version() == Some(report.version.as_str());
|
||||||
|
|||||||
@@ -0,0 +1 @@
|
|||||||
|
ALTER TABLE projects ADD COLUMN permanently_disabled BOOLEAN NOT NULL DEFAULT FALSE;
|
||||||
Reference in New Issue
Block a user