username update

This commit is contained in:
realaravinth 2021-08-12 17:13:17 +05:30
parent 751a1046fb
commit a65b1c219c
No known key found for this signature in database
GPG key ID: AD9F0F08E855ED88
15 changed files with 1140 additions and 1285 deletions

View file

@ -31,6 +31,7 @@
"webpack-dev-server": "^3.1.14"
},
"dependencies": {
"mcaptcha-browser": "./browser/pkg/"
"mcaptcha-browser": "./browser/pkg/",
"mcaptcha-glue": "^0.1.0-alpha-1"
}
}

View file

@ -1,19 +1,19 @@
/*
* Copyright (C) 2021 Aravinth Manivannan <realaravinth@batsense.net>
*
* This program is free software: you can redistribute it and/or modify
* it under the terms of the GNU Affero General Public License as
* published by the Free Software Foundation, either version 3 of the
* License, or (at your option) any later version.
*
* This program is distributed in the hope that it will be useful,
* but WITHOUT ANY WARRANTY; without even the implied warranty of
* MERCHANTABILITY or FITNESS FOR A PARTICULAR PURPOSE. See the
* GNU Affero General Public License for more details.
*
* You should have received a copy of the GNU Affero General Public License
* along with this program. If not, see <https://www.gnu.org/licenses/>.
*/
* Copyright (C) 2021 Aravinth Manivannan <realaravinth@batsense.net>
*
* This program is free software: you can redistribute it and/or modify
* it under the terms of the GNU Affero General Public License as
* published by the Free Software Foundation, either version 3 of the
* License, or (at your option) any later version.
*
* This program is distributed in the hope that it will be useful,
* but WITHOUT ANY WARRANTY; without even the implied warranty of
* MERCHANTABILITY or FITNESS FOR A PARTICULAR PURPOSE. See the
* GNU Affero General Public License for more details.
*
* You should have received a copy of the GNU Affero General Public License
* along with this program. If not, see <https://www.gnu.org/licenses/>.
*/
use std::borrow::Cow;
use actix_identity::Identity;

View file

@ -38,6 +38,7 @@ pub mod routes {
pub update_password: &'static str,
pub update_secret: &'static str,
pub username_exists: &'static str,
pub update_username: &'static str,
}
impl Account {
@ -47,6 +48,7 @@ pub mod routes {
let delete = "/api/v1/account/delete";
let email_exists = "/api/v1/account/email/exists";
let username_exists = "/api/v1/account/username/exists";
let update_username = "/api/v1/account/username/update";
let update_email = "/api/v1/account/email/update";
let update_password = "/api/v1/account/password/update";
Account {
@ -57,6 +59,7 @@ pub mod routes {
update_password,
update_secret,
username_exists,
update_username,
}
}
}

View file

@ -19,6 +19,7 @@ use actix_web::http::StatusCode;
use actix_web::test;
use super::email::*;
use super::username::Username;
use super::*;
use crate::api::v1::auth::runners::Password;
use crate::api::v1::ROUTES;
@ -149,7 +150,7 @@ async fn email_udpate_password_validation_del_userworks() {
.await;
assert_eq!(email_update_resp.status(), StatusCode::OK);
// check duplicate email while dupate email
// check duplicate email while duplicate email
email_payload.email = EMAIL2.into();
bad_post_req_test(
NAME,
@ -197,3 +198,48 @@ async fn email_udpate_password_validation_del_userworks() {
let txt: ErrorToResponse = test::read_body_json(account_not_found_resp).await;
assert_eq!(txt.error, format!("{}", ServiceError::AccountNotFound));
}
#[actix_rt::test]
async fn username_update_works() {
const NAME: &str = "testuserupda";
const EMAIL: &str = "testuserupda@sss.com";
const EMAIL2: &str = "testuserupda2@sss.com";
const PASSWORD: &str = "longpassword2";
const NAME2: &str = "terstusrtds";
const NAME_CHANGE: &str = "terstusrtdsxx";
{
let data = Data::new().await;
delete_user(NAME, &data).await;
delete_user(NAME2, &data).await;
}
let _ = register_and_signin(NAME2, EMAIL2, PASSWORD).await;
let (data, _creds, signin_resp) = register_and_signin(NAME, EMAIL, PASSWORD).await;
let cookies = get_cookie!(signin_resp);
let app = get_app!(data).await;
// update username
let mut username_udpate = Username {
username: NAME_CHANGE.into(),
};
let username_update_resp = test::call_service(
&app,
post_request!(&username_udpate, ROUTES.account.update_username)
.cookie(cookies)
.to_request(),
)
.await;
assert_eq!(username_update_resp.status(), StatusCode::OK);
// check duplicate username with duplicate username
username_udpate.username = NAME2.into();
bad_post_req_test(
NAME_CHANGE,
PASSWORD,
ROUTES.account.update_username,
&username_udpate,
ServiceError::UsernameTaken,
)
.await;
}

View file

@ -1,20 +1,24 @@
/*
* Copyright (C) 2021 Aravinth Manivannan <realaravinth@batsense.net>
*
* This program is free software: you can redistribute it and/or modify
* it under the terms of the GNU Affero General Public License as
* published by the Free Software Foundation, either version 3 of the
* License, or (at your option) any later version.
*
* This program is distributed in the hope that it will be useful,
* but WITHOUT ANY WARRANTY; without even the implied warranty of
* MERCHANTABILITY or FITNESS FOR A PARTICULAR PURPOSE. See the
* GNU Affero General Public License for more details.
*
* You should have received a copy of the GNU Affero General Public License
* along with this program. If not, see <https://www.gnu.org/licenses/>.
*/
* Copyright (C) 2021 Aravinth Manivannan <realaravinth@batsense.net>
*
* This program is free software: you can redistribute it and/or modify
* it under the terms of the GNU Affero General Public License as
* published by the Free Software Foundation, either version 3 of the
* License, or (at your option) any later version.
*
* This program is distributed in the hope that it will be useful,
* but WITHOUT ANY WARRANTY; without even the implied warranty of
* MERCHANTABILITY or FITNESS FOR A PARTICULAR PURPOSE. See the
* GNU Affero General Public License for more details.
*
* You should have received a copy of the GNU Affero General Public License
* along with this program. If not, see <https://www.gnu.org/licenses/>.
*/
use std::borrow::Cow;
use actix_identity::Identity;
use actix_web::{web, HttpResponse, Responder};
use serde::{Deserialize, Serialize};
use super::{AccountCheckPayload, AccountCheckResp};
use crate::errors::*;
@ -55,6 +59,52 @@ pub mod runners {
}
}
#[derive(Clone, Debug, Deserialize, Serialize)]
pub struct Username {
pub username: String,
}
/// update username
#[my_codegen::post(
path = "crate::V1_API_ROUTES.account.update_username",
wrap = "crate::CheckLogin"
)]
async fn set_username(
id: Identity,
payload: web::Json<Username>,
data: AppData,
) -> ServiceResult<impl Responder> {
let username = id.identity().unwrap();
let processed_uname = data.creds.username(&payload.username)?;
let res = sqlx::query!(
"UPDATE mcaptcha_users set name = $1
WHERE name = $2",
&processed_uname,
&username,
)
.execute(&data.db)
.await;
if res.is_err() {
if let Err(sqlx::Error::Database(err)) = res {
if err.code() == Some(Cow::from("23505"))
&& err.message().contains("mcaptcha_users_name_key")
{
return Err(ServiceError::UsernameTaken);
} else {
return Err(sqlx::Error::Database(err).into());
}
};
}
id.forget();
id.remember(processed_uname);
Ok(HttpResponse::Ok())
}
pub fn services(cfg: &mut actix_web::web::ServiceConfig) {
cfg.service(username_exists);
cfg.service(set_username);
}

View file

@ -1,20 +1,19 @@
/*
* Copyright (C) 2021 Aravinth Manivannan <realaravinth@batsense.net>
*
* This program is free software: you can redistribute it and/or modify
* it under the terms of the GNU Affero General Public License as
* published by the Free Software Foundation, either version 3 of the
* License, or (at your option) any later version.
*
* This program is distributed in the hope that it will be useful,
* but WITHOUT ANY WARRANTY; without even the implied warranty of
* MERCHANTABILITY or FITNESS FOR A PARTICULAR PURPOSE. See the
* GNU Affero General Public License for more details.
*
* You should have received a copy of the GNU Affero General Public License
* along with this program. If not, see <https://www.gnu.org/licenses/>.
*/
* Copyright (C) 2021 Aravinth Manivannan <realaravinth@batsense.net>
*
* This program is free software: you can redistribute it and/or modify
* it under the terms of the GNU Affero General Public License as
* published by the Free Software Foundation, either version 3 of the
* License, or (at your option) any later version.
*
* This program is distributed in the hope that it will be useful,
* but WITHOUT ANY WARRANTY; without even the implied warranty of
* MERCHANTABILITY or FITNESS FOR A PARTICULAR PURPOSE. See the
* GNU Affero General Public License for more details.
*
* You should have received a copy of the GNU Affero General Public License
* along with this program. If not, see <https://www.gnu.org/licenses/>.
*/
use actix_identity::Identity;
use actix_web::{web, HttpResponse, Responder};
use serde::{Deserialize, Serialize};
@ -111,21 +110,6 @@ async fn get_duration(
pub fn services(cfg: &mut web::ServiceConfig) {
cfg.service(get_duration);
cfg.service(update_duration);
// use crate::define_resource;
// use crate::V1_API_ROUTES;
//
// define_resource!(
// cfg,
// V1_API_ROUTES.duration.get,
// Methods::ProtectPost,
// get_duration
// );
// define_resource!(
// cfg,
// V1_API_ROUTES.duration.update,
// Methods::ProtectPost,
// update_duration
// );
}
#[cfg(test)]

View file

@ -37,7 +37,7 @@ async fn register_demo_user(data: &AppData) -> ServiceResult<()> {
val: DEMO_USER.into(),
};
if !username_exists(&user_exists_payload, &data).await?.exists {
if !username_exists(&user_exists_payload, data).await?.exists {
let register_payload = Register {
username: DEMO_USER.into(),
password: DEMO_PASSWORD.into(),

View file

@ -1,19 +1,19 @@
/*
* Copyright (C) 2021 Aravinth Manivannan <realaravinth@batsense.net>
*
* This program is free software: you can redistribute it and/or modify
* it under the terms of the GNU Affero General Public License as
* published by the Free Software Foundation, either version 3 of the
* License, or (at your option) any later version.
*
* This program is distributed in the hope that it will be useful,
* but WITHOUT ANY WARRANTY; without even the implied warranty of
* MERCHANTABILITY or FITNESS FOR A PARTICULAR PURPOSE. See the
* GNU Affero General Public License for more details.
*
* You should have received a copy of the GNU Affero General Public License
* along with this program. If not, see <https://www.gnu.org/licenses/>.
*/
* Copyright (C) 2021 Aravinth Manivannan <realaravinth@batsense.net>
*
* This program is free software: you can redistribute it and/or modify
* it under the terms of the GNU Affero General Public License as
* published by the Free Software Foundation, either version 3 of the
* License, or (at your option) any later version.
*
* This program is distributed in the hope that it will be useful,
* but WITHOUT ANY WARRANTY; without even the implied warranty of
* MERCHANTABILITY or FITNESS FOR A PARTICULAR PURPOSE. See the
* GNU Affero General Public License for more details.
*
* You should have received a copy of the GNU Affero General Public License
* along with this program. If not, see <https://www.gnu.org/licenses/>.
*/
use std::borrow::Cow;
use actix_web::body::Body;
@ -44,10 +44,7 @@ pub mod routes {
}
pub fn services(cfg: &mut web::ServiceConfig) {
use crate::define_resource;
define_resource!(cfg, &DOCS.home[0..DOCS.home.len() - 1], Methods::Get, index);
define_resource!(cfg, DOCS.spec, Methods::Get, spec);
define_resource!(cfg, DOCS.assets, Methods::Get, dist);
cfg.service(index).service(spec).service(dist);
}
#[derive(RustEmbed)]
@ -72,16 +69,19 @@ pub fn handle_embedded_file(path: &str) -> HttpResponse {
}
}
#[my_codegen::get(path = "DOCS.assets")]
async fn dist(path: web::Path<String>) -> impl Responder {
handle_embedded_file(&path)
}
#[my_codegen::get(path = "DOCS.spec")]
async fn spec() -> HttpResponse {
HttpResponse::Ok()
.content_type("appilcation/json")
.body(&*crate::OPEN_API_DOC)
}
#[my_codegen::get(path = "&DOCS.home[0..DOCS.home.len() -1]")]
async fn index() -> HttpResponse {
handle_embedded_file("index.html")
}

View file

@ -139,8 +139,8 @@ async fn main() -> std::io::Result<()> {
actix_middleware::TrailingSlash::Trim,
))
.configure(v1::services)
.configure(widget::services)
.configure(docs::services)
.configure(widget::services)
.configure(pages::services)
.configure(static_assets::services)
.app_data(get_json_err())

View file

@ -49,6 +49,9 @@ lazy_static! {
.unwrap();
}
const ERROR_ROUTE: &str = "/error/{id}";
#[my_codegen::get(path = "ERROR_ROUTE")]
async fn error(path: web::Path<usize>) -> impl Responder {
let resp = match path.into_inner() {
500 => HttpResponse::InternalServerError()
@ -64,9 +67,7 @@ async fn error(path: web::Path<usize>) -> impl Responder {
}
pub fn services(cfg: &mut web::ServiceConfig) {
use crate::define_resource;
define_resource!(cfg, "/error/{id}", Methods::Get, error);
cfg.service(error);
}
pub mod routes {

View file

@ -1,19 +1,19 @@
/*
* Copyright (C) 2021 Aravinth Manivannan <realaravinth@batsense.net>
*
* This program is free software: you can redistribute it and/or modify
* it under the terms of the GNU Affero General Public License as
* published by the Free Software Foundation, either version 3 of the
* License, or (at your option) any later version.
*
* This program is distributed in the hope that it will be useful,
* but WITHOUT ANY WARRANTY; without even the implied warranty of
* MERCHANTABILITY or FITNESS FOR A PARTICULAR PURPOSE. See the
* GNU Affero General Public License for more details.
*
* You should have received a copy of the GNU Affero General Public License
* along with this program. If not, see <https://www.gnu.org/licenses/>.
*/
* Copyright (C) 2021 Aravinth Manivannan <realaravinth@batsense.net>
*
* This program is free software: you can redistribute it and/or modify
* it under the terms of the GNU Affero General Public License as
* published by the Free Software Foundation, either version 3 of the
* License, or (at your option) any later version.
*
* This program is distributed in the hope that it will be useful,
* but WITHOUT ANY WARRANTY; without even the implied warranty of
* MERCHANTABILITY or FITNESS FOR A PARTICULAR PURPOSE. See the
* GNU Affero General Public License for more details.
*
* You should have received a copy of the GNU Affero General Public License
* along with this program. If not, see <https://www.gnu.org/licenses/>.
*/
#[allow(dead_code)]
pub enum Methods {

View file

@ -0,0 +1,14 @@
<div style="width: 304px; height: 78px;">
<iframe
title="mCaptcha"
src="<.= crate::WIDGET_ROUTES.verification_widget .>/?sitekey=<.= ROOT_KEY.>"
role="presentation"
name="mcaptcha-widget__iframe"
id="mcaptcha-widget__iframe"
scrolling="no"
sandbox="allow-same-origin allow-scripts"
width="304"
height="78"
frameborder="0"
></iframe>
</div>

View file

@ -0,0 +1,19 @@
/*
* Copyright (C) 2021 Aravinth Manivannan <realaravinth@batsense.net>
*
* This program is free software: you can redistribute it and/or modify
* it under the terms of the GNU Affero General Public License as
* published by the Free Software Foundation, either version 3 of the
* License, or (at your option) any later version.
*
* This program is distributed in the hope that it will be useful,
* but WITHOUT ANY WARRANTY; without even the implied warranty of
* MERCHANTABILITY or FITNESS FOR A PARTICULAR PURPOSE. See the
* GNU Affero General Public License for more details.
*
* You should have received a copy of the GNU Affero General Public License
* along with this program. If not, see <https://www.gnu.org/licenses/>.
*/
import init from 'mcaptcha-glue';
export const register = () => init();

View file

@ -14,6 +14,7 @@
* You should have received a copy of the GNU Affero General Public License
* along with this program. If not, see <https://www.gnu.org/licenses/>.
*/
import {init} from 'mcaptcha-glue';
import VIEWS from '../../../views/v1/routes';
@ -68,4 +69,5 @@ export const index = () => {
const form = <HTMLFontElement>document.getElementById('form');
form.addEventListener('submit', login, true);
registerShowPassword();
init();
};

2101
yarn.lock

File diff suppressed because it is too large Load diff