001: /***************************************************************
002: * This file is part of the [fleXive](R) project.
003: *
004: * Copyright (c) 1999-2008
005: * UCS - unique computing solutions gmbh (http://www.ucs.at)
006: * All rights reserved
007: *
008: * The [fleXive](R) project is free software; you can redistribute
009: * it and/or modify it under the terms of the GNU General Public
010: * License as published by the Free Software Foundation;
011: * either version 2 of the License, or (at your option) any
012: * later version.
013: *
014: * The GNU General Public License can be found at
015: * http://www.gnu.org/copyleft/gpl.html.
016: * A copy is found in the textfile GPL.txt and important notices to the
017: * license from the author are found in LICENSE.txt distributed with
018: * these libraries.
019: *
020: * This library is distributed in the hope that it will be useful,
021: * but WITHOUT ANY WARRANTY; without even the implied warranty of
022: * MERCHANTABILITY or FITNESS FOR A PARTICULAR PURPOSE. See the
023: * GNU General Public License for more details.
024: *
025: * For further information about UCS - unique computing solutions gmbh,
026: * please see the company website: http://www.ucs.at
027: *
028: * For further information about [fleXive](R), please see the
029: * project website: http://www.flexive.org
030: *
031: *
032: * This copyright notice MUST APPEAR in all copies of the file!
033: ***************************************************************/package com.flexive.tests.embedded;
034:
035: import com.flexive.shared.CacheAdmin;
036: import com.flexive.shared.EJBLookup;
037: import com.flexive.shared.FxContext;
038: import com.flexive.shared.content.FxContent;
039: import com.flexive.shared.content.FxPK;
040: import com.flexive.shared.content.FxPermissionUtils;
041: import com.flexive.shared.exceptions.FxApplicationException;
042: import com.flexive.shared.exceptions.FxNoAccessException;
043: import com.flexive.shared.interfaces.ACLEngine;
044: import com.flexive.shared.interfaces.AssignmentEngine;
045: import com.flexive.shared.interfaces.ContentEngine;
046: import com.flexive.shared.interfaces.TypeEngine;
047: import com.flexive.shared.security.ACL;
048: import com.flexive.shared.security.Role;
049: import com.flexive.shared.structure.*;
050: import com.flexive.shared.value.FxNoAccess;
051: import com.flexive.shared.value.FxString;
052: import static com.flexive.tests.embedded.FxTestUtils.login;
053: import static com.flexive.tests.embedded.FxTestUtils.logout;
054: import org.apache.commons.lang.RandomStringUtils;
055: import org.testng.annotations.AfterClass;
056: import org.testng.annotations.BeforeClass;
057: import org.testng.annotations.Test;
058:
059: /**
060: * Security test for the ContentEngine (for property permissions)
061: *
062: * @author Markus Plesser (markus.plesser@flexive.com), UCS - unique computing solutions gmbh (http://www.ucs.at)
063: */
064: @Test(groups={"ejb","content","security"})
065: public class ContentPropertySecurityTest {
066:
067: private ContentEngine co;
068: private ACLEngine acl;
069: private TypeEngine type;
070: private AssignmentEngine ass;
071:
072: private TestUser user;
073: private long typeACL, prop1ACL, prop2ACL, contentACL, workflowACL;
074: private long stepId;
075: private final static String TYPE_NAME = "TESTSECURITY_"
076: + RandomStringUtils.random(16, true, true);
077:
078: long typeId;
079: private static final String PROP1_NAME = "PROP1_"
080: + RandomStringUtils.random(16, true, true);
081: private static final String PROP2_NAME = "PROP2_"
082: + RandomStringUtils.random(16, true, true);
083:
084: private static final FxString PROP1_VALUE = new FxString(false,
085: "PROP1_VALUE_" + RandomStringUtils.random(16, true, true));
086: private static final FxString PROP1_NEW_VALUE = new FxString(false,
087: "PROP1_NEW_VALUE_"
088: + RandomStringUtils.random(16, true, true));
089: private static final FxString PROP2_VALUE = new FxString(false,
090: "PROP2_VALUE_" + RandomStringUtils.random(16, true, true));
091:
092: private FxPK refpk;
093:
094: /**
095: * setup...
096: *
097: * @throws Exception on errors
098: */
099: @BeforeClass
100: public void setup() throws Exception {
101: co = EJBLookup.getContentEngine();
102: acl = EJBLookup.getACLEngine();
103: type = EJBLookup.getTypeEngine();
104: ass = EJBLookup.getAssignmentEngine();
105: login(TestUsers.SUPERVISOR);
106: //acl for the 2 property assignments and the used type
107: typeACL = TestUsers.newStructureACL("type");
108: prop1ACL = TestUsers.newStructureACL("prop1");
109: prop2ACL = TestUsers.newStructureACL("prop2");
110:
111: //acl for the content itself
112: contentACL = TestUsers.newContentACL("content");
113: //acl for the workflows of the type
114: workflowACL = TestUsers.newWorkflowACL("workflow");
115:
116: //initialize the user with full access to all property assignments
117: user = TestUsers.createUser("ContentPropertySecurity",
118: Role.StructureManagement, Role.ACLManagement);
119: user.createUser(TestUsers.getTestMandator(), TestUsers
120: .getEnglishLanguageId());
121: // TestUsers.assignACL(user, typeACL, ACL.PERM.CREATE);
122: logout();
123: login(user);
124: }
125:
126: @BeforeClass(dependsOnMethods={"setup"})
127: public void setupStructures() throws Exception {
128: typeId = type.save(FxTypeEdit.createNew(TYPE_NAME,
129: new FxString("Test data"),
130: CacheAdmin.getEnvironment().getACL(typeACL), null)
131: .setPermissions(
132: FxPermissionUtils.encodeTypePermissions(true,
133: true, false, false)));
134: // typeId = type.create(typeACL, 1, TestUsers.getTestMandator(), new ArrayList<Mandator>(2), TYPE_NAME,
135: // new FxString("Test data"), null, false,
136: // TypeStorageMode.Hierarchical, TypeCategory.User, TypeMode.Content,
137: // true, LanguageMode.Multiple, TypeState.Available,
138: // FxPermissionUtils.encodeTypePermissions(true, true, false, false),
139: // true, 0, 0, 0, 0);
140: //create the 2 properties
141: ass.createProperty(typeId, FxPropertyEdit.createNew(PROP1_NAME,
142: new FxString("Security UnitTest"), new FxString(
143: "hint..."), new FxMultiplicity(1, 2),
144: CacheAdmin.getEnvironment().getACL(prop1ACL),
145: FxDataType.String1024), "/");
146: ass.createProperty(typeId, FxPropertyEdit.createNew(PROP2_NAME,
147: new FxString("Security UnitTest"), new FxString(
148: "hint..."), new FxMultiplicity(1, 2),
149: CacheAdmin.getEnvironment().getACL(prop2ACL),
150: FxDataType.String1024), "/");
151: //get first possible step (steps aint subject of the tests here...)
152: stepId = CacheAdmin.getEnvironment().getType(typeId)
153: .getWorkflow().getSteps().get(0).getId();
154: FxContext.get().runAsSystem();
155: FxContent test = co.initialize(typeId, TestUsers
156: .getTestMandator(), contentACL, stepId, TestUsers
157: .getEnglishLanguageId());
158: test.setValue("/" + PROP1_NAME, PROP1_VALUE);
159: test.setValue("/" + PROP2_NAME, new FxString(PROP2_VALUE));
160: refpk = co.save(test);
161: FxContext.get().stopRunAsSystem();
162: }
163:
164: @Test
165: public void checkTypePermissionSetup()
166: throws FxApplicationException {
167: FxType type = CacheAdmin.getEnvironment().getType(typeId);
168: assert type.usePermissions();
169: assert type.useInstancePermissions();
170: assert type.usePropertyPermissions();
171: assert !type.useStepPermissions();
172: assert !type.useTypePermissions();
173: }
174:
175: public void securityLoad() throws FxApplicationException {
176: }
177:
178: @Test
179: public void securityFullAccess() throws FxApplicationException {
180: TestUsers.assignACL(user, contentACL, ACL.Permission.CREATE,
181: ACL.Permission.DELETE, ACL.Permission.EDIT,
182: ACL.Permission.READ);
183: TestUsers.assignACL(user, prop1ACL, ACL.Permission.CREATE,
184: ACL.Permission.DELETE, ACL.Permission.EDIT,
185: ACL.Permission.READ);
186: TestUsers.assignACL(user, prop2ACL, ACL.Permission.CREATE,
187: ACL.Permission.DELETE, ACL.Permission.EDIT,
188: ACL.Permission.READ);
189: FxContent test = co.initialize(typeId, TestUsers
190: .getTestMandator(), contentACL, stepId, TestUsers
191: .getEnglishLanguageId());
192: test.setValue("/" + PROP1_NAME, PROP1_VALUE);
193: test.setValue("/" + PROP2_NAME, new FxString(PROP2_VALUE));
194: FxPK pk = co.save(test);
195: FxContent comp = co.load(pk);
196:
197: assert comp.getPropertyData("/" + PROP1_NAME).getValue()
198: .equals(PROP1_VALUE);
199: assert !comp.getPropertyData("/" + PROP1_NAME).getValue()
200: .isReadOnly();
201: assert comp.getPropertyData("/" + PROP1_NAME).mayCreateMore();
202:
203: assert comp.getPropertyData("/" + PROP2_NAME).getValue()
204: .equals(PROP2_VALUE);
205: assert !comp.getPropertyData("/" + PROP2_NAME).getValue()
206: .isReadOnly();
207: assert comp.getPropertyData("/" + PROP2_NAME).mayCreateMore();
208: co.remove(pk);
209: }
210:
211: @Test
212: public void securityReadOnlyAccess() throws FxApplicationException {
213: TestUsers.assignACL(user, contentACL, ACL.Permission.READ);
214: TestUsers.assignACL(user, prop1ACL, ACL.Permission.READ);
215: TestUsers.assignACL(user, prop2ACL, ACL.Permission.READ);
216: FxContent comp = co.load(refpk);
217:
218: assert comp.getPropertyData("/" + PROP1_NAME).getValue()
219: .equals(PROP1_VALUE);
220: assert comp.getPropertyData("/" + PROP1_NAME).getValue()
221: .isReadOnly();
222: assert comp.getPropertyData("/" + PROP1_NAME).mayCreateMore();
223:
224: assert comp.getPropertyData("/" + PROP2_NAME).getValue()
225: .equals(PROP2_VALUE);
226: assert comp.getPropertyData("/" + PROP2_NAME).getValue()
227: .isReadOnly();
228: assert comp.getPropertyData("/" + PROP2_NAME).mayCreateMore();
229: }
230:
231: @Test
232: public void securityNoAccess() throws FxApplicationException {
233: TestUsers.assignACL(user, contentACL, ACL.Permission.READ,
234: ACL.Permission.EDIT);
235: TestUsers.assignACL(user, prop1ACL, ACL.Permission.READ,
236: ACL.Permission.EDIT);
237: TestUsers.assignACL(user, prop2ACL);
238: FxContent comp = co.load(refpk);
239: //check if prop1 is full editable
240: assert comp.getPropertyData("/" + PROP1_NAME).getValue()
241: .equals(PROP1_VALUE);
242: assert comp.getPropertyData("/" + PROP1_NAME).mayCreateMore();
243: assert !comp.getPropertyData("/" + PROP1_NAME).getValue()
244: .isReadOnly();
245: assert !(comp.getPropertyData("/" + PROP1_NAME).getValue() instanceof FxNoAccess);
246: //check if prop2 is not accessible
247: assert !comp.getPropertyData("/" + PROP2_NAME).getValue()
248: .equals(PROP2_VALUE);
249: assert !comp.getPropertyData("/" + PROP2_NAME).mayCreateMore();
250: assert comp.getPropertyData("/" + PROP2_NAME).getValue()
251: .isReadOnly();
252: assert comp.getPropertyData("/" + PROP2_NAME).getValue() instanceof FxNoAccess;
253: //set prop1 to a new value and check if its set
254: comp.getPropertyData("/" + PROP1_NAME)
255: .setValue(PROP1_NEW_VALUE);
256: assert comp.getPropertyData("/" + PROP1_NAME).getValue()
257: .equals(PROP1_NEW_VALUE);
258: //try to set prop2 to a new value and check if it remains unchanged and still not accessible
259: try {
260: comp.getPropertyData("/" + PROP2_NAME).setValue(
261: PROP1_NEW_VALUE);
262: assert false : "FxNoAccessException expected!";
263: } catch (FxNoAccessException e) {
264: //ok this was expected
265: }
266: assert !comp.getPropertyData("/" + PROP2_NAME).getValue()
267: .equals(PROP2_VALUE);
268: assert comp.getPropertyData("/" + PROP2_NAME).getValue()
269: .isReadOnly();
270: assert comp.getPropertyData("/" + PROP2_NAME).getValue() instanceof FxNoAccess;
271: co.save(comp);
272: FxContext.get().runAsSystem();
273: comp = co.load(refpk);
274: //check for correct changes
275: assert comp.getPropertyData("/" + PROP1_NAME).getValue()
276: .equals(PROP1_NEW_VALUE);
277: assert comp.getPropertyData("/" + PROP2_NAME).getValue()
278: .equals(PROP2_VALUE);
279: comp.getPropertyData("/" + PROP1_NAME).setValue(PROP1_VALUE);
280: assert comp.getPropertyData("/" + PROP1_NAME).mayCreateMore();
281: assert comp.getPropertyData("/" + PROP2_NAME).mayCreateMore();
282: co.save(comp); //re-save with original prop1 value
283: FxContext.get().stopRunAsSystem();
284: }
285:
286: @AfterClass
287: public void cleanup() throws Exception {
288: logout();
289: login(TestUsers.SUPERVISOR);
290: co.removeForType(typeId);
291: type.remove(typeId);
292: acl.remove(contentACL);
293: acl.remove(workflowACL);
294: acl.remove(prop1ACL);
295: acl.remove(prop2ACL);
296: acl.remove(typeACL);
297: logout();
298: }
299:
300: }
|