Configure linter and fix its warnings
This commit is contained in:
parent
e9c5bda55c
commit
c473070fd4
30 changed files with 89 additions and 76 deletions
9
.cargo/config.toml
Normal file
9
.cargo/config.toml
Normal file
|
@ -0,0 +1,9 @@
|
|||
# https://github.com/rust-lang/cargo/issues/5034#issuecomment-927105016
|
||||
[target.'cfg(feature = "cargo-clippy")']
|
||||
rustflags = [
|
||||
"-Aclippy::let_and_return",
|
||||
"-Aclippy::map_entry",
|
||||
"-Aclippy::or_fun_call",
|
||||
"-Aclippy::redundant_field_names",
|
||||
"-Aclippy::unused_unit",
|
||||
]
|
|
@ -54,6 +54,12 @@ cargo run
|
|||
cargo run --bin mitractl
|
||||
```
|
||||
|
||||
### Run linter
|
||||
|
||||
```
|
||||
cargo clippy
|
||||
```
|
||||
|
||||
### Run tests
|
||||
|
||||
```
|
||||
|
|
|
@ -98,20 +98,19 @@ fn create_activity(
|
|||
) -> Activity {
|
||||
let actor_id = get_actor_url(
|
||||
instance_url,
|
||||
&actor_name,
|
||||
actor_name,
|
||||
);
|
||||
let activity_id = get_object_url(
|
||||
instance_url,
|
||||
&activity_uuid.unwrap_or(Uuid::new_v4()),
|
||||
);
|
||||
let activity = Activity {
|
||||
Activity {
|
||||
context: json!(AP_CONTEXT),
|
||||
id: activity_id,
|
||||
activity_type: activity_type.to_string(),
|
||||
actor: actor_id,
|
||||
object: serde_json::to_value(object).unwrap(),
|
||||
};
|
||||
activity
|
||||
}
|
||||
}
|
||||
|
||||
pub fn create_note(
|
||||
|
|
|
@ -1,4 +1,4 @@
|
|||
use std::path::PathBuf;
|
||||
use std::path::Path;
|
||||
|
||||
use serde_json::Value;
|
||||
|
||||
|
@ -29,7 +29,7 @@ pub enum FetchError {
|
|||
|
||||
pub async fn fetch_avatar_and_banner(
|
||||
actor: &Actor,
|
||||
media_dir: &PathBuf,
|
||||
media_dir: &Path,
|
||||
) -> Result<(Option<String>, Option<String>), FetchError> {
|
||||
let avatar = match &actor.icon {
|
||||
Some(icon) => {
|
||||
|
@ -57,7 +57,7 @@ pub async fn fetch_avatar_and_banner(
|
|||
pub async fn fetch_profile(
|
||||
username: &str,
|
||||
instance_host: &str,
|
||||
media_dir: &PathBuf,
|
||||
media_dir: &Path,
|
||||
) -> Result<ProfileCreateData, FetchError> {
|
||||
let actor_address = format!("{}@{}", &username, &instance_host);
|
||||
let webfinger_account_uri = format!("acct:{}", actor_address);
|
||||
|
@ -80,7 +80,7 @@ pub async fn fetch_profile(
|
|||
|
||||
pub async fn fetch_profile_by_actor_id(
|
||||
actor_url: &str,
|
||||
media_dir: &PathBuf,
|
||||
media_dir: &Path,
|
||||
) -> Result<ProfileCreateData, FetchError> {
|
||||
let actor_host = url::Url::parse(actor_url)?
|
||||
.host_str()
|
||||
|
@ -115,7 +115,7 @@ pub async fn fetch_profile_by_actor_id(
|
|||
|
||||
pub async fn fetch_attachment(
|
||||
url: &str,
|
||||
output_dir: &PathBuf,
|
||||
output_dir: &Path,
|
||||
) -> Result<String, FetchError> {
|
||||
let response = reqwest::get(url).await?;
|
||||
let file_data = response.bytes().await?;
|
||||
|
|
|
@ -1,4 +1,4 @@
|
|||
use std::path::PathBuf;
|
||||
use std::path::Path;
|
||||
|
||||
use regex::Regex;
|
||||
use serde_json::Value;
|
||||
|
@ -52,7 +52,7 @@ fn parse_actor_id(
|
|||
);
|
||||
let url_regexp = Regex::new(&url_regexp_str)
|
||||
.map_err(|_| ValidationError("error"))?;
|
||||
let url_caps = url_regexp.captures(&actor_id)
|
||||
let url_caps = url_regexp.captures(actor_id)
|
||||
.ok_or(ValidationError("invalid actor ID"))?;
|
||||
let username = url_caps.name("username")
|
||||
.ok_or(ValidationError("invalid actor ID"))?
|
||||
|
@ -71,7 +71,7 @@ fn parse_object_id(
|
|||
);
|
||||
let url_regexp = Regex::new(&url_regexp_str)
|
||||
.map_err(|_| ValidationError("error"))?;
|
||||
let url_caps = url_regexp.captures(&object_id)
|
||||
let url_caps = url_regexp.captures(object_id)
|
||||
.ok_or(ValidationError("invalid object ID"))?;
|
||||
let object_uuid: Uuid = url_caps.name("uuid")
|
||||
.ok_or(ValidationError("invalid object ID"))?
|
||||
|
@ -83,7 +83,7 @@ fn parse_object_id(
|
|||
async fn get_or_fetch_profile_by_actor_id(
|
||||
db_client: &impl GenericClient,
|
||||
actor_id: &str,
|
||||
media_dir: &PathBuf,
|
||||
media_dir: &Path,
|
||||
) -> Result<DbActorProfile, HttpError> {
|
||||
let profile = match get_profile_by_actor_id(db_client, actor_id).await {
|
||||
Ok(profile) => profile,
|
||||
|
@ -116,6 +116,7 @@ pub async fn process_note(
|
|||
|
||||
// Fetch ancestors by going through inReplyTo references
|
||||
// TODO: fetch replies too
|
||||
#[allow(clippy::while_let_loop)]
|
||||
loop {
|
||||
let object_id = match maybe_parent_object_id {
|
||||
Some(parent_object_id) => {
|
||||
|
@ -237,7 +238,7 @@ pub async fn receive_activity(
|
|||
.and_then(|val| val.as_str())
|
||||
.unwrap_or("Unknown")
|
||||
.to_owned();
|
||||
let db_client = &mut **get_database_client(&db_pool).await?;
|
||||
let db_client = &mut **get_database_client(db_pool).await?;
|
||||
match (activity_type.as_str(), object_type.as_str()) {
|
||||
(ACCEPT, FOLLOW) => {
|
||||
let object: Object = serde_json::from_value(activity.object)
|
||||
|
@ -313,7 +314,7 @@ pub async fn receive_activity(
|
|||
|
||||
// Send activity
|
||||
let recipients = vec![source_actor];
|
||||
deliver_activity(&config, &target_user, new_activity, recipients);
|
||||
deliver_activity(config, &target_user, new_activity, recipients);
|
||||
},
|
||||
(UNDO, FOLLOW) => {
|
||||
let object: Object = serde_json::from_value(activity.object)
|
||||
|
|
|
@ -1,5 +1,4 @@
|
|||
use clap::Clap;
|
||||
use tokio;
|
||||
use uuid::Uuid;
|
||||
|
||||
use mitra::config;
|
||||
|
@ -82,7 +81,7 @@ async fn main() {
|
|||
},
|
||||
SubCommand::ListInviteCodes(_) => {
|
||||
let invite_codes = get_invite_codes(db_client).await.unwrap();
|
||||
if invite_codes.len() == 0 {
|
||||
if invite_codes.is_empty() {
|
||||
println!("no invite codes found");
|
||||
return;
|
||||
}
|
||||
|
|
|
@ -3,15 +3,14 @@ pub mod migrate;
|
|||
pub type Pool = deadpool_postgres::Pool;
|
||||
|
||||
pub fn create_pool(database_url: &str) -> Pool {
|
||||
let pool = deadpool_postgres::Pool::new(
|
||||
deadpool_postgres::Pool::new(
|
||||
deadpool_postgres::Manager::new(
|
||||
database_url.parse().expect("invalid database URL"),
|
||||
tokio_postgres::NoTls,
|
||||
),
|
||||
// https://wiki.postgresql.org/wiki/Number_Of_Database_Connections
|
||||
num_cpus::get() * 2,
|
||||
);
|
||||
pool
|
||||
)
|
||||
}
|
||||
|
||||
use tokio_postgres::error::{Error as PgError, SqlState};
|
||||
|
|
|
@ -1,5 +1,5 @@
|
|||
use std::fs;
|
||||
use std::path::PathBuf;
|
||||
use std::path::Path;
|
||||
|
||||
pub const COLLECTIBLE: &str = "Collectible";
|
||||
pub const MANAGER: &str = "Manager";
|
||||
|
@ -17,7 +17,7 @@ pub enum ArtifactError {
|
|||
}
|
||||
|
||||
pub fn load_abi(
|
||||
contract_dir: &PathBuf,
|
||||
contract_dir: &Path,
|
||||
contract_name: &str,
|
||||
) -> Result<Vec<u8>, ArtifactError> {
|
||||
let contract_artifact_path = contract_dir.join(format!("{}.json", contract_name));
|
||||
|
|
|
@ -74,7 +74,7 @@ pub async fn process_events(
|
|||
db_pool: &Pool,
|
||||
token_waitlist_map: &mut HashMap<Uuid, DateTime<Utc>>,
|
||||
) -> Result<(), EthereumError> {
|
||||
let db_client = &**get_database_client(&db_pool).await?;
|
||||
let db_client = &**get_database_client(db_pool).await?;
|
||||
|
||||
// Create/update token waitlist map
|
||||
let token_waitlist = get_token_waitlist(db_client).await?;
|
||||
|
@ -196,7 +196,7 @@ pub fn create_mint_signature(
|
|||
let contract_address = parse_address(&contract_config.address)?;
|
||||
let user_address = parse_address(user_address)?;
|
||||
let chain_id: U256 = contract_config.chain_id.into();
|
||||
let chain_id_token = Token::Uint(chain_id.into());
|
||||
let chain_id_token = Token::Uint(chain_id);
|
||||
let chain_id_bin = encode(&[chain_id_token]);
|
||||
let message = [
|
||||
&chain_id_bin,
|
||||
|
|
|
@ -42,7 +42,7 @@ pub fn sign_message(
|
|||
signing_key: &str,
|
||||
message: &[u8],
|
||||
) -> Result<SignatureData, SignatureError> {
|
||||
let key = SecretKey::from_str(&signing_key)?;
|
||||
let key = SecretKey::from_str(signing_key)?;
|
||||
let message_hash = keccak256(message);
|
||||
let eip_191_message = [
|
||||
"\x19Ethereum Signed Message:\n32".as_bytes(),
|
||||
|
|
|
@ -58,7 +58,7 @@ fn parse_http_signature(
|
|||
);
|
||||
let signature_header_regexp = Regex::new(signature_header_regexp_raw).unwrap();
|
||||
let signature_header_caps = signature_header_regexp
|
||||
.captures(&signature_header)
|
||||
.captures(signature_header)
|
||||
.ok_or(VerificationError::HeaderError("invalid signature header"))?;
|
||||
let key_id = signature_header_caps.name("key_id")
|
||||
.ok_or(VerificationError::ParseError("keyId parameter is missing"))?
|
||||
|
@ -78,7 +78,7 @@ fn parse_http_signature(
|
|||
request_method.as_str().to_lowercase(),
|
||||
request_uri,
|
||||
);
|
||||
for header in headers_parameter.split(" ") {
|
||||
for header in headers_parameter.split(' ') {
|
||||
if header == "(request-target)" {
|
||||
continue;
|
||||
}
|
||||
|
|
|
@ -12,7 +12,7 @@ pub struct ParseError;
|
|||
|
||||
pub fn parse_ipfs_url(url: &str) -> Result<String, ParseError> {
|
||||
let regexp = Regex::new(r"ipfs://(?P<cid>\w+)").unwrap();
|
||||
let caps = regexp.captures(&url).ok_or(ParseError)?;
|
||||
let caps = regexp.captures(url).ok_or(ParseError)?;
|
||||
let cid = caps.name("cid")
|
||||
.ok_or(ParseError)?
|
||||
.as_str().to_string();
|
||||
|
|
|
@ -1,4 +1,4 @@
|
|||
use std::path::PathBuf;
|
||||
use std::path::Path;
|
||||
|
||||
use chrono::{DateTime, Utc};
|
||||
use serde::{Deserialize, Serialize};
|
||||
|
@ -49,9 +49,9 @@ pub struct Account {
|
|||
impl Account {
|
||||
pub fn from_profile(profile: DbActorProfile, instance_url: &str) -> Self {
|
||||
let avatar_url = profile.avatar_file_name.as_ref()
|
||||
.map(|name| get_file_url(instance_url, &name));
|
||||
.map(|name| get_file_url(instance_url, name));
|
||||
let header_url = profile.banner_file_name.as_ref()
|
||||
.map(|name| get_file_url(instance_url, &name));
|
||||
.map(|name| get_file_url(instance_url, name));
|
||||
let fields = profile.extra_fields.unpack().into_iter()
|
||||
.map(|field| AccountField { name: field.name, value: field.value })
|
||||
.collect();
|
||||
|
@ -126,17 +126,17 @@ pub struct AccountUpdateData {
|
|||
fn process_b64_image_field_value(
|
||||
form_value: Option<String>,
|
||||
db_value: Option<String>,
|
||||
output_dir: &PathBuf,
|
||||
output_dir: &Path,
|
||||
) -> Result<Option<String>, FileError> {
|
||||
let maybe_file_name = match form_value {
|
||||
Some(b64_data) => {
|
||||
if b64_data == "" {
|
||||
if b64_data.is_empty() {
|
||||
// Remove file
|
||||
None
|
||||
} else {
|
||||
// Decode and save file
|
||||
let (file_name, _) = save_validated_b64_file(
|
||||
&b64_data, &output_dir, "image/",
|
||||
&b64_data, output_dir, "image/",
|
||||
)?;
|
||||
Some(file_name)
|
||||
}
|
||||
|
@ -152,7 +152,7 @@ impl AccountUpdateData {
|
|||
self,
|
||||
current_avatar: &Option<String>,
|
||||
current_banner: &Option<String>,
|
||||
media_dir: &PathBuf,
|
||||
media_dir: &Path,
|
||||
) -> Result<ProfileUpdateData, FileError> {
|
||||
let avatar = process_b64_image_field_value(
|
||||
self.avatar, current_avatar.clone(), media_dir,
|
||||
|
|
|
@ -49,21 +49,21 @@ pub async fn create_account(
|
|||
if !config.registrations_open {
|
||||
let invite_code = user_data.invite_code.as_ref()
|
||||
.ok_or(ValidationError("invite code is required"))?;
|
||||
if !is_valid_invite_code(db_client, &invite_code).await? {
|
||||
Err(ValidationError("invalid invite code"))?;
|
||||
if !is_valid_invite_code(db_client, invite_code).await? {
|
||||
return Err(ValidationError("invalid invite code").into());
|
||||
}
|
||||
}
|
||||
if config.ethereum_contract.is_some() {
|
||||
let is_allowed = is_allowed_user(&config, &user_data.wallet_address).await
|
||||
.map_err(|_| HttpError::InternalError)?;
|
||||
if !is_allowed {
|
||||
Err(ValidationError("not allowed to sign up"))?;
|
||||
return Err(ValidationError("not allowed to sign up").into());
|
||||
}
|
||||
}
|
||||
// Hash password and generate private key
|
||||
let password_hash = hash_password(&user_data.password)
|
||||
.map_err(|_| HttpError::InternalError)?;
|
||||
let private_key = match web::block(move || generate_private_key()).await {
|
||||
let private_key = match web::block(generate_private_key).await {
|
||||
Ok(private_key) => private_key,
|
||||
Err(_) => return Err(HttpError::InternalError),
|
||||
};
|
||||
|
|
|
@ -27,7 +27,7 @@ impl From<&Config> for InstanceInfo {
|
|||
short_description: config.instance_short_description.clone(),
|
||||
description: config.instance_description.clone(),
|
||||
version: config.version.clone(),
|
||||
registrations: config.registrations_open.clone(),
|
||||
registrations: config.registrations_open,
|
||||
login_message: config.login_message.clone(),
|
||||
ethereum_explorer_url: config.ethereum_explorer_url.clone(),
|
||||
nft_contract_name: config.ethereum_contract.as_ref()
|
||||
|
|
|
@ -18,8 +18,8 @@ async fn token_view(
|
|||
db_pool: web::Data<Pool>,
|
||||
request_data: web::Json<TokenRequest>,
|
||||
) -> Result<HttpResponse, HttpError> {
|
||||
if request_data.grant_type != "password".to_string() {
|
||||
Err(ValidationError("unsupported grant type"))?;
|
||||
if &request_data.grant_type != "password" {
|
||||
return Err(ValidationError("unsupported grant type").into());
|
||||
}
|
||||
let db_client = &**get_database_client(&db_pool).await?;
|
||||
let user = get_user_by_wallet_address(
|
||||
|
@ -32,7 +32,7 @@ async fn token_view(
|
|||
).map_err(|_| HttpError::InternalError)?;
|
||||
if !password_correct {
|
||||
// Invalid signature/password
|
||||
Err(ValidationError("incorrect password"))?;
|
||||
return Err(ValidationError("incorrect password").into());
|
||||
}
|
||||
let access_token = generate_access_token();
|
||||
let created_at = Utc::now();
|
||||
|
|
|
@ -22,7 +22,7 @@ fn parse_profile_query(query: &str) ->
|
|||
.ok_or(ValidationError("invalid search query"))?
|
||||
.as_str().to_string();
|
||||
let maybe_instance = acct_caps.name("instance")
|
||||
.and_then(|val| Some(val.as_str().to_string()));
|
||||
.map(|val| val.as_str().to_string());
|
||||
Ok((username, maybe_instance))
|
||||
}
|
||||
|
||||
|
@ -39,7 +39,7 @@ async fn search_profiles(
|
|||
},
|
||||
};
|
||||
let mut profiles = search_profile(db_client, &username, instance.as_ref()).await?;
|
||||
if profiles.len() == 0 && instance.is_some() {
|
||||
if profiles.is_empty() && instance.is_some() {
|
||||
let instance_host = instance.unwrap();
|
||||
let media_dir = config.media_dir();
|
||||
match fetch_profile(&username, &instance_host, &media_dir).await {
|
||||
|
|
|
@ -18,7 +18,7 @@ async fn search_view(
|
|||
) -> Result<HttpResponse, HttpError> {
|
||||
let db_client = &mut **get_database_client(&db_pool).await?;
|
||||
get_current_user(db_client, auth.token()).await?;
|
||||
let results = search(&config, db_client, &query_params.q.trim()).await?;
|
||||
let results = search(&config, db_client, query_params.q.trim()).await?;
|
||||
Ok(HttpResponse::Ok().json(results))
|
||||
}
|
||||
|
||||
|
|
|
@ -182,7 +182,7 @@ async fn favourite(
|
|||
let activity = create_activity_like(
|
||||
&config.instance_url(),
|
||||
¤t_user.profile,
|
||||
&object_id,
|
||||
object_id,
|
||||
);
|
||||
deliver_activity(&config, ¤t_user, activity, vec![remote_actor]);
|
||||
}
|
||||
|
@ -238,7 +238,7 @@ async fn make_permanent(
|
|||
let image_path = config.media_dir().join(&attachment.file_name);
|
||||
let image_data = std::fs::read(image_path)
|
||||
.map_err(|_| HttpError::InternalError)?;
|
||||
let image_cid = ipfs_store::add(&ipfs_api_url, image_data).await
|
||||
let image_cid = ipfs_store::add(ipfs_api_url, image_data).await
|
||||
.map_err(|_| HttpError::InternalError)?;
|
||||
set_attachment_ipfs_cid(db_client, &attachment.id, &image_cid).await?;
|
||||
image_cid
|
||||
|
@ -259,7 +259,7 @@ async fn make_permanent(
|
|||
let post_metadata_json = serde_json::to_string(&post_metadata)
|
||||
.map_err(|_| HttpError::InternalError)?
|
||||
.as_bytes().to_vec();
|
||||
let post_metadata_cid = ipfs_store::add(&ipfs_api_url, post_metadata_json).await
|
||||
let post_metadata_cid = ipfs_store::add(ipfs_api_url, post_metadata_json).await
|
||||
.map_err(|_| HttpError::InternalError)?;
|
||||
|
||||
// Update post
|
||||
|
@ -284,14 +284,14 @@ async fn get_signature(
|
|||
let post = get_post_by_id(db_client, &status_id).await?;
|
||||
if post.author.id != current_user.id {
|
||||
// Users can only tokenize their own posts
|
||||
Err(HttpError::NotFoundError("post"))?;
|
||||
return Err(HttpError::NotFoundError("post"));
|
||||
}
|
||||
let ipfs_cid = post.ipfs_cid
|
||||
// Post metadata is not immutable
|
||||
.ok_or(HttpError::ValidationError("post is not immutable".into()))?;
|
||||
let token_uri = get_ipfs_url(&ipfs_cid);
|
||||
let signature = create_mint_signature(
|
||||
&contract_config,
|
||||
contract_config,
|
||||
¤t_user.wallet_address,
|
||||
&token_uri,
|
||||
).map_err(|_| HttpError::InternalError)?;
|
||||
|
|
|
@ -13,7 +13,7 @@ pub struct DeletionQueue {
|
|||
impl DeletionQueue {
|
||||
pub async fn process(self, config: &Config) -> () {
|
||||
remove_files(self.files, &config.media_dir());
|
||||
if self.ipfs_objects.len() > 0 {
|
||||
if self.ipfs_objects.is_empty() {
|
||||
match &config.ipfs_api_url {
|
||||
Some(ipfs_api_url) => {
|
||||
ipfs_store::remove(ipfs_api_url, self.ipfs_objects).await
|
||||
|
|
|
@ -93,7 +93,7 @@ pub async fn get_notifications(
|
|||
&[&recipient_id],
|
||||
).await?;
|
||||
let mut notifications: Vec<Notification> = rows.iter()
|
||||
.map(|row| Notification::try_from(row))
|
||||
.map(Notification::try_from)
|
||||
.collect::<Result<_, _>>()?;
|
||||
let posts = notifications.iter_mut()
|
||||
.filter_map(|item| item.post.as_mut())
|
||||
|
|
|
@ -53,7 +53,7 @@ pub fn replace_mentions(
|
|||
) -> String {
|
||||
let mention_re = Regex::new(MENTION_RE).unwrap();
|
||||
let result = mention_re.replace_all(text, |caps: &Captures| {
|
||||
let acct = pattern_to_acct(&caps, instance_host);
|
||||
let acct = pattern_to_acct(caps, instance_host);
|
||||
match mention_map.get(&acct) {
|
||||
Some(profile) => {
|
||||
// Replace with a link
|
||||
|
|
|
@ -63,7 +63,7 @@ pub async fn get_home_timeline(
|
|||
&[¤t_user_id],
|
||||
).await?;
|
||||
let posts: Vec<Post> = rows.iter()
|
||||
.map(|row| Post::try_from(row))
|
||||
.map(Post::try_from)
|
||||
.collect::<Result<_, _>>()?;
|
||||
Ok(posts)
|
||||
}
|
||||
|
@ -98,7 +98,7 @@ pub async fn get_posts_by_author(
|
|||
&[&account_id],
|
||||
).await?;
|
||||
let posts: Vec<Post> = rows.iter()
|
||||
.map(|row| Post::try_from(row))
|
||||
.map(Post::try_from)
|
||||
.collect::<Result<_, _>>()?;
|
||||
Ok(posts)
|
||||
}
|
||||
|
@ -257,9 +257,9 @@ pub async fn get_thread(
|
|||
&[&post_id],
|
||||
).await?;
|
||||
let posts: Vec<Post> = rows.iter()
|
||||
.map(|row| Post::try_from(row))
|
||||
.map(Post::try_from)
|
||||
.collect::<Result<_, _>>()?;
|
||||
if posts.len() == 0 {
|
||||
if posts.is_empty() {
|
||||
return Err(DatabaseError::NotFound("post"));
|
||||
}
|
||||
Ok(posts)
|
||||
|
|
|
@ -125,7 +125,7 @@ impl PostCreateData {
|
|||
pub fn validate(&mut self) -> Result<(), ValidationError> {
|
||||
let content_safe = clean_html(&self.content);
|
||||
let content_trimmed = content_safe.trim();
|
||||
if content_trimmed == "" {
|
||||
if content_trimmed.is_empty() {
|
||||
return Err(ValidationError("post can not be empty"));
|
||||
}
|
||||
self.content = content_trimmed.to_string();
|
||||
|
|
|
@ -148,7 +148,7 @@ impl ProfileUpdateData {
|
|||
field.value = clean_html(&field.value);
|
||||
field
|
||||
})
|
||||
.filter(|field| field.name.len() > 0)
|
||||
.filter(|field| !field.name.is_empty())
|
||||
.collect();
|
||||
// Validate extra fields
|
||||
if self.extra_fields.len() >= 10 {
|
||||
|
|
|
@ -45,7 +45,7 @@ pub async fn get_relationships(
|
|||
&[&source_id, &target_ids],
|
||||
).await?;
|
||||
let relationships = rows.iter()
|
||||
.map(|row| Relationship::try_from(row))
|
||||
.map(Relationship::try_from)
|
||||
.collect::<Result<_, _>>()?;
|
||||
Ok(relationships)
|
||||
}
|
||||
|
|
|
@ -123,7 +123,7 @@ pub async fn create_user(
|
|||
&[&invite_code],
|
||||
).await?;
|
||||
if updated_count == 0 {
|
||||
Err(DatabaseError::NotFound("invite code"))?;
|
||||
return Err(DatabaseError::NotFound("invite code"));
|
||||
}
|
||||
}
|
||||
// Create profile
|
||||
|
|
|
@ -34,7 +34,7 @@ pub fn serialize_private_key(
|
|||
pub fn deserialize_private_key(
|
||||
private_key_pem: &str,
|
||||
) -> Result<RsaPrivateKey, rsa::pkcs8::Error> {
|
||||
RsaPrivateKey::from_pkcs8_pem(&private_key_pem)
|
||||
RsaPrivateKey::from_pkcs8_pem(private_key_pem)
|
||||
}
|
||||
|
||||
pub fn get_public_key_pem(
|
||||
|
@ -47,7 +47,7 @@ pub fn get_public_key_pem(
|
|||
pub fn deserialize_public_key(
|
||||
public_key_pem: &str,
|
||||
) -> Result<RsaPublicKey, rsa::pkcs8::Error> {
|
||||
RsaPublicKey::from_public_key_pem(&public_key_pem.trim())
|
||||
RsaPublicKey::from_public_key_pem(public_key_pem.trim())
|
||||
}
|
||||
|
||||
pub fn sign_message(
|
||||
|
|
|
@ -1,6 +1,6 @@
|
|||
use std::fs::{remove_file, File};
|
||||
use std::io::prelude::*;
|
||||
use std::path::PathBuf;
|
||||
use std::path::Path;
|
||||
|
||||
use mime_guess::get_mime_extensions_str;
|
||||
use mime_sniffer::MimeTypeSniffer;
|
||||
|
@ -18,7 +18,7 @@ pub enum FileError {
|
|||
InvalidMediaType,
|
||||
}
|
||||
|
||||
pub fn save_file(data: Vec<u8>, output_dir: &PathBuf) -> Result<String, FileError> {
|
||||
pub fn save_file(data: Vec<u8>, output_dir: &Path) -> Result<String, FileError> {
|
||||
let digest = Sha256::digest(&data);
|
||||
let mut file_name = hex::encode(digest);
|
||||
let maybe_extension = data.sniff_mime_type()
|
||||
|
@ -34,13 +34,13 @@ pub fn save_file(data: Vec<u8>, output_dir: &PathBuf) -> Result<String, FileErro
|
|||
Ok(file_name)
|
||||
}
|
||||
|
||||
fn sniff_media_type(data: &Vec<u8>) -> Option<String> {
|
||||
fn sniff_media_type(data: &[u8]) -> Option<String> {
|
||||
data.sniff_mime_type().map(|val| val.to_string())
|
||||
}
|
||||
|
||||
pub fn save_b64_file(
|
||||
b64data: &str,
|
||||
output_dir: &PathBuf,
|
||||
output_dir: &Path,
|
||||
) -> Result<(String, Option<String>), FileError> {
|
||||
let data = base64::decode(b64data)?;
|
||||
let media_type = sniff_media_type(&data);
|
||||
|
@ -50,7 +50,7 @@ pub fn save_b64_file(
|
|||
|
||||
pub fn save_validated_b64_file(
|
||||
b64data: &str,
|
||||
output_dir: &PathBuf,
|
||||
output_dir: &Path,
|
||||
media_type_prefix: &str,
|
||||
) -> Result<(String, String), FileError> {
|
||||
let data = base64::decode(b64data)?;
|
||||
|
@ -67,7 +67,7 @@ pub fn get_file_url(instance_url: &str, file_name: &str) -> String {
|
|||
format!("{}/media/{}", instance_url, file_name)
|
||||
}
|
||||
|
||||
pub fn remove_files(files: Vec<String>, from_dir: &PathBuf) -> () {
|
||||
pub fn remove_files(files: Vec<String>, from_dir: &Path) -> () {
|
||||
for file_name in files {
|
||||
let file_path = from_dir.join(&file_name);
|
||||
let file_path_str = file_path.to_string_lossy();
|
||||
|
|
|
@ -6,7 +6,7 @@ use crate::activitypub::views::get_actor_url;
|
|||
use crate::activitypub::constants::ACTIVITY_CONTENT_TYPE;
|
||||
use crate::config::{Config, Instance};
|
||||
use crate::database::{Pool, get_database_client};
|
||||
use crate::errors::HttpError;
|
||||
use crate::errors::{HttpError, ValidationError};
|
||||
use crate::models::users::queries::is_registered_user;
|
||||
use super::types::{
|
||||
JRD_CONTENT_TYPE,
|
||||
|
@ -24,22 +24,22 @@ async fn get_user_info(
|
|||
// https://datatracker.ietf.org/doc/html/rfc7565#section-7
|
||||
let uri_regexp = Regex::new(r"acct:(?P<user>\w+)@(?P<instance>.+)").unwrap();
|
||||
let uri_caps = uri_regexp.captures(&query_params.resource)
|
||||
.ok_or(HttpError::ValidationError("invalid query target".into()))?;
|
||||
.ok_or(ValidationError("invalid query target"))?;
|
||||
let username = uri_caps.name("user")
|
||||
.ok_or(HttpError::ValidationError("invalid query target".into()))?
|
||||
.ok_or(ValidationError("invalid query target"))?
|
||||
.as_str();
|
||||
let instance_host = uri_caps.name("instance")
|
||||
.ok_or(HttpError::ValidationError("invalid query target".into()))?
|
||||
.ok_or(ValidationError("invalid query target"))?
|
||||
.as_str();
|
||||
|
||||
if instance_host != instance.host() {
|
||||
// Wrong instance
|
||||
return Err(HttpError::NotFoundError("user"));
|
||||
}
|
||||
if !is_registered_user(db_client, &username).await? {
|
||||
if !is_registered_user(db_client, username).await? {
|
||||
return Err(HttpError::NotFoundError("user"));
|
||||
}
|
||||
let actor_url = get_actor_url(&instance.url(), &username);
|
||||
let actor_url = get_actor_url(&instance.url(), username);
|
||||
let link = Link {
|
||||
rel: "self".to_string(),
|
||||
link_type: Some(ACTIVITY_CONTENT_TYPE.to_string()),
|
||||
|
|
Loading…
Reference in a new issue