mirror of
https://github.com/YGGverse/Yoda.git
synced 2025-01-15 17:20:08 +00:00
implement auth wrapper for stream
This commit is contained in:
parent
f487215ca9
commit
5bb0617c57
@ -21,7 +21,7 @@ use crate::Profile;
|
|||||||
use gtk::{
|
use gtk::{
|
||||||
gdk_pixbuf::Pixbuf,
|
gdk_pixbuf::Pixbuf,
|
||||||
gio::{
|
gio::{
|
||||||
Cancellable, SocketClient, SocketClientEvent, SocketConnectable, SocketProtocol,
|
Cancellable, IOStream, SocketClient, SocketClientEvent, SocketConnectable, SocketProtocol,
|
||||||
TlsCertificate, TlsCertificateFlags, TlsClientConnection,
|
TlsCertificate, TlsCertificateFlags, TlsClientConnection,
|
||||||
},
|
},
|
||||||
glib::{
|
glib::{
|
||||||
@ -29,7 +29,7 @@ use gtk::{
|
|||||||
UriFlags, UriHideFlags,
|
UriFlags, UriHideFlags,
|
||||||
},
|
},
|
||||||
prelude::{
|
prelude::{
|
||||||
CancellableExt, EditableExt, IOStreamExt, OutputStreamExt, SocketClientExt,
|
CancellableExt, Cast, EditableExt, IOStreamExt, IsA, OutputStreamExt, SocketClientExt,
|
||||||
TlsConnectionExt,
|
TlsConnectionExt,
|
||||||
},
|
},
|
||||||
};
|
};
|
||||||
@ -428,6 +428,21 @@ impl Page {
|
|||||||
// Use local namespaces @TODO
|
// Use local namespaces @TODO
|
||||||
// use gemini::client::response::
|
// use gemini::client::response::
|
||||||
|
|
||||||
|
// Wrapper for TLS connection
|
||||||
|
fn auth(
|
||||||
|
connection: impl IsA<IOStream>,
|
||||||
|
certificate: Option<TlsCertificate>,
|
||||||
|
) -> impl IsA<IOStream> {
|
||||||
|
if let Some(certificate) = certificate {
|
||||||
|
let tls_connection =
|
||||||
|
TlsClientConnection::new(&connection, None::<&SocketConnectable>).unwrap(); // @TODO handle
|
||||||
|
tls_connection.set_certificate(&certificate);
|
||||||
|
tls_connection.upcast::<IOStream>()
|
||||||
|
} else {
|
||||||
|
connection.upcast::<IOStream>()
|
||||||
|
}
|
||||||
|
}
|
||||||
|
|
||||||
// Init shared objects (async)
|
// Init shared objects (async)
|
||||||
let cancellable = self.cancellable.borrow().clone();
|
let cancellable = self.cancellable.borrow().clone();
|
||||||
let update = self.browser_action.update().clone();
|
let update = self.browser_action.update().clone();
|
||||||
@ -443,20 +458,21 @@ impl Page {
|
|||||||
client.set_protocol(SocketProtocol::Tcp);
|
client.set_protocol(SocketProtocol::Tcp);
|
||||||
|
|
||||||
// Check request match configured identity in profile database
|
// Check request match configured identity in profile database
|
||||||
let auth = if let Some(pem) = self
|
let certificate = match self
|
||||||
.profile
|
.profile
|
||||||
.identity
|
.identity
|
||||||
.gemini(&self.navigation.request().widget().gobject().text())
|
.gemini(&self.navigation.request().widget().gobject().text())
|
||||||
{
|
{
|
||||||
match TlsCertificate::from_pem(&pem) {
|
Some(pem) => match TlsCertificate::from_pem(&pem) {
|
||||||
Ok(certificate) => Some(certificate),
|
Ok(certificate) => Some(certificate),
|
||||||
Err(_) => todo!(),
|
Err(_) => todo!(),
|
||||||
}
|
},
|
||||||
} else {
|
None => {
|
||||||
// Use unauthorized connection
|
// Use unauthorized connection
|
||||||
client.set_tls_validation_flags(TlsCertificateFlags::INSECURE);
|
client.set_tls_validation_flags(TlsCertificateFlags::INSECURE);
|
||||||
client.set_tls(true);
|
client.set_tls(true);
|
||||||
None
|
None
|
||||||
|
}
|
||||||
};
|
};
|
||||||
|
|
||||||
// Listen for connection status updates
|
// Listen for connection status updates
|
||||||
@ -488,23 +504,11 @@ impl Page {
|
|||||||
Some(&cancellable.clone()),
|
Some(&cancellable.clone()),
|
||||||
move |connect| match connect {
|
move |connect| match connect {
|
||||||
Ok(connection) => {
|
Ok(connection) => {
|
||||||
// Wrap connection with TLS
|
// Encrypt stream using authorization TLS
|
||||||
if let Some(certificate) = auth {
|
let stream = auth(connection, certificate);
|
||||||
let connection = TlsClientConnection::new(
|
|
||||||
&connection.clone(),
|
|
||||||
None::<&SocketConnectable>,
|
|
||||||
)
|
|
||||||
.unwrap(); // @TODO handle
|
|
||||||
// Apply authorization
|
|
||||||
connection.set_certificate(
|
|
||||||
&certificate,
|
|
||||||
);
|
|
||||||
// Validate @TODO
|
|
||||||
// connection.connect_accept_certificate(|_, _, _| true);
|
|
||||||
}
|
|
||||||
|
|
||||||
// Send request
|
// Send request
|
||||||
connection.output_stream().write_bytes_async(
|
stream.output_stream().write_bytes_async(
|
||||||
&Bytes::from(gformat!("{url}\r\n").as_bytes()),
|
&Bytes::from(gformat!("{url}\r\n").as_bytes()),
|
||||||
Priority::DEFAULT,
|
Priority::DEFAULT,
|
||||||
Some(&cancellable.clone()),
|
Some(&cancellable.clone()),
|
||||||
@ -512,7 +516,7 @@ impl Page {
|
|||||||
Ok(_) => {
|
Ok(_) => {
|
||||||
// Read meta from input stream
|
// Read meta from input stream
|
||||||
gemini::client::response::Meta::from_stream_async(
|
gemini::client::response::Meta::from_stream_async(
|
||||||
connection.clone(),
|
stream.clone(),
|
||||||
Some(Priority::DEFAULT),
|
Some(Priority::DEFAULT),
|
||||||
Some(cancellable.clone()),
|
Some(cancellable.clone()),
|
||||||
move |result| match result
|
move |result| match result
|
||||||
@ -561,7 +565,7 @@ impl Page {
|
|||||||
Some(gemini::client::response::meta::Mime::TextGemini) => {
|
Some(gemini::client::response::meta::Mime::TextGemini) => {
|
||||||
// Read entire input stream to buffer
|
// Read entire input stream to buffer
|
||||||
gemini::client::response::data::Text::from_stream_async(
|
gemini::client::response::data::Text::from_stream_async(
|
||||||
connection,
|
stream,
|
||||||
Some(Priority::DEFAULT),
|
Some(Priority::DEFAULT),
|
||||||
Some(cancellable.clone()),
|
Some(cancellable.clone()),
|
||||||
move |result|{
|
move |result|{
|
||||||
@ -629,7 +633,7 @@ impl Page {
|
|||||||
// Asynchronously move `InputStream` data from `SocketConnection` into the local `MemoryInputStream`
|
// Asynchronously move `InputStream` data from `SocketConnection` into the local `MemoryInputStream`
|
||||||
// this action allows to count the bytes for loading widget and validate max size for incoming data
|
// this action allows to count the bytes for loading widget and validate max size for incoming data
|
||||||
gemini::gio::memory_input_stream::from_stream_async(
|
gemini::gio::memory_input_stream::from_stream_async(
|
||||||
connection,
|
stream,
|
||||||
Some(cancellable.clone()),
|
Some(cancellable.clone()),
|
||||||
Priority::DEFAULT,
|
Priority::DEFAULT,
|
||||||
0x400, // 1024 bytes per chunk, optional step for images download tracking
|
0x400, // 1024 bytes per chunk, optional step for images download tracking
|
||||||
|
Loading…
x
Reference in New Issue
Block a user