Skip to content
New issue

Have a question about this project? Sign up for a free GitHub account to open an issue and contact its maintainers and the community.

By clicking “Sign up for GitHub”, you agree to our terms of service and privacy statement. We’ll occasionally send you account related emails.

Already on GitHub? Sign in to your account

added ockam:// scheme association in app for linux and mac #5663

Merged
merged 2 commits into from
Sep 14, 2023
Merged
Show file tree
Hide file tree
Changes from all commits
Commits
File filter

Filter by extension

Filter by extension


Conversations
Failed to load comments.
Loading
Jump to
Jump to file
Failed to load files.
Loading
Diff view
Diff view
2 changes: 1 addition & 1 deletion .github/actions/build_binaries/action.yml
Original file line number Diff line number Diff line change
Expand Up @@ -88,7 +88,7 @@ runs:
if: inputs.build_app == 'true'
run: |
set -x
cargo install --locked tauri-cli --version 2.0.0-alpha.10
cargo install tauri-cli --git https://github.com/build-trust/tauri.git --branch add-url-scheme

cd implementations/rust/ockam/ockam_app/
cargo tauri build --target ${{ inputs.target }}
11 changes: 7 additions & 4 deletions Cargo.lock

Some generated files are not rendered by default. Learn more about how customized files appear on GitHub.

6 changes: 6 additions & 0 deletions Cargo.toml
Original file line number Diff line number Diff line change
Expand Up @@ -49,3 +49,9 @@ inherits = "test"
opt-level = 2
[profile.dev.package.adler]
opt-level = 1

[patch.crates-io]
# temporary fork for url scheme - https://github.com/build-trust/ockam/issues/5667
tauri = { git = "https://github.com/build-trust/tauri.git", branch = "add-url-scheme" }
tauri-build = { git = "https://github.com/build-trust/tauri.git", branch = "add-url-scheme" }
tauri-utils = { git = "https://github.com/build-trust/tauri.git", branch = "add-url-scheme" }
1 change: 1 addition & 0 deletions implementations/rust/ockam/ockam_app/src/app/events.rs
Original file line number Diff line number Diff line change
@@ -1,6 +1,7 @@
use tauri::{AppHandle, Manager, Runtime};

pub const SYSTEM_TRAY_ON_UPDATE: &str = "app/system_tray/on_update";
pub const URL_OPEN: &str = "app/url/open";

#[derive(Debug, Clone, Default, serde::Serialize, serde::Deserialize)]
pub struct SystemTrayOnUpdatePayload {
Expand Down
7 changes: 7 additions & 0 deletions implementations/rust/ockam/ockam_app/src/app/process.rs
Original file line number Diff line number Diff line change
Expand Up @@ -4,6 +4,13 @@ use tauri::{AppHandle, RunEvent, Runtime};
/// This is the function dispatching application events
pub fn process_application_event<R: Runtime>(app: &AppHandle<R>, event: RunEvent) {
match event {
#[cfg(any(target_os = "macos", target_os = "ios"))]
RunEvent::Opened { urls } => {
urls.into_iter().for_each(|url| {
use tauri::Manager;
app.trigger_global(crate::app::events::URL_OPEN, Some(url.into()));
});
}
RunEvent::ExitRequested { api, .. } => {
api.prevent_exit();
}
Expand Down
30 changes: 30 additions & 0 deletions implementations/rust/ockam/ockam_app/src/lib.rs
Original file line number Diff line number Diff line change
Expand Up @@ -28,6 +28,8 @@ mod cli;
mod enroll;
mod error;
mod invitations;
#[cfg(target_os = "linux")]
mod linux_url_plugin;
mod options;
mod platform;
mod projects;
Expand All @@ -44,6 +46,29 @@ pub fn run() {
exit(-1)
}

//On linux only, to handle ockam:// link argument from args we check if
//the app is already running, send a packet to it via unix socket.
//Using unix socket rather than ockam, to fully separate concerns.
#[cfg(target_os = "linux")]
{
use std::io::Write;
use std::os::unix::net::UnixStream;

let mut args = std::env::args();
args.next(); //skip the first argument which is the executable name
let args: Vec<String> = args.collect();

//if we can connect to the socket then the app is already running
//if it's not running yet the arguments will be checked upon startup
if !args.is_empty() && args[0].starts_with("ockam:") {
if let Ok(mut stream) = UnixStream::connect(linux_url_plugin::open_url_sock_path()) {
stream.write_all(args[0].as_bytes()).unwrap();
stream.flush().unwrap();
return;
}
}
}

// For now, the application only consists of a system tray with several menu items
#[allow(unused_mut)]
let mut builder = tauri::Builder::default()
Expand All @@ -61,6 +86,11 @@ pub fn run() {
builder = builder.plugin(configure_tauri_plugin_log());
}

#[cfg(target_os = "linux")]
{
builder = builder.plugin(linux_url_plugin::init());
}

let mut app = builder
.build(tauri::generate_context!())
.expect("Error while building the Ockam application");
Expand Down
69 changes: 69 additions & 0 deletions implementations/rust/ockam/ockam_app/src/linux_url_plugin.rs
Original file line number Diff line number Diff line change
@@ -0,0 +1,69 @@
use std::os::unix::fs::PermissionsExt;
use std::time::Duration;

use tauri::{
async_runtime::spawn,
plugin::{Builder, TauriPlugin},
Manager, Runtime,
};
use tokio::io::AsyncReadExt;
use tokio::net::UnixListener;
use tokio::time::sleep;
use tracing::{info, warn};

pub(crate) fn open_url_sock_path() -> String {
let runtime_directory = std::env::var("XDG_RUNTIME_DIR").unwrap_or("/tmp".to_string());
format!("{runtime_directory}/ockam-open-url-sock")
}
const ONLY_WRITE_FROM_USER_PERMISSIONS: u32 = 0o200;

pub(crate) fn init<R: Runtime>() -> TauriPlugin<R> {
Builder::new("linux-url")
.setup(|app, _api| {
let handle = app.clone();
spawn(async move {
let sock_path = &open_url_sock_path();
//bind fails if the file already exists
let _ = std::fs::remove_file(sock_path);
let listener = UnixListener::bind(sock_path)
.unwrap_or_else(|_| panic!("cannot listener on {sock_path}"));
//only allow the current user to write to the socket
std::fs::set_permissions(
sock_path,
std::fs::Permissions::from_mode(ONLY_WRITE_FROM_USER_PERMISSIONS),
)
.unwrap_or_else(|_| panic!("cannot set permissions on {sock_path}"));

//wait a bit to let the app start
sleep(Duration::from_millis(250)).await;

//check if we had an ockam:// argument passed to us
if let Some(url) = std::env::args().nth(1) {
if url.starts_with("ockam:") {
info!("received url: {}", url);
handle.trigger_global(crate::app::events::URL_OPEN, Some(url));
} else {
warn!("ignored argument: {}", url);
}
}

while let Ok((mut stream, _)) = listener.accept().await {
let mut buffer = [0; 4096];
if let Ok(read_bytes) = stream.read(&mut buffer).await {
if let Ok(url) = String::from_utf8(buffer[..read_bytes].to_vec()) {
if url.starts_with("ockam:") {
info!("received url: {}", url);
handle.trigger_global(crate::app::events::URL_OPEN, Some(url));
} else {
warn!("ignored url: {}", url);
}
}
}
//every connection is used only once
drop(stream);
}
});
Ok(())
})
.build()
}
6 changes: 6 additions & 0 deletions implementations/rust/ockam/ockam_app/tauri.conf.json
Original file line number Diff line number Diff line change
Expand Up @@ -23,6 +23,12 @@
"category": "DeveloperTool",
"identifier": "io.ockam.app",
"publisher": "Ockam",
"schemeAssociations": [
{
"scheme": ["ockam"],
"role": "Editor"
}
],
"externalBin": [],
"icon": [
"icons/32x32.png",
Expand Down
2 changes: 1 addition & 1 deletion tools/docker/builder/Dockerfile
Original file line number Diff line number Diff line change
Expand Up @@ -104,7 +104,7 @@ RUN set -xe; \
cargo install --locked cargo-deny; \
cargo install --locked cargo-nextest; \
cargo install --locked cargo-readme; \
cargo install --locked tauri-cli --version 2.0.0-alpha.10; \
cargo install tauri-cli --git https://github.com/build-trust/tauri.git --branch add-url-scheme; \
chmod -R a+w "$RUSTUP_HOME" "$CARGO_HOME"; \
# Setup erlang
echo "deb http://deb.debian.org/debian bullseye main" >> /etc/apt/sources.list; \
Expand Down
10 changes: 5 additions & 5 deletions tools/nix/parts/tauri.nix
Original file line number Diff line number Diff line change
Expand Up @@ -15,23 +15,23 @@
pname = "tauri-cli";
# NOTE: Bumping version must always be accompanied by updating the two hashes below
# https://github.com/tauri-apps/tauri/releases
version = "2.0.0-alpha.10";
version = "2.0.0-alpha.11";
in
# Need to make changes?
# https://nixos.org/manual/nixpkgs/stable/#compiling-rust-applications-with-cargo
pkgs.rustPlatform.buildRustPackage {
inherit pname version;

src = pkgs.fetchFromGitHub {
owner = "tauri-apps";
owner = "build-trust";
repo = "tauri";
rev = "tauri-v${version}";
hash = "sha256-WOxl+hgzKmKXQryD5tH7SJ9YvZb9QA4R+YUYnarnhKA=";
rev = "7856354fe16197b270dfa36bc095fec33bec4cff";
hash = "sha256-UxWT5k3ZTbydy2iW9LXuSLIfQhSafN39g566J0xWDDs=";
};
sourceRoot = "source/tooling/cli";

cargoDepsName = pname;
cargoHash = "sha256-MQmEOdQWyRbO+hogGQA2xjB9mezq21FClvscs1oWYLE=";
cargoHash = "sha256-4OKYj9rPB998JQTLi/k8ICBgYL/jcxXJT/4MAAR6wzU=";

buildInputs =
[pkgs.openssl]
Expand Down
Loading