Created
February 14, 2015 01:22
-
-
Save csoma/a24f0e7b32f3faf387ee to your computer and use it in GitHub Desktop.
Desk.com integration in scala
This file contains 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
// Desk.com integration based on http://dev.desk.com/guides/sso/ | |
// License: Public domain | |
import scala.util.parsing.json.JSONObject | |
import org.apache.commons.codec.binary.Base64 | |
import java.util.Arrays | |
import java.text.DateFormat | |
import java.text.SimpleDateFormat | |
import java.util.Date | |
import java.net.URLEncoder | |
import java.security.MessageDigest | |
import java.security.SecureRandom | |
import javax.crypto.Cipher | |
import javax.crypto.Mac | |
import javax.crypto.spec.IvParameterSpec | |
import javax.crypto.spec.SecretKeySpec | |
/** | |
Create redirect URL for Desk.com "Private Access / Multipass SSO" | |
Usage: | |
val desk = new DeskDotCom("yoursite", "xxxx") | |
val url = desk.loginURL("test123", "[email protected]", "John Smith", "co12", "Example Inc") | |
redirect(url) // the url format returned: "https://yoursite.desk.com/..." | |
If you're using custom fields, they have to be created first in the admin console: | |
https://yoursite.desk.com/admin/case-management/customer-settings/custom-fields | |
Name=CompanyID key=companyid Type=Text | |
Name=Company key=company Type=text | |
*/ | |
class DeskDotCom(siteKeyOrig: String, apiKey:String) { | |
protected val siteKey: String = siteKeyOrig.toLowerCase | |
def loginURL(custUid:String, custEmail:String, custName:String, custCompanyID:String="", custCompanyName:String=""): String = { | |
val salted: String = apiKey + siteKey | |
val md: MessageDigest = MessageDigest.getInstance("SHA1") | |
md.update(salted.getBytes("utf-8")) | |
val digest: Array[Byte] = md.digest() | |
val key: SecretKeySpec = new SecretKeySpec(Arrays.copyOfRange(digest, 0, 16), "AES") | |
val iv: Array[Byte] = new Array[Byte](16) | |
val random: SecureRandom = new SecureRandom() | |
random.nextBytes(iv) | |
val df: DateFormat = new SimpleDateFormat("yyyy-MM-dd'T'HH:mmZ") | |
var userMap: Map[String, String] = Map() | |
userMap += ("uid"-> custUid) | |
userMap += ("expires" -> df.format(new Date(new Date().getTime() + 300000))) | |
userMap += ("customer_email" -> custEmail) | |
userMap += ("customer_name" -> custName) | |
if (!custCompanyID.isEmpty) userMap += ("customer_custom_companyid"-> custCompanyID) | |
if (!custCompanyName.isEmpty) userMap += ("customer_custom_company" -> custCompanyName) | |
val data = JSONObject( userMap ).toString() | |
val aes = Cipher.getInstance("AES/CBC/PKCS5Padding") | |
val ivSpec = new IvParameterSpec(iv) | |
aes.init(Cipher.ENCRYPT_MODE, key, ivSpec) | |
val encrypted: Array[Byte] = aes.doFinal(data.getBytes("utf-8")) | |
val combined: Array[Byte] = new Array(iv.length + encrypted.length) | |
System.arraycopy(iv, 0, combined, 0, iv.length) | |
System.arraycopy(encrypted, 0, combined, iv.length, encrypted.length) | |
val multipass: Array[Byte] = Base64.encodeBase64(combined) | |
val apiKeyEnc: SecretKeySpec = new SecretKeySpec(apiKey.getBytes("utf-8"), "HmacSHA1") | |
val hmac: Mac = Mac.getInstance("HmacSHA1") | |
hmac.init(apiKeyEnc) | |
val rawHmac: Array[Byte] = hmac.doFinal(multipass) | |
val signature: Array[Byte] = Base64.encodeBase64(rawHmac) | |
val encodeType = "UTF-8" | |
val multipassString = URLEncoder.encode(new String(multipass), encodeType) | |
val signatureString = URLEncoder.encode(new String(signature), encodeType) | |
val url = "https://" + siteKey + | |
".desk.com/customer/authentication/multipass/callback?multipass=" + | |
multipassString + "&signature=" + signatureString | |
return url | |
} | |
} |
Sign up for free
to join this conversation on GitHub.
Already have an account?
Sign in to comment