aboutsummaryrefslogtreecommitdiff
diff options
context:
space:
mode:
-rw-r--r--.github/workflows/pull_request.yml1
-rw-r--r--.github/workflows/push.yml56
-rw-r--r--.gitignore1
-rw-r--r--.sqlx/query-1dc5f44967ffdee882f4cef32262fd643b452aacca373ee527c978e816115de6.json49
-rw-r--r--.sqlx/query-25ab5caa92ff80ef3f85ddce1174021ce0fb896a818a6deee291a1eb85ae2a8a.json15
-rw-r--r--.sqlx/query-566c84386614590144dfebce2248cb3a734074014a493a7aad6fa03bb1286dc8.json49
-rw-r--r--.sqlx/query-5ac2b9a76338dd1342938cc09e37b14c828c4ee44b696d83f87f739022be6948.json20
-rw-r--r--.sqlx/query-62c84231c7e9c85dc91d71f6b4f7ee6dae2130c2109fb6f1e47e0990ec395744.json46
-rw-r--r--.sqlx/query-a1114f47abaa2ace231ef61cbd787a2f2a30efc581ea075b7e86ae75458c9014.json46
-rw-r--r--.sqlx/query-adead45e1a6b02d5eabd68b8cf06394a302d288e91f5eedde65db6630021f737.json17
-rw-r--r--.sqlx/query-df462bb016e2d258de146e248493f4458a532eee554d57438ef7849758238185.json15
-rw-r--r--.sqlx/query-e452c5ed8bdaec2011d78386cffd2b4739d88b3061931562e07c3e8dd24e6359.json49
-rw-r--r--.sqlx/query-edc4ecf39512caec1076be1b2849b2530be7bcdcbe14362077b3fd47cd711c89.json17
-rw-r--r--Cargo.lock731
-rw-r--r--Cargo.toml3
-rw-r--r--Dockerfile2
-rw-r--r--README.md27
-rw-r--r--build.rs5
-rw-r--r--docker-compose.yml13
-rw-r--r--migrations/20231009123228_devices.sql9
-rw-r--r--src/auth.rs5
-rw-r--r--src/config.rs5
-rw-r--r--src/db.rs37
-rw-r--r--src/error.rs21
-rw-r--r--src/main.rs41
-rw-r--r--src/routes/device.rs118
-rw-r--r--src/routes/start.rs100
-rw-r--r--src/routes/status.rs24
-rw-r--r--src/services/ping.rs45
-rw-r--r--src/storage.rs70
-rw-r--r--src/wol.rs20
31 files changed, 240 insertions, 1417 deletions
diff --git a/.github/workflows/pull_request.yml b/.github/workflows/pull_request.yml
index 7196d4e..663f437 100644
--- a/.github/workflows/pull_request.yml
+++ b/.github/workflows/pull_request.yml
@@ -5,7 +5,6 @@ on: [ pull_request, workflow_dispatch ]
5env: 5env:
6 SCCACHE_GHA_ENABLED: "true" 6 SCCACHE_GHA_ENABLED: "true"
7 RUSTC_WRAPPER: "sccache" 7 RUSTC_WRAPPER: "sccache"
8 SQLX_OFFLINE: "true"
9 CARGO_TERM_COLOR: always 8 CARGO_TERM_COLOR: always
10 9
11jobs: 10jobs:
diff --git a/.github/workflows/push.yml b/.github/workflows/push.yml
index d41941b..30edefa 100644
--- a/.github/workflows/push.yml
+++ b/.github/workflows/push.yml
@@ -1,15 +1,11 @@
1name: build and push 1name: container
2 2
3on: 3on:
4 push: 4 push:
5 branches: [ "main" ] 5 branches:
6 workflow_dispatch: 6 - "main"
7 7 tags:
8env: 8 - "v*.*.*"
9 SCCACHE_GHA_ENABLED: "true"
10 RUSTC_WRAPPER: "sccache"
11 SQLX_OFFLINE: "true"
12 CARGO_TERM_COLOR: always
13 9
14jobs: 10jobs:
15 test: 11 test:
@@ -23,28 +19,42 @@ jobs:
23 - run: cargo check --release 19 - run: cargo check --release
24 - run: cargo clippy --release 20 - run: cargo clippy --release
25 21
26 build: 22 docker:
27 runs-on: ubuntu-latest 23 runs-on: ubuntu-latest
28 needs: test
29 steps: 24 steps:
25 - name: Checkout
26 uses: actions/checkout@v4
27 - name: Docker meta
28 id: meta
29 uses: docker/metadata-action@v5
30 with:
31 # list of Docker images to use as base name for tags
32 images: ghcr.io/fxqnlr/webol
33 # generate Docker tags based on the following events/attributes
34 tags: |
35 type=schedule
36 type=ref,event=branch
37 type=ref,event=pr
38 type=semver,pattern={{version}}
39 type=semver,pattern={{major}}.{{minor}}
40 type=semver,pattern={{major}}
41 type=sha
30 - name: Set up QEMU 42 - name: Set up QEMU
31 uses: docker/setup-qemu-action@v3 43 uses: docker/setup-qemu-action@v3
32 - name: Set up Docker Buildx 44 - name: Set up Docker Buildx
33 uses: docker/setup-buildx-action@v2 45 uses: docker/setup-buildx-action@v3
34 - name: Login to DockerHub 46 - name: Login to GHCR
35 uses: docker/login-action@v2 47 if: github.event_name != 'pull_request'
48 uses: docker/login-action@v3
36 with: 49 with:
37 registry: ghcr.io 50 registry: ghcr.io
38 username: ${{ github.actor }} 51 username: ${{ github.repository_owner }}
39 password: ${{ secrets.GITHUB_TOKEN }} 52 password: ${{ secrets.GITHUB_TOKEN }}
40 - name: Build and push 53 - name: Build and push
41 id: docker_build 54 uses: docker/build-push-action@v5
42 uses: docker/build-push-action@v3
43 with: 55 with:
44 push: true 56 context: .
45 platforms: linux/amd64,linux/arm64 57 platforms: linux/amd64,linux/arm64
46 cache-from: type=gha 58 push: ${{ github.event_name != 'pull_request' }}
47 cache-to: type=gha,mode=max 59 tags: ${{ steps.meta.outputs.tags }}
48 tags: | 60 labels: ${{ steps.meta.outputs.labels }}
49 ghcr.io/fxqnlr/webol:dev-latest
50 ghcr.io/fxqnlr/webol:dev-${{ github.run_number }}
diff --git a/.gitignore b/.gitignore
index cbba613..9458d8b 100644
--- a/.gitignore
+++ b/.gitignore
@@ -17,4 +17,5 @@ config.*
17.lapce 17.lapce
18 18
19logs/ 19logs/
20devices/
20*.log 21*.log
diff --git a/.sqlx/query-1dc5f44967ffdee882f4cef32262fd643b452aacca373ee527c978e816115de6.json b/.sqlx/query-1dc5f44967ffdee882f4cef32262fd643b452aacca373ee527c978e816115de6.json
deleted file mode 100644
index dd85eaa..0000000
--- a/.sqlx/query-1dc5f44967ffdee882f4cef32262fd643b452aacca373ee527c978e816115de6.json
+++ /dev/null
@@ -1,49 +0,0 @@
1{
2 "db_name": "PostgreSQL",
3 "query": "\n UPDATE devices\n SET mac = $1, broadcast_addr = $2, ip = $3 WHERE id = $4\n RETURNING id, mac, broadcast_addr, ip, times;\n ",
4 "describe": {
5 "columns": [
6 {
7 "ordinal": 0,
8 "name": "id",
9 "type_info": "Varchar"
10 },
11 {
12 "ordinal": 1,
13 "name": "mac",
14 "type_info": "Macaddr"
15 },
16 {
17 "ordinal": 2,
18 "name": "broadcast_addr",
19 "type_info": "Varchar"
20 },
21 {
22 "ordinal": 3,
23 "name": "ip",
24 "type_info": "Inet"
25 },
26 {
27 "ordinal": 4,
28 "name": "times",
29 "type_info": "Int8Array"
30 }
31 ],
32 "parameters": {
33 "Left": [
34 "Macaddr",
35 "Varchar",
36 "Inet",
37 "Text"
38 ]
39 },
40 "nullable": [
41 false,
42 false,
43 false,
44 false,
45 true
46 ]
47 },
48 "hash": "1dc5f44967ffdee882f4cef32262fd643b452aacca373ee527c978e816115de6"
49}
diff --git a/.sqlx/query-25ab5caa92ff80ef3f85ddce1174021ce0fb896a818a6deee291a1eb85ae2a8a.json b/.sqlx/query-25ab5caa92ff80ef3f85ddce1174021ce0fb896a818a6deee291a1eb85ae2a8a.json
deleted file mode 100644
index 71438e3..0000000
--- a/.sqlx/query-25ab5caa92ff80ef3f85ddce1174021ce0fb896a818a6deee291a1eb85ae2a8a.json
+++ /dev/null
@@ -1,15 +0,0 @@
1{
2 "db_name": "PostgreSQL",
3 "query": "\n UPDATE devices\n SET times = array_append(times, $1)\n WHERE id = $2;\n ",
4 "describe": {
5 "columns": [],
6 "parameters": {
7 "Left": [
8 "Int8",
9 "Text"
10 ]
11 },
12 "nullable": []
13 },
14 "hash": "25ab5caa92ff80ef3f85ddce1174021ce0fb896a818a6deee291a1eb85ae2a8a"
15}
diff --git a/.sqlx/query-566c84386614590144dfebce2248cb3a734074014a493a7aad6fa03bb1286dc8.json b/.sqlx/query-566c84386614590144dfebce2248cb3a734074014a493a7aad6fa03bb1286dc8.json
deleted file mode 100644
index 735c3bb..0000000
--- a/.sqlx/query-566c84386614590144dfebce2248cb3a734074014a493a7aad6fa03bb1286dc8.json
+++ /dev/null
@@ -1,49 +0,0 @@
1{
2 "db_name": "PostgreSQL",
3 "query": "\n INSERT INTO devices (id, mac, broadcast_addr, ip)\n VALUES ($1, $2, $3, $4)\n RETURNING id, mac, broadcast_addr, ip, times;\n ",
4 "describe": {
5 "columns": [
6 {
7 "ordinal": 0,
8 "name": "id",
9 "type_info": "Varchar"
10 },
11 {
12 "ordinal": 1,
13 "name": "mac",
14 "type_info": "Macaddr"
15 },
16 {
17 "ordinal": 2,
18 "name": "broadcast_addr",
19 "type_info": "Varchar"
20 },
21 {
22 "ordinal": 3,
23 "name": "ip",
24 "type_info": "Inet"
25 },
26 {
27 "ordinal": 4,
28 "name": "times",
29 "type_info": "Int8Array"
30 }
31 ],
32 "parameters": {
33 "Left": [
34 "Varchar",
35 "Macaddr",
36 "Varchar",
37 "Inet"
38 ]
39 },
40 "nullable": [
41 false,
42 false,
43 false,
44 false,
45 true
46 ]
47 },
48 "hash": "566c84386614590144dfebce2248cb3a734074014a493a7aad6fa03bb1286dc8"
49}
diff --git a/.sqlx/query-5ac2b9a76338dd1342938cc09e37b14c828c4ee44b696d83f87f739022be6948.json b/.sqlx/query-5ac2b9a76338dd1342938cc09e37b14c828c4ee44b696d83f87f739022be6948.json
deleted file mode 100644
index c385101..0000000
--- a/.sqlx/query-5ac2b9a76338dd1342938cc09e37b14c828c4ee44b696d83f87f739022be6948.json
+++ /dev/null
@@ -1,20 +0,0 @@
1{
2 "db_name": "PostgreSQL",
3 "query": "SELECT times FROM devices;",
4 "describe": {
5 "columns": [
6 {
7 "ordinal": 0,
8 "name": "times",
9 "type_info": "Int8Array"
10 }
11 ],
12 "parameters": {
13 "Left": []
14 },
15 "nullable": [
16 true
17 ]
18 },
19 "hash": "5ac2b9a76338dd1342938cc09e37b14c828c4ee44b696d83f87f739022be6948"
20}
diff --git a/.sqlx/query-62c84231c7e9c85dc91d71f6b4f7ee6dae2130c2109fb6f1e47e0990ec395744.json b/.sqlx/query-62c84231c7e9c85dc91d71f6b4f7ee6dae2130c2109fb6f1e47e0990ec395744.json
deleted file mode 100644
index 905bb51..0000000
--- a/.sqlx/query-62c84231c7e9c85dc91d71f6b4f7ee6dae2130c2109fb6f1e47e0990ec395744.json
+++ /dev/null
@@ -1,46 +0,0 @@
1{
2 "db_name": "PostgreSQL",
3 "query": "\n SELECT id, mac, broadcast_addr, ip, times\n FROM devices\n WHERE id = $1;\n ",
4 "describe": {
5 "columns": [
6 {
7 "ordinal": 0,
8 "name": "id",
9 "type_info": "Varchar"
10 },
11 {
12 "ordinal": 1,
13 "name": "mac",
14 "type_info": "Macaddr"
15 },
16 {
17 "ordinal": 2,
18 "name": "broadcast_addr",
19 "type_info": "Varchar"
20 },
21 {
22 "ordinal": 3,
23 "name": "ip",
24 "type_info": "Inet"
25 },
26 {
27 "ordinal": 4,
28 "name": "times",
29 "type_info": "Int8Array"
30 }
31 ],
32 "parameters": {
33 "Left": [
34 "Text"
35 ]
36 },
37 "nullable": [
38 false,
39 false,
40 false,
41 false,
42 true
43 ]
44 },
45 "hash": "62c84231c7e9c85dc91d71f6b4f7ee6dae2130c2109fb6f1e47e0990ec395744"
46}
diff --git a/.sqlx/query-a1114f47abaa2ace231ef61cbd787a2f2a30efc581ea075b7e86ae75458c9014.json b/.sqlx/query-a1114f47abaa2ace231ef61cbd787a2f2a30efc581ea075b7e86ae75458c9014.json
deleted file mode 100644
index 53608ed..0000000
--- a/.sqlx/query-a1114f47abaa2ace231ef61cbd787a2f2a30efc581ea075b7e86ae75458c9014.json
+++ /dev/null
@@ -1,46 +0,0 @@
1{
2 "db_name": "PostgreSQL",
3 "query": "\n SELECT id, mac, broadcast_addr, ip, times\n FROM devices\n WHERE id = $1;\n ",
4 "describe": {
5 "columns": [
6 {
7 "ordinal": 0,
8 "name": "id",
9 "type_info": "Varchar"
10 },
11 {
12 "ordinal": 1,
13 "name": "mac",
14 "type_info": "Macaddr"
15 },
16 {
17 "ordinal": 2,
18 "name": "broadcast_addr",
19 "type_info": "Varchar"
20 },
21 {
22 "ordinal": 3,
23 "name": "ip",
24 "type_info": "Inet"
25 },
26 {
27 "ordinal": 4,
28 "name": "times",
29 "type_info": "Int8Array"
30 }
31 ],
32 "parameters": {
33 "Left": [
34 "Text"
35 ]
36 },
37 "nullable": [
38 false,
39 false,
40 false,
41 false,
42 true
43 ]
44 },
45 "hash": "a1114f47abaa2ace231ef61cbd787a2f2a30efc581ea075b7e86ae75458c9014"
46}
diff --git a/.sqlx/query-adead45e1a6b02d5eabd68b8cf06394a302d288e91f5eedde65db6630021f737.json b/.sqlx/query-adead45e1a6b02d5eabd68b8cf06394a302d288e91f5eedde65db6630021f737.json
deleted file mode 100644
index d25b12e..0000000
--- a/.sqlx/query-adead45e1a6b02d5eabd68b8cf06394a302d288e91f5eedde65db6630021f737.json
+++ /dev/null
@@ -1,17 +0,0 @@
1{
2 "db_name": "PostgreSQL",
3 "query": "\n INSERT INTO devices (id, mac, broadcast_addr, ip)\n VALUES ($1, $2, $3, $4);\n ",
4 "describe": {
5 "columns": [],
6 "parameters": {
7 "Left": [
8 "Varchar",
9 "Macaddr",
10 "Varchar",
11 "Inet"
12 ]
13 },
14 "nullable": []
15 },
16 "hash": "adead45e1a6b02d5eabd68b8cf06394a302d288e91f5eedde65db6630021f737"
17}
diff --git a/.sqlx/query-df462bb016e2d258de146e248493f4458a532eee554d57438ef7849758238185.json b/.sqlx/query-df462bb016e2d258de146e248493f4458a532eee554d57438ef7849758238185.json
deleted file mode 100644
index e448b24..0000000
--- a/.sqlx/query-df462bb016e2d258de146e248493f4458a532eee554d57438ef7849758238185.json
+++ /dev/null
@@ -1,15 +0,0 @@
1{
2 "db_name": "PostgreSQL",
3 "query": "\n UPDATE devices\n SET times = array_append(times, $1)\n WHERE id = $2;\n ",
4 "describe": {
5 "columns": [],
6 "parameters": {
7 "Left": [
8 "Int8",
9 "Text"
10 ]
11 },
12 "nullable": []
13 },
14 "hash": "df462bb016e2d258de146e248493f4458a532eee554d57438ef7849758238185"
15}
diff --git a/.sqlx/query-e452c5ed8bdaec2011d78386cffd2b4739d88b3061931562e07c3e8dd24e6359.json b/.sqlx/query-e452c5ed8bdaec2011d78386cffd2b4739d88b3061931562e07c3e8dd24e6359.json
deleted file mode 100644
index 75ec121..0000000
--- a/.sqlx/query-e452c5ed8bdaec2011d78386cffd2b4739d88b3061931562e07c3e8dd24e6359.json
+++ /dev/null
@@ -1,49 +0,0 @@
1{
2 "db_name": "PostgreSQL",
3 "query": "\n UPDATE devices\n SET mac = $1, broadcast_addr = $2, ip = $3 WHERE id = $4\n RETURNING id, mac, broadcast_addr, ip, times;\n ",
4 "describe": {
5 "columns": [
6 {
7 "ordinal": 0,
8 "name": "id",
9 "type_info": "Varchar"
10 },
11 {
12 "ordinal": 1,
13 "name": "mac",
14 "type_info": "Macaddr"
15 },
16 {
17 "ordinal": 2,
18 "name": "broadcast_addr",
19 "type_info": "Varchar"
20 },
21 {
22 "ordinal": 3,
23 "name": "ip",
24 "type_info": "Inet"
25 },
26 {
27 "ordinal": 4,
28 "name": "times",
29 "type_info": "Int8Array"
30 }
31 ],
32 "parameters": {
33 "Left": [
34 "Macaddr",
35 "Varchar",
36 "Inet",
37 "Text"
38 ]
39 },
40 "nullable": [
41 false,
42 false,
43 false,
44 false,
45 true
46 ]
47 },
48 "hash": "e452c5ed8bdaec2011d78386cffd2b4739d88b3061931562e07c3e8dd24e6359"
49}
diff --git a/.sqlx/query-edc4ecf39512caec1076be1b2849b2530be7bcdcbe14362077b3fd47cd711c89.json b/.sqlx/query-edc4ecf39512caec1076be1b2849b2530be7bcdcbe14362077b3fd47cd711c89.json
deleted file mode 100644
index 2b17c9b..0000000
--- a/.sqlx/query-edc4ecf39512caec1076be1b2849b2530be7bcdcbe14362077b3fd47cd711c89.json
+++ /dev/null
@@ -1,17 +0,0 @@
1{
2 "db_name": "PostgreSQL",
3 "query": "\n INSERT INTO devices (id, mac, broadcast_addr, ip)\n VALUES ($1, $2, $3, $4);\n ",
4 "describe": {
5 "columns": [],
6 "parameters": {
7 "Left": [
8 "Varchar",
9 "Macaddr",
10 "Varchar",
11 "Inet"
12 ]
13 },
14 "nullable": []
15 },
16 "hash": "edc4ecf39512caec1076be1b2849b2530be7bcdcbe14362077b3fd47cd711c89"
17}
diff --git a/Cargo.lock b/Cargo.lock
index 0296951..5261edf 100644
--- a/Cargo.lock
+++ b/Cargo.lock
@@ -18,19 +18,6 @@ source = "registry+https://github.com/rust-lang/crates.io-index"
18checksum = "f26201604c87b1e01bd3d98f8d5d9a8fcbb815e8cedb41ffccbeb4bf593a35fe" 18checksum = "f26201604c87b1e01bd3d98f8d5d9a8fcbb815e8cedb41ffccbeb4bf593a35fe"
19 19
20[[package]] 20[[package]]
21name = "ahash"
22version = "0.8.11"
23source = "registry+https://github.com/rust-lang/crates.io-index"
24checksum = "e89da841a80418a9b391ebaea17f5c112ffaaa96f621d2c285b5174da76b9011"
25dependencies = [
26 "cfg-if",
27 "getrandom",
28 "once_cell",
29 "version_check",
30 "zerocopy",
31]
32
33[[package]]
34name = "aho-corasick" 21name = "aho-corasick"
35version = "1.1.3" 22version = "1.1.3"
36source = "registry+https://github.com/rust-lang/crates.io-index" 23source = "registry+https://github.com/rust-lang/crates.io-index"
@@ -40,12 +27,6 @@ dependencies = [
40] 27]
41 28
42[[package]] 29[[package]]
43name = "allocator-api2"
44version = "0.2.16"
45source = "registry+https://github.com/rust-lang/crates.io-index"
46checksum = "0942ffc6dcaadf03badf6e6a2d0228460359d5e34b57ccdc720b7382dfbd5ec5"
47
48[[package]]
49name = "async-trait" 30name = "async-trait"
50version = "0.1.79" 31version = "0.1.79"
51source = "registry+https://github.com/rust-lang/crates.io-index" 32source = "registry+https://github.com/rust-lang/crates.io-index"
@@ -57,15 +38,6 @@ dependencies = [
57] 38]
58 39
59[[package]] 40[[package]]
60name = "atoi"
61version = "2.0.0"
62source = "registry+https://github.com/rust-lang/crates.io-index"
63checksum = "f28d99ec8bfea296261ca1af174f24225171fea9664ba9003cbebee704810528"
64dependencies = [
65 "num-traits",
66]
67
68[[package]]
69name = "autocfg" 41name = "autocfg"
70version = "1.2.0" 42version = "1.2.0"
71source = "registry+https://github.com/rust-lang/crates.io-index" 43source = "registry+https://github.com/rust-lang/crates.io-index"
@@ -163,12 +135,6 @@ source = "registry+https://github.com/rust-lang/crates.io-index"
163checksum = "9d297deb1925b89f2ccc13d7635fa0714f12c87adce1c75356b39ca9b7178567" 135checksum = "9d297deb1925b89f2ccc13d7635fa0714f12c87adce1c75356b39ca9b7178567"
164 136
165[[package]] 137[[package]]
166name = "base64ct"
167version = "1.6.0"
168source = "registry+https://github.com/rust-lang/crates.io-index"
169checksum = "8c3c1a368f70d6cf7302d78f8f7093da241fb8e8807c05cc9e51a125895a6d5b"
170
171[[package]]
172name = "bitflags" 138name = "bitflags"
173version = "1.3.2" 139version = "1.3.2"
174source = "registry+https://github.com/rust-lang/crates.io-index" 140source = "registry+https://github.com/rust-lang/crates.io-index"
@@ -264,12 +230,6 @@ dependencies = [
264] 230]
265 231
266[[package]] 232[[package]]
267name = "const-oid"
268version = "0.9.6"
269source = "registry+https://github.com/rust-lang/crates.io-index"
270checksum = "c2459377285ad874054d797f3ccebf984978aa39129f6eafde5cdc8315b612f8"
271
272[[package]]
273name = "const-random" 233name = "const-random"
274version = "0.1.18" 234version = "0.1.18"
275source = "registry+https://github.com/rust-lang/crates.io-index" 235source = "registry+https://github.com/rust-lang/crates.io-index"
@@ -308,21 +268,6 @@ dependencies = [
308] 268]
309 269
310[[package]] 270[[package]]
311name = "crc"
312version = "3.2.1"
313source = "registry+https://github.com/rust-lang/crates.io-index"
314checksum = "69e6e4d7b33a94f0991c26729976b10ebde1d34c3ee82408fb536164fa10d636"
315dependencies = [
316 "crc-catalog",
317]
318
319[[package]]
320name = "crc-catalog"
321version = "2.4.0"
322source = "registry+https://github.com/rust-lang/crates.io-index"
323checksum = "19d374276b40fb8bbdee95aef7c7fa6b5316ec764510eb64b8dd0e2ed0d7e7f5"
324
325[[package]]
326name = "crc32fast" 271name = "crc32fast"
327version = "1.4.0" 272version = "1.4.0"
328source = "registry+https://github.com/rust-lang/crates.io-index" 273source = "registry+https://github.com/rust-lang/crates.io-index"
@@ -341,15 +286,6 @@ dependencies = [
341] 286]
342 287
343[[package]] 288[[package]]
344name = "crossbeam-queue"
345version = "0.3.11"
346source = "registry+https://github.com/rust-lang/crates.io-index"
347checksum = "df0346b5d5e76ac2fe4e327c5fd1118d6be7c51dfb18f9b7922923f287471e35"
348dependencies = [
349 "crossbeam-utils",
350]
351
352[[package]]
353name = "crossbeam-utils" 289name = "crossbeam-utils"
354version = "0.8.19" 290version = "0.8.19"
355source = "registry+https://github.com/rust-lang/crates.io-index" 291source = "registry+https://github.com/rust-lang/crates.io-index"
@@ -391,17 +327,6 @@ source = "registry+https://github.com/rust-lang/crates.io-index"
391checksum = "7e962a19be5cfc3f3bf6dd8f61eb50107f356ad6270fbb3ed41476571db78be5" 327checksum = "7e962a19be5cfc3f3bf6dd8f61eb50107f356ad6270fbb3ed41476571db78be5"
392 328
393[[package]] 329[[package]]
394name = "der"
395version = "0.7.9"
396source = "registry+https://github.com/rust-lang/crates.io-index"
397checksum = "f55bf8e7b65898637379c1b74eb1551107c8294ed26d855ceb9fd1a09cfc9bc0"
398dependencies = [
399 "const-oid",
400 "pem-rfc7468",
401 "zeroize",
402]
403
404[[package]]
405name = "deranged" 330name = "deranged"
406version = "0.3.11" 331version = "0.3.11"
407source = "registry+https://github.com/rust-lang/crates.io-index" 332source = "registry+https://github.com/rust-lang/crates.io-index"
@@ -417,9 +342,7 @@ source = "registry+https://github.com/rust-lang/crates.io-index"
417checksum = "9ed9a281f7bc9b7576e61468ba615a66a5c8cfdff42420a70aa82701a3b1e292" 342checksum = "9ed9a281f7bc9b7576e61468ba615a66a5c8cfdff42420a70aa82701a3b1e292"
418dependencies = [ 343dependencies = [
419 "block-buffer", 344 "block-buffer",
420 "const-oid",
421 "crypto-common", 345 "crypto-common",
422 "subtle",
423] 346]
424 347
425[[package]] 348[[package]]
@@ -432,54 +355,12 @@ dependencies = [
432] 355]
433 356
434[[package]] 357[[package]]
435name = "dotenvy"
436version = "0.15.7"
437source = "registry+https://github.com/rust-lang/crates.io-index"
438checksum = "1aaf95b3e5c8f23aa320147307562d361db0ae0d51242340f558153b4eb2439b"
439
440[[package]]
441name = "either"
442version = "1.10.0"
443source = "registry+https://github.com/rust-lang/crates.io-index"
444checksum = "11157ac094ffbdde99aa67b23417ebdd801842852b500e395a45a9c0aac03e4a"
445dependencies = [
446 "serde",
447]
448
449[[package]]
450name = "equivalent" 358name = "equivalent"
451version = "1.0.1" 359version = "1.0.1"
452source = "registry+https://github.com/rust-lang/crates.io-index" 360source = "registry+https://github.com/rust-lang/crates.io-index"
453checksum = "5443807d6dff69373d433ab9ef5378ad8df50ca6298caf15de6e52e24aaf54d5" 361checksum = "5443807d6dff69373d433ab9ef5378ad8df50ca6298caf15de6e52e24aaf54d5"
454 362
455[[package]] 363[[package]]
456name = "errno"
457version = "0.3.8"
458source = "registry+https://github.com/rust-lang/crates.io-index"
459checksum = "a258e46cdc063eb8519c00b9fc845fc47bcfca4130e2f08e88665ceda8474245"
460dependencies = [
461 "libc",
462 "windows-sys 0.52.0",
463]
464
465[[package]]
466name = "etcetera"
467version = "0.8.0"
468source = "registry+https://github.com/rust-lang/crates.io-index"
469checksum = "136d1b5283a1ab77bd9257427ffd09d8667ced0570b6f938942bc7568ed5b943"
470dependencies = [
471 "cfg-if",
472 "home",
473 "windows-sys 0.48.0",
474]
475
476[[package]]
477name = "event-listener"
478version = "2.5.3"
479source = "registry+https://github.com/rust-lang/crates.io-index"
480checksum = "0206175f82b8d6bf6652ff7d71a1e27fd2e4efde587fd368662814d6ec1d9ce0"
481
482[[package]]
483name = "eyre" 364name = "eyre"
484version = "0.6.12" 365version = "0.6.12"
485source = "registry+https://github.com/rust-lang/crates.io-index" 366source = "registry+https://github.com/rust-lang/crates.io-index"
@@ -490,18 +371,6 @@ dependencies = [
490] 371]
491 372
492[[package]] 373[[package]]
493name = "fastrand"
494version = "2.0.2"
495source = "registry+https://github.com/rust-lang/crates.io-index"
496checksum = "658bd65b1cf4c852a3cc96f18a8ce7b5640f6b703f905c7d74532294c2a63984"
497
498[[package]]
499name = "finl_unicode"
500version = "1.2.0"
501source = "registry+https://github.com/rust-lang/crates.io-index"
502checksum = "8fcfdc7a0362c9f4444381a9e697c79d435fe65b52a37466fc2c1184cee9edc6"
503
504[[package]]
505name = "flate2" 374name = "flate2"
506version = "1.0.28" 375version = "1.0.28"
507source = "registry+https://github.com/rust-lang/crates.io-index" 376source = "registry+https://github.com/rust-lang/crates.io-index"
@@ -512,17 +381,6 @@ dependencies = [
512] 381]
513 382
514[[package]] 383[[package]]
515name = "flume"
516version = "0.11.0"
517source = "registry+https://github.com/rust-lang/crates.io-index"
518checksum = "55ac459de2512911e4b674ce33cf20befaba382d05b62b008afc1c8b57cbf181"
519dependencies = [
520 "futures-core",
521 "futures-sink",
522 "spin 0.9.8",
523]
524
525[[package]]
526name = "fnv" 384name = "fnv"
527version = "1.0.7" 385version = "1.0.7"
528source = "registry+https://github.com/rust-lang/crates.io-index" 386source = "registry+https://github.com/rust-lang/crates.io-index"
@@ -544,7 +402,6 @@ source = "registry+https://github.com/rust-lang/crates.io-index"
544checksum = "eac8f7d7865dcb88bd4373ab671c8cf4508703796caa2b1985a9ca867b3fcb78" 402checksum = "eac8f7d7865dcb88bd4373ab671c8cf4508703796caa2b1985a9ca867b3fcb78"
545dependencies = [ 403dependencies = [
546 "futures-core", 404 "futures-core",
547 "futures-sink",
548] 405]
549 406
550[[package]] 407[[package]]
@@ -554,34 +411,6 @@ source = "registry+https://github.com/rust-lang/crates.io-index"
554checksum = "dfc6580bb841c5a68e9ef15c77ccc837b40a7504914d52e47b8b0e9bbda25a1d" 411checksum = "dfc6580bb841c5a68e9ef15c77ccc837b40a7504914d52e47b8b0e9bbda25a1d"
555 412
556[[package]] 413[[package]]
557name = "futures-executor"
558version = "0.3.30"
559source = "registry+https://github.com/rust-lang/crates.io-index"
560checksum = "a576fc72ae164fca6b9db127eaa9a9dda0d61316034f33a0a0d4eda41f02b01d"
561dependencies = [
562 "futures-core",
563 "futures-task",
564 "futures-util",
565]
566
567[[package]]
568name = "futures-intrusive"
569version = "0.5.0"
570source = "registry+https://github.com/rust-lang/crates.io-index"
571checksum = "1d930c203dd0b6ff06e0201a4a2fe9149b43c684fd4420555b26d21b1a02956f"
572dependencies = [
573 "futures-core",
574 "lock_api",
575 "parking_lot",
576]
577
578[[package]]
579name = "futures-io"
580version = "0.3.30"
581source = "registry+https://github.com/rust-lang/crates.io-index"
582checksum = "a44623e20b9681a318efdd71c299b6b222ed6f231972bfe2f224ebad6311f0c1"
583
584[[package]]
585name = "futures-sink" 414name = "futures-sink"
586version = "0.3.30" 415version = "0.3.30"
587source = "registry+https://github.com/rust-lang/crates.io-index" 416source = "registry+https://github.com/rust-lang/crates.io-index"
@@ -600,10 +429,8 @@ source = "registry+https://github.com/rust-lang/crates.io-index"
600checksum = "3d6401deb83407ab3da39eba7e33987a73c3df0c82b4bb5813ee871c19c41d48" 429checksum = "3d6401deb83407ab3da39eba7e33987a73c3df0c82b4bb5813ee871c19c41d48"
601dependencies = [ 430dependencies = [
602 "futures-core", 431 "futures-core",
603 "futures-io",
604 "futures-sink", 432 "futures-sink",
605 "futures-task", 433 "futures-task",
606 "memchr",
607 "pin-project-lite", 434 "pin-project-lite",
608 "pin-utils", 435 "pin-utils",
609 "slab", 436 "slab",
@@ -653,28 +480,12 @@ name = "hashbrown"
653version = "0.14.3" 480version = "0.14.3"
654source = "registry+https://github.com/rust-lang/crates.io-index" 481source = "registry+https://github.com/rust-lang/crates.io-index"
655checksum = "290f1a1d9242c78d09ce40a5e87e7554ee637af1351968159f4952f028f75604" 482checksum = "290f1a1d9242c78d09ce40a5e87e7554ee637af1351968159f4952f028f75604"
656dependencies = [
657 "ahash",
658 "allocator-api2",
659]
660
661[[package]]
662name = "hashlink"
663version = "0.8.4"
664source = "registry+https://github.com/rust-lang/crates.io-index"
665checksum = "e8094feaf31ff591f651a2664fb9cfd92bba7a60ce3197265e9482ebe753c8f7"
666dependencies = [
667 "hashbrown 0.14.3",
668]
669 483
670[[package]] 484[[package]]
671name = "heck" 485name = "heck"
672version = "0.4.1" 486version = "0.4.1"
673source = "registry+https://github.com/rust-lang/crates.io-index" 487source = "registry+https://github.com/rust-lang/crates.io-index"
674checksum = "95505c38b4572b2d910cecb0281560f54b440a19336cbbcb27bf6ce6adc6f5a8" 488checksum = "95505c38b4572b2d910cecb0281560f54b440a19336cbbcb27bf6ce6adc6f5a8"
675dependencies = [
676 "unicode-segmentation",
677]
678 489
679[[package]] 490[[package]]
680name = "hermit-abi" 491name = "hermit-abi"
@@ -689,33 +500,6 @@ source = "registry+https://github.com/rust-lang/crates.io-index"
689checksum = "7f24254aa9a54b5c858eaee2f5bccdb46aaf0e486a595ed5fd8f86ba55232a70" 500checksum = "7f24254aa9a54b5c858eaee2f5bccdb46aaf0e486a595ed5fd8f86ba55232a70"
690 501
691[[package]] 502[[package]]
692name = "hkdf"
693version = "0.12.4"
694source = "registry+https://github.com/rust-lang/crates.io-index"
695checksum = "7b5f8eb2ad728638ea2c7d47a21db23b7b58a72ed6a38256b8a1849f15fbbdf7"
696dependencies = [
697 "hmac",
698]
699
700[[package]]
701name = "hmac"
702version = "0.12.1"
703source = "registry+https://github.com/rust-lang/crates.io-index"
704checksum = "6c49c37c09c17a53d937dfbb742eb3a961d65a994e6bcdcf37e7399d0cc8ab5e"
705dependencies = [
706 "digest",
707]
708
709[[package]]
710name = "home"
711version = "0.5.9"
712source = "registry+https://github.com/rust-lang/crates.io-index"
713checksum = "e3d1354bf6b7235cb4a0576c2619fd4ed18183f689b12b006a0ee7329eeff9a5"
714dependencies = [
715 "windows-sys 0.52.0",
716]
717
718[[package]]
719name = "http" 503name = "http"
720version = "1.1.0" 504version = "1.1.0"
721source = "registry+https://github.com/rust-lang/crates.io-index" 505source = "registry+https://github.com/rust-lang/crates.io-index"
@@ -833,15 +617,6 @@ dependencies = [
833] 617]
834 618
835[[package]] 619[[package]]
836name = "itertools"
837version = "0.12.1"
838source = "registry+https://github.com/rust-lang/crates.io-index"
839checksum = "ba291022dbbd398a455acf126c1e341954079855bc60dfdda641363bd6922569"
840dependencies = [
841 "either",
842]
843
844[[package]]
845name = "itoa" 620name = "itoa"
846version = "1.0.11" 621version = "1.0.11"
847source = "registry+https://github.com/rust-lang/crates.io-index" 622source = "registry+https://github.com/rust-lang/crates.io-index"
@@ -863,9 +638,6 @@ name = "lazy_static"
863version = "1.4.0" 638version = "1.4.0"
864source = "registry+https://github.com/rust-lang/crates.io-index" 639source = "registry+https://github.com/rust-lang/crates.io-index"
865checksum = "e2abad23fbc42b3700f2f279844dc832adb2b2eb069b2df918f455c4e18cc646" 640checksum = "e2abad23fbc42b3700f2f279844dc832adb2b2eb069b2df918f455c4e18cc646"
866dependencies = [
867 "spin 0.5.2",
868]
869 641
870[[package]] 642[[package]]
871name = "libc" 643name = "libc"
@@ -874,35 +646,12 @@ source = "registry+https://github.com/rust-lang/crates.io-index"
874checksum = "9c198f91728a82281a64e1f4f9eeb25d82cb32a5de251c6bd1b5154d63a8e7bd" 646checksum = "9c198f91728a82281a64e1f4f9eeb25d82cb32a5de251c6bd1b5154d63a8e7bd"
875 647
876[[package]] 648[[package]]
877name = "libm"
878version = "0.2.8"
879source = "registry+https://github.com/rust-lang/crates.io-index"
880checksum = "4ec2a862134d2a7d32d7983ddcdd1c4923530833c9f2ea1a44fc5fa473989058"
881
882[[package]]
883name = "libsqlite3-sys"
884version = "0.27.0"
885source = "registry+https://github.com/rust-lang/crates.io-index"
886checksum = "cf4e226dcd58b4be396f7bd3c20da8fdee2911400705297ba7d2d7cc2c30f716"
887dependencies = [
888 "cc",
889 "pkg-config",
890 "vcpkg",
891]
892
893[[package]]
894name = "linked-hash-map" 649name = "linked-hash-map"
895version = "0.5.6" 650version = "0.5.6"
896source = "registry+https://github.com/rust-lang/crates.io-index" 651source = "registry+https://github.com/rust-lang/crates.io-index"
897checksum = "0717cef1bc8b636c6e1c1bbdefc09e6322da8a9321966e8928ef80d20f7f770f" 652checksum = "0717cef1bc8b636c6e1c1bbdefc09e6322da8a9321966e8928ef80d20f7f770f"
898 653
899[[package]] 654[[package]]
900name = "linux-raw-sys"
901version = "0.4.13"
902source = "registry+https://github.com/rust-lang/crates.io-index"
903checksum = "01cda141df6706de531b6c46c3a33ecca755538219bd484262fa09410c13539c"
904
905[[package]]
906name = "lock_api" 655name = "lock_api"
907version = "0.4.11" 656version = "0.4.11"
908source = "registry+https://github.com/rust-lang/crates.io-index" 657source = "registry+https://github.com/rust-lang/crates.io-index"
@@ -945,16 +694,6 @@ source = "registry+https://github.com/rust-lang/crates.io-index"
945checksum = "0e7465ac9959cc2b1404e8e2367b43684a6d13790fe23056cc8c6c5a6b7bcb94" 694checksum = "0e7465ac9959cc2b1404e8e2367b43684a6d13790fe23056cc8c6c5a6b7bcb94"
946 695
947[[package]] 696[[package]]
948name = "md-5"
949version = "0.10.6"
950source = "registry+https://github.com/rust-lang/crates.io-index"
951checksum = "d89e7ee0cfbedfc4da3340218492196241d89eefb6dab27de5df917a6d2e78cf"
952dependencies = [
953 "cfg-if",
954 "digest",
955]
956
957[[package]]
958name = "memchr" 697name = "memchr"
959version = "2.7.2" 698version = "2.7.2"
960source = "registry+https://github.com/rust-lang/crates.io-index" 699source = "registry+https://github.com/rust-lang/crates.io-index"
@@ -1051,59 +790,12 @@ dependencies = [
1051] 790]
1052 791
1053[[package]] 792[[package]]
1054name = "num-bigint-dig"
1055version = "0.8.4"
1056source = "registry+https://github.com/rust-lang/crates.io-index"
1057checksum = "dc84195820f291c7697304f3cbdadd1cb7199c0efc917ff5eafd71225c136151"
1058dependencies = [
1059 "byteorder",
1060 "lazy_static",
1061 "libm",
1062 "num-integer",
1063 "num-iter",
1064 "num-traits",
1065 "rand",
1066 "smallvec",
1067 "zeroize",
1068]
1069
1070[[package]]
1071name = "num-conv" 793name = "num-conv"
1072version = "0.1.0" 794version = "0.1.0"
1073source = "registry+https://github.com/rust-lang/crates.io-index" 795source = "registry+https://github.com/rust-lang/crates.io-index"
1074checksum = "51d515d32fb182ee37cda2ccdcb92950d6a3c2893aa280e540671c2cd0f3b1d9" 796checksum = "51d515d32fb182ee37cda2ccdcb92950d6a3c2893aa280e540671c2cd0f3b1d9"
1075 797
1076[[package]] 798[[package]]
1077name = "num-integer"
1078version = "0.1.46"
1079source = "registry+https://github.com/rust-lang/crates.io-index"
1080checksum = "7969661fd2958a5cb096e56c8e1ad0444ac2bbcd0061bd28660485a44879858f"
1081dependencies = [
1082 "num-traits",
1083]
1084
1085[[package]]
1086name = "num-iter"
1087version = "0.1.44"
1088source = "registry+https://github.com/rust-lang/crates.io-index"
1089checksum = "d869c01cc0c455284163fd0092f1f93835385ccab5a98a0dcc497b2f8bf055a9"
1090dependencies = [
1091 "autocfg",
1092 "num-integer",
1093 "num-traits",
1094]
1095
1096[[package]]
1097name = "num-traits"
1098version = "0.2.18"
1099source = "registry+https://github.com/rust-lang/crates.io-index"
1100checksum = "da0df0e5185db44f69b44f26786fe401b6c293d1907744beaa7fa62b2e5a517a"
1101dependencies = [
1102 "autocfg",
1103 "libm",
1104]
1105
1106[[package]]
1107name = "num_cpus" 799name = "num_cpus"
1108version = "1.16.0" 800version = "1.16.0"
1109source = "registry+https://github.com/rust-lang/crates.io-index" 801source = "registry+https://github.com/rust-lang/crates.io-index"
@@ -1183,27 +875,12 @@ dependencies = [
1183] 875]
1184 876
1185[[package]] 877[[package]]
1186name = "paste"
1187version = "1.0.14"
1188source = "registry+https://github.com/rust-lang/crates.io-index"
1189checksum = "de3145af08024dea9fa9914f381a17b8fc6034dfb00f3a84013f7ff43f29ed4c"
1190
1191[[package]]
1192name = "pathdiff" 878name = "pathdiff"
1193version = "0.2.1" 879version = "0.2.1"
1194source = "registry+https://github.com/rust-lang/crates.io-index" 880source = "registry+https://github.com/rust-lang/crates.io-index"
1195checksum = "8835116a5c179084a830efb3adc117ab007512b535bc1a21c991d3b32a6b44dd" 881checksum = "8835116a5c179084a830efb3adc117ab007512b535bc1a21c991d3b32a6b44dd"
1196 882
1197[[package]] 883[[package]]
1198name = "pem-rfc7468"
1199version = "0.7.0"
1200source = "registry+https://github.com/rust-lang/crates.io-index"
1201checksum = "88b39c9bfcfc231068454382784bb460aae594343fb030d46e9f50a645418412"
1202dependencies = [
1203 "base64ct",
1204]
1205
1206[[package]]
1207name = "percent-encoding" 884name = "percent-encoding"
1208version = "2.3.1" 885version = "2.3.1"
1209source = "registry+https://github.com/rust-lang/crates.io-index" 886source = "registry+https://github.com/rust-lang/crates.io-index"
@@ -1287,33 +964,6 @@ source = "registry+https://github.com/rust-lang/crates.io-index"
1287checksum = "8b870d8c151b6f2fb93e84a13146138f05d02ed11c7e7c54f8826aaaf7c9f184" 964checksum = "8b870d8c151b6f2fb93e84a13146138f05d02ed11c7e7c54f8826aaaf7c9f184"
1288 965
1289[[package]] 966[[package]]
1290name = "pkcs1"
1291version = "0.7.5"
1292source = "registry+https://github.com/rust-lang/crates.io-index"
1293checksum = "c8ffb9f10fa047879315e6625af03c164b16962a5368d724ed16323b68ace47f"
1294dependencies = [
1295 "der",
1296 "pkcs8",
1297 "spki",
1298]
1299
1300[[package]]
1301name = "pkcs8"
1302version = "0.10.2"
1303source = "registry+https://github.com/rust-lang/crates.io-index"
1304checksum = "f950b2377845cebe5cf8b5165cb3cc1a5e0fa5cfa3e1f7f55707d8fd82e0a7b7"
1305dependencies = [
1306 "der",
1307 "spki",
1308]
1309
1310[[package]]
1311name = "pkg-config"
1312version = "0.3.30"
1313source = "registry+https://github.com/rust-lang/crates.io-index"
1314checksum = "d231b230927b5e4ad203db57bbcbee2802f6bce620b1e4a9024a07d94e2907ec"
1315
1316[[package]]
1317name = "pnet_base" 967name = "pnet_base"
1318version = "0.34.0" 968version = "0.34.0"
1319source = "registry+https://github.com/rust-lang/crates.io-index" 969source = "registry+https://github.com/rust-lang/crates.io-index"
@@ -1505,26 +1155,6 @@ dependencies = [
1505] 1155]
1506 1156
1507[[package]] 1157[[package]]
1508name = "rsa"
1509version = "0.9.6"
1510source = "registry+https://github.com/rust-lang/crates.io-index"
1511checksum = "5d0e5124fcb30e76a7e79bfee683a2746db83784b86289f6251b54b7950a0dfc"
1512dependencies = [
1513 "const-oid",
1514 "digest",
1515 "num-bigint-dig",
1516 "num-integer",
1517 "num-traits",
1518 "pkcs1",
1519 "pkcs8",
1520 "rand_core",
1521 "signature",
1522 "spki",
1523 "subtle",
1524 "zeroize",
1525]
1526
1527[[package]]
1528name = "rust-embed" 1158name = "rust-embed"
1529version = "8.3.0" 1159version = "8.3.0"
1530source = "registry+https://github.com/rust-lang/crates.io-index" 1160source = "registry+https://github.com/rust-lang/crates.io-index"
@@ -1575,19 +1205,6 @@ source = "registry+https://github.com/rust-lang/crates.io-index"
1575checksum = "d626bb9dae77e28219937af045c257c28bfd3f69333c512553507f5f9798cb76" 1205checksum = "d626bb9dae77e28219937af045c257c28bfd3f69333c512553507f5f9798cb76"
1576 1206
1577[[package]] 1207[[package]]
1578name = "rustix"
1579version = "0.38.32"
1580source = "registry+https://github.com/rust-lang/crates.io-index"
1581checksum = "65e04861e65f21776e67888bfbea442b3642beaa0138fdb1dd7a84a52dffdb89"
1582dependencies = [
1583 "bitflags 2.5.0",
1584 "errno",
1585 "libc",
1586 "linux-raw-sys",
1587 "windows-sys 0.52.0",
1588]
1589
1590[[package]]
1591name = "rustversion" 1208name = "rustversion"
1592version = "1.0.15" 1209version = "1.0.15"
1593source = "registry+https://github.com/rust-lang/crates.io-index" 1210source = "registry+https://github.com/rust-lang/crates.io-index"
@@ -1708,16 +1325,6 @@ dependencies = [
1708] 1325]
1709 1326
1710[[package]] 1327[[package]]
1711name = "signature"
1712version = "2.2.0"
1713source = "registry+https://github.com/rust-lang/crates.io-index"
1714checksum = "77549399552de45a898a580c1b41d445bf730df867cc44e6c0233bbc4b8329de"
1715dependencies = [
1716 "digest",
1717 "rand_core",
1718]
1719
1720[[package]]
1721name = "slab" 1328name = "slab"
1722version = "0.4.9" 1329version = "0.4.9"
1723source = "registry+https://github.com/rust-lang/crates.io-index" 1330source = "registry+https://github.com/rust-lang/crates.io-index"
@@ -1743,257 +1350,6 @@ dependencies = [
1743] 1350]
1744 1351
1745[[package]] 1352[[package]]
1746name = "spin"
1747version = "0.5.2"
1748source = "registry+https://github.com/rust-lang/crates.io-index"
1749checksum = "6e63cff320ae2c57904679ba7cb63280a3dc4613885beafb148ee7bf9aa9042d"
1750
1751[[package]]
1752name = "spin"
1753version = "0.9.8"
1754source = "registry+https://github.com/rust-lang/crates.io-index"
1755checksum = "6980e8d7511241f8acf4aebddbb1ff938df5eebe98691418c4468d0b72a96a67"
1756dependencies = [
1757 "lock_api",
1758]
1759
1760[[package]]
1761name = "spki"
1762version = "0.7.3"
1763source = "registry+https://github.com/rust-lang/crates.io-index"
1764checksum = "d91ed6c858b01f942cd56b37a94b3e0a1798290327d1236e4d9cf4eaca44d29d"
1765dependencies = [
1766 "base64ct",
1767 "der",
1768]
1769
1770[[package]]
1771name = "sqlformat"
1772version = "0.2.3"
1773source = "registry+https://github.com/rust-lang/crates.io-index"
1774checksum = "ce81b7bd7c4493975347ef60d8c7e8b742d4694f4c49f93e0a12ea263938176c"
1775dependencies = [
1776 "itertools",
1777 "nom",
1778 "unicode_categories",
1779]
1780
1781[[package]]
1782name = "sqlx"
1783version = "0.7.4"
1784source = "registry+https://github.com/rust-lang/crates.io-index"
1785checksum = "c9a2ccff1a000a5a59cd33da541d9f2fdcd9e6e8229cc200565942bff36d0aaa"
1786dependencies = [
1787 "sqlx-core",
1788 "sqlx-macros",
1789 "sqlx-mysql",
1790 "sqlx-postgres",
1791 "sqlx-sqlite",
1792]
1793
1794[[package]]
1795name = "sqlx-core"
1796version = "0.7.4"
1797source = "registry+https://github.com/rust-lang/crates.io-index"
1798checksum = "24ba59a9342a3d9bab6c56c118be528b27c9b60e490080e9711a04dccac83ef6"
1799dependencies = [
1800 "ahash",
1801 "atoi",
1802 "byteorder",
1803 "bytes",
1804 "crc",
1805 "crossbeam-queue",
1806 "either",
1807 "event-listener",
1808 "futures-channel",
1809 "futures-core",
1810 "futures-intrusive",
1811 "futures-io",
1812 "futures-util",
1813 "hashlink",
1814 "hex",
1815 "indexmap",
1816 "ipnetwork",
1817 "log",
1818 "mac_address",
1819 "memchr",
1820 "once_cell",
1821 "paste",
1822 "percent-encoding",
1823 "serde",
1824 "serde_json",
1825 "sha2",
1826 "smallvec",
1827 "sqlformat",
1828 "thiserror",
1829 "tokio",
1830 "tokio-stream",
1831 "tracing",
1832 "url",
1833]
1834
1835[[package]]
1836name = "sqlx-macros"
1837version = "0.7.4"
1838source = "registry+https://github.com/rust-lang/crates.io-index"
1839checksum = "4ea40e2345eb2faa9e1e5e326db8c34711317d2b5e08d0d5741619048a803127"
1840dependencies = [
1841 "proc-macro2",
1842 "quote",
1843 "sqlx-core",
1844 "sqlx-macros-core",
1845 "syn 1.0.109",
1846]
1847
1848[[package]]
1849name = "sqlx-macros-core"
1850version = "0.7.4"
1851source = "registry+https://github.com/rust-lang/crates.io-index"
1852checksum = "5833ef53aaa16d860e92123292f1f6a3d53c34ba8b1969f152ef1a7bb803f3c8"
1853dependencies = [
1854 "dotenvy",
1855 "either",
1856 "heck",
1857 "hex",
1858 "once_cell",
1859 "proc-macro2",
1860 "quote",
1861 "serde",
1862 "serde_json",
1863 "sha2",
1864 "sqlx-core",
1865 "sqlx-mysql",
1866 "sqlx-postgres",
1867 "sqlx-sqlite",
1868 "syn 1.0.109",
1869 "tempfile",
1870 "tokio",
1871 "url",
1872]
1873
1874[[package]]
1875name = "sqlx-mysql"
1876version = "0.7.4"
1877source = "registry+https://github.com/rust-lang/crates.io-index"
1878checksum = "1ed31390216d20e538e447a7a9b959e06ed9fc51c37b514b46eb758016ecd418"
1879dependencies = [
1880 "atoi",
1881 "base64",
1882 "bitflags 2.5.0",
1883 "byteorder",
1884 "bytes",
1885 "crc",
1886 "digest",
1887 "dotenvy",
1888 "either",
1889 "futures-channel",
1890 "futures-core",
1891 "futures-io",
1892 "futures-util",
1893 "generic-array",
1894 "hex",
1895 "hkdf",
1896 "hmac",
1897 "itoa",
1898 "log",
1899 "md-5",
1900 "memchr",
1901 "once_cell",
1902 "percent-encoding",
1903 "rand",
1904 "rsa",
1905 "serde",
1906 "sha1",
1907 "sha2",
1908 "smallvec",
1909 "sqlx-core",
1910 "stringprep",
1911 "thiserror",
1912 "tracing",
1913 "whoami",
1914]
1915
1916[[package]]
1917name = "sqlx-postgres"
1918version = "0.7.4"
1919source = "registry+https://github.com/rust-lang/crates.io-index"
1920checksum = "7c824eb80b894f926f89a0b9da0c7f435d27cdd35b8c655b114e58223918577e"
1921dependencies = [
1922 "atoi",
1923 "base64",
1924 "bitflags 2.5.0",
1925 "byteorder",
1926 "crc",
1927 "dotenvy",
1928 "etcetera",
1929 "futures-channel",
1930 "futures-core",
1931 "futures-io",
1932 "futures-util",
1933 "hex",
1934 "hkdf",
1935 "hmac",
1936 "home",
1937 "ipnetwork",
1938 "itoa",
1939 "log",
1940 "mac_address",
1941 "md-5",
1942 "memchr",
1943 "once_cell",
1944 "rand",
1945 "serde",
1946 "serde_json",
1947 "sha2",
1948 "smallvec",
1949 "sqlx-core",
1950 "stringprep",
1951 "thiserror",
1952 "tracing",
1953 "whoami",
1954]
1955
1956[[package]]
1957name = "sqlx-sqlite"
1958version = "0.7.4"
1959source = "registry+https://github.com/rust-lang/crates.io-index"
1960checksum = "b244ef0a8414da0bed4bb1910426e890b19e5e9bccc27ada6b797d05c55ae0aa"
1961dependencies = [
1962 "atoi",
1963 "flume",
1964 "futures-channel",
1965 "futures-core",
1966 "futures-executor",
1967 "futures-intrusive",
1968 "futures-util",
1969 "libsqlite3-sys",
1970 "log",
1971 "percent-encoding",
1972 "serde",
1973 "sqlx-core",
1974 "tracing",
1975 "url",
1976 "urlencoding",
1977]
1978
1979[[package]]
1980name = "stringprep"
1981version = "0.1.4"
1982source = "registry+https://github.com/rust-lang/crates.io-index"
1983checksum = "bb41d74e231a107a1b4ee36bd1214b11285b77768d2e3824aedafa988fd36ee6"
1984dependencies = [
1985 "finl_unicode",
1986 "unicode-bidi",
1987 "unicode-normalization",
1988]
1989
1990[[package]]
1991name = "subtle"
1992version = "2.5.0"
1993source = "registry+https://github.com/rust-lang/crates.io-index"
1994checksum = "81cdd64d312baedb58e21336b31bc043b77e01cc99033ce76ef539f78e965ebc"
1995
1996[[package]]
1997name = "surge-ping" 1353name = "surge-ping"
1998version = "0.8.1" 1354version = "0.8.1"
1999source = "registry+https://github.com/rust-lang/crates.io-index" 1355source = "registry+https://github.com/rust-lang/crates.io-index"
@@ -2016,7 +1372,6 @@ source = "registry+https://github.com/rust-lang/crates.io-index"
2016checksum = "72b64191b275b66ffe2469e8af2c1cfe3bafa67b529ead792a6d0160888b4237" 1372checksum = "72b64191b275b66ffe2469e8af2c1cfe3bafa67b529ead792a6d0160888b4237"
2017dependencies = [ 1373dependencies = [
2018 "proc-macro2", 1374 "proc-macro2",
2019 "quote",
2020 "unicode-ident", 1375 "unicode-ident",
2021] 1376]
2022 1377
@@ -2044,18 +1399,6 @@ source = "registry+https://github.com/rust-lang/crates.io-index"
2044checksum = "a7065abeca94b6a8a577f9bd45aa0867a2238b74e8eb67cf10d492bc39351394" 1399checksum = "a7065abeca94b6a8a577f9bd45aa0867a2238b74e8eb67cf10d492bc39351394"
2045 1400
2046[[package]] 1401[[package]]
2047name = "tempfile"
2048version = "3.10.1"
2049source = "registry+https://github.com/rust-lang/crates.io-index"
2050checksum = "85b77fafb263dd9d05cbeac119526425676db3784113aa9295c88498cbf8bff1"
2051dependencies = [
2052 "cfg-if",
2053 "fastrand",
2054 "rustix",
2055 "windows-sys 0.52.0",
2056]
2057
2058[[package]]
2059name = "thiserror" 1402name = "thiserror"
2060version = "1.0.58" 1403version = "1.0.58"
2061source = "registry+https://github.com/rust-lang/crates.io-index" 1404source = "registry+https://github.com/rust-lang/crates.io-index"
@@ -2171,17 +1514,6 @@ dependencies = [
2171] 1514]
2172 1515
2173[[package]] 1516[[package]]
2174name = "tokio-stream"
2175version = "0.1.15"
2176source = "registry+https://github.com/rust-lang/crates.io-index"
2177checksum = "267ac89e0bec6e691e5813911606935d77c476ff49024f98abcea3e7b15e37af"
2178dependencies = [
2179 "futures-core",
2180 "pin-project-lite",
2181 "tokio",
2182]
2183
2184[[package]]
2185name = "tokio-tungstenite" 1517name = "tokio-tungstenite"
2186version = "0.21.0" 1518version = "0.21.0"
2187source = "registry+https://github.com/rust-lang/crates.io-index" 1519source = "registry+https://github.com/rust-lang/crates.io-index"
@@ -2408,12 +1740,6 @@ source = "registry+https://github.com/rust-lang/crates.io-index"
2408checksum = "d4c87d22b6e3f4a18d4d40ef354e97c90fcb14dd91d7dc0aa9d8a1172ebf7202" 1740checksum = "d4c87d22b6e3f4a18d4d40ef354e97c90fcb14dd91d7dc0aa9d8a1172ebf7202"
2409 1741
2410[[package]] 1742[[package]]
2411name = "unicode_categories"
2412version = "0.1.1"
2413source = "registry+https://github.com/rust-lang/crates.io-index"
2414checksum = "39ec24b3121d976906ece63c9daad25b85969647682eee313cb5779fdd69e14e"
2415
2416[[package]]
2417name = "url" 1743name = "url"
2418version = "2.5.0" 1744version = "2.5.0"
2419source = "registry+https://github.com/rust-lang/crates.io-index" 1745source = "registry+https://github.com/rust-lang/crates.io-index"
@@ -2425,12 +1751,6 @@ dependencies = [
2425] 1751]
2426 1752
2427[[package]] 1753[[package]]
2428name = "urlencoding"
2429version = "2.1.3"
2430source = "registry+https://github.com/rust-lang/crates.io-index"
2431checksum = "daf8dba3b7eb870caf1ddeed7bc9d2a049f3cfdfae7cb521b087cc33ae4c49da"
2432
2433[[package]]
2434name = "utf-8" 1754name = "utf-8"
2435version = "0.7.6" 1755version = "0.7.6"
2436source = "registry+https://github.com/rust-lang/crates.io-index" 1756source = "registry+https://github.com/rust-lang/crates.io-index"
@@ -2494,12 +1814,6 @@ source = "registry+https://github.com/rust-lang/crates.io-index"
2494checksum = "830b7e5d4d90034032940e4ace0d9a9a057e7a45cd94e6c007832e39edb82f6d" 1814checksum = "830b7e5d4d90034032940e4ace0d9a9a057e7a45cd94e6c007832e39edb82f6d"
2495 1815
2496[[package]] 1816[[package]]
2497name = "vcpkg"
2498version = "0.2.15"
2499source = "registry+https://github.com/rust-lang/crates.io-index"
2500checksum = "accd4ea62f7bb7a82fe23066fb0957d48ef677f6eeb8215f372f52e48bb32426"
2501
2502[[package]]
2503name = "version_check" 1817name = "version_check"
2504version = "0.9.4" 1818version = "0.9.4"
2505source = "registry+https://github.com/rust-lang/crates.io-index" 1819source = "registry+https://github.com/rust-lang/crates.io-index"
@@ -2522,14 +1836,8 @@ source = "registry+https://github.com/rust-lang/crates.io-index"
2522checksum = "9c8d87e72b64a3b4db28d11ce29237c246188f4f51057d65a7eab63b7987e423" 1836checksum = "9c8d87e72b64a3b4db28d11ce29237c246188f4f51057d65a7eab63b7987e423"
2523 1837
2524[[package]] 1838[[package]]
2525name = "wasite"
2526version = "0.1.0"
2527source = "registry+https://github.com/rust-lang/crates.io-index"
2528checksum = "b8dad83b4f25e74f184f64c43b150b91efe7647395b42289f38e50566d82855b"
2529
2530[[package]]
2531name = "webol" 1839name = "webol"
2532version = "0.3.4" 1840version = "0.4.0"
2533dependencies = [ 1841dependencies = [
2534 "axum", 1842 "axum",
2535 "axum-macros", 1843 "axum-macros",
@@ -2540,7 +1848,6 @@ dependencies = [
2540 "mac_address", 1848 "mac_address",
2541 "serde", 1849 "serde",
2542 "serde_json", 1850 "serde_json",
2543 "sqlx",
2544 "surge-ping", 1851 "surge-ping",
2545 "thiserror", 1852 "thiserror",
2546 "time", 1853 "time",
@@ -2554,16 +1861,6 @@ dependencies = [
2554] 1861]
2555 1862
2556[[package]] 1863[[package]]
2557name = "whoami"
2558version = "1.5.1"
2559source = "registry+https://github.com/rust-lang/crates.io-index"
2560checksum = "a44ab49fad634e88f55bf8f9bb3abd2f27d7204172a112c7c9987e01c1c94ea9"
2561dependencies = [
2562 "redox_syscall",
2563 "wasite",
2564]
2565
2566[[package]]
2567name = "winapi" 1864name = "winapi"
2568version = "0.3.9" 1865version = "0.3.9"
2569source = "registry+https://github.com/rust-lang/crates.io-index" 1866source = "registry+https://github.com/rust-lang/crates.io-index"
@@ -2745,32 +2042,6 @@ dependencies = [
2745] 2042]
2746 2043
2747[[package]] 2044[[package]]
2748name = "zerocopy"
2749version = "0.7.32"
2750source = "registry+https://github.com/rust-lang/crates.io-index"
2751checksum = "74d4d3961e53fa4c9a25a8637fc2bfaf2595b3d3ae34875568a5cf64787716be"
2752dependencies = [
2753 "zerocopy-derive",
2754]
2755
2756[[package]]
2757name = "zerocopy-derive"
2758version = "0.7.32"
2759source = "registry+https://github.com/rust-lang/crates.io-index"
2760checksum = "9ce1b18ccd8e73a9321186f97e46f9f04b778851177567b1975109d26a08d2a6"
2761dependencies = [
2762 "proc-macro2",
2763 "quote",
2764 "syn 2.0.58",
2765]
2766
2767[[package]]
2768name = "zeroize"
2769version = "1.7.0"
2770source = "registry+https://github.com/rust-lang/crates.io-index"
2771checksum = "525b4ec142c6b68a2d10f01f7bbf6755599ca3f81ea53b8431b7dd348f5fdb2d"
2772
2773[[package]]
2774name = "zip" 2045name = "zip"
2775version = "0.6.6" 2046version = "0.6.6"
2776source = "registry+https://github.com/rust-lang/crates.io-index" 2047source = "registry+https://github.com/rust-lang/crates.io-index"
diff --git a/Cargo.toml b/Cargo.toml
index d15bcd1..1b7db8e 100644
--- a/Cargo.toml
+++ b/Cargo.toml
@@ -1,6 +1,6 @@
1[package] 1[package]
2name = "webol" 2name = "webol"
3version = "0.3.4" 3version = "0.4.0"
4edition = "2021" 4edition = "2021"
5 5
6# See more keys and their definitions at https://doc.rust-lang.org/cargo/reference/manifest.html 6# See more keys and their definitions at https://doc.rust-lang.org/cargo/reference/manifest.html
@@ -14,7 +14,6 @@ time = { version = "0.3", features = ["macros"] }
14serde = { version = "1.0", features = ["derive"] } 14serde = { version = "1.0", features = ["derive"] }
15serde_json = "1.0" 15serde_json = "1.0"
16config = "0.14" 16config = "0.14"
17sqlx = { version = "0.7", features = ["postgres", "runtime-tokio", "ipnetwork", "mac_address"]}
18surge-ping = "0.8" 17surge-ping = "0.8"
19axum-macros = "0.4" 18axum-macros = "0.4"
20uuid = { version = "1.8", features = ["v4", "fast-rng"] } 19uuid = { version = "1.8", features = ["v4", "fast-rng"] }
diff --git a/Dockerfile b/Dockerfile
index 3336fe2..e5057e9 100644
--- a/Dockerfile
+++ b/Dockerfile
@@ -5,7 +5,7 @@ RUN cd /tmp && \
5 mkdir /dpkg && \ 5 mkdir /dpkg && \
6 for deb in *.deb; do dpkg --extract $deb /dpkg || exit 10; done 6 for deb in *.deb; do dpkg --extract $deb /dpkg || exit 10; done
7 7
8FROM rust:1.76 as builder 8FROM rust:1.77 as builder
9WORKDIR /app 9WORKDIR /app
10COPY . . 10COPY . .
11RUN cargo install --path . 11RUN cargo install --path .
diff --git a/README.md b/README.md
index eabc051..88f786a 100644
--- a/README.md
+++ b/README.md
@@ -1,9 +1,28 @@
1# webol 1# webol
2 2
3DATABASE_URL: `String` 3## Config
4Default `config.toml`:
5```toml
6serveraddr = "0.0.0.0:7229" # String
7pingtimeout = 10 # i64
8pingthreshold = 1 # i64
9timeoffset = 0 # i8
4 10
5WEBOL_APIKEY: `String` 11[auth]
12method = "none" # "none"|"key"
13secret = "" # String
14```
6 15
7WEBOL_SERVERADDR: `Option<String>` (0.0.0.0:7229) 16## Docker
8 17
9WEBOL_PINGTIMEOUT: `Option<i64>` (10) 18minimal `docker-compose.yaml`:
19```yaml
20services:
21 webol:
22 image: ghcr.io/fxqnlr/webol:0.4.0
23 container_name: webol
24 restart: unless-stopped
25 volumes:
26 - ./devices:/devices
27 network_mode: host
28```
diff --git a/build.rs b/build.rs
deleted file mode 100644
index 7609593..0000000
--- a/build.rs
+++ /dev/null
@@ -1,5 +0,0 @@
1// generated by `sqlx migrate build-script`
2fn main() {
3 // trigger recompilation when a new migration is added
4 println!("cargo:rerun-if-changed=migrations");
5} \ No newline at end of file
diff --git a/docker-compose.yml b/docker-compose.yml
deleted file mode 100644
index abac64e..0000000
--- a/docker-compose.yml
+++ /dev/null
@@ -1,13 +0,0 @@
1version: '3.1'
2
3services:
4 db:
5 image: postgres
6 container_name: webol_dev_postgres
7 restart: no
8 environment:
9 - POSTGRES_PASSWORD=postgres
10 - POSTGRES_DB=webol
11
12 ports:
13 - "5432:5432"
diff --git a/migrations/20231009123228_devices.sql b/migrations/20231009123228_devices.sql
deleted file mode 100644
index 6983ada..0000000
--- a/migrations/20231009123228_devices.sql
+++ /dev/null
@@ -1,9 +0,0 @@
1-- Add migration script here
2CREATE TABLE IF NOT EXISTS "devices"
3(
4 "id" VARCHAR(255) PRIMARY KEY NOT NULL,
5 "mac" MACADDR NOT NULL,
6 "broadcast_addr" VARCHAR(39) NOT NULL,
7 "ip" INET NOT NULL,
8 "times" BIGINT[]
9)
diff --git a/src/auth.rs b/src/auth.rs
index 74008b5..c662e36 100644
--- a/src/auth.rs
+++ b/src/auth.rs
@@ -6,6 +6,7 @@ use axum::{
6 response::Response, 6 response::Response,
7}; 7};
8use serde::Deserialize; 8use serde::Deserialize;
9use tracing::trace;
9 10
10#[derive(Debug, Clone, Deserialize)] 11#[derive(Debug, Clone, Deserialize)]
11pub enum Methods { 12pub enum Methods {
@@ -20,15 +21,19 @@ pub async fn auth(
20 next: Next, 21 next: Next,
21) -> Result<Response, StatusCode> { 22) -> Result<Response, StatusCode> {
22 let auth = state.config.auth; 23 let auth = state.config.auth;
24 trace!(?auth.method, "auth request");
23 match auth.method { 25 match auth.method {
24 Methods::Key => { 26 Methods::Key => {
25 if let Some(secret) = headers.get("authorization") { 27 if let Some(secret) = headers.get("authorization") {
26 if auth.secret.as_str() != secret { 28 if auth.secret.as_str() != secret {
29 trace!("auth failed, unknown secret");
27 return Err(StatusCode::UNAUTHORIZED); 30 return Err(StatusCode::UNAUTHORIZED);
28 }; 31 };
32 trace!("auth successfull");
29 let response = next.run(request).await; 33 let response = next.run(request).await;
30 Ok(response) 34 Ok(response)
31 } else { 35 } else {
36 trace!("auth failed, no secret");
32 Err(StatusCode::UNAUTHORIZED) 37 Err(StatusCode::UNAUTHORIZED)
33 } 38 }
34 } 39 }
diff --git a/src/config.rs b/src/config.rs
index 9636af4..bfb28be 100644
--- a/src/config.rs
+++ b/src/config.rs
@@ -5,7 +5,6 @@ use crate::auth;
5 5
6#[derive(Debug, Clone, Deserialize)] 6#[derive(Debug, Clone, Deserialize)]
7pub struct Config { 7pub struct Config {
8 pub database_url: String,
9 pub serveraddr: String, 8 pub serveraddr: String,
10 pub pingtimeout: i64, 9 pub pingtimeout: i64,
11 pub pingthreshold: i64, 10 pub pingthreshold: i64,
@@ -26,9 +25,11 @@ impl Config {
26 .set_default("pingtimeout", 10)? 25 .set_default("pingtimeout", 10)?
27 .set_default("pingthreshold", 1)? 26 .set_default("pingthreshold", 1)?
28 .set_default("timeoffset", 0)? 27 .set_default("timeoffset", 0)?
28 .set_default("auth.method", "none")?
29 .set_default("auth.secret", "")?
29 .add_source(File::with_name("config.toml").required(false)) 30 .add_source(File::with_name("config.toml").required(false))
30 .add_source(File::with_name("config.dev.toml").required(false)) 31 .add_source(File::with_name("config.dev.toml").required(false))
31 .add_source(config::Environment::with_prefix("WEBOL").prefix_separator("_")) 32 .add_source(config::Environment::with_prefix("WEBOL").separator("_"))
32 .build()?; 33 .build()?;
33 34
34 config.try_deserialize() 35 config.try_deserialize()
diff --git a/src/db.rs b/src/db.rs
deleted file mode 100644
index a2b2009..0000000
--- a/src/db.rs
+++ /dev/null
@@ -1,37 +0,0 @@
1use serde::Serialize;
2use sqlx::{PgPool, postgres::PgPoolOptions, types::{ipnetwork::IpNetwork, mac_address::MacAddress}};
3use tracing::{debug, info};
4use utoipa::ToSchema;
5
6#[derive(Serialize, Debug)]
7pub struct Device {
8 pub id: String,
9 pub mac: MacAddress,
10 pub broadcast_addr: String,
11 pub ip: IpNetwork,
12 pub times: Option<Vec<i64>>
13}
14
15#[derive(ToSchema)]
16#[schema(as = Device)]
17pub struct DeviceSchema {
18 pub id: String,
19 pub mac: String,
20 pub broadcast_addr: String,
21 pub ip: String,
22 pub times: Option<Vec<i64>>
23}
24
25pub async fn init_db_pool(db_url: &str) -> PgPool {
26 debug!("attempt to connect dbPool to '{}'", db_url);
27
28 let pool = PgPoolOptions::new()
29 .max_connections(5)
30 .connect(db_url)
31 .await
32 .unwrap();
33
34 info!("dbPool successfully connected to '{}'", db_url);
35
36 pool
37}
diff --git a/src/error.rs b/src/error.rs
index 006fcdb..2d70592 100644
--- a/src/error.rs
+++ b/src/error.rs
@@ -7,14 +7,14 @@ use mac_address::MacParseError;
7use serde_json::json; 7use serde_json::json;
8use utoipa::ToSchema; 8use utoipa::ToSchema;
9use std::io; 9use std::io;
10use tracing::error; 10use tracing::{error, warn};
11 11
12#[derive(Debug, thiserror::Error, ToSchema)] 12#[derive(Debug, thiserror::Error, ToSchema)]
13pub enum Error { 13pub enum Error {
14 #[error("db: {source}")] 14 #[error("json: {source}")]
15 Db { 15 Json {
16 #[from] 16 #[from]
17 source: sqlx::Error, 17 source: serde_json::Error,
18 }, 18 },
19 19
20 #[error("buffer parse: {source}")] 20 #[error("buffer parse: {source}")]
@@ -50,15 +50,20 @@ pub enum Error {
50 50
51impl IntoResponse for Error { 51impl IntoResponse for Error {
52 fn into_response(self) -> Response { 52 fn into_response(self) -> Response {
53 error!("{}", self.to_string()); 53 // error!("{}", self.to_string());
54 let (status, error_message) = match self { 54 let (status, error_message) = match self {
55 Self::Db { source } => { 55 Self::Json { source } => {
56 error!("{source}"); 56 error!("{source}");
57 (StatusCode::INTERNAL_SERVER_ERROR, "Server Error") 57 (StatusCode::INTERNAL_SERVER_ERROR, "Server Error")
58 } 58 }
59 Self::Io { source } => { 59 Self::Io { source } => {
60 error!("{source}"); 60 if source.kind() == io::ErrorKind::NotFound {
61 (StatusCode::INTERNAL_SERVER_ERROR, "Server Error") 61 warn!("unknown device requested");
62 (StatusCode::NOT_FOUND, "Requested device not found")
63 } else {
64 error!("{source}");
65 (StatusCode::INTERNAL_SERVER_ERROR, "Server Error")
66 }
62 } 67 }
63 Self::ParseHeader { source } => { 68 Self::ParseHeader { source } => {
64 error!("{source}"); 69 error!("{source}");
diff --git a/src/main.rs b/src/main.rs
index 70c67cf..204c318 100644
--- a/src/main.rs
+++ b/src/main.rs
@@ -1,8 +1,5 @@
1use crate::{ 1use crate::{
2 config::Config, 2 config::Config, routes::{device, start, status}, services::ping::{BroadcastCommand, StatusMap}, storage::Device
3 db::init_db_pool,
4 routes::{device, start, status},
5 services::ping::{BroadcastCommand, StatusMap},
6}; 3};
7use axum::{ 4use axum::{
8 middleware::from_fn_with_state, 5 middleware::from_fn_with_state,
@@ -10,11 +7,10 @@ use axum::{
10 Router, 7 Router,
11}; 8};
12use dashmap::DashMap; 9use dashmap::DashMap;
13use sqlx::PgPool;
14use std::{env, sync::Arc}; 10use std::{env, sync::Arc};
15use time::UtcOffset; 11use time::UtcOffset;
16use tokio::sync::broadcast::{channel, Sender}; 12use tokio::sync::broadcast::{channel, Sender};
17use tracing::{info, level_filters::LevelFilter}; 13use tracing::{info, level_filters::LevelFilter, trace};
18use tracing_subscriber::{ 14use tracing_subscriber::{
19 fmt::{self, time::OffsetTime}, 15 fmt::{self, time::OffsetTime},
20 prelude::*, 16 prelude::*,
@@ -26,10 +22,10 @@ use utoipa::{
26}; 22};
27use utoipa_swagger_ui::SwaggerUi; 23use utoipa_swagger_ui::SwaggerUi;
28 24
25mod auth;
29mod config; 26mod config;
30mod db; 27mod storage;
31mod error; 28mod error;
32mod auth;
33mod routes; 29mod routes;
34mod services; 30mod services;
35mod wol; 31mod wol;
@@ -39,20 +35,16 @@ mod wol;
39 paths( 35 paths(
40 start::post, 36 start::post,
41 start::get, 37 start::get,
42 start::start_payload,
43 device::get, 38 device::get,
44 device::get_payload,
45 device::post, 39 device::post,
46 device::put, 40 device::put,
47 ), 41 ),
48 components( 42 components(
49 schemas( 43 schemas(
50 start::PayloadOld, 44 start::SPayload,
51 start::Payload,
52 start::Response, 45 start::Response,
53 device::DevicePayload, 46 device::DPayload,
54 device::GetDevicePayload, 47 storage::DeviceSchema,
55 db::DeviceSchema,
56 ) 48 )
57 ), 49 ),
58 modifiers(&SecurityAddon), 50 modifiers(&SecurityAddon),
@@ -76,7 +68,6 @@ impl Modify for SecurityAddon {
76} 68}
77 69
78#[tokio::main] 70#[tokio::main]
79#[allow(deprecated)]
80async fn main() -> color_eyre::eyre::Result<()> { 71async fn main() -> color_eyre::eyre::Result<()> {
81 color_eyre::install()?; 72 color_eyre::install()?;
82 73
@@ -98,35 +89,28 @@ async fn main() -> color_eyre::eyre::Result<()> {
98 .from_env_lossy(), 89 .from_env_lossy(),
99 ) 90 )
100 .init(); 91 .init();
92 trace!("logging initialized");
101 93
102 let version = env!("CARGO_PKG_VERSION"); 94 Device::setup()?;
103
104 info!("start webol v{}", version);
105 95
106 let db = init_db_pool(&config.database_url).await; 96 let version = env!("CARGO_PKG_VERSION");
107 sqlx::migrate!().run(&db).await.unwrap(); 97 info!(?version, "start webol");
108 98
109 let (tx, _) = channel(32); 99 let (tx, _) = channel(32);
110 100
111 let ping_map: StatusMap = DashMap::new(); 101 let ping_map: StatusMap = DashMap::new();
112 102
113 let shared_state = AppState { 103 let shared_state = AppState {
114 db,
115 config: config.clone(), 104 config: config.clone(),
116 ping_send: tx, 105 ping_send: tx,
117 ping_map, 106 ping_map,
118 }; 107 };
119 108
120 let app = Router::new() 109 let app = Router::new()
121 .route("/start", post(start::start_payload))
122 .route("/start/:id", post(start::post).get(start::get)) 110 .route("/start/:id", post(start::post).get(start::get))
123 .route( 111 .route("/device", post(device::post).put(device::put))
124 "/device",
125 post(device::post).get(device::get_payload).put(device::put),
126 )
127 .route("/device/:id", get(device::get)) 112 .route("/device/:id", get(device::get))
128 .route("/status", get(status::status)) 113 .route("/status", get(status::status))
129 // TODO: Don't load on `None` Auth
130 .route_layer(from_fn_with_state(shared_state.clone(), auth::auth)) 114 .route_layer(from_fn_with_state(shared_state.clone(), auth::auth))
131 .merge(SwaggerUi::new("/swagger-ui").url("/api-docs/openapi.json", ApiDoc::openapi())) 115 .merge(SwaggerUi::new("/swagger-ui").url("/api-docs/openapi.json", ApiDoc::openapi()))
132 .with_state(Arc::new(shared_state)); 116 .with_state(Arc::new(shared_state));
@@ -141,7 +125,6 @@ async fn main() -> color_eyre::eyre::Result<()> {
141 125
142#[derive(Clone)] 126#[derive(Clone)]
143pub struct AppState { 127pub struct AppState {
144 db: PgPool,
145 config: Config, 128 config: Config,
146 ping_send: Sender<BroadcastCommand>, 129 ping_send: Sender<BroadcastCommand>,
147 ping_map: StatusMap, 130 ping_map: StatusMap,
diff --git a/src/routes/device.rs b/src/routes/device.rs
index 40b5cd8..49361f2 100644
--- a/src/routes/device.rs
+++ b/src/routes/device.rs
@@ -1,49 +1,17 @@
1use crate::db::Device;
2use crate::error::Error; 1use crate::error::Error;
3use axum::extract::{Path, State}; 2use crate::storage::Device;
3use axum::extract::Path;
4use axum::Json; 4use axum::Json;
5use ipnetwork::IpNetwork;
5use mac_address::MacAddress; 6use mac_address::MacAddress;
6use serde::Deserialize; 7use serde::Deserialize;
7use serde_json::{json, Value}; 8use serde_json::{json, Value};
8use sqlx::types::ipnetwork::IpNetwork; 9use std::str::FromStr;
9use std::{str::FromStr, sync::Arc};
10use tracing::{debug, info}; 10use tracing::{debug, info};
11use utoipa::ToSchema; 11use utoipa::ToSchema;
12 12
13#[utoipa::path( 13#[utoipa::path(
14 get, 14 get,
15 path = "/device",
16 request_body = GetDevicePayload,
17 responses(
18 (status = 200, description = "Get `Device` information", body = [Device])
19 ),
20 security(("api_key" = []))
21)]
22#[deprecated]
23pub async fn get_payload(
24 State(state): State<Arc<crate::AppState>>,
25 Json(payload): Json<GetDevicePayload>,
26) -> Result<Json<Value>, Error> {
27 info!("get device {}", payload.id);
28 let device = sqlx::query_as!(
29 Device,
30 r#"
31 SELECT id, mac, broadcast_addr, ip, times
32 FROM devices
33 WHERE id = $1;
34 "#,
35 payload.id
36 )
37 .fetch_one(&state.db)
38 .await?;
39
40 debug!("got device {:?}", device);
41
42 Ok(Json(json!(device)))
43}
44
45#[utoipa::path(
46 get,
47 path = "/device/{id}", 15 path = "/device/{id}",
48 responses( 16 responses(
49 (status = 200, description = "Get `Device` information", body = [Device]) 17 (status = 200, description = "Get `Device` information", body = [Device])
@@ -53,22 +21,10 @@ pub async fn get_payload(
53 ), 21 ),
54 security((), ("api_key" = [])) 22 security((), ("api_key" = []))
55)] 23)]
56pub async fn get( 24pub async fn get(Path(id): Path<String>) -> Result<Json<Value>, Error> {
57 State(state): State<Arc<crate::AppState>>, 25 info!("get device from path {}", id);
58 Path(path): Path<String>, 26
59) -> Result<Json<Value>, Error> { 27 let device = Device::read(&id)?;
60 info!("get device from path {}", path);
61 let device = sqlx::query_as!(
62 Device,
63 r#"
64 SELECT id, mac, broadcast_addr, ip, times
65 FROM devices
66 WHERE id = $1;
67 "#,
68 path
69 )
70 .fetch_one(&state.db)
71 .await?;
72 28
73 debug!("got device {:?}", device); 29 debug!("got device {:?}", device);
74 30
@@ -76,13 +32,7 @@ pub async fn get(
76} 32}
77 33
78#[derive(Deserialize, ToSchema)] 34#[derive(Deserialize, ToSchema)]
79#[deprecated] 35pub struct DPayload {
80pub struct GetDevicePayload {
81 id: String,
82}
83
84#[derive(Deserialize, ToSchema)]
85pub struct DevicePayload {
86 id: String, 36 id: String,
87 mac: String, 37 mac: String,
88 broadcast_addr: String, 38 broadcast_addr: String,
@@ -92,15 +42,14 @@ pub struct DevicePayload {
92#[utoipa::path( 42#[utoipa::path(
93 put, 43 put,
94 path = "/device", 44 path = "/device",
95 request_body = DevicePayload, 45 request_body = DPayload,
96 responses( 46 responses(
97 (status = 200, description = "add device to storage", body = [DeviceSchema]) 47 (status = 200, description = "add device to storage", body = [DeviceSchema])
98 ), 48 ),
99 security((), ("api_key" = [])) 49 security((), ("api_key" = []))
100)] 50)]
101pub async fn put( 51pub async fn put(
102 State(state): State<Arc<crate::AppState>>, 52 Json(payload): Json<DPayload>,
103 Json(payload): Json<DevicePayload>,
104) -> Result<Json<Value>, Error> { 53) -> Result<Json<Value>, Error> {
105 info!( 54 info!(
106 "add device {} ({}, {}, {})", 55 "add device {} ({}, {}, {})",
@@ -109,20 +58,14 @@ pub async fn put(
109 58
110 let ip = IpNetwork::from_str(&payload.ip)?; 59 let ip = IpNetwork::from_str(&payload.ip)?;
111 let mac = MacAddress::from_str(&payload.mac)?; 60 let mac = MacAddress::from_str(&payload.mac)?;
112 let device = sqlx::query_as!( 61 let device = Device {
113 Device, 62 id: payload.id,
114 r#"
115 INSERT INTO devices (id, mac, broadcast_addr, ip)
116 VALUES ($1, $2, $3, $4)
117 RETURNING id, mac, broadcast_addr, ip, times;
118 "#,
119 payload.id,
120 mac, 63 mac,
121 payload.broadcast_addr, 64 broadcast_addr: payload.broadcast_addr,
122 ip 65 ip,
123 ) 66 times: None,
124 .fetch_one(&state.db) 67 };
125 .await?; 68 device.write()?;
126 69
127 Ok(Json(json!(device))) 70 Ok(Json(json!(device)))
128} 71}
@@ -130,15 +73,14 @@ pub async fn put(
130#[utoipa::path( 73#[utoipa::path(
131 post, 74 post,
132 path = "/device", 75 path = "/device",
133 request_body = DevicePayload, 76 request_body = DPayload,
134 responses( 77 responses(
135 (status = 200, description = "update device in storage", body = [DeviceSchema]) 78 (status = 200, description = "update device in storage", body = [DeviceSchema])
136 ), 79 ),
137 security((), ("api_key" = [])) 80 security((), ("api_key" = []))
138)] 81)]
139pub async fn post( 82pub async fn post(
140 State(state): State<Arc<crate::AppState>>, 83 Json(payload): Json<DPayload>,
141 Json(payload): Json<DevicePayload>,
142) -> Result<Json<Value>, Error> { 84) -> Result<Json<Value>, Error> {
143 info!( 85 info!(
144 "edit device {} ({}, {}, {})", 86 "edit device {} ({}, {}, {})",
@@ -146,20 +88,16 @@ pub async fn post(
146 ); 88 );
147 let ip = IpNetwork::from_str(&payload.ip)?; 89 let ip = IpNetwork::from_str(&payload.ip)?;
148 let mac = MacAddress::from_str(&payload.mac)?; 90 let mac = MacAddress::from_str(&payload.mac)?;
149 let device = sqlx::query_as!( 91 let times = Device::read(&payload.id)?.times;
150 Device, 92
151 r#" 93 let device = Device {
152 UPDATE devices 94 id: payload.id,
153 SET mac = $1, broadcast_addr = $2, ip = $3 WHERE id = $4
154 RETURNING id, mac, broadcast_addr, ip, times;
155 "#,
156 mac, 95 mac,
157 payload.broadcast_addr, 96 broadcast_addr: payload.broadcast_addr,
158 ip, 97 ip,
159 payload.id 98 times,
160 ) 99 };
161 .fetch_one(&state.db) 100 device.write()?;
162 .await?;
163 101
164 Ok(Json(json!(device))) 102 Ok(Json(json!(device)))
165} 103}
diff --git a/src/routes/start.rs b/src/routes/start.rs
index ff3d1be..ae2b384 100644
--- a/src/routes/start.rs
+++ b/src/routes/start.rs
@@ -1,7 +1,7 @@
1use crate::db::Device; 1use crate::storage::Device;
2use crate::error::Error; 2use crate::error::Error;
3use crate::services::ping::Value as PingValue; 3use crate::services::ping::Value as PingValue;
4use crate::wol::{create_buffer, send_packet}; 4use crate::wol::send_packet;
5use axum::extract::{Path, State}; 5use axum::extract::{Path, State};
6use axum::Json; 6use axum::Json;
7use serde::{Deserialize, Serialize}; 7use serde::{Deserialize, Serialize};
@@ -13,57 +13,8 @@ use uuid::Uuid;
13 13
14#[utoipa::path( 14#[utoipa::path(
15 post, 15 post,
16 path = "/start",
17 request_body = PayloadOld,
18 responses(
19 (status = 200, description = "DEP", body = [Response])
20 ),
21 security((), ("api_key" = []))
22)]
23#[deprecated]
24pub async fn start_payload(
25 State(state): State<Arc<crate::AppState>>,
26 Json(payload): Json<PayloadOld>,
27) -> Result<Json<Value>, Error> {
28 info!("POST request");
29 let device = sqlx::query_as!(
30 Device,
31 r#"
32 SELECT id, mac, broadcast_addr, ip, times
33 FROM devices
34 WHERE id = $1;
35 "#,
36 payload.id
37 )
38 .fetch_one(&state.db)
39 .await?;
40
41 info!("starting {}", device.id);
42
43 let bind_addr = "0.0.0.0:0";
44
45 let _ = send_packet(
46 bind_addr,
47 &device.broadcast_addr,
48 &create_buffer(&device.mac.to_string())?,
49 )?;
50 let dev_id = device.id.clone();
51 let uuid = if payload.ping.is_some_and(|ping| ping) {
52 Some(setup_ping(state, device))
53 } else {
54 None
55 };
56 Ok(Json(json!(Response {
57 id: dev_id,
58 boot: true,
59 uuid
60 })))
61}
62
63#[utoipa::path(
64 post,
65 path = "/start/{id}", 16 path = "/start/{id}",
66 request_body = Option<Payload>, 17 request_body = Option<SPayload>,
67 responses( 18 responses(
68 (status = 200, description = "start the device with the given id", body = [Response]) 19 (status = 200, description = "start the device with the given id", body = [Response])
69 ), 20 ),
@@ -75,9 +26,9 @@ pub async fn start_payload(
75pub async fn post( 26pub async fn post(
76 State(state): State<Arc<crate::AppState>>, 27 State(state): State<Arc<crate::AppState>>,
77 Path(id): Path<String>, 28 Path(id): Path<String>,
78 payload: Option<Json<Payload>>, 29 payload: Option<Json<SPayload>>,
79) -> Result<Json<Value>, Error> { 30) -> Result<Json<Value>, Error> {
80 send_wol(state, &id, payload).await 31 send_wol(state, &id, payload)
81} 32}
82 33
83#[utoipa::path( 34#[utoipa::path(
@@ -95,26 +46,16 @@ pub async fn get(
95 State(state): State<Arc<crate::AppState>>, 46 State(state): State<Arc<crate::AppState>>,
96 Path(id): Path<String>, 47 Path(id): Path<String>,
97) -> Result<Json<Value>, Error> { 48) -> Result<Json<Value>, Error> {
98 send_wol(state, &id, None).await 49 send_wol(state, &id, None)
99} 50}
100 51
101async fn send_wol( 52fn send_wol(
102 state: Arc<crate::AppState>, 53 state: Arc<crate::AppState>,
103 id: &str, 54 id: &str,
104 payload: Option<Json<Payload>>, 55 payload: Option<Json<SPayload>>,
105) -> Result<Json<Value>, Error> { 56) -> Result<Json<Value>, Error> {
106 info!("Start request for {id}"); 57 info!("start request for {id}");
107 let device = sqlx::query_as!( 58 let device = Device::read(id)?;
108 Device,
109 r#"
110 SELECT id, mac, broadcast_addr, ip, times
111 FROM devices
112 WHERE id = $1;
113 "#,
114 id
115 )
116 .fetch_one(&state.db)
117 .await?;
118 59
119 info!("starting {}", device.id); 60 info!("starting {}", device.id);
120 61
@@ -122,8 +63,8 @@ async fn send_wol(
122 63
123 let _ = send_packet( 64 let _ = send_packet(
124 bind_addr, 65 bind_addr,
125 &device.broadcast_addr, 66 &device.broadcast_addr.to_string(),
126 &create_buffer(&device.mac.to_string())?, 67 &device.mac.bytes()
127 )?; 68 )?;
128 let dev_id = device.id.clone(); 69 let dev_id = device.id.clone();
129 let uuid = if let Some(pl) = payload { 70 let uuid = if let Some(pl) = payload {
@@ -163,6 +104,7 @@ fn setup_ping(state: Arc<crate::AppState>, device: Device) -> String {
163 uuid_gen.clone(), 104 uuid_gen.clone(),
164 PingValue { 105 PingValue {
165 ip: device.ip, 106 ip: device.ip,
107 eta: get_eta(device.clone().times),
166 online: false, 108 online: false,
167 }, 109 },
168 ); 110 );
@@ -174,7 +116,6 @@ fn setup_ping(state: Arc<crate::AppState>, device: Device) -> String {
174 device, 116 device,
175 uuid_gen, 117 uuid_gen,
176 &state.ping_map, 118 &state.ping_map,
177 &state.db,
178 ) 119 )
179 .await; 120 .await;
180 }); 121 });
@@ -182,15 +123,18 @@ fn setup_ping(state: Arc<crate::AppState>, device: Device) -> String {
182 uuid_ret 123 uuid_ret
183} 124}
184 125
185#[derive(Deserialize, ToSchema)] 126fn get_eta(times: Option<Vec<i64>>) -> i64 {
186#[deprecated] 127 let times = if let Some(times) = times {
187pub struct PayloadOld { 128 times
188 id: String, 129 } else {
189 ping: Option<bool>, 130 vec![0]
131 };
132
133 times.iter().sum::<i64>() / i64::try_from(times.len()).unwrap()
190} 134}
191 135
192#[derive(Deserialize, ToSchema)] 136#[derive(Deserialize, ToSchema)]
193pub struct Payload { 137pub struct SPayload {
194 ping: Option<bool>, 138 ping: Option<bool>,
195} 139}
196 140
diff --git a/src/routes/status.rs b/src/routes/status.rs
index 0e25f7d..b38202b 100644
--- a/src/routes/status.rs
+++ b/src/routes/status.rs
@@ -3,7 +3,6 @@ use crate::AppState;
3use axum::extract::ws::{Message, WebSocket}; 3use axum::extract::ws::{Message, WebSocket};
4use axum::extract::{State, WebSocketUpgrade}; 4use axum::extract::{State, WebSocketUpgrade};
5use axum::response::Response; 5use axum::response::Response;
6use sqlx::PgPool;
7use std::sync::Arc; 6use std::sync::Arc;
8use tracing::{debug, trace}; 7use tracing::{debug, trace};
9 8
@@ -18,13 +17,13 @@ pub async fn websocket(mut socket: WebSocket, state: Arc<AppState>) {
18 17
19 trace!("Search for uuid: {}", uuid); 18 trace!("Search for uuid: {}", uuid);
20 19
21 let eta = get_eta(&state.db).await;
22 let _ = socket
23 .send(Message::Text(format!("eta_{eta}_{uuid}")))
24 .await;
25 20
26 let device_exists = state.ping_map.contains_key(&uuid); 21 let device_exists = state.ping_map.contains_key(&uuid);
27 if device_exists { 22 if device_exists {
23 let eta = state.ping_map.get(&uuid).unwrap().eta;
24 let _ = socket
25 .send(Message::Text(format!("eta_{eta}_{uuid}")))
26 .await;
28 let _ = socket 27 let _ = socket
29 .send(receive_ping_broadcast(state.clone(), uuid).await) 28 .send(receive_ping_broadcast(state.clone(), uuid).await)
30 .await; 29 .await;
@@ -62,18 +61,3 @@ async fn receive_ping_broadcast(state: Arc<AppState>, uuid: String) -> Message {
62 } 61 }
63 } 62 }
64} 63}
65
66async fn get_eta(db: &PgPool) -> i64 {
67 let query = sqlx::query!(r#"SELECT times FROM devices;"#)
68 .fetch_one(db)
69 .await
70 .unwrap();
71
72 let times = if let Some(times) = query.times {
73 times
74 } else {
75 vec![0]
76 };
77
78 times.iter().sum::<i64>() / i64::try_from(times.len()).unwrap()
79}
diff --git a/src/services/ping.rs b/src/services/ping.rs
index 8cf6072..1bf022d 100644
--- a/src/services/ping.rs
+++ b/src/services/ping.rs
@@ -1,8 +1,7 @@
1use crate::config::Config; 1use crate::config::Config;
2use crate::db::Device; 2use crate::storage::Device;
3use dashmap::DashMap; 3use dashmap::DashMap;
4use ipnetwork::IpNetwork; 4use ipnetwork::IpNetwork;
5use sqlx::PgPool;
6use std::fmt::Display; 5use std::fmt::Display;
7use time::{Duration, Instant}; 6use time::{Duration, Instant};
8use tokio::sync::broadcast::Sender; 7use tokio::sync::broadcast::Sender;
@@ -13,6 +12,7 @@ pub type StatusMap = DashMap<String, Value>;
13#[derive(Debug, Clone)] 12#[derive(Debug, Clone)]
14pub struct Value { 13pub struct Value {
15 pub ip: IpNetwork, 14 pub ip: IpNetwork,
15 pub eta: i64,
16 pub online: bool, 16 pub online: bool,
17} 17}
18 18
@@ -22,7 +22,6 @@ pub async fn spawn(
22 device: Device, 22 device: Device,
23 uuid: String, 23 uuid: String,
24 ping_map: &StatusMap, 24 ping_map: &StatusMap,
25 db: &PgPool,
26) { 25) {
27 let timer = Instant::now(); 26 let timer = Instant::now();
28 let payload = [0; 8]; 27 let payload = [0; 8];
@@ -56,27 +55,29 @@ pub async fn spawn(
56 let _ = tx.send(msg.clone()); 55 let _ = tx.send(msg.clone());
57 if msg.command == BroadcastCommands::Success { 56 if msg.command == BroadcastCommands::Success {
58 if timer.elapsed().whole_seconds() > config.pingthreshold { 57 if timer.elapsed().whole_seconds() > config.pingthreshold {
59 sqlx::query!( 58 let newtimes = if let Some(mut oldtimes) = device.times {
60 r#" 59 oldtimes.push(timer.elapsed().whole_seconds());
61 UPDATE devices 60 oldtimes
62 SET times = array_append(times, $1) 61 } else {
63 WHERE id = $2; 62 vec![timer.elapsed().whole_seconds()]
64 "#, 63 };
65 timer.elapsed().whole_seconds(), 64
66 device.id 65 let updatedev = Device {
67 ) 66 id: device.id,
68 .execute(db) 67 mac: device.mac,
69 .await 68 broadcast_addr: device.broadcast_addr,
70 .unwrap(); 69 ip: device.ip,
70 times: Some(newtimes),
71 };
72 updatedev.write().unwrap();
71 } 73 }
72 74
73 ping_map.insert( 75 ping_map.alter(&uuid, |_, v| Value {
74 uuid.clone(), 76 ip: v.ip,
75 Value { 77 eta: v.eta,
76 ip: device.ip, 78 online: true,
77 online: true, 79 });
78 }, 80
79 );
80 tokio::time::sleep(tokio::time::Duration::from_secs(60)).await; 81 tokio::time::sleep(tokio::time::Duration::from_secs(60)).await;
81 } 82 }
82 trace!("remove {} from ping_map", uuid); 83 trace!("remove {} from ping_map", uuid);
diff --git a/src/storage.rs b/src/storage.rs
new file mode 100644
index 0000000..0da245b
--- /dev/null
+++ b/src/storage.rs
@@ -0,0 +1,70 @@
1use std::{
2 fs::{create_dir_all, File},
3 io::{Read, Write},
4 path::Path,
5};
6
7use ipnetwork::IpNetwork;
8use mac_address::MacAddress;
9use serde::{Deserialize, Serialize};
10use serde_json::json;
11use tracing::{debug, trace, warn};
12use utoipa::ToSchema;
13
14use crate::error::Error;
15
16#[derive(Serialize, Deserialize, Clone, Debug)]
17pub struct Device {
18 pub id: String,
19 pub mac: MacAddress,
20 pub broadcast_addr: String,
21 pub ip: IpNetwork,
22 pub times: Option<Vec<i64>>,
23}
24
25impl Device {
26 const STORAGE_PATH: &'static str = "devices";
27
28 pub fn setup() -> Result<String, Error> {
29 trace!("check for storage at {}", Self::STORAGE_PATH);
30 let sp = Path::new(Self::STORAGE_PATH);
31 if !sp.exists() {
32 warn!("device storage path doesn't exist, creating it");
33 create_dir_all(Self::STORAGE_PATH)?;
34 };
35
36 debug!("device storage at '{}'", Self::STORAGE_PATH);
37
38 Ok(Self::STORAGE_PATH.to_string())
39 }
40
41 pub fn read(id: &str) -> Result<Self, Error> {
42 trace!(?id, "attempt to read file");
43 let mut file = File::open(format!("{}/{id}.json", Self::STORAGE_PATH))?;
44 let mut buf = String::new();
45 file.read_to_string(&mut buf)?;
46 trace!(?id, ?buf, "read successfully from file");
47
48 let dev = serde_json::from_str(&buf)?;
49 Ok(dev)
50 }
51
52 pub fn write(&self) -> Result<(), Error> {
53 trace!(?self.id, ?self, "attempt to write to file");
54 let mut file = File::create(format!("{}/{}.json", Self::STORAGE_PATH, self.id))?;
55 file.write_all(json!(self).to_string().as_bytes())?;
56 trace!(?self.id, "wrote successfully to file");
57
58 Ok(())
59 }
60}
61
62#[derive(ToSchema)]
63#[schema(as = Device)]
64pub struct DeviceSchema {
65 pub id: String,
66 pub mac: String,
67 pub broadcast_addr: String,
68 pub ip: String,
69 pub times: Option<Vec<i64>>,
70}
diff --git a/src/wol.rs b/src/wol.rs
index 31cf350..6392366 100644
--- a/src/wol.rs
+++ b/src/wol.rs
@@ -2,26 +2,6 @@ use std::net::{ToSocketAddrs, UdpSocket};
2 2
3use crate::error::Error; 3use crate::error::Error;
4 4
5/// Creates the magic packet from a mac address
6///
7/// # Panics
8///
9/// Panics if `mac_addr` is an invalid mac
10pub fn create_buffer(mac_addr: &str) -> Result<Vec<u8>, Error> {
11 let mut mac = Vec::new();
12 let sp = mac_addr.split(':');
13 for f in sp {
14 mac.push(u8::from_str_radix(f, 16)?);
15 }
16 let mut buf = vec![255; 6];
17 for _ in 0..16 {
18 for i in &mac {
19 buf.push(*i);
20 }
21 }
22 Ok(buf)
23}
24
25/// Sends a buffer on UDP broadcast 5/// Sends a buffer on UDP broadcast
26pub fn send_packet<A: ToSocketAddrs>( 6pub fn send_packet<A: ToSocketAddrs>(
27 bind_addr: A, 7 bind_addr: A,