mirror of
https://github.com/Nutomic/ibis.git
synced 2024-11-26 12:11:10 +00:00
wip
This commit is contained in:
parent
7772585ffc
commit
72d123aab1
8 changed files with 55 additions and 40 deletions
|
@ -64,7 +64,7 @@ axum-extra = { version = "0.9.4", features = ["cookie"], optional = true }
|
||||||
leptos = "0.6.15"
|
leptos = "0.6.15"
|
||||||
leptos_meta = "0.6.15"
|
leptos_meta = "0.6.15"
|
||||||
leptos_router = "0.6.15"
|
leptos_router = "0.6.15"
|
||||||
leptos_axum = { version = "0.6.15", optional = true }
|
leptos_axum = { version = "0.6.15", features = ["wasm"], optional = true }
|
||||||
bcrypt = "0.15.1"
|
bcrypt = "0.15.1"
|
||||||
chrono = { version = "0.4.38", features = ["serde"] }
|
chrono = { version = "0.4.38", features = ["serde"] }
|
||||||
diesel = { version = "2.2.4", features = [
|
diesel = { version = "2.2.4", features = [
|
||||||
|
|
|
@ -68,7 +68,7 @@ pub(in crate::backend::api) async fn create_article(
|
||||||
instance_id: local_instance.id,
|
instance_id: local_instance.id,
|
||||||
local: true,
|
local: true,
|
||||||
protected: false,
|
protected: false,
|
||||||
approved: !data.config.article_approval,
|
approved: !data.config.config.article_approval,
|
||||||
};
|
};
|
||||||
let article = DbArticle::create(form, &data)?;
|
let article = DbArticle::create(form, &data)?;
|
||||||
|
|
||||||
|
@ -214,7 +214,7 @@ pub(in crate::backend::api) async fn fork_article(
|
||||||
instance_id: local_instance.id,
|
instance_id: local_instance.id,
|
||||||
local: true,
|
local: true,
|
||||||
protected: false,
|
protected: false,
|
||||||
approved: !data.config.article_approval,
|
approved: !data.config.config.article_approval,
|
||||||
};
|
};
|
||||||
let article = DbArticle::create(form, &data)?;
|
let article = DbArticle::create(form, &data)?;
|
||||||
|
|
||||||
|
|
|
@ -12,20 +12,12 @@ use crate::{
|
||||||
search_article,
|
search_article,
|
||||||
},
|
},
|
||||||
instance::{follow_instance, get_instance, resolve_instance},
|
instance::{follow_instance, get_instance, resolve_instance},
|
||||||
user::{
|
user::{get_user, login_user, logout_user, register_user, validate, AUTH_COOKIE},
|
||||||
get_user,
|
|
||||||
login_user,
|
|
||||||
logout_user,
|
|
||||||
my_profile,
|
|
||||||
register_user,
|
|
||||||
validate,
|
|
||||||
AUTH_COOKIE,
|
|
||||||
},
|
|
||||||
},
|
},
|
||||||
database::IbisData,
|
database::IbisData,
|
||||||
error::MyResult,
|
error::MyResult,
|
||||||
},
|
},
|
||||||
common::LocalUserView,
|
common::{LocalUserView, SiteView},
|
||||||
};
|
};
|
||||||
use activitypub_federation::config::Data;
|
use activitypub_federation::config::Data;
|
||||||
use anyhow::anyhow;
|
use anyhow::anyhow;
|
||||||
|
@ -36,9 +28,11 @@ use axum::{
|
||||||
middleware::{self, Next},
|
middleware::{self, Next},
|
||||||
response::Response,
|
response::Response,
|
||||||
routing::{get, post},
|
routing::{get, post},
|
||||||
|
Json,
|
||||||
Router,
|
Router,
|
||||||
};
|
};
|
||||||
use axum_extra::extract::CookieJar;
|
use axum_extra::extract::CookieJar;
|
||||||
|
use axum_macros::debug_handler;
|
||||||
use instance::list_remote_instances;
|
use instance::list_remote_instances;
|
||||||
use user::{count_notifications, list_notifications};
|
use user::{count_notifications, list_notifications};
|
||||||
|
|
||||||
|
@ -67,8 +61,8 @@ pub fn api_routes() -> Router<()> {
|
||||||
.route("/user/notifications/count", get(count_notifications))
|
.route("/user/notifications/count", get(count_notifications))
|
||||||
.route("/account/register", post(register_user))
|
.route("/account/register", post(register_user))
|
||||||
.route("/account/login", post(login_user))
|
.route("/account/login", post(login_user))
|
||||||
.route("/account/my_profile", get(my_profile))
|
|
||||||
.route("/account/logout", get(logout_user))
|
.route("/account/logout", get(logout_user))
|
||||||
|
.route("/site", get(site_view))
|
||||||
.route_layer(middleware::from_fn(auth))
|
.route_layer(middleware::from_fn(auth))
|
||||||
}
|
}
|
||||||
|
|
||||||
|
@ -93,3 +87,20 @@ fn check_is_admin(user: &LocalUserView) -> MyResult<()> {
|
||||||
}
|
}
|
||||||
Ok(())
|
Ok(())
|
||||||
}
|
}
|
||||||
|
|
||||||
|
#[debug_handler]
|
||||||
|
pub(in crate::backend::api) async fn site_view(
|
||||||
|
data: Data<IbisData>,
|
||||||
|
jar: CookieJar,
|
||||||
|
) -> MyResult<Json<SiteView>> {
|
||||||
|
let jwt = jar.get(AUTH_COOKIE).map(|c| c.value());
|
||||||
|
let my_profile = if let Some(jwt) = jwt {
|
||||||
|
Some(validate(jwt, &data).await?)
|
||||||
|
} else {
|
||||||
|
None
|
||||||
|
};
|
||||||
|
Ok(Json(SiteView {
|
||||||
|
my_profile,
|
||||||
|
config: data.config.config.clone(),
|
||||||
|
}))
|
||||||
|
}
|
||||||
|
|
|
@ -77,7 +77,7 @@ pub(in crate::backend::api) async fn register_user(
|
||||||
jar: CookieJar,
|
jar: CookieJar,
|
||||||
Form(form): Form<RegisterUserForm>,
|
Form(form): Form<RegisterUserForm>,
|
||||||
) -> MyResult<(CookieJar, Json<LocalUserView>)> {
|
) -> MyResult<(CookieJar, Json<LocalUserView>)> {
|
||||||
if !data.config.registration_open {
|
if !data.config.config.registration_open {
|
||||||
return Err(anyhow!("Registration is closed").into());
|
return Err(anyhow!("Registration is closed").into());
|
||||||
}
|
}
|
||||||
let user = DbPerson::create_local(form.username, form.password, false, &data)?;
|
let user = DbPerson::create_local(form.username, form.password, false, &data)?;
|
||||||
|
@ -122,19 +122,6 @@ fn create_cookie(jwt: String, data: &Data<IbisData>) -> Cookie<'static> {
|
||||||
.build()
|
.build()
|
||||||
}
|
}
|
||||||
|
|
||||||
#[debug_handler]
|
|
||||||
pub(in crate::backend::api) async fn my_profile(
|
|
||||||
data: Data<IbisData>,
|
|
||||||
jar: CookieJar,
|
|
||||||
) -> MyResult<Json<LocalUserView>> {
|
|
||||||
let jwt = jar.get(AUTH_COOKIE).map(|c| c.value());
|
|
||||||
if let Some(jwt) = jwt {
|
|
||||||
Ok(Json(validate(jwt, &data).await?))
|
|
||||||
} else {
|
|
||||||
Err(anyhow!("invalid/missing auth").into())
|
|
||||||
}
|
|
||||||
}
|
|
||||||
|
|
||||||
#[debug_handler]
|
#[debug_handler]
|
||||||
pub(in crate::backend::api) async fn logout_user(
|
pub(in crate::backend::api) async fn logout_user(
|
||||||
data: Data<IbisData>,
|
data: Data<IbisData>,
|
||||||
|
|
|
@ -1,4 +1,4 @@
|
||||||
use crate::backend::error::MyResult;
|
use crate::{backend::error::MyResult, common::SharedConfig};
|
||||||
use config::Config;
|
use config::Config;
|
||||||
use doku::Document;
|
use doku::Document;
|
||||||
use serde::Deserialize;
|
use serde::Deserialize;
|
||||||
|
@ -10,17 +10,10 @@ use smart_default::SmartDefault;
|
||||||
pub struct IbisConfig {
|
pub struct IbisConfig {
|
||||||
/// Details about the PostgreSQL database connection
|
/// Details about the PostgreSQL database connection
|
||||||
pub database: IbisConfigDatabase,
|
pub database: IbisConfigDatabase,
|
||||||
/// Whether users can create new accounts
|
|
||||||
#[default = true]
|
|
||||||
#[doku(example = "true")]
|
|
||||||
pub registration_open: bool,
|
|
||||||
/// Whether admins need to approve new articles
|
|
||||||
#[default = false]
|
|
||||||
#[doku(example = "false")]
|
|
||||||
pub article_approval: bool,
|
|
||||||
/// Details of the initial admin account
|
/// Details of the initial admin account
|
||||||
pub setup: IbisConfigSetup,
|
pub setup: IbisConfigSetup,
|
||||||
pub federation: IbisConfigFederation,
|
pub federation: IbisConfigFederation,
|
||||||
|
pub config: SharedConfig,
|
||||||
}
|
}
|
||||||
|
|
||||||
impl IbisConfig {
|
impl IbisConfig {
|
||||||
|
|
|
@ -86,7 +86,6 @@ impl DbInstance {
|
||||||
Ok(InstanceView {
|
Ok(InstanceView {
|
||||||
instance,
|
instance,
|
||||||
followers,
|
followers,
|
||||||
registration_open: data.config.registration_open,
|
|
||||||
})
|
})
|
||||||
}
|
}
|
||||||
|
|
||||||
|
|
|
@ -34,7 +34,7 @@ async fn node_info(data: Data<IbisData>) -> MyResult<Json<NodeInfo>> {
|
||||||
version: env!("CARGO_PKG_VERSION").to_string(),
|
version: env!("CARGO_PKG_VERSION").to_string(),
|
||||||
},
|
},
|
||||||
protocols: vec!["activitypub".to_string()],
|
protocols: vec!["activitypub".to_string()],
|
||||||
open_registrations: data.config.registration_open,
|
open_registrations: data.config.config.registration_open,
|
||||||
}))
|
}))
|
||||||
}
|
}
|
||||||
|
|
||||||
|
|
|
@ -6,6 +6,7 @@ use chrono::{DateTime, Utc};
|
||||||
use newtypes::{ArticleId, ConflictId, EditId, InstanceId, PersonId};
|
use newtypes::{ArticleId, ConflictId, EditId, InstanceId, PersonId};
|
||||||
use serde::{Deserialize, Serialize};
|
use serde::{Deserialize, Serialize};
|
||||||
use sha2::{Digest, Sha256};
|
use sha2::{Digest, Sha256};
|
||||||
|
use smart_default::SmartDefault;
|
||||||
use url::Url;
|
use url::Url;
|
||||||
use uuid::Uuid;
|
use uuid::Uuid;
|
||||||
#[cfg(feature = "ssr")]
|
#[cfg(feature = "ssr")]
|
||||||
|
@ -17,6 +18,7 @@ use {
|
||||||
},
|
},
|
||||||
activitypub_federation::fetch::{collection_id::CollectionId, object_id::ObjectId},
|
activitypub_federation::fetch::{collection_id::CollectionId, object_id::ObjectId},
|
||||||
diesel::{Identifiable, Queryable, Selectable},
|
diesel::{Identifiable, Queryable, Selectable},
|
||||||
|
doku::Document,
|
||||||
};
|
};
|
||||||
|
|
||||||
pub const MAIN_PAGE_NAME: &str = "Main_Page";
|
pub const MAIN_PAGE_NAME: &str = "Main_Page";
|
||||||
|
@ -133,6 +135,30 @@ pub struct LoginUserForm {
|
||||||
pub password: String,
|
pub password: String,
|
||||||
}
|
}
|
||||||
|
|
||||||
|
#[derive(Clone, Debug, Serialize, Deserialize, PartialEq, Eq, SmartDefault)]
|
||||||
|
#[serde(default)]
|
||||||
|
#[serde(deny_unknown_fields)]
|
||||||
|
#[cfg_attr(feature = "ssr", derive(Queryable, Document))]
|
||||||
|
#[cfg_attr(feature = "ssr", diesel(check_for_backend(diesel::pg::Pg)))]
|
||||||
|
pub struct SharedConfig {
|
||||||
|
/// Whether users can create new accounts
|
||||||
|
#[default = true]
|
||||||
|
#[cfg_attr(feature = "ssr", doku(example = "true"))]
|
||||||
|
pub registration_open: bool,
|
||||||
|
/// Whether admins need to approve new articles
|
||||||
|
#[default = false]
|
||||||
|
#[cfg_attr(feature = "ssr", doku(example = "false"))]
|
||||||
|
pub article_approval: bool,
|
||||||
|
}
|
||||||
|
|
||||||
|
#[derive(Clone, Debug, Serialize, Deserialize, PartialEq)]
|
||||||
|
#[cfg_attr(feature = "ssr", derive(Queryable))]
|
||||||
|
#[cfg_attr(feature = "ssr", diesel(check_for_backend(diesel::pg::Pg)))]
|
||||||
|
pub struct SiteView {
|
||||||
|
pub my_profile: Option<LocalUserView>,
|
||||||
|
pub config: SharedConfig,
|
||||||
|
}
|
||||||
|
|
||||||
#[derive(Clone, Debug, Serialize, Deserialize, PartialEq)]
|
#[derive(Clone, Debug, Serialize, Deserialize, PartialEq)]
|
||||||
#[cfg_attr(feature = "ssr", derive(Queryable))]
|
#[cfg_attr(feature = "ssr", derive(Queryable))]
|
||||||
#[cfg_attr(feature = "ssr", diesel(check_for_backend(diesel::pg::Pg)))]
|
#[cfg_attr(feature = "ssr", diesel(check_for_backend(diesel::pg::Pg)))]
|
||||||
|
@ -306,7 +332,6 @@ impl DbInstance {
|
||||||
pub struct InstanceView {
|
pub struct InstanceView {
|
||||||
pub instance: DbInstance,
|
pub instance: DbInstance,
|
||||||
pub followers: Vec<DbPerson>,
|
pub followers: Vec<DbPerson>,
|
||||||
pub registration_open: bool,
|
|
||||||
}
|
}
|
||||||
|
|
||||||
#[derive(Deserialize, Serialize, Clone, Debug)]
|
#[derive(Deserialize, Serialize, Clone, Debug)]
|
||||||
|
|
Loading…
Reference in a new issue