Skip to content

Commit 5b25a3d

Browse files
committed
Merge branch 'signedurl'
2 parents 62028cb + 7da4550 commit 5b25a3d

File tree

2 files changed

+55
-4
lines changed

2 files changed

+55
-4
lines changed

cloudinary-core/src/main/java/com/cloudinary/Url.java

Lines changed: 31 additions & 3 deletions
Original file line numberDiff line numberDiff line change
@@ -2,10 +2,14 @@
22

33
import java.io.UnsupportedEncodingException;
44
import java.net.URLDecoder;
5+
import java.security.MessageDigest;
6+
import java.security.NoSuchAlgorithmException;
57
import java.util.Map;
68
import java.util.TreeMap;
79
import java.util.zip.CRC32;
810

11+
import org.apache.commons.codec.binary.Base64;
12+
import org.apache.commons.codec.binary.Hex;
913
import org.apache.commons.lang.StringUtils;
1014

1115
public class Url {
@@ -15,12 +19,14 @@ public class Url {
1519
String secureDistribution;
1620
boolean cdnSubdomain;
1721
boolean shorten;
22+
boolean signUrl;
1823
String cname;
1924
String type = "upload";
2025
String resourceType = "image";
2126
String format = null;
2227
String version = null;
2328
String source = null;
29+
String apiSecret = null;
2430
Transformation transformation = null;
2531

2632
public Url(Cloudinary cloudinary) {
@@ -31,6 +37,8 @@ public Url(Cloudinary cloudinary) {
3137
this.privateCdn = cloudinary.getBooleanConfig("private_cdn", false);
3238
this.cdnSubdomain = cloudinary.getBooleanConfig("cdn_subdomain", false);
3339
this.shorten = cloudinary.getBooleanConfig("shorten", false);
40+
this.signUrl = cloudinary.getBooleanConfig("sign_url", false);
41+
this.apiSecret = cloudinary.getStringConfig("api_secret");
3442
}
3543

3644
public Url type(String type) {
@@ -117,6 +125,11 @@ public Transformation transformation() {
117125
this.transformation = new Transformation();
118126
return this.transformation;
119127
}
128+
129+
public Url signed(boolean signUrl) {
130+
this.signUrl = signUrl;
131+
return this;
132+
}
120133

121134
public String generate(String source) {
122135
this.source = source;
@@ -178,9 +191,24 @@ public String generate() {
178191

179192
if (version != null)
180193
version = "v" + version;
181-
182-
return StringUtils.join(new String[] { prefix, resourceType, type, transformationStr, version, source }, "/").replaceAll(
183-
"([^:])\\/+", "$1/");
194+
195+
String rest = StringUtils.join(new String[] {transformationStr, version, source }, "/");
196+
rest = rest.replaceAll("^/+", "").replaceAll("([^:])\\/+", "$1/");
197+
198+
if (signUrl) {
199+
MessageDigest md = null;
200+
try {
201+
md = MessageDigest.getInstance("SHA-1");
202+
}
203+
catch(NoSuchAlgorithmException e) {
204+
throw new RuntimeException("Unexpected exception", e);
205+
}
206+
byte[] digest = md.digest((rest + apiSecret).getBytes());
207+
String signature = Base64.encodeBase64URLSafeString(digest);
208+
rest = "s--" + signature.substring(0, 8) + "--/" + rest;
209+
}
210+
211+
return StringUtils.join(new String[] { prefix, resourceType, type, rest }, "/").replaceAll("([^:])\\/+", "$1/");
184212
}
185213

186214
public String generateSpriteCss(String source) {

cloudinary-core/src/test/java/com/cloudinary/test/CloudinaryTest.java

Lines changed: 24 additions & 1 deletion
Original file line numberDiff line numberDiff line change
@@ -5,7 +5,6 @@
55

66
import java.io.UnsupportedEncodingException;
77
import java.net.URI;
8-
import java.net.URISyntaxException;
98
import java.net.URLDecoder;
109
import java.util.HashMap;
1110
import java.util.Map;
@@ -410,6 +409,30 @@ public void testEscapePublicId() {
410409
assertEquals("http://res.cloudinary.com/test123/image/upload/" + entry.getValue(), result);
411410
}
412411
}
412+
413+
@Test
414+
public void testSignedUrl() {
415+
// should correctly sign a url
416+
String expected = "http://res.cloudinary.com/test123/image/upload/s--MaRXzoEC--/c_crop,h_20,w_10/v1234/image.jpg";
417+
String actual = cloudinary.url().version(1234).
418+
transformation(new Transformation().crop("crop").width(10).height(20)).
419+
signed(true).
420+
generate("image.jpg");
421+
assertEquals(expected, actual);
422+
423+
expected = "http://res.cloudinary.com/test123/image/upload/s--ZlgFLQcO--/v1234/image.jpg";
424+
actual = cloudinary.url().version(1234).
425+
signed(true).
426+
generate("image.jpg");
427+
assertEquals(expected, actual);
428+
429+
expected = "http://res.cloudinary.com/test123/image/upload/s--Ai4Znfl3--/c_crop,h_20,w_10/image.jpg";
430+
actual = cloudinary.url().
431+
transformation(new Transformation().crop("crop").width(10).height(20)).
432+
signed(true).
433+
generate("image.jpg");
434+
assertEquals(expected, actual);
435+
}
413436

414437
public static Map<String, String> getUrlParameters(URI uri) throws UnsupportedEncodingException {
415438
Map<String, String> params = new HashMap<String, String>();

0 commit comments

Comments
 (0)