From a840c4ad53f6075f3b562ed4346a319e72b852b9 Mon Sep 17 00:00:00 2001 From: Rob Loach Date: Wed, 6 Apr 2011 16:56:51 -0400 Subject: [PATCH] Issue #423684: Disqus Single Sign-On for Drupal. --- disqus.admin.inc | 46 ++++++++++++++++++++++++++++++++++--- disqus.install | 3 ++ disqus.js | 19 +++++++++++---- disqus.module | 65 +++++++++++++++++++++++++++++++++++++++++++++++++++-- 4 files changed, 121 insertions(+), 12 deletions(-) diff --git a/disqus.admin.inc b/disqus.admin.inc index b67892a..ec15728 100644 --- a/disqus.admin.inc +++ b/disqus.admin.inc @@ -11,6 +11,7 @@ function disqus_admin_settings() { '#description' => t('The domain that you registered Disqus with. If you registered http://example.disqus.com, you would enter "example" here.'), '#default_value' => variable_get('disqus_domain', ''), ); + // Visibility settings. $form['visibility'] = array( '#type' => 'fieldset', '#title' => t('Visibility'), @@ -42,29 +43,66 @@ function disqus_admin_settings() { '#default_value' => variable_get('disqus_weight', 50), '#options' => drupal_map_assoc(array(-100, -75, -50, -25, 0, 25, 50, 75, 100)), ); - $form['disqus_behavior'] = array( + // Behavior settings. + $form['behavior'] = array( '#type' => 'fieldset', '#title' => t('Behavior'), '#collapsed' => TRUE, '#collapsible' => TRUE, ); - $form['disqus_behavior']['disqus_userapikey'] = array( + $form['behavior']['disqus_userapikey'] = array( '#type' => 'textfield', '#title' => t('User API Key'), '#description' => t('The API key of the administrator account on Disqus. You can get yours here.', array('@key' => 'http://disqus.com/api/get_my_key/')), '#default_value' => variable_get('disqus_userapikey', ''), ); - $form['disqus_behavior']['disqus_localization'] = array( + $form['behavior']['disqus_localization'] = array( '#type' => 'checkbox', '#title' => t('Localization support'), '#description' => t("When enabled, overrides the language set by Disqus with the language provided by the site."), '#default_value' => variable_get('disqus_localization', FALSE), ); - $form['disqus_behavior']['disqus_developer'] = array( + $form['behavior']['disqus_developer'] = array( '#type' => 'checkbox', '#title' => t('Testing'), '#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'), + '#collapsed' => TRUE, + '#collapsible' => TRUE, + '#description' => t('Use these settings to configure the more advanced uses of Disqus. You can find ore 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), + ); 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.install b/disqus.install index 4abe791..819d75d 100644 --- a/disqus.install +++ b/disqus.install @@ -13,6 +13,9 @@ function disqus_uninstall() { variable_del('disqus_userapikey'); variable_del('disqus_nodetypes'); variable_del('disqus_developer'); + variable_del('disqus_sso'); + variable_del('disqus_secretkey'); + variable_del('disqus_publickey'); drupal_uninstall_schema('disqus'); } diff --git a/disqus.js b/disqus.js index 2ad38aa..50512c5 100644 --- a/disqus.js +++ b/disqus.js @@ -39,12 +39,21 @@ Drupal.behaviors.disqus = function(context) { disqus_def_name = disqus.name || null; disqus_def_email = disqus.email || null; - // Assign the language. - if (disqus.language || false) { - disqus_config = function() { + // Language and SSO settings are passed in through disqus_config(). + disqus_config = function() { + if (disqus.language || false) { this.language = disqus.language; - }; - } + } + if (disqus.remote_auth_s3 || false) { + this.page.remote_auth_s3 = disqus.remote_auth_s3; + } + if (disqus.api_key || false) { + this.page.api_key = disqus.api_key; + } + if (disqus.sso || false) { + this.sso = disqus.sso; + } + }; // Make the AJAX call for the comment thread. jQuery.ajax({ diff --git a/disqus.module b/disqus.module index 6960357..ac04e80 100644 --- a/disqus.module +++ b/disqus.module @@ -47,6 +47,14 @@ function disqus_menu() { 'description' => 'Provides general configuration options for the Disqus comment system.', 'weight' => -10, ); + $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; } @@ -160,9 +168,9 @@ function disqus_form_alter(&$form, $form_state, $form_id) { $form['comment_settings']['disqus'] = array( '#tree' => TRUE, 'status' => array( - '#type' => 'checkbox', - '#title' => t('Enable Disqus comments'), - '#default_value' => isset($node->disqus['status']) ? $node->disqus['status'] : TRUE, + '#type' => 'checkbox', + '#title' => t('Enable Disqus comments'), + '#default_value' => isset($node->disqus['status']) ? $node->disqus['status'] : TRUE, ), ); } @@ -426,6 +434,57 @@ function disqus_footer($main = 0, $options = NULL) { $settings['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)) { + $data['avatar'] = url($user->picture, array('absolute' => TRUE)); + } + elseif (!empty($user_picture_default)) { + $data['avatar'] = url($user_picture_default, array('absolute' => TRUE)); + } + } + + // Give Disqus information about the site. + $settings['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('logout', array('query' => array('destination' => $_GET['q']))), + 'width' => 800, + 'height' => 600, + ); + if ($logo = theme_get_setting('logo')) { + $settings['sso']['button'] = $logo; + } + else { + $settings['sso']['button'] = url('misc/druplicon.png', array('absolute' => TRUE)); + } + if ($favicon = theme_get_setting('favicon')) { + $settings['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. + $settings['remote_auth_s3'] = "$message $hmac $timestamp"; + $settings['api_key'] = variable_get('disqus_publickey', ''); + } + // Add the JavaScript. drupal_add_js(array( 'disqus' => $settings, -- 1.7.2.1