Fix moderation issues
This commit is contained in:
		
							parent
							
								
									ebc9fbc88a
								
							
						
					
					
						commit
						5d2e653a3b
					
				
							
								
								
									
										13
									
								
								Cargo.lock
									
									
									
										generated
									
									
									
								
							
							
						
						
									
										13
									
								
								Cargo.lock
									
									
									
										generated
									
									
									
								
							| @ -1894,12 +1894,9 @@ dependencies = [ | ||||
| 
 | ||||
| [[package]] | ||||
| name = "hermit-abi" | ||||
| version = "0.2.6" | ||||
| version = "0.3.9" | ||||
| source = "registry+https://github.com/rust-lang/crates.io-index" | ||||
| checksum = "ee512640fe35acbfb4bb779db6f0d80704c2cacfa2e39b601ef3e3f47d1ae4c7" | ||||
| dependencies = [ | ||||
|  "libc", | ||||
| ] | ||||
| checksum = "d231dfb89cfffdbc30e7fc41579ed6066ad03abda9e567ccafae602b97ec5024" | ||||
| 
 | ||||
| [[package]] | ||||
| name = "hex" | ||||
| @ -3116,11 +3113,11 @@ dependencies = [ | ||||
| 
 | ||||
| [[package]] | ||||
| name = "num_cpus" | ||||
| version = "1.15.0" | ||||
| version = "1.16.0" | ||||
| source = "registry+https://github.com/rust-lang/crates.io-index" | ||||
| checksum = "0fac9e2da13b5eb447a6ce3d392f23a29d8694bff781bf03a16cd9ac8697593b" | ||||
| checksum = "4161fcb6d602d4d2081af7c3a45852d875a03dd337a6bfdd6e06407b61342a43" | ||||
| dependencies = [ | ||||
|  "hermit-abi 0.2.6", | ||||
|  "hermit-abi 0.3.9", | ||||
|  "libc", | ||||
| ] | ||||
| 
 | ||||
|  | ||||
| @ -5,7 +5,7 @@ use rocket::{ | ||||
|     Outcome, | ||||
| }; | ||||
| 
 | ||||
| /// Wrapper around User to use as a request guard on pages reserved to admins.
 | ||||
| /// Wrapper around User to use as a request guard on pages exclusively reserved to admins.
 | ||||
| pub struct Admin(pub User); | ||||
| 
 | ||||
| impl<'a, 'r> FromRequest<'a, 'r> for Admin { | ||||
| @ -21,6 +21,23 @@ impl<'a, 'r> FromRequest<'a, 'r> for Admin { | ||||
|     } | ||||
| } | ||||
| 
 | ||||
| /// Same as `Admin` but it forwards to next guard if the user is not an admin.
 | ||||
| /// It's useful when there are multiple implementations of routes for admin and moderator.
 | ||||
| pub struct InclusiveAdmin(pub User); | ||||
| 
 | ||||
| impl<'a, 'r> FromRequest<'a, 'r> for InclusiveAdmin { | ||||
|     type Error = (); | ||||
| 
 | ||||
|     fn from_request(request: &'a Request<'r>) -> request::Outcome<InclusiveAdmin, ()> { | ||||
|         let user = request.guard::<User>()?; | ||||
|         if user.is_admin() { | ||||
|             Outcome::Success(InclusiveAdmin(user)) | ||||
|         } else { | ||||
|             Outcome::Forward(()) | ||||
|         } | ||||
|     } | ||||
| } | ||||
| 
 | ||||
| /// Same as `Admin` but for moderators.
 | ||||
| pub struct Moderator(pub User); | ||||
| 
 | ||||
|  | ||||
| @ -221,7 +221,8 @@ impl Timeline { | ||||
| 
 | ||||
|     pub fn add_to_all_timelines(conn: &Connection, post: &Post, kind: Kind<'_>) -> Result<()> { | ||||
|         let timelines = timeline_definition::table | ||||
|             .load::<Self>(conn.deref()) | ||||
|             //.load::<Self>(conn.deref())
 | ||||
|             .load::<Self>(conn) | ||||
|             .map_err(Error::from)?; | ||||
| 
 | ||||
|         for t in timelines { | ||||
|  | ||||
| @ -1 +1 @@ | ||||
| nightly-2023-04-14 | ||||
| nightly-2023-11-10 | ||||
|  | ||||
| @ -51,7 +51,7 @@ pub fn index(conn: DbConn, rockets: PlumeRocket) -> Result<Ructe, ErrorPage> { | ||||
| } | ||||
| 
 | ||||
| #[get("/admin")] | ||||
| pub fn admin(_admin: Admin, conn: DbConn, rockets: PlumeRocket) -> Result<Ructe, ErrorPage> { | ||||
| pub fn admin(_admin: InclusiveAdmin, conn: DbConn, rockets: PlumeRocket) -> Result<Ructe, ErrorPage> { | ||||
|     let local_inst = Instance::get_local()?; | ||||
|     Ok(render!(instance::admin( | ||||
|         &(&conn, &rockets).to_context(), | ||||
|  | ||||
| @ -87,6 +87,8 @@ | ||||
|                 <a href="@uri!(instance::privacy)">@i18n!(ctx.1, "Privacy policy")</a> | ||||
|                 @if ctx.2.clone().map(|u| u.is_admin()).unwrap_or(false) { | ||||
|                     <a href="@uri!(instance::admin)">@i18n!(ctx.1, "Administration")</a> | ||||
|                 } else if ctx.2.clone().map(|u| u.is_moderator()).unwrap_or(false) { | ||||
|                     <a href="@uri!(instance::admin_mod)">@i18n!(ctx.1, "Moderation")</a> | ||||
|                 } | ||||
|             </div> | ||||
|             <div> | ||||
|  | ||||
| @ -1,6 +1,6 @@ | ||||
| @use plume_models::instance::Instance; | ||||
| @use validator::ValidationErrors; | ||||
| @use crate::templates::base; | ||||
| @use crate::templates::{base, instance::admin_header}; | ||||
| @use crate::template_utils::*; | ||||
| @use crate::routes::instance::InstanceSettingsForm; | ||||
| @use crate::routes::*; | ||||
| @ -8,15 +8,7 @@ | ||||
| @(ctx: BaseContext, instance: Instance, form: InstanceSettingsForm, errors: ValidationErrors) | ||||
| 
 | ||||
| @:base(ctx, i18n!(ctx.1, "Administration of {0}"; instance.name.clone()), {}, {}, { | ||||
|   <h1>@i18n!(ctx.1, "Administration")</h1> | ||||
| 
 | ||||
|   @tabs(&[ | ||||
|     (&uri!(instance::admin).to_string(), i18n!(ctx.1, "Configuration"), true), | ||||
|     (&uri!(instance::admin_instances: page = _).to_string(), i18n!(ctx.1, "Instances"), false), | ||||
|     (&uri!(instance::admin_users: page = _).to_string(), i18n!(ctx.1, "Users"), false), | ||||
|     (&uri!(instance::admin_email_blocklist: page=_).to_string(), i18n!(ctx.1, "Email blocklist"), false) | ||||
|   ]) | ||||
| 
 | ||||
|   @:admin_header(ctx, "Administration", 1) | ||||
|   <form method="post" action="@uri!(instance::update_settings)"> | ||||
|     @(Input::new("name", i18n!(ctx.1, "Name")) | ||||
|         .default(&form.name) | ||||
|  | ||||
							
								
								
									
										22
									
								
								templates/instance/admin_header.rs.html
									
									
									
									
									
										Normal file
									
								
							
							
						
						
									
										22
									
								
								templates/instance/admin_header.rs.html
									
									
									
									
									
										Normal file
									
								
							| @ -0,0 +1,22 @@ | ||||
| @use crate::template_utils::*; | ||||
| @use crate::routes::*; | ||||
| 
 | ||||
| @(ctx: BaseContext, title: &str, selected_tab: u8) | ||||
| 
 | ||||
| <h1>@i18n!(ctx.1, title)</h1> | ||||
| 
 | ||||
| @if ctx.2.clone().map(|u| u.is_admin()).unwrap_or(false) { | ||||
|     @tabs(&[ | ||||
|         (&uri!(instance::admin).to_string(), i18n!(ctx.1, "Configuration"), selected_tab == 1), | ||||
|         (&uri!(instance::admin_instances: page = _).to_string(), i18n!(ctx.1, "Instances"), selected_tab == 2), | ||||
|         (&uri!(instance::admin_users: page = _).to_string(), i18n!(ctx.1, "Users"), selected_tab == 3), | ||||
|         (&uri!(instance::admin_email_blocklist: page=_).to_string(), i18n!(ctx.1, "Email blocklist"), selected_tab == 4) | ||||
|     ]) | ||||
| } else { | ||||
|     @tabs(&[ | ||||
|         (&uri!(instance::admin_instances: page = _).to_string(), i18n!(ctx.1, "Instances"), selected_tab == 2), | ||||
|         (&uri!(instance::admin_users: page = _).to_string(), i18n!(ctx.1, "Users"), selected_tab == 3), | ||||
|         (&uri!(instance::admin_email_blocklist: page=_).to_string(), i18n!(ctx.1, "Email blocklist"), selected_tab == 4) | ||||
|     ]) | ||||
| } | ||||
| 
 | ||||
| @ -1,15 +1,8 @@ | ||||
| @use crate::templates::base; | ||||
| @use crate::templates::{base, instance::admin_header}; | ||||
| @use crate::template_utils::*; | ||||
| @use crate::routes::*; | ||||
| 
 | ||||
| @(ctx: BaseContext) | ||||
| 
 | ||||
| @:base(ctx, i18n!(ctx.1, "Moderation"), {}, {}, { | ||||
|   <h1>@i18n!(ctx.1, "Moderation")</h1> | ||||
| 
 | ||||
|   @tabs(&[ | ||||
|     (&uri!(instance::admin).to_string(), i18n!(ctx.1, "Home"), true), | ||||
|     (&uri!(instance::admin_instances: page = _).to_string(), i18n!(ctx.1, "Instances"), false), | ||||
|     (&uri!(instance::admin_users: page = _).to_string(), i18n!(ctx.1, "Users"), false), | ||||
|   ]) | ||||
|   @:admin_header(ctx, "Moderation", 0) | ||||
| }) | ||||
|  | ||||
| @ -1,17 +1,11 @@ | ||||
| @use plume_models::blocklisted_emails::BlocklistedEmail; | ||||
| @use crate::templates::base; | ||||
| @use crate::templates::{base, instance::admin_header}; | ||||
| @use crate::template_utils::*; | ||||
| @use crate::routes::*; | ||||
| 
 | ||||
| @(ctx:BaseContext, emails: Vec<BlocklistedEmail>, page:i32, n_pages:i32) | ||||
|     @:base(ctx, i18n!(ctx.1, "Blocklisted Emails"), {}, {}, { | ||||
|     <h1>@i18n!(ctx.1,"Blocklisted Emails")</h1> | ||||
|     @tabs(&[ | ||||
|         (&uri!(instance::admin).to_string(), i18n!(ctx.1, "Configuration"), false), | ||||
|         (&uri!(instance::admin_instances: page = _).to_string(), i18n!(ctx.1, "Instances"), false), | ||||
|         (&uri!(instance::admin_users: page = _).to_string(), i18n!(ctx.1, "Users"), false), | ||||
|         (&uri!(instance::admin_email_blocklist:page=_).to_string(), i18n!(ctx.1, "Email blocklist"), true), | ||||
|     ]) | ||||
| @:base(ctx, i18n!(ctx.1, "Blocklisted Emails"), {}, {}, { | ||||
|     @:admin_header(ctx, "Blocklisted Emails", 4) | ||||
|     <form method="post" action="@uri!(instance::add_email_blocklist)"> | ||||
|         @(Input::new("email_address", i18n!(ctx.1, "Email address")) | ||||
|         .details(i18n!(ctx.1, "The email address you wish to block. In order to block domains, you can use globbing syntax, for example '*@example.com' blocks all addresses from example.com")) | ||||
|  | ||||
| @ -1,19 +1,12 @@ | ||||
| @use plume_models::instance::Instance; | ||||
| @use crate::templates::base; | ||||
| @use crate::templates::{base, instance::admin_header}; | ||||
| @use crate::template_utils::*; | ||||
| @use crate::routes::*; | ||||
| 
 | ||||
| @(ctx: BaseContext, instance: Instance, instances: Vec<Instance>, page: i32, n_pages: i32) | ||||
| 
 | ||||
| @:base(ctx, i18n!(ctx.1, "Administration of {0}"; instance.name), {}, {}, { | ||||
|     <h1>@i18n!(ctx.1, "Instances")</h1> | ||||
| 
 | ||||
|     @tabs(&[ | ||||
|     (&uri!(instance::admin).to_string(), i18n!(ctx.1, "Configuration"), false), | ||||
|     (&uri!(instance::admin_instances: page = _).to_string(), i18n!(ctx.1, "Instances"), true), | ||||
|     (&uri!(instance::admin_users: page = _).to_string(), i18n!(ctx.1, "Users"), false), | ||||
|     (&uri!(instance::admin_email_blocklist:page=_).to_string(), i18n!(ctx.1, "Email blocklist"), false), | ||||
|     ]) | ||||
|     @:admin_header(ctx, "Instances", 2)) | ||||
| 
 | ||||
|     <div class="list"> | ||||
|         @for instance in instances { | ||||
|  | ||||
| @ -1,19 +1,12 @@ | ||||
| @use plume_models::users::User; | ||||
| @use crate::templates::base; | ||||
| @use crate::templates::{base, instance::admin_header}; | ||||
| @use crate::template_utils::*; | ||||
| @use crate::routes::*; | ||||
| 
 | ||||
| @(ctx: BaseContext, users: Vec<User>, user: Option<&str>, page: i32, n_pages: i32) | ||||
| 
 | ||||
| @:base(ctx, i18n!(ctx.1, "Users"), {}, {}, { | ||||
|     <h1>@i18n!(ctx.1, "Users")</h1> | ||||
| 
 | ||||
|     @tabs(&[ | ||||
|         (&uri!(instance::admin).to_string(), i18n!(ctx.1, "Configuration"), false), | ||||
|         (&uri!(instance::admin_instances: page = _).to_string(), i18n!(ctx.1, "Instances"), false), | ||||
|         (&uri!(instance::admin_users: page = _).to_string(), i18n!(ctx.1, "Users"), true), | ||||
|         (&uri!(instance::admin_email_blocklist: page=_).to_string(), i18n!(ctx.1, "Email blocklist"), false) | ||||
|     ]) | ||||
|     @:admin_header(ctx, "Users", 3)) | ||||
| 
 | ||||
|     <form method="get" action="@uri!(instance::admin_search_users: page = _, user = user.unwrap_or_default())"> | ||||
|         <header> | ||||
|  | ||||
		Loading…
	
	
			
			x
			
			
		
	
		Reference in New Issue
	
	Block a user