/*
 *  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.
 */

/* Notes on the contents of this policy file:
 *
 * The following methods in groovy have privileged operations wrapping
 * setAccessible.  If these wrappers are not provided, most codebases below
 * must have the following grant: 
 * permission java.lang.reflect.ReflectPermission "suppressAccessChecks";
 *  MetaMethod.createMetaMethod
 *  MetaMethod.invoke(Object Object[])
 *  ReflectionMetaMethod.invoke(Object Object[])
 *  DefaultGoovyMethods.dump(Object)
 */

/*
 * This keystore contains the public key of the pair used to sign GroovyTestJar.jar
 * See SecurityTest.testReadSignedJar()
 */
keystore "file:${user.dir}/security/groovykeys";

/*
 * ================= Codebases requiring java.security.AllPermission ===============
 * The following codebases require java.security.AllPermission.  They are considered trusted
 * for purposes of groovy security enforcement.  In a deployed groovy environment, these classes
 * would all be in a set of jars.  If these jars are signed, the grants could be strengthened to
 * by adding a signedBy clause to the grant.
 */
 
//spg:  Looks like james switched the output destination to bin from target/classes
//in his 7/13/04 update to the eclipse .classpath.  This permission allows the 
//Security tests to run properly in eclipse (they were unaffected when running from maven)
grant codeBase "file:${user.dir}/bin/-" {
    permission java.security.AllPermission;
};

grant codeBase "file:${user.dir}/target/classes/-" {
    permission java.security.AllPermission;
};

grant codeBase "file:${user.dir}/target/dist/-" {
    permission java.security.AllPermission;
};

grant codeBase "file:${user.dir}/target/instrumented-classes/-" {
    permission java.security.AllPermission;
};

grant codeBase "file:${user.dir}/target/classes/test/-" {
    permission java.security.AllPermission;
};

grant codeBase "file:${groovy.lib}/-" {
    permission java.security.AllPermission;
};

/*
 * When running from maven, this codebase is required.
 * If not running from maven, the codesource will not be found, but will not cause an error.
 */
grant codeBase "file:${maven.home}/-" {
    permission java.security.AllPermission;
};

/*
 * When running from Gradle, this codebase is required.
 * If not running from Gradle, the codesource will not be found, but will not cause an error.
 */
grant codeBase "file:${gradle.home}/-" {
    permission java.security.AllPermission;
};

grant codeBase "file:${gradle.junit}" {
    permission java.security.AllPermission;
};

/*
 * When running from ant, this codebase is required.
 * If not running from ant, the codesource will not be found, but will not cause an error.
 * TODO: narrow this down to specific jars
 */
grant codeBase "file:${user.dir}/target/lib/-" {
    permission java.security.AllPermission;
};

/*
 * When running the junit plugin from within eclipse, this codebase is required.
 * If not running from eclipse, the codesource will not be found, but will not cause an error.
 */
grant codeBase "file:${user.dir}/../../plugins/-" {
    permission java.security.AllPermission;
};

/*
 * ================= Default codebases created by groovy. ===============
 * The following codebases are assigned when groovy parses a groovy script
 */

/* 
 * GroovyShell.parse(InputStream,...) is given a codebase of "groovy.shell" because no actual
 * codebase can be determined.  The other forms of parse(File) and parse(GroovyCodeSource) allow
 * for more control.  These permission should be set to control scripts that are passed into
 * the shell in the form of a string or other groovy code of unknown provenance.
 */
grant codeBase "file:/groovy/shell" {
    permission java.lang.RuntimePermission "accessDeclaredMembers";
};

/*
 * Similar to "file:/groovy/shell", but implying a direct call to GroovyClassLoader.parse() without
 * passing through GroovyShell.
 */
grant codeBase "file:/groovy/script" {
    permission java.lang.RuntimePermission "accessDeclaredMembers";
    //permission java.util.PropertyPermission "groovy.output.dir", "read";
};

/*
 * The TestSupport class has a loadClass method that takes a ClassNode and runs it
 * through defineClass() of the class loader.  The codebase for this operation is
 * set to "/groovy/testSupport".
 */
grant codeBase "file:/groovy/testSupport" {
    permission java.lang.RuntimePermission "accessDeclaredMembers";
};

/*
 * ================= SecurityTest codebases  ===============
 * The following grants are for individual security test cases where the
 * codebase is explicity specified (e.g. the script is a raw string rather
 * than read from a file).  Note that even though the codebases conform to
 * the file URL syntax, they are not physical files: they represent virtual
 * codebases.
 * The permission grant that is commented out is the permission that is 
 * expected to be missing by the test case.  It is here as a comment for
 * information.
 */
 
//Since a codebase is a URL, we can make use of the natural hierarchy permission implications
//to grant a 'global' accessDeclaredPermission here.
grant codeBase "file:/groovy/security/-" {
    permission java.lang.RuntimePermission "accessDeclaredMembers";
};

grant codeBase "file:/groovy/security/testForbiddenPackage" {
    //permission java.lang.RuntimePermission "accessClassInPackage.sun.*";
};

grant codeBase "file:/groovy/security/javax/print/deny" {
    //permission java.lang.RuntimePermission "accessClassInPackage.javax.print";
};

grant codeBase "file:/groovy/security/javax/print/allow" {
    permission java.lang.RuntimePermission "accessClassInPackage.javax.print";
};

/*
 * ================= .groovy script file codebases  ===============
 * The following grants are for individual security test cases.
 * The permission grant that is commented out is the permission that is 
 * expected to be missing by the test case.  It is here as a comment for
 * information.
 */
grant codeBase "file:${user.dir}/src/test/-" {
    // Required by most groovy scripts during execution because of the heavy use of reflection/
    // introspection.  The groovy code could potentially be changed to eliminate this requirement
    // by adding privileged operations in many places.
    permission java.lang.RuntimePermission "accessDeclaredMembers";

    // SHOULD NOT HAVE TO DO THIS! - Level.getLocalizedName() should have a doPrivileged block.
    // Any test that logs, will encounter this (although it will be masked by the method
    permission java.lang.RuntimePermission "accessClassInPackage.sun.util.logging.resources";
};

grant codeBase "file:${user.dir}/src/test/groovy/security/forbiddenCodeBase.gvy" {
    //The following grant is commented out so that the test case will throw an AccessControlException
    permission groovy.security.GroovyCodeSourcePermission "groovy/security/forbiddenCodeBase";
};

// Grant permission to .groovy files extracted from a signed jar that has been signedBy "Groovy"
grant signedBy "Groovy" {
    permission java.lang.RuntimePermission "accessDeclaredMembers";
    permission java.util.PropertyPermission "user.home", "read";
};

grant codeBase "file:${user.dir}/src/test/groovy/bugs/BadScriptNameBug.groovy" {
    permission java.util.PropertyPermission "java.class.path", "read";
    permission java.io.FilePermission "<<ALL FILES>>", "read";
    permission java.lang.RuntimePermission "createClassLoader";
};

grant codeBase "file:${user.dir}/src/test/groovy/ClosureListenerTest.groovy" {
    permission java.util.PropertyPermission "java.awt.headless", "read";
    // below seems like a new requirement in jdk 1.6/1.7
    permission java.util.PropertyPermission "os.version", "read";
};

grant codeBase "file:${user.dir}/src/test/groovy/ClosureMethodTest.groovy" {
    permission java.io.FilePermission "${user.dir}${/}src${/}test${/}-", "read";
    permission java.util.PropertyPermission "file.encoding", "read";
};

grant codeBase "file:${user.dir}/src/test/groovy/GroovyMethodsTest.groovy" {
    permission java.util.PropertyPermission "*", "read,write";
    //spg 2006-02-09 added ALL FILES execute because a test case 
    //invokes Runtime.exec().  This is OK and permission should be granted here.
    permission java.io.FilePermission "<<ALL FILES>>", "execute";
};

grant codeBase "file:${user.dir}/src/test/groovy/ClosureWithDefaultParamTest.groovy" {
    permission java.io.FilePermission "src${/}test${/}-", "read";
    permission java.util.PropertyPermission "file.encoding", "read";
};

grant codeBase "file:${user.dir}/src/test/groovy/bugs/ConstructorBug.groovy" {
    permission java.lang.RuntimePermission "createClassLoader";
    permission java.io.FilePermission "src${/}test${/}groovy${/}bugs${/}TestBase.groovy", "read";
    permission java.io.FilePermission "src${/}test${/}groovy${/}bugs${/}TestDerived.groovy", "read";
};

grant codeBase "file:${user.dir}/src/test/groovy/bugs/ForAndSqlBug.groovy" {
    permission java.io.FilePermission "target${/}classes${/}test${/}*", "read, write";
};

grant codeBase "file:${user.dir}/src/test/groovy/bugs/ForLoopBug.groovy" {
    permission java.io.FilePermission "target${/}classes${/}test${/}*", "read, write";
    permission java.io.FilePermission "target${/}classes${/}test${/}*", "read, write";
};

grant codeBase "file:${user.dir}/src/test/groovy/bugs/Groovy303_Bug.groovy" {
    permission java.awt.AWTPermission "showWindowWithoutWarningBanner";
    // below seems like a new requirement in jdk 1.5
    permission java.util.PropertyPermission "os.version", "read";
};

grant codeBase "file:${user.dir}/src/test/groovy/script/ScriptTest.groovy" {
    permission java.io.FilePermission "src${/}test${/}groovy${/}-", "read";
};

grant codeBase "file:${user.dir}/src/test/groovy/script/EvalInScript.groovy" {
    permission java.io.FilePermission "src${/}test${/}groovy${/}script${/}HelloWorld.groovy", "read";
};

grant codeBase "file:${user.dir}/src/test/groovy/sql/PersonTest.groovy" {
    permission java.io.FilePermission "target${/}classes${/}test${/}groovy${/}sql${/}-", "read";
};

grant codeBase "file:${user.dir}/src/test/groovy/sql/SqlCompleteTest.groovy" {
    permission java.io.FilePermission "target${/}classes${/}test${/}groovy${/}sql${/}-", "read";
};

grant codeBase "file:${user.dir}/src/test/groovy/sql/-" {
    permission java.util.PropertyPermission "groovy.testdb.props", "read";
    permission java.io.FilePermission "${groovy.testdb.props}", "read";
};

grant codeBase "file:${user.dir}/src/test/groovy/sql/SqlCompleteWithoutDataSourceTest.groovy" {
    permission java.util.PropertyPermission "file.separator", "read";
    permission java.util.PropertyPermission "line.separator", "read";
};

grant codeBase "file:${user.dir}/src/test/groovy/sql/SqlTest.groovy" {
    permission java.io.FilePermission "target${/}classes${/}test${/}groovy${/}sql${/}-", "read";
};

grant codeBase "file:${user.dir}/src/test/groovy/util/AntTest.groovy" {
    permission java.security.AllPermission;
};

grant codeBase "file:${user.dir}/src/test/org/codehaus/groovy/classgen/MetaClassTest.groovy" {
    permission java.io.FilePermission "target${/}classes${/}test${/}-", "read";
};
