dummy auth #2

This commit is contained in:
Jovi Hsu 2021-11-04 14:41:56 +08:00
parent c0868ff56a
commit c87b60a738
6 changed files with 134 additions and 45 deletions

View File

@ -21,6 +21,7 @@ actix-web = "3.3.2"
actix-files = "0.5.0" actix-files = "0.5.0"
actix-web-actors = "3.0.0" actix-web-actors = "3.0.0"
urlencoding = "2.1.0" urlencoding = "2.1.0"
serde = "1.0"
serde_json = "1.0" serde_json = "1.0"
rand = "0.8" rand = "0.8"

View File

@ -3,13 +3,18 @@ use actix_session::CookieSession;
use actix_web::http::{ContentEncoding, StatusCode}; use actix_web::http::{ContentEncoding, StatusCode};
use actix_web::*; use actix_web::*;
use femme;
use log::info; use log::info;
use rand::Rng; use rand::Rng;
mod user; mod user;
mod ws; mod ws;
// pub struct AppState ;
// impl Actor for AppState {
// type Context = actix::Context<Self>;
// }
const STATIC_DIR: &str = "./static/"; const STATIC_DIR: &str = "./static/";
const PAGE_INDEX: &str = "./static/index.html"; const PAGE_INDEX: &str = "./static/index.html";
const PAGE_NOT_FOUND: &str = "./static/p404.html"; const PAGE_NOT_FOUND: &str = "./static/p404.html";
@ -38,6 +43,7 @@ async fn main() -> std::io::Result<()> {
let private_key = rand::thread_rng().gen::<[u8; 32]>(); let private_key = rand::thread_rng().gen::<[u8; 32]>();
HttpServer::new(move || { HttpServer::new(move || {
App::new() App::new()
// .data(AppState)
.wrap(CookieSession::signed(&private_key).secure(false)) .wrap(CookieSession::signed(&private_key).secure(false))
.wrap(middleware::Compress::new(ContentEncoding::Gzip)) .wrap(middleware::Compress::new(ContentEncoding::Gzip))
.service(index) .service(index)

View File

@ -1,12 +1,63 @@
use actix::{Actor, Context, Handler, Message, MessageResponse};
use actix_web::*; use actix_web::*;
use serde::{Deserialize, Serialize};
use serde_json::json; use serde_json::json;
use log::info; use log::info;
#[post("/auth")] #[derive(Message)]
pub async fn auth(req: HttpRequest) -> Result<HttpResponse, Error> { #[rtype(result = "Self")]
info!("{:?}", req); #[derive(MessageResponse)]
Ok(HttpResponse::Ok() #[allow(dead_code)]
.content_type("application/json") enum AuthMessage {
.body(json!({"status": "success"}))) DoAuth,
AuthSuccess,
AuthFailure,
}
#[derive(Serialize, Deserialize, Debug)]
pub struct AuthInfo {
username: String,
password: String,
}
impl Actor for AuthInfo {
type Context = Context<Self>;
fn started(&mut self, _ctx: &mut Self::Context) {
info!("AuthInfo started");
info!("{:?}", self);
}
fn stopped(&mut self, _ctx: &mut Self::Context) {
info!("AuthInfo stopped");
}
}
impl Handler<AuthMessage> for AuthInfo {
type Result = AuthMessage;
fn handle(&mut self, _msg: AuthMessage, _ctx: &mut Context<Self>) -> Self::Result {
info!("AuthInfo handle");
AuthMessage::AuthSuccess
}
}
#[post("/auth")]
pub async fn auth(params: web::Json<AuthInfo>) -> Result<HttpResponse, Error> {
let auth = params.into_inner();
let auth_addr = auth.start();
let res = auth_addr.send(AuthMessage::DoAuth).await;
match res {
Ok(AuthMessage::AuthSuccess) => Ok(HttpResponse::Ok().json(json!({
"status": "success",
}))),
Ok(AuthMessage::AuthFailure) => Ok(HttpResponse::Ok().json(json!({
"status": "failure",
}))),
_ => Ok(HttpResponse::Ok().json(json!({
"status": "failure",
}))),
}
} }

View File

@ -1,10 +1,10 @@
use std::borrow::Cow; use std::borrow::Cow;
use crate::components::auth;
use crate::pages::{page_home::PageHome, page_not_found::PageNotFound, page_ssh::PageSsh}; use crate::pages::{page_home::PageHome, page_not_found::PageNotFound, page_ssh::PageSsh};
use yew::html::IntoPropValue; use yew::html::IntoPropValue;
use yew::prelude::*; use yew::prelude::*;
use yew::services::ConsoleService; use yew::services::ConsoleService;
use yew::virtual_dom::VNode;
use yew::Component; use yew::Component;
use yew_router::prelude::*; use yew_router::prelude::*;
use yew_router::{router::Router, Switch}; use yew_router::{router::Router, Switch};
@ -21,11 +21,11 @@ enum AppRoute {
NotFound, NotFound,
} }
impl Into<&str> for AppRoute { impl From<AppRoute> for &str {
fn into(self) -> &'static str { fn from(route: AppRoute) -> Self {
match self { match route {
AppRoute::Ssh => &"/ssh", AppRoute::Ssh => "/ssh",
_ => &"/", _ => "/",
} }
} }
} }
@ -36,19 +36,30 @@ impl IntoPropValue<Option<Cow<'_, str>>> for AppRoute {
} }
} }
pub struct App {} pub struct App {
authdone: bool,
link: ComponentLink<Self>,
}
pub enum Msg {} pub enum AppMsg {
AuthDone,
}
impl Component for App { impl Component for App {
type Message = Msg; type Message = AppMsg;
type Properties = (); type Properties = ();
fn create(_: Self::Properties, _link: ComponentLink<Self>) -> Self { fn create(_: Self::Properties, link: ComponentLink<Self>) -> Self {
Self {} Self {
authdone: false,
link,
}
} }
fn update(&mut self, _msg: Self::Message) -> ShouldRender { fn update(&mut self, msg: Self::Message) -> ShouldRender {
match msg {
AppMsg::AuthDone => self.authdone = true,
}
true true
} }
@ -56,19 +67,35 @@ impl Component for App {
false false
} }
fn view(&self) -> VNode { fn view(&self) -> Html {
html! { html! {
<> <>
{ self.view_nav() } {
<main class="content">
<Router<AppRoute> if self.authdone {
render = Router::render(Self::switch) html! {
redirect=Router::redirect(|route: Route| { <>
ConsoleService::log(&format!("{:?}", route)); {self.view_nav()}
AppRoute::NotFound
}) <main class="content">
/> <Router<AppRoute>
</main> render = Router::render(Self::switch)
redirect=Router::redirect(|route: Route| {
ConsoleService::log(&format!("{:?}", route));
AppRoute::NotFound
})
/>
</main>
</>
}
}
else {
let onauthdone = &self.link.callback(|_| AppMsg::AuthDone);
html!{
<auth::AuthComponents onauthdone=onauthdone/>
}
}
}
<footer class="footer"> <footer class="footer">
{ "Powered by " } { "Powered by " }
<a href="https://yew.rs">{ "Yew" }</a> <a href="https://yew.rs">{ "Yew" }</a>

View File

@ -20,6 +20,7 @@ pub struct AuthComponents {
link: ComponentLink<Self>, link: ComponentLink<Self>,
auth_result: String, auth_result: String,
fetch_task: Option<FetchTask>, fetch_task: Option<FetchTask>,
onauthdone: Callback<()>,
} }
impl Debug for AuthComponents { impl Debug for AuthComponents {
@ -32,17 +33,24 @@ impl Debug for AuthComponents {
} }
} }
#[derive(Clone, PartialEq, Properties)]
pub struct AuthProps {
#[prop_or_default]
pub onauthdone: Callback<()>,
}
impl Component for AuthComponents { impl Component for AuthComponents {
type Message = AuthMsg; type Message = AuthMsg;
type Properties = (); type Properties = AuthProps;
fn create(_: Self::Properties, link: ComponentLink<Self>) -> Self { fn create(props: Self::Properties, link: ComponentLink<Self>) -> Self {
AuthComponents { AuthComponents {
username: String::new(), username: String::new(),
password: String::new(), password: String::new(),
auth_result: String::new(), auth_result: String::new(),
link, link,
fetch_task: None, fetch_task: None,
onauthdone: props.onauthdone,
} }
} }
@ -83,6 +91,9 @@ impl Component for AuthComponents {
AuthMsg::AuthResponse(response) => { AuthMsg::AuthResponse(response) => {
if let Ok(response) = response { if let Ok(response) = response {
self.auth_result = response["status"].to_string(); self.auth_result = response["status"].to_string();
if "\"success\"" == self.auth_result {
self.onauthdone.emit(());
}
} else { } else {
self.auth_result = String::from("Auth failed with unknown reason"); self.auth_result = String::from("Auth failed with unknown reason");
ConsoleService::error(&format!("{:?}", response.unwrap_err().to_string())); ConsoleService::error(&format!("{:?}", response.unwrap_err().to_string()));
@ -90,7 +101,6 @@ impl Component for AuthComponents {
// release resources // release resources
self.fetch_task = None; self.fetch_task = None;
} }
_ => panic!("unexpected message"),
} }
// ConsoleService::log(&format!( // ConsoleService::log(&format!(
// "username: {}, password {}", // "username: {}, password {}",
@ -139,7 +149,7 @@ impl Component for AuthComponents {
impl AuthComponents { impl AuthComponents {
fn auth_result_view(&self) -> Html { fn auth_result_view(&self) -> Html {
if let Some(_) = &self.fetch_task { if self.fetch_task.is_some() {
html! { html! {
<div>{"Authing..."}</div> <div>{"Authing..."}</div>
} }

View File

@ -2,25 +2,19 @@ use yew::prelude::*;
use yew::ShouldRender; use yew::ShouldRender;
use yew::{html, Component, Html}; use yew::{html, Component, Html};
use crate::components; pub struct PageHome;
pub enum HomeMsg {}
pub struct PageHome {
link: ComponentLink<Self>,
}
impl Component for PageHome { impl Component for PageHome {
type Message = HomeMsg; type Message = ();
type Properties = (); type Properties = ();
fn create(_props: Self::Properties, link: ComponentLink<Self>) -> Self { fn create(_props: Self::Properties, _link: ComponentLink<Self>) -> Self {
Self { link } Self
} }
fn view(&self) -> Html { fn view(&self) -> Html {
html! { html! {
<components::auth::AuthComponents/> "Hello world"
} }
} }