bhubbard
9/2/2015 - 11:57 PM

WordPress - Desk.com Multipass SSO Plugin

WordPress - Desk.com Multipass SSO Plugin

<?php
/**
 * Plugin Name: Desk.com Multipass
 * Plugin URI: https://github.com/tstachl/wp-desk_multipass
 * Description: A WordPress plugin to add a menu option that redirects to your Desk.com Support Site.
 * Version: 1.0.0
 * Author: Thomas Stachl
 * Author URI: https://github.com/tstachl
 * License: BSD 3-Clause License
 */
defined('ABSPATH') or die('No script kiddies please!');

add_action('admin_init', function() {
  register_setting('general', 'desk-domain', 'esc_attr');
  register_setting('general', 'desk-site_name', 'esc_attr');
  register_setting('general', 'desk-api_key', 'esc_attr');

  add_settings_section('desk-section', 'Desk.com Settings', function() {
    echo '<p>Specify the Multipass/SSO settings for your Desk.com Account.</p>';
  }, 'general');

  add_settings_field('desk-domain', '<label for="desk-domain">Domain</label>', function() {
    $value = get_option('desk-domain', '');
    echo '<input type="url" name="desk-domain" id="desk-domain" value="' . $value . '" class="regular-text ltr">';
    echo '<p class="description">This is your Desk.com domain (https://example.desk.com), if you have a CNAME set up use your domain (https://support.example.com).</p>';
  }, 'general', 'desk-section');

  add_settings_field('desk-site_name', '<label for="desk-site_name">Site Name</label>', function() {
    $value = get_option('desk-site_name', '');
    echo '<input type="text" name="desk-site_name" id="desk-site_name" value="' . $value . '" class="regular-text ltr">';
    echo '<p class="description">This is your Desk.com site name, eg: YOURSITENAME.desk.com, without .desk.com.</p>';
  }, 'general', 'desk-section');
  
  add_settings_field('desk-api_key', '<label for="desk-api_key">Multipass Key</label>', function() {
    $value = get_option('desk-api_key', '');
    echo '<input type="text" name="desk-api_key" id="desk-api_key" value="' . $value . '" class="regular-text ltr">';
    echo '<p class="description">This is your Multipass Key, you can find it in Admin -> Channels -> Support Center -> Private Access.</p>';
  }, 'general', 'desk-section');
});

add_action('admin_menu', function() {
  $site_name = get_option('desk-site_name');
  $api_key   = get_option('desk-api_key');
  $domain    = get_option('desk-domain');

  if ($site_name == '' || $api_key == '' || $domain == '') return;
  
  // hack submenu
  $hook = add_submenu_page('tools.php', 'Support', 'Support', 'read', 'desk-support', function() {});
  add_action("load-$hook", function() { 
    $site_name = get_option('desk-site_name');
    $api_key   = get_option('desk-api_key');
    $domain    = get_option('desk-domain');
    
    // Create the encryption key using a 16 byte SHA1 digest of your api key and subdomain
    $salted = $api_key . $site_name;
    $digest = hash('sha1', $salted, true);
    $key    = substr($digest, 0, 16);

    // Generate a random 16 byte IV
    $iv = mcrypt_create_iv(16);

    // Build json data
    $current_user = wp_get_current_user();
    $user_data = array(
      'uid' => $current_user->ID,
      'customer_email' => $current_user->user_email,
      'customer_name' => $current_user->display_name,
      'expires' => date('c', strtotime('+5 minutes'))
    );
    $data = json_encode($user_data);
    
    // PHP's mcrypt library does not perform padding by default
    // Pad using standard PKCS#5 padding with block size of 16 bytes
    $pad = 16 - (strlen($data) % 16);
    $data = $data . str_repeat(chr($pad), $pad);

    // Encrypt data using AES128-cbc
    $cipher = mcrypt_module_open(MCRYPT_RIJNDAEL_128, '', 'cbc', '');
    mcrypt_generic_init($cipher, $key, $iv);
    $multipass = mcrypt_generic($cipher, $data);
    mcrypt_generic_deinit($cipher);

    // Prepend the IV to the encrypted data
    // This will be extracted and used for decryption
    $multipass = $iv . $multipass;

    // Base64 encode the encrypted data
    $multipass = base64_encode($multipass);

    // Build an HMAC-SHA1 signature using the encoded string and your api key
    $signature = hash_hmac('sha1', $multipass, $api_key, true);
    // Base64 encode the signature
    $signature = base64_encode($signature);

    // Finally, URL encode the multipass and signature
    $multipass = urlencode($multipass);
    $signature = urlencode($signature);

    wp_redirect("$domain/customer/authentication/multipass/callback?multipass=$multipass&signature=$signature", 302);
  });
});