feat(server): add config for enabling public signup view
							parent
							
								
									5017bfb710
								
							
						
					
					
						commit
						69e84b4266
					
				|  | @ -8,6 +8,7 @@ and this project adheres to [Semantic Versioning](https://semver.org/spec/v2.0.0 | |||
| ## [Unreleased](https://git.rustybever.be/Chewing_Bever/otter) | ||||
| 
 | ||||
| * CLI command to add new users | ||||
| * Added public sign-up page (disabled by default) | ||||
| 
 | ||||
| ## [0.2.1](https://git.rustybever.be/Chewing_Bever/otter/src/tag/0.2.1) | ||||
| 
 | ||||
|  |  | |||
|  | @ -1,6 +1,8 @@ | |||
| data_dir = "./data" | ||||
| log_level = "debug" | ||||
| 
 | ||||
| allow_public_signup = true | ||||
| 
 | ||||
| [net] | ||||
| type = "tcp" | ||||
| domain = "127.0.0.1" | ||||
|  |  | |||
|  | @ -23,6 +23,7 @@ pub fn serve(config: &crate::config::Config) -> Result<(), CliError> { | |||
|     let ctx = server::Context { | ||||
|         store, | ||||
|         tera: Arc::new(tera), | ||||
|         config: config.clone(), | ||||
|     }; | ||||
|     let app = server::app(ctx.clone()); | ||||
| 
 | ||||
|  |  | |||
|  | @ -23,7 +23,7 @@ impl From<LogLevel> for tracing::Level { | |||
|     } | ||||
| } | ||||
| 
 | ||||
| #[derive(Serialize, Deserialize)] | ||||
| #[derive(Serialize, Deserialize, Clone)] | ||||
| #[serde(rename_all = "lowercase")] | ||||
| #[serde(tag = "type")] | ||||
| pub enum NetConfig { | ||||
|  | @ -31,12 +31,13 @@ pub enum NetConfig { | |||
|     Unix { path: PathBuf }, | ||||
| } | ||||
| 
 | ||||
| #[derive(Serialize, Deserialize)] | ||||
| #[derive(Serialize, Deserialize, Clone)] | ||||
| pub struct Config { | ||||
|     pub net: NetConfig, | ||||
|     pub data_dir: PathBuf, | ||||
|     pub session_cleanup_interval: u64, | ||||
|     pub log_level: LogLevel, | ||||
|     pub allow_public_signup: bool, | ||||
| } | ||||
| 
 | ||||
| impl Default for Config { | ||||
|  | @ -50,6 +51,7 @@ impl Default for Config { | |||
|             // Once per day
 | ||||
|             session_cleanup_interval: 60 * 60 * 24, | ||||
|             log_level: LogLevel::Warn, | ||||
|             allow_public_signup: false, | ||||
|         } | ||||
|     } | ||||
| } | ||||
|  |  | |||
|  | @ -20,6 +20,7 @@ use tower_http::trace::TraceLayer; | |||
| pub struct Context { | ||||
|     pub store: ::gpodder::GpodderRepository, | ||||
|     pub tera: Arc<tera::Tera>, | ||||
|     pub config: crate::config::Config, | ||||
| } | ||||
| 
 | ||||
| pub fn app(ctx: Context) -> Router { | ||||
|  |  | |||
|  | @ -21,7 +21,7 @@ use crate::{ | |||
| }; | ||||
| 
 | ||||
| pub fn router(ctx: Context) -> Router<Context> { | ||||
|     Router::new() | ||||
|     let mut router = Router::new() | ||||
|         // .layer(middleware::from_fn_with_state(
 | ||||
|         //     ctx.clone(),
 | ||||
|         //     auth_web_middleware,
 | ||||
|  | @ -29,8 +29,15 @@ pub fn router(ctx: Context) -> Router<Context> { | |||
|         // Login route needs to be handled differently, as the middleware turns it into a redirect
 | ||||
|         // loop
 | ||||
|         .route("/login", get(get_login).post(post_login)) | ||||
|         .route("/logout", post(post_logout)) | ||||
|         .route("/signup", get(get_signup).post(post_signup)) | ||||
|         .route("/logout", post(post_logout)); | ||||
| 
 | ||||
|     // If public signups aren't allowed, we don't even register the route to prevent any dumb
 | ||||
|     // security mistakes
 | ||||
|     if ctx.config.allow_public_signup { | ||||
|         router = router.route("/signup", get(get_signup).post(post_signup)) | ||||
|     } | ||||
| 
 | ||||
|     router | ||||
| } | ||||
| 
 | ||||
| /// Middleware that authenticates the current user via the session token. If the credentials are
 | ||||
|  | @ -87,10 +94,12 @@ async fn get_login(State(ctx): State<Context>, headers: HeaderMap, jar: CookieJa | |||
|     { | ||||
|         Redirect::to("/").into_response() | ||||
|     } else { | ||||
|         View::Login | ||||
|             .page(&headers) | ||||
|             .response(&ctx.tera) | ||||
|             .into_response() | ||||
|         View::Login { | ||||
|             signup_note: ctx.config.allow_public_signup, | ||||
|         } | ||||
|         .page(&headers) | ||||
|         .response(&ctx.tera) | ||||
|         .into_response() | ||||
|     } | ||||
| } | ||||
| 
 | ||||
|  |  | |||
|  | @ -78,7 +78,7 @@ pub fn initialize_tera() -> tera::Result<tera::Tera> { | |||
|             include_str!("templates/views/index.html"), | ||||
|         ), | ||||
|         ( | ||||
|             View::Login.template(), | ||||
|             View::Login { signup_note: false }.template(), | ||||
|             include_str!("templates/views/login.html"), | ||||
|         ), | ||||
|         ( | ||||
|  |  | |||
|  | @ -6,4 +6,8 @@ | |||
|         <input type="password" id="password" name="password"> | ||||
|         <input type="submit" value="Login"> | ||||
|     </form> | ||||
| 
 | ||||
|     {% if signup_note %} | ||||
|     <p>Don't have an account yet? <a hx-get="/signup" hx-target="#inner" hx-push-url="/signup">Create one here</a>!</p> | ||||
|     {% endif %} | ||||
| </article> | ||||
|  |  | |||
|  | @ -5,7 +5,9 @@ use super::{Query, Template}; | |||
| 
 | ||||
| pub enum View { | ||||
|     Index, | ||||
|     Login, | ||||
|     Login { | ||||
|         signup_note: bool, | ||||
|     }, | ||||
|     Sessions(Vec<gpodder::Session>, i64, Option<Query>), | ||||
|     Users(Vec<gpodder::User>, i64, Option<Query>), | ||||
|     Signup { | ||||
|  | @ -32,7 +34,7 @@ impl Template for View { | |||
|     fn template(&self) -> &'static str { | ||||
|         match self { | ||||
|             Self::Index => "views/index.html", | ||||
|             Self::Login => "views/login.html", | ||||
|             Self::Login { .. } => "views/login.html", | ||||
|             Self::Sessions(..) => "views/sessions.html", | ||||
|             Self::Users(..) => "views/users.html", | ||||
|             Self::Signup { .. } => "views/signup.html", | ||||
|  | @ -76,6 +78,9 @@ impl Template for View { | |||
|                 ctx.insert("username_available", &username_available); | ||||
|                 ctx.insert("passwords_match", &passwords_match); | ||||
|             } | ||||
|             Self::Login { signup_note } => { | ||||
|                 ctx.insert("signup_note", &signup_note); | ||||
|             } | ||||
|             _ => {} | ||||
|         }; | ||||
| 
 | ||||
|  |  | |||
		Loading…
	
		Reference in New Issue