summaryrefslogtreecommitdiffstats
diff options
context:
space:
mode:
authorDaniel Pocock2015-01-22 21:35:02 (GMT)
committerDaniel Pocock2015-01-22 21:35:02 (GMT)
commit01d6d6d46f258b1962527d94100a7240d5d755c1 (patch)
tree68462ed0655031a8dfcab224e74832769f4f9560
parent704d7ba69f5266324af548f068f8825e5a435573 (diff)
Add support for logged-in users using WebSocket cookie and URL authentication7.x-2.3
-rw-r--r--drucall.admin.inc48
-rw-r--r--drucall.module70
-rw-r--r--js/drucall.js4
3 files changed, 115 insertions, 7 deletions
diff --git a/drucall.admin.inc b/drucall.admin.inc
index 6905013..8608668 100644
--- a/drucall.admin.inc
+++ b/drucall.admin.inc
@@ -47,6 +47,49 @@ function drucall_admin($form, &$form_state) {
'#description' => t('Whether or not to show a DTMF dialing pad during calls.'),
);
+ $form['sip_domain'] = array(
+ '#type' => 'textfield',
+ '#title' => t('SIP domain'),
+ '#default_value' => variable_get('sip_domain', ''),
+ '#cols' => 40,
+ '#rows' => 1,
+ '#description' => t('The SIP domain to be used to construct the <em>From:</em> header for calls made by logged-in Drupal users.'),
+ );
+
+ $form['ws_cookie_secret'] = array(
+ '#type' => 'textfield',
+ '#title' => t('WebSocket Cookie Shared Secret'),
+ '#default_value' => variable_get('ws_cookie_secret', ''),
+ '#cols' => 40,
+ '#rows' => 1,
+ '#description' => t('The shared secret used to authenticate WebSocket cookies. Must match the <b>WSCookieAuthSharedSecret</b> in <a href="http://www.resiprocate.org/SIP_Over_WebSocket_Cookies">the repro SIP proxy</a>.'),
+ );
+
+ $form['ws_cookie_domain'] = array(
+ '#type' => 'textfield',
+ '#title' => t('WebSocket Cookie Domain'),
+ '#default_value' => variable_get('ws_cookie_domain', ''),
+ '#cols' => 40,
+ '#rows' => 1,
+ '#description' => t('The domain to set in cookies if using <a href="http://www.resiprocate.org/SIP_Over_WebSocket_Cookies">SIP over WebSocket cookie authentication</a>. This may just be part of the domain and it must match both the Drupal web server domain and the WebSocket URL (below). E.g. if the web site is <em>www.example.org</em> and WebSocket server is <em>wss://sip-ws.example.org</em> then you must put <em>example.org</em> in this field.'),
+ );
+
+ $form['ws_cookie_timeout'] = array(
+ '#type' => 'textfield',
+ '#title' => t('WebSocket Cookie Timeout'),
+ '#default_value' => variable_get('ws_cookie_timeout', '900'),
+ '#cols' => 40,
+ '#rows' => 1,
+ '#description' => t('Specify the duration, in seconds, that the authentication code is valid. This also sets the expiration time of the cookies.'),
+ );
+
+ $form['ws_cookies_in_url'] = array(
+ '#type' => 'checkbox',
+ '#title' => t('Send WebSocket authentication as URL parameters'),
+ '#default_value' => variable_get('ws_cookies_in_url', true),
+ '#description' => t('If the WebSocket server doesn\'t have the same domain name or domain suffix as the Drupal web site, the browser will not send the cookies. Select this option to append the cookie values to the WebSocket URL so authentication will work across domains.'),
+ );
+
$form['display_name'] = array(
'#type' => 'textfield',
'#title' => t('Display name for caller'),
@@ -156,6 +199,11 @@ function drucall_admin_submit($form, &$form_state) {
variable_set('enable_video', $form_state['values']['enable_video']);
variable_set('enable_chat', $form_state['values']['enable_chat']);
variable_set('enable_dtmf_pad', $form_state['values']['enable_dtmf_pad']);
+ variable_set('sip_domain', $form_state['values']['sip_domain']);
+ variable_set('ws_cookie_secret', $form_state['values']['ws_cookie_secret']);
+ variable_set('ws_cookie_domain', $form_state['values']['ws_cookie_domain']);
+ variable_set('ws_cookie_timeout', $form_state['values']['ws_cookie_timeout']);
+ variable_set('ws_cookies_in_url', $form_state['values']['ws_cookies_in_url']);
variable_set('display_name', $form_state['values']['display_name']);
variable_set('from_uri', $form_state['values']['from_uri']);
variable_set('auth_user', $form_state['values']['auth_user']);
diff --git a/drucall.module b/drucall.module
index f7a1ba6..683bbe7 100644
--- a/drucall.module
+++ b/drucall.module
@@ -48,6 +48,7 @@ function drucall_theme() {
function drucall_call() {
global $language;
+ global $user;
// Make sure the necessary jQuery UI components are available on
// the page, Drupal loads core jQuery automatically but not jQuery UI
@@ -72,6 +73,63 @@ function drucall_call() {
libraries_load($libname);
}
+ $caller_domain = variable_get('sip_domain');
+ $display_name = '';
+ $caller_uri = '';
+ $caller_auth_user = '';
+ $caller_password = '';
+ $sip_register = FALSE;
+ if($user->uid != 0 && !empty($caller_domain)) {
+ // A user is logged in
+ $display_name = $user->name;
+ // FIXME: should check that Drupal username is valid for SIP
+ $caller_uri = 'sip:' . $user->name . '@' . $caller_domain;
+ $sip_register = TRUE;
+ } else {
+ // Guest user
+ $display_name = variable_get('display_name');
+ $caller_uri = variable_get('from_uri');
+ $caller_auth_user = variable_get('auth_user');
+ $caller_password = variable_get('auth_password');
+ }
+
+ $ws_cookie_secret = variable_get('ws_cookie_secret');
+ $websocket_server_url = variable_get('websocket_server_url');
+ $ws_cookies_in_url = variable_get('ws_cookies_in_url');
+ if(!empty($ws_cookie_secret)) {
+ $ws_cookie_timeout = variable_get('ws_cookie_timeout'); // seconds
+ $sip_from = explode(':', $caller_uri)[1];
+ $sip_to = '*@*';
+ $ws_cookie_domain = variable_get('ws_cookie_domain');
+ $ws_url = parse_url($websocket_server_url);
+ if(empty($ws_cookie_domain)) {
+ $ws_cookie_domain = $ws_url['host'];
+ }
+
+ $time_limit = REQUEST_TIME + $ws_cookie_timeout; // seconds
+ $cookie_value = '1:' . REQUEST_TIME . ':' . $time_limit . ':' . $sip_from . ':' . $sip_to;
+ $cookie_value_encoded = urlencode($cookie_value);
+ $extra_value = ''; // TODO - a shopping cart ID,
+ // order ID, customer ID or some other value
+ // Example sending the Drupal session ID through SIP
+ if(!empty($user->ssid))
+ $extra_value = 'drupal:ssid:' . $user->ssid;
+ else
+ $extra_value = 'drupal:sid:' . $user->sid;
+ $extra_value_encoded = urlencode($extra_value);
+ $digest_input = $cookie_value . ':' . $extra_value;
+ $cookie_mac = hash_hmac ('sha1', $digest_input, $ws_cookie_secret);
+
+ setrawcookie("WSSessionInfo", $cookie_value_encoded, $time_limit, '/', $ws_cookie_domain);
+ setrawcookie("WSSessionExtra", $extra_value_encoded, $time_limit, '/', $ws_cookie_domain);
+ setrawcookie("WSSessionMAC", $cookie_mac, $time_limit, '/', $ws_cookie_domain);
+ if($ws_cookies_in_url) {
+ if(empty($ws_url['path']))
+ $websocket_server_url = $websocket_server_url . '/';
+ $websocket_server_url = $websocket_server_url . ';WSSessionInfo=' . $cookie_value_encoded . ';WSSessionExtra=' . $extra_value_encoded . ';WSSessionMAC=' . $cookie_mac;
+ }
+ }
+
$my_settings = array(
'mod_path' => drupal_get_path('module', 'drucall'),
'phone_number' => variable_get('default_destination'),
@@ -79,17 +137,19 @@ function drucall_call() {
'enable_video' => variable_get('enable_video'),
'enable_chat' => variable_get('enable_chat'),
'enable_dtmf_pad' => variable_get('enable_dtmf_pad'),
- 'display_name' => variable_get('display_name'),
- 'impi' => variable_get('auth_user'),
- 'impu' => variable_get('from_uri'),
- 'password' => variable_get('auth_password'),
+ 'display_name' => $display_name,
+ 'impi' => $caller_auth_user,
+ 'impu' => $caller_uri,
+ 'password' => $caller_password,
'realm' => variable_get('auth_realm'),
- 'websocket_server_url' => variable_get('websocket_server_url'),
+ 'websocket_server_url' => $websocket_server_url,
'sip_outboundproxy_url' => variable_get('sip_outboundproxy_url'),
'turn_server_url' => variable_get('turn_server_url'),
'turn_username' => variable_get('turn_username'),
'turn_password' => variable_get('turn_password'),
'language_code' => $language->language,
+ 'sip_register' => $sip_register,
+ 'extra_header_value' => $extra_value,
);
drupal_add_js(
diff --git a/js/drucall.js b/js/drucall.js
index d6dbced..fdc1df1 100644
--- a/js/drucall.js
+++ b/js/drucall.js
@@ -39,7 +39,7 @@
// User SIP registration
registration : {
- on_startup: false, // Register when websocket link starts?
+ on_startup: dcsettings.sip_register, // Register when websocket link starts?
expiry: 3600, // Registration expiry (seconds)
user_control: false, // Show button for user to (de)register
server: null, // Registration server
@@ -84,7 +84,7 @@
},
extra_headers : [
- // 'X-WS-Session-Extra: some_token=value'
+ 'X-WS-Session-Extra: ' + dcsettings.extra_header_value
]
};