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-web-actors = "3.0.0"
urlencoding = "2.1.0"
serde = "1.0"
serde_json = "1.0"
rand = "0.8"

View File

@ -3,13 +3,18 @@ use actix_session::CookieSession;
use actix_web::http::{ContentEncoding, StatusCode};
use actix_web::*;
use femme;
use log::info;
use rand::Rng;
mod user;
mod ws;
// pub struct AppState ;
// impl Actor for AppState {
// type Context = actix::Context<Self>;
// }
const STATIC_DIR: &str = "./static/";
const PAGE_INDEX: &str = "./static/index.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]>();
HttpServer::new(move || {
App::new()
// .data(AppState)
.wrap(CookieSession::signed(&private_key).secure(false))
.wrap(middleware::Compress::new(ContentEncoding::Gzip))
.service(index)

View File

@ -1,12 +1,63 @@
use actix::{Actor, Context, Handler, Message, MessageResponse};
use actix_web::*;
use serde::{Deserialize, Serialize};
use serde_json::json;
use log::info;
#[post("/auth")]
pub async fn auth(req: HttpRequest) -> Result<HttpResponse, Error> {
info!("{:?}", req);
Ok(HttpResponse::Ok()
.content_type("application/json")
.body(json!({"status": "success"})))
#[derive(Message)]
#[rtype(result = "Self")]
#[derive(MessageResponse)]
#[allow(dead_code)]
enum AuthMessage {
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 crate::components::auth;
use crate::pages::{page_home::PageHome, page_not_found::PageNotFound, page_ssh::PageSsh};
use yew::html::IntoPropValue;
use yew::prelude::*;
use yew::services::ConsoleService;
use yew::virtual_dom::VNode;
use yew::Component;
use yew_router::prelude::*;
use yew_router::{router::Router, Switch};
@ -21,11 +21,11 @@ enum AppRoute {
NotFound,
}
impl Into<&str> for AppRoute {
fn into(self) -> &'static str {
match self {
AppRoute::Ssh => &"/ssh",
_ => &"/",
impl From<AppRoute> for &str {
fn from(route: AppRoute) -> Self {
match route {
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 {
type Message = Msg;
type Message = AppMsg;
type Properties = ();
fn create(_: Self::Properties, _link: ComponentLink<Self>) -> Self {
Self {}
fn create(_: Self::Properties, link: ComponentLink<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
}
@ -56,19 +67,35 @@ impl Component for App {
false
}
fn view(&self) -> VNode {
fn view(&self) -> Html {
html! {
<>
{ self.view_nav() }
<main class="content">
<Router<AppRoute>
render = Router::render(Self::switch)
redirect=Router::redirect(|route: Route| {
ConsoleService::log(&format!("{:?}", route));
AppRoute::NotFound
})
/>
</main>
{
if self.authdone {
html! {
<>
{self.view_nav()}
<main class="content">
<Router<AppRoute>
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">
{ "Powered by " }
<a href="https://yew.rs">{ "Yew" }</a>

View File

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

View File

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