Formatting and cleanup
This commit is contained in:
@@ -292,9 +292,6 @@ async fn do_oauth_callback(
|
||||
Ok(Redirect::temporary(&ui_redirect_uri).into_response())
|
||||
}
|
||||
|
||||
// ------------------------------------------------------------------ //
|
||||
// LOGIN MODE: look up (or create) the local user for this Discord account
|
||||
// ------------------------------------------------------------------ //
|
||||
None => {
|
||||
// Find existing connection → local user_id
|
||||
let local_user_id: Option<(Uuid, String)> = sqlx::query_as(
|
||||
@@ -403,10 +400,6 @@ async fn do_oauth_callback(
|
||||
}
|
||||
}
|
||||
|
||||
// ---------------------------------------------------------------------------
|
||||
// Helpers
|
||||
// ---------------------------------------------------------------------------
|
||||
|
||||
/// Return a username derived from `base` that does not yet exist in `users`.
|
||||
async fn generate_unique_username(pool: &sqlx::PgPool, base: &str) -> crate::error::Result<String> {
|
||||
// Truncate to 28 chars to leave room for the `_XXXX` suffix
|
||||
|
||||
@@ -41,10 +41,6 @@ pub fn get_routes() -> Router<Arc<AppState>> {
|
||||
.route("/connections/{provider}", delete(disconnect_provider))
|
||||
}
|
||||
|
||||
// ---------------------------------------------------------------------------
|
||||
// Payloads
|
||||
// ---------------------------------------------------------------------------
|
||||
|
||||
#[derive(Deserialize)]
|
||||
struct RegisterPayload {
|
||||
username: String,
|
||||
@@ -71,10 +67,6 @@ struct ChangePasswordPayload {
|
||||
new_password: String,
|
||||
}
|
||||
|
||||
// ---------------------------------------------------------------------------
|
||||
// Response types
|
||||
// ---------------------------------------------------------------------------
|
||||
|
||||
#[derive(Serialize)]
|
||||
pub struct ConnectionInfo {
|
||||
pub provider: String,
|
||||
@@ -95,10 +87,6 @@ pub struct UserInfo {
|
||||
pub connections: Vec<ConnectionInfo>,
|
||||
}
|
||||
|
||||
// ---------------------------------------------------------------------------
|
||||
// DB row types
|
||||
// ---------------------------------------------------------------------------
|
||||
|
||||
#[derive(sqlx::FromRow)]
|
||||
struct DbUser {
|
||||
id: Uuid,
|
||||
@@ -116,10 +104,6 @@ struct DbConnection {
|
||||
provider_avatar: Option<String>,
|
||||
}
|
||||
|
||||
// ---------------------------------------------------------------------------
|
||||
// Password helpers
|
||||
// ---------------------------------------------------------------------------
|
||||
|
||||
/// Hash and salt a plaintext password with Argon2.
|
||||
pub fn hash_password(password: &str) -> Result<String> {
|
||||
let salt = SaltString::generate(&mut OsRng);
|
||||
@@ -139,10 +123,6 @@ pub fn verify_password(password: &str, hash: &str) -> bool {
|
||||
.is_ok()
|
||||
}
|
||||
|
||||
// ---------------------------------------------------------------------------
|
||||
// Cookie / session helpers
|
||||
// ---------------------------------------------------------------------------
|
||||
|
||||
/// Build the `siren_session` HttpOnly Secure cookie.
|
||||
pub fn build_session_cookie(token: String) -> Cookie<'static> {
|
||||
Cookie::build(("siren_session", token))
|
||||
@@ -192,10 +172,6 @@ pub async fn create_session_and_cookie(
|
||||
Ok((jar, ()))
|
||||
}
|
||||
|
||||
// ---------------------------------------------------------------------------
|
||||
// Helper: load full UserInfo for a given user_id
|
||||
// ---------------------------------------------------------------------------
|
||||
|
||||
async fn load_user_info(user_id: Uuid) -> Result<UserInfo> {
|
||||
let pool = data::pool();
|
||||
|
||||
@@ -232,10 +208,6 @@ async fn load_user_info(user_id: Uuid) -> Result<UserInfo> {
|
||||
})
|
||||
}
|
||||
|
||||
// ---------------------------------------------------------------------------
|
||||
// Handlers
|
||||
// ---------------------------------------------------------------------------
|
||||
|
||||
async fn register(
|
||||
headers: HeaderMap,
|
||||
jar: CookieJar,
|
||||
@@ -245,12 +217,6 @@ async fn register(
|
||||
if username.is_empty() || username.len() > 32 {
|
||||
return Err(Error::new(422, "Username must be 1–32 characters".into()));
|
||||
}
|
||||
if payload.password.len() < 8 {
|
||||
return Err(Error::new(
|
||||
422,
|
||||
"Password must be at least 8 characters".into(),
|
||||
));
|
||||
}
|
||||
|
||||
let pool = data::pool();
|
||||
|
||||
@@ -402,13 +368,6 @@ async fn change_password(
|
||||
) -> Result<StatusCode> {
|
||||
let session = session.ok_or_else(|| Error::from(StatusCode::UNAUTHORIZED))?;
|
||||
|
||||
if payload.new_password.len() < 8 {
|
||||
return Err(Error::new(
|
||||
422,
|
||||
"New password must be at least 8 characters".into(),
|
||||
));
|
||||
}
|
||||
|
||||
let pool = data::pool();
|
||||
|
||||
let existing_hash: Option<String> =
|
||||
|
||||
@@ -61,10 +61,6 @@ pub fn get_routes() -> Router<Arc<AppState>> {
|
||||
.route("/maps/{id}/ws", get(ws_handler))
|
||||
}
|
||||
|
||||
// ---------------------------------------------------------------------------
|
||||
// Access helpers
|
||||
// ---------------------------------------------------------------------------
|
||||
|
||||
/// Fetch the role of `user_id` on `map_id`, or `None` if no record exists.
|
||||
async fn get_user_role(map_id: &str, user_id: Uuid) -> Result<Option<MapRole>> {
|
||||
let pool = siren_core::data::pool();
|
||||
@@ -120,10 +116,6 @@ async fn is_owner(map: &GridMap, session: &Option<Session>) -> bool {
|
||||
.unwrap_or(false)
|
||||
}
|
||||
|
||||
// ---------------------------------------------------------------------------
|
||||
// Map CRUD
|
||||
// ---------------------------------------------------------------------------
|
||||
|
||||
pub async fn list_maps(
|
||||
SessionAuthorization(session): SessionAuthorization,
|
||||
) -> Result<Json<Vec<ListedMap>>> {
|
||||
@@ -287,10 +279,6 @@ pub async fn delete_map(
|
||||
Ok(StatusCode::NO_CONTENT)
|
||||
}
|
||||
|
||||
// ---------------------------------------------------------------------------
|
||||
// Permission management
|
||||
// ---------------------------------------------------------------------------
|
||||
|
||||
pub async fn list_permissions(
|
||||
SessionAuthorization(session): SessionAuthorization,
|
||||
Path(id): Path<String>,
|
||||
@@ -429,10 +417,6 @@ pub async fn unfavorite_map(
|
||||
Ok(StatusCode::NO_CONTENT)
|
||||
}
|
||||
|
||||
// ---------------------------------------------------------------------------
|
||||
// Access Requests
|
||||
// ---------------------------------------------------------------------------
|
||||
|
||||
pub async fn create_access_request(
|
||||
SessionAuthorization(session): SessionAuthorization,
|
||||
Path(id): Path<String>,
|
||||
@@ -572,10 +556,6 @@ pub async fn resolve_access_request(
|
||||
Ok(StatusCode::NO_CONTENT)
|
||||
}
|
||||
|
||||
// ---------------------------------------------------------------------------
|
||||
// WebSocket handler
|
||||
// ---------------------------------------------------------------------------
|
||||
|
||||
pub async fn ws_handler(
|
||||
ws: WebSocketUpgrade,
|
||||
State(state): State<Arc<AppState>>,
|
||||
|
||||
@@ -1,11 +1,7 @@
|
||||
use chrono::NaiveDateTime;
|
||||
use chrono::{DateTime, Utc};
|
||||
use serde::{Deserialize, Serialize};
|
||||
use uuid::Uuid;
|
||||
|
||||
// ---------------------------------------------------------------------------
|
||||
// Map Role / Permission
|
||||
// ---------------------------------------------------------------------------
|
||||
|
||||
#[derive(Serialize, Deserialize, sqlx::Type, Clone, Debug, PartialEq, Eq)]
|
||||
#[sqlx(type_name = "text", rename_all = "lowercase")]
|
||||
#[serde(rename_all = "lowercase")]
|
||||
@@ -36,10 +32,6 @@ pub struct PermissionWithUser {
|
||||
pub role: MapRole,
|
||||
}
|
||||
|
||||
// ---------------------------------------------------------------------------
|
||||
// Grid Map
|
||||
// ---------------------------------------------------------------------------
|
||||
|
||||
/// Core map record as stored/returned by create, get, and update endpoints.
|
||||
#[derive(Serialize, Deserialize, sqlx::FromRow, Clone, Debug)]
|
||||
pub struct GridMap {
|
||||
@@ -49,8 +41,8 @@ pub struct GridMap {
|
||||
pub public_access: String,
|
||||
pub owner_id: Uuid,
|
||||
pub colors: Vec<String>,
|
||||
pub created_at: NaiveDateTime,
|
||||
pub updated_at: NaiveDateTime,
|
||||
pub created_at: DateTime<Utc>,
|
||||
pub updated_at: DateTime<Utc>,
|
||||
}
|
||||
|
||||
/// Extended map record returned by the list endpoint.
|
||||
@@ -64,8 +56,8 @@ pub struct ListedMap {
|
||||
pub owner_id: Uuid,
|
||||
pub owner_username: String,
|
||||
pub colors: Vec<String>,
|
||||
pub created_at: NaiveDateTime,
|
||||
pub updated_at: NaiveDateTime,
|
||||
pub created_at: DateTime<Utc>,
|
||||
pub updated_at: DateTime<Utc>,
|
||||
/// The authenticated caller's role on this map, or NULL if they only have it
|
||||
/// via a favorite (no explicit permission).
|
||||
pub user_role: Option<MapRole>,
|
||||
@@ -98,10 +90,6 @@ pub struct UpdatePermissionPayload {
|
||||
pub role: Option<MapRole>,
|
||||
}
|
||||
|
||||
// ---------------------------------------------------------------------------
|
||||
// Map Access Requests
|
||||
// ---------------------------------------------------------------------------
|
||||
|
||||
/// An access-request row joined with the requesting user's username.
|
||||
#[derive(Serialize, sqlx::FromRow, Clone, Debug)]
|
||||
pub struct AccessRequestWithUser {
|
||||
@@ -111,8 +99,8 @@ pub struct AccessRequestWithUser {
|
||||
pub username: String,
|
||||
pub requested_role: MapRole,
|
||||
pub status: String,
|
||||
pub created_at: NaiveDateTime,
|
||||
pub updated_at: NaiveDateTime,
|
||||
pub created_at: DateTime<Utc>,
|
||||
pub updated_at: DateTime<Utc>,
|
||||
}
|
||||
|
||||
#[derive(Deserialize, Clone, Debug)]
|
||||
@@ -126,10 +114,6 @@ pub struct ResolveAccessRequestPayload {
|
||||
pub action: String,
|
||||
}
|
||||
|
||||
// ---------------------------------------------------------------------------
|
||||
// Grid Cell (no id column — composite PK in DB)
|
||||
// ---------------------------------------------------------------------------
|
||||
|
||||
#[derive(Serialize, Deserialize, sqlx::FromRow, Clone, Debug)]
|
||||
pub struct GridCell {
|
||||
pub map_id: String,
|
||||
@@ -146,10 +130,6 @@ pub struct CellPatch {
|
||||
pub color: String,
|
||||
}
|
||||
|
||||
// ---------------------------------------------------------------------------
|
||||
// Grid Token
|
||||
// ---------------------------------------------------------------------------
|
||||
|
||||
#[derive(Serialize, Deserialize, sqlx::FromRow, Clone, Debug)]
|
||||
pub struct GridToken {
|
||||
pub id: String,
|
||||
@@ -160,10 +140,6 @@ pub struct GridToken {
|
||||
pub color: String,
|
||||
}
|
||||
|
||||
// ---------------------------------------------------------------------------
|
||||
// Full map state (used on initial WS connect and REST GET)
|
||||
// ---------------------------------------------------------------------------
|
||||
|
||||
#[derive(Serialize, Deserialize, Clone, Debug)]
|
||||
pub struct MapState {
|
||||
pub map: GridMap,
|
||||
@@ -171,10 +147,6 @@ pub struct MapState {
|
||||
pub tokens: Vec<GridToken>,
|
||||
}
|
||||
|
||||
// ---------------------------------------------------------------------------
|
||||
// WebSocket message types
|
||||
// ---------------------------------------------------------------------------
|
||||
|
||||
#[derive(Serialize, Deserialize, Clone, Debug)]
|
||||
#[serde(tag = "type", rename_all = "snake_case")]
|
||||
pub enum ClientMessage {
|
||||
|
||||
@@ -16,16 +16,8 @@ pub struct EnvironmentConfiguration {
|
||||
pub api_session_ttl: u64,
|
||||
pub valkey_host: String,
|
||||
pub valkey_port: u16,
|
||||
pub minio_root_user: String,
|
||||
pub minio_root_password: String,
|
||||
pub minio_host: String,
|
||||
pub minio_port: u16,
|
||||
pub minio_port_internal: u16,
|
||||
pub data_dir_path: Option<String>,
|
||||
pub force_register: bool,
|
||||
pub default_api_key: String,
|
||||
pub default_server: Option<String>,
|
||||
pub default_user: Option<String>,
|
||||
pub force_command_register: bool,
|
||||
}
|
||||
|
||||
impl EnvironmentConfiguration {
|
||||
@@ -57,25 +49,11 @@ impl EnvironmentConfiguration {
|
||||
.unwrap_or_else(|_| "6379".to_string())
|
||||
.parse()
|
||||
.unwrap_or(6379),
|
||||
minio_root_user: env::var("MINIO_ROOT_USER")?,
|
||||
minio_root_password: env::var("MINIO_ROOT_PASSWORD")?,
|
||||
minio_host: env::var("MINIO_HOST").unwrap_or_else(|_| "localhost".to_string()),
|
||||
minio_port: env::var("MINIO_PORT")
|
||||
.unwrap_or_else(|_| "9000".to_string())
|
||||
.parse()
|
||||
.unwrap_or(9000),
|
||||
minio_port_internal: env::var("MINIO_PORT_INTERNAL")
|
||||
.unwrap_or_else(|_| "9001".to_string())
|
||||
.parse()
|
||||
.unwrap_or(9001),
|
||||
data_dir_path: env::var("DATA_DIR_PATH").ok().filter(|s| !s.is_empty()),
|
||||
force_register: env::var("FORCE_REGISTER")
|
||||
force_command_register: env::var("FORCE_COMMAND_REGISTER")
|
||||
.ok()
|
||||
.map(|v| v.to_lowercase() == "true")
|
||||
.unwrap_or(false),
|
||||
default_api_key: env::var("DEFAULT_API_KEY").unwrap_or_default(),
|
||||
default_server: env::var("DEFAULT_SERVER").ok().filter(|s| !s.is_empty()),
|
||||
default_user: env::var("DEFAULT_USER").ok().filter(|s| !s.is_empty()),
|
||||
})
|
||||
}
|
||||
}
|
||||
|
||||
@@ -1,3 +0,0 @@
|
||||
mod model;
|
||||
|
||||
pub use model::*;
|
||||
@@ -1,74 +0,0 @@
|
||||
use crate::error::Result;
|
||||
use serde::{Deserialize, Serialize};
|
||||
|
||||
const TABLE_NAME: &str = "messages";
|
||||
|
||||
#[derive(Debug, Serialize, Deserialize, sqlx::FromRow)]
|
||||
pub struct MessageCache {
|
||||
pub id: String,
|
||||
pub guild_id: i64,
|
||||
pub channel_id: i64,
|
||||
pub author_id: i64,
|
||||
pub created: i64,
|
||||
pub model: String,
|
||||
pub request: String,
|
||||
pub response: String,
|
||||
pub request_tags: Vec<String>,
|
||||
pub response_tags: Vec<String>,
|
||||
}
|
||||
|
||||
impl MessageCache {
|
||||
pub async fn insert(&self) -> Result<()> {
|
||||
let pool = crate::data::pool();
|
||||
sqlx::query(&format!(
|
||||
"INSERT INTO {} (
|
||||
id,
|
||||
guild_id,
|
||||
channel_id,
|
||||
author_id,
|
||||
created,
|
||||
model,
|
||||
request,
|
||||
response,
|
||||
request_tags,
|
||||
response_tags
|
||||
) VALUES (
|
||||
$1, $2, $3, $4, $5, $6, $7, $8, $9, $10
|
||||
)",
|
||||
TABLE_NAME
|
||||
))
|
||||
.bind(&self.id)
|
||||
.bind(self.guild_id)
|
||||
.bind(self.channel_id)
|
||||
.bind(self.author_id)
|
||||
.bind(self.created)
|
||||
.bind(&self.model)
|
||||
.bind(&self.request)
|
||||
.bind(&self.response)
|
||||
.bind(&self.request_tags)
|
||||
.bind(&self.response_tags)
|
||||
.execute(pool)
|
||||
.await?;
|
||||
Ok(())
|
||||
}
|
||||
|
||||
pub async fn find(
|
||||
guild_id: i64,
|
||||
channel_id: i64,
|
||||
author_id: i64,
|
||||
limit: i64,
|
||||
) -> Result<Vec<MessageCache>> {
|
||||
let pool = crate::data::pool();
|
||||
let messages = sqlx::query_as::<_, MessageCache>(&format!(
|
||||
"SELECT * FROM {} WHERE guild_id = $1 AND channel_id = $2 AND author_id = $3 ORDER BY created ASC LIMIT $4",
|
||||
TABLE_NAME
|
||||
))
|
||||
.bind(guild_id)
|
||||
.bind(channel_id)
|
||||
.bind(author_id)
|
||||
.bind(limit)
|
||||
.fetch_all(pool)
|
||||
.await?;
|
||||
Ok(messages)
|
||||
}
|
||||
}
|
||||
@@ -9,7 +9,6 @@ pub mod events;
|
||||
mod executable_query;
|
||||
pub mod guilds;
|
||||
pub mod insert;
|
||||
pub mod messages;
|
||||
pub mod query;
|
||||
pub mod update;
|
||||
use crate::config::EnvironmentConfiguration;
|
||||
|
||||
@@ -21,7 +21,7 @@ async fn main() -> std::result::Result<(), Box<dyn std::error::Error>> {
|
||||
let config = EnvironmentConfiguration::load()?;
|
||||
siren_core::data::initialize(&config).await?;
|
||||
|
||||
let handler = BotHandler::new(config.force_register);
|
||||
let handler = BotHandler::new(config.force_command_register);
|
||||
let songbird = Songbird::serenity();
|
||||
let intents: GatewayIntents = GatewayIntents::all();
|
||||
|
||||
|
||||
Reference in New Issue
Block a user