/*******************************************************************************
* Copyright (c) 2010-2014 SAP AG 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:
* SAP AG - initial API and implementation
*******************************************************************************/
package org.eclipse.skalli.services.permit;
import static org.junit.Assert.*;
import java.util.Arrays;
import java.util.Iterator;
import java.util.List;
import org.eclipse.skalli.services.permit.Permit.Level;
import org.hamcrest.BaseMatcher;
import org.hamcrest.Description;
import org.hamcrest.Factory;
import org.junit.Assert;
import org.junit.Test;
@SuppressWarnings("nls")
public class PermitTest {
private static final Permit[] PERMITS = new Permit[] {
Permit.valueOf("ALLOW GET /projects"),
Permit.valueOf("ALLOW GET /"),
Permit.valueOf("FORBID GET /projects"),
Permit.valueOf("ALLOW GET /**"),
Permit.valueOf("ALLOW GET /projects/foobar"),
Permit.valueOf("FORBID PUT /projects/foobar"),
Permit.valueOf("FORBID GET /projects/foobar"),
Permit.valueOf("FORBID PUT /projects/**/props"),
Permit.valueOf("ALLOW PUT /projects/**/props/prop"),
Permit.valueOf("FORBID PUT /projects/**/props/prop"),
Permit.valueOf("ALLOW PUT /projects/**/props/**"),
Permit.valueOf("FORBID DELETE /projects/foobar"),
Permit.valueOf("FORBID POST /projects/foobar"),
Permit.valueOf("FORBID XYZ /projects/foobar"),
Permit.valueOf("ALLOW PUT /projects/foobar/props/prop"),
Permit.valueOf("FORBID PUT /projects/foobar/props/prop"),
Permit.valueOf("ALLOW GET /projects/foobar/props/prop"),
Permit.valueOf("ALLOW POST /projects/foobar/props/prop"),
Permit.valueOf("ALLOW DELETE /projects/foobar/props/prop"),
Permit.valueOf("ALLOW PUT /projects/**/props/prop"),
Permit.valueOf("ALLOW GET /projects/foobar/a/b/c"),
Permit.valueOf("ALLOW ** /projects/foobar/a/b/c"),
Permit.valueOf("FORBID ** /projects/foobar/a/b/c"),
Permit.valueOf("FORBID GET /projects/foobar/a/b/c"),
Permit.valueOf("10 GET /projects/foobar/a/b/c")
};
private static final List<Permit> EXPECTED_SORTED_PERMITS = Arrays.asList(
Permit.valueOf("10 GET /projects/foobar/a/b/c"),
Permit.valueOf("FORBID ** /projects/foobar/a/b/c"),
Permit.valueOf("ALLOW DELETE /projects/foobar/props/prop"),
Permit.valueOf("ALLOW GET /projects/foobar/props/prop"),
Permit.valueOf("ALLOW POST /projects/foobar/props/prop"),
Permit.valueOf("FORBID PUT /projects/foobar/props/prop"),
Permit.valueOf("ALLOW PUT /projects/**/props/prop"),
Permit.valueOf("ALLOW PUT /projects/**/props/**"),
Permit.valueOf("FORBID PUT /projects/**/props"),
Permit.valueOf("FORBID DELETE /projects/foobar"),
Permit.valueOf("FORBID GET /projects/foobar"),
Permit.valueOf("FORBID POST /projects/foobar"),
Permit.valueOf("FORBID PUT /projects/foobar"),
Permit.valueOf("FORBID XYZ /projects/foobar"),
Permit.valueOf("FORBID GET /projects"),
Permit.valueOf("ALLOW GET /**"),
Permit.valueOf("ALLOW GET /")
);
private static final PermitSet SORTED_PERMITS = new PermitSet(PERMITS);
@Test
public void testValueOf() throws Exception {
assertPermit(1, "GET", "/projects", Permit.valueOf("ALLOW GET /projects"));
assertPermit(0, "GET", "/projects", Permit.valueOf("FORBID GET /projects"));
assertPermit(1, "PUT", "/projects", Permit.valueOf("ALLOW PUT /projects"));
assertPermit(1, "GET", "/projects/foobar", Permit.valueOf("ALLOW GET /projects/foobar"));
assertPermit(1, "GET", "/projects/**/props", Permit.valueOf("ALLOW GET /projects/**/props"));
assertPermit(1, "GET", "/", Permit.valueOf("ALLOW GET /"));
assertPermit(1, "GET", "/**", Permit.valueOf("ALLOW GET **"));
assertPermit(0, "PUT", "/projects", Permit.valueOf("FORBID PUT projects"));
assertPermit(0, "PUT", "/projects", Permit.valueOf("0 put /projects"));
assertPermit(1, "PUT", "/projects", Permit.valueOf("1 put /projects"));
assertPermit(1, "PUT", "/projects", Permit.valueOf("+1 put /projects"));
assertPermit(15, "PUT", "/projects", Permit.valueOf("15 put /projects"));
assertPermit(0, "PUT", "/projects", Permit.valueOf("-1 put /projects"));
assertPermit(0, "PUT", "/projects", Permit.valueOf("forbid put /projects"));
assertPermit(1, "GET", "/projects", Permit.valueOf("allow get /projects"));
assertPermit(0, "XYZ", "/projects", Permit.valueOf("FORBID xyz projects"));
assertPermit(0, "PUT", "/projects", Permit.valueOf("FORBID \t PUT \n /projects \t "));
}
@Test
public void testParseLevel() throws Exception {
assertEquals(0, Permit.parseLevel("0"));
assertEquals(0, Permit.parseLevel("FORBID"));
assertEquals(0, Permit.parseLevel("forbid"));
assertEquals(1, Permit.parseLevel("1"));
assertEquals(1, Permit.parseLevel("ALLOW"));
assertEquals(1, Permit.parseLevel("allow"));
assertEquals(1, Permit.parseLevel("+1"));
assertEquals(0, Permit.parseLevel(null));
assertEquals(0, Permit.parseLevel(""));
}
@Test(expected=NumberFormatException.class)
public void testInvalidParseLevel() throws Exception {
Permit.parseLevel("foobar");
}
@Test(expected=IllegalArgumentException.class)
public void testValueOfIllegalArgument() throws Exception {
Permit.valueOf("PUT");
Permit.valueOf("PUT /projects");
Permit.valueOf("PUT /projects ");
Permit.valueOf("PUT /projects\t");
Permit.valueOf("ALLOW PUT /projects foobar");
Permit.valueOf("ALLOW PUT /projects /**");
Permit.valueOf(null);
Permit.valueOf("");
Permit.valueOf(" ");
}
@Test(expected=NumberFormatException.class)
public void testValueOfIllegalLevel() throws Exception {
Permit.valueOf("foobar GET /projects");
}
@Test
public void testConstructor() throws Exception {
assertPermit(0, "**", "/", new Permit());
assertPermit(0, "**", "/", new Permit(-1, null, (String)null));
assertPermit(0, "**", "/", new Permit(-1, null, (String[])null));
assertPermit(0, "**", "/", new Permit(-1, null, (String[])null));
assertPermit(0, "**", "/", new Permit(-1, "", ""));
assertPermit(1, "GET", "/projects", new Permit(Level.ALLOW, "GET", "/projects"));
assertPermit(0, "GET", "/projects", new Permit(Level.FORBID, "GET", "/projects"));
assertPermit(1, "PUT", "/projects", new Permit(Level.ALLOW, "PUT", "/projects"));
assertPermit(1, "GET", "/projects/foobar", new Permit(Level.ALLOW, "GET", "/projects/foobar"));
assertPermit(1, "GET", "/projects/**/props", new Permit(Level.ALLOW, "GET", "/projects/**/props"));
assertPermit(1, "GET", "/", new Permit(Level.ALLOW, "GET", "/"));
assertPermit(1, "GET", "/**", new Permit(Level.ALLOW, "GET", "**"));
assertPermit(0, "PUT", "/projects", new Permit(Level.FORBID, "PUT", "projects"));
assertPermit(0, "PUT", "/projects", new Permit(0, "put", "/projects"));
assertPermit(1, "PUT", "/projects", new Permit(1, "put", "/projects"));
assertPermit(15, "PUT", "/projects", new Permit(15, "put", "/projects"));
assertPermit(0, "PUT", "/projects", new Permit(-1, "put", "/projects"));
assertPermit(0, "PUT", "/projects", new Permit(Level.FORBID, "put", "/projects"));
assertPermit(1, "GET", "/projects", new Permit(Level.ALLOW, "get", "/projects"));
assertPermit(0, "XYZ", "/projects", new Permit(Level.FORBID, "xyz", "projects"));
}
@Test
public void testGetSegments() throws Exception {
assertSegments("\nprojects/ foo/ **/bar\t", "projects", "foo", "**", "bar");
assertSegments("/projects/foo/**/bar", "projects", "foo", "**", "bar");
assertSegments("/projects", "projects");
assertSegments("projects", "projects");
assertSegments("/", new String[]{});
assertSegments("", new String[]{});
assertSegments(null, new String[]{});
}
private void assertSegments(String path, String...expected) {
Permit permit = new Permit();
permit.setPath(path);
String[] segments = permit.getSegments();
Assert.assertArrayEquals(expected, segments);
}
@Test
public void testGetSetPath() throws Exception {
Permit permit = new Permit();
permit.setPath("\nprojects/ foo/ ** /bar");
assertEquals("/projects/foo/**/bar", permit.getPath());
}
@Test
public void testPermitSet() throws Exception {
assertEquals(25, PERMITS.length);
assertEquals(17, SORTED_PERMITS.size());
assertEqualsPermits(EXPECTED_SORTED_PERMITS, SORTED_PERMITS);
}
@Test
public void testEquals() throws Exception {
for (int i = 0, j = PERMITS.length - 1; i < PERMITS.length; ++i, --j) {
assertEquals(i == j, PERMITS[i].equals(PERMITS[j]));
}
}
@Test
public void testMatch() throws Exception {
for (Permit permit : SORTED_PERMITS) {
assertTrue(Permit.match(SORTED_PERMITS, permit.getLevel(), permit.getAction(), permit.getSegments()));
}
assertFalse(matchPermit("ALLOW PUT /")); // implicit FORBID ** /
assertFalse(matchPermit("ALLOW PUT /**")); // implicit FORBID ** /
assertFalse(matchPermit("ALLOW PUT /foobar")); // implicit FORBID ** /
assertTrue(matchPermit("ALLOW GET /")); // ALLOW GET /
assertTrue(matchPermit("ALLOW GET /foobar")); // ALLOW GET /**
assertFalse(matchPermit("ALLOW GET /projects")); // FORBID GET /projects
assertTrue(matchPermit("ALLOW PUT /projects/a/props/b")); // ALLOW PUT /projects/**/props/**
assertFalse(matchPermit("ALLOW PUT /projects/foobar/props/prop")); // FORBID PUT /projects/foobar/props/prop
assertTrue(matchPermit("ALLOW PUT /projects/foobar/props/b")); // ALLOW PUT /projects/**/props/**
assertTrue(matchPermit("9 GET /projects/foobar/a/b/c"));
assertTrue(matchPermit("10 GET /projects/foobar/a/b/c"));
assertFalse(matchPermit("11 GET /projects/foobar/a/b/c"));
}
private boolean matchPermit(String s) {
return Permit.match(SORTED_PERMITS, Permit.valueOf(s));
}
private void assertPermit(int level, String action, String path, Permit permit) {
assertEquals(level, permit.getLevel());
assertEquals(action, permit.getAction());
assertEquals(path, permit.getPath());
}
private void assertEqualsPermits(List<Permit> list, PermitSet set) {
Assert.assertEquals("size", list.size(), set.size());
Iterator<Permit> it1 = list.iterator();
Iterator<Permit> it2 = set.iterator();
while (it1.hasNext()) {
Permit next1 = it1.next();
Permit next2 = it2.next();
assertThat(next1, IsSamePermit.samePermit(next2));
}
}
private static class IsSamePermit extends BaseMatcher<Permit> {
private final Permit object;
public IsSamePermit(Permit object) {
this.object = object;
}
@Override
public boolean matches(Object arg) {
if (!(arg instanceof Permit)) {
return false;
}
Permit permit = (Permit) arg;
return object.getAction().equals(permit.getAction())
&& object.getPath().equals(permit.getPath())
&& object.getLevel() == permit.getLevel();
}
@Override
public void describeTo(Description description) {
description.appendText("equals(").appendValue(object).appendText(")");
}
/**
* Creates a new instance of IsSamePermit
*
* @param object The predicate evaluates to true only when the argument is
* this object.
*/
@Factory
public static IsSamePermit samePermit(Permit object) {
return new IsSamePermit(object);
}
}
}