From b0106f0952b2148154314e661bdcacb419dd06c9 Mon Sep 17 00:00:00 2001 From: Rob Loach Date: Wed, 6 Apr 2011 13:35:52 -0400 Subject: [PATCH] Issue #423684: Disqus Single Sign-On for Drupal. --- disqus.admin.inc | 43 +++++++++++++++++++++++++++++++++++++ disqus.js | 21 ++++++++++++++---- disqus.module | 62 ++++++++++++++++++++++++++++++++++++++++++++++++++++++ 3 files changed, 121 insertions(+), 5 deletions(-) diff --git a/disqus.admin.inc b/disqus.admin.inc index 0efb546..85513be 100644 --- a/disqus.admin.inc +++ b/disqus.admin.inc @@ -18,6 +18,7 @@ function disqus_admin_settings() { '#type' => 'vertical_tabs', '#weight' => 50, ); + // Visibility settings. $form['visibility'] = array( '#type' => 'fieldset', '#title' => t('Visibility'), @@ -57,6 +58,7 @@ function disqus_admin_settings() { ), ), ); + // Behavior settings. $form['behavior'] = array( '#type' => 'fieldset', '#title' => t('Behavior'), @@ -80,5 +82,46 @@ function disqus_admin_settings() { '#description' => t('When enabled, uses the disqus_developer flag to tell Disqus that you are in a testing environment. Threads will not display on the public community page with this set.'), '#default_value' => variable_get('disqus_developer', FALSE), ); + // Advanced settings. + $form['advanced'] = array( + '#type' => 'fieldset', + '#title' => t('Advanced'), + '#group' => 'settings', + '#description' => t('Use these settings to configure the more advanced uses of Disqus. You can find more information about these in the Applications section of Disqus.', array( + '@applications' => 'http://disqus.com/api/applications/', + )), + ); + $form['advanced']['disqus_publickey'] = array( + '#type' => 'textfield', + '#title' => t('Public Key'), + '#default_value' => variable_get('disqus_publickey', ''), + ); + $form['advanced']['disqus_secretkey'] = array( + '#type' => 'textfield', + '#title' => t('Secret Key'), + '#default_value' => variable_get('disqus_secretkey', ''), + ); + $form['advanced']['disqus_sso'] = array( + '#type' => 'checkbox', + '#title' => t('Single Sign-On'), + '#description' => t('Provide Single Sign-On access to your site.', array( + '@sso' => 'http://disqus.com/api/sso/', + )), + '#default_value' => variable_get('disqus_sso', FALSE), + '#states' => array( + 'visible' => array( + 'input[name="disqus_publickey"]' => array('empty' => FALSE), + 'input[name="disqus_secretkey"]' => array('empty' => FALSE), + ), + ), + ); return system_settings_form($form); } + +/** + * Menu callback; Automatically closes the window after the user logs in. + */ +function disqus_closewindow() { + drupal_add_js('window.close();', 'inline'); + return t('Thank you for logging in. Please close this window, or click here to continue.', array('@clickhere' => 'javascript:window.close();')); +} diff --git a/disqus.js b/disqus.js index e643f57..74d971d 100644 --- a/disqus.js +++ b/disqus.js @@ -8,7 +8,7 @@ var disqus_shortname = ''; var disqus_url = ''; var disqus_title = ''; var disqus_identifier = ''; -var disqus_developer = ''; +var disqus_developer = 0; var disqus_def_name = ''; var disqus_def_email = ''; var disqus_config; @@ -31,11 +31,22 @@ Drupal.behaviors.disqus = { disqus_developer = settings.disqus.developer || 0; disqus_def_name = settings.disqus.name || ''; disqus_def_email = settings.disqus.email || ''; - if (settings.disqus.language || false) { - disqus_config = function() { + + // Language and SSO settings are passed in through disqus_config(). + disqus_config = function() { + if (settings.disqus.language || false) { this.language = settings.disqus.language; - }; - } + } + if (settings.disqus.remote_auth_s3 || false) { + this.page.remote_auth_s3 = settings.disqus.remote_auth_s3; + } + if (settings.disqus.api_key || false) { + this.page.api_key = settings.disqus.api_key; + } + if (settings.disqus.sso || false) { + this.sso = settings.disqus.sso; + } + }; // Make the AJAX call to get the Disqus comments. jQuery.ajax({ diff --git a/disqus.module b/disqus.module index 3ab7329..98d425b 100644 --- a/disqus.module +++ b/disqus.module @@ -53,6 +53,14 @@ function disqus_menu() { 'page arguments' => array('disqus_admin_settings'), 'file' => 'disqus.admin.inc', ); + $items['disqus/closewindow'] = array( + 'title' => 'Please wait', + 'description' => 'Once the user logs in through the Disqus login workflow, they are redirected here to automatically close the popup window.', + 'access arguments' => array('access content'), + 'page callback' => 'disqus_closewindow', + 'file' => 'disqus.admin.inc', + 'type' => MENU_CALLBACK, + ); return $items; } @@ -97,6 +105,60 @@ function disqus_element_post_render($children, &$element) { $disqus['language'] = $language->language; } + // Check if we are to provide Single Sign-On access. + if (variable_get('disqus_sso', FALSE)) { + $data = array(); + + // Inject the user data if it's available. + if ($user->uid > 0) { + $data['id'] = $user->uid; + $data['username'] = $user->name; + $data['email'] = $user->mail; + $data['url'] = url('user/' . $user->uid, array('absolute' => TRUE)); + + // Load the user's avatar. + $user_picture_default = variable_get('user_picture_default', ''); + if (isset($user->picture) && !empty($user->picture) && is_numeric($user->picture) && $file = file_load($user->picture)) { + $data['avatar'] = !empty($file->uri) ? $file->uri : NULL; + } + elseif (!empty($user_picture_default)) { + $data['avatar'] = variable_get('user_picture_default', ''); + } + if (isset($data['avatar'])) { + $data['avatar'] = file_create_url($data['avatar']); + } + } + + // Give Disqus information about the site. + $disqus['sso'] = array( + 'name' => variable_get('site_name', t('Drupal')), + // The login window must be closed once the user logs in. + 'url' => url('user/login', array('query' => array('destination' => 'disqus/closewindow'))), + // The logout link must redirect back to the original page. + 'logout' => url('user/logout', array('query' => array('destination' => $_GET['q']))), + 'width' => 800, + 'height' => 600, + ); + if ($logo = theme_get_setting('logo')) { + $disqus['sso']['button'] = $logo; + } + else { + $disqus['sso']['button'] = url('misc/druplicon.png', array('absolute' => TRUE)); + } + if ($favicon = theme_get_setting('favicon')) { + $disqus['sso']['icon'] = $favicon; + } + + // Encode the data to be sent off to Disqus. + $message = base64_encode(json_encode($data)); + $timestamp = time(); + $hmac = hash_hmac('sha1', "$message $timestamp", variable_get('disqus_secretkey', '')); + + // Stick the authentication requirements and data in the settings. + $disqus['remote_auth_s3'] = "$message $hmac $timestamp"; + $disqus['api_key'] = variable_get('disqus_publickey', ''); + } + // Add the disqus.js and all the settings to process the JavaScript and load Disqus. $element['#attached']['js'] = array( drupal_get_path('module', 'disqus') . '/disqus.js' => array(), -- 1.7.2.1