mirror of https://github.com/apache/jclouds.git
Added a set of changes as requested by Adrian
This commit is contained in:
parent
b6d106c7a1
commit
2b8e2a4c01
|
@ -21,16 +21,13 @@ package org.jclouds.cloudstack.features;
|
||||||
import com.google.common.util.concurrent.ListenableFuture;
|
import com.google.common.util.concurrent.ListenableFuture;
|
||||||
import org.jclouds.cloudstack.domain.Account;
|
import org.jclouds.cloudstack.domain.Account;
|
||||||
import org.jclouds.cloudstack.domain.LoginResponse;
|
import org.jclouds.cloudstack.domain.LoginResponse;
|
||||||
import org.jclouds.cloudstack.functions.HashToMD5;
|
|
||||||
import org.jclouds.rest.annotations.ExceptionParser;
|
import org.jclouds.rest.annotations.ExceptionParser;
|
||||||
import org.jclouds.rest.annotations.ParamParser;
|
|
||||||
import org.jclouds.rest.annotations.QueryParams;
|
import org.jclouds.rest.annotations.QueryParams;
|
||||||
import org.jclouds.rest.annotations.SelectJson;
|
import org.jclouds.rest.annotations.SelectJson;
|
||||||
import org.jclouds.rest.functions.ReturnNullOnNotFoundOr404;
|
import org.jclouds.rest.functions.ReturnNullOnNotFoundOr404;
|
||||||
import org.jclouds.rest.functions.ReturnVoidOnNotFoundOr404;
|
import org.jclouds.rest.functions.ReturnVoidOnNotFoundOr404;
|
||||||
|
|
||||||
import javax.ws.rs.Consumes;
|
import javax.ws.rs.Consumes;
|
||||||
import javax.ws.rs.CookieParam;
|
|
||||||
import javax.ws.rs.GET;
|
import javax.ws.rs.GET;
|
||||||
import javax.ws.rs.HeaderParam;
|
import javax.ws.rs.HeaderParam;
|
||||||
import javax.ws.rs.QueryParam;
|
import javax.ws.rs.QueryParam;
|
||||||
|
@ -49,30 +46,18 @@ import javax.ws.rs.core.MediaType;
|
||||||
public interface SessionAsyncClient {
|
public interface SessionAsyncClient {
|
||||||
|
|
||||||
/**
|
/**
|
||||||
* @see SessionClient#loginWithHashedPassword
|
* @see SessionClient#loginUserInDomainWithHashOfPassword
|
||||||
*/
|
*/
|
||||||
@GET
|
@GET
|
||||||
@QueryParams(keys = "command", values = "login")
|
@QueryParams(keys = "command", values = "login")
|
||||||
@SelectJson("loginresponse")
|
@SelectJson("loginresponse")
|
||||||
@Consumes(MediaType.APPLICATION_JSON)
|
@Consumes(MediaType.APPLICATION_JSON)
|
||||||
@ExceptionParser(ReturnNullOnNotFoundOr404.class)
|
@ExceptionParser(ReturnNullOnNotFoundOr404.class)
|
||||||
ListenableFuture<LoginResponse> loginWithHashedPassword(@QueryParam("username") String userName,
|
ListenableFuture<LoginResponse> loginUserInDomainWithHashOfPassword(@QueryParam("username") String userName,
|
||||||
@QueryParam("password") String hashedPassword, @QueryParam("domain") String domainOrEmpty);
|
@QueryParam("domain") String domain, @QueryParam("password") String hashedPassword);
|
||||||
|
|
||||||
/**
|
/**
|
||||||
* @see SessionClient#loginWithPlainTextPassword
|
* @see SessionClient#getAccountByNameUsingSession
|
||||||
*/
|
|
||||||
@GET
|
|
||||||
@QueryParams(keys = "command", values = "login")
|
|
||||||
@SelectJson("loginresponse")
|
|
||||||
@Consumes(MediaType.APPLICATION_JSON)
|
|
||||||
@ExceptionParser(ReturnNullOnNotFoundOr404.class)
|
|
||||||
ListenableFuture<LoginResponse> loginWithPlainTextPassword(@QueryParam("username") String userName,
|
|
||||||
@QueryParam("password") @ParamParser(HashToMD5.class) String plainTextPassword,
|
|
||||||
@QueryParam("domain") String domainOrEmpty);
|
|
||||||
|
|
||||||
/**
|
|
||||||
* @see SessionClient#getAccountByName
|
|
||||||
*/
|
*/
|
||||||
@GET
|
@GET
|
||||||
@QueryParams(keys = "comand", values = "listAccounts")
|
@QueryParams(keys = "comand", values = "listAccounts")
|
||||||
|
@ -80,14 +65,14 @@ public interface SessionAsyncClient {
|
||||||
@Consumes(MediaType.APPLICATION_JSON)
|
@Consumes(MediaType.APPLICATION_JSON)
|
||||||
@ExceptionParser(ReturnNullOnNotFoundOr404.class)
|
@ExceptionParser(ReturnNullOnNotFoundOr404.class)
|
||||||
@HeaderParam(HttpHeaders.COOKIE)
|
@HeaderParam(HttpHeaders.COOKIE)
|
||||||
ListenableFuture<Account> getAccountByName(@QueryParam("name") String accountName,
|
ListenableFuture<Account> getAccountByNameUsingSession(@QueryParam("name") String accountName,
|
||||||
@CookieParam("sessionKey") @QueryParam("sessionkey") String sessionKey);
|
@QueryParam("sessionkey") String sessionKey);
|
||||||
|
|
||||||
/**
|
/**
|
||||||
* @see SessionClient#logout
|
* @see SessionClient#logoutUser
|
||||||
*/
|
*/
|
||||||
@GET
|
@GET
|
||||||
@QueryParams(keys = "command", values = "logout")
|
@QueryParams(keys = "command", values = "logout")
|
||||||
@ExceptionParser(ReturnVoidOnNotFoundOr404.class)
|
@ExceptionParser(ReturnVoidOnNotFoundOr404.class)
|
||||||
ListenableFuture<Void> logout(@QueryParam("sessionkey") String sessionKey);
|
ListenableFuture<Void> logoutUser(@QueryParam("sessionkey") String sessionKey);
|
||||||
}
|
}
|
||||||
|
|
|
@ -39,32 +39,18 @@ public interface SessionClient {
|
||||||
* cookie value that can be passed in subsequent Query command calls until the "logout"
|
* cookie value that can be passed in subsequent Query command calls until the "logout"
|
||||||
* command has been issued or the session has expired.
|
* command has been issued or the session has expired.
|
||||||
*
|
*
|
||||||
* @param userName
|
*
|
||||||
* user account name
|
|
||||||
* @param hashedPassword
|
|
||||||
* hashed password (by default MD5)
|
|
||||||
* @param domainOrEmpty
|
|
||||||
* domain name, if empty defaults to ROOT
|
|
||||||
* @return
|
|
||||||
* login response with session key or null
|
|
||||||
*/
|
|
||||||
LoginResponse loginWithHashedPassword(String userName, String hashedPassword, String domainOrEmpty);
|
|
||||||
|
|
||||||
/**
|
|
||||||
* Logs a user into Cloudstack. A successful login attempt will generate a session key
|
|
||||||
* cookie value that can be passed in subsequent Query command calls until the "logout"
|
|
||||||
* command has been issued or the session has expired.
|
|
||||||
*
|
*
|
||||||
* @param userName
|
* @param userName
|
||||||
* user account name
|
* user account name
|
||||||
* @param plainTextPassword
|
* @param domain
|
||||||
* plain text password
|
|
||||||
* @param domainOrEmpty
|
|
||||||
* domain name, if empty defaults to ROOT
|
* domain name, if empty defaults to ROOT
|
||||||
|
* @param hashedPassword
|
||||||
|
* hashed password (by default MD5)
|
||||||
* @return
|
* @return
|
||||||
* login response with session key or null
|
* login response with session key or null
|
||||||
*/
|
*/
|
||||||
LoginResponse loginWithPlainTextPassword(String userName, String plainTextPassword, String domainOrEmpty);
|
LoginResponse loginUserInDomainWithHashOfPassword(String userName, String domain, String hashedPassword);
|
||||||
|
|
||||||
/**
|
/**
|
||||||
* Retrieve an account by name using the session key for login
|
* Retrieve an account by name using the session key for login
|
||||||
|
@ -76,7 +62,7 @@ public interface SessionClient {
|
||||||
* @return
|
* @return
|
||||||
* account instance or null
|
* account instance or null
|
||||||
*/
|
*/
|
||||||
Account getAccountByName(String accountName, String sessionKey);
|
Account getAccountByNameUsingSession(String accountName, String sessionKey);
|
||||||
|
|
||||||
/**
|
/**
|
||||||
* Logs out the user by invalidating the session key
|
* Logs out the user by invalidating the session key
|
||||||
|
@ -84,6 +70,6 @@ public interface SessionClient {
|
||||||
* @param sessionKey
|
* @param sessionKey
|
||||||
* user session key
|
* user session key
|
||||||
*/
|
*/
|
||||||
Void logout(String sessionKey);
|
void logoutUser(String sessionKey);
|
||||||
|
|
||||||
}
|
}
|
||||||
|
|
|
@ -1,49 +0,0 @@
|
||||||
/**
|
|
||||||
* Licensed to jclouds, Inc. (jclouds) under one or more
|
|
||||||
* contributor license agreements. See the NOTICE file
|
|
||||||
* distributed with this work for additional information
|
|
||||||
* regarding copyright ownership. jclouds licenses this file
|
|
||||||
* to you under the Apache License, Version 2.0 (the
|
|
||||||
* "License"); you may not use this file except in compliance
|
|
||||||
* with the License. You may obtain a copy of the License at
|
|
||||||
*
|
|
||||||
* http://www.apache.org/licenses/LICENSE-2.0
|
|
||||||
*
|
|
||||||
* Unless required by applicable law or agreed to in writing,
|
|
||||||
* software distributed under the License is distributed on an
|
|
||||||
* "AS IS" BASIS, WITHOUT WARRANTIES OR CONDITIONS OF ANY
|
|
||||||
* KIND, either express or implied. See the License for the
|
|
||||||
* specific language governing permissions and limitations
|
|
||||||
* under the License.
|
|
||||||
*/
|
|
||||||
package org.jclouds.cloudstack.functions;
|
|
||||||
|
|
||||||
import com.google.common.base.Function;
|
|
||||||
import com.google.common.io.InputSupplier;
|
|
||||||
import org.jclouds.crypto.CryptoStreams;
|
|
||||||
|
|
||||||
import java.io.ByteArrayInputStream;
|
|
||||||
import java.io.IOException;
|
|
||||||
import java.io.InputStream;
|
|
||||||
|
|
||||||
/**
|
|
||||||
* Hash a string to MD5 (hex representation)
|
|
||||||
*
|
|
||||||
* @author Andrei Savu
|
|
||||||
*/
|
|
||||||
public class HashToMD5 implements Function<Object, String> {
|
|
||||||
|
|
||||||
@Override
|
|
||||||
public String apply(final Object input) {
|
|
||||||
try {
|
|
||||||
return CryptoStreams.md5Hex(new InputSupplier<InputStream>() {
|
|
||||||
@Override
|
|
||||||
public InputStream getInput() throws IOException {
|
|
||||||
return new ByteArrayInputStream(String.class.cast(input).getBytes());
|
|
||||||
}
|
|
||||||
});
|
|
||||||
} catch (IOException e) {
|
|
||||||
throw new RuntimeException(e);
|
|
||||||
}
|
|
||||||
}
|
|
||||||
}
|
|
|
@ -25,7 +25,7 @@ import java.net.URI;
|
||||||
/**
|
/**
|
||||||
* @author Andrei Savu
|
* @author Andrei Savu
|
||||||
*/
|
*/
|
||||||
public class CloudStackUtil {
|
public class ApiKeyPairs {
|
||||||
|
|
||||||
/**
|
/**
|
||||||
* Retrieve the API key pair for a given CloudStack user
|
* Retrieve the API key pair for a given CloudStack user
|
|
@ -25,6 +25,7 @@ import org.jclouds.cloudstack.domain.User;
|
||||||
import org.testng.annotations.Test;
|
import org.testng.annotations.Test;
|
||||||
|
|
||||||
import static com.google.common.collect.Iterables.find;
|
import static com.google.common.collect.Iterables.find;
|
||||||
|
import static org.jclouds.crypto.CryptoStreams.md5Hex;
|
||||||
import static org.testng.Assert.assertNotNull;
|
import static org.testng.Assert.assertNotNull;
|
||||||
import static org.testng.AssertJUnit.assertEquals;
|
import static org.testng.AssertJUnit.assertEquals;
|
||||||
|
|
||||||
|
@ -38,24 +39,14 @@ public class SessionClientLiveTest extends BaseCloudStackClientLiveTest {
|
||||||
|
|
||||||
private final String USER = "jcloud";
|
private final String USER = "jcloud";
|
||||||
private final String PLAIN_TEXT_PASSWORD = "jcl0ud";
|
private final String PLAIN_TEXT_PASSWORD = "jcl0ud";
|
||||||
private final String PASSWORD_MD5_HASH = "30e14b3727225d833aad2206acea1275";
|
private final String DOMAIN = "Partners/jCloud";
|
||||||
private final String DOMAIN = "/Partners/jCloud";
|
|
||||||
|
|
||||||
private LoginResponse loginResponse;
|
private LoginResponse loginResponse;
|
||||||
|
|
||||||
@Test(enabled = true)
|
|
||||||
public void testLoginWithPlainTextPassword() throws Exception {
|
|
||||||
LoginResponse response = client.getSessionClient()
|
|
||||||
.loginWithPlainTextPassword(USER, PLAIN_TEXT_PASSWORD, DOMAIN);
|
|
||||||
|
|
||||||
assertNotNull(response);
|
|
||||||
assertNotNull(response.getSessionKey());
|
|
||||||
}
|
|
||||||
|
|
||||||
@Test(enabled = true)
|
@Test(enabled = true)
|
||||||
public void testLoginWithHashedPassword() throws Exception {
|
public void testLoginWithHashedPassword() throws Exception {
|
||||||
loginResponse = client.getSessionClient()
|
loginResponse = client.getSessionClient()
|
||||||
.loginWithHashedPassword(USER, PASSWORD_MD5_HASH, DOMAIN);
|
.loginUserInDomainWithHashOfPassword(USER, DOMAIN, md5Hex(PLAIN_TEXT_PASSWORD));
|
||||||
|
|
||||||
assertNotNull(loginResponse);
|
assertNotNull(loginResponse);
|
||||||
assertNotNull(loginResponse.getSessionKey());
|
assertNotNull(loginResponse.getSessionKey());
|
||||||
|
@ -64,7 +55,7 @@ public class SessionClientLiveTest extends BaseCloudStackClientLiveTest {
|
||||||
@Test(dependsOnMethods = "testLoginWithHashedPassword")
|
@Test(dependsOnMethods = "testLoginWithHashedPassword")
|
||||||
public void testRetrieveUserInfoWithSessionKey() throws Exception {
|
public void testRetrieveUserInfoWithSessionKey() throws Exception {
|
||||||
Account account = client.getSessionClient()
|
Account account = client.getSessionClient()
|
||||||
.getAccountByName(loginResponse.getAccountName(), loginResponse.getSessionKey());
|
.getAccountByNameUsingSession(loginResponse.getAccountName(), loginResponse.getSessionKey());
|
||||||
|
|
||||||
assertNotNull(account);
|
assertNotNull(account);
|
||||||
assertEquals(account.getName(), loginResponse.getAccountName());
|
assertEquals(account.getName(), loginResponse.getAccountName());
|
||||||
|
@ -82,6 +73,6 @@ public class SessionClientLiveTest extends BaseCloudStackClientLiveTest {
|
||||||
|
|
||||||
@Test(dependsOnMethods = "testRetrieveUserInfoWithSessionKey")
|
@Test(dependsOnMethods = "testRetrieveUserInfoWithSessionKey")
|
||||||
public void testLogout() throws Exception {
|
public void testLogout() throws Exception {
|
||||||
client.getSessionClient().logout(loginResponse.getSessionKey());
|
client.getSessionClient().logoutUser(loginResponse.getSessionKey());
|
||||||
}
|
}
|
||||||
}
|
}
|
||||||
|
|
|
@ -18,8 +18,17 @@
|
||||||
*/
|
*/
|
||||||
package org.jclouds.crypto;
|
package org.jclouds.crypto;
|
||||||
|
|
||||||
import static com.google.common.base.Preconditions.checkNotNull;
|
import com.google.common.annotations.Beta;
|
||||||
|
import com.google.common.base.Charsets;
|
||||||
|
import com.google.common.base.Throwables;
|
||||||
|
import com.google.common.io.ByteProcessor;
|
||||||
|
import com.google.common.io.ByteStreams;
|
||||||
|
import com.google.common.io.InputSupplier;
|
||||||
|
import org.jclouds.encryption.internal.Base64;
|
||||||
|
import org.jclouds.io.InputSuppliers;
|
||||||
|
|
||||||
|
import javax.crypto.Mac;
|
||||||
|
import java.io.ByteArrayInputStream;
|
||||||
import java.io.ByteArrayOutputStream;
|
import java.io.ByteArrayOutputStream;
|
||||||
import java.io.IOException;
|
import java.io.IOException;
|
||||||
import java.io.InputStream;
|
import java.io.InputStream;
|
||||||
|
@ -28,17 +37,7 @@ import java.security.MessageDigest;
|
||||||
import java.security.NoSuchAlgorithmException;
|
import java.security.NoSuchAlgorithmException;
|
||||||
import java.util.Arrays;
|
import java.util.Arrays;
|
||||||
|
|
||||||
import javax.crypto.Mac;
|
import static com.google.common.base.Preconditions.checkNotNull;
|
||||||
|
|
||||||
import org.jclouds.encryption.internal.Base64;
|
|
||||||
import org.jclouds.io.InputSuppliers;
|
|
||||||
|
|
||||||
import com.google.common.annotations.Beta;
|
|
||||||
import com.google.common.base.Charsets;
|
|
||||||
import com.google.common.base.Throwables;
|
|
||||||
import com.google.common.io.ByteProcessor;
|
|
||||||
import com.google.common.io.ByteStreams;
|
|
||||||
import com.google.common.io.InputSupplier;
|
|
||||||
|
|
||||||
/**
|
/**
|
||||||
* functions related to but not in {@link com.google.common.io.ByteStreams}
|
* functions related to but not in {@link com.google.common.io.ByteStreams}
|
||||||
|
@ -89,6 +88,18 @@ public class CryptoStreams {
|
||||||
return hex(md5(supplier));
|
return hex(md5(supplier));
|
||||||
}
|
}
|
||||||
|
|
||||||
|
/**
|
||||||
|
* @see #md5Hex
|
||||||
|
*/
|
||||||
|
public static String md5Hex(final String in) throws IOException {
|
||||||
|
return md5Hex(new InputSupplier<InputStream>() {
|
||||||
|
@Override
|
||||||
|
public InputStream getInput() throws IOException {
|
||||||
|
return new ByteArrayInputStream(in.getBytes());
|
||||||
|
}
|
||||||
|
});
|
||||||
|
}
|
||||||
|
|
||||||
/**
|
/**
|
||||||
* @see #md5
|
* @see #md5
|
||||||
* @see #base64
|
* @see #base64
|
||||||
|
|
Loading…
Reference in New Issue