diff --git a/Cargo.lock b/Cargo.lock index 9624b80..db57d61 100644 --- a/Cargo.lock +++ b/Cargo.lock @@ -88,9 +88,9 @@ dependencies = [ [[package]] name = "anyhow" -version = "1.0.52" +version = "1.0.53" source = "registry+https://github.com/rust-lang/crates.io-index" -checksum = "84450d0b4a8bd1ba4144ce8ce718fbc5d071358b1e5384bace6536b3d1f2d5b3" +checksum = "94a45b455c14666b85fc40a019e8ab9eb75e3a124e05494f5397122bc9eb06e0" [[package]] name = "arrayref" @@ -128,8 +128,8 @@ dependencies = [ "serde_repr", "zbus 2.0.1", "zbus_macros 2.0.1", - "zvariant 3.0.0", - "zvariant_derive 3.0.0", + "zvariant 3.1.1", + "zvariant_derive 3.1.1", ] [[package]] @@ -321,6 +321,7 @@ dependencies = [ "rand 0.8.4", "ring", "rust-argon2", + "search-provider", "secret-service", "serde", "serde_json", @@ -677,9 +678,9 @@ checksum = "dcb25d077389e53838a8158c8e99174c5a9d902dee4904320db714f3c653ffba" [[package]] name = "crc32fast" -version = "1.3.0" +version = "1.3.1" source = "registry+https://github.com/rust-lang/crates.io-index" -checksum = "738c290dfaea84fc1ca15ad9c168d083b05a714e1efddd8edaab678dc28d2836" +checksum = "a2209c310e29876f7f0b2721e7e26b84aff178aa3da5d091f9bfbf47669e60e3" dependencies = [ "cfg-if 1.0.0", ] @@ -998,15 +999,15 @@ dependencies = [ [[package]] name = "event-listener" -version = "2.5.1" +version = "2.5.2" source = "registry+https://github.com/rust-lang/crates.io-index" -checksum = "f7531096570974c3a9dcf9e4b8e1cede1ec26cf5046219fb3b9d897503b9be59" +checksum = "77f3309417938f28bf8228fcff79a4a37103981e3e186d2ccd19c74b38f4eb71" [[package]] name = "fastrand" -version = "1.6.0" +version = "1.7.0" source = "registry+https://github.com/rust-lang/crates.io-index" -checksum = "779d043b6a0b90cc4c0ed7ee380a6504394cee7efd7db050e3774eee387324b2" +checksum = "c3fcf0cee53519c866c09b5de1f6c56ff9d647101f81c1964fa632e148896cdf" dependencies = [ "instant", ] @@ -1192,9 +1193,9 @@ dependencies = [ [[package]] name = "gdk4" -version = "0.4.1" +version = "0.4.4" source = "registry+https://github.com/rust-lang/crates.io-index" -checksum = "f1023950739cd692fbf559507cad031bf2b0369d68466121f8a1316bc5ae29f0" +checksum = "319c74160dbe3e29cc1bf36ae4a08b9072f352b751e9e3e5501b3aa3ca633f66" dependencies = [ "bitflags", "cairo-rs", @@ -1208,9 +1209,9 @@ dependencies = [ [[package]] name = "gdk4-sys" -version = "0.4.1" +version = "0.4.2" source = "registry+https://github.com/rust-lang/crates.io-index" -checksum = "401b6be19db1e0ad2978fde7b46989b82f7595affa09cb56fe6f1302bc4f19e3" +checksum = "48a39e34abe35ee2cf54a1e29dd983accecd113ad30bdead5050418fa92f2a1b" dependencies = [ "cairo-sys-rs", "gdk-pixbuf-sys", @@ -1225,9 +1226,9 @@ dependencies = [ [[package]] name = "gdk4-wayland" -version = "0.4.1" +version = "0.4.2" source = "registry+https://github.com/rust-lang/crates.io-index" -checksum = "249e2056b774769a173cf58fe0b028dc6697542fa3a0ca54fd3d790f1a8eda28" +checksum = "12e6dcdd75e7fa114869d89c03a00081a3f54d7b5300f7d02a82bd3a97026c40" dependencies = [ "gdk4", "gdk4-wayland-sys", @@ -1238,9 +1239,9 @@ dependencies = [ [[package]] name = "gdk4-wayland-sys" -version = "0.4.1" +version = "0.4.2" source = "registry+https://github.com/rust-lang/crates.io-index" -checksum = "ac7518759dfb80e28a3cea17e450e5012dc49bb9e79f0e75db5cd9e0d5ca2865" +checksum = "22cbf7fa3fc7714c72902d82229677f9291f7cceb33855c5cef868f177356c30" dependencies = [ "glib-sys", "libc", @@ -1249,9 +1250,9 @@ dependencies = [ [[package]] name = "gdk4-x11" -version = "0.4.1" +version = "0.4.2" source = "registry+https://github.com/rust-lang/crates.io-index" -checksum = "11d4045a8841ee6fc17f14bc3f80eada5936244c2a958e7dd14f024d4601a454" +checksum = "f2a54a4f3405461afa18ddc2b5fbeaecc2558fcd8b132ed0c9c7c4ffa2f9ae22" dependencies = [ "gdk4", "gdk4-x11-sys", @@ -1262,9 +1263,9 @@ dependencies = [ [[package]] name = "gdk4-x11-sys" -version = "0.4.1" +version = "0.4.2" source = "registry+https://github.com/rust-lang/crates.io-index" -checksum = "d24f2fc9c91675f3873caa9baaaee042edfb5fcf77f866a1cbdd99f9a334c1bd" +checksum = "1eb40aebb4f15b270df2ac2c463bf7f6d82211d9c5df1d13b84541a63a3139d7" dependencies = [ "gdk4-sys", "glib-sys", @@ -1474,9 +1475,9 @@ dependencies = [ [[package]] name = "gsk4" -version = "0.4.1" +version = "0.4.4" source = "registry+https://github.com/rust-lang/crates.io-index" -checksum = "d3dd7c79a864b8c4606d39fad3fd872688ea20ba8e833a9f38e905a458a29a8c" +checksum = "0672c63e4101e19d5e9cb4a0aed8b3278e9573529bd0b6a86d9c748c71bd9882" dependencies = [ "bitflags", "cairo-rs", @@ -1490,9 +1491,9 @@ dependencies = [ [[package]] name = "gsk4-sys" -version = "0.4.1" +version = "0.4.2" source = "registry+https://github.com/rust-lang/crates.io-index" -checksum = "6d25ee96f7d1bdb6fa9945425aea95ce60efedf60c994eceb671fd93ad11d541" +checksum = "e31d21d7ce02ba261bb24c50c4ab238a10b41a2c97c32afffae29471b7cca69b" dependencies = [ "cairo-sys-rs", "gdk4-sys", @@ -1530,9 +1531,9 @@ dependencies = [ [[package]] name = "gstreamer" -version = "0.18.0" +version = "0.18.1" source = "registry+https://github.com/rust-lang/crates.io-index" -checksum = "939fd4f8afd09be887d05bb7ced532f215f21401837bf59f9fd2f68608e1e285" +checksum = "8050dd478c50f1796595275eb8f21b2e1c2604f7797fcd2cc513c7af710bb4ac" dependencies = [ "bitflags", "cfg-if 1.0.0", @@ -1594,9 +1595,9 @@ dependencies = [ [[package]] name = "gstreamer-video" -version = "0.18.0" +version = "0.18.1" source = "registry+https://github.com/rust-lang/crates.io-index" -checksum = "6c5f4d1bdccb60be70c63001d331e4945d9b61bf77610e33584525df10633917" +checksum = "410c72d885a67aeb7dbfa49c347e6c85d60f54e1cdaf6aadf8b5364892451261" dependencies = [ "bitflags", "cfg-if 1.0.0", @@ -1632,9 +1633,9 @@ checksum = "da5bf7748fd4cd0b2490df8debcc911809dbcbee4ece9531b96c29a9c729de5a" [[package]] name = "gtk4" -version = "0.4.1" +version = "0.4.4" source = "registry+https://github.com/rust-lang/crates.io-index" -checksum = "a6fda2b49a25eefc1116f15d06585d333c21fc3ce499ab0a86641fac2fbf40ac" +checksum = "b5020aeb559e0431930d66d85b8f16fc453fc0863466b13b7e1e1b800cf1a47b" dependencies = [ "bitflags", "cairo-rs", @@ -1655,9 +1656,9 @@ dependencies = [ [[package]] name = "gtk4-macros" -version = "0.4.1" +version = "0.4.3" source = "registry+https://github.com/rust-lang/crates.io-index" -checksum = "5b17860e493ada8a40577f0e92bce8249a97c831e39d7811ef21de6281d67f86" +checksum = "573db42bb64973a4d5f718b73caa7204285a1a665308a23b11723d0ee56ec305" dependencies = [ "anyhow", "proc-macro-crate 1.1.0", @@ -1669,9 +1670,9 @@ dependencies = [ [[package]] name = "gtk4-sys" -version = "0.4.1" +version = "0.4.2" source = "registry+https://github.com/rust-lang/crates.io-index" -checksum = "ffc1047ea7a0ff2947fbfb703eecfcca6b58912171037a4c55b1577015f079d5" +checksum = "1544614a8d44f38719a2fdfd608d644d5f385beab33e5852688f48a983a2b583" dependencies = [ "cairo-sys-rs", "gdk-pixbuf-sys", @@ -1744,7 +1745,7 @@ checksum = "31f4c6746584866f0feabcc69893c5b51beef3831656a968ed7ae254cdc4fd03" dependencies = [ "bytes 1.1.0", "fnv", - "itoa 1.0.1", + "itoa", ] [[package]] @@ -1876,12 +1877,6 @@ dependencies = [ "either", ] -[[package]] -name = "itoa" -version = "0.4.8" -source = "registry+https://github.com/rust-lang/crates.io-index" -checksum = "b71991ff56294aa922b450139ee08b3bfc70982c6b2c7562771375cf73542dd4" - [[package]] name = "itoa" version = "1.0.1" @@ -1899,9 +1894,9 @@ dependencies = [ [[package]] name = "js-sys" -version = "0.3.55" +version = "0.3.56" source = "registry+https://github.com/rust-lang/crates.io-index" -checksum = "7cc9ffccd38c451a86bf13657df244e9c3f37493cce8e5e21e940963777acc84" +checksum = "a38fc24e30fd564ce974c02bf1d337caddff65be6cc4735a1f7eab22a7440f04" dependencies = [ "wasm-bindgen", ] @@ -1974,9 +1969,9 @@ dependencies = [ [[package]] name = "libc" -version = "0.2.112" +version = "0.2.113" source = "registry+https://github.com/rust-lang/crates.io-index" -checksum = "1b03d17f364a3a042d5e5d46b053bbbf82c92c9430c592dd4c064dc6ee997125" +checksum = "eef78b64d87775463c549fbd80e19249ef436ea3bf1de2a1eb7e717ec7fab1e9" [[package]] name = "libloading" @@ -2729,9 +2724,9 @@ dependencies = [ [[package]] name = "quote" -version = "1.0.14" +version = "1.0.15" source = "registry+https://github.com/rust-lang/crates.io-index" -checksum = "47aa80447ce4daf1717500037052af176af5d38cc3e571d9ec1c7353fc10c87d" +checksum = "864d3e96a899863136fc6e99f3d7cae289dafe43bf2c5ac19b70df7210c0a145" dependencies = [ "proc-macro2", ] @@ -2988,6 +2983,19 @@ version = "1.1.0" source = "registry+https://github.com/rust-lang/crates.io-index" checksum = "d29ab0c6d3fc0ee92fe66e2d99f700eab17a8d57d1c1d3b748380fb20baa78cd" +[[package]] +name = "search-provider" +version = "0.3.0" +source = "registry+https://github.com/rust-lang/crates.io-index" +checksum = "350ac7d1c6898fa22b7ac0e4fbc857997c1b5f077ece7cdb1415c13954402f17" +dependencies = [ + "futures", + "serde", + "zbus 2.0.1", + "zvariant 3.1.1", + "zvariant_derive 3.1.1", +] + [[package]] name = "secret-service" version = "2.0.1" @@ -3043,18 +3051,18 @@ dependencies = [ [[package]] name = "serde" -version = "1.0.133" +version = "1.0.135" source = "registry+https://github.com/rust-lang/crates.io-index" -checksum = "97565067517b60e2d1ea8b268e59ce036de907ac523ad83a0475da04e818989a" +checksum = "2cf9235533494ea2ddcdb794665461814781c53f19d87b76e571a1c35acbad2b" dependencies = [ "serde_derive", ] [[package]] name = "serde_derive" -version = "1.0.133" +version = "1.0.135" source = "registry+https://github.com/rust-lang/crates.io-index" -checksum = "ed201699328568d8d08208fdd080e3ff594e6c422e438b6705905da01005d537" +checksum = "8dcde03d87d4c973c04be249e7d8f0b35db1c848c487bd43032808e59dd8328d" dependencies = [ "proc-macro2", "quote", @@ -3063,11 +3071,11 @@ dependencies = [ [[package]] name = "serde_json" -version = "1.0.75" +version = "1.0.78" source = "registry+https://github.com/rust-lang/crates.io-index" -checksum = "c059c05b48c5c0067d4b4b2b4f0732dd65feb52daf7e0ea09cd87e7dadc1af79" +checksum = "d23c1ba4cf0efd44be32017709280b32d1cea5c3f1275c3b6d9e8bc54f758085" dependencies = [ - "itoa 1.0.1", + "itoa", "ryu", "serde", ] @@ -3096,12 +3104,12 @@ dependencies = [ [[package]] name = "serde_urlencoded" -version = "0.7.0" +version = "0.7.1" source = "registry+https://github.com/rust-lang/crates.io-index" -checksum = "edfa57a7f8d9c1d260a549e7224100f6c43d43f9103e06dd8b4095a9b2b43ce9" +checksum = "d3491c14715ca2294c4d6a88f15e84739788c1d030eed8c110436aafdaa2f3fd" dependencies = [ "form_urlencoded", - "itoa 0.4.8", + "itoa", "ryu", "serde", ] @@ -3175,9 +3183,9 @@ checksum = "f2dd574626839106c320a323308629dcb1acfc96e32a8cba364ddc61ac23ee83" [[package]] name = "socket2" -version = "0.4.2" +version = "0.4.3" source = "registry+https://github.com/rust-lang/crates.io-index" -checksum = "5dc90fe6c7be1a323296982db1836d1ea9e47b6839496dde9a541bc496df3516" +checksum = "0f82496b90c36d70af5fcd482edaa2e0bd16fade569de1330405fecbbdac736b" dependencies = [ "libc", "winapi", @@ -3329,9 +3337,9 @@ dependencies = [ [[package]] name = "syn" -version = "1.0.85" +version = "1.0.86" source = "registry+https://github.com/rust-lang/crates.io-index" -checksum = "a684ac3dcd8913827e18cd09a68384ee66c1de24157e3c556c9ab16d85695fb7" +checksum = "8a65b3f4ffa0092e9887669db0eae07941f023991ab58ea44da8fe8e2d511c6b" dependencies = [ "proc-macro2", "quote", @@ -3684,9 +3692,9 @@ checksum = "fd6fbd9a79829dd1ad0cc20627bf1ed606756a7f77edff7b66b7064f9cb327c6" [[package]] name = "wasm-bindgen" -version = "0.2.78" +version = "0.2.79" source = "registry+https://github.com/rust-lang/crates.io-index" -checksum = "632f73e236b219150ea279196e54e610f5dbafa5d61786303d4da54f84e47fce" +checksum = "25f1af7423d8588a3d840681122e72e6a24ddbcb3f0ec385cac0d12d24256c06" dependencies = [ "cfg-if 1.0.0", "wasm-bindgen-macro", @@ -3694,9 +3702,9 @@ dependencies = [ [[package]] name = "wasm-bindgen-backend" -version = "0.2.78" +version = "0.2.79" source = "registry+https://github.com/rust-lang/crates.io-index" -checksum = "a317bf8f9fba2476b4b2c85ef4c4af8ff39c3c7f0cdfeed4f82c34a880aa837b" +checksum = "8b21c0df030f5a177f3cba22e9bc4322695ec43e7257d865302900290bcdedca" dependencies = [ "bumpalo", "lazy_static", @@ -3709,9 +3717,9 @@ dependencies = [ [[package]] name = "wasm-bindgen-futures" -version = "0.4.28" +version = "0.4.29" source = "registry+https://github.com/rust-lang/crates.io-index" -checksum = "8e8d7523cb1f2a4c96c1317ca690031b714a51cc14e05f712446691f413f5d39" +checksum = "2eb6ec270a31b1d3c7e266b999739109abce8b6c87e4b31fcfcd788b65267395" dependencies = [ "cfg-if 1.0.0", "js-sys", @@ -3721,9 +3729,9 @@ dependencies = [ [[package]] name = "wasm-bindgen-macro" -version = "0.2.78" +version = "0.2.79" source = "registry+https://github.com/rust-lang/crates.io-index" -checksum = "d56146e7c495528bf6587663bea13a8eb588d39b36b679d83972e1a2dbbdacf9" +checksum = "2f4203d69e40a52ee523b2529a773d5ffc1dc0071801c87b3d270b471b80ed01" dependencies = [ "quote", "wasm-bindgen-macro-support", @@ -3731,9 +3739,9 @@ dependencies = [ [[package]] name = "wasm-bindgen-macro-support" -version = "0.2.78" +version = "0.2.79" source = "registry+https://github.com/rust-lang/crates.io-index" -checksum = "7803e0eea25835f8abdc585cd3021b3deb11543c6fe226dcd30b228857c5c5ab" +checksum = "bfa8a30d46208db204854cadbb5d4baf5fcf8071ba5bf48190c3e59937962ebc" dependencies = [ "proc-macro2", "quote", @@ -3744,15 +3752,15 @@ dependencies = [ [[package]] name = "wasm-bindgen-shared" -version = "0.2.78" +version = "0.2.79" source = "registry+https://github.com/rust-lang/crates.io-index" -checksum = "0237232789cf037d5480773fe568aac745bfe2afbc11a863e97901780a6b47cc" +checksum = "3d958d035c4438e28c70e4321a2911302f10135ce78a9c7834c0cab4123d06a2" [[package]] name = "web-sys" -version = "0.3.55" +version = "0.3.56" source = "registry+https://github.com/rust-lang/crates.io-index" -checksum = "38eb105f1c59d9eaa6b5cdc92b859d85b926e82cb2e0945cd0c9259faa6fe9fb" +checksum = "c060b319f29dd25724f09a2ba1418f142f539b2be99fbf4d2d5a8f7330afb8eb" dependencies = [ "js-sys", "wasm-bindgen", @@ -3893,7 +3901,7 @@ dependencies = [ "static_assertions", "zbus_macros 2.0.1", "zbus_names", - "zvariant 3.0.0", + "zvariant 3.1.1", ] [[package]] @@ -3929,7 +3937,7 @@ checksum = "45dfcdcf87b71dad505d30cc27b1b7b88a64b6d1c435648f48f9dbc1fdc4b7e1" dependencies = [ "serde", "static_assertions", - "zvariant 3.0.0", + "zvariant 3.1.1", ] [[package]] @@ -3948,16 +3956,16 @@ dependencies = [ [[package]] name = "zvariant" -version = "3.0.0" +version = "3.1.1" source = "registry+https://github.com/rust-lang/crates.io-index" -checksum = "4a946c049b2eac1a253f98e9267a8ce7a3d93be274ea146e6dd7a0965232a911" +checksum = "f3e5f0c5e59387ef95e9845837408831545e3fa4960c485550577c74e74a307e" dependencies = [ "byteorder", "enumflags2 0.7.3", "libc", "serde", "static_assertions", - "zvariant_derive 3.0.0", + "zvariant_derive 3.1.1", ] [[package]] @@ -3974,9 +3982,9 @@ dependencies = [ [[package]] name = "zvariant_derive" -version = "3.0.0" +version = "3.1.1" source = "registry+https://github.com/rust-lang/crates.io-index" -checksum = "28fce5afb8d639bff79b1e8cdb258a3ca22d458f4603b23d794b4cb4e878c990" +checksum = "cc88c5b820f3789337482b6278e2a57c41b8dff6b58950a094229e40de129ea7" dependencies = [ "proc-macro-crate 1.1.0", "proc-macro2", diff --git a/Cargo.toml b/Cargo.toml index 99b16f0..493b7a6 100644 --- a/Cargo.toml +++ b/Cargo.toml @@ -17,6 +17,7 @@ gst = {package = "gstreamer", version = "0.18"} gst4gtk = { package = "gst-plugin-gtk4", version = "0.1"} gtk = {package = "gtk4", version = "0.4"} gtk-macros = "0.3" +search-provider = "0.3" hex = "0.4" image = "0.23" log = "0.4" diff --git a/build-aux/com.belmoussaoui.Authenticator.Devel.json b/build-aux/com.belmoussaoui.Authenticator.Devel.json index 968b888..0f2ed60 100644 --- a/build-aux/com.belmoussaoui.Authenticator.Devel.json +++ b/build-aux/com.belmoussaoui.Authenticator.Devel.json @@ -16,7 +16,8 @@ "--device=dri", "--talk-name=org.freedesktop.secrets", "--env=RUST_LOG=authenticator=debug,ashpd=debug", - "--env=G_MESSAGES_DEBUG=none" + "--env=G_MESSAGES_DEBUG=none", + "--own-name=com.belmoussaoui.Authenticator.Devel.SearchProvider" ], "build-options": { "append-path": "/usr/lib/sdk/rust-stable/bin", diff --git a/data/com.belmoussaoui.Authenticator.SearchProvider.service.in b/data/com.belmoussaoui.Authenticator.SearchProvider.service.in new file mode 100644 index 0000000..3d29df7 --- /dev/null +++ b/data/com.belmoussaoui.Authenticator.SearchProvider.service.in @@ -0,0 +1,4 @@ +[D-BUS Service] +Name=@appid@.SearchProvider +Exec=@bindir@/@name@ --gapplication-service + diff --git a/data/com.belmoussaoui.Authenticator.search-provider.ini b/data/com.belmoussaoui.Authenticator.search-provider.ini new file mode 100644 index 0000000..492f185 --- /dev/null +++ b/data/com.belmoussaoui.Authenticator.search-provider.ini @@ -0,0 +1,6 @@ +[Shell Search Provider] +DesktopId=@appid@.desktop +BusName=@appid@.SearchProvider +ObjectPath=@object_path@ +Version=2 + diff --git a/data/meson.build b/data/meson.build index 0d1d94a..9a9009d 100644 --- a/data/meson.build +++ b/data/meson.build @@ -78,4 +78,26 @@ if appstream_util.found() ) endif + +# Search Provider +service_conf = configuration_data() +service_conf.set('appid', application_id) +service_conf.set('name', meson.project_name()) +service_conf.set('bindir', bindir) +configure_file( + input: 'com.belmoussaoui.Authenticator.SearchProvider.service.in', + output: '@0@.SearchProvider.service'.format(application_id), + configuration: service_conf, + install_dir: datadir / 'dbus-1' / 'services' +) +search_conf = configuration_data() +search_conf.set('appid', application_id) +search_conf.set('object_path', object_path) +configure_file( + input: 'com.belmoussaoui.Authenticator.search-provider.ini', + output: '@0@.search-provider.ini'.format(application_id), + configuration: search_conf, + install_dir: datadir / 'gnome-shell' / 'search-providers', +) + subdir('icons') diff --git a/meson.build b/meson.build index e849325..9df11fa 100644 --- a/meson.build +++ b/meson.build @@ -40,10 +40,13 @@ if get_option('profile') == 'development' else version_suffix = '-@0@'.format (vcs_tag) endif + object_path = '/com/belmoussaoui/Authenticator/Devel/SearchProvider' else profile = '' version_suffix = '' application_id = 'com.belmoussaoui.Authenticator' + object_path = '/com/belmoussaoui/Authenticator/SearchProvider' + endif i18n = import('i18n') diff --git a/src/application.rs b/src/application.rs index 5af1388..d03f8b2 100644 --- a/src/application.rs +++ b/src/application.rs @@ -1,13 +1,14 @@ use crate::{ config, - models::{Keyring, OTPUri, ProvidersModel, FAVICONS_PATH}, - widgets::{PreferencesWindow, ProvidersDialog, Window}, + models::{Account, Keyring, OTPUri, Provider, ProvidersModel, FAVICONS_PATH}, + widgets::{PreferencesWindow, ProvidersDialog, View, Window}, }; use adw::prelude::*; use gettextrs::gettext; use glib::clone; use gtk::{gio, glib, subclass::prelude::*}; use gtk_macros::{action, get_action}; +use search_provider::{ResultID, ResultMeta, SearchProvider, SearchProviderImpl}; use std::str::FromStr; mod imp { @@ -25,6 +26,7 @@ mod imp { pub lock_timeout_id: RefCell>, pub can_be_locked: Cell, pub settings: gio::Settings, + pub search_provider: RefCell>>, } // Sets up the basics for the GObject @@ -46,6 +48,7 @@ mod imp { can_be_locked: Cell::new(false), lock_timeout_id: RefCell::default(), locked: Cell::new(false), + search_provider: RefCell::default(), } } } @@ -108,20 +111,19 @@ mod imp { app, "preferences", clone!(@weak app, @weak self.model as model => move |_,_| { - let active_window = app.active_window().unwrap(); - let win = active_window.downcast_ref::().unwrap(); + let window = app.active_window(); let preferences = PreferencesWindow::new(model); preferences.set_has_set_password(app.can_be_locked()); - preferences.connect_local("restore-completed", false, clone!(@weak win => @default-return None, move |_| { - win.providers().refilter(); + preferences.connect_local("restore-completed", false, clone!(@weak window => @default-return None, move |_| { + window.providers().refilter(); None })); preferences.connect_notify_local(Some("has-set-password"), clone!(@weak app => move |preferences, _| { let state = preferences.has_set_password(); app.set_can_be_locked(state); })); - preferences.set_transient_for(Some(&active_window)); + preferences.set_transient_for(Some(&window)); preferences.show(); }) ); @@ -131,7 +133,7 @@ mod imp { app, "about", clone!(@weak app => move |_, _| { - let window = app.active_window().unwrap(); + let window = app.active_window(); gtk::AboutDialog::builder() .program_name(&gettext("Authenticator")) .modal(true) @@ -152,11 +154,10 @@ mod imp { app, "providers", clone!(@weak app,@weak self.model as model => move |_, _| { - let window = app.active_window().unwrap(); + let window = app.active_window(); let providers = ProvidersDialog::new(model); - let win = window.downcast_ref::().unwrap(); - providers.connect_local("changed", false, clone!(@weak win => @default-return None, move |_| { - win.providers().refilter(); + providers.connect_local("changed", false, clone!(@weak window => @default-return None, move |_| { + window.providers().refilter(); None })); providers.set_transient_for(Some(&window)); @@ -204,6 +205,20 @@ mod imp { }), ); app.update_color_scheme(); + + let search_provider_path = config::OBJECT_PATH; + let search_provider_name = format!("{}.SearchProvider", config::APP_ID); + + let ctx = glib::MainContext::default(); + ctx.spawn_local(clone!(@strong app as application => async move { + let imp = application.imp(); + match SearchProvider::new(application.clone(), search_provider_name, search_provider_path).await { + Ok(search_provider) => { + imp.search_provider.replace(Some(search_provider)); + }, + Err(err) => log::debug!("Could not start search provider: {}", err), + }; + })); } fn activate(&self, app: &Self::Type) { @@ -243,7 +258,7 @@ mod imp { .collect::>(); // We only handle a signle URI (see the desktop file) if let Some(uri) = uris.get(0) { - let window = self.window.borrow().as_ref().unwrap().upgrade().unwrap(); + let window = application.active_window(); window.open_add_account(Some(uri)) } } @@ -285,6 +300,16 @@ impl Application { ApplicationExtManual::run(&app); } + pub fn active_window(&self) -> Window { + self.imp() + .window + .borrow() + .as_ref() + .unwrap() + .upgrade() + .unwrap() + } + pub fn locked(&self) -> bool { self.property("locked") } @@ -346,4 +371,71 @@ impl Application { manager.set_color_scheme(color_scheme); } } + + fn account_provider_by_identifier(&self, id: &str) -> Option<(Provider, Account)> { + let identifier = id.split(':').collect::>(); + let provider_id = identifier.get(0)?.parse::().ok()?; + let account_id = identifier.get(1)?.parse::().ok()?; + + let provider = self.imp().model.find_by_id(provider_id)?; + let account = provider.accounts_model().find_by_id(account_id)?; + + Some((provider, account)) + } +} + +impl SearchProviderImpl for Application { + fn launch_search(&self, terms: &[String], timestamp: u32) { + self.activate(); + let window = self.active_window(); + window.imp().search_entry.set_text(&terms.join(" ")); + window.imp().search_btn.set_active(true); + window.present_with_time(timestamp); + } + + fn activate_result(&self, identifier: ResultID, _terms: &[String], timestamp: u32) { + self.activate(); + + let identifier = identifier.split(':').collect::>(); + let provider_id = identifier[0].parse::().unwrap(); + let account_id = identifier[1].parse::().unwrap(); + + let provider = self.imp().model.find_by_id(provider_id).unwrap(); + let account = provider.accounts_model().find_by_id(account_id).unwrap(); + account.copy_otp(); + + let window = self.active_window(); + window.set_view(View::Account(account)); + window.present_with_time(timestamp); + } + + fn initial_result_set(&self, terms: &[String]) -> Vec { + // don't show any results if the application is locked + if self.property::("locked") { + vec![] + } else { + self.imp() + .model + .find_accounts(terms) + .into_iter() + .map(|account| format!("{}:{}", account.provider().id(), account.id())) + .collect::>() + } + } + + fn result_metas(&self, identifiers: &[ResultID]) -> Vec { + identifiers + .into_iter() + .map(|id| { + self.account_provider_by_identifier(id) + .map(|(provider, account)| { + ResultMeta::builder(id.to_owned(), &account.name()) + .description(&provider.name()) + .clipboard_text(&account.otp()) + .build() + }) + }) + .flatten() + .collect::>() + } } diff --git a/src/config.rs.in b/src/config.rs.in index 55183fd..e3537ee 100644 --- a/src/config.rs.in +++ b/src/config.rs.in @@ -4,4 +4,4 @@ pub static PROFILE: &str = @PROFILE@; pub static VERSION: &str = @VERSION@; pub static GETTEXT_PACKAGE: &str = @GETTEXT_PACKAGE@; pub static LOCALEDIR: &str = @LOCALEDIR@; - +pub static OBJECT_PATH: &str = @OBJECT_PATH@; diff --git a/src/meson.build b/src/meson.build index 725ac1d..1edbba4 100644 --- a/src/meson.build +++ b/src/meson.build @@ -7,6 +7,7 @@ global_conf.set_quoted('PROFILE', profile) global_conf.set_quoted('VERSION', version + version_suffix) global_conf.set_quoted('GETTEXT_PACKAGE', gettext_package) global_conf.set_quoted('LOCALEDIR', localedir) +global_conf.set_quoted('OBJECT_PATH', object_path) config_output_file = configure_file( input: 'config.rs.in', output: 'config.rs', diff --git a/src/models/account.rs b/src/models/account.rs index df33aea..cc0333d 100644 --- a/src/models/account.rs +++ b/src/models/account.rs @@ -168,7 +168,12 @@ glib::wrapper! { } impl Account { - pub fn create(name: &str, token: &str, counter: Option, provider: &Provider) -> Result { + pub fn create( + name: &str, + token: &str, + counter: Option, + provider: &Provider, + ) -> Result { let db = database::connection(); let conn = db.get()?; @@ -312,6 +317,10 @@ impl Account { Ok(()) } + pub fn otp(&self) -> String { + self.property("otp") + } + pub fn copy_otp(&self) { let display = gtk::gdk::Display::default().unwrap(); let clipboard = display.clipboard(); diff --git a/src/models/accounts.rs b/src/models/accounts.rs index aeec772..9440349 100644 --- a/src/models/accounts.rs +++ b/src/models/accounts.rs @@ -57,10 +57,21 @@ impl AccountsModel { self.items_changed(pos, 1, 0); } - pub fn find_by_id(&self, id: u32) -> Option { + pub fn find_by_id(&self, id: u32) -> Option { for pos in 0..self.n_items() { let obj = self.item(pos)?; let account = obj.downcast::().unwrap(); + if account.id() == id { + return Some(account); + } + } + None + } + + pub fn find_position_by_id(&self, id: u32) -> Option { + for pos in 0..self.n_items() { + let obj = self.item(pos)?; + let account = obj.downcast_ref::().unwrap(); if account.id() == id { return Some(pos); } diff --git a/src/models/provider.rs b/src/models/provider.rs index 0b80eb0..a737efa 100644 --- a/src/models/provider.rs +++ b/src/models/provider.rs @@ -473,7 +473,7 @@ impl Provider { } pub fn has_account(&self, account: &Account) -> Option { - self.imp().accounts.find_by_id(account.id()) + self.imp().accounts.find_position_by_id(account.id()) } pub fn has_accounts(&self) -> bool { @@ -488,6 +488,22 @@ impl Provider { &self.imp().accounts } + pub fn find_accounts(&self, terms: &[String]) -> Vec { + let mut results = vec![]; + let model = self.accounts_model(); + + for pos in 0..model.n_items() { + let obj = model.item(pos).unwrap(); + let account = obj.downcast::().unwrap(); + let account_name = account.name(); + + if terms.iter().any(|term| account_name.contains(term)) { + results.push(account); + } + } + results + } + pub fn accounts(&self) -> >k::FilterListModel { &self.imp().filter_model } @@ -509,7 +525,7 @@ impl Provider { pub fn remove_account(&self, account: Account) { let imp = self.imp(); - if let Some(pos) = imp.accounts.find_by_id(account.id()) { + if let Some(pos) = imp.accounts.find_position_by_id(account.id()) { imp.accounts.remove(pos); } } diff --git a/src/models/providers.rs b/src/models/providers.rs index 3e8872b..f93fb24 100644 --- a/src/models/providers.rs +++ b/src/models/providers.rs @@ -172,6 +172,18 @@ impl ProvidersModel { } } + pub fn find_accounts(&self, terms: &[String]) -> Vec { + let mut results = vec![]; + + for pos in 0..self.n_items() { + let obj = self.item(pos).unwrap(); + let provider = obj.downcast_ref::().unwrap(); + let accounts = provider.find_accounts(terms); + results.extend(accounts); + } + results + } + fn init(&self) { // fill in the providers from the database Provider::load()