diff --git a/.idea/.gitignore b/.idea/.gitignore
new file mode 100644
index 0000000..1c2fda5
--- /dev/null
+++ b/.idea/.gitignore
@@ -0,0 +1,8 @@
+# Default ignored files
+/shelf/
+/workspace.xml
+# Editor-based HTTP Client requests
+/httpRequests/
+# Datasource local storage ignored files
+/dataSources/
+/dataSources.local.xml
diff --git a/.idea/dataSources.local.xml b/.idea/dataSources.local.xml
deleted file mode 100644
index 9744bab..0000000
--- a/.idea/dataSources.local.xml
+++ /dev/null
@@ -1,18 +0,0 @@
-
-
-
-
-
- "
-
-
- master_key
- no-auth
-
-
-
-
-
-
-
-
\ No newline at end of file
diff --git a/.idea/dataSources.xml b/.idea/dataSources.xml
deleted file mode 100644
index 04513d7..0000000
--- a/.idea/dataSources.xml
+++ /dev/null
@@ -1,12 +0,0 @@
-
-
-
-
- sqlite.xerial
- true
- org.sqlite.JDBC
- jdbc:sqlite:$PROJECT_DIR$/db.sqlite
- $ProjectFileDir$
-
-
-
\ No newline at end of file
diff --git a/.idea/dataSources/26059583-0fdb-4f6f-ad11-10388e9658c2.xml b/.idea/dataSources/26059583-0fdb-4f6f-ad11-10388e9658c2.xml
deleted file mode 100644
index 1694b35..0000000
--- a/.idea/dataSources/26059583-0fdb-4f6f-ad11-10388e9658c2.xml
+++ /dev/null
@@ -1,1923 +0,0 @@
-
-
-
-
- 3.45.1
-
-
-
-
-
-
-
-
-
-
-
-
-
-
-
-
- 1
-
-
- 1
-
-
- 1
-
-
- 1
-
-
- 1
-
-
- 1
-
-
- 1
-
-
- 1
-
-
- 1
-
-
- 1
-
-
-
- window
-
-
- 1
-
-
- 1
-
-
- 1
-
-
-
- 1
- 1
-
-
-
-
- 1
- 1
-
-
- 1
- 1
-
-
- 1
- 1
-
-
- 1
-
-
- 1
-
-
-
-
- window
-
-
- window
-
-
-
-
-
- 1
- 1
-
-
- 1
- 1
-
-
- 1
-
-
- window
-
-
-
- 1
-
-
- window
-
-
- 1
-
-
- 1
- 1
-
-
-
-
-
- 1
-
-
- 1
-
-
- window
-
-
- 1
-
-
- 1
-
-
- 1
-
-
- 1
-
-
- 1
-
-
- 1
-
-
- 1
- 1
-
-
- 1
-
-
- 1
-
-
- 1
- 1
-
-
- 1
- window
-
-
- 1
- window
-
-
- 1
- 1
-
-
- 1
- 1
-
-
- 1
-
-
- 1
-
-
- 1
- 1
-
-
- 1
- 1
-
-
- 1
- 1
-
-
- 1
-
-
- 1
-
-
- 1
-
-
- 1
- 1
-
-
- 1
- 1
-
-
- 1
- window
-
-
- 1
- window
-
-
- 1
- 1
-
-
- 1
- 1
-
-
- 1
-
-
- 1
- 1
-
-
- 1
- 1
-
-
- 1
- 1
-
-
- 1
- 1
-
-
- window
-
-
- window
-
-
-
- window
-
-
- window
-
-
- window
-
-
-
- 1
-
-
- 1
-
-
- 1
-
-
- 1
-
-
- 1
-
-
-
- 1
-
-
- 1
-
-
- 1
-
-
- 1
-
-
- aggregate
-
-
- 1
-
-
-
-
-
- 1
- 1
-
-
- window
-
-
- aggregate
-
-
- 1
- 1
-
-
- window
-
-
- 1
-
-
- aggregate
-
-
- window
-
-
- window
-
-
- 1
-
-
- 1
-
-
-
-
-
-
-
- window
-
-
- 1
-
-
- 1
-
-
- 1
-
-
- 1
- 1
-
-
-
- 1
-
-
- 1
-
-
-
-
- window
-
-
- 1
-
-
- 1
-
-
-
-
-
- 1
-
-
- window
-
-
- 1
-
-
-
-
- 1
-
-
- 1
-
-
- 1
-
-
- 1
-
-
- 1
-
-
-
-
- 1
-
-
-
-
- 1
-
-
-
- aggregate
-
-
-
- 1
- 1
-
-
- window
-
-
- 1
-
-
- 1
-
-
- 1
-
-
- window
-
-
- 1
-
-
- 1
-
-
- 1
- 1
-
-
- 1
-
-
- window
-
-
-
- 1
-
-
- 1
-
-
- 1
-
-
- 1
-
-
- 1
-
-
- 1
- 1
-
-
- 1
-
-
- 1
-
-
- aggregate
-
-
- aggregate
-
-
- 1
-
-
- 1
- 2025-07-31.16:26:29
-
-
- R
-
-
- 1
-
-
- 2
-
-
- R
-
-
- 1
-
-
- 2
-
-
- R
-
-
- 1
-
-
- R
-
-
- 1
-
-
- R
-
-
- 1
-
-
- R
-
-
- 1
-
-
- R
-
-
- 1
-
-
- R
-
-
- 1
-
-
- R
-
-
- 1
-
-
- 2
-
-
- R
-
-
- 1
-
-
- R
-
-
- 1
-
-
- 2
-
-
- R
-
-
- 1
-
-
- R
-
-
- R
-
-
- 1
-
-
- R
-
-
- 1
-
-
- R
-
-
- R
-
-
- R
-
-
- 1
-
-
- 2
-
-
- R
-
-
- 1
-
-
- 2
-
-
- 3
-
-
- R
-
-
- R
-
-
- R
-
-
- R
-
-
- 1
-
-
- R
-
-
- 1
-
-
- R
-
-
- 1
-
-
- R
-
-
- 1
-
-
- R
-
-
- 1
-
-
- R
-
-
- R
-
-
- R
-
-
- R
-
-
- R
-
-
- R
-
-
- R
-
-
- 1
-
-
- R
-
-
- R
-
-
- 1
-
-
- 2
-
-
- R
-
-
- 1
-
-
- R
-
-
- 1
-
-
- R
-
-
- 1
-
-
- R
-
-
- R
-
-
- 1
-
-
- R
-
-
- 1
-
-
- 2
-
-
- R
-
-
- 1
-
-
- R
-
-
- R
-
-
- 1
-
-
- 2
-
-
- R
-
-
- 1
-
-
- 2
-
-
- R
-
-
- 1
-
-
- R
-
-
- R
-
-
- 1
-
-
- 2
-
-
- R
-
-
- 1
-
-
- 2
-
-
- 3
-
-
- R
-
-
- 1
-
-
- 2
-
-
- R
-
-
- 1
-
-
- R
-
-
- R
-
-
- 1
-
-
- 2
-
-
- R
-
-
- 1
-
-
- R
-
-
- R
-
-
- 1
-
-
- R
-
-
- 1
-
-
- 2
-
-
- R
-
-
- R
-
-
- R
-
-
- 1
-
-
- 2
-
-
- R
-
-
- 1
-
-
- R
-
-
- R
-
-
- R
-
-
- R
-
-
- 1
-
-
- 2
-
-
- R
-
-
- 1
-
-
- 2
-
-
- R
-
-
- 1
-
-
- R
-
-
- R
-
-
- R
-
-
- 1
-
-
- R
-
-
- 1
-
-
- 2
-
-
- R
-
-
- R
-
-
- R
-
-
- 1
-
-
- 2
-
-
- R
-
-
- R
-
-
- R
-
-
- R
-
-
- R
-
-
- 1
-
-
- 2
-
-
- R
-
-
- 1
-
-
- 2
-
-
- 3
-
-
- R
-
-
- R
-
-
- 1
-
-
- R
-
-
- 1
-
-
- 2
-
-
- R
-
-
- 1
-
-
- 2
-
-
- 3
-
-
- R
-
-
- 1
-
-
- 2
-
-
- R
-
-
- 1
-
-
- R
-
-
- 1
-
-
- 2
-
-
- 3
-
-
- R
-
-
- 1
-
-
- 2
-
-
- R
-
-
- 1
-
-
- R
-
-
- 1
-
-
- R
-
-
- 1
-
-
- 2
-
-
- R
-
-
- 1
-
-
- 2
-
-
- R
-
-
- 1
-
-
- R
-
-
- 1
-
-
- R
-
-
- 1
-
-
- R
-
-
- 1
-
-
- R
-
-
- 1
-
-
- 2
-
-
- R
-
-
- 1
-
-
- 2
-
-
- R
-
-
- 1
-
-
- R
-
-
- 1
-
-
- 2
-
-
- R
-
-
- R
-
-
- 1
-
-
- R
-
-
- 1
-
-
- R
-
-
- R
-
-
- 1
-
-
- R
-
-
- 1
-
-
- 2
-
-
- R
-
-
- 1
-
-
- R
-
-
- 1
-
-
- 2
-
-
- R
-
-
- 1
-
-
- R
-
-
- 1
-
-
- 2
-
-
- R
-
-
- 1
-
-
- R
-
-
- 1
-
-
- R
-
-
- 1
-
-
- R
-
-
- 1
-
-
- 2
-
-
- R
-
-
- 1
-
-
- 2
-
-
- R
-
-
- 1
-
-
- 2
-
-
- R
-
-
- R
-
-
- R
-
-
- 1
-
-
- 2
-
-
- R
-
-
- 1
-
-
- 2
-
-
- R
-
-
- R
-
-
- 1
-
-
- R
-
-
- 1
-
-
- R
-
-
- 1
-
-
- R
-
-
- R
-
-
- 1
-
-
- R
-
-
- R
-
-
- R
-
-
- 1
-
-
- 2
-
-
- 3
-
-
- R
-
-
- 1
-
-
- 2
-
-
- R
-
-
- 1
-
-
- R
-
-
- 1
-
-
- 2
-
-
- R
-
-
- 1
-
-
- 2
-
-
- R
-
-
- R
-
-
- R
-
-
- 1
-
-
- R
-
-
- 1
-
-
- 2
-
-
- R
-
-
- 1
-
-
- 2
-
-
- R
-
-
- 1
-
-
- R
-
-
- 1
-
-
- R
-
-
- 1
-
-
- R
-
-
- R
-
-
- 1
-
-
- R
-
-
- 1
-
-
- R
-
-
- 1
-
-
- 2
-
-
- R
-
-
- R
-
-
- R
-
-
- 1
-
-
- R
-
-
- 1
-
-
- R
-
-
- 1
-
-
- R
-
-
- 1
-
-
- 2
-
-
- R
-
-
- R
-
-
- 1
-
-
- 2
-
-
- R
-
-
- 1
-
-
- 2
-
-
- 3
-
-
- R
-
-
- 1
-
-
- 2
-
-
- 3
-
-
- R
-
-
- 1
-
-
- R
-
-
- 1
-
-
- R
-
-
- 1
-
-
- R
-
-
- 1
-
-
- R
-
-
- R
-
-
- 1
-
-
- 2
-
-
- R
-
-
- 1
-
-
- R
-
-
- R
-
-
- 1
-
-
- 2
-
-
- R
-
-
- 1
-
-
- R
-
-
- 1
-
-
- R
-
-
- 1
-
-
- 2
-
-
- R
-
-
- 1
-
-
- R
-
-
- R
-
-
- 1
-
-
- R
-
-
- 1
-
-
- R
-
-
- 1
-
-
- R
-
-
- 1
-
-
- R
-
-
- 1
-
-
-
-
-
-
-
-
-
- 1
- BIGINT|0s
-
-
- 1
- 2
- TEXT|0s
-
-
- CURRENT_TIMESTAMP
- 1
- 3
- TIMESTAMP|0s
-
-
- 1
- 4
- BOOLEAN|0s
-
-
- 1
- 5
- BLOB|0s
-
-
- 1
- 6
- BIGINT|0s
-
-
- version
- 1
- 1
-
-
- version
- 1
- sqlite_autoindex__sqlx_migrations_1
-
-
- 1
- 1
- TEXT|0s
-
-
- 1
- 2
- TEXT|0s
-
-
- 3
- TEXT|0s
-
-
- 1
- 4
- TEXT|0s
-
-
- 1
- 5
- TEXT|0s
-
-
- 1
- 6
- TEXT|0s
-
-
- 1
- 7
- TEXT|0s
-
-
- sub_server_id
- id
- sub_server
-
-
- id
- 1
- 1
-
-
- sub_server_id
-
-
- id
- 1
- sqlite_autoindex_channel_1
-
-
- 1
- 1
- TEXT|0s
-
-
- 1
- 2
- TEXT|0s
-
-
- 1
- 3
- TEXT|0s
-
-
- 1
- 4
- TEXT|0s
-
-
- 1
- 5
- TEXT|0s
-
-
- 1
- 6
- TEXT|0s
-
-
- author_id
- id
- user
-
-
- channel_id
- id
- channel
-
-
- id
- 1
- 1
-
-
- author_id
-
-
- channel_id
-
-
- id
- 1
- sqlite_autoindex_message_1
-
-
- 1
- TEXT|0s
-
-
- 2
- TEXT|0s
-
-
- 3
- TEXT|0s
-
-
- 4
- INT|0s
-
-
- 5
- TEXT|0s
-
-
- 1
- 1
- TEXT|0s
-
-
- 1
- 2
- TEXT|0s
-
-
- 3
- TEXT|0s
-
-
- 1
- 4
- TEXT|0s
-
-
- 1
- 5
- TEXT|0s
-
-
- 1
- 6
- TEXT|0s
-
-
- owner_id
- id
- user
-
-
- id
- 1
- 1
-
-
- id
- 1
- sqlite_autoindex_sub_server_1
-
-
- 1
- 1
- TEXT|0s
-
-
- 1
- 2
- TEXT|0s
-
-
- 1
- 3
- TEXT|0s
-
-
- 1
- 4
- TEXT|0s
-
-
- 5
- TEXT|0s
-
-
- sub_server_id
- id
- sub_server
-
-
- user_id
- id
- user
-
-
- id
- 1
- 1
-
-
- sub_server_id
-user_id
- 1
- 1
-
-
- sub_server_id
-
-
- user_id
-
-
- id
- 1
- sqlite_autoindex_sub_server_user_1
-
-
- sub_server_id
-user_id
- sqlite_autoindex_sub_server_user_2
-
-
- 1
- 1
- TEXT|0s
-
-
- 1
- 2
- TEXT|0s
-
-
- 3
- TEXT|0s
-
-
- 4
- TEXT|0s
-
-
- 1
- 5
- TEXT|0s
-
-
- 1
- 6
- TEXT|0s
-
-
- id
- 1
- 1
-
-
- username
- 1
- 1
-
-
- id
- 1
- sqlite_autoindex_user_1
-
-
- username
- sqlite_autoindex_user_2
-
-
-
\ No newline at end of file
diff --git a/.idea/dataSources/26059583-0fdb-4f6f-ad11-10388e9658c2/storage_v2/_src_/schema/main.uQUzAA.meta b/.idea/dataSources/26059583-0fdb-4f6f-ad11-10388e9658c2/storage_v2/_src_/schema/main.uQUzAA.meta
deleted file mode 100644
index 8dab49c..0000000
--- a/.idea/dataSources/26059583-0fdb-4f6f-ad11-10388e9658c2/storage_v2/_src_/schema/main.uQUzAA.meta
+++ /dev/null
@@ -1,2 +0,0 @@
-#n:main
-! [0, 0, null, null, -2147483648, -2147483648]
diff --git a/.idea/workspace.xml b/.idea/workspace.xml
index a2102a8..fb24d27 100644
--- a/.idea/workspace.xml
+++ b/.idea/workspace.xml
@@ -1,9 +1,5 @@
-
-
-
-
@@ -15,20 +11,56 @@
-
-
-
-
+
+
+
+
+
+
+
+
+
+
+
+
+
+
+
+
+
+
+
+
+
+
+
+
+
+
+
+
+
+
+
+
+
+
+
+
+
+
+
+
@@ -37,43 +69,32 @@
-
-
-
-
-
-
-
+
{
- "associatedIndex": 5
+ "associatedIndex": 7
}
-
+
{
"keyToString": {
- "Cargo.Run.executor": "Run",
+ "Cargo.Run ox_speak_server.executor": "Run",
"ModuleVcsDetector.initialDetectionPerformed": "true",
"RunOnceActivity.ShowReadmeOnStart": "true",
+ "RunOnceActivity.TerminalTabsStorage.copyFrom.TerminalArrangementManager.252": "true",
"RunOnceActivity.git.unshallow": "true",
"RunOnceActivity.rust.reset.selective.auto.import": "true",
"git-widget-placeholder": "master",
"ignore.virus.scanning.warn.message": "true",
"junie.onboarding.icon.badge.shown": "true",
- "last_opened_file_path": "D:/Dev/ox_speak_server/src/network",
+ "last_opened_file_path": "//wsl.localhost/Debian/home/Nell/linux_dev/ox_speak_server",
"node.js.detected.package.eslint": "true",
"node.js.detected.package.tslint": "true",
"node.js.selected.package.eslint": "(autodetect)",
@@ -82,28 +103,14 @@
"org.rust.cargo.project.model.PROJECT_DISCOVERY": "true",
"org.rust.cargo.project.model.impl.CargoExternalSystemProjectAware.subscribe.first.balloon": "",
"org.rust.first.attach.projects": "true",
- "run.code.analysis.last.selected.profile": "pProject Default",
- "settings.editor.selected.configurable": "junie.allowlist",
+ "settings.editor.selected.configurable": "preferences.pluginManager",
"to.speed.mode.migration.done": "true",
"vue.rearranger.settings.migration": "true"
- },
- "keyToStringList": {
- "DatabaseDriversLRU": [
- "sqlite"
- ]
}
}
-
-
-
-
-
-
-
-
-
-
-
+
+
+
@@ -120,133 +127,42 @@
+
+
+
+
+
+
+
+
+
+
+
+
+
+
+
+
+
-
+
-
- 1751970990022
+
+ 1755963473950
- 1751970990022
-
-
-
-
-
-
-
-
-
-
-
-
-
-
-
-
-
-
-
-
-
-
-
-
-
-
-
-
-
-
-
-
-
-
-
-
-
-
-
-
-
-
-
-
-
-
-
-
-
-
+ 1755963473950
+
+
-
-
- 1752591904243
-
-
-
- 1752591904243
-
-
-
- 1752591989113
-
-
-
- 1752591989113
-
-
-
- 1753813204617
-
-
-
- 1753813204617
-
-
-
- 1754213783870
-
-
-
- 1754213783870
-
-
-
-
-
-
-
-
-
-
-
diff --git a/Cargo.lock b/Cargo.lock
index 0913e67..2597c98 100644
--- a/Cargo.lock
+++ b/Cargo.lock
@@ -1432,12 +1432,12 @@ dependencies = [
[[package]]
name = "socket2"
-version = "0.5.10"
+version = "0.6.0"
source = "registry+https://github.com/rust-lang/crates.io-index"
-checksum = "e22376abed350d73dd1cd119b57ffccad95b4e585a7cda43e286245ce23c0678"
+checksum = "233504af464074f9d066d7b5416c5f9b894a5862a6506e306f7b816cdd6f1807"
dependencies = [
"libc",
- "windows-sys 0.52.0",
+ "windows-sys 0.59.0",
]
[[package]]
@@ -1776,9 +1776,9 @@ checksum = "1f3ccbac311fea05f86f61904b462b55fb3df8837a366dfc601a0161d0532f20"
[[package]]
name = "tokio"
-version = "1.46.1"
+version = "1.47.1"
source = "registry+https://github.com/rust-lang/crates.io-index"
-checksum = "0cc3a2344dafbe23a245241fe8b09735b521110d30fcefbbd5feb1797ca35d17"
+checksum = "89e49afdadebb872d3145a5638b59eb0691ea23e46ca484037cfab3b76b95038"
dependencies = [
"backtrace",
"bytes",
@@ -1791,7 +1791,7 @@ dependencies = [
"slab",
"socket2",
"tokio-macros",
- "windows-sys 0.52.0",
+ "windows-sys 0.59.0",
]
[[package]]
@@ -1969,9 +1969,9 @@ checksum = "b6c140620e7ffbb22c2dee59cafe6084a59b5ffc27a8859a5f0d494b5d52b6be"
[[package]]
name = "uuid"
-version = "1.17.0"
+version = "1.18.0"
source = "registry+https://github.com/rust-lang/crates.io-index"
-checksum = "3cf4199d1e5d15ddd86a694e4d0dffa9c323ce759fea589f00fef9d81cc1931d"
+checksum = "f33196643e165781c20a5ead5582283a7dacbb87855d867fbc2df3f81eddc1be"
dependencies = [
"getrandom 0.3.3",
"js-sys",
diff --git a/Cargo.toml b/Cargo.toml
index 36170c1..641630c 100644
--- a/Cargo.toml
+++ b/Cargo.toml
@@ -17,9 +17,9 @@ debug = true
serde = { version = "1", features = ["derive"] }
serde_json = "1"
parking_lot = "0.12"
-tokio = { version = "1.46", features = ["full"] }
+tokio = { version = "1.47", features = ["full"] }
strum = {version = "0.27", features = ["derive"] }
-uuid = {version = "1.17", features = ["v4", "serde"] }
+uuid = {version = "1.18", features = ["v4", "serde"] }
event-listener = "5.4"
dashmap = "6.1"
bytes = "1.10"
diff --git a/README.md b/README.md
index 4613072..9b2a3a1 100644
--- a/README.md
+++ b/README.md
@@ -3,3 +3,4 @@ créer un fichier de migration sqlx :
sqlx migrate add --source src/store/migrations migration_name
```
+# Example
\ No newline at end of file
diff --git a/src/network/http.rs b/src/network/http.rs
index e24c213..91b577e 100644
--- a/src/network/http.rs
+++ b/src/network/http.rs
@@ -1,11 +1,9 @@
use std::net::SocketAddr;
use std::sync::Arc;
-use axum::{
- extract::{ws::WebSocket, ws::WebSocketUpgrade, State},
- response::Response,
- Json, Router,
- routing::{get, post}
-};
+use axum::{extract::{ws::WebSocket, ws::WebSocketUpgrade, State}, response::Response, Json, Router, routing::{get, post}, middleware};
+use axum::body::Body;
+use axum::http::{HeaderValue, Request, StatusCode};
+use axum::middleware::Next;
use tokio::net::TcpListener;
use crate::domain::event::EventBus;
use crate::network::http_routes::master;
@@ -46,7 +44,8 @@ impl HttpServer {
fn create_router(&self) -> Router {
let api_route = Router::new()
- .nest("/master", master::create_router());
+ .nest("/master", master::create_router())
+ .layer(middleware::from_fn(app_only_middleware));
Router::new()
.nest("/api", api_route)
@@ -67,4 +66,24 @@ impl HttpServer {
todo!("a faire")
})
}
+}
+
+// Middlewares
+async fn app_only_middleware(request: Request, next: Next) -> Result {
+ let headers = request.headers();
+ let expected_client = HeaderValue::from_static("ox_speak");
+ let expected_version = HeaderValue::from_static("1.0");
+ let expected_user_agent = HeaderValue::from_static("OxSpeak/1.0");
+
+ if headers.get("X-Client-Type") != Some(&expected_client) ||
+ headers.get("X-Protocol-Version") != Some(&expected_version) ||
+ headers.get("User-Agent") != Some(&expected_user_agent) {
+ return Ok(Response::builder()
+ .status(StatusCode::BAD_REQUEST)
+ .body("Invalid client".into())
+ .unwrap());
+ }
+
+ Ok(next.run(request).await)
+
}
\ No newline at end of file
diff --git a/src/network/http_routes/master.rs b/src/network/http_routes/master.rs
index c97193f..d72af99 100644
--- a/src/network/http_routes/master.rs
+++ b/src/network/http_routes/master.rs
@@ -10,9 +10,37 @@ use crate::network::http::HttpState;
pub fn create_router() -> Router {
Router::new()
- .route("/auth/", post(join_master_server))
+ .route("/auth/", post(join))
}
-pub async fn join_master_server(State(state): State) -> Json> {
+pub async fn challenge(State(state): State) -> Json> {
+ // permet de sécuriser les échanges entre le client et le serveur pour qu'elle soit propre à l'application
+ // l'idée est d'éviter que les système comme les navigateurs, curl ... puisse accéder à l'application
+ todo!("challenge master server")
+}
+
+pub async fn join(State(state): State) -> Json> {
+ // Cette page est systématiquement appelé à la première connexion du client
+ // dans le payload de la requête, on aura les info client
+ // public key
+ // dans la réponse, on aura le status
+ // success, error, password_needed
+
+ // match determine_server_state().await {
+ // ServerState::FirstSetup => {
+ // // Logique de création du super admin
+ // // Validation des champs requis (password, username)
+ // }
+ // ServerState::RequiresPassword => {
+ // // Logique d'authentification
+ // // Validation du mot de passe serveur
+ // }
+ // ServerState::Ready => {
+ // // Logique de connexion normale
+ // // Juste la public key suffit
+ // }
+ // }
+
todo!("join master server")
+
}
\ No newline at end of file
diff --git a/src/store/models/mod.rs b/src/store/models/mod.rs
index 96bac26..3acd86e 100644
--- a/src/store/models/mod.rs
+++ b/src/store/models/mod.rs
@@ -3,7 +3,6 @@ pub mod channel;
pub mod user;
pub mod message;
pub mod link_sub_server_user;
-mod models;
pub use sub_server::*;
pub use channel::*;
diff --git a/src/store/session/client.rs b/src/store/session/client.rs
index 0529f8e..a4800ab 100644
--- a/src/store/session/client.rs
+++ b/src/store/session/client.rs
@@ -103,7 +103,7 @@ pub struct ClientManager {
/// Index des clients par channel_id
voice_channel_clients: SharedArcMap>, // channel_id -> HashSet
/// Index des clients par sub_server_id
- sub_server_clients: SharedArcMap>, // sub_server_id -> Vec
+ sub_server_clients: SharedArcMap>, // sub_server_id -> Vec
/// Index des clients par adresse UDP
udp_clients: SharedArcMap, // udp_address -> session_id
}
@@ -135,9 +135,18 @@ impl ClientManager {
arc_client
}
+ pub fn join_sub_server(&self, client: &Arc, sub_server: &SubServer) {
+ let clients = self.sub_server_clients.get(sub_server).unwrap_or_else(|| {
+ let new_clients = Arc::new(SharedArcHashSet::new());
+ self.sub_server_clients.insert_arc(sub_server.clone(), new_clients.clone());
+ new_clients
+ });
+
+ clients.insert_arc(client.clone());
+ }
+
/// Obtient un client par son session_id
pub fn get_client(&self, session_id: &Uuid) -> Option> {
- // Convertir &str en String pour les clés
self.clients.get(session_id)
}
@@ -159,35 +168,14 @@ impl ClientManager {
///
/// # Returns
/// `true` si le client a été trouvé et modifié, `false` sinon
- pub fn modify_client(&self, session_id: &str, f: F) -> bool
+ pub fn modify_client(&self, client: &Client, f: F) -> bool
where
F: FnOnce(&mut Client),
{
// Convertir &str en String pour les clés
- self.clients.modify(&session_id.to_string(), f)
+
+ todo!()
}
-
- // ===== OPÉRATIONS ATOMIQUES HAUT NIVEAU =====
-
- // Nettoie tous les index d'un client (appelé lors de la suppression)
- // pub(crate) fn cleanup_client_indexes(&self, session_id: &str) {
- // if let Some(client) = self.get_client(session_id) {
- // // Nettoyer l'index des channels
- // if let Some(channel_id) = client.current_channel {
- // self.remove_from_channel_index(session_id, channel_id);
- // }
- //
- // // Nettoyer l'index des sub-servers
- // if let Some(sub_server_id) = client.current_sub_server {
- // self.remove_from_sub_server_index(session_id, sub_server_id);
- // }
- //
- // // Nettoyer l'index UDP
- // if let Some(udp_address) = client.udp_socket {
- // self.udp_clients.remove(&udp_address);
- // }
- // }
- // }
}
impl ClientManager {
@@ -219,16 +207,7 @@ impl ClientManager {
pub fn remove_client_from_sub_servers(&self, client: &Client) {
for (sub_server, clients) in self.sub_server_clients.iter() {
- let mut to_remove = Vec::::new();
- for (index, client) in clients.iter().enumerate() {
- if client == client {
- to_remove.push(index);
- }
- }
-
- for idx in to_remove.iter() {
- clients.
- }
+ clients.remove(client);
}
}
}
\ No newline at end of file
diff --git a/src/utils/shared_store.rs b/src/utils/shared_store.rs
index fbd065a..76d0fad 100644
--- a/src/utils/shared_store.rs
+++ b/src/utils/shared_store.rs
@@ -246,87 +246,68 @@ impl SharedVec {
/// Supprime l'élément à l'index donné et le retourne.
/// Retourne `None` si l'index est hors limites.
+ ///
+ /// Exemple : `let removed = clients.delete(2); // Supprime le 3e client`
pub fn delete(&self, index: usize) -> Option
where
T: Clone,
{
- loop {
- let current = self.inner.load();
-
- if index >= current.len() {
- return None;
- }
-
- let mut new_vec = current.as_ref().clone();
- let removed_item = new_vec.remove(index);
-
- let new_arc = Arc::new(new_vec);
-
- if self.inner.compare_and_swap(¤t, new_arc).is_ok() {
- return Some(removed_item);
- }
- // Retry si le CAS a échoué
+ let current = self.inner.load_full();
+ if index >= current.len() {
+ return None;
}
+
+ let mut new_vec = current.as_ref().clone();
+ let removed_item = new_vec.remove(index);
+ self.inner.store(Arc::new(new_vec));
+ Some(removed_item)
}
/// Supprime et retourne le dernier élément du vecteur.
/// Retourne `None` si le vecteur est vide.
+ ///
+ /// Exemple : `let last_client = clients.pop(); // Supprime le dernier client`
pub fn pop(&self) -> Option
where
T: Clone,
{
- loop {
- let current = self.inner.load();
-
- if current.is_empty() {
- return None;
- }
-
- let mut new_vec = current.as_ref().clone();
- let popped_item = new_vec.pop();
-
- let new_arc = Arc::new(new_vec);
-
- if self.inner.compare_and_swap(¤t, new_arc).is_ok() {
- return popped_item;
- }
- // Retry si le CAS a échoué
+ let current = self.inner.load_full();
+ if current.is_empty() {
+ return None;
}
+
+ let mut new_vec = current.as_ref().clone();
+ let popped_item = new_vec.pop();
+ self.inner.store(Arc::new(new_vec));
+ popped_item
}
/// Supprime tous les éléments qui correspondent au prédicat donné.
/// Retourne le nombre d'éléments supprimés.
+ ///
+ /// Exemple : `let removed = clients.delete_matching(|c| c.is_disconnected());`
pub fn delete_matching(&self, predicate: F) -> usize
where
T: Clone,
F: Fn(&T) -> bool,
{
- loop {
- let current = self.inner.load();
- let mut new_vec = Vec::with_capacity(current.len());
- let mut removed_count = 0;
+ let current = self.inner.load_full();
+ let mut new_vec = Vec::with_capacity(current.len());
+ let mut removed_count = 0;
- for item in current.iter() {
- if predicate(item) {
- removed_count += 1;
- } else {
- new_vec.push(item.clone());
- }
+ for item in current.iter() {
+ if predicate(item) {
+ removed_count += 1;
+ } else {
+ new_vec.push(item.clone());
}
-
- if removed_count == 0 {
- return 0;
- }
-
- let new_arc = Arc::new(new_vec);
-
- if self.inner.compare_and_swap(¤t, new_arc).is_ok() {
- return removed_count;
- }
- // Retry si le CAS a échoué
}
- }
+ if removed_count > 0 {
+ self.inner.store(Arc::new(new_vec));
+ }
+ removed_count
+ }
/// Clear optimisé
///
@@ -939,45 +920,29 @@ impl SharedArcVec {
/// Supprime l'élément à l'index donné et le retourne.
/// Retourne `None` si l'index est hors limites.
pub fn delete(&self, index: usize) -> Option> {
- loop {
- let current = self.inner.load();
-
- if index >= current.len() {
- return None;
- }
-
- let mut new_vec = current.as_ref().clone();
- let removed_item = new_vec.remove(index);
-
- let new_arc = Arc::new(new_vec);
-
- if self.inner.compare_and_swap(¤t, new_arc).is_ok() {
- return Some(removed_item);
- }
- // Retry si le CAS a échoué
+ let current = self.inner.load_full();
+ if index >= current.len() {
+ return None;
}
+
+ let mut new_vec = current.as_ref().clone();
+ let removed_item = new_vec.remove(index);
+ self.inner.store(Arc::new(new_vec));
+ Some(removed_item)
}
/// Supprime et retourne le dernier élément du vecteur.
/// Retourne `None` si le vecteur est vide.
pub fn pop(&self) -> Option> {
- loop {
- let current = self.inner.load();
-
- if current.is_empty() {
- return None;
- }
-
- let mut new_vec = current.as_ref().clone();
- let popped_item = new_vec.pop();
-
- let new_arc = Arc::new(new_vec);
-
- if self.inner.compare_and_swap(¤t, new_arc).is_ok() {
- return popped_item;
- }
- // Retry si le CAS a échoué
+ let current = self.inner.load_full();
+ if current.is_empty() {
+ return None;
}
+
+ let mut new_vec = current.as_ref().clone();
+ let popped_item = new_vec.pop();
+ self.inner.store(Arc::new(new_vec));
+ popped_item
}
/// Supprime tous les éléments qui correspondent au prédicat donné.
@@ -986,30 +951,22 @@ impl SharedArcVec {
where
F: Fn(&T) -> bool,
{
- loop {
- let current = self.inner.load();
- let mut new_vec = Vec::with_capacity(current.len());
- let mut removed_count = 0;
+ let current = self.inner.load_full();
+ let mut new_vec = Vec::with_capacity(current.len());
+ let mut removed_count = 0;
- for item in current.iter() {
- if predicate(item.as_ref()) {
- removed_count += 1;
- } else {
- new_vec.push(item.clone());
- }
+ for item in current.iter() {
+ if predicate(item.as_ref()) {
+ removed_count += 1;
+ } else {
+ new_vec.push(item.clone());
}
-
- if removed_count == 0 {
- return 0;
- }
-
- let new_arc = Arc::new(new_vec);
-
- if self.inner.compare_and_swap(¤t, new_arc).is_ok() {
- return removed_count;
- }
- // Retry si le CAS a échoué
}
+
+ if removed_count > 0 {
+ self.inner.store(Arc::new(new_vec));
+ }
+ removed_count
}
/// Supprime le premier élément trouvé qui correspond au prédicat.
@@ -1018,30 +975,23 @@ impl SharedArcVec {
where
F: Fn(&T) -> bool,
{
- loop {
- let current = self.inner.load();
- let mut found_index = None;
+ let current = self.inner.load_full();
+ let mut found_index = None;
- for (index, item) in current.iter().enumerate() {
- if predicate(item.as_ref()) {
- found_index = Some(index);
- break;
- }
+ for (index, item) in current.iter().enumerate() {
+ if predicate(item.as_ref()) {
+ found_index = Some(index);
+ break;
}
+ }
- if let Some(index) = found_index {
- let mut new_vec = current.as_ref().clone();
- let removed_item = new_vec.remove(index);
-
- let new_arc = Arc::new(new_vec);
-
- if self.inner.compare_and_swap(¤t, new_arc).is_ok() {
- return Some(removed_item);
- }
- // Retry si le CAS a échoué
- } else {
- return None;
- }
+ if let Some(index) = found_index {
+ let mut new_vec = current.as_ref().clone();
+ let removed_item = new_vec.remove(index);
+ self.inner.store(Arc::new(new_vec));
+ Some(removed_item)
+ } else {
+ None
}
}