/** * DO NOT ALTER OR REMOVE COPYRIGHT NOTICES OR THIS HEADER. * * Copyright (c) 2009 Sun Microsystems Inc. All Rights Reserved * * The contents of this file are subject to the terms * of the Common Development and Distribution License * (the License). You may not use this file except in * compliance with the License. * * You can obtain a copy of the License at * https://opensso.dev.java.net/public/CDDLv1.0.html or * opensso/legal/CDDLv1.0.txt * See the License for the specific language governing * permission and limitations under the License. * * When distributing Covered Code, include this CDDL * Header Notice in each file and include the License file * at opensso/legal/CDDLv1.0.txt. * If applicable, add the following below the CDDL Header, * with the fields enclosed by brackets [] replaced by * your own identifying information: * "Portions Copyrighted [year] [name of copyright owner]" * * $Id: RestTest.java,v 1.3 2009/11/24 23:08:35 veiming Exp $ * * Portions Copyrighted 2014 ForgeRock AS */ /** * Portions copyright 2014 ForgeRock AS. */ package com.sun.identity.rest; import com.sun.identity.entitlement.util.AuthUtils; import com.iplanet.am.util.SystemProperties; import com.iplanet.sso.SSOToken; import com.sun.identity.entitlement.Entitlement; import com.sun.identity.entitlement.EntitlementSubject; import com.sun.identity.entitlement.JSONEntitlement; import com.sun.identity.entitlement.NumericAttributeCondition; import com.sun.identity.entitlement.Privilege; import com.sun.identity.entitlement.PrivilegeManager; import com.sun.identity.entitlement.opensso.SubjectUtils; import com.sun.identity.entitlement.util.IdRepoUtils; import com.sun.identity.idm.AMIdentity; import com.sun.identity.unittest.UnittestLog; import com.sun.jersey.api.client.Client; import com.sun.jersey.api.client.WebResource; import com.sun.jersey.api.representation.Form; import com.sun.identity.shared.Constants; import com.sun.identity.shared.encode.Hash; import com.sun.jersey.api.client.UniformInterfaceException; import java.net.URLEncoder; import java.util.HashMap; import java.util.Map; import java.util.Set; import javax.security.auth.Subject; import javax.ws.rs.core.Cookie; import org.forgerock.openam.entitlement.conditions.subject.AuthenticatedUsers; import org.json.JSONArray; import org.json.JSONObject; import org.testng.annotations.AfterClass; import org.testng.annotations.BeforeClass; import org.testng.annotations.Test; /** * To Test REST interface * @author Ravi Hingarajiya */ public class RestTest { private static final String REALM = "/"; private static final String AGENT_NAME = "RestTestAgent"; private static final String PRIVILEGE_NAME = "RestTestPrivilege"; private Subject adminSubject = SubjectUtils.createSuperAdminSubject(); private static final String RESOURCE_NAME = "http://www.resttest.com"; private static final String ATTR_NAME = "bankAcc"; private static final float ATTR_VAL = 1234f; private AMIdentity user; private String userTokenIdHeader; private Cookie cookie; private String hashedUserTokenId; private WebResource entitlementClient; private WebResource entitlementsClient; private WebResource decisionClient; private WebResource decisionsClient; @BeforeClass public void setup() throws Exception { try { PrivilegeManager pm = PrivilegeManager.getInstance(REALM, adminSubject); Privilege privilege = Privilege.getNewInstance(); privilege.setName(PRIVILEGE_NAME); Map actions = new HashMap(); actions.put("GET", true); Entitlement entitlement = new Entitlement(RESOURCE_NAME + "/*", actions); privilege.setEntitlement(entitlement); EntitlementSubject sbj = new AuthenticatedUsers(); privilege.setSubject(sbj); NumericAttributeCondition cond = new NumericAttributeCondition(); cond.setAttributeName(ATTR_NAME); cond.setOperator(NumericAttributeCondition.Operator.EQUAL); cond.setValue(ATTR_VAL); privilege.setCondition(cond); pm.add(privilege); user = IdRepoUtils.createAgent(REALM, AGENT_NAME); SSOToken ssoToken = AuthUtils.authenticate(REALM, AGENT_NAME, AGENT_NAME); String userTokenId = ssoToken.getTokenID().toString(); hashedUserTokenId = Hash.hash(userTokenId); userTokenIdHeader = RestServiceManager.SSOTOKEN_SUBJECT_PREFIX + RestServiceManager.SUBJECT_DELIMITER + userTokenId; String cookieValue = userTokenId; if (Boolean.parseBoolean( SystemProperties.get(Constants.AM_COOKIE_ENCODE, "false"))) { cookieValue = URLEncoder.encode(userTokenId, "UTF-8"); } cookie = new Cookie(SystemProperties.get(Constants.AM_COOKIE_NAME), cookieValue); String serverURL = SystemProperties.getServerInstanceName(); decisionClient = Client.create().resource(serverURL + "/ws/1/entitlement/decision"); decisionsClient = Client.create().resource(serverURL + "/ws/1/entitlement/decisions"); entitlementClient = Client.create().resource(serverURL + "/ws/1/entitlement/entitlement"); entitlementsClient = Client.create().resource(serverURL + "/ws/1/entitlement/entitlements"); } catch (Exception e) { UnittestLog.logError("RestTest.setup() failed:", e); throw e; } } @AfterClass public void cleanup() throws Exception { PrivilegeManager pm = PrivilegeManager.getInstance(REALM, adminSubject); pm.remove(PRIVILEGE_NAME); IdRepoUtils.deleteIdentity(REALM, user); } @Test public void getDecisionTest() throws Exception { Form params = new Form(); params.add("subject", hashedUserTokenId); params.add("resource", RESOURCE_NAME + "/index.html"); params.add("action", "GET"); params.add("env", ATTR_NAME + "=" + ATTR_VAL); params.add("realm", REALM); String decision = decisionClient .queryParams(params) .header(RestServiceManager.SUBJECT_HEADER_NAME, userTokenIdHeader) .cookie(cookie) .accept("text/plain") .get(String.class); if ((decision == null) || !decision.equals("allow")) { throw new Exception("RESTTest.getDecisionTest() failed"); } } @Test public void getDecisionsTest() throws Exception { Form params = new Form(); params.add("subject", hashedUserTokenId); params.add("resources", RESOURCE_NAME + "/index.html"); params.add("action", "GET"); params.add("env", ATTR_NAME + "=" + ATTR_VAL); params.add("realm", REALM); String json = decisionsClient .queryParams(params) .header(RestServiceManager.SUBJECT_HEADER_NAME, userTokenIdHeader) .cookie(cookie) .accept("application/json") .get(String.class); JSONObject jo = new JSONObject(json); if (jo.optInt("statusCode") != 200) { throw new Exception( "RESTTest.getDecisionsTest() failed, status code not 200"); } JSONObject jbody = jo.optJSONObject("body"); if (jbody == null) { throw new Exception( "RESTTest.getDecisionsTest() failed, body element is null"); } JSONArray results = jbody.optJSONArray("results"); if (results == null) { throw new Exception( "RESTTest.getDecisionsTest() failed, results array is null"); } if (results.length() < 1) { throw new Exception( "RESTTest.getDecisionsTest() failed, results array is empty"); } JSONEntitlement ent = new JSONEntitlement(results.getJSONObject(0)); boolean result = ent.getActionValue("GET"); if (!result) { throw new Exception("RESTTest.getDecisionsTest() failed"); } } @Test public void getEntitlementTest() throws Exception { Form params = new Form(); params.add("subject", hashedUserTokenId); params.add("resource", RESOURCE_NAME + "/index.html"); params.add("action", "GET"); params.add("env", ATTR_NAME + "=" + ATTR_VAL); params.add("realm", REALM); String json = entitlementClient .queryParams(params) .header(RestServiceManager.SUBJECT_HEADER_NAME, userTokenIdHeader) .cookie(cookie) .accept("application/json") .get(String.class); JSONObject jo = new JSONObject(json); if (jo.optInt("statusCode") != 200) { throw new Exception( "RESTTest.getEntitlementTest() failed, status code not 200"); } JSONObject jbody = jo.optJSONObject("body"); if (jbody == null) { throw new Exception( "RESTTest.getEntitlementTest() failed, body element is null"); } JSONEntitlement ent = new JSONEntitlement(jbody); boolean result = ent.getActionValue("GET"); if (!result) { throw new Exception("RESTTest.getEntitlementTest() failed"); } } @Test public void getEntitlementsTest() throws Exception { Form params = new Form(); params.add("subject", hashedUserTokenId); params.add("resource", RESOURCE_NAME); params.add("env", ATTR_NAME + "=" + ATTR_VAL); params.add("realm", REALM); String json = entitlementsClient .queryParams(params) .header(RestServiceManager.SUBJECT_HEADER_NAME, userTokenIdHeader) .cookie(cookie) .accept("application/json") .get(String.class); JSONObject jo = new JSONObject(json); if (jo.optInt("statusCode") != 200) { throw new Exception( "RESTTest.getEntitlementsTest: failed, status code not 200"); } JSONObject jbody = jo.optJSONObject("body"); if (jbody == null) { throw new Exception( "RESTTest.getEntitlementsTest: failed, body element is null"); } JSONArray results = jbody.optJSONArray("results"); if (results == null) { throw new Exception( "RESTTest.getEntitlementsTest: failed, results element is null"); } if (results.length() < 1) { throw new Exception( "RESTTest.getEntitlementsTest: failed, results array is empty"); } // dude, there are two entitlements returned. // the first one is the root resource which is http://www.resttest.com // and the action value is empty. // we need to get the second one, which is http://www.resttest.com:80/* JSONEntitlement ent = new JSONEntitlement(results.getJSONObject(1)); Object resultObj = ent.getActionValue("GET"); if (resultObj != null) { if (!ent.getActionValue("GET")) { throw new Exception( "RESTTest.getEntitlementsTest: failed, action value is false"); } } else { throw new Exception( "RESTTest.getEntitlementsTest: failed, action value is null"); } } @Test public void negativeTest() throws Exception { Form params = new Form(); params.add("subject", hashedUserTokenId); params.add("resource", RESOURCE_NAME + "/index.html"); params.add("action", "GET"); params.add("realm", REALM); String decision = decisionClient .queryParams(params) .header(RestServiceManager.SUBJECT_HEADER_NAME, userTokenIdHeader) .cookie(cookie) .accept("text/plain") .get(String.class); if ((decision != null) && decision.equals("allow")) { throw new Exception("RESTTest.negativeTest (/decision) failed"); } String json = entitlementClient .queryParams(params) .header(RestServiceManager.SUBJECT_HEADER_NAME, userTokenIdHeader) .cookie(cookie) .accept("application/json") .get(String.class); JSONObject jo = new JSONObject(json); if (jo.optInt("statusCode") != 200) { throw new Exception("RESTTest.negativeTest() failed, status code not 200"); } JSONObject jbody = jo.optJSONObject("body"); if (jbody == null) { throw new Exception("RESTTest.negativeTest() failed, body element is null"); } JSONEntitlement ent = new JSONEntitlement(jbody); boolean result = false; Object resultObj = ent.getActionValue("GET"); if (resultObj != null) { result = ent.getActionValue("GET"); } if (result) { throw new Exception("RESTTest.getnegativeTest() failed"); } Map> advices = ent.getAdvices(); Set setNumericCondAdvice = advices.get( NumericAttributeCondition.class.getName()); if ((setNumericCondAdvice == null) || setNumericCondAdvice.isEmpty()) { throw new Exception("RESTTest.negativeTest: no advice"); } String advice = setNumericCondAdvice.iterator().next(); if (!advice.equals(ATTR_NAME + "=" + ATTR_VAL)) { throw new Exception("RESTTest.negativeTest: incorrect advice"); } } @Test public void missingResourceTest() throws Exception { Form params = new Form(); params.add("subject", hashedUserTokenId); params.add("action", "GET"); params.add("env", ATTR_NAME + "=" + ATTR_VAL); params.add("realm", REALM); try { entitlementClient .queryParams(params) .header(RestServiceManager.SUBJECT_HEADER_NAME, userTokenIdHeader) .cookie(cookie) .accept("application/json") .get(String.class); throw new Exception( "RESTTest.missingResourceTest: no exception thrown."); } catch (UniformInterfaceException e) { int errorCode = e.getResponse().getStatus(); if (errorCode != 400) { throw new Exception( "RESTTest.missingResourceTest: incorrect error code"); } String json = e.getResponse().getEntity(String.class); JSONObject jo = new JSONObject(json); if (jo.optInt("statusCode") != 420) { throw new Exception( "RESTTest.missingResourceTest() failed, status code not 420"); } if (jo.optJSONObject("body") != null) { throw new Exception( "RESTTest.missingResourceTest() failed, body not empty"); } } } @Test public void missingResourcesTest() throws Exception { Form params = new Form(); params.add("subject", hashedUserTokenId); params.add("action", "GET"); params.add("env", ATTR_NAME + "=" + ATTR_VAL); params.add("realm", REALM); try { decisionsClient .queryParams(params) .header(RestServiceManager.SUBJECT_HEADER_NAME, userTokenIdHeader) .cookie(cookie) .accept("application/json") .get(String.class); throw new Exception( "RESTTest.missingResourceTest: no exception thrown."); } catch (UniformInterfaceException e) { int errorCode = e.getResponse().getStatus(); if (errorCode != 400) { throw new Exception( "RESTTest.missingResourceTest: incorrect error code"); } String json = e.getResponse().getEntity(String.class); JSONObject jo = new JSONObject(json); if (jo.optInt("statusCode") != 424) { throw new Exception( "RESTTest.missingResourcesTest() failed, status code not 424"); } if (jo.optJSONObject("body") != null) { throw new Exception( "RESTTest.missingResourcesTest() failed, body not empty"); } } } @Test public void missingActionTest() throws Exception { Form params = new Form(); params.add("subject", hashedUserTokenId); params.add("resource", RESOURCE_NAME + "/index.html"); params.add("env", ATTR_NAME + "=" + ATTR_VAL); params.add("realm", REALM); try { decisionClient .queryParams(params) .header(RestServiceManager.SUBJECT_HEADER_NAME, userTokenIdHeader) .cookie(cookie) .accept("text/plain") .get(String.class); throw new Exception( "RESTTest.missingActionTest: no exception thrown."); } catch (UniformInterfaceException e) { int errorCode = e.getResponse().getStatus(); if (errorCode != 400) { throw new Exception( "RESTTest.missingActionTest: incorrect error code"); } } } }