Java tutorial
/******************************************************************************* * Copyright (c) 2015 IBM Corp. * * Licensed 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 com.ibm.ws.lars.rest; import static com.ibm.ws.lars.rest.RepositoryContext.RC_REJECT; import static org.junit.Assert.assertEquals; import java.io.IOException; import java.nio.charset.StandardCharsets; import java.util.ArrayList; import java.util.Collection; import org.apache.http.ParseException; import org.apache.http.client.ClientProtocolException; import org.apache.http.entity.ContentType; import org.junit.Assert; import org.junit.Before; import org.junit.Rule; import org.junit.Test; import org.junit.runner.RunWith; import org.junit.runners.Parameterized; import org.junit.runners.Parameterized.Parameters; import com.ibm.ws.lars.rest.RepositoryContext.Protocol; import com.ibm.ws.lars.rest.exceptions.InvalidJsonAssetException; import com.ibm.ws.lars.rest.model.Asset; import com.ibm.ws.lars.rest.model.AssetList; import com.ibm.ws.lars.rest.model.Attachment; import com.ibm.ws.lars.testutils.FatUtils; /** * Test that security permissions work correctly. */ @RunWith(Parameterized.class) public class PermissionTest { @Rule public RepositoryContext adminContext; @Rule public RepositoryContext userContext; /** * HTTP URL for the test instance where read operations are restricted to users with the User * role. */ private static final String RESTRICTED_URL_HTTP = RepositoryContext.DEFAULT_URLS.get(Protocol.HTTP); /** * HTTPS URL for the test instance where read operations are restricted to users with the User * role. */ private static final String RESTRICTED_URL_HTTPS = RepositoryContext.DEFAULT_URLS.get(Protocol.HTTPS); /** * HTTP URL for the test instance where read operations are unrestricted. * <p> * Write operations are still restricted to users with the Admin role. */ private static final String UNRESTRICTED_URL_HTTP = "http://localhost:" + FatUtils.LIBERTY_PORT_HTTP + "/unrestricted" + FatUtils.LARS_APPLICATION_ROOT; /** * HTTPS URL for the test instance where read operations are unrestricted. * <p> * Write operations are still restricted to users with the Admin role. */ private static final String UNRESTRICTED_URL_HTTPS = "https://localhost:" + FatUtils.LIBERTY_PORT_HTTPS + "/unrestricted" + FatUtils.LARS_APPLICATION_ROOT; /** * The available roles that we expect test users to be mapped to by the test server * configuration. */ private enum Role { ADMIN, USER, NONE; public boolean isAdmin() { return this == ADMIN; } public boolean isUser() { return this == ADMIN || this == USER; } } /** * The users to test with. * <p> * Each user has a username and password and two roles. One is the role we expect the user to be * mapped to for the unrestricted configuration. The other is the role we expect the user to be * mapped to in the restricted configuration. * <p> * This enum is used to build the test parameters in {@link PermissionTest#makeParameters()}. */ private enum User { ADMIN("admin", "passw0rd", Role.ADMIN, Role.ADMIN), USER("user", "passw0rd", Role.USER, Role.USER), NO_ROLE( "noRoleUser", "passw0rd", Role.USER, Role.NONE), BAD_ADMIN_PW("admin", "wrongPassw0rd", Role.USER, Role.NONE), BAD_USER_PW("user", "wrongPassw0rd", Role.USER, Role.NONE), UNAUTHENTICATED(null, null, Role.USER, Role.NONE); String username; String password; Role restrictedConfigRole; Role unrestrictedConfigRole; private User(String username, String password, Role unrestrictedConfigRole, Role restrictedConfigRole) { this.username = username; this.password = password; this.restrictedConfigRole = restrictedConfigRole; this.unrestrictedConfigRole = unrestrictedConfigRole; } } private Asset testAsset; private Asset createdAsset; private Asset assetWithAttachments; private Asset createAssetWithAttachments; private String attachmentName; private byte[] attachmentContent; private Attachment attachment; private Attachment createdAttachment; /** * The role that we expect the user in the userContext to be mapped to * <p> * Tests should look at this field when deciding whether or not operations that they run from * the userContext should succeed or fail. */ private final Role role; /** * Build the test parameters * <p> * We want to test the same methods with multiple users which we expect to map to different * roles. JUnit lets us construct a list of test parameters and each test will run which each * set of test parameters. * <p> * The parameters we are passing are URL, username, password, expected role and label. The label * is just used to name the test so we can tell them apart in the test results. * * @return the test parameters */ @Parameters(name = "{4}") public static Collection<Object[]> makeParameters() { Collection<Object[]> data = new ArrayList<>(); for (User user : User.values()) { data.add(new Object[] { RESTRICTED_URL_HTTP, user.username, user.password, user.restrictedConfigRole, user + " - restricted - http" }); data.add(new Object[] { UNRESTRICTED_URL_HTTP, user.username, user.password, user.unrestrictedConfigRole, user + " - unrestricted - http" }); data.add(new Object[] { RESTRICTED_URL_HTTPS, user.username, user.password, user.restrictedConfigRole, user + " - restricted - https" }); data.add(new Object[] { UNRESTRICTED_URL_HTTPS, user.username, user.password, user.unrestrictedConfigRole, user + " - unrestricted - https" }); } System.out.println("sending data: " + data.size()); return data; } /** * Process the test parameters and set up the adminContext and userContext. */ public PermissionTest(String url, String username, String password, Role role, String label) { adminContext = RepositoryContext.createAsAdmin(url, true); userContext = new RepositoryContext(url, username, password, false); this.role = role; } @Before public void setUp() throws IOException, InvalidJsonAssetException { testAsset = AssetUtils.getTestAsset(); createdAsset = adminContext.addAssetNoAttachments(testAsset); assetWithAttachments = AssetUtils.getTestAsset(); createAssetWithAttachments = adminContext.addAssetNoAttachments(assetWithAttachments); attachmentName = "nocontent.txt"; attachmentContent = "I am the content.\nThere is not much content to be had.\n" .getBytes(StandardCharsets.UTF_8); attachment = AssetUtils.getTestAttachmentWithContent(); createdAttachment = adminContext.doPostAttachmentWithContent(createAssetWithAttachments.get_id(), attachmentName, attachment, attachmentContent, ContentType.APPLICATION_OCTET_STREAM); } /** * * GET /assets * * Allowed for ADMIN and USER */ @Test public void testGetAllAssets() throws InvalidJsonAssetException, ParseException, IOException { if (role.isUser()) { AssetList assets = userContext.doGetAllAssets(200); assertEquals("Wrong number of assets", 2, assets.size()); } else { userContext.doGetAllAssetsBad(RC_REJECT); } } /** * POST /assets * * Allowed for ADMIN * */ @Test public void testPostAsset() throws InvalidJsonAssetException, IOException { Asset asset = AssetUtils.getTestAsset(); if (role.isAdmin()) { Asset returnedAsset = userContext.addAssetNoAttachments(asset); AssetUtils.assertUploadedAssetEquivalentToOriginal( "Returned asset should match the asset that was uploaded", asset, returnedAsset); } else { userContext.addBadAsset(asset, RC_REJECT); } } /** * GET /assets/{assetId} * * Allowed for ADMIN and USER */ @Test public void testGetAsset() throws InvalidJsonAssetException, IOException { if (role.isUser()) { Asset returnedAsset = userContext.getAsset(createdAsset.get_id()); AssetUtils.assertUploadedAssetEquivalentToOriginal( "Returned asset should match the asset that was uploaded", testAsset, returnedAsset); } else { userContext.getBadAsset(createdAsset.get_id(), RC_REJECT); } } /** * DELETE /assets/{assetId} * * Allowed for ADMIN */ @Test public void testDeleteAsset() throws IOException { if (role.isAdmin()) { userContext.deleteAsset(createdAsset.get_id(), 204); } else { userContext.deleteAsset(createdAsset.get_id(), RC_REJECT); } } /** * POST /assets/{assetId}/attachments Content-type: multipart/formdata * * Allowed for ADMIN * * @throws IOException * @throws InvalidJsonAssetException * @throws ClientProtocolException */ @Test public void testPostAttachmentNoContent() throws ClientProtocolException, InvalidJsonAssetException, IOException { Attachment attachment = AssetUtils.getTestAttachmentNoContent(); if (role.isAdmin()) { userContext.doPostAttachmentNoContent(createdAsset.get_id(), "theAttachment", attachment); } else { userContext.doPostBadAttachmentNoContent(createdAsset.get_id(), "theAttachment", attachment, RC_REJECT, null); } } /** * POST /assets/{assetId}/attachments Content-type: application/json * * Allowed for ADMIN * */ @Test public void testPostAttachmentWithContent() throws ClientProtocolException, InvalidJsonAssetException, IOException { byte[] content = "I am the content.\nThere is not much to me.\n".getBytes(StandardCharsets.UTF_8); String name = "theAttachment"; if (role.isAdmin()) { userContext.doPostAttachmentWithContent(createdAsset.get_id(), name, attachment, content, ContentType.APPLICATION_OCTET_STREAM); } else { userContext.doPostBadAttachmentWithContent(createdAsset.get_id(), "I am the attachment!", attachment, content, ContentType.APPLICATION_OCTET_STREAM, RC_REJECT, null); } } /** * DELETE /assets/{assetId}/attachments/{attachmentId} * * Allowed for ADMIN */ @Test public void testDeleteAttachment() throws ClientProtocolException, IOException { if (role.isAdmin()) { userContext.doDeleteAttachment(createdAsset.get_id(), createdAttachment.get_id(), 204); } else { userContext.doDeleteAttachment(createdAsset.get_id(), createdAttachment.get_id(), RC_REJECT); } } /** * GET /assets/{assetId}/attachments/{attachmentId}/{name} * * Allowed for ADMIN and USER */ @Test public void testGetAttachmentContent() throws IOException { if (role.isUser()) { byte[] returnedContent = userContext.doGetAttachmentContent(createAssetWithAttachments.get_id(), createdAttachment.get_id(), attachmentName); Assert.assertArrayEquals("Returned content should be equal to that which was uploaded", attachmentContent, returnedContent); } else { userContext.doGetAttachmentContentInError(createAssetWithAttachments.get_id(), createdAttachment.get_id(), attachmentName, RC_REJECT, null); } } /** * PUT /assets/{assetId}/state * * Allowed for ADMIN * */ @Test public void testPutAssetState() throws InvalidJsonAssetException, IOException { if (role.isAdmin()) { userContext.updateAssetState(createdAsset.get_id(), Asset.StateAction.PUBLISH.getValue(), 200); } else { userContext.updateAssetState(createdAsset.get_id(), Asset.StateAction.PUBLISH.getValue(), RC_REJECT); } } /** * GET /assets/summary * * Allowed for ADMIN and USER */ @Test public void testGetAssetSummary() throws Exception { if (role.isUser()) { userContext.getAssetSummary("fields=name"); } else { userContext.getBadAssetSummary("fields=name", RC_REJECT); } } }