@@ -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+
3365pub 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
90122pub 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
0 commit comments