Login for the wasm interface
This commit is contained in:
+5
-1
@@ -281,7 +281,7 @@ pub async fn webservice(
|
||||
.wrap(IdentityService::new(
|
||||
CookieIdentityPolicy::new(&[0; 32])
|
||||
.name("auth-cookie")
|
||||
.secure(false),
|
||||
.secure(true),
|
||||
))
|
||||
.data(tera.clone())
|
||||
.service(actix_web_static_files::ResourceFiles::new(
|
||||
@@ -377,6 +377,10 @@ pub async fn webservice(
|
||||
.route(
|
||||
"/get_logged_user/",
|
||||
web::post().to(views::get_logged_user_json),
|
||||
)
|
||||
.route(
|
||||
"/login_user/",
|
||||
web::post().to(views::process_login_json),
|
||||
),
|
||||
)
|
||||
// login to the admin area
|
||||
|
||||
@@ -213,12 +213,6 @@ impl NewUser {
|
||||
}
|
||||
}
|
||||
|
||||
#[derive(Debug, Deserialize)]
|
||||
pub struct LoginUser {
|
||||
pub username: String,
|
||||
pub password: String,
|
||||
}
|
||||
|
||||
#[async_trait]
|
||||
pub trait LinkDbOperations<T> {
|
||||
async fn get_link_by_code(code: &str, server_config: &ServerConfig) -> Result<T, ServerError>;
|
||||
|
||||
+54
-7
@@ -17,13 +17,13 @@ use queries::{authenticate, Role};
|
||||
use shared::apirequests::{
|
||||
general::{Message, Status},
|
||||
links::{LinkDelta, LinkRequestForm},
|
||||
users::{UserDelta, UserRequestForm},
|
||||
users::{LoginUser, UserDelta, UserRequestForm},
|
||||
};
|
||||
use tera::{Context, Tera};
|
||||
use tracing::{error, info, instrument, warn};
|
||||
|
||||
use crate::forms::LinkForm;
|
||||
use crate::models::{LoginUser, NewUser};
|
||||
use crate::models::NewUser;
|
||||
use crate::queries;
|
||||
use crate::ServerError;
|
||||
|
||||
@@ -74,7 +74,6 @@ pub async fn wasm_app(config: web::Data<crate::ServerConfig>) -> Result<HttpResp
|
||||
Ok(HttpResponse::Ok().body(
|
||||
r#"<!DOCTYPE html>
|
||||
<html>
|
||||
|
||||
<head>
|
||||
<meta charset="utf-8" />
|
||||
<meta name="viewport" content="width=device-width, initial-scale=1, shrink-to-fit=no" />
|
||||
@@ -84,7 +83,6 @@ pub async fn wasm_app(config: web::Data<crate::ServerConfig>) -> Result<HttpResp
|
||||
<link rel="stylesheet" href="/static/admin.css">
|
||||
<title>Server integration example</title>
|
||||
</head>
|
||||
|
||||
<body>
|
||||
<section id="app"><div class="lds-ellipsis">Loading: <div></div><div></div><div></div><div></div></div></section>
|
||||
<script type="module">
|
||||
@@ -92,7 +90,6 @@ pub async fn wasm_app(config: web::Data<crate::ServerConfig>) -> Result<HttpResp
|
||||
init('/app/pkg/package_bg.wasm');
|
||||
</script>
|
||||
</body>
|
||||
|
||||
</html>"#,
|
||||
))
|
||||
}
|
||||
@@ -178,7 +175,7 @@ pub async fn get_logged_user_json(
|
||||
let user = authenticate(&id, &config).await?;
|
||||
match user {
|
||||
Role::NotAuthenticated | Role::Disabled => {
|
||||
Err(ServerError::User("User not logged in!".to_string()))
|
||||
Ok(HttpResponse::Unauthorized().finish())
|
||||
}
|
||||
Role::Regular { user } | Role::Admin { user } => Ok(HttpResponse::Ok().json2(&user)),
|
||||
}
|
||||
@@ -484,7 +481,57 @@ pub async fn process_login(
|
||||
}
|
||||
Err(e) => {
|
||||
info!("Failed to login: {}", e);
|
||||
Ok(redirect_builder("/admin/login/"))
|
||||
Ok(HttpResponse::Unauthorized().json2(&Status::Error(Message {
|
||||
message: "Failed to Login".to_string(),
|
||||
})))
|
||||
}
|
||||
}
|
||||
}
|
||||
|
||||
#[instrument(skip(id))]
|
||||
pub async fn process_login_json(
|
||||
data: web::Json<LoginUser>,
|
||||
config: web::Data<crate::ServerConfig>,
|
||||
id: Identity,
|
||||
) -> Result<HttpResponse, ServerError> {
|
||||
// query the username to see if a user by that name exists.
|
||||
let user = queries::get_user_by_name(&data.username, &config).await;
|
||||
|
||||
match user {
|
||||
Ok(u) => {
|
||||
// get the password hash
|
||||
if let Some(hash) = &u.password.secret {
|
||||
// get the servers secret
|
||||
let secret = &config.secret;
|
||||
// validate the secret
|
||||
let valid = Verifier::default()
|
||||
.with_hash(hash)
|
||||
.with_password(&data.password)
|
||||
.with_secret_key(secret.secret.as_ref().expect("No secret available"))
|
||||
.verify()?;
|
||||
|
||||
// login the user
|
||||
if valid {
|
||||
info!("Log-in of user: {}", &u.username);
|
||||
let session_token = u.username.clone();
|
||||
id.remember(session_token);
|
||||
Ok(HttpResponse::Ok().json2(&u))
|
||||
} else {
|
||||
info!("Invalid password for user: {}", &u.username);
|
||||
Ok(redirect_builder("/admin/login/"))
|
||||
}
|
||||
} else {
|
||||
// should fail earlier if secret is missing.
|
||||
Ok(HttpResponse::Unauthorized().json2(&Status::Error(Message {
|
||||
message: "Failed to Login".to_string(),
|
||||
})))
|
||||
}
|
||||
}
|
||||
Err(e) => {
|
||||
info!("Failed to login: {}", e);
|
||||
Ok(HttpResponse::Unauthorized().json2(&Status::Error(Message {
|
||||
message: "Failed to Login".to_string(),
|
||||
})))
|
||||
}
|
||||
}
|
||||
}
|
||||
|
||||
@@ -35,6 +35,16 @@ form {
|
||||
background-color: #eae9ea;
|
||||
}
|
||||
|
||||
div.login div {
|
||||
width: 100%;
|
||||
height: 60px;
|
||||
display: table;
|
||||
}
|
||||
div.login input {
|
||||
padding: 15px;
|
||||
margin-bottom: 20px;
|
||||
}
|
||||
|
||||
.center table p {
|
||||
font-size: x-small;
|
||||
margin: 0;
|
||||
|
||||
Reference in New Issue
Block a user