aboutsummaryrefslogtreecommitdiffstats
path: root/teleterm/src
diff options
context:
space:
mode:
Diffstat (limited to 'teleterm/src')
-rw-r--r--teleterm/src/web.rs19
-rw-r--r--teleterm/src/web/disk_session.rs99
-rw-r--r--teleterm/src/web/list.rs13
-rw-r--r--teleterm/src/web/login.rs26
-rw-r--r--teleterm/src/web/watch.rs13
5 files changed, 170 insertions, 0 deletions
diff --git a/teleterm/src/web.rs b/teleterm/src/web.rs
index 992b79d..07ece12 100644
--- a/teleterm/src/web.rs
+++ b/teleterm/src/web.rs
@@ -1,4 +1,6 @@
+mod disk_session;
mod list;
+mod login;
mod view;
mod watch;
mod ws;
@@ -15,6 +17,11 @@ struct Config {
public_address: String,
}
+#[derive(Default, serde::Deserialize, serde::Serialize)]
+struct SessionData {
+ username: Option<String>,
+}
+
pub struct Server {
server: Box<dyn futures::Future<Item = (), Error = ()> + Send>,
}
@@ -54,6 +61,14 @@ fn router(data: &Config) -> impl gotham::handler::NewHandler {
.add(gotham::middleware::state::StateMiddleware::new(
data.clone(),
))
+ .add(
+ gotham::middleware::session::NewSessionMiddleware::new(
+ disk_session::DiskSession,
+ )
+ .insecure()
+ .with_cookie_name("teleterm")
+ .with_session_type::<SessionData>(),
+ )
.build(),
);
gotham::router::builder::build_router(chain, pipeline, |route| {
@@ -75,6 +90,10 @@ fn router(data: &Config) -> impl gotham::handler::NewHandler {
.get("/watch")
.with_query_string_extractor::<watch::QueryParams>()
.to(watch::run);
+ route
+ .get("/login")
+ .with_query_string_extractor::<login::QueryParams>()
+ .to(login::run);
})
}
diff --git a/teleterm/src/web/disk_session.rs b/teleterm/src/web/disk_session.rs
new file mode 100644
index 0000000..423bcd0
--- /dev/null
+++ b/teleterm/src/web/disk_session.rs
@@ -0,0 +1,99 @@
+use crate::prelude::*;
+
+use std::io::Write as _;
+
+#[derive(Clone)]
+pub struct DiskSession;
+
+impl DiskSession {
+ fn file_for_id(
+ &self,
+ identifier: &gotham::middleware::session::SessionIdentifier,
+ should_exist: bool,
+ ) -> Option<std::path::PathBuf> {
+ let name = format!("web-{}", identifier.value);
+ crate::dirs::Dirs::new().data_file(&name, should_exist)
+ }
+}
+
+impl gotham::middleware::session::NewBackend for DiskSession {
+ type Instance = Self;
+
+ fn new_backend(&self) -> std::io::Result<Self::Instance> {
+ Ok(Self)
+ }
+}
+
+impl gotham::middleware::session::Backend for DiskSession {
+ fn persist_session(
+ &self,
+ identifier: gotham::middleware::session::SessionIdentifier,
+ content: &[u8],
+ ) -> std::result::Result<(), gotham::middleware::session::SessionError>
+ {
+ let filename = self.file_for_id(&identifier, false).unwrap();
+ let mut file = std::fs::File::create(filename).map_err(|e| {
+ gotham::middleware::session::SessionError::Backend(format!(
+ "{}",
+ e
+ ))
+ })?;
+ file.write_all(content).map_err(|e| {
+ gotham::middleware::session::SessionError::Backend(format!(
+ "{}",
+ e
+ ))
+ })?;
+ file.sync_all().map_err(|e| {
+ gotham::middleware::session::SessionError::Backend(format!(
+ "{}",
+ e
+ ))
+ })?;
+ Ok(())
+ }
+
+ fn read_session(
+ &self,
+ identifier: gotham::middleware::session::SessionIdentifier,
+ ) -> Box<
+ dyn futures::Future<
+ Item = Option<Vec<u8>>,
+ Error = gotham::middleware::session::SessionError,
+ > + Send,
+ > {
+ if let Some(filename) = self.file_for_id(&identifier, true) {
+ Box::new(
+ tokio::fs::File::open(filename)
+ .and_then(|file| {
+ let buf = vec![];
+ tokio::io::read_to_end(file, buf)
+ })
+ .map(|(_, v)| Some(v))
+ .map_err(|e| {
+ gotham::middleware::session::SessionError::Backend(
+ format!("{}", e),
+ )
+ }),
+ )
+ } else {
+ Box::new(futures::future::ok(None))
+ }
+ }
+
+ fn drop_session(
+ &self,
+ identifier: gotham::middleware::session::SessionIdentifier,
+ ) -> std::result::Result<(), gotham::middleware::session::SessionError>
+ {
+ if let Some(filename) = self.file_for_id(&identifier, true) {
+ std::fs::remove_file(filename).map_err(|e| {
+ gotham::middleware::session::SessionError::Backend(format!(
+ "{}",
+ e
+ ))
+ })?;
+ }
+ Ok(())
+ }
+}
diff --git a/teleterm/src/web/list.rs b/teleterm/src/web/list.rs
index 9c1bcc6..0906f82 100644
--- a/teleterm/src/web/list.rs
+++ b/teleterm/src/web/list.rs
@@ -5,6 +5,19 @@ use gotham::state::FromState as _;
pub fn run(
state: gotham::state::State,
) -> (gotham::state::State, hyper::Response<hyper::Body>) {
+ let session = gotham::middleware::session::SessionData::<
+ crate::web::SessionData,
+ >::borrow_from(&state);
+ if session.username.is_none() {
+ return (
+ state,
+ hyper::Response::builder()
+ .status(hyper::StatusCode::FORBIDDEN)
+ .body(hyper::Body::empty())
+ .unwrap(),
+ );
+ }
+
let config = crate::web::Config::borrow_from(&state);
let (_, address) = config.server_address;
diff --git a/teleterm/src/web/login.rs b/teleterm/src/web/login.rs
new file mode 100644
index 0000000..a678b95
--- /dev/null
+++ b/teleterm/src/web/login.rs
@@ -0,0 +1,26 @@
+use gotham::state::FromState as _;
+
+#[derive(
+ serde::Deserialize,
+ gotham_derive::StateData,
+ gotham_derive::StaticResponseExtender,
+)]
+pub struct QueryParams {
+ username: Option<String>,
+}
+
+pub fn run(
+ mut state: gotham::state::State,
+) -> (gotham::state::State, hyper::Response<hyper::Body>) {
+ let username = {
+ let query_params = QueryParams::borrow_from(&state);
+ query_params.username.clone()
+ };
+ let session = gotham::middleware::session::SessionData::<
+ crate::web::SessionData,
+ >::borrow_mut_from(&mut state);
+
+ session.username = username;
+
+ (state, hyper::Response::new(hyper::Body::from("{}")))
+}
diff --git a/teleterm/src/web/watch.rs b/teleterm/src/web/watch.rs
index 720e9f8..74a59dd 100644
--- a/teleterm/src/web/watch.rs
+++ b/teleterm/src/web/watch.rs
@@ -15,6 +15,19 @@ pub struct QueryParams {
pub fn run(
mut state: gotham::state::State,
) -> (gotham::state::State, hyper::Response<hyper::Body>) {
+ let session = gotham::middleware::session::SessionData::<
+ crate::web::SessionData,
+ >::borrow_from(&state);
+ if session.username.is_none() {
+ return (
+ state,
+ hyper::Response::builder()
+ .status(hyper::StatusCode::FORBIDDEN)
+ .body(hyper::Body::empty())
+ .unwrap(),
+ );
+ }
+
let body = hyper::Body::take_from(&mut state);
let headers = hyper::HeaderMap::take_from(&mut state);
let config = crate::web::Config::borrow_from(&state);