| /* |
| * 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.apache.sling.repoinit.parser.test; |
| |
| import static org.junit.Assert.assertEquals; |
| import static org.junit.Assert.fail; |
| |
| import java.io.PrintWriter; |
| import java.io.StringReader; |
| import java.io.StringWriter; |
| import java.util.ArrayList; |
| import java.util.Collection; |
| import java.util.List; |
| |
| import org.apache.sling.repoinit.parser.impl.ParseException; |
| import org.apache.sling.repoinit.parser.impl.RepoInitParserImpl; |
| import org.apache.sling.repoinit.parser.impl.TokenMgrError; |
| import org.junit.Test; |
| import org.junit.runner.RunWith; |
| import org.junit.runners.Parameterized; |
| import org.junit.runners.Parameterized.Parameters; |
| |
| /** Test various parsing errors */ |
| @RunWith(Parameterized.class) |
| public class ParsingErrorsTest { |
| |
| private final String input; |
| private final Class<? extends Throwable> expected; |
| |
| @Parameters(name="{0}") |
| public static Collection<Object[]> data() { |
| @SuppressWarnings("serial") |
| final List<Object []> result = new ArrayList<Object []>() {{ |
| add(new Object[] { "foo", ParseException.class }); |
| add(new Object[] { "12", ParseException.class }); |
| |
| add(new Object[] { "set ACL on /apps \n remove * for u \n end", null }); |
| add(new Object[] { "set ACL on /apps \n badkeyword * for u \n end", ParseException.class }); |
| add(new Object[] { "set ACL on appsWithoutSlash \n remove * for u \n end", ParseException.class }); |
| add(new Object[] { "set ACL", ParseException.class }); |
| add(new Object[] { "set ACL \n end", ParseException.class }); |
| |
| add(new Object[] { "create service user bob, alice, tom21", null }); |
| add(new Object[] { "create service user bob-221_BOB", null }); |
| |
| // this passes since introducing "register namespace" and loosening |
| // the PRINCIPAL regexp |
| add(new Object[] { "create service user bob/221", null }); |
| |
| add(new Object[] { "create service user bob,/alice, tom21", ParseException.class }); |
| add(new Object[] { "create service user bob,alice,tom21 # comment not allowed here", TokenMgrError.class }); |
| add(new Object[] { "CREATE service user bob, alice, tom21", ParseException.class }); |
| add(new Object[] { "create SERVICE user bob, alice, tom21", ParseException.class }); |
| |
| // Disable users with missing reason |
| add(new Object[] { "disable service user foo", ParseException.class }); |
| add(new Object[] { "disable user regularfoo", ParseException.class }); |
| |
| // Quoted strings in disable service user |
| add(new Object[] { "disable service user foo", ParseException.class }); |
| add(new Object[] { "disable service user foo missing colon and quotes", ParseException.class }); |
| add(new Object[] { "disable service user foo : missing quotes", ParseException.class }); |
| add(new Object[] { "disable service user foo \"missing colon\"", ParseException.class }); |
| add(new Object[] { "disable service user foo : missing start quote\"", ParseException.class }); |
| add(new Object[] { "disable service user foo : \"missing end quote", ParseException.class }); |
| add(new Object[] { "disable service user foo: \"Unescaped quoted single backslash \"\\\" fails", ParseException.class }); |
| |
| // SLING-7066 default mixin is not supported |
| add(new Object[] { "create path (sling:Folder mixin mix:A) /var/foo", ParseException.class }); |
| add(new Object[] { "create path (mixin mix:A) /var/foo", ParseException.class }); |
| |
| // SLING-7061 |
| add(new Object[] { "set repository ACL for principal1\nallow jcr:somePermission on /\nend", ParseException.class }); |
| |
| // path must come before password if used |
| add(new Object[] { "create user E with password PWD with path P", ParseException.class }); |
| |
| // SLING-8757 - functions at the beginning of paths |
| add(new Object[] { "set ACL on home(missingRParen \n remove * for u \n end", ParseException.class }); |
| add(new Object[] { "set ACL on spaceAfterFunctionName(user) \n remove * for u \n end", ParseException.class }); |
| add(new Object[] { "set ACL on one(name)two(onlyOneFunctionAllowed) \n remove * for u \n end", ParseException.class }); |
| add(new Object[] { "set ACL on home(alice:colonNotAllowed) \n remove * for u \n end", ParseException.class }); |
| add(new Object[] { "set ACL on home(alice#hashNotAllowed) \n remove * for u \n end", ParseException.class }); |
| add(new Object[] { "set ACL on home(alice,commaNotAllowed) \n remove * for u \n end", ParseException.class }); |
| add(new Object[] { "set ACL on home(alice,comma,not,allowed) \n remove * for u \n end", ParseException.class }); |
| |
| // SLING-9084 - add/remove group members |
| add(new Object[] { "add to group missingUsernames", ParseException.class }); |
| add(new Object[] { "add missingGroupName, another to group", ParseException.class }); |
| add(new Object[] { "add bob, alice to group only, one, allowed", ParseException.class }); |
| add(new Object[] { "remove from group missingUsernames", ParseException.class }); |
| add(new Object[] { "remove missingGroup from group", ParseException.class }); |
| add(new Object[] { "remove bob, alice from group only, one, really", ParseException.class }); |
| add(new Object[] { "add bob, alice from group shouldBeToNotFrom", ParseException.class }); |
| add(new Object[] { "remove bob, alice to group shouldBeFromNotTo", ParseException.class }); |
| add(new Object[] { "add bob, alice group missingTo", ParseException.class }); |
| add(new Object[] { "remove bob, alice group missingFrom", ParseException.class }); |
| |
| // SLING-9171 Support setting node properties via repoinit |
| add(new Object[] { "set properties on appsWithoutSlash \n set sling:ResourceType{String} to /x/y/z \n end", ParseException.class }); |
| add(new Object[] { "set properties on /apps \n set dob{Date} to 13-10-2019 \n end", ParseException.class }); |
| add(new Object[] { "set properties on /pathA/b \n set someProp{inValidType} to abc \n end", ParseException.class }); |
| add(new Object[] { "set properties on /pathA/b \n set lowercasetype{string} to abc \n end", ParseException.class }); |
| add(new Object[] { "set properties on /pathA/b \n set {String} to missingPropertyName \n end", ParseException.class }); |
| add(new Object[] { "set properties on /pathA/b \n set somepProp{String} withoutTo \n end", ParseException.class }); |
| add(new Object[] { "set properties on /noPropsFails \n end", ParseException.class }); |
| |
| // SLING-10299 - checking that remove ACL is not valid so far |
| add(new Object[] { "remove ACL on /libs", ParseException.class }); |
| add(new Object[] { "remove jcr:ACL on /libs", ParseException.class }); |
| add(new Object[] { "remove ACL for alice", ParseException.class }); |
| add(new Object[] { "remove principal ACL for thePrincipal", ParseException.class }); |
| |
| // SLING-6219 - delete user does not support lists |
| add(new Object[] { "delete user alice,bob", ParseException.class }); |
| |
| // SLING-10952 - Support quoted group names |
| add(new Object[] { "create group My Group", ParseException.class }); |
| add(new Object[] { "create group My\tGroup", ParseException.class }); |
| add(new Object[] { "create group \"My\u200bGroup\"", ParseException.class }); |
| |
| // SLING-11160 - Repoinit does not allow to remove individual ACEs |
| // -> remove-action not supported. only 'allow' and 'deny' |
| add(new Object[] { "remove ACE on /content\n remove jcr:read for alice\n end", ParseException.class}); |
| add(new Object[] { "remove ACE on /content\n remove * for alice\n end", ParseException.class}); |
| add(new Object[] { "remove ACE for alice\n remove jcr:read on /content\n end", ParseException.class}); |
| add(new Object[] { "remove ACE for alice\n remove * on /content\n end", ParseException.class}); |
| add(new Object[] { "remove principal ACE for alice\n remove jcr:read on /content\n end", ParseException.class}); |
| add(new Object[] { "remove principal ACE for alice\n remove * on /content\n end", ParseException.class}); |
| // -> acl-options not supported |
| add(new Object[] {"remove ACE for user1 (ACLOptions=mergePreserve)\n allow jcr:read on /content\n end", ParseException.class}); |
| add(new Object[] {"remove principal ACE for user1 (ACLOptions=mergePreserve)\n allow jcr:read on /content\n end", ParseException.class}); |
| add(new Object[] {"remove ACE on /content (ACLOptions=mergePreserve)\n allow jcr:read for user1\n end", ParseException.class}); |
| }}; |
| return result; |
| } |
| |
| public ParsingErrorsTest(String input, Class<? extends Throwable> expected) { |
| this.input = input; |
| this.expected = expected; |
| } |
| |
| private String getInfo(String msg, Throwable unexpected) { |
| final StringWriter sw = new StringWriter(); |
| final PrintWriter pw = new PrintWriter(sw); |
| pw.println("For input '" + input + "', unexpected stack trace="); |
| unexpected.printStackTrace(pw); |
| pw.flush(); |
| return sw.toString(); |
| } |
| |
| @Test |
| public void checkResult() { |
| final StringReader r = new StringReader(input); |
| boolean noException = false; |
| String parsed = null; |
| try { |
| parsed = new RepoInitParserImpl(r).parse().toString(); |
| noException = true; |
| } catch (Exception | Error e) { |
| assertEquals(getInfo(input, e), expected, e.getClass()); |
| } finally { |
| r.close(); |
| } |
| |
| if (noException && expected != null) { |
| fail("Expected a " + expected.getSimpleName() + " for [" + input + "] parsed to [" + parsed + "]"); |
| } |
| } |
| } |