mirror of https://github.com/apache/jclouds.git
Merge branch 'retrieve-keys' of https://github.com/andreisavu/jclouds
* 'retrieve-keys' of https://github.com/andreisavu/jclouds: Include the JSESSIONID as part of the LoginResponse Added a set of changes as requested by Adrian Implemented login / logout APIs
This commit is contained in:
commit
b3254b31e6
|
@ -34,6 +34,7 @@ import org.jclouds.cloudstack.features.NetworkAsyncClient;
|
||||||
import org.jclouds.cloudstack.features.OfferingAsyncClient;
|
import org.jclouds.cloudstack.features.OfferingAsyncClient;
|
||||||
import org.jclouds.cloudstack.features.SSHKeyPairAsyncClient;
|
import org.jclouds.cloudstack.features.SSHKeyPairAsyncClient;
|
||||||
import org.jclouds.cloudstack.features.SecurityGroupAsyncClient;
|
import org.jclouds.cloudstack.features.SecurityGroupAsyncClient;
|
||||||
|
import org.jclouds.cloudstack.features.SessionAsyncClient;
|
||||||
import org.jclouds.cloudstack.features.SnapshotAsyncClient;
|
import org.jclouds.cloudstack.features.SnapshotAsyncClient;
|
||||||
import org.jclouds.cloudstack.features.TemplateAsyncClient;
|
import org.jclouds.cloudstack.features.TemplateAsyncClient;
|
||||||
import org.jclouds.cloudstack.features.VMGroupAsyncClient;
|
import org.jclouds.cloudstack.features.VMGroupAsyncClient;
|
||||||
|
@ -184,4 +185,10 @@ public interface CloudStackAsyncClient {
|
||||||
*/
|
*/
|
||||||
@Delegate
|
@Delegate
|
||||||
SnapshotAsyncClient getSnapshotClient();
|
SnapshotAsyncClient getSnapshotClient();
|
||||||
|
|
||||||
|
/**
|
||||||
|
* Provides asynchronous access to Sessions
|
||||||
|
*/
|
||||||
|
@Delegate
|
||||||
|
SessionAsyncClient getSessionClient();
|
||||||
}
|
}
|
||||||
|
|
|
@ -18,8 +18,6 @@
|
||||||
*/
|
*/
|
||||||
package org.jclouds.cloudstack;
|
package org.jclouds.cloudstack;
|
||||||
|
|
||||||
import java.util.concurrent.TimeUnit;
|
|
||||||
|
|
||||||
import org.jclouds.cloudstack.features.AccountClient;
|
import org.jclouds.cloudstack.features.AccountClient;
|
||||||
import org.jclouds.cloudstack.features.AddressClient;
|
import org.jclouds.cloudstack.features.AddressClient;
|
||||||
import org.jclouds.cloudstack.features.AsyncJobClient;
|
import org.jclouds.cloudstack.features.AsyncJobClient;
|
||||||
|
@ -41,10 +39,13 @@ import org.jclouds.cloudstack.features.TemplateClient;
|
||||||
import org.jclouds.cloudstack.features.VMGroupClient;
|
import org.jclouds.cloudstack.features.VMGroupClient;
|
||||||
import org.jclouds.cloudstack.features.VirtualMachineClient;
|
import org.jclouds.cloudstack.features.VirtualMachineClient;
|
||||||
import org.jclouds.cloudstack.features.VolumeClient;
|
import org.jclouds.cloudstack.features.VolumeClient;
|
||||||
|
import org.jclouds.cloudstack.features.SessionClient;
|
||||||
import org.jclouds.cloudstack.features.ZoneClient;
|
import org.jclouds.cloudstack.features.ZoneClient;
|
||||||
import org.jclouds.concurrent.Timeout;
|
import org.jclouds.concurrent.Timeout;
|
||||||
import org.jclouds.rest.annotations.Delegate;
|
import org.jclouds.rest.annotations.Delegate;
|
||||||
|
|
||||||
|
import java.util.concurrent.TimeUnit;
|
||||||
|
|
||||||
/**
|
/**
|
||||||
* Provides synchronous access to CloudStack.
|
* Provides synchronous access to CloudStack.
|
||||||
* <p/>
|
* <p/>
|
||||||
|
@ -187,4 +188,10 @@ public interface CloudStackClient {
|
||||||
*/
|
*/
|
||||||
@Delegate
|
@Delegate
|
||||||
SnapshotClient getSnapshotClient();
|
SnapshotClient getSnapshotClient();
|
||||||
|
|
||||||
|
/**
|
||||||
|
* Provides synchronous access to Sessions
|
||||||
|
*/
|
||||||
|
@Delegate
|
||||||
|
SessionClient getSessionClient();
|
||||||
}
|
}
|
||||||
|
|
|
@ -18,12 +18,12 @@
|
||||||
*/
|
*/
|
||||||
package org.jclouds.cloudstack;
|
package org.jclouds.cloudstack;
|
||||||
|
|
||||||
import static org.jclouds.Constants.PROPERTY_API_VERSION;
|
import org.jclouds.PropertiesBuilder;
|
||||||
import static org.jclouds.Constants.PROPERTY_ENDPOINT;
|
|
||||||
|
|
||||||
import java.util.Properties;
|
import java.util.Properties;
|
||||||
|
|
||||||
import org.jclouds.PropertiesBuilder;
|
import static org.jclouds.Constants.PROPERTY_API_VERSION;
|
||||||
|
import static org.jclouds.Constants.PROPERTY_ENDPOINT;
|
||||||
|
|
||||||
/**
|
/**
|
||||||
* Builds properties used in cloudstack Clients
|
* Builds properties used in cloudstack Clients
|
||||||
|
|
|
@ -96,6 +96,8 @@ import org.jclouds.cloudstack.features.SSHKeyPairAsyncClient;
|
||||||
import org.jclouds.cloudstack.features.SSHKeyPairClient;
|
import org.jclouds.cloudstack.features.SSHKeyPairClient;
|
||||||
import org.jclouds.cloudstack.features.SecurityGroupAsyncClient;
|
import org.jclouds.cloudstack.features.SecurityGroupAsyncClient;
|
||||||
import org.jclouds.cloudstack.features.SecurityGroupClient;
|
import org.jclouds.cloudstack.features.SecurityGroupClient;
|
||||||
|
import org.jclouds.cloudstack.features.SessionAsyncClient;
|
||||||
|
import org.jclouds.cloudstack.features.SessionClient;
|
||||||
import org.jclouds.cloudstack.features.SnapshotAsyncClient;
|
import org.jclouds.cloudstack.features.SnapshotAsyncClient;
|
||||||
import org.jclouds.cloudstack.features.SnapshotClient;
|
import org.jclouds.cloudstack.features.SnapshotClient;
|
||||||
import org.jclouds.cloudstack.features.TemplateAsyncClient;
|
import org.jclouds.cloudstack.features.TemplateAsyncClient;
|
||||||
|
@ -175,6 +177,7 @@ public class CloudStackRestClientModule extends RestClientModule<CloudStackClien
|
||||||
.put(GlobalUsageClient.class, GlobalUsageAsyncClient.class)//
|
.put(GlobalUsageClient.class, GlobalUsageAsyncClient.class)//
|
||||||
.put(GlobalPodClient.class, GlobalPodAsyncClient.class)//
|
.put(GlobalPodClient.class, GlobalPodAsyncClient.class)//
|
||||||
.put(GlobalVlanClient.class, GlobalVlanAsyncClient.class)//
|
.put(GlobalVlanClient.class, GlobalVlanAsyncClient.class)//
|
||||||
|
.put(SessionClient.class, SessionAsyncClient.class)//
|
||||||
.build();
|
.build();
|
||||||
|
|
||||||
@Override
|
@Override
|
||||||
|
|
|
@ -0,0 +1,302 @@
|
||||||
|
/**
|
||||||
|
* 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.domain;
|
||||||
|
|
||||||
|
import com.google.gson.annotations.SerializedName;
|
||||||
|
|
||||||
|
/**
|
||||||
|
* Representation of the login API call response
|
||||||
|
*
|
||||||
|
* @author Andrei Savu
|
||||||
|
*/
|
||||||
|
public class LoginResponse implements Comparable<LoginResponse> {
|
||||||
|
|
||||||
|
public static Builder builder() {
|
||||||
|
return new Builder();
|
||||||
|
}
|
||||||
|
|
||||||
|
public static class Builder {
|
||||||
|
|
||||||
|
private String userName;
|
||||||
|
private long userId;
|
||||||
|
private String password;
|
||||||
|
private long domainId;
|
||||||
|
private long timeout;
|
||||||
|
private String accountName;
|
||||||
|
private String firstName;
|
||||||
|
private String lastName;
|
||||||
|
private Account.Type accountType;
|
||||||
|
private String timezone;
|
||||||
|
private String timezoneOffset;
|
||||||
|
private String sessionKey;
|
||||||
|
private String jSessionId;
|
||||||
|
|
||||||
|
public Builder copyOf(LoginResponse r) {
|
||||||
|
this.userName = r.userName;
|
||||||
|
this.userId = r.userId;
|
||||||
|
this.password = r.password;
|
||||||
|
this.domainId = r.domainId;
|
||||||
|
this.timeout = r.timeout;
|
||||||
|
this.accountName = r.accountName;
|
||||||
|
this.firstName = r.firstName;
|
||||||
|
this.lastName = r.lastName;
|
||||||
|
this.accountType = r.accountType;
|
||||||
|
this.timezone = r.timezone;
|
||||||
|
this.timezoneOffset = r.timezoneOffset;
|
||||||
|
this.sessionKey = r.sessionKey;
|
||||||
|
this.jSessionId = r.jSessionId;
|
||||||
|
return this;
|
||||||
|
}
|
||||||
|
|
||||||
|
public Builder userName(String userName) {
|
||||||
|
this.userName = userName;
|
||||||
|
return this;
|
||||||
|
}
|
||||||
|
|
||||||
|
public Builder userId(long userId) {
|
||||||
|
this.userId = userId;
|
||||||
|
return this;
|
||||||
|
}
|
||||||
|
|
||||||
|
public Builder password(String password) {
|
||||||
|
this.password = password;
|
||||||
|
return this;
|
||||||
|
}
|
||||||
|
|
||||||
|
public Builder domainId(long domainId) {
|
||||||
|
this.domainId = domainId;
|
||||||
|
return this;
|
||||||
|
}
|
||||||
|
|
||||||
|
public Builder timeout(long timeout) {
|
||||||
|
this.timeout = timeout;
|
||||||
|
return this;
|
||||||
|
}
|
||||||
|
|
||||||
|
public Builder accountName(String accountName) {
|
||||||
|
this.accountName = accountName;
|
||||||
|
return this;
|
||||||
|
}
|
||||||
|
|
||||||
|
public Builder firstName(String firstName) {
|
||||||
|
this.firstName = firstName;
|
||||||
|
return this;
|
||||||
|
}
|
||||||
|
|
||||||
|
public Builder lastName(String lastName) {
|
||||||
|
this.lastName = lastName;
|
||||||
|
return this;
|
||||||
|
}
|
||||||
|
|
||||||
|
public Builder accountType(Account.Type accountType) {
|
||||||
|
this.accountType = accountType;
|
||||||
|
return this;
|
||||||
|
}
|
||||||
|
|
||||||
|
public Builder timezone(String timezone) {
|
||||||
|
this.timezone = timezone;
|
||||||
|
return this;
|
||||||
|
}
|
||||||
|
|
||||||
|
public Builder timezoneOffset(String timezoneOffset) {
|
||||||
|
this.timezoneOffset = timezoneOffset;
|
||||||
|
return this;
|
||||||
|
}
|
||||||
|
|
||||||
|
public Builder sessionKey(String sessionKey) {
|
||||||
|
this.sessionKey = sessionKey;
|
||||||
|
return this;
|
||||||
|
}
|
||||||
|
|
||||||
|
public Builder jSessionId(String jSessionId) {
|
||||||
|
this.jSessionId = jSessionId;
|
||||||
|
return this;
|
||||||
|
}
|
||||||
|
|
||||||
|
public LoginResponse build() {
|
||||||
|
return new LoginResponse(userName, userId, password, domainId, timeout, accountName,
|
||||||
|
firstName, lastName, accountType, timezone, timezoneOffset, sessionKey, jSessionId);
|
||||||
|
}
|
||||||
|
}
|
||||||
|
|
||||||
|
// for deserialization
|
||||||
|
LoginResponse() { }
|
||||||
|
|
||||||
|
@SerializedName("username")
|
||||||
|
private String userName;
|
||||||
|
@SerializedName("userid")
|
||||||
|
private long userId;
|
||||||
|
private String password;
|
||||||
|
@SerializedName("domainid")
|
||||||
|
private long domainId;
|
||||||
|
private long timeout;
|
||||||
|
@SerializedName("account")
|
||||||
|
private String accountName;
|
||||||
|
@SerializedName("firstname")
|
||||||
|
private String firstName;
|
||||||
|
@SerializedName("lastname")
|
||||||
|
private String lastName;
|
||||||
|
@SerializedName("type")
|
||||||
|
private Account.Type accountType;
|
||||||
|
private String timezone;
|
||||||
|
@SerializedName("timezoneoffset")
|
||||||
|
private String timezoneOffset;
|
||||||
|
@SerializedName("sessionkey")
|
||||||
|
private String sessionKey;
|
||||||
|
private String jSessionId;
|
||||||
|
|
||||||
|
public LoginResponse(String userName, long userId, String password, long domainId, long timeout,
|
||||||
|
String accountName, String firstName, String lastName, Account.Type accountType,
|
||||||
|
String timezone, String timezoneOffset, String sessionKey, String jSessionId) {
|
||||||
|
this.userName = userName;
|
||||||
|
this.userId = userId;
|
||||||
|
this.password = password;
|
||||||
|
this.domainId = domainId;
|
||||||
|
this.timeout = timeout;
|
||||||
|
this.accountName = accountName;
|
||||||
|
this.firstName = firstName;
|
||||||
|
this.lastName = lastName;
|
||||||
|
this.accountType = accountType;
|
||||||
|
this.timezone = timezone;
|
||||||
|
this.timezoneOffset = timezoneOffset;
|
||||||
|
this.sessionKey = sessionKey;
|
||||||
|
this.jSessionId = jSessionId;
|
||||||
|
}
|
||||||
|
|
||||||
|
public String getUserName() {
|
||||||
|
return userName;
|
||||||
|
}
|
||||||
|
|
||||||
|
public long getUserId() {
|
||||||
|
return userId;
|
||||||
|
}
|
||||||
|
|
||||||
|
public String getPassword() {
|
||||||
|
return password;
|
||||||
|
}
|
||||||
|
|
||||||
|
public long getDomainId() {
|
||||||
|
return domainId;
|
||||||
|
}
|
||||||
|
|
||||||
|
public long getTimeout() {
|
||||||
|
return timeout;
|
||||||
|
}
|
||||||
|
|
||||||
|
public String getAccountName() {
|
||||||
|
return accountName;
|
||||||
|
}
|
||||||
|
|
||||||
|
public String getFirstName() {
|
||||||
|
return firstName;
|
||||||
|
}
|
||||||
|
|
||||||
|
public String getLastName() {
|
||||||
|
return lastName;
|
||||||
|
}
|
||||||
|
|
||||||
|
public Account.Type getAccountType() {
|
||||||
|
return accountType;
|
||||||
|
}
|
||||||
|
|
||||||
|
public String getTimezone() {
|
||||||
|
return timezone;
|
||||||
|
}
|
||||||
|
|
||||||
|
public String getTimezoneOffset() {
|
||||||
|
return timezoneOffset;
|
||||||
|
}
|
||||||
|
|
||||||
|
public String getSessionKey() {
|
||||||
|
return sessionKey;
|
||||||
|
}
|
||||||
|
|
||||||
|
public String getJSessionId() {
|
||||||
|
return jSessionId;
|
||||||
|
}
|
||||||
|
|
||||||
|
@Override
|
||||||
|
public boolean equals(Object o) {
|
||||||
|
if (this == o) return true;
|
||||||
|
if (o == null || getClass() != o.getClass()) return false;
|
||||||
|
|
||||||
|
LoginResponse loginResponse = (LoginResponse) o;
|
||||||
|
|
||||||
|
if (domainId != loginResponse.domainId) return false;
|
||||||
|
if (timeout != loginResponse.timeout) return false;
|
||||||
|
if (userId != loginResponse.userId) return false;
|
||||||
|
if (accountName != null ? !accountName.equals(loginResponse.accountName) : loginResponse.accountName != null) return false;
|
||||||
|
if (accountType != loginResponse.accountType) return false;
|
||||||
|
if (firstName != null ? !firstName.equals(loginResponse.firstName) : loginResponse.firstName != null) return false;
|
||||||
|
if (lastName != null ? !lastName.equals(loginResponse.lastName) : loginResponse.lastName != null) return false;
|
||||||
|
if (password != null ? !password.equals(loginResponse.password) : loginResponse.password != null) return false;
|
||||||
|
if (sessionKey != null ? !sessionKey.equals(loginResponse.sessionKey) : loginResponse.sessionKey != null) return false;
|
||||||
|
if (timezone != null ? !timezone.equals(loginResponse.timezone) : loginResponse.timezone != null) return false;
|
||||||
|
if (timezoneOffset != null ? !timezoneOffset.equals(loginResponse.timezoneOffset) : loginResponse.timezoneOffset != null)
|
||||||
|
return false;
|
||||||
|
if (userName != null ? !userName.equals(loginResponse.userName) : loginResponse.userName != null) return false;
|
||||||
|
if (jSessionId != null ? !jSessionId.equals(loginResponse.jSessionId) : loginResponse.jSessionId != null) return false;
|
||||||
|
|
||||||
|
return true;
|
||||||
|
}
|
||||||
|
|
||||||
|
@Override
|
||||||
|
public int hashCode() {
|
||||||
|
int result = userName != null ? userName.hashCode() : 0;
|
||||||
|
result = 31 * result + (int) (userId ^ (userId >>> 32));
|
||||||
|
result = 31 * result + (password != null ? password.hashCode() : 0);
|
||||||
|
result = 31 * result + (int) (domainId ^ (domainId >>> 32));
|
||||||
|
result = 31 * result + (int) (timeout ^ (timeout >>> 32));
|
||||||
|
result = 31 * result + (accountName != null ? accountName.hashCode() : 0);
|
||||||
|
result = 31 * result + (firstName != null ? firstName.hashCode() : 0);
|
||||||
|
result = 31 * result + (lastName != null ? lastName.hashCode() : 0);
|
||||||
|
result = 31 * result + (accountType != null ? accountType.hashCode() : 0);
|
||||||
|
result = 31 * result + (timezone != null ? timezone.hashCode() : 0);
|
||||||
|
result = 31 * result + (timezoneOffset != null ? timezoneOffset.hashCode() : 0);
|
||||||
|
result = 31 * result + (sessionKey != null ? sessionKey.hashCode() : 0);
|
||||||
|
result = 31 * result + (jSessionId != null ? jSessionId.hashCode() : 0);
|
||||||
|
return result;
|
||||||
|
}
|
||||||
|
|
||||||
|
@Override
|
||||||
|
public String toString() {
|
||||||
|
return "LoginResponse{" +
|
||||||
|
"userName='" + userName + '\'' +
|
||||||
|
", userId=" + userId +
|
||||||
|
", password='" + password + '\'' +
|
||||||
|
", domainId=" + domainId +
|
||||||
|
", timeout=" + timeout +
|
||||||
|
", accountName='" + accountName + '\'' +
|
||||||
|
", firstName='" + firstName + '\'' +
|
||||||
|
", lastName='" + lastName + '\'' +
|
||||||
|
", accountType=" + accountType +
|
||||||
|
", timezone='" + timezone + '\'' +
|
||||||
|
", timezoneOffset='" + timezoneOffset + '\'' +
|
||||||
|
", sessionKey='" + sessionKey + '\'' +
|
||||||
|
", jSessionId='" + jSessionId + '\'' +
|
||||||
|
'}';
|
||||||
|
}
|
||||||
|
|
||||||
|
@Override
|
||||||
|
public int compareTo(LoginResponse arg0) {
|
||||||
|
return sessionKey.compareTo(arg0.getSessionKey());
|
||||||
|
}
|
||||||
|
|
||||||
|
}
|
|
@ -0,0 +1,78 @@
|
||||||
|
/**
|
||||||
|
* 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.features;
|
||||||
|
|
||||||
|
import com.google.common.util.concurrent.ListenableFuture;
|
||||||
|
import org.jclouds.cloudstack.domain.Account;
|
||||||
|
import org.jclouds.cloudstack.domain.LoginResponse;
|
||||||
|
import org.jclouds.cloudstack.functions.ParseLoginResponseFromHttpResponse;
|
||||||
|
import org.jclouds.rest.annotations.ExceptionParser;
|
||||||
|
import org.jclouds.rest.annotations.QueryParams;
|
||||||
|
import org.jclouds.rest.annotations.ResponseParser;
|
||||||
|
import org.jclouds.rest.annotations.SelectJson;
|
||||||
|
import org.jclouds.rest.functions.ReturnNullOnNotFoundOr404;
|
||||||
|
import org.jclouds.rest.functions.ReturnVoidOnNotFoundOr404;
|
||||||
|
|
||||||
|
import javax.ws.rs.Consumes;
|
||||||
|
import javax.ws.rs.CookieParam;
|
||||||
|
import javax.ws.rs.GET;
|
||||||
|
import javax.ws.rs.QueryParam;
|
||||||
|
import javax.ws.rs.core.MediaType;
|
||||||
|
|
||||||
|
/**
|
||||||
|
* Provides asynchronous access to Cloudstack Sessions
|
||||||
|
* <p/>
|
||||||
|
*
|
||||||
|
* @see org.jclouds.cloudstack.features.SessionClient
|
||||||
|
* @see <a href="http://download.cloud.com/releases/2.2.0/api_2.2.12/TOC_User.html" />
|
||||||
|
* @author Andrei Savu
|
||||||
|
*/
|
||||||
|
@QueryParams(keys = "response", values = "json")
|
||||||
|
public interface SessionAsyncClient {
|
||||||
|
|
||||||
|
/**
|
||||||
|
* @see SessionClient#loginUserInDomainWithHashOfPassword
|
||||||
|
*/
|
||||||
|
@GET
|
||||||
|
@QueryParams(keys = "command", values = "login")
|
||||||
|
@ResponseParser(ParseLoginResponseFromHttpResponse.class)
|
||||||
|
@Consumes(MediaType.APPLICATION_JSON)
|
||||||
|
@ExceptionParser(ReturnNullOnNotFoundOr404.class)
|
||||||
|
ListenableFuture<LoginResponse> loginUserInDomainWithHashOfPassword(@QueryParam("username") String userName,
|
||||||
|
@QueryParam("domain") String domain, @QueryParam("password") String hashedPassword);
|
||||||
|
|
||||||
|
/**
|
||||||
|
* @see SessionClient#getAccountByNameUsingSession
|
||||||
|
*/
|
||||||
|
@GET
|
||||||
|
@QueryParams(keys = "comand", values = "listAccounts")
|
||||||
|
@SelectJson("account")
|
||||||
|
@Consumes(MediaType.APPLICATION_JSON)
|
||||||
|
@ExceptionParser(ReturnNullOnNotFoundOr404.class)
|
||||||
|
ListenableFuture<Account> getAccountByNameUsingSession(@QueryParam("name") String accountName,
|
||||||
|
@QueryParam("sessionkey") String sessionKey, @CookieParam("JSESSIONID") String jSessionId);
|
||||||
|
|
||||||
|
/**
|
||||||
|
* @see SessionClient#logoutUser
|
||||||
|
*/
|
||||||
|
@GET
|
||||||
|
@QueryParams(keys = "command", values = "logout")
|
||||||
|
@ExceptionParser(ReturnVoidOnNotFoundOr404.class)
|
||||||
|
ListenableFuture<Void> logoutUser(@QueryParam("sessionkey") String sessionKey);
|
||||||
|
}
|
|
@ -0,0 +1,77 @@
|
||||||
|
/**
|
||||||
|
* 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.features;
|
||||||
|
|
||||||
|
import org.jclouds.cloudstack.domain.Account;
|
||||||
|
import org.jclouds.cloudstack.domain.LoginResponse;
|
||||||
|
import org.jclouds.concurrent.Timeout;
|
||||||
|
|
||||||
|
import java.util.concurrent.TimeUnit;
|
||||||
|
|
||||||
|
/**
|
||||||
|
* Provides synchronous access to CloudStack Sessions
|
||||||
|
* <p/>
|
||||||
|
*
|
||||||
|
* @see <a href="http://download.cloud.com/releases/2.2.0/api_2.2.12/TOC_User.html" />
|
||||||
|
* @author Andrei Savu
|
||||||
|
*/
|
||||||
|
@Timeout(duration = 120, timeUnit = TimeUnit.SECONDS)
|
||||||
|
public interface SessionClient {
|
||||||
|
|
||||||
|
/**
|
||||||
|
* Logs a user into Cloudstack. A successful login attempt will generate a JSESSIONID
|
||||||
|
* 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
|
||||||
|
* user account name
|
||||||
|
* @param domain
|
||||||
|
* domain name, if empty defaults to ROOT
|
||||||
|
* @param hashedPassword
|
||||||
|
* hashed password (by default MD5)
|
||||||
|
* @return
|
||||||
|
* login response with session key or null
|
||||||
|
*/
|
||||||
|
LoginResponse loginUserInDomainWithHashOfPassword(String userName, String domain, String hashedPassword);
|
||||||
|
|
||||||
|
/**
|
||||||
|
* Retrieve an account by name using the session key for login
|
||||||
|
*
|
||||||
|
* @param accountName
|
||||||
|
* account name
|
||||||
|
* @param sessionKey
|
||||||
|
* a valid session key
|
||||||
|
* @param jSessionId
|
||||||
|
* the JSESSIONID cookie returned by the server
|
||||||
|
* @return
|
||||||
|
* account instance or null
|
||||||
|
*/
|
||||||
|
Account getAccountByNameUsingSession(String accountName, String sessionKey, String jSessionId);
|
||||||
|
|
||||||
|
/**
|
||||||
|
* Logs out the user by invalidating the session key
|
||||||
|
*
|
||||||
|
* @param sessionKey
|
||||||
|
* user session key
|
||||||
|
*/
|
||||||
|
void logoutUser(String sessionKey);
|
||||||
|
|
||||||
|
}
|
|
@ -0,0 +1,41 @@
|
||||||
|
package org.jclouds.cloudstack.functions;
|
||||||
|
|
||||||
|
import com.google.common.base.Function;
|
||||||
|
import com.google.common.base.Splitter;
|
||||||
|
import com.google.inject.Inject;
|
||||||
|
import com.google.inject.TypeLiteral;
|
||||||
|
import org.jclouds.cloudstack.domain.LoginResponse;
|
||||||
|
import org.jclouds.http.HttpResponse;
|
||||||
|
import org.jclouds.http.functions.ParseFirstJsonValueNamed;
|
||||||
|
import org.jclouds.json.internal.GsonWrapper;
|
||||||
|
|
||||||
|
import static com.google.common.base.Preconditions.checkNotNull;
|
||||||
|
import static com.google.common.collect.Iterables.get;
|
||||||
|
import static com.google.common.collect.Iterables.getOnlyElement;
|
||||||
|
|
||||||
|
/**
|
||||||
|
* @author Andrei Savu
|
||||||
|
*/
|
||||||
|
public class ParseLoginResponseFromHttpResponse implements Function<HttpResponse, LoginResponse> {
|
||||||
|
|
||||||
|
private ParseFirstJsonValueNamed<LoginResponse> parser;
|
||||||
|
|
||||||
|
@Inject
|
||||||
|
ParseLoginResponseFromHttpResponse(GsonWrapper gson) {
|
||||||
|
this.parser = new ParseFirstJsonValueNamed<LoginResponse>(checkNotNull(gson, "gsonWrapper"),
|
||||||
|
new TypeLiteral<LoginResponse>(){}, "loginresponse");
|
||||||
|
}
|
||||||
|
|
||||||
|
@Override
|
||||||
|
public LoginResponse apply(HttpResponse response) {
|
||||||
|
checkNotNull(response, "response");
|
||||||
|
|
||||||
|
LoginResponse login = parser.apply(response);
|
||||||
|
checkNotNull(login, "loginResponse");
|
||||||
|
|
||||||
|
String jSessionId = get(Splitter.on("=").split(get(Splitter.on(";").trimResults().split(
|
||||||
|
getOnlyElement(response.getHeaders().get("Set-Cookie"))), 0)), 1);
|
||||||
|
|
||||||
|
return LoginResponse.builder().copyOf(login).jSessionId(jSessionId).build();
|
||||||
|
}
|
||||||
|
}
|
|
@ -0,0 +1,46 @@
|
||||||
|
/**
|
||||||
|
* 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.util;
|
||||||
|
|
||||||
|
import org.jclouds.cloudstack.domain.ApiKeyPair;
|
||||||
|
|
||||||
|
import java.net.URI;
|
||||||
|
|
||||||
|
/**
|
||||||
|
* @author Andrei Savu
|
||||||
|
*/
|
||||||
|
public class ApiKeyPairs {
|
||||||
|
|
||||||
|
/**
|
||||||
|
* Retrieve the API key pair for a given CloudStack user
|
||||||
|
*
|
||||||
|
* @param endpoint
|
||||||
|
* CloudStack API endpoint (e.g. http://72.52.126.25/client/api/)
|
||||||
|
* @param userName
|
||||||
|
* User account name
|
||||||
|
* @param password
|
||||||
|
* User password
|
||||||
|
* @param domain
|
||||||
|
* Domain name. If empty defaults to ROOT
|
||||||
|
* @return
|
||||||
|
*/
|
||||||
|
public static ApiKeyPair getApiKeyPairForUser(URI endpoint, String userName, String password, String domain) {
|
||||||
|
return null;
|
||||||
|
}
|
||||||
|
}
|
|
@ -0,0 +1,79 @@
|
||||||
|
/**
|
||||||
|
* 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.features;
|
||||||
|
|
||||||
|
import com.google.common.base.Predicate;
|
||||||
|
import org.jclouds.cloudstack.domain.Account;
|
||||||
|
import org.jclouds.cloudstack.domain.LoginResponse;
|
||||||
|
import org.jclouds.cloudstack.domain.User;
|
||||||
|
import org.testng.annotations.Test;
|
||||||
|
|
||||||
|
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.AssertJUnit.assertEquals;
|
||||||
|
|
||||||
|
/**
|
||||||
|
* Tests behavior of {@code SessionClient}
|
||||||
|
*
|
||||||
|
* @author Andrei Savu
|
||||||
|
*/
|
||||||
|
@Test(groups = "live", singleThreaded = true, testName = "SessionClientLiveTest")
|
||||||
|
public class SessionClientLiveTest extends BaseCloudStackClientLiveTest {
|
||||||
|
|
||||||
|
private final String USER = "jcloud";
|
||||||
|
private final String PLAIN_TEXT_PASSWORD = "jcl0ud";
|
||||||
|
private final String DOMAIN = "Partners/jCloud";
|
||||||
|
|
||||||
|
private LoginResponse login;
|
||||||
|
|
||||||
|
@Test(enabled = true)
|
||||||
|
public void testLoginWithHashOfPassword() throws Exception {
|
||||||
|
login = client.getSessionClient()
|
||||||
|
.loginUserInDomainWithHashOfPassword(USER, DOMAIN, md5Hex(PLAIN_TEXT_PASSWORD));
|
||||||
|
|
||||||
|
assertNotNull(login);
|
||||||
|
assertNotNull(login.getSessionKey());
|
||||||
|
assertNotNull(login.getJSessionId());
|
||||||
|
}
|
||||||
|
|
||||||
|
@Test(dependsOnMethods = "testLoginWithHashOfPassword")
|
||||||
|
public void testRetrieveUserInfoWithSessionKey() throws Exception {
|
||||||
|
Account account = client.getSessionClient().getAccountByNameUsingSession(
|
||||||
|
login.getAccountName(), login.getSessionKey(), login.getJSessionId());
|
||||||
|
|
||||||
|
assertNotNull(account);
|
||||||
|
assertEquals(account.getName(), login.getAccountName());
|
||||||
|
|
||||||
|
User currentUser = find(account.getUsers(), new Predicate<User>() {
|
||||||
|
@Override
|
||||||
|
public boolean apply(User user) {
|
||||||
|
return user.getId() == login.getUserId();
|
||||||
|
}
|
||||||
|
});
|
||||||
|
assertNotNull(currentUser);
|
||||||
|
assertEquals(currentUser.getName(), login.getUserName());
|
||||||
|
assertEquals(currentUser.getDomainId(), login.getDomainId());
|
||||||
|
}
|
||||||
|
|
||||||
|
@Test(dependsOnMethods = "testRetrieveUserInfoWithSessionKey")
|
||||||
|
public void testLogout() throws Exception {
|
||||||
|
client.getSessionClient().logoutUser(login.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