@@ -62,75 +62,6 @@ namespace nmos
62
62
};
63
63
}
64
64
65
- web::websockets::experimental::listener::validate_handler make_events_ws_validate_handler (nmos::node_model& model, nmos::experimental::authorization_state& authorization_state, nmos::experimental::validate_authorization_token_handler access_token_validation, slog::base_gate& gate_)
66
- {
67
- return [&model, &authorization_state, access_token_validation, &gate_](web::http::http_request req)
68
- {
69
- nmos::ws_api_gate gate (gate_, req.request_uri ());
70
- auto lock = model.write_lock ();
71
- auto & resources = model.connection_resources ;
72
-
73
- // RFC 6750 defines two methods of sending bearer access tokens which are applicable to WebSocket
74
- // Clients SHOULD use the "Authorization Request Header Field" method.
75
- // Clients MAY use a "URI Query Parameter".
76
- // See https://tools.ietf.org/html/rfc6750#section-2
77
- if (web::http::methods::OPTIONS != req.method () && nmos::experimental::fields::server_authorization (model.settings ))
78
- {
79
- const auto & settings = model.settings ;
80
-
81
- web::uri token_issuer;
82
- // note: ws_validate_authorization returns the token_issuer via function parameter
83
- const auto result = nmos::experimental::ws_validate_authorization (req, nmos::experimental::scopes::events, nmos::get_host_name (settings), token_issuer, access_token_validation, gate_);
84
- if (!result)
85
- {
86
- // set error repsonse
87
- auto realm = web::http::get_host_port (req).first ;
88
- if (realm.empty ()) { realm = nmos::get_host (settings); }
89
- web::http::http_response res;
90
- const auto retry_after = nmos::experimental::fields::service_unavailable_retry_after (settings);
91
- nmos::experimental::details::set_error_reply (res, realm, retry_after, result);
92
- req.reply (res);
93
-
94
- // if no matching public keys caused the error, trigger a re-fetch to obtain public keys from the token issuer (authorization_state.token_issuer)
95
- if (result.value == nmos::experimental::authorization_error::no_matching_keys)
96
- {
97
- slog::log <slog::severities::warning>(gate, SLOG_FLF) << " Invalid websocket connection to: " << req.request_uri ().path () << " : " << result.message ;
98
-
99
- with_write_lock (authorization_state.mutex , [&authorization_state, token_issuer]
100
- {
101
- authorization_state.fetch_token_issuer_pubkeys = true ;
102
- authorization_state.token_issuer = token_issuer;
103
- });
104
-
105
- model.notify ();
106
- }
107
- else
108
- {
109
- slog::log <slog::severities::error>(gate, SLOG_FLF) << " Invalid websocket connection to: " << req.request_uri ().path () << " : " << result.message ;
110
- }
111
- return false ;
112
- }
113
- }
114
-
115
- // For now, to determine whether the "resource name" is valid, only look at the path, and ignore any query parameters
116
- const auto & ws_resource_path = req.request_uri ().path ();
117
- slog::log <slog::severities::more_info>(gate, SLOG_FLF) << " Validating websocket connection to: " << ws_resource_path;
118
-
119
- const bool has_ws_resource_path = resources.end () != find_resource_if (resources, nmos::types::sender, [&ws_resource_path](const nmos::resource& resource)
120
- {
121
- auto active = nmos::fields::master_enable (nmos::fields::endpoint_active (resource.data ));
122
- auto & transport_params = nmos::fields::transport_params (nmos::fields::endpoint_active (resource.data ));
123
- auto & connection_uri = nmos::fields::connection_uri (transport_params.at (0 ));
124
- return active
125
- && !connection_uri.is_null ()
126
- && ws_resource_path == web::uri (connection_uri.as_string ()).path ();
127
- });
128
-
129
- if (!has_ws_resource_path) slog::log <slog::severities::error>(gate, SLOG_FLF) << " Invalid websocket connection to: " << ws_resource_path;
130
- return has_ws_resource_path;
131
- };
132
- }
133
-
134
65
web::websockets::experimental::listener::open_handler make_events_ws_open_handler (nmos::node_model& model, nmos::websockets& websockets, slog::base_gate& gate_)
135
66
{
136
67
using web::json::value;
0 commit comments