Skip to content

Commit f53132f

Browse files
authored
Implement socketio auth (1c3t3a#165)
* feat: add socketio auth * docs: add socketio ClientBuilder.auth docs * test: add socketio auth test * ci: add missing docker-compose service * feat: change auth to Option<serde_json::Value> * test: fix socket io auth listener edge case * feat: make auth consume Into again * fix: remove debug println
1 parent 3dce3e1 commit f53132f

File tree

8 files changed

+114
-5
lines changed

8 files changed

+114
-5
lines changed

.devcontainer/docker-compose.yaml

Lines changed: 9 additions & 0 deletions
Original file line numberDiff line numberDiff line change
@@ -32,6 +32,14 @@ services:
3232
- "4200:4200"
3333
environment:
3434
- "DEBUG=*"
35+
node-socket-io-auth:
36+
build:
37+
context: ../ci
38+
command: [ "node", "/test/socket-io-auth.js" ]
39+
ports:
40+
- "4204:4204"
41+
environment:
42+
- "DEBUG=*"
3543
rust-client:
3644
build:
3745
context: ..
@@ -43,6 +51,7 @@ services:
4351
- "..:/workspace/rust-socketio"
4452
environment:
4553
- "SOCKET_IO_SERVER=http://node-socket-io:4200"
54+
- "SOCKET_IO_AUTH_SERVER=http://node-socket-io:4204"
4655
- "ENGINE_IO_SERVER=http://node-engine-io:4201"
4756
- "ENGINE_IO_SECURE_SERVER=https://node-engine-io-secure:4202"
4857
- "ENGINE_IO_SECURE_HOST=node-engine-io-secure"

.github/workflows/coverage.yml

Lines changed: 1 addition & 1 deletion
Original file line numberDiff line numberDiff line change
@@ -31,7 +31,7 @@ jobs:
3131
- name: Build docker container
3232
run: |
3333
cd ci && docker build -t test_suite:latest .
34-
docker run -d --name test_suite -p 4200:4200 -p 4201:4201 -p 4202:4202 -p 4203:4203 test_suite:latest
34+
docker run -d --name test_suite -p 4200:4200 -p 4201:4201 -p 4202:4202 -p 4203:4203 -p 4204:4204 test_suite:latest
3535
3636
- uses: actions/cache@v2
3737
with:

.github/workflows/test.yml

Lines changed: 1 addition & 1 deletion
Original file line numberDiff line numberDiff line change
@@ -34,7 +34,7 @@ jobs:
3434
- name: Build docker container
3535
run: |
3636
cd ci && docker build -t test_suite:latest .
37-
docker run -d -p 4200:4200 -p 4201:4201 -p 4202:4202 -p 4203:4203 test_suite:latest
37+
docker run -d -p 4200:4200 -p 4201:4201 -p 4202:4202 -p 4203:4203 -p 4204:4204 test_suite:latest
3838
3939
- name: Generate Cargo.lock
4040
run: cargo generate-lockfile

ci/socket-io-auth.js

Lines changed: 18 additions & 0 deletions
Original file line numberDiff line numberDiff line change
@@ -0,0 +1,18 @@
1+
const server = require('http').createServer();
2+
const io = require('socket.io')(server);
3+
4+
console.log('Started');
5+
var callback = client => {
6+
console.log('Connected!');;
7+
client.on('test', function (arg, ack) {
8+
console.log('Ack received')
9+
if (ack) {
10+
const payload = client.handshake.auth.password === '123' ? '456' : '789'
11+
ack(payload);
12+
}
13+
});
14+
};
15+
io.on('connection', callback);
16+
io.of('/admin').on('connection', callback);
17+
// the socket.io client runs on port 4204
18+
server.listen(4204);

ci/start_test_server.sh

Lines changed: 8 additions & 0 deletions
Original file line numberDiff line numberDiff line change
@@ -23,6 +23,14 @@ if [ $status -ne 0 ]; then
2323
fi
2424
echo "Successfully started socket.io instance"
2525

26+
DEBUG=* node socket-io-auth.js &
27+
status=$?
28+
if [ $status -ne 0 ]; then
29+
echo "Failed to start socket.io auth: $status"
30+
exit $status
31+
fi
32+
echo "Successfully started socket.io auth instance"
33+
2634
DEBUG=* node engine-io-secure.js &
2735
status=$?
2836
if [ $status -ne 0 ]; then

socketio/src/client/builder.rs

Lines changed: 23 additions & 1 deletion
Original file line numberDiff line numberDiff line change
@@ -36,6 +36,7 @@ pub struct ClientBuilder {
3636
tls_config: Option<TlsConnector>,
3737
opening_headers: Option<HeaderMap>,
3838
transport_type: TransportType,
39+
auth: Option<serde_json::Value>,
3940
}
4041

4142
impl ClientBuilder {
@@ -77,6 +78,7 @@ impl ClientBuilder {
7778
tls_config: None,
7879
opening_headers: None,
7980
transport_type: TransportType::Any,
81+
auth: None,
8082
}
8183
}
8284

@@ -172,6 +174,26 @@ impl ClientBuilder {
172174
self
173175
}
174176

177+
/// Sets data sent in the opening request.
178+
/// # Example
179+
/// ```rust
180+
/// use rust_socketio::{ClientBuilder};
181+
/// use serde_json::json;
182+
///
183+
/// let socket = ClientBuilder::new("http://localhost:4204/")
184+
/// .namespace("/admin")
185+
/// .auth(json!({ "password": "1337" }))
186+
/// .on("error", |err, _| eprintln!("Error: {:#?}", err))
187+
/// .connect()
188+
/// .expect("Connection error");
189+
///
190+
/// ```
191+
pub fn auth<T: Into<serde_json::Value>>(mut self, auth: T) -> Self {
192+
self.auth = Some(auth.into());
193+
194+
self
195+
}
196+
175197
/// Specifies which EngineIO [`TransportType`] to use.
176198
/// # Example
177199
/// ```rust
@@ -261,7 +283,7 @@ impl ClientBuilder {
261283

262284
let inner_socket = InnerSocket::new(engine_client)?;
263285

264-
let socket = Client::new(inner_socket, &self.namespace, self.on)?;
286+
let socket = Client::new(inner_socket, &self.namespace, self.on, self.auth)?;
265287
socket.connect()?;
266288

267289
Ok(socket)

socketio/src/client/client.rs

Lines changed: 39 additions & 2 deletions
Original file line numberDiff line numberDiff line change
@@ -35,6 +35,8 @@ pub struct Client {
3535
outstanding_acks: Arc<RwLock<Vec<Ack>>>,
3636
// namespace, for multiplexing messages
3737
nsp: String,
38+
// Data sent in opening header
39+
auth: Option<serde_json::Value>,
3840
}
3941

4042
impl Client {
@@ -46,12 +48,14 @@ impl Client {
4648
socket: InnerSocket,
4749
namespace: T,
4850
on: HashMap<Event, Callback>,
51+
auth: Option<serde_json::Value>,
4952
) -> Result<Self> {
5053
Ok(Client {
5154
socket,
5255
nsp: namespace.into(),
5356
on: Arc::new(RwLock::new(on)),
5457
outstanding_acks: Arc::new(RwLock::new(Vec::new())),
58+
auth,
5559
})
5660
}
5761

@@ -62,8 +66,10 @@ impl Client {
6266
// Connect the underlying socket
6367
self.socket.connect()?;
6468

69+
let auth = self.auth.as_ref().map(|data| data.to_string());
70+
6571
// construct the opening packet
66-
let open_packet = Packet::new(PacketId::Connect, self.nsp.clone(), None, None, 0, None);
72+
let open_packet = Packet::new(PacketId::Connect, self.nsp.clone(), auth, None, 0, None);
6773

6874
self.socket.send(open_packet)?;
6975

@@ -389,7 +395,7 @@ impl<'a> Iterator for Iter<'a> {
389395

390396
#[cfg(test)]
391397
mod test {
392-
398+
use std::sync::mpsc;
393399
use std::thread::sleep;
394400

395401
use super::*;
@@ -524,6 +530,37 @@ mod test {
524530
test_socketio_socket(socket, "/admin".to_owned())
525531
}
526532

533+
#[test]
534+
fn socket_io_auth_builder_integration() -> Result<()> {
535+
let url = crate::test::socket_io_auth_server();
536+
let socket = ClientBuilder::new(url)
537+
.namespace("/admin")
538+
.auth(json!({ "password": "123" }))
539+
.connect()?;
540+
541+
let (tx, rx) = mpsc::sync_channel(0);
542+
543+
// Send emit with ack after 1s, so socketio server has enough time to register it's listeners
544+
sleep(Duration::from_secs(1));
545+
546+
assert!(socket
547+
.emit_with_ack(
548+
"test",
549+
json!({ "msg": "1" }),
550+
Duration::from_secs(1),
551+
move |payload, _| {
552+
println!("Got ack");
553+
tx.send(Payload::from(json!(["456"])) == payload).unwrap();
554+
}
555+
)
556+
.is_ok());
557+
558+
let received = rx.recv();
559+
assert!(received.is_ok() && received.unwrap());
560+
561+
Ok(())
562+
}
563+
527564
#[test]
528565
fn socketio_polling_integration() -> Result<()> {
529566
let url = crate::test::socket_io_server();

socketio/src/lib.rs

Lines changed: 15 additions & 0 deletions
Original file line numberDiff line numberDiff line change
@@ -124,4 +124,19 @@ pub(crate) mod test {
124124

125125
url
126126
}
127+
128+
// The socket.io auth server for testing runs on port 4204
129+
const AUTH_SERVER_URL: &str = "http://localhost:4204";
130+
131+
pub(crate) fn socket_io_auth_server() -> Url {
132+
let url =
133+
std::env::var("SOCKET_IO_AUTH_SERVER").unwrap_or_else(|_| AUTH_SERVER_URL.to_owned());
134+
let mut url = Url::parse(&url).unwrap();
135+
136+
if url.path() == "/" {
137+
url.set_path("/socket.io/");
138+
}
139+
140+
url
141+
}
127142
}

0 commit comments

Comments
 (0)