Skip to content

Commit 0ec5903

Browse files
authored
Allow readonly tags in mod.json if mod has it serverside (#50)
* fix(tags): allow readonly tags on mod update if mod has the tag * chore: sqlx prepare
1 parent b417d2d commit 0ec5903

File tree

4 files changed

+93
-20
lines changed

4 files changed

+93
-20
lines changed

.sqlx/query-01959e9a4fdc1c6b0d9dbeff80c79a58e0bae2d79af6c2b9e53ead7d9b6e214d.json

Lines changed: 40 additions & 0 deletions
Some generated files are not rendered by default. Learn more about customizing how changed files appear on GitHub.

src/database/repository/mod_tags.rs

Lines changed: 50 additions & 17 deletions
Original file line numberDiff line numberDiff line change
@@ -30,6 +30,38 @@ pub async fn get_all_writable(conn: &mut PgConnection) -> Result<Vec<Tag>, ApiEr
3030
Ok(tags)
3131
}
3232

33+
pub async fn get_allowed_for_mod(id: &str, conn: &mut PgConnection) -> Result<Vec<Tag>, ApiError> {
34+
let mut writable = get_all_writable(&mut *conn).await?;
35+
let allowed_readonly = sqlx::query!(
36+
"SELECT DISTINCT
37+
t.id,
38+
t.name,
39+
t.display_name,
40+
t.is_readonly
41+
FROM mod_tags t
42+
INNER JOIN mods_mod_tags mmt ON mmt.tag_id = t.id
43+
WHERE t.is_readonly = true
44+
AND mmt.mod_id = $1",
45+
id
46+
)
47+
.fetch_all(&mut *conn)
48+
.await
49+
.inspect_err(|e| log::error!("mod_tags::get_allowed_for_mod failed: {e}"))
50+
.or(Err(ApiError::DbError))?
51+
.into_iter()
52+
.map(|i| Tag {
53+
id: i.id,
54+
display_name: i.display_name.unwrap_or(i.name.clone()),
55+
name: i.name,
56+
is_readonly: i.is_readonly,
57+
})
58+
.collect::<Vec<Tag>>();
59+
60+
writable.extend(allowed_readonly);
61+
62+
return Ok(writable);
63+
}
64+
3365
pub async fn get_all(conn: &mut PgConnection) -> Result<Vec<Tag>, ApiError> {
3466
let tags = sqlx::query!(
3567
"SELECT
@@ -39,20 +71,20 @@ pub async fn get_all(conn: &mut PgConnection) -> Result<Vec<Tag>, ApiError> {
3971
is_readonly
4072
FROM mod_tags"
4173
)
42-
.fetch_all(&mut *conn)
43-
.await
44-
.map_err(|e| {
45-
log::error!("mod_tags::get_all failed: {}", e);
46-
ApiError::DbError
47-
})?
48-
.into_iter()
49-
.map(|i| Tag {
50-
id: i.id,
51-
display_name: i.display_name.unwrap_or(i.name.clone()),
52-
name: i.name,
53-
is_readonly: i.is_readonly,
54-
})
55-
.collect::<Vec<Tag>>();
74+
.fetch_all(&mut *conn)
75+
.await
76+
.map_err(|e| {
77+
log::error!("mod_tags::get_all failed: {}", e);
78+
ApiError::DbError
79+
})?
80+
.into_iter()
81+
.map(|i| Tag {
82+
id: i.id,
83+
display_name: i.display_name.unwrap_or_else(|| i.name.clone()),
84+
name: i.name,
85+
is_readonly: i.is_readonly,
86+
})
87+
.collect::<Vec<Tag>>();
5688

5789
Ok(tags)
5890
}
@@ -89,13 +121,14 @@ pub async fn get_for_mod(id: &str, conn: &mut PgConnection) -> Result<Vec<Tag>,
89121

90122
pub async fn parse_tag_list(
91123
tags: &[String],
124+
mod_id: &str,
92125
conn: &mut PgConnection,
93126
) -> Result<Vec<Tag>, ApiError> {
94127
if tags.is_empty() {
95128
return Ok(vec![]);
96129
}
97130

98-
let db_tags = get_all_writable(conn).await?;
131+
let db_tags = get_allowed_for_mod(mod_id, conn).await?;
99132

100133
let mut ret = Vec::new();
101134
for tag in tags {
@@ -126,13 +159,13 @@ pub async fn update_for_mod(
126159

127160
let insertable = tags
128161
.iter()
129-
.filter(|t| !existing.iter().any(|e| e.id == t.id))
162+
.filter(|t| !t.is_readonly && !existing.iter().any(|e| e.id == t.id))
130163
.map(|x| x.id)
131164
.collect::<Vec<_>>();
132165

133166
let deletable = existing
134167
.iter()
135-
.filter(|e| !e.is_readonly && !tags.iter().any(|t| e.id == t.id))
168+
.filter(|i| !i.is_readonly && !tags.iter().any(|j| i.id == j.id))
136169
.map(|x| x.id)
137170
.collect::<Vec<_>>();
138171

src/endpoints/mod_versions.rs

Lines changed: 2 additions & 2 deletions
Original file line numberDiff line numberDiff line change
@@ -371,7 +371,7 @@ pub async fn create_version(
371371
}
372372
if let Some(tags) = &json.tags {
373373
if !tags.is_empty() {
374-
let tags = mod_tags::parse_tag_list(tags, &mut tx).await?;
374+
let tags = mod_tags::parse_tag_list(tags, &the_mod.id, &mut tx).await?;
375375
mod_tags::update_for_mod(&the_mod.id, &tags, &mut tx).await?;
376376
}
377377
}
@@ -490,7 +490,7 @@ pub async fn update_version(
490490

491491
// Update tags with data from mod.json
492492
let tags = if let Some(tags) = &json.tags {
493-
mod_tags::parse_tag_list(tags, &mut tx).await?
493+
mod_tags::parse_tag_list(tags, &the_mod.id, &mut tx).await?
494494
} else {
495495
vec![]
496496
};

src/endpoints/mods.rs

Lines changed: 1 addition & 1 deletion
Original file line numberDiff line numberDiff line change
@@ -198,7 +198,7 @@ pub async fn create(
198198
}
199199

200200
if let Some(tags) = &json.tags {
201-
let tag_list = mod_tags::parse_tag_list(tags, &mut tx).await?;
201+
let tag_list = mod_tags::parse_tag_list(tags, &the_mod.id, &mut tx).await?;
202202
mod_tags::update_for_mod(&the_mod.id, &tag_list, &mut tx).await?;
203203
}
204204
if let Some(l) = json.links.clone() {

0 commit comments

Comments
 (0)