1 package ch
.cyberduck
.core
.openstack
;
4 * Copyright (c) 2002-2013 David Kocher. All rights reserved.
7 * This program is free software; you can redistribute it and/or modify
8 * it under the terms of the GNU General Public License as published by
9 * the Free Software Foundation; either version 2 of the License, or
10 * (at your option) any later version.
12 * This program is distributed in the hope that it will be useful,
13 * but WITHOUT ANY WARRANTY; without even the implied warranty of
14 * MERCHANTABILITY or FITNESS FOR A PARTICULAR PURPOSE. See the
15 * GNU General Public License for more details.
17 * Bug fixes, suggestions and comments should be sent to feedback@cyberduck.ch
20 import ch
.cyberduck
.core
.Credentials
;
21 import ch
.cyberduck
.core
.DescriptiveUrl
;
22 import ch
.cyberduck
.core
.DescriptiveUrlBag
;
23 import ch
.cyberduck
.core
.HostPasswordStore
;
24 import ch
.cyberduck
.core
.LocaleFactory
;
25 import ch
.cyberduck
.core
.PasswordStoreFactory
;
26 import ch
.cyberduck
.core
.Path
;
27 import ch
.cyberduck
.core
.PathContainerService
;
28 import ch
.cyberduck
.core
.Scheme
;
29 import ch
.cyberduck
.core
.UserDateFormatterFactory
;
31 import org
.apache
.commons
.lang3
.StringUtils
;
32 import org
.apache
.log4j
.Logger
;
35 import java
.text
.MessageFormat
;
36 import java
.util
.Arrays
;
37 import java
.util
.Collections
;
39 import ch
.iterate
.openstack
.swift
.model
.AccountInfo
;
40 import ch
.iterate
.openstack
.swift
.model
.Region
;
45 public class SwiftHpUrlProvider
extends SwiftUrlProvider
{
46 private static final Logger log
= Logger
.getLogger(SwiftUrlProvider
.class);
48 private PathContainerService containerService
49 = new SwiftPathContainerService();
51 private HostPasswordStore store
;
53 private SwiftSession session
;
55 public SwiftHpUrlProvider(final SwiftSession session
) {
56 this(session
, PasswordStoreFactory
.get());
59 public SwiftHpUrlProvider(final SwiftSession session
, final HostPasswordStore store
) {
60 super(session
, Collections
.<Region
, AccountInfo
>emptyMap());
61 this.session
= session
;
66 protected DescriptiveUrlBag
sign(final Region region
, final Path file
, final long expiry
) {
67 final String path
= region
.getStorageUrl(
68 containerService
.getContainer(file
).getName(), containerService
.getKey(file
)).getRawPath();
69 final Credentials credentials
= session
.getHost().getCredentials();
70 if(StringUtils
.contains(credentials
.getUsername(), ':')) {
71 if(log
.isInfoEnabled()) {
72 log
.info("Using account secret key to sign");
74 final String tenant
= StringUtils
.split(credentials
.getUsername(), ':')[0];
75 final String accesskey
= StringUtils
.split(credentials
.getUsername(), ':')[1];
76 // HP Cloud Object Storage Temporary URLs require the user's Tenant ID and Access Key ID
77 // to be prepended to the signature. Using the secret key to sign.
78 final String secret
= store
.find(session
.getHost());
79 if(StringUtils
.isBlank(secret
)) {
80 log
.warn("No secret found in keychain required to sign temporary URL");
81 return DescriptiveUrlBag
.empty();
83 final String body
= String
.format("GET\n%d\n%s", expiry
, path
);
84 final String signature
= String
.format("%s:%s:%s", tenant
, accesskey
, this.sign(secret
, body
));
85 //Compile the temporary URL
86 final DescriptiveUrlBag list
= new DescriptiveUrlBag();
87 for(Scheme scheme
: Arrays
.asList(Scheme
.http
, Scheme
.https
)) {
88 list
.add(new DescriptiveUrl(URI
.create(String
.format("%s://%s%s?temp_url_sig=%s&temp_url_expires=%d",
89 scheme
.name(), region
.getStorageUrl().getHost(), path
, signature
, expiry
)),
90 DescriptiveUrl
.Type
.signed
,
91 MessageFormat
.format(LocaleFactory
.localizedString("{0} URL"), LocaleFactory
.localizedString("Signed", "S3"))
92 + " (" + MessageFormat
.format(LocaleFactory
.localizedString("Expires {0}", "S3") + ")",
93 UserDateFormatterFactory
.get().getShortFormat(expiry
))
99 log
.warn("Missing tenant in user credentials to sign temporary URL");
100 return DescriptiveUrlBag
.empty();