Created
May 30, 2018 18:21
-
-
Save crspybits/d8d34d18a08eab57c62a0b30f64c4f64 to your computer and use it in GitHub Desktop.
Cloudinary signature generation, in Swift-- using the CryptoSwift Cocoapod for SHA1 hash.
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
/* Experimenting with creating a signature to make it easier to do the server-side development. | |
See https://github.com/cloudinary/cloudinary_java/blob/master/cloudinary-core/src/main/java/com/cloudinary/Cloudinary.java#L129 | |
and https://support.cloudinary.com/hc/en-us/articles/203817991-How-to-generate-a-Cloudinary-signature-on-my-own- | |
*/ | |
// The optional timestamp is for testing this method-- this should be a UNIX timestamp with no trailing decimals-- i.e., just an integer number. | |
// Don't use "public_id" or "timestamp" as keys in otherParams if you give it. | |
func createSignature(publicId: String, apiSecret: String, otherParams: [String: Any]? = nil, timestamp: String? = nil) -> (signature: String, timestamp: String)? { | |
// 1) Set up the parameters we're going to use in the signing. | |
var params = [String: Any]() | |
if let otherParams = otherParams { | |
for (key, value) in otherParams { | |
params[key] = value | |
} | |
} | |
params["public_id"] = publicId | |
// "UNIX" timestamp | |
if let timestamp = timestamp { | |
params["timestamp"] = timestamp | |
} else { | |
params["timestamp"] = "\(Int(Date().timeIntervalSince1970))" | |
} | |
// 2) Sort the keys-- Cloudinary relies on the keys being sorted in ascending order before generating the signature. | |
let sortedKeys = params.keys.sorted(by: <) | |
var toSign:String = "" | |
// 3) Set up the key=value pairs, with intervening "&" between pairs, for signing | |
for key in sortedKeys { | |
if toSign.length > 0 { | |
toSign += "&" | |
} | |
let value = params[key]! | |
toSign += "\(key)=\(value)" | |
} | |
// 4) Cloudinary signature generation relies on the secret being appended to this sequence of key value pairs. | |
toSign += apiSecret | |
guard let toSignData = toSign.data(using: .utf8) else { | |
Log.error("Failed converting string to data.") | |
return nil | |
} | |
// 5) Generate the SHA1 hash. | |
let signedData = toSignData.sha1() | |
return (signedData.toHexString(), params["timestamp"] as! String) | |
} | |
func testSignatureCreation() { | |
/* From: https://support.cloudinary.com/hc/en-us/articles/203817991-How-to-generate-a-Cloudinary-signature-on-my-own- | |
Sanity check - Signing the following string: | |
"public_id=sample_image×tamp=1315060510abcd" | |
where `abcd` is the api_secret, should result with the following signature: | |
"b4ad47fb4e25c7bf5f92a20089f9db59bc302313" | |
*/ | |
let expectedResult = "b4ad47fb4e25c7bf5f92a20089f9db59bc302313" | |
guard let (signature, _) = createSignature(publicId: "sample_image", apiSecret: "abcd", timestamp: "1315060510") else { | |
XCTFail() | |
return | |
} | |
XCTAssert(expectedResult == signature) | |
} |
Sign up for free
to join this conversation on GitHub.
Already have an account?
Sign in to comment