2020package com .cloud .utils ;
2121
2222import java .io .File ;
23- import java .util .Arrays ;
23+ import java .net .URL ;
24+ import java .security .InvalidKeyException ;
25+ import java .security .NoSuchAlgorithmException ;
26+ import java .security .SignatureException ;
2427import java .util .Map ;
28+ import java .util .Arrays ;
29+ import java .util .HashMap ;
30+ import java .util .Formatter ;
2531
2632import org .apache .log4j .Logger ;
2733
2834import com .cloud .utils .exception .CloudRuntimeException ;
2935import com .cloud .utils .script .OutputInterpreter ;
3036import com .cloud .utils .script .Script ;
3137
38+ import javax .crypto .Mac ;
39+ import javax .crypto .spec .SecretKeySpec ;
40+
3241public class SwiftUtil {
3342 private static Logger logger = Logger .getLogger (SwiftUtil .class );
3443 private static final long SWIFT_MAX_SIZE = 5L * 1024L * 1024L * 1024L ;
44+ private static final String HMAC_SHA1_ALGORITHM = "HmacSHA1" ;
45+
46+
3547
3648 public interface SwiftClientCfg {
3749 String getAccount ();
@@ -143,8 +155,7 @@ public static String[] list(SwiftClientCfg swift, String container, String rFile
143155 OutputInterpreter .AllLinesParser parser = new OutputInterpreter .AllLinesParser ();
144156 String result = command .execute (parser );
145157 if (result == null && parser .getLines () != null && !parser .getLines ().equalsIgnoreCase ("" )) {
146- String [] lines = parser .getLines ().split ("\\ n" );
147- return lines ;
158+ return parser .getLines ().split ("\\ n" );
148159 } else {
149160 if (result != null ) {
150161 String errMsg = "swiftList failed , err=" + result ;
@@ -161,7 +172,7 @@ public static File getObject(SwiftClientCfg cfg, File destDirectory, String swif
161172 int firstIndexOfSeparator = swiftPath .indexOf (File .separator );
162173 String container = swiftPath .substring (0 , firstIndexOfSeparator );
163174 String srcPath = swiftPath .substring (firstIndexOfSeparator + 1 );
164- String destFilePath = null ;
175+ String destFilePath ;
165176 if (destDirectory .isDirectory ()) {
166177 destFilePath = destDirectory .getAbsolutePath () + File .separator + srcPath ;
167178 } else {
@@ -171,7 +182,7 @@ public static File getObject(SwiftClientCfg cfg, File destDirectory, String swif
171182 Script command = new Script ("/bin/bash" , logger );
172183 command .add ("-c" );
173184 command .add ("/usr/bin/python " + swiftCli + " -A " + cfg .getEndPoint () + " -U " + cfg .getAccount () + ":" + cfg .getUserName () + " -K " + cfg .getKey () +
174- " download " + container + " " + srcPath + " -o " + destFilePath );
185+ " download " + container + " " + srcPath + " -o " + destFilePath );
175186 OutputInterpreter .AllLinesParser parser = new OutputInterpreter .AllLinesParser ();
176187 String result = command .execute (parser );
177188 if (result != null ) {
@@ -236,4 +247,59 @@ public static boolean deleteObject(SwiftClientCfg cfg, String path) {
236247 command .execute (parser );
237248 return true ;
238249 }
250+
251+ public static boolean setTempKey (SwiftClientCfg cfg , String tempKey ){
252+
253+ Map <String , String > tempKeyMap = new HashMap <>();
254+ tempKeyMap .put ("Temp-URL-Key" , tempKey );
255+ return postMeta (cfg , "" , "" , tempKeyMap );
256+
257+ }
258+
259+ public static URL generateTempUrl (SwiftClientCfg cfg , String container , String object , String tempKey , int urlExpirationInterval ) {
260+
261+ int currentTime = (int ) (System .currentTimeMillis () / 1000L );
262+ int expirationSeconds = currentTime + urlExpirationInterval ;
263+
264+ try {
265+
266+ URL endpoint = new URL (cfg .getEndPoint ());
267+ String method = "GET" ;
268+ String path = String .format ("/v1/AUTH_%s/%s/%s" , cfg .getAccount (), container , object );
269+
270+ //sign the request
271+ String hmacBody = String .format ("%s\n %d\n %s" , method , expirationSeconds , path );
272+ String signature = calculateRFC2104HMAC (hmacBody , tempKey );
273+ path += String .format ("?temp_url_sig=%s&temp_url_expires=%d" , signature , expirationSeconds );
274+
275+ //generate the temp url
276+ URL tempUrl = new URL (endpoint .getProtocol (), endpoint .getHost (), endpoint .getPort (), path );
277+
278+ return tempUrl ;
279+
280+ } catch (Exception e ) {
281+ logger .error (e .getMessage ());
282+ throw new CloudRuntimeException (e .getMessage ());
283+ }
284+
285+ }
286+
287+ public static String calculateRFC2104HMAC (String data , String key )
288+ throws SignatureException , NoSuchAlgorithmException , InvalidKeyException {
289+
290+ SecretKeySpec signingKey = new SecretKeySpec (key .getBytes (), HMAC_SHA1_ALGORITHM );
291+ Mac mac = Mac .getInstance (HMAC_SHA1_ALGORITHM );
292+ mac .init (signingKey );
293+ return toHexString (mac .doFinal (data .getBytes ()));
294+
295+ }
296+
297+ public static String toHexString (byte [] bytes ) {
298+
299+ Formatter formatter = new Formatter ();
300+ for (byte b : bytes ) {
301+ formatter .format ("%02x" , b );
302+ }
303+ return formatter .toString ();
304+ }
239305}
0 commit comments