Package com.getperka.flatpack.policy

Source Code of com.getperka.flatpack.policy.PolicyExtractionTest

package com.getperka.flatpack.policy;

/*
* #%L
* FlatPack Security Policy
* %%
* Copyright (C) 2012 - 2013 Perka Inc.
* %%
* 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.
* #L%
*/

import static com.getperka.flatpack.util.FlatPackCollections.setForIteration;
import static org.junit.Assert.assertEquals;
import static org.junit.Assert.assertFalse;
import static org.junit.Assert.assertNotNull;
import static org.junit.Assert.assertTrue;
import static org.junit.Assert.fail;

import java.util.Collections;
import java.util.List;
import java.util.Map;
import java.util.Random;
import java.util.Set;

import org.junit.Test;

import com.getperka.flatpack.FlatPack;
import com.getperka.flatpack.HasUuid;
import com.getperka.flatpack.ext.Property;
import com.getperka.flatpack.ext.TypeContext;
import com.getperka.flatpack.policy.domain.ExtendsMerchant;
import com.getperka.flatpack.policy.domain.Merchant;
import com.getperka.flatpack.policy.pst.Ident;
import com.getperka.flatpack.policy.pst.PolicyFile;
import com.getperka.flatpack.policy.pst.PolicyNode;
import com.getperka.flatpack.policy.visitors.PolicyVisitor;
import com.getperka.flatpack.security.GroupPermissions;
import com.getperka.flatpack.security.SecurityAction;
import com.getperka.flatpack.security.SecurityGroup;

/**
* Verify that a parsed policy file is correctly transformed into the appropriate in-memory objects.
*/
public class PolicyExtractionTest extends PolicyTestBase {

  @Test
  public void test() {
    doTest(loadTestPolicyContents());
  }

  /**
   * Parse the test file, and shuffle the elements to ensure that there aren't any test dependencies
   * on the particulars of how the contents of the file are ordered.
   */
  @Test
  public void testShuffle() {
    PolicyFile policyFile = loadTestPolicy();

    final Random r = new Random(0);
    for (int i = 0; i < 10; i++) {
      policyFile.accept(new PolicyVisitor() {

        /**
         * Shuffle nested lists.
         */
        @Override
        public void traverse(List<? extends PolicyNode> list) {
          if (list != null) {
            Collections.shuffle(list, r);
          }
          super.traverse(list);
        }

        /**
         * Don't re-order the internal state of an Ident.
         */
        @Override
        public boolean visit(Ident<?> x) {
          return false;
        }
      });

      try {
        doTest(policyFile.toSource());
      } catch (IllegalArgumentException e) {
        System.err.println(i + " Failing source:\n" + policyFile.toSource());
        throw e;
      }
    }
  }

  SecurityGroup checkPermissions(GroupPermissions p, String groupName, String... actionNames) {
    Set<SecurityAction> expected = setForIteration();
    for (String name : actionNames) {
      String[] parts = name.split("\\.");
      assertEquals(2, parts.length);
      expected.add(SecurityAction.of(parts[0], parts[1]));
    }
    for (Map.Entry<SecurityGroup, Set<SecurityAction>> entry : p.getOperations().entrySet()) {
      if (groupName.equals(entry.getKey().getName())) {
        assertEquals(expected, entry.getValue());
        return entry.getKey();
      }
    }
    fail("Did not find SecurityGroup named " + groupName + " in " + p);
    return null;
  }

  /**
   * Examination of the actual structure of the parsed data. The tests performed here must not
   * assume any relative ordering of rules, since this method will be called with shuffled input.
   */
  void doTest(String contents) {
    doTest(contents, Merchant.class);
    doTest(contents, ExtendsMerchant.class);
  }

  void doTest(String contents, Class<? extends Merchant> clazz) {
    FlatPack fp = flatpack(contents);
    GroupPermissions p = fp.getTypeContext().describe(clazz).getGroupPermissions();
    assertNotNull(p);

    // Check various type-level permissions
    checkMerchantPermissions(p);

    // Check property-level permissions, especially type- and global-overrides
    Property name = getProperty(fp.getTypeContext(), clazz, "name");
    p = name.getGroupPermissions();
    assertNotNull(p);
    // Just replacing a previous declaration
    assertEquals(5, p.getOperations().size());
    checkPermissions(p, "*", "crudOperation.read");

    // Test the "allow only" construct
    Property note = getProperty(fp.getTypeContext(), clazz, "note");
    p = note.getGroupPermissions();
    assertNotNull(p);
    assertEquals(1, p.getOperations().size());
    checkPermissions(p, "internalUser", "*.*");

    // Verify that unreferenced properties inherit the type's allow
    Property other = getProperty(fp.getTypeContext(), clazz, "other");
    p = other.getGroupPermissions();
    assertNotNull(p);
    checkMerchantPermissions(p);
  }

  private void checkMerchantPermissions(GroupPermissions p) {
    assertEquals(p.getOperations().toString(), 5, p.getOperations().size());
    SecurityGroup everybody = checkPermissions(p, "*");
    assertTrue(everybody.isGlobalSecurityGroup());

    checkPermissions(p, "merchantUser", "crudOperation.update");

    // integrator is initially defined as a global group, but then redefined in the merchant block
    SecurityGroup integratorUser = checkPermissions(p, "integratorUser",
        "crudOperation.create", "crudOperation.read",
        "crudOperation.update", "crudOperation.delete");
    assertFalse(integratorUser.isGlobalSecurityGroup());
    assertEquals("integratorUser", integratorUser.getPaths().get(0).getPath().get(0).getName());

    checkPermissions(p, "clerk", "crudOperation.read");
    SecurityGroup internalUser = checkPermissions(p, "internalUser", "*.*");
    assertTrue(internalUser.isGlobalSecurityGroup());
  }

  private Property getProperty(TypeContext ctx, Class<? extends HasUuid> clazz, String propertyName) {
    for (Property p : ctx.describe(clazz).getProperties()) {
      if (p.getName().equals(propertyName)) {
        return p;
      }
    }
    return null;
  }
}
TOP

Related Classes of com.getperka.flatpack.policy.PolicyExtractionTest

TOP
Copyright © 2018 www.massapi.com. All rights reserved.
All source code are property of their respective owners. Java is a trademark of Sun Microsystems, Inc and owned by ORACLE Inc. Contact coftware#gmail.com.