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

// Policy file for solr. Please keep minimal and avoid wildcards.

// permissions needed for tests to pass, based on properties set by the build system
// NOTE: if the property is not set, the permission entry is ignored.
grant {
  // 3rd party jar resources (where symlinks are not supported), test-files/ resources
  permission java.io.FilePermission "${common.dir}${/}-", "read";
  permission java.io.FilePermission "${common.dir}${/}..${/}solr${/}-", "read";

  // system jar resources
  permission java.io.FilePermission "${java.home}${/}-", "read";

  // tmpdir
  permission java.io.FilePermission "${java.io.tmpdir}", "read,write";
  permission java.io.FilePermission "${java.io.tmpdir}${/}-", "read,write,delete";

  // Test launchers (randomizedtesting, etc.)
  permission java.io.FilePermission "${junit4.childvm.cwd}", "read";
  permission java.io.FilePermission "${junit4.childvm.cwd}${/}temp", "read,write,delete";
  permission java.io.FilePermission "${junit4.childvm.cwd}${/}temp${/}-", "read,write,delete";
  permission java.io.FilePermission "${junit4.childvm.cwd}${/}jacoco.db", "write";
  permission java.io.FilePermission "${junit4.tempDir}${/}*", "read,write,delete";
  permission java.io.FilePermission "${clover.db.dir}${/}-", "read,write,delete";
  // 3rd party jar resources (where symlinks are supported)
  permission java.io.FilePermission "${user.home}${/}.ivy2${/}cache${/}-", "read";

  permission java.io.FilePermission "${tests.linedocsfile}", "read";
  // DirectoryFactoryTest messes with these (wtf?)
  permission java.io.FilePermission "/tmp/inst1/conf/solrcore.properties", "read";
  permission java.io.FilePermission "/path/to/myinst/conf/solrcore.properties", "read";
  // TestConfigSets messes with these (wtf?)
  permission java.io.FilePermission "/path/to/solr/home/lib", "read";

  permission java.nio.file.LinkPermission "hard";

  // all possibilities of accepting/binding/connections on localhost with ports >=1024:
  permission java.net.SocketPermission "localhost:1024-", "accept,listen,connect,resolve";
  permission java.net.SocketPermission "127.0.0.1:1024-", "accept,listen,connect,resolve";
  permission java.net.SocketPermission "[::1]:1024-", "accept,listen,connect,resolve";

  // Basic permissions needed for Lucene to work:
  permission java.util.PropertyPermission "*", "read,write";

  // needed by randomizedtesting runner to identify test methods.
  permission java.lang.reflect.ReflectPermission "suppressAccessChecks";
  permission java.lang.reflect.ReflectPermission "newProxyInPackage.dev.langchain4j.model.cohere";
  permission java.lang.reflect.ReflectPermission "newProxyInPackage.dev.ai4j.openai4j";
  permission java.lang.reflect.ReflectPermission "newProxyInPackage.dev.langchain4j.model.huggingface";
  permission java.net.SocketPermission "api.cohere.ai", "accept,listen,connect,resolve";
  permission java.net.SocketPermission "api.openai.com", "accept,listen,connect,resolve";
  permission java.net.SocketPermission "api.mistral.ai", "accept,listen,connect,resolve";
  permission java.net.SocketPermission "api-inference.huggingface.co", "accept,listen,connect,resolve";
  permission java.net.SocketPermission "langchain4j.dev", "accept,listen,connect,resolve";

  permission java.lang.RuntimePermission "accessDeclaredMembers";
  // needed by certain tests to redirect sysout/syserr:
  permission java.lang.RuntimePermission "setIO";
  // needed by randomized runner to catch failures from other threads:
  permission java.lang.RuntimePermission "setDefaultUncaughtExceptionHandler";
  // needed by randomized runner getTopThreadGroup:
  permission java.lang.RuntimePermission "modifyThreadGroup";
  // needed by tests e.g. shutting down executors:
  permission java.lang.RuntimePermission "modifyThread";
  // needed for tons of test hacks etc
  permission java.lang.RuntimePermission "getStackTrace";
  // needed for mock filesystems in tests
  permission java.lang.RuntimePermission "fileSystemProvider";
  // needed by IndexFetcher
  permission java.lang.RuntimePermission "getFileStoreAttributes";
  // analyzers/uima: needed by lucene expressions' JavascriptCompiler
  permission java.lang.RuntimePermission "createClassLoader";
  // needed to test unmap hack on platforms that support it
  permission java.lang.RuntimePermission "accessClassInPackage.sun.misc";
  // needed by jacoco to dump coverage
  permission java.lang.RuntimePermission "shutdownHooks";
  // needed by org.apache.logging.log4j
  permission java.lang.RuntimePermission "getenv.*";
  permission java.lang.RuntimePermission "getClassLoader";
  permission java.lang.RuntimePermission "setContextClassLoader";
  permission java.lang.RuntimePermission "getStackWalkerWithClassReference";
  // needed by bytebuddy
  permission java.lang.RuntimePermission "defineClass";
  // needed by mockito
  permission java.lang.RuntimePermission "accessClassInPackage.sun.reflect";
  permission java.lang.RuntimePermission "reflectionFactoryAccess";
  // needed by SolrResourceLoader
  permission java.lang.RuntimePermission "closeClassLoader";
  // needed by HttpSolrClient
  permission java.lang.RuntimePermission "getFileSystemAttributes";
  // needed by hadoop auth (TODO: there is a cleaner way to handle this)
  permission java.lang.RuntimePermission "loadLibrary.jaas";
  permission java.lang.RuntimePermission "loadLibrary.jaas_unix";
  permission java.lang.RuntimePermission "loadLibrary.jaas_nt";
  // needed by hadoop common RawLocalFileSystem for java nio getOwner
  permission java.lang.RuntimePermission "accessUserInformation";
  // needed by hadoop hdfs
  permission java.lang.RuntimePermission "readFileDescriptor";
  permission java.lang.RuntimePermission "writeFileDescriptor";
  // needed by hadoop http
  permission java.lang.RuntimePermission "getProtectionDomain";
  // needed by aws s3 sdk (Apache HTTP Client)
  permission java.lang.RuntimePermission "accessClassInPackage.jdk.internal.reflect";
  // These two *have* to be spelled out a separate
  permission java.lang.management.ManagementPermission "control";
  permission java.lang.management.ManagementPermission "monitor";

  // needed by DIH - possibly even after DIH is a package
  permission java.sql.SQLPermission "deregisterDriver";

  permission java.util.logging.LoggingPermission "control";

  // needed by solr mbeans feature/tests
  // TODO: can we remove wildcard for class names/members?
  permission javax.management.MBeanPermission "*", "getAttribute";
  permission javax.management.MBeanPermission "*", "getMBeanInfo";
  permission javax.management.MBeanPermission "*", "queryMBeans";
  permission javax.management.MBeanPermission "*", "queryNames";
  permission javax.management.MBeanPermission "*", "registerMBean";
  permission javax.management.MBeanPermission "*", "unregisterMBean";
  permission javax.management.MBeanServerPermission "createMBeanServer";
  permission javax.management.MBeanServerPermission "findMBeanServer";
  permission javax.management.MBeanServerPermission "releaseMBeanServer";
  permission javax.management.MBeanTrustPermission "register";

  // needed by hadoop auth
  permission javax.security.auth.AuthPermission "getSubject";
  permission javax.security.auth.AuthPermission "modifyPrincipals";
  permission javax.security.auth.AuthPermission "doAs";
  permission javax.security.auth.AuthPermission "getLoginConfiguration";
  permission javax.security.auth.AuthPermission "setLoginConfiguration";
  permission javax.security.auth.AuthPermission "modifyPrivateCredentials";
  permission javax.security.auth.AuthPermission "modifyPublicCredentials";
  permission javax.security.auth.PrivateCredentialPermission "org.apache.hadoop.security.Credentials * \"*\"", "read";

  // needed by hadoop security
  permission java.security.SecurityPermission "putProviderProperty.SaslPlainServer";
  permission java.security.SecurityPermission "insertProvider";

  // Needed by JWT integration tests & S3 clients
  permission java.lang.RuntimePermission "setFactory";
  permission java.security.SecurityPermission "getProperty.org.bouncycastle.pkcs12.default";

  permission javax.xml.bind.JAXBPermission "setDatatypeConverter";

  // SSL related properties for Solr tests
  permission javax.net.ssl.SSLPermission "setDefaultSSLContext";

  // SASL/Kerberos related properties for Solr tests
  permission javax.security.auth.PrivateCredentialPermission "javax.security.auth.kerberos.KerberosTicket * \"*\"", "read";

  // may only be necessary with Java 7?
  permission javax.security.auth.PrivateCredentialPermission "javax.security.auth.kerberos.KeyTab * \"*\"", "read";
  permission javax.security.auth.PrivateCredentialPermission "sun.security.jgss.krb5.Krb5Util$KeysFromKeyTab * \"*\"", "read";

  permission javax.security.auth.kerberos.ServicePermission "*", "initiate";
  permission javax.security.auth.kerberos.ServicePermission "*", "accept";
  permission javax.security.auth.kerberos.DelegationPermission "\"*\" \"krbtgt/EXAMPLE.COM@EXAMPLE.COM\"";

  // java 8 accessibility requires this perm - should not after 8 I believe (rrd4j is the root reason we hit an accessibility code path)
  permission java.awt.AWTPermission "*";

  // used by solr to create sandboxes (e.g. script execution)
  permission java.security.SecurityPermission "createAccessControlContext";

  // for Apache HttpClient useSystemProperties
  permission java.net.NetPermission "getProxySelector";
  permission java.net.NetPermission "requestPasswordAuthentication";
};

// additional permissions based on system properties set by /bin/solr
// NOTE: if the property is not set, the permission entry is ignored.
grant {
  permission java.io.FilePermission "${hadoop.security.credential.provider.path}", "read,write,delete,readlink";
  permission java.io.FilePermission "${hadoop.security.credential.provider.path}${/}-", "read,write,delete,readlink";

  permission java.io.FilePermission "${solr.jetty.keystore}", "read,readlink";

  permission java.io.FilePermission "${solr.jetty.truststore}", "read,readlink";

  permission java.io.FilePermission "${javax.net.ssl.keyStore}", "read,readlink";

  permission java.io.FilePermission "${javax.net.ssl.trustStore}", "read,readlink";

  permission java.io.FilePermission "${solr.jetty.keystoreParentPath}", "read,readlink";
  permission java.io.FilePermission "${javax.net.ssl.keyStoreParentPath}", "read,readlink";

  permission java.io.FilePermission "${solr.install.dir}", "read,write,delete,readlink";
  permission java.io.FilePermission "${solr.install.dir}${/}-", "read,write,delete,readlink";
  permission java.io.FilePermission "${solr.install.symDir}", "read,write,delete,readlink";
  permission java.io.FilePermission "${solr.install.symDir}${/}-", "read,write,delete,readlink";

  permission java.io.FilePermission "${jetty.home}", "read,write,delete,readlink";
  permission java.io.FilePermission "${jetty.home}${/}-", "read,write,delete,readlink";

  permission java.io.FilePermission "${solr.solr.home}", "read,write,delete,readlink";
  permission java.io.FilePermission "${solr.solr.home}${/}-", "read,write,delete,readlink";

  permission java.io.FilePermission "${solr.data.home}", "read,write,delete,readlink";
  permission java.io.FilePermission "${solr.data.home}${/}-", "read,write,delete,readlink";

  permission java.io.FilePermission "${solr.default.confdir}", "read,write,delete,readlink";
  permission java.io.FilePermission "${solr.default.confdir}${/}-", "read,write,delete,readlink";

  permission java.io.FilePermission "${solr.log.dir}", "read,write,delete,readlink";
  permission java.io.FilePermission "${solr.log.dir}${/}-", "read,write,delete,readlink";

  permission java.io.FilePermission "${solr.allowPaths}", "read,write,delete,readlink";
  permission java.io.FilePermission "${solr.allowPaths}${/}-", "read,write,delete,readlink";

  permission java.io.FilePermission "${solr.sharedLib}", "read,readlink";
  permission java.io.FilePermission "${solr.sharedLib}${/}-", "read,readlink";

  permission java.io.FilePermission "${log4j.configurationFile}", "read,write,delete,readlink";

  // Credentials for S3 Repository
  permission java.io.FilePermission "${aws.sharedCredentialsFile}", "read,readlink";
  permission java.io.FilePermission "${aws.configFile}", "read,readlink";
  permission java.io.FilePermission "${user.home}${/}.aws${/}-", "read,readlink";

  // expanded to a wildcard if set, allows all networking everywhere
  permission java.net.SocketPermission "${solr.internal.network.permission}", "accept,listen,connect,resolve";
};
