Last active
August 29, 2015 13:56
-
-
Save NullVoxPopuli/9095713 to your computer and use it in GitHub Desktop.
Authenticating to Box.com using Single Sign On in Ruby on Rails
This file contains hidden or bidirectional Unicode text that may be interpreted or compiled differently than what appears below. To review, open the file in an editor that reveals hidden Unicode characters.
Learn more about bidirectional Unicode characters
# https://github.com/assistly/multipass-examples/blob/master/ruby.rb | |
module DeskSSO | |
# http://dev.desk.com/guides/sso/#enable | |
def self.build_url(user) | |
json = { | |
uid: user.id, | |
expires: (DateTime.now + 10.years).iso8601, | |
customer_email: user.email, | |
customer_name: user.name | |
} | |
return self.multipass_callback_url(json.to_json) | |
end | |
def self.multipass_callback_url(json) | |
multipass = self.multipass(json) | |
signature = self.signature(multipass) | |
# URL escape the final multipass and signature parameters | |
multipass = CGI.escape(multipass) | |
signature = CGI.escape(signature) | |
url = "https://" | |
url << self.desk["domain"] | |
url << "/customer/authentication/multipass/callback?multipass=" | |
url << multipass | |
url << "&signature=" | |
url << signature | |
return url | |
end | |
private | |
# Encrypt the hash using AES128-cbc encryption with your site key as the password | |
# and your api key as the salt. Use a block size of 16 bytes and make sure to pad | |
# the hash using this block size. You can see this in detail on our PHP code example | |
# Base64 encode the result | |
# Convert to a URL safe string by performing the following | |
# - Remove any newlines | |
# - Remove trailing equal (=) characters | |
# - Change any plus (+) characters to dashes (-) | |
# - Change any slashes (/) characters to underscores (_) | |
def self.multipass(json) | |
cipher = OpenSSL::Cipher::AES.new(128, :CBC) | |
cipher.encrypt # cipher is now in encryption mode | |
# Create the encryption key using a 16 byte SHA1 digest of your api key and subdomain | |
key = Digest::SHA1.digest(self.desk["api_key"] + self.desk["subdomain"])[0...16] | |
# key = cipher.pkcs5_keyivgen(self.desk["api_key"], self.desk["subdomain"]) | |
# key = Digest::SHA1.digest(key)[0..16] | |
# key = OpenSSL::PKCS5.pbkdf2_hmac_sha1(self.desk["api_key"], self.desk["subdomain"], 1000, 16) | |
# Generate a random 16 byte IV | |
iv = OpenSSL::Random.random_bytes(16) | |
cipher.key = key | |
cipher.iv = iv | |
encrypted = cipher.update(json) + cipher.final | |
# Prepend encrypted data with the IV | |
prepended = iv + encrypted | |
Base64.encode64(prepended) | |
end | |
# Build a SHA1 HMAC using your multipass api key and your finished multipass token. | |
# Base64 encode the resulting HMAC. | |
def self.signature(multipass) | |
Base64.encode64(OpenSSL::HMAC.digest("sha1", self.desk["api_key"], multipass)) | |
end | |
# shortcut | |
def self.desk; IntegrationsConfig["desk"]; end | |
end |
Sign up for free
to join this conversation on GitHub.
Already have an account?
Sign in to comment