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