add: channels, messages
This commit is contained in:
parent
67492cf73f
commit
7774124bd0
40 changed files with 2238 additions and 115 deletions
|
@ -190,9 +190,12 @@ pub struct UserSettings {
|
|||
/// If dislikes are hidden for the user.
|
||||
#[serde(default)]
|
||||
pub hide_dislikes: bool,
|
||||
/// The timeline that the "Home" button takes you to
|
||||
/// The timeline that the "Home" button takes you to.
|
||||
#[serde(default)]
|
||||
pub default_timeline: DefaultTimelineChoice,
|
||||
/// If other users that you aren't following can add you to chats.
|
||||
#[serde(default)]
|
||||
pub private_chats: bool,
|
||||
}
|
||||
|
||||
impl Default for User {
|
||||
|
@ -352,10 +355,12 @@ pub enum ConnectionService {
|
|||
|
||||
#[derive(Clone, Debug, Serialize, Deserialize, PartialEq, Eq)]
|
||||
pub enum ConnectionType {
|
||||
/// A connection through a token with an expiration time.
|
||||
/// A connection through a token which never expires.
|
||||
Token,
|
||||
/// <https://www.rfc-editor.org/rfc/rfc7636>
|
||||
PKCE,
|
||||
/// A connection with no stored authentication.
|
||||
None,
|
||||
}
|
||||
|
||||
#[derive(Clone, Debug, Serialize, Deserialize)]
|
||||
|
|
|
@ -18,11 +18,17 @@ pub struct Channel {
|
|||
///
|
||||
/// Top (0) to bottom.
|
||||
pub position: usize,
|
||||
/// The members of the chat (ids). Should be empty if `community > 0`.
|
||||
///
|
||||
/// The owner should not be a member of the channel since any member can update members.
|
||||
pub members: Vec<usize>,
|
||||
/// The title of the channel.
|
||||
pub title: String,
|
||||
}
|
||||
|
||||
impl Channel {
|
||||
/// Create a new [`Channel`].
|
||||
pub fn new(community: usize, owner: usize, position: usize) -> Self {
|
||||
pub fn new(community: usize, owner: usize, position: usize, title: String) -> Self {
|
||||
Self {
|
||||
id: AlmostSnowflake::new(1234567890)
|
||||
.to_string()
|
||||
|
@ -34,8 +40,32 @@ impl Channel {
|
|||
minimum_role_read: (CommunityPermission::DEFAULT | CommunityPermission::MEMBER).bits(),
|
||||
minimum_role_write: (CommunityPermission::DEFAULT | CommunityPermission::MEMBER).bits(),
|
||||
position,
|
||||
members: Vec::new(),
|
||||
title,
|
||||
}
|
||||
}
|
||||
|
||||
/// Check if the given `uid` can post in the channel.
|
||||
pub fn check_post(&self, uid: usize, membership: Option<CommunityPermission>) -> bool {
|
||||
let mut is_member = false;
|
||||
|
||||
if let Some(membership) = membership {
|
||||
is_member = membership.bits() >= self.minimum_role_write
|
||||
}
|
||||
|
||||
(uid == self.owner) | is_member | self.members.contains(&uid)
|
||||
}
|
||||
|
||||
/// Check if the given `uid` can post in the channel.
|
||||
pub fn check_read(&self, uid: usize, membership: Option<CommunityPermission>) -> bool {
|
||||
let mut is_member = false;
|
||||
|
||||
if let Some(membership) = membership {
|
||||
is_member = membership.bits() >= self.minimum_role_read
|
||||
}
|
||||
|
||||
(uid == self.owner) | is_member | self.members.contains(&uid)
|
||||
}
|
||||
}
|
||||
|
||||
#[derive(Serialize, Deserialize)]
|
||||
|
|
|
@ -2,6 +2,7 @@ pub mod auth;
|
|||
pub mod communities;
|
||||
pub mod communities_permissions;
|
||||
pub mod moderation;
|
||||
pub mod oauth;
|
||||
pub mod permissions;
|
||||
pub mod reactions;
|
||||
pub mod requests;
|
||||
|
@ -9,6 +10,9 @@ pub mod requests;
|
|||
#[cfg(feature = "redis")]
|
||||
pub mod channels;
|
||||
|
||||
#[cfg(feature = "redis")]
|
||||
pub mod socket;
|
||||
|
||||
use std::fmt::Display;
|
||||
|
||||
use serde::{Deserialize, Serialize};
|
||||
|
|
36
crates/core/src/model/oauth.rs
Normal file
36
crates/core/src/model/oauth.rs
Normal file
|
@ -0,0 +1,36 @@
|
|||
use base64::{engine::general_purpose::URL_SAFE as base64url, Engine};
|
||||
use serde::{Serialize, Deserialize};
|
||||
use tetratto_shared::hash::hash;
|
||||
use super::{Result, Error};
|
||||
|
||||
#[derive(Serialize, Deserialize, PartialEq, Eq)]
|
||||
pub enum PkceChallengeMethod {
|
||||
S256,
|
||||
}
|
||||
|
||||
#[derive(Serialize, Deserialize, PartialEq, Eq)]
|
||||
pub enum AppScope {
|
||||
#[serde(alias = "user-read-profile")]
|
||||
UserReadProfile,
|
||||
}
|
||||
|
||||
/// Check a verifier against the stored challenge (using the given [`PkceChallengeMethod`]).
|
||||
pub fn check_verifier(verifier: &str, challenge: &str, method: PkceChallengeMethod) -> Result<()> {
|
||||
if method != PkceChallengeMethod::S256 {
|
||||
return Err(Error::MiscError("only S256 is supported".to_string()));
|
||||
}
|
||||
|
||||
let decoded = match base64url.decode(challenge.as_bytes()) {
|
||||
Ok(hash) => hash,
|
||||
Err(e) => return Err(Error::MiscError(e.to_string())),
|
||||
};
|
||||
|
||||
let hash = hash(verifier.to_string());
|
||||
|
||||
if hash.as_bytes() != decoded {
|
||||
// the verifier we received does not match the verifier from the stored challenge
|
||||
return Err(Error::NotAllowed);
|
||||
}
|
||||
|
||||
Ok(())
|
||||
}
|
23
crates/core/src/model/socket.rs
Normal file
23
crates/core/src/model/socket.rs
Normal file
|
@ -0,0 +1,23 @@
|
|||
use serde::{Serialize, Deserialize, de::DeserializeOwned};
|
||||
|
||||
#[derive(Serialize, Deserialize, PartialEq, Eq)]
|
||||
pub enum SocketMethod {
|
||||
/// Authentication and channel identification.
|
||||
Headers,
|
||||
/// A message was sent in the channel.
|
||||
Message,
|
||||
/// A message was deleted in the channel.
|
||||
Delete,
|
||||
}
|
||||
|
||||
#[derive(Serialize, Deserialize)]
|
||||
pub struct SocketMessage {
|
||||
pub method: SocketMethod,
|
||||
pub data: String,
|
||||
}
|
||||
|
||||
impl SocketMessage {
|
||||
pub fn data<T: DeserializeOwned>(&self) -> T {
|
||||
serde_json::from_str(&self.data).unwrap()
|
||||
}
|
||||
}
|
Loading…
Add table
Add a link
Reference in a new issue