Partially handle errors
This commit is contained in:
parent
76b9e8b7bf
commit
3bc299859f
2 changed files with 107 additions and 100 deletions
|
|
@ -1,4 +1,4 @@
|
||||||
use greetd_ipc::{codec::SyncCodec, AuthMessageType, Request, Response};
|
use greetd_ipc::{codec::SyncCodec, AuthMessageType, ErrorType, Request, Response};
|
||||||
use std::io;
|
use std::io;
|
||||||
use tokio::net::UnixListener;
|
use tokio::net::UnixListener;
|
||||||
|
|
||||||
|
|
@ -40,7 +40,15 @@ async fn main() {
|
||||||
auth_message_type: AuthMessageType::Secret,
|
auth_message_type: AuthMessageType::Secret,
|
||||||
auth_message: "Password:".to_string(),
|
auth_message: "Password:".to_string(),
|
||||||
},
|
},
|
||||||
Request::PostAuthMessageResponse { .. } => Response::Success,
|
Request::PostAuthMessageResponse { response } => {
|
||||||
|
match response.as_ref().map(|x| x.as_str()) {
|
||||||
|
Some("password") => Response::Success,
|
||||||
|
_ => Response::Error {
|
||||||
|
error_type: ErrorType::AuthError,
|
||||||
|
description: "pam_authenticate: AUTH_ERR".to_string(),
|
||||||
|
},
|
||||||
|
}
|
||||||
|
}
|
||||||
Request::StartSession { .. } => Response::Success,
|
Request::StartSession { .. } => Response::Success,
|
||||||
_ => {
|
_ => {
|
||||||
println!("unhandled request");
|
println!("unhandled request");
|
||||||
|
|
|
||||||
195
src/main.rs
195
src/main.rs
|
|
@ -154,7 +154,7 @@ fn main() -> Result<(), Box<dyn std::error::Error>> {
|
||||||
Ok(())
|
Ok(())
|
||||||
}
|
}
|
||||||
|
|
||||||
async fn request(socket: Arc<UnixStream>, request: Request) -> Message {
|
async fn request_message(socket: Arc<UnixStream>, request: Request) -> Message {
|
||||||
//TODO: handle errors
|
//TODO: handle errors
|
||||||
socket.writable().await.unwrap();
|
socket.writable().await.unwrap();
|
||||||
{
|
{
|
||||||
|
|
@ -181,28 +181,42 @@ async fn request(socket: Arc<UnixStream>, request: Request) -> Message {
|
||||||
} => match auth_message_type {
|
} => match auth_message_type {
|
||||||
AuthMessageType::Secret => {
|
AuthMessageType::Secret => {
|
||||||
return Message::Input(InputState::Auth {
|
return Message::Input(InputState::Auth {
|
||||||
secret: true,
|
|
||||||
prompt: auth_message,
|
prompt: auth_message,
|
||||||
value: String::new(),
|
value_opt: Some(String::new()),
|
||||||
|
secret: true,
|
||||||
})
|
})
|
||||||
}
|
}
|
||||||
AuthMessageType::Visible => {
|
AuthMessageType::Visible => {
|
||||||
return Message::Input(InputState::Auth {
|
return Message::Input(InputState::Auth {
|
||||||
secret: false,
|
|
||||||
prompt: auth_message,
|
prompt: auth_message,
|
||||||
value: String::new(),
|
value_opt: Some(String::new()),
|
||||||
|
secret: false,
|
||||||
|
})
|
||||||
|
}
|
||||||
|
//TODO: treat error type differently?
|
||||||
|
AuthMessageType::Info | AuthMessageType::Error => {
|
||||||
|
return Message::Input(InputState::Auth {
|
||||||
|
prompt: auth_message,
|
||||||
|
value_opt: None,
|
||||||
|
secret: false,
|
||||||
})
|
})
|
||||||
}
|
}
|
||||||
_ => todo!("unsupported auth_message_type {:?}", auth_message_type),
|
|
||||||
},
|
},
|
||||||
|
Response::Error {
|
||||||
|
error_type: _,
|
||||||
|
description,
|
||||||
|
} => {
|
||||||
|
//TODO: use error_type?
|
||||||
|
return Message::Error(description);
|
||||||
|
}
|
||||||
Response::Success => match request {
|
Response::Success => match request {
|
||||||
Request::CreateSession { .. } => {
|
Request::CreateSession { .. } => {
|
||||||
// User has no auth required, proceed to login
|
// User has no auth required, proceed to login
|
||||||
return Message::Login;
|
return Message::Login(socket);
|
||||||
}
|
}
|
||||||
Request::PostAuthMessageResponse { .. } => {
|
Request::PostAuthMessageResponse { .. } => {
|
||||||
// All auth is completed, proceed to login
|
// All auth is completed, proceed to login
|
||||||
return Message::Login;
|
return Message::Login(socket);
|
||||||
}
|
}
|
||||||
Request::StartSession { .. } => {
|
Request::StartSession { .. } => {
|
||||||
// Session has been started, exit greeter
|
// Session has been started, exit greeter
|
||||||
|
|
@ -213,10 +227,6 @@ async fn request(socket: Arc<UnixStream>, request: Request) -> Message {
|
||||||
return Message::None;
|
return Message::None;
|
||||||
}
|
}
|
||||||
},
|
},
|
||||||
_ => {
|
|
||||||
log::error!("unhandled response");
|
|
||||||
break;
|
|
||||||
}
|
|
||||||
}
|
}
|
||||||
}
|
}
|
||||||
Err(err) => match err.kind() {
|
Err(err) => match err.kind() {
|
||||||
|
|
@ -232,6 +242,13 @@ async fn request(socket: Arc<UnixStream>, request: Request) -> Message {
|
||||||
Message::None
|
Message::None
|
||||||
}
|
}
|
||||||
|
|
||||||
|
fn request_command(socket: Arc<UnixStream>, request: Request) -> Command<Message> {
|
||||||
|
Command::perform(
|
||||||
|
async move { message::app(request_message(socket, request).await) },
|
||||||
|
|x| x,
|
||||||
|
)
|
||||||
|
}
|
||||||
|
|
||||||
#[derive(Clone)]
|
#[derive(Clone)]
|
||||||
pub struct Flags {
|
pub struct Flags {
|
||||||
users: Vec<(pwd::Passwd, Option<widget::image::Handle>)>,
|
users: Vec<(pwd::Passwd, Option<widget::image::Handle>)>,
|
||||||
|
|
@ -255,9 +272,9 @@ pub enum InputState {
|
||||||
None,
|
None,
|
||||||
Username,
|
Username,
|
||||||
Auth {
|
Auth {
|
||||||
secret: bool,
|
|
||||||
prompt: String,
|
prompt: String,
|
||||||
value: String,
|
value_opt: Option<String>,
|
||||||
|
secret: bool,
|
||||||
},
|
},
|
||||||
}
|
}
|
||||||
|
|
||||||
|
|
@ -268,9 +285,10 @@ pub enum Message {
|
||||||
Socket(SocketState),
|
Socket(SocketState),
|
||||||
Input(InputState),
|
Input(InputState),
|
||||||
Session(String),
|
Session(String),
|
||||||
Username(String),
|
Error(String),
|
||||||
Auth(String),
|
Username(Arc<UnixStream>, String),
|
||||||
Login,
|
Auth(Arc<UnixStream>, Option<String>),
|
||||||
|
Login(Arc<UnixStream>),
|
||||||
Exit,
|
Exit,
|
||||||
}
|
}
|
||||||
|
|
||||||
|
|
@ -278,10 +296,11 @@ pub enum Message {
|
||||||
pub struct App {
|
pub struct App {
|
||||||
core: Core,
|
core: Core,
|
||||||
flags: Flags,
|
flags: Flags,
|
||||||
session_names: Vec<String>,
|
|
||||||
selected_session: String,
|
|
||||||
socket_state: SocketState,
|
socket_state: SocketState,
|
||||||
input_state: InputState,
|
input_state: InputState,
|
||||||
|
session_names: Vec<String>,
|
||||||
|
selected_session: String,
|
||||||
|
error_opt: Option<String>,
|
||||||
text_input_id: widget::Id,
|
text_input_id: widget::Id,
|
||||||
}
|
}
|
||||||
|
|
||||||
|
|
@ -326,11 +345,12 @@ impl cosmic::Application for App {
|
||||||
App {
|
App {
|
||||||
core,
|
core,
|
||||||
flags,
|
flags,
|
||||||
session_names,
|
|
||||||
selected_session,
|
|
||||||
socket_state: SocketState::Pending,
|
socket_state: SocketState::Pending,
|
||||||
//TODO: set to pending until socket is open?
|
//TODO: set to pending until socket is open?
|
||||||
input_state: InputState::Username,
|
input_state: InputState::Username,
|
||||||
|
session_names,
|
||||||
|
selected_session,
|
||||||
|
error_opt: None,
|
||||||
text_input_id: widget::Id::unique(),
|
text_input_id: widget::Id::unique(),
|
||||||
},
|
},
|
||||||
Command::perform(
|
Command::perform(
|
||||||
|
|
@ -363,66 +383,29 @@ impl cosmic::Application for App {
|
||||||
Message::Session(selected_session) => {
|
Message::Session(selected_session) => {
|
||||||
self.selected_session = selected_session;
|
self.selected_session = selected_session;
|
||||||
}
|
}
|
||||||
Message::Username(username) => match &self.socket_state {
|
Message::Error(error) => {
|
||||||
SocketState::Open(socket) => {
|
self.error_opt = Some(error);
|
||||||
let socket = socket.clone();
|
}
|
||||||
let username = username.clone();
|
Message::Username(socket, username) => {
|
||||||
return Command::perform(
|
return request_command(socket, Request::CreateSession { username });
|
||||||
async move {
|
}
|
||||||
message::app(request(socket, Request::CreateSession { username }).await)
|
Message::Auth(socket, response) => {
|
||||||
},
|
return request_command(socket, Request::PostAuthMessageResponse { response });
|
||||||
|x| x,
|
}
|
||||||
);
|
Message::Login(socket) => {
|
||||||
}
|
match self.flags.sessions.get(&self.selected_session).cloned() {
|
||||||
_ => todo!("socket not open but username provided"),
|
Some(cmd) => {
|
||||||
},
|
return request_command(
|
||||||
Message::Auth(value) => match &self.socket_state {
|
socket,
|
||||||
SocketState::Open(socket) => {
|
Request::StartSession {
|
||||||
let socket = socket.clone();
|
cmd,
|
||||||
let value = value.clone();
|
env: Vec::new(),
|
||||||
return Command::perform(
|
},
|
||||||
async move {
|
);
|
||||||
message::app(
|
|
||||||
request(
|
|
||||||
socket,
|
|
||||||
Request::PostAuthMessageResponse {
|
|
||||||
response: Some(value),
|
|
||||||
},
|
|
||||||
)
|
|
||||||
.await,
|
|
||||||
)
|
|
||||||
},
|
|
||||||
|x| x,
|
|
||||||
);
|
|
||||||
}
|
|
||||||
_ => todo!("socket not open but authentication provided"),
|
|
||||||
},
|
|
||||||
Message::Login => match &self.socket_state {
|
|
||||||
SocketState::Open(socket) => {
|
|
||||||
match self.flags.sessions.get(&self.selected_session).cloned() {
|
|
||||||
Some(cmd) => {
|
|
||||||
let socket = socket.clone();
|
|
||||||
return Command::perform(
|
|
||||||
async move {
|
|
||||||
message::app(
|
|
||||||
request(
|
|
||||||
socket,
|
|
||||||
Request::StartSession {
|
|
||||||
cmd,
|
|
||||||
env: Vec::new(),
|
|
||||||
},
|
|
||||||
)
|
|
||||||
.await,
|
|
||||||
)
|
|
||||||
},
|
|
||||||
|x| x,
|
|
||||||
);
|
|
||||||
}
|
|
||||||
None => todo!("session {:?} not found", self.selected_session),
|
|
||||||
}
|
}
|
||||||
|
None => todo!("session {:?} not found", self.selected_session),
|
||||||
}
|
}
|
||||||
_ => todo!("socket not open but attempting to log in"),
|
}
|
||||||
},
|
|
||||||
Message::Exit => {
|
Message::Exit => {
|
||||||
return iced::window::close();
|
return iced::window::close();
|
||||||
}
|
}
|
||||||
|
|
@ -434,7 +417,7 @@ impl cosmic::Application for App {
|
||||||
fn view(&self) -> Element<Self::Message> {
|
fn view(&self) -> Element<Self::Message> {
|
||||||
let content: Element<_> = match &self.socket_state {
|
let content: Element<_> = match &self.socket_state {
|
||||||
SocketState::Pending => widget::text("Opening GREETD_SOCK").into(),
|
SocketState::Pending => widget::text("Opening GREETD_SOCK").into(),
|
||||||
SocketState::Open(_) => match &self.input_state {
|
SocketState::Open(socket) => match &self.input_state {
|
||||||
InputState::None => {
|
InputState::None => {
|
||||||
//TODO
|
//TODO
|
||||||
widget::text("").into()
|
widget::text("").into()
|
||||||
|
|
@ -466,35 +449,47 @@ impl cosmic::Application for App {
|
||||||
.padding(16)
|
.padding(16)
|
||||||
.style(cosmic::theme::Container::Primary),
|
.style(cosmic::theme::Container::Primary),
|
||||||
)
|
)
|
||||||
.on_press(Message::Username(user.name.clone())),
|
.on_press(Message::Username(socket.clone(), user.name.clone())),
|
||||||
);
|
);
|
||||||
}
|
}
|
||||||
row.into()
|
row.into()
|
||||||
}
|
}
|
||||||
InputState::Auth {
|
InputState::Auth {
|
||||||
secret,
|
|
||||||
prompt,
|
prompt,
|
||||||
value,
|
value_opt,
|
||||||
|
secret,
|
||||||
} => {
|
} => {
|
||||||
let mut column = widget::column::with_capacity(2)
|
let mut column = widget::column::with_capacity(2)
|
||||||
.spacing(12.0)
|
.spacing(12.0)
|
||||||
.width(iced::Length::Fixed(400.0));
|
.width(iced::Length::Fixed(400.0));
|
||||||
column = column.push(widget::text(prompt));
|
column = column.push(widget::text(prompt));
|
||||||
let text_input = widget::text_input("", &value)
|
|
||||||
.id(self.text_input_id.clone())
|
match value_opt {
|
||||||
.on_input(|value| {
|
Some(value) => {
|
||||||
Message::Input(InputState::Auth {
|
let text_input = widget::text_input("", &value)
|
||||||
secret: *secret,
|
.id(self.text_input_id.clone())
|
||||||
prompt: prompt.clone(),
|
.on_input(|value| {
|
||||||
value,
|
Message::Input(InputState::Auth {
|
||||||
})
|
prompt: prompt.clone(),
|
||||||
})
|
value_opt: Some(value),
|
||||||
.on_submit(Message::Auth(value.clone()));
|
secret: *secret,
|
||||||
if *secret {
|
})
|
||||||
column = column.push(text_input.password());
|
})
|
||||||
} else {
|
.on_submit(Message::Auth(socket.clone(), Some(value.clone())));
|
||||||
column = column.push(text_input);
|
if *secret {
|
||||||
|
column = column.push(text_input.password());
|
||||||
|
} else {
|
||||||
|
column = column.push(text_input);
|
||||||
|
}
|
||||||
|
}
|
||||||
|
None => {
|
||||||
|
column = column.push(
|
||||||
|
widget::button("Confirm")
|
||||||
|
.on_press(Message::Auth(socket.clone(), None)),
|
||||||
|
);
|
||||||
|
}
|
||||||
}
|
}
|
||||||
|
|
||||||
column.into()
|
column.into()
|
||||||
}
|
}
|
||||||
},
|
},
|
||||||
|
|
@ -510,11 +505,15 @@ impl cosmic::Application for App {
|
||||||
Message::Session,
|
Message::Session,
|
||||||
);
|
);
|
||||||
|
|
||||||
let column = widget::column::with_capacity(2)
|
let mut column = widget::column::with_capacity(3)
|
||||||
.push(content)
|
.push(content)
|
||||||
.push(session_picker)
|
.push(session_picker)
|
||||||
.spacing(12.0);
|
.spacing(12.0);
|
||||||
|
|
||||||
|
if let Some(error) = &self.error_opt {
|
||||||
|
column = column.push(widget::text(error.clone()));
|
||||||
|
}
|
||||||
|
|
||||||
let centered = widget::container(column)
|
let centered = widget::container(column)
|
||||||
.width(iced::Length::Fill)
|
.width(iced::Length::Fill)
|
||||||
.height(iced::Length::Fill)
|
.height(iced::Length::Fill)
|
||||||
|
|
|
||||||
Loading…
Add table
Add a link
Reference in a new issue