use super::*;
use crate::settings::Settings;
use crate::{generate_random_string, send_email};
use bcrypt::verify;
use diesel::PgConnection;
use std::str::FromStr;
#[derive(Serialize, Deserialize, Debug)]
pub struct Login {
username_or_email: String,
password: String,
}
#[derive(Serialize, Deserialize)]
pub struct Register {
username: String,
email: Option<String>,
password: String,
password_verify: String,
admin: bool,
show_nsfw: bool,
}
#[derive(Serialize, Deserialize)]
pub struct SaveUserSettings {
show_nsfw: bool,
theme: String,
default_sort_type: i16,
default_listing_type: i16,
lang: String,
avatar: Option<String>,
email: Option<String>,
new_password: Option<String>,
new_password_verify: Option<String>,
old_password: Option<String>,
show_avatars: bool,
send_notifications_to_email: bool,
auth: String,
}
#[derive(Serialize, Deserialize)]
pub struct LoginResponse {
op: String,
jwt: String,
}
#[derive(Serialize, Deserialize)]
pub struct GetUserDetails {
user_id: Option<i32>,
username: Option<String>,
sort: String,
page: Option<i64>,
limit: Option<i64>,
community_id: Option<i32>,
saved_only: bool,
auth: Option<String>,
}
#[derive(Serialize, Deserialize)]
pub struct GetUserDetailsResponse {
op: String,
user: UserView,
follows: Vec<CommunityFollowerView>,
moderates: Vec<CommunityModeratorView>,
comments: Vec<CommentView>,
posts: Vec<PostView>,
admins: Vec<UserView>,
}
#[derive(Serialize, Deserialize)]
pub struct GetRepliesResponse {
op: String,
replies: Vec<ReplyView>,
}
#[derive(Serialize, Deserialize)]
pub struct GetUserMentionsResponse {
op: String,
mentions: Vec<UserMentionView>,
}
#[derive(Serialize, Deserialize)]
pub struct MarkAllAsRead {
auth: String,
}
#[derive(Serialize, Deserialize)]
pub struct AddAdmin {
user_id: i32,
added: bool,
auth: String,
}
#[derive(Serialize, Deserialize)]
pub struct AddAdminResponse {
op: String,
admins: Vec<UserView>,
}
#[derive(Serialize, Deserialize)]
pub struct BanUser {
user_id: i32,
ban: bool,
reason: Option<String>,
expires: Option<i64>,
auth: String,
}
#[derive(Serialize, Deserialize)]
pub struct BanUserResponse {
op: String,
user: UserView,
banned: bool,
}
#[derive(Serialize, Deserialize)]
pub struct GetReplies {
sort: String,
page: Option<i64>,
limit: Option<i64>,
unread_only: bool,
auth: String,
}
#[derive(Serialize, Deserialize)]
pub struct GetUserMentions {
sort: String,
page: Option<i64>,
limit: Option<i64>,
unread_only: bool,
auth: String,
}
#[derive(Serialize, Deserialize)]
pub struct EditUserMention {
user_mention_id: i32,
read: Option<bool>,
auth: String,
}
#[derive(Serialize, Deserialize, Clone)]
pub struct UserMentionResponse {
op: String,
mention: UserMentionView,
}
#[derive(Serialize, Deserialize)]
pub struct DeleteAccount {
password: String,
auth: String,
}
#[derive(Serialize, Deserialize)]
pub struct PasswordReset {
email: String,
}
#[derive(Serialize, Deserialize, Clone)]
pub struct PasswordResetResponse {
op: String,
}
#[derive(Serialize, Deserialize)]
pub struct PasswordChange {
token: String,
password: String,
password_verify: String,
}
impl Perform<LoginResponse> for Oper<Login> {
fn perform(&self, conn: &PgConnection) -> Result<LoginResponse, Error> {
let data: &Login = &self.data;
// Fetch that username / email
let user: User_ = match User_::find_by_email_or_username(&conn, &data.username_or_email) {
Ok(user) => user,
Err(_e) => return Err(APIError::err(&self.op, "couldnt_find_that_username_or_email").into()),
};
// Verify the password
let valid: bool = verify(&data.password, &user.password_encrypted).unwrap_or(false);
if !valid {
return Err(APIError::err(&self.op, "password_incorrect").into());
}
// Return the jwt
Ok(LoginResponse {
op: self.op.to_string(),
jwt: user.jwt(),
})
}
}
impl Perform<LoginResponse> for Oper<Register> {
fn perform(&self, conn: &PgConnection) -> Result<LoginResponse, Error> {
let data: &Register = &self.data;
// Make sure site has open registration
if let Ok(site) = SiteView::read(&conn) {
if !site.open_registration {
return Err(APIError::err(&self.op, "registration_closed").into());
}
}
// Make sure passwords match
if data.password != data.password_verify {
return Err(APIError::err(&self