/******************************************************************************* * Copyright (c) 2010, 2015 IBM Corporation and others * All rights reserved. This program and the accompanying materials * are made available under the terms of the Eclipse Public License v1.0 * which accompanies this distribution, and is available at * http://www.eclipse.org/legal/epl-v10.html * * Contributors: * IBM Corporation - initial API and implementation *******************************************************************************/ package org.eclipse.orion.server.tests.servlets.users; import static org.junit.Assert.assertEquals; import static org.junit.Assert.assertFalse; import static org.junit.Assert.assertTrue; import static org.junit.Assert.fail; import java.io.IOException; import java.io.OutputStream; import java.net.HttpURLConnection; import org.eclipse.core.filesystem.EFS; import org.eclipse.core.filesystem.IFileStore; import org.eclipse.core.runtime.CoreException; import org.eclipse.orion.internal.server.servlets.useradmin.UserHandlerV1; import org.eclipse.orion.internal.server.servlets.workspace.authorization.AuthorizationService; import org.eclipse.orion.server.core.OrionConfiguration; import org.eclipse.orion.server.core.metastore.ProjectInfo; import org.eclipse.orion.server.core.metastore.UserInfo; import org.eclipse.orion.server.core.metastore.WorkspaceInfo; import org.eclipse.orion.server.core.users.UserConstants; import org.json.JSONArray; import org.json.JSONException; import org.json.JSONObject; import org.junit.Test; import org.xml.sax.SAXException; import com.meterware.httpunit.WebConversation; import com.meterware.httpunit.WebRequest; import com.meterware.httpunit.WebResponse; public class BasicUsersTest extends UsersTest { @Test public void testGetUsersList() throws IOException, SAXException, JSONException { WebConversation webConversation = new WebConversation(); webConversation.setExceptionsThrownOnErrorStatus(false); WebRequest request = getGetUsersRequest("", true); WebResponse response = webConversation.getResponse(request); assertEquals(response.getText(), HttpURLConnection.HTTP_OK, response.getResponseCode()); JSONObject responseObject = new JSONObject(response.getText()); assertTrue("Invalid format of response.", responseObject.has(UserHandlerV1.USERS)); JSONArray usersArray = responseObject.getJSONArray(UserHandlerV1.USERS); assertTrue("Too small number of users returned", usersArray.length() > 1); assertTrue(responseObject.has(UserHandlerV1.USERS_START)); assertTrue(responseObject.has(UserHandlerV1.USERS_ROWS)); assertTrue(responseObject.has(UserHandlerV1.USERS_LENGTH)); assertEquals(0, responseObject.getInt(UserHandlerV1.USERS_START)); if (responseObject.getInt(UserHandlerV1.USERS_LENGTH) >= 20) { assertTrue(responseObject.getInt(UserHandlerV1.USERS_ROWS) == 20); } else { assertTrue(responseObject.getInt(UserHandlerV1.USERS_LENGTH) < 20); } } @Test public void testGetUsersForbidden() throws IOException, SAXException, JSONException { WebConversation webConversation = new WebConversation(); webConversation.setExceptionsThrownOnErrorStatus(false); WebRequest request = getGetUsersRequest("", false); WebResponse response = webConversation.getResponse(request); assertEquals(HttpURLConnection.HTTP_FORBIDDEN, response.getResponseCode()); JSONObject responseObject = new JSONObject(response.getText()); assertTrue(responseObject.has("HttpCode")); assertEquals(HttpURLConnection.HTTP_FORBIDDEN, responseObject.getInt("HttpCode")); } @Test public void testCreateDuplicateUser() throws IOException, SAXException, JSONException { WebConversation webConversation = new WebConversation(); webConversation.setExceptionsThrownOnErrorStatus(false); // create user JSONObject json = new JSONObject(); json.put(UserConstants.USER_NAME, "testDupUser"); json.put(UserConstants.FULL_NAME, "username_testCreateDuplicateUser"); json.put(UserConstants.PASSWORD, "pass_" + System.currentTimeMillis()); WebRequest request = getPostUsersRequest("", json, true); WebResponse response = webConversation.getResponse(request); assertEquals(response.getText(), HttpURLConnection.HTTP_CREATED, response.getResponseCode()); //try creating same user again response = webConversation.getResponse(request); assertEquals(response.getText(), HttpURLConnection.HTTP_BAD_REQUEST, response.getResponseCode()); } @Test public void testCreateUserDuplicateEmail() throws IOException, SAXException, JSONException { WebConversation webConversation = new WebConversation(); webConversation.setExceptionsThrownOnErrorStatus(false); // create user JSONObject json = new JSONObject(); json.put(UserConstants.USER_NAME, "testDupEmail"); json.put(UserConstants.FULL_NAME, "username_testCreateUserDuplicateEmail"); json.put(UserConstants.PASSWORD, "pass_" + System.currentTimeMillis()); json.put(UserConstants.EMAIL, "username@example.com"); WebRequest request = getPostUsersRequest("", json, true); WebResponse response = webConversation.getResponse(request); assertEquals(response.getText(), HttpURLConnection.HTTP_CREATED, response.getResponseCode()); //try creating another user with same email address json.put(UserConstants.USER_NAME, "usertestCreateUserDuplicateEmail2"); request = getPostUsersRequest("", json, true); response = webConversation.getResponse(request); assertEquals(response.getText(), HttpURLConnection.HTTP_BAD_REQUEST, response.getResponseCode()); } @Test public void testCreateUserEmailDifferentCase() throws IOException, SAXException, JSONException { WebConversation webConversation = new WebConversation(); webConversation.setExceptionsThrownOnErrorStatus(false); // create user JSONObject json = new JSONObject(); json.put(UserConstants.USER_NAME, "testCaseEmail"); json.put(UserConstants.FULL_NAME, "username_testCreateUserEmailDifferentCase"); json.put(UserConstants.PASSWORD, "pass_" + System.currentTimeMillis()); json.put(UserConstants.EMAIL, "duplicateemail@example.com"); WebRequest request = getPostUsersRequest("", json, true); WebResponse response = webConversation.getResponse(request); assertEquals(response.getText(), HttpURLConnection.HTTP_CREATED, response.getResponseCode()); //try creating another user with same email address but different case json.put(UserConstants.EMAIL, "DUPLICATEEMAIL@example.com"); json.put(UserConstants.USER_NAME, "testCaseEmail2"); request = getPostUsersRequest("", json, true); response = webConversation.getResponse(request); assertEquals(response.getText(), HttpURLConnection.HTTP_BAD_REQUEST, response.getResponseCode()); } /** * Tests creating users with username that can't be represented in a URI. * @throws IOException * @throws SAXException * @throws JSONException */ @Test public void testCreateUserInvalidName() throws IOException, SAXException, JSONException { WebConversation webConversation = new WebConversation(); webConversation.setExceptionsThrownOnErrorStatus(false); //restrict to alphanumeric characters String invalidChars = " !@#$%^&*()-=_+[]{}\";':\\/><.,`~"; for (int i = 0; i < invalidChars.length(); i++) { String username = "bad" + invalidChars.charAt(i) + "name"; // create user JSONObject json = new JSONObject(); json.put(UserConstants.USER_NAME, username); json.put(UserConstants.FULL_NAME, "Tom"); json.put(UserConstants.PASSWORD, "pass_" + System.currentTimeMillis()); WebRequest request = getPostUsersRequest("", json, true); WebResponse response = webConversation.getResponse(request); assertEquals("Should fail with name: " + username, HttpURLConnection.HTTP_BAD_REQUEST, response.getResponseCode()); } } @Test public void testCreateDeleteUsers() throws IOException, SAXException, JSONException { WebConversation webConversation = new WebConversation(); webConversation.setExceptionsThrownOnErrorStatus(false); // create user JSONObject json = new JSONObject(); json.put(UserConstants.USER_NAME, "user" + System.currentTimeMillis()); json.put(UserConstants.FULL_NAME, "username_" + System.currentTimeMillis()); json.put(UserConstants.PASSWORD, "pass_" + System.currentTimeMillis()); WebRequest request = getPostUsersRequest("", json, true); WebResponse response = webConversation.getResponse(request); assertEquals(response.getText(), HttpURLConnection.HTTP_CREATED, response.getResponseCode()); JSONObject responseObject = new JSONObject(response.getText()); assertTrue("Response should contain user location", responseObject.has(UserConstants.LOCATION)); // check user details String location = responseObject.getString(UserConstants.LOCATION); request = getGetUsersRequest(location, true); response = webConversation.getResponse(request); assertEquals(response.getText(), HttpURLConnection.HTTP_OK, response.getResponseCode()); responseObject = new JSONObject(response.getText()); assertEquals("Invalid user login", json.getString(UserConstants.USER_NAME), responseObject.getString(UserConstants.USER_NAME)); assertEquals("Invalid user name", json.getString(UserConstants.FULL_NAME), responseObject.getString(UserConstants.FULL_NAME)); assertFalse("Response shouldn't contain password", responseObject.has(UserConstants.PASSWORD)); // check if user can authenticate request = getGetUsersRequest("", true); // create some project contents to test that delete user also deletes all project contents try { UserInfo userInfo = OrionConfiguration.getMetaStore().readUser(json.getString(UserConstants.USER_NAME)); String workspaceName = "Orion Content"; WorkspaceInfo workspaceInfo = new WorkspaceInfo(); workspaceInfo.setFullName(workspaceName); workspaceInfo.setUserId(userInfo.getUniqueId()); OrionConfiguration.getMetaStore().createWorkspace(workspaceInfo); String projectName = "Orion Project"; ProjectInfo projectInfo = new ProjectInfo(); projectInfo.setFullName(projectName); projectInfo.setWorkspaceId(workspaceInfo.getUniqueId()); OrionConfiguration.getMetaStore().createProject(projectInfo); IFileStore projectFolder = OrionConfiguration.getMetaStore().getDefaultContentLocation(projectInfo); projectInfo.setContentLocation(projectFolder.toURI()); OrionConfiguration.getMetaStore().updateProject(projectInfo); if (!projectFolder.fetchInfo().exists()) { projectFolder.mkdir(EFS.NONE, null); } assertTrue(projectFolder.fetchInfo().exists() && projectFolder.fetchInfo().isDirectory()); String fileName = "file.html"; IFileStore file = projectFolder.getChild(fileName); try { OutputStream outputStream = file.openOutputStream(EFS.NONE, null); outputStream.write("<!doctype html>".getBytes()); outputStream.close(); } catch (IOException e) { fail("Count not create a test file in the Orion Project:" + e.getLocalizedMessage()); } assertTrue("the file in the project folder should exist.", file.fetchInfo().exists()); } catch (CoreException e) { fail("Could not create project contents for the user"); } // delete user request = getDeleteUsersRequest(location, true); setAuthentication(request, json.getString(UserConstants.USER_NAME), json.getString(UserConstants.PASSWORD)); response = webConversation.getResponse(request); assertEquals("User could not delete his own account, response: " + response.getText(), HttpURLConnection.HTTP_OK, response.getResponseCode()); } @Test public void testCreateDeleteRights() throws IOException, SAXException, CoreException, JSONException { WebConversation webConversation = new WebConversation(); webConversation.setExceptionsThrownOnErrorStatus(false); // create user JSONObject json = new JSONObject(); json.put(UserConstants.USER_NAME, "testCrDelRights"); json.put(UserConstants.FULL_NAME, "username_" + System.currentTimeMillis()); json.put(UserConstants.EMAIL, "test@test_" + System.currentTimeMillis()); json.put("workspace", "workspace_" + System.currentTimeMillis()); json.put(UserConstants.PASSWORD, "pass_" + System.currentTimeMillis()); WebRequest request = getPostUsersRequest("", json, true); WebResponse response = webConversation.getResponse(request); assertEquals(response.getText(), HttpURLConnection.HTTP_CREATED, response.getResponseCode()); JSONObject responseObject = new JSONObject(response.getText()); assertTrue("Response should container user name", responseObject.has(UserConstants.USER_NAME)); String username = responseObject.getString(UserConstants.USER_NAME); String location = responseObject.getString(UserConstants.LOCATION); // check if user can authenticate request = getGetUsersRequest("", true); setAuthentication(request, json.getString(UserConstants.USER_NAME), json.getString(UserConstants.PASSWORD)); response = webConversation.getResponse(request); assertEquals("User has no admin privileges", HttpURLConnection.HTTP_FORBIDDEN, response.getResponseCode()); // add admin rights AuthorizationService.addUserRight(username, "/users"); AuthorizationService.addUserRight(username, "/users/*"); // check if user can authenticate request = getGetUsersRequest("", true); setAuthentication(request, json.getString(UserConstants.USER_NAME), json.getString(UserConstants.PASSWORD)); response = webConversation.getResponse(request); assertEquals("User has no admin privileges", HttpURLConnection.HTTP_OK, response.getResponseCode()); // delete admin rights AuthorizationService.removeUserRight(username, "/users"); AuthorizationService.removeUserRight(username, "/users/*"); // check if user can authenticate request = getGetUsersRequest("", true); setAuthentication(request, json.getString(UserConstants.USER_NAME), json.getString(UserConstants.PASSWORD)); response = webConversation.getResponse(request); assertEquals("User has no admin privileges", HttpURLConnection.HTTP_FORBIDDEN, response.getResponseCode()); // delete user request = getDeleteUsersRequest(location, true); response = webConversation.getResponse(request); assertEquals(response.getText(), HttpURLConnection.HTTP_OK, response.getResponseCode()); } @Test public void testUpdateUsers() throws IOException, SAXException, JSONException { WebConversation webConversation = new WebConversation(); webConversation.setExceptionsThrownOnErrorStatus(false); // create user JSONObject json = new JSONObject(); json.put(UserConstants.USER_NAME, "user" + System.currentTimeMillis()); json.put(UserConstants.FULL_NAME, "username_" + System.currentTimeMillis()); String oldPass = "pass_" + System.currentTimeMillis(); json.put(UserConstants.PASSWORD, oldPass); WebRequest request = getPostUsersRequest("", json, true); WebResponse response = webConversation.getResponse(request); assertEquals(response.getText(), HttpURLConnection.HTTP_CREATED, response.getResponseCode()); JSONObject responseObject = new JSONObject(response.getText()); assertTrue("Response should contain user location", responseObject.has(UserConstants.LOCATION)); String location = responseObject.getString(UserConstants.LOCATION); // update user JSONObject updateBody = new JSONObject(); updateBody.put(UserConstants.FULL_NAME, "usernameUpdate_" + System.currentTimeMillis()); updateBody.put(UserConstants.OLD_PASSWORD, oldPass); updateBody.put(UserConstants.PASSWORD, "passUpdate_" + System.currentTimeMillis()); request = getPutUsersRequest(location, updateBody, true); response = webConversation.getResponse(request); assertEquals(response.getText(), HttpURLConnection.HTTP_OK, response.getResponseCode()); // check user details request = getGetUsersRequest(location, true); response = webConversation.getResponse(request); assertEquals(response.getText(), HttpURLConnection.HTTP_OK, response.getResponseCode()); responseObject = new JSONObject(response.getText()); assertEquals("Invalid user login", json.get(UserConstants.USER_NAME), responseObject.getString(UserConstants.USER_NAME)); assertEquals("Invalid user name", updateBody.getString(UserConstants.FULL_NAME), responseObject.getString(UserConstants.FULL_NAME)); assertFalse("Response shouldn't contain password", responseObject.has(UserConstants.PASSWORD)); // check if user can authenticate and does not have admin role request = getGetUsersRequest("", true); setAuthentication(request, json.getString(UserConstants.USER_NAME), updateBody.getString(UserConstants.PASSWORD)); response = webConversation.getResponse(request); assertEquals("User with no roles has admin privilegges", HttpURLConnection.HTTP_FORBIDDEN, response.getResponseCode()); // delete user request = getDeleteUsersRequest(location, true); response = webConversation.getResponse(request); assertEquals(response.getText(), HttpURLConnection.HTTP_OK, response.getResponseCode()); } @Test public void testResetUser() throws IOException, SAXException, JSONException { WebConversation webConversation = new WebConversation(); webConversation.setExceptionsThrownOnErrorStatus(false); // create user JSONObject json = new JSONObject(); String username = "user" + System.currentTimeMillis(); json.put(UserConstants.USER_NAME, username); json.put(UserConstants.FULL_NAME, "username" + System.currentTimeMillis()); json.put("roles", "admin"); String oldPass = "pass_" + System.currentTimeMillis(); json.put(UserConstants.PASSWORD, oldPass); WebRequest request = getPostUsersRequest("", json, true); WebResponse response = webConversation.getResponse(request); assertEquals(response.getText(), HttpURLConnection.HTTP_CREATED, response.getResponseCode()); JSONObject responseObject = new JSONObject(response.getText()); assertTrue("Response should contian user location", responseObject.has(UserConstants.LOCATION)); String location = responseObject.getString(UserConstants.LOCATION); //reset password String newPass = "passUpdate_" + System.currentTimeMillis(); json = new JSONObject(); json.put(UserConstants.USER_NAME, username); json.put(UserConstants.PASSWORD, newPass); json.put(UserConstants.RESET, "true"); request = getPostUsersRequest(location, json, true); response = webConversation.getResponse(request); assertEquals(response.getText(), HttpURLConnection.HTTP_OK, response.getResponseCode()); // check if user can authenticate request = getGetUsersRequest(location, true); setAuthentication(request, json.getString(UserConstants.USER_NAME), newPass); response = webConversation.getResponse(request); assertEquals("User cannot log in with new credentials", HttpURLConnection.HTTP_OK, response.getResponseCode()); // delete user request = getDeleteUsersRequest(location, true); response = webConversation.getResponse(request); assertEquals(response.getText(), HttpURLConnection.HTTP_OK, response.getResponseCode()); } @Test public void testCreateUser() throws JSONException, IOException, SAXException { WebConversation webConversation = new WebConversation(); webConversation.setExceptionsThrownOnErrorStatus(false); String username1 = "user1" + System.currentTimeMillis(); String password = "pass" + System.currentTimeMillis(); // create user JSONObject json = new JSONObject(); json.put(UserConstants.USER_NAME, username1); json.put(UserConstants.PASSWORD, password); WebRequest request = getPostUsersRequest("", json, true); WebResponse response = webConversation.getResponse(request); assertEquals(response.getText(), HttpURLConnection.HTTP_CREATED, response.getResponseCode()); JSONObject responseObject = new JSONObject(response.getText()); assertTrue(responseObject.has(UserConstants.LOCATION)); assertEquals("/users/" + username1, responseObject.getString(UserConstants.LOCATION)); assertTrue(responseObject.getBoolean(UserConstants.HAS_PASSWORD)); assertFalse(responseObject.getBoolean(UserConstants.EMAIL_CONFIRMED)); assertTrue(responseObject.has(UserConstants.USER_NAME)); assertEquals(username1, responseObject.getString(UserConstants.USER_NAME)); assertTrue(responseObject.has(UserConstants.FULL_NAME)); assertEquals(username1, responseObject.getString(UserConstants.FULL_NAME)); } @Test public void testChangeUserName() throws JSONException, IOException, SAXException { WebConversation webConversation = new WebConversation(); webConversation.setExceptionsThrownOnErrorStatus(false); String username1 = "user1" + System.currentTimeMillis(); String password = "pass" + System.currentTimeMillis(); // create user JSONObject json = new JSONObject(); json.put(UserConstants.USER_NAME, username1); json.put(UserConstants.PASSWORD, password); WebRequest request = getPostUsersRequest("", json, true); WebResponse response = webConversation.getResponse(request); assertEquals(response.getText(), HttpURLConnection.HTTP_CREATED, response.getResponseCode()); JSONObject responseObject = new JSONObject(response.getText()); assertTrue("Response should contian user location", responseObject.has(UserConstants.LOCATION)); String location = responseObject.getString(UserConstants.LOCATION); String username2 = "user2" + System.currentTimeMillis(); JSONObject updateBody = new JSONObject(); updateBody.put(UserConstants.USER_NAME, username2); request = getPutUsersRequest(location, updateBody, true); response = webConversation.getResponse(request); assertEquals(response.getText(), HttpURLConnection.HTTP_OK, response.getResponseCode()); // When you rename the user, the location becomes /users/{newUser} location = "/users/" + username2; request = getGetUsersRequest(location, true); setAuthentication(request, username2, password); response = webConversation.getResponse(request); assertEquals("User could not authenticate with new login" + response.getText(), HttpURLConnection.HTTP_OK, response.getResponseCode()); responseObject = new JSONObject(response.getText()); assertEquals("New login wasn't returned in user details", username2, responseObject.get(UserConstants.USER_NAME)); } /** * @return a string representing the test users name. */ public String getTestUserName() { return "testNoAccess"; } public String getTestUserPassword() { return "testNoAccess"; } @Override public void setAdminRights(UserInfo adminUser) throws CoreException { //by default allow 'admin' to modify all users data AuthorizationService.addUserRight(adminUser.getUniqueId(), "/users"); AuthorizationService.addUserRight(adminUser.getUniqueId(), "/users/*"); } @Override public void setTestUserRights(UserInfo testUser) throws CoreException { //by default allow 'test' to modify his own data AuthorizationService.addUserRight(testUser.getUniqueId(), "/users/" + testUser.getUniqueId()); } }