/*
* Licensed to the Apache Software Foundation (ASF) under one or more
* contributor license agreements. See the NOTICE file distributed with
* this work for additional information regarding copyright ownership.
* The ASF 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.vcloud.director.v1_5.features.admin;
import static com.google.common.base.Objects.equal;
import static org.jclouds.vcloud.director.v1_5.VCloudDirectorLiveTestConstants.OBJ_FIELD_UPDATABLE;
import static org.jclouds.vcloud.director.v1_5.domain.Checks.checkUser;
import static org.testng.Assert.assertNotNull;
import static org.testng.Assert.assertNull;
import static org.testng.Assert.assertTrue;
import static org.testng.Assert.fail;
import static org.testng.AssertJUnit.assertFalse;
import java.net.URI;
import org.jclouds.rest.AuthorizationException;
import org.jclouds.vcloud.director.v1_5.domain.Role.DefaultRoles;
import org.jclouds.vcloud.director.v1_5.domain.SessionWithToken;
import org.jclouds.vcloud.director.v1_5.domain.User;
import org.jclouds.vcloud.director.v1_5.domain.org.OrgPasswordPolicySettings;
import org.jclouds.vcloud.director.v1_5.internal.BaseVCloudDirectorApiLiveTest;
import org.jclouds.vcloud.director.v1_5.login.SessionApi;
import org.testng.annotations.AfterClass;
import org.testng.annotations.BeforeClass;
import org.testng.annotations.Test;
/**
* Tests live behavior of {@link UserApi}.
*
* @author danikov
*/
@Test(groups = { "live", "admin" }, singleThreaded = true, testName = "UserApiLiveTest")
public class UserApiLiveTest extends BaseVCloudDirectorApiLiveTest {
public static final String USER = "admin user";
/*
* Convenience references to API apis.
*/
UserApi userApi;
/*
* Shared state between dependant tests.
*/
private User user;
@Override
@BeforeClass(alwaysRun = true)
public void setupRequiredApis() {
userApi = adminContext.getApi().getUserApi();
}
@AfterClass(alwaysRun = true)
public void cleanUp() throws Exception {
if (user != null) {
try {
userApi.remove(user.getHref());
} catch (Exception e) {
logger.warn(e, "Error deleting user '%s'", user.getName());
}
}
}
@Test(description = "POST /admin/org/{id}/users")
public void testAddUser() {
User newUser = randomTestUser("testAddUser");
user = userApi.addUserToOrg(newUser, org.getId());
checkUser(newUser);
}
@Test(description = "GET /admin/user/{id}", dependsOnMethods = { "testAddUser" })
public void testGetUser() {
user = userApi.get(user.getHref());
checkUser(user);
}
@Test(description = "PUT /admin/user/{id}", dependsOnMethods = { "testGetUser" })
public void testEditUser() {
User oldUser = user.toBuilder().build();
User newUser = user.toBuilder()
.fullName("new"+oldUser.getFullName())
.emailAddress("new"+oldUser.getEmailAddress())
.telephone("1-"+oldUser.getTelephone())
.isEnabled(true)
.im("new"+oldUser.getIM())
.isAlertEnabled(true)
.alertEmailPrefix("new"+oldUser.getAlertEmailPrefix())
.alertEmail("new"+oldUser.getAlertEmail())
.storedVmQuota(1)
.deployedVmQuota(1)
.password("newPassword")
// TODO test setting other fields?
// .name("new"+oldUser.getName())
.role(getRoleReferenceFor(DefaultRoles.AUTHOR.value()))
.build();
userApi.edit(user.getHref(), newUser);
user = userApi.get(user.getHref());
checkUser(user);
assertTrue(equal(user.getFullName(), newUser.getFullName()),
String.format(OBJ_FIELD_UPDATABLE, USER, "fullName"));
assertTrue(equal(user.getEmailAddress(), newUser.getEmailAddress()),
String.format(OBJ_FIELD_UPDATABLE, USER, "emailAddress"));
assertTrue(equal(user.getTelephone(), newUser.getTelephone()),
String.format(OBJ_FIELD_UPDATABLE, USER, "telephone"));
assertTrue(equal(user.isEnabled(), newUser.isEnabled()),
String.format(OBJ_FIELD_UPDATABLE, USER, "isEnabled"));
assertTrue(equal(user.getIM(), newUser.getIM()),
String.format(OBJ_FIELD_UPDATABLE, USER, "im"));
assertTrue(equal(user.isAlertEnabled(), newUser.isAlertEnabled()),
String.format(OBJ_FIELD_UPDATABLE, USER, "isAlertEnabled"));
assertTrue(equal(user.getAlertEmailPrefix(), newUser.getAlertEmailPrefix()),
String.format(OBJ_FIELD_UPDATABLE, USER, "alertEmailPrefix"));
assertTrue(equal(user.getAlertEmail(), newUser.getAlertEmail()),
String.format(OBJ_FIELD_UPDATABLE, USER, "alertEmail"));
// assertTrue(equal(user.getRole(), newUser.getRole()),
// String.format(OBJ_FIELD_UPDATABLE, USER, "role"));
assertTrue(equal(user.getStoredVmQuota(), newUser.getStoredVmQuota()),
String.format(OBJ_FIELD_UPDATABLE, USER, "storedVmQuota"));
assertTrue(equal(user.getDeployedVmQuota(), newUser.getDeployedVmQuota()),
String.format(OBJ_FIELD_UPDATABLE, USER, "deployedVmQuota"));
// session api isn't typically exposed to the user, as it is implicit
SessionApi sessionApi = context.utils().injector().getInstance(SessionApi.class);
// Check the user can really login with the changed password
// NOTE: the password is NOT returned in the User object returned from the server
SessionWithToken sessionWithToken = sessionApi.loginUserInOrgWithPassword(URI.create(endpoint + "/sessions"), user.getName(), org.getName(), "newPassword");
assertNotNull(sessionWithToken.getToken());
sessionApi.logoutSessionWithToken(sessionWithToken.getSession().getHref(), sessionWithToken.getToken());
}
@Test(description = "POST /admin/user/{id}/action/unlock", dependsOnMethods = { "testEditUser" })
public void testUnlockUser() {
// Need to know how many times to fail login to lock account
AdminOrgApi adminOrgApi = adminContext.getApi().getOrgApi();
OrgPasswordPolicySettings settingsToRevertTo = null;
// session api isn't typically exposed to the user, as it is implicit
SessionApi sessionApi = context.utils().injector().getInstance(SessionApi.class);
OrgPasswordPolicySettings settings = adminOrgApi.getSettings(org.getId()).getPasswordPolicy();
assertNotNull(settings);
// Adjust account settings so we can lock the account - be careful to not set invalidLoginsBeforeLockout too low!
if (!settings.isAccountLockoutEnabled()) {
settingsToRevertTo = settings;
settings = settings.toBuilder().accountLockoutEnabled(true).invalidLoginsBeforeLockout(5).build();
settings = adminOrgApi.editPasswordPolicy(org.getId(), settings);
}
assertTrue(settings.isAccountLockoutEnabled());
for (int i = 0; i < settings.getInvalidLoginsBeforeLockout() + 1; i++) {
try {
sessionApi.loginUserInOrgWithPassword(URI.create(endpoint + "/sessions"), user.getName(), org.getName(), "wrongpassword!");
fail("Managed to login using the wrong password!");
} catch (AuthorizationException e) {
} catch (Exception e) {
fail("Expected AuthorizationException", e);
}
}
user = userApi.get(user.getHref());
assertTrue(user.isLocked());
try {
sessionApi.loginUserInOrgWithPassword(URI.create(endpoint + "/sessions"), user.getName(), org.getName(), "newPassword");
fail("Managed to login to locked account!");
} catch (AuthorizationException e) {
} catch (Exception e) {
fail("Expected AuthorizationException", e);
}
userApi.unlock(user.getHref());
user = userApi.get(user.getHref());
assertFalse(user.isLocked());
// Double-check the user can now login again
SessionWithToken sessionWithToken = sessionApi.loginUserInOrgWithPassword(URI.create(endpoint + "/sessions"), user.getName(), org.getName(), "newPassword");
assertNotNull(sessionWithToken.getToken());
sessionApi.logoutSessionWithToken(sessionWithToken.getSession().getHref(), sessionWithToken.getToken());
// Return account settings to the previous values, if necessary
if (settingsToRevertTo != null) {
adminOrgApi.editPasswordPolicy(org.getId(), settingsToRevertTo);
}
}
@Test(description = "DELETE /admin/user/{id}", dependsOnMethods = { "testAddUser" })
public void testRemoveUser() {
// Create a user to be removed (so we remove dependencies on test ordering)
User newUser = randomTestUser("testRemoveUser"+getTestDateTimeStamp());
User userToBeDeleted = userApi.addUserToOrg(newUser, org.getId());
// Delete the user
userApi.remove(userToBeDeleted.getHref());
// Confirm cannot no longer be accessed
User removed = userApi.get(userToBeDeleted.getHref());
assertNull(removed);
}
}