commit d7b0d6f9f538e2b5ca36feb104bcc81e0d59059d
parent 0822c0c128d3b71b13109bb8c0f94f73174440fe
Author: Daniel GarcĂa <dani-garcia@users.noreply.github.com>
Date: Thu, 3 Sep 2020 19:51:04 +0200
Merge pull request #1124 from aaxdev/fix/support-mobile-signalr-msgpack
Fixing MsgPack headers type and support mobile SignalR
Diffstat:
1 file changed, 37 insertions(+), 29 deletions(-)
diff --git a/src/api/notifications.rs b/src/api/notifications.rs
@@ -20,10 +20,12 @@ static SHOW_WEBSOCKETS_MSG: AtomicBool = AtomicBool::new(true);
#[get("/hub")]
fn websockets_err() -> EmptyResult {
if CONFIG.websocket_enabled() && SHOW_WEBSOCKETS_MSG.compare_and_swap(true, false, Ordering::Relaxed) {
- err!("###########################################################
+ err!(
+ "###########################################################
'/notifications/hub' should be proxied to the websocket server or notifications won't work.
Go to the Wiki for more info, or disable WebSockets setting WEBSOCKET_ENABLED=false.
- ###########################################################################################")
+ ###########################################################################################"
+ )
} else {
Err(Error::empty())
}
@@ -137,7 +139,6 @@ struct InitialMessage {
const PING_MS: u64 = 15_000;
const PING: Token = Token(1);
-const ID_KEY: &str = "id=";
const ACCESS_TOKEN_KEY: &str = "access_token=";
impl WSHandler {
@@ -148,6 +149,32 @@ impl WSHandler {
let io_error = io::Error::from(io::ErrorKind::InvalidData);
Err(ws::Error::new(ws::ErrorKind::Io(io_error), msg))
}
+
+ fn get_request_token(&self, hs: Handshake) -> Option<String> {
+ use std::str::from_utf8;
+
+ // Verify we have a token header
+ if let Some(header_value) = hs.request.header("Authorization") {
+ if let Ok(converted) = from_utf8(header_value) {
+ if let Some(token_part) = converted.split("Bearer ").nth(1) {
+ return Some(token_part.into());
+ }
+ }
+ };
+
+ // Otherwise verify the query parameter value
+ let path = hs.request.resource();
+ if let Some(params) = path.split('?').nth(1) {
+ let params_iter = params.split('&').take(1);
+ for val in params_iter {
+ if val.starts_with(ACCESS_TOKEN_KEY) {
+ return Some(val[ACCESS_TOKEN_KEY.len()..].into());
+ }
+ }
+ };
+
+ None
+ }
}
impl Handler for WSHandler {
@@ -156,35 +183,16 @@ impl Handler for WSHandler {
//
// We don't use `id`, and as of around 2020-03-25, the official clients
// no longer seem to pass `id` (only `access_token`).
- let path = hs.request.resource();
-
- let (_id, access_token) = match path.split('?').nth(1) {
- Some(params) => {
- let params_iter = params.split('&').take(2);
-
- let mut id = None;
- let mut access_token = None;
- for val in params_iter {
- if val.starts_with(ID_KEY) {
- id = Some(&val[ID_KEY.len()..]);
- } else if val.starts_with(ACCESS_TOKEN_KEY) {
- access_token = Some(&val[ACCESS_TOKEN_KEY.len()..]);
- }
- }
-
- match (id, access_token) {
- (Some(a), Some(b)) => (a, b),
- (None, Some(b)) => ("", b), // Ignore missing `id`.
- _ => return self.err("Missing access token"),
- }
- }
- None => return self.err("Missing query parameters"),
+ // Get user token from header or query parameter
+ let access_token = match self.get_request_token(hs) {
+ Some(token) => token,
+ _ => return self.err("Missing access token"),
};
// Validate the user
use crate::auth;
- let claims = match auth::decode_login(access_token) {
+ let claims = match auth::decode_login(access_token.as_str()) {
Ok(claims) => claims,
Err(_) => return self.err("Invalid access token provided"),
};
@@ -335,7 +343,7 @@ impl WebSocketUsers {
/* Message Structure
[
1, // MessageType.Invocation
- {}, // Headers
+ {}, // Headers (map)
null, // InvocationId
"ReceiveMessage", // Target
[ // Arguments
@@ -352,7 +360,7 @@ fn create_update(payload: Vec<(Value, Value)>, ut: UpdateType) -> Vec<u8> {
let value = V::Array(vec![
1.into(),
- V::Array(vec![]),
+ V::Map(vec![]),
V::Nil,
"ReceiveMessage".into(),
V::Array(vec![V::Map(vec![