Skip to content

Instantly share code, notes, and snippets.

@NullVoxPopuli
Last active August 29, 2015 13:56
Show Gist options
  • Save NullVoxPopuli/9095713 to your computer and use it in GitHub Desktop.
Save NullVoxPopuli/9095713 to your computer and use it in GitHub Desktop.
Authenticating to Box.com using Single Sign On in Ruby on Rails
# 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