fragment.
<artifactId>org.argeo.maintenance</artifactId>
<version>2.1.89-SNAPSHOT</version>
</dependency>
- <dependency>
- <groupId>org.argeo.commons</groupId>
- <artifactId>org.argeo.ext.jackrabbit</artifactId>
- <version>2.1.89-SNAPSHOT</version>
- </dependency>
+<!-- <dependency> -->
+<!-- <groupId>org.argeo.commons</groupId> -->
+<!-- <artifactId>org.argeo.ext.jackrabbit</artifactId> -->
+<!-- <version>2.1.89-SNAPSHOT</version> -->
+<!-- </dependency> -->
<dependency>
<groupId>org.argeo.commons</groupId>
<artifactId>org.argeo.ext.equinox.jetty</artifactId>
package org.argeo.api;
+/** A configured node deployment. */
public interface NodeDeployment {
Long getAvailableSince();
}
import java.util.List;
import java.util.Locale;
+/** A running node process. */
public interface NodeState {
Locale getDefaultLocale();
String getHostname();
- boolean isClean();
-
Long getAvailableSince();
}
--- /dev/null
+eclipse.preferences.version=1
+org.eclipse.jdt.core.compiler.annotation.inheritNullAnnotations=disabled
+org.eclipse.jdt.core.compiler.annotation.missingNonNullByDefaultAnnotation=ignore
+org.eclipse.jdt.core.compiler.annotation.nonnull=org.eclipse.jdt.annotation.NonNull
+org.eclipse.jdt.core.compiler.annotation.nonnull.secondary=
+org.eclipse.jdt.core.compiler.annotation.nonnullbydefault=org.eclipse.jdt.annotation.NonNullByDefault
+org.eclipse.jdt.core.compiler.annotation.nonnullbydefault.secondary=
+org.eclipse.jdt.core.compiler.annotation.nullable=org.eclipse.jdt.annotation.Nullable
+org.eclipse.jdt.core.compiler.annotation.nullable.secondary=
+org.eclipse.jdt.core.compiler.annotation.nullanalysis=disabled
+org.eclipse.jdt.core.compiler.problem.APILeak=warning
+org.eclipse.jdt.core.compiler.problem.annotationSuperInterface=warning
+org.eclipse.jdt.core.compiler.problem.autoboxing=ignore
+org.eclipse.jdt.core.compiler.problem.comparingIdentical=warning
+org.eclipse.jdt.core.compiler.problem.deadCode=warning
+org.eclipse.jdt.core.compiler.problem.deprecation=warning
+org.eclipse.jdt.core.compiler.problem.deprecationInDeprecatedCode=disabled
+org.eclipse.jdt.core.compiler.problem.deprecationWhenOverridingDeprecatedMethod=disabled
+org.eclipse.jdt.core.compiler.problem.discouragedReference=warning
+org.eclipse.jdt.core.compiler.problem.emptyStatement=ignore
+org.eclipse.jdt.core.compiler.problem.explicitlyClosedAutoCloseable=ignore
+org.eclipse.jdt.core.compiler.problem.fallthroughCase=ignore
+org.eclipse.jdt.core.compiler.problem.fatalOptionalError=disabled
+org.eclipse.jdt.core.compiler.problem.fieldHiding=ignore
+org.eclipse.jdt.core.compiler.problem.finalParameterBound=warning
+org.eclipse.jdt.core.compiler.problem.finallyBlockNotCompletingNormally=warning
+org.eclipse.jdt.core.compiler.problem.forbiddenReference=warning
+org.eclipse.jdt.core.compiler.problem.hiddenCatchBlock=warning
+org.eclipse.jdt.core.compiler.problem.includeNullInfoFromAsserts=disabled
+org.eclipse.jdt.core.compiler.problem.incompatibleNonInheritedInterfaceMethod=warning
+org.eclipse.jdt.core.compiler.problem.incompleteEnumSwitch=warning
+org.eclipse.jdt.core.compiler.problem.indirectStaticAccess=ignore
+org.eclipse.jdt.core.compiler.problem.localVariableHiding=ignore
+org.eclipse.jdt.core.compiler.problem.methodWithConstructorName=warning
+org.eclipse.jdt.core.compiler.problem.missingDefaultCase=ignore
+org.eclipse.jdt.core.compiler.problem.missingDeprecatedAnnotation=ignore
+org.eclipse.jdt.core.compiler.problem.missingEnumCaseDespiteDefault=disabled
+org.eclipse.jdt.core.compiler.problem.missingHashCodeMethod=ignore
+org.eclipse.jdt.core.compiler.problem.missingOverrideAnnotation=ignore
+org.eclipse.jdt.core.compiler.problem.missingOverrideAnnotationForInterfaceMethodImplementation=enabled
+org.eclipse.jdt.core.compiler.problem.missingSerialVersion=warning
+org.eclipse.jdt.core.compiler.problem.missingSynchronizedOnInheritedMethod=ignore
+org.eclipse.jdt.core.compiler.problem.noEffectAssignment=warning
+org.eclipse.jdt.core.compiler.problem.noImplicitStringConversion=warning
+org.eclipse.jdt.core.compiler.problem.nonExternalizedStringLiteral=ignore
+org.eclipse.jdt.core.compiler.problem.nonnullParameterAnnotationDropped=warning
+org.eclipse.jdt.core.compiler.problem.nonnullTypeVariableFromLegacyInvocation=warning
+org.eclipse.jdt.core.compiler.problem.nullAnnotationInferenceConflict=error
+org.eclipse.jdt.core.compiler.problem.nullReference=warning
+org.eclipse.jdt.core.compiler.problem.nullSpecViolation=error
+org.eclipse.jdt.core.compiler.problem.nullUncheckedConversion=warning
+org.eclipse.jdt.core.compiler.problem.overridingPackageDefaultMethod=warning
+org.eclipse.jdt.core.compiler.problem.parameterAssignment=ignore
+org.eclipse.jdt.core.compiler.problem.pessimisticNullAnalysisForFreeTypeVariables=warning
+org.eclipse.jdt.core.compiler.problem.possibleAccidentalBooleanAssignment=ignore
+org.eclipse.jdt.core.compiler.problem.potentialNullReference=ignore
+org.eclipse.jdt.core.compiler.problem.potentiallyUnclosedCloseable=ignore
+org.eclipse.jdt.core.compiler.problem.rawTypeReference=warning
+org.eclipse.jdt.core.compiler.problem.redundantNullAnnotation=warning
+org.eclipse.jdt.core.compiler.problem.redundantNullCheck=ignore
+org.eclipse.jdt.core.compiler.problem.redundantSpecificationOfTypeArguments=ignore
+org.eclipse.jdt.core.compiler.problem.redundantSuperinterface=ignore
+org.eclipse.jdt.core.compiler.problem.reportMethodCanBePotentiallyStatic=ignore
+org.eclipse.jdt.core.compiler.problem.reportMethodCanBeStatic=ignore
+org.eclipse.jdt.core.compiler.problem.specialParameterHidingField=disabled
+org.eclipse.jdt.core.compiler.problem.staticAccessReceiver=warning
+org.eclipse.jdt.core.compiler.problem.suppressOptionalErrors=disabled
+org.eclipse.jdt.core.compiler.problem.suppressWarnings=enabled
+org.eclipse.jdt.core.compiler.problem.suppressWarningsNotFullyAnalysed=info
+org.eclipse.jdt.core.compiler.problem.syntacticNullAnalysisForFields=disabled
+org.eclipse.jdt.core.compiler.problem.syntheticAccessEmulation=ignore
+org.eclipse.jdt.core.compiler.problem.terminalDeprecation=warning
+org.eclipse.jdt.core.compiler.problem.typeParameterHiding=warning
+org.eclipse.jdt.core.compiler.problem.unavoidableGenericTypeProblems=enabled
+org.eclipse.jdt.core.compiler.problem.uncheckedTypeOperation=warning
+org.eclipse.jdt.core.compiler.problem.unclosedCloseable=warning
+org.eclipse.jdt.core.compiler.problem.undocumentedEmptyBlock=ignore
+org.eclipse.jdt.core.compiler.problem.unhandledWarningToken=warning
+org.eclipse.jdt.core.compiler.problem.unlikelyCollectionMethodArgumentType=warning
+org.eclipse.jdt.core.compiler.problem.unlikelyCollectionMethodArgumentTypeStrict=disabled
+org.eclipse.jdt.core.compiler.problem.unlikelyEqualsArgumentType=info
+org.eclipse.jdt.core.compiler.problem.unnecessaryElse=ignore
+org.eclipse.jdt.core.compiler.problem.unnecessaryTypeCheck=ignore
+org.eclipse.jdt.core.compiler.problem.unqualifiedFieldAccess=ignore
+org.eclipse.jdt.core.compiler.problem.unstableAutoModuleName=warning
+org.eclipse.jdt.core.compiler.problem.unusedDeclaredThrownException=ignore
+org.eclipse.jdt.core.compiler.problem.unusedDeclaredThrownExceptionExemptExceptionAndThrowable=enabled
+org.eclipse.jdt.core.compiler.problem.unusedDeclaredThrownExceptionIncludeDocCommentReference=enabled
+org.eclipse.jdt.core.compiler.problem.unusedDeclaredThrownExceptionWhenOverriding=disabled
+org.eclipse.jdt.core.compiler.problem.unusedExceptionParameter=ignore
+org.eclipse.jdt.core.compiler.problem.unusedImport=warning
+org.eclipse.jdt.core.compiler.problem.unusedLabel=warning
+org.eclipse.jdt.core.compiler.problem.unusedLocal=warning
+org.eclipse.jdt.core.compiler.problem.unusedObjectAllocation=ignore
+org.eclipse.jdt.core.compiler.problem.unusedParameter=ignore
+org.eclipse.jdt.core.compiler.problem.unusedParameterIncludeDocCommentReference=enabled
+org.eclipse.jdt.core.compiler.problem.unusedParameterWhenImplementingAbstract=disabled
+org.eclipse.jdt.core.compiler.problem.unusedParameterWhenOverridingConcrete=disabled
+org.eclipse.jdt.core.compiler.problem.unusedPrivateMember=warning
+org.eclipse.jdt.core.compiler.problem.unusedTypeParameter=ignore
+org.eclipse.jdt.core.compiler.problem.unusedWarningToken=warning
+org.eclipse.jdt.core.compiler.problem.varargsArgumentNeedCast=warning
+++ /dev/null
-compilers.f.unresolved-features=1
-compilers.f.unresolved-plugins=1
-compilers.incompatible-environment=1
-compilers.p.build=1
-compilers.p.build.bin.includes=1
-compilers.p.build.encodings=2
-compilers.p.build.java.compiler=2
-compilers.p.build.java.compliance=1
-compilers.p.build.missing.output=2
-compilers.p.build.output.library=1
-compilers.p.build.source.library=1
-compilers.p.build.src.includes=1
-compilers.p.deprecated=1
-compilers.p.discouraged-class=1
-compilers.p.exec-env-too-low=1
-compilers.p.internal=1
-compilers.p.missing-packages=2
-compilers.p.missing-version-export-package=2
-compilers.p.missing-version-import-package=2
-compilers.p.missing-version-require-bundle=2
-compilers.p.no-required-att=0
-compilers.p.no.automatic.module=1
-compilers.p.not-externalized-att=2
-compilers.p.service.component.without.lazyactivation=2
-compilers.p.unknown-attribute=1
-compilers.p.unknown-class=1
-compilers.p.unknown-element=1
-compilers.p.unknown-identifier=1
-compilers.p.unknown-resource=1
-compilers.p.unresolved-ex-points=0
-compilers.p.unresolved-import=0
-compilers.s.create-docs=false
-compilers.s.doc-folder=doc
-compilers.s.open-tags=1
-eclipse.preferences.version=1
--- /dev/null
+package org.argeo.cms.internal.jcr;
+
+import java.util.Properties;
+
+import org.apache.jackrabbit.core.config.ConfigurationException;
+import org.apache.jackrabbit.core.config.RepositoryConfigurationParser;
+import org.apache.jackrabbit.core.config.WorkspaceSecurityConfig;
+import org.apache.jackrabbit.core.util.db.ConnectionFactory;
+import org.w3c.dom.Element;
+
+/**
+ * A {@link RepositoryConfigurationParser} providing more flexibility with
+ * classloaders.
+ */
+@SuppressWarnings("restriction")
+class CustomRepositoryConfigurationParser extends RepositoryConfigurationParser {
+ private ClassLoader accessControlProviderClassLoader = null;
+
+ public CustomRepositoryConfigurationParser(Properties variables) {
+ super(variables);
+ }
+
+ public CustomRepositoryConfigurationParser(Properties variables, ConnectionFactory connectionFactory) {
+ super(variables, connectionFactory);
+ }
+
+ @Override
+ protected RepositoryConfigurationParser createSubParser(Properties variables) {
+ Properties props = new Properties(getVariables());
+ props.putAll(variables);
+ CustomRepositoryConfigurationParser subParser = new CustomRepositoryConfigurationParser(props,
+ connectionFactory);
+ subParser.setAccessControlProviderClassLoader(accessControlProviderClassLoader);
+ return subParser;
+ }
+
+ @Override
+ public WorkspaceSecurityConfig parseWorkspaceSecurityConfig(Element parent) throws ConfigurationException {
+ WorkspaceSecurityConfig workspaceSecurityConfig = super.parseWorkspaceSecurityConfig(parent);
+ workspaceSecurityConfig.getAccessControlProviderConfig().setClassLoader(accessControlProviderClassLoader);
+ return workspaceSecurityConfig;
+ }
+
+ public void setAccessControlProviderClassLoader(ClassLoader accessControlProviderClassLoader) {
+ this.accessControlProviderClassLoader = accessControlProviderClassLoader;
+ }
+
+}
throw new ArgeoJcrException("Repository configuration not found");
InputSource config = new InputSource(in);
Properties jackrabbitVars = getConfigurationProperties(type, properties);
- RepositoryConfig repositoryConfig = RepositoryConfig.create(config, jackrabbitVars);
+ // RepositoryConfig repositoryConfig = RepositoryConfig.create(config,
+ // jackrabbitVars);
+
+ // custom configuration parser
+ CustomRepositoryConfigurationParser parser = new CustomRepositoryConfigurationParser(jackrabbitVars);
+ parser.setAccessControlProviderClassLoader(cl);
+ RepositoryConfig repositoryConfig = parser.parseRepositoryConfig(config);
+ repositoryConfig.init();
+
+ // set the proper classloaders
+ repositoryConfig.getSecurityConfig().getSecurityManagerConfig().setClassLoader(cl);
+ repositoryConfig.getSecurityConfig().getAccessManagerConfig().setClassLoader(cl);
+// for (WorkspaceConfig workspaceConfig : repositoryConfig.getWorkspaceConfigs()) {
+// workspaceConfig.getSecurityConfig().getAccessControlProviderConfig().setClassLoader(cl);
+// }
return repositoryConfig;
}
}
import java.io.IOException;
import java.net.URL;
-import java.nio.file.Files;
-import java.nio.file.Path;
import java.security.AllPermission;
-import java.util.Dictionary;
import java.util.List;
import java.util.Locale;
import java.util.concurrent.ExecutorService;
import org.argeo.api.NodeState;
import org.argeo.cms.CmsException;
import org.argeo.ident.IdentClient;
-import org.argeo.util.LangUtils;
import org.ietf.jgss.GSSCredential;
import org.osgi.framework.BundleActivator;
import org.osgi.framework.BundleContext;
private void initNode() throws IOException {
// Node state
- Path stateUuidPath = bc.getDataFile("stateUuid").toPath();
- String stateUuid;
- if (Files.exists(stateUuidPath)) {
- stateUuid = Files.readAllLines(stateUuidPath).get(0);
- } else {
- stateUuid = bc.getProperty(Constants.FRAMEWORK_UUID);
- Files.write(stateUuidPath, stateUuid.getBytes());
- }
- nodeState = new CmsState(stateUuid);
- Dictionary<String, Object> regProps = LangUtils.dico(Constants.SERVICE_PID, NodeConstants.NODE_STATE_PID);
- regProps.put(NodeConstants.CN, stateUuid);
- bc.registerService(NodeState.class, nodeState, regProps);
+// Path stateUuidPath = bc.getDataFile("stateUuid").toPath();
+// String stateUuid;
+// if (Files.exists(stateUuidPath)) {
+// stateUuid = Files.readAllLines(stateUuidPath).get(0);
+// } else {
+// stateUuid = bc.getProperty(Constants.FRAMEWORK_UUID);
+// Files.write(stateUuidPath, stateUuid.getBytes());
+// }
+ nodeState = new CmsState();
+// Dictionary<String, Object> regProps = LangUtils.dico(Constants.SERVICE_PID, NodeConstants.NODE_STATE_PID);
+// regProps.put(NodeConstants.CN, stateUuid);
+ bc.registerService(NodeState.class, nodeState, null);
// Node deployment
nodeDeployment = new CmsDeployment();
import static org.argeo.api.DataModelNamespace.CMS_DATA_MODEL_NAMESPACE;
import java.io.File;
+import java.io.IOException;
import java.io.InputStreamReader;
import java.io.Reader;
import java.lang.management.ManagementFactory;
private Long availableSince;
- private final boolean cleanState;
+// private final boolean cleanState;
private NodeHttp nodeHttp;
private boolean httpAvailable = false;
public CmsDeployment() {
- ServiceReference<NodeState> nodeStateSr = bc.getServiceReference(NodeState.class);
- if (nodeStateSr == null)
- throw new CmsException("No node state available");
+// ServiceReference<NodeState> nodeStateSr = bc.getServiceReference(NodeState.class);
+// if (nodeStateSr == null)
+// throw new CmsException("No node state available");
- NodeState nodeState = bc.getService(nodeStateSr);
- cleanState = nodeState.isClean();
+// NodeState nodeState = bc.getService(nodeStateSr);
+// cleanState = nodeState.isClean();
- nodeHttp = new NodeHttp(cleanState);
+ nodeHttp = new NodeHttp();
dataModels = new DataModels(bc);
initTrackers();
}
@Override
public ConfigurationAdmin addingService(ServiceReference<ConfigurationAdmin> reference) {
ConfigurationAdmin configurationAdmin = bc.getService(reference);
- deployConfig = new DeployConfig(configurationAdmin, dataModels, cleanState);
+ boolean isClean;
+ try {
+ Configuration[] confs = configurationAdmin
+ .listConfigurations("(service.factoryPid=" + NodeConstants.NODE_USER_ADMIN_PID + ")");
+ isClean = confs == null || confs.length == 0;
+ } catch (Exception e) {
+ throw new CmsException("Cannot analize clean state", e);
+ }
+ deployConfig = new DeployConfig(configurationAdmin, dataModels, isClean);
httpExpected = deployConfig.getProps(KernelConstants.JETTY_FACTORY_PID, "default") != null;
try {
- // Configuration[] configs = configurationAdmin
- // .listConfigurations("(service.factoryPid=" +
- // NodeConstants.NODE_REPOS_FACTORY_PID + ")");
- // for (Configuration config : configs) {
- // Object cn = config.getProperties().get(NodeConstants.CN);
- // if (log.isDebugEnabled())
- // log.debug("Standalone repo cn: " + cn);
- // }
Configuration[] configs = configurationAdmin
.listConfigurations("(service.factoryPid=" + NodeConstants.NODE_USER_ADMIN_PID + ")");
private List<Runnable> stopHooks = new ArrayList<>();
private final String stateUuid;
- private final boolean cleanState;
+// private final boolean cleanState;
private String hostname;
- public CmsState(String stateUuid) {
- this.stateUuid = stateUuid;
- String frameworkUuid = KernelUtils.getFrameworkProp(Constants.FRAMEWORK_UUID);
- this.cleanState = stateUuid.equals(frameworkUuid);
+ public CmsState() {
+// this.stateUuid = stateUuid;
+ this.stateUuid = KernelUtils.getFrameworkProp(Constants.FRAMEWORK_UUID);
+// this.cleanState = stateUuid.equals(frameworkUuid);
try {
this.hostname = InetAddress.getLocalHost().getHostName();
} catch (UnknownHostException e) {
availableSince = System.currentTimeMillis();
if (log.isDebugEnabled())
- log.debug("## CMS starting... stateUuid=" + this.stateUuid + (cleanState ? " (clean state) " : " "));
+ // log.debug("## CMS starting... stateUuid=" + this.stateUuid + (cleanState ? "
+ // (clean state) " : " "));
+ log.debug("## CMS starting... (" + stateUuid + ")");
initI18n();
initServices();
void shutdown() {
if (log.isDebugEnabled())
- log.debug("CMS stopping... stateUuid=" + this.stateUuid + (cleanState ? " (clean state) " : " "));
+ log.debug("CMS stopping... (" + this.stateUuid + ")");
if (kernelThread != null)
kernelThread.destroyAndJoin();
- // In a different state in order to avois interruptions
- new Thread(() -> applyStopHooks(), "Apply Argeo Stop Hooks").start();
- // applyStopHooks();
+ // In a different thread in order to avoid interruptions
+ Thread stopHookThread = new Thread(() -> applyStopHooks(), "Apply Argeo Stop Hooks");
+ stopHookThread.start();
+ try {
+ stopHookThread.join(10 * 60 * 1000);
+ } catch (InterruptedException e) {
+ // silent
+ }
long duration = ((System.currentTimeMillis() - availableSince) / 1000) / 60;
log.info("## ARGEO CMS STOPPED after " + (duration / 60) + "h " + (duration % 60) + "min uptime ##");
new GogoShellKiller().start();
}
- @Override
- public boolean isClean() {
- return cleanState;
- }
+// @Override
+// public boolean isClean() {
+// return cleanState;
+// }
@Override
public Long getAvailableSince() {
} catch (Exception e1) {
// silent
}
+ tryCount--;
}
}
} catch (Exception e) {
deployConfigs = new LdifParser().read(in);
}
if (isClean) {
+ if(log.isDebugEnabled())
+ log.debug("Clean state, loading from framework properties...");
setFromFrameworkProperties(isFirstInit);
for (LdapName dn : deployConfigs.keySet()) {
Rdn lastRdn = dn.getRdn(dn.size() - 1);
private String httpRealm = "Argeo";
private String webDavConfig = HttpUtils.WEBDAV_CONFIG;
- private final boolean cleanState;
+// private final boolean cleanState;
- public NodeHttp(boolean cleanState) {
- this.cleanState = cleanState;
+ public NodeHttp() {
+// this.cleanState = cleanState;
httpServiceTracker = new PrepareHttpStc();
// httpServiceTracker.open();
KernelUtils.asyncOpen(httpServiceTracker);
throw new CmsException("An http service is already configured");
repositories = new RepositoriesStc(bc, httpService);
// repositories.open();
- if (cleanState)
- KernelUtils.asyncOpen(repositories);
+
+ ///if (cleanState)
+ // FIXME properly publish servlets
+ //KernelUtils.asyncOpen(repositories);
+
log.info(httpPortsMsg(httpPort, httpsPort));
// httpAvailable = true;
// checkReadiness();
--- /dev/null
+package org.argeo.security.jackrabbit;
+
+import java.security.Principal;
+import java.util.Map;
+import java.util.Set;
+
+import javax.jcr.RepositoryException;
+import javax.jcr.Session;
+
+import org.apache.jackrabbit.core.security.authorization.acl.ACLProvider;
+
+/** Argeo specific access control provider */
+public class ArgeoAccessControlProvider extends ACLProvider {
+
+ @SuppressWarnings({ "rawtypes", "unchecked" })
+ @Override
+ public void init(Session systemSession, Map configuration) throws RepositoryException {
+ if (!configuration.containsKey(PARAM_ALLOW_UNKNOWN_PRINCIPALS))
+ configuration.put(PARAM_ALLOW_UNKNOWN_PRINCIPALS, "true");
+ if (!configuration.containsKey(PARAM_OMIT_DEFAULT_PERMISSIONS))
+ configuration.put(PARAM_OMIT_DEFAULT_PERMISSIONS, "true");
+ super.init(systemSession, configuration);
+ }
+
+ @Override
+ public boolean canAccessRoot(Set<Principal> principals) throws RepositoryException {
+ return super.canAccessRoot(principals);
+ }
+
+}
--- /dev/null
+/*
+ * Copyright (C) 2007-2012 Argeo GmbH
+ *
+ * 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.
+ */
+package org.argeo.security.jackrabbit;
+
+import javax.jcr.PathNotFoundException;
+import javax.jcr.RepositoryException;
+import javax.jcr.security.Privilege;
+
+import org.apache.jackrabbit.core.id.ItemId;
+import org.apache.jackrabbit.core.security.DefaultAccessManager;
+import org.apache.jackrabbit.spi.Path;
+
+/**
+ * Intermediary class in order to have a consistent naming in config files. Does
+ * nothing for the time being, but may in the future.
+ */
+public class ArgeoAccessManager extends DefaultAccessManager {
+
+ @Override
+ public boolean canRead(Path itemPath, ItemId itemId)
+ throws RepositoryException {
+ return super.canRead(itemPath, itemId);
+ }
+
+ @Override
+ public Privilege[] getPrivileges(String absPath)
+ throws PathNotFoundException, RepositoryException {
+ return super.getPrivileges(absPath);
+ }
+
+ @Override
+ public boolean hasPrivileges(String absPath, Privilege[] privileges)
+ throws PathNotFoundException, RepositoryException {
+ return super.hasPrivileges(absPath, privileges);
+ }
+
+}
--- /dev/null
+package org.argeo.security.jackrabbit;
+
+import javax.security.auth.Subject;
+import javax.security.auth.callback.CallbackHandler;
+import javax.security.auth.login.LoginContext;
+import javax.security.auth.login.LoginException;
+
+import org.apache.jackrabbit.core.security.authentication.AuthContext;
+
+/** Wraps a regular {@link LoginContext}, using the proper class loader. */
+class ArgeoAuthContext implements AuthContext {
+ private LoginContext lc;
+
+ public ArgeoAuthContext(String appName, Subject subject, CallbackHandler callbackHandler) {
+ try {
+ lc = new LoginContext(appName, subject, callbackHandler);
+ } catch (LoginException e) {
+ throw new IllegalStateException("Cannot configure Jackrabbit login context", e);
+ }
+ }
+
+ @Override
+ public void login() throws LoginException {
+ lc.login();
+ }
+
+ @Override
+ public Subject getSubject() {
+ return lc.getSubject();
+ }
+
+ @Override
+ public void logout() throws LoginException {
+ lc.logout();
+ }
+
+}
--- /dev/null
+/*
+ * Copyright (C) 2007-2012 Argeo GmbH
+ *
+ * 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.
+ */
+package org.argeo.security.jackrabbit;
+
+import java.security.Principal;
+import java.util.HashSet;
+import java.util.Properties;
+import java.util.Set;
+
+import javax.jcr.Credentials;
+import javax.jcr.Repository;
+import javax.jcr.RepositoryException;
+import javax.jcr.Session;
+import javax.security.auth.Subject;
+import javax.security.auth.callback.CallbackHandler;
+import javax.security.auth.x500.X500Principal;
+
+import org.apache.commons.logging.Log;
+import org.apache.commons.logging.LogFactory;
+import org.apache.jackrabbit.api.security.user.UserManager;
+import org.apache.jackrabbit.core.DefaultSecurityManager;
+import org.apache.jackrabbit.core.security.AMContext;
+import org.apache.jackrabbit.core.security.AccessManager;
+import org.apache.jackrabbit.core.security.SecurityConstants;
+import org.apache.jackrabbit.core.security.SystemPrincipal;
+import org.apache.jackrabbit.core.security.authentication.AuthContext;
+import org.apache.jackrabbit.core.security.authentication.CallbackHandlerImpl;
+import org.apache.jackrabbit.core.security.authorization.WorkspaceAccessManager;
+import org.apache.jackrabbit.core.security.principal.AdminPrincipal;
+import org.apache.jackrabbit.core.security.principal.PrincipalProvider;
+import org.argeo.api.NodeConstants;
+import org.argeo.api.security.AnonymousPrincipal;
+import org.argeo.api.security.DataAdminPrincipal;
+import org.argeo.cms.auth.CmsSession;
+import org.osgi.framework.BundleContext;
+import org.osgi.framework.FrameworkUtil;
+
+/** Customises Jackrabbit security. */
+public class ArgeoSecurityManager extends DefaultSecurityManager {
+ private final static Log log = LogFactory.getLog(ArgeoSecurityManager.class);
+
+ private BundleContext cmsBundleContext = null;
+
+ public ArgeoSecurityManager() {
+ if (FrameworkUtil.getBundle(CmsSession.class) != null) {
+ cmsBundleContext = FrameworkUtil.getBundle(CmsSession.class).getBundleContext();
+ }
+ }
+
+ public AuthContext getAuthContext(Credentials creds, Subject subject, String workspaceName)
+ throws RepositoryException {
+ checkInitialized();
+
+ CallbackHandler cbHandler = new CallbackHandlerImpl(creds, getSystemSession(), getPrincipalProviderRegistry(),
+ adminId, anonymousId);
+ String appName = "Jackrabbit";
+ return new ArgeoAuthContext(appName, subject, cbHandler);
+ }
+
+ @Override
+ public AccessManager getAccessManager(Session session, AMContext amContext) throws RepositoryException {
+ synchronized (getSystemSession()) {
+ return super.getAccessManager(session, amContext);
+ }
+ }
+
+ @Override
+ public UserManager getUserManager(Session session) throws RepositoryException {
+ synchronized (getSystemSession()) {
+ return super.getUserManager(session);
+ }
+ }
+
+ @Override
+ protected PrincipalProvider createDefaultPrincipalProvider(Properties[] moduleConfig) throws RepositoryException {
+ return super.createDefaultPrincipalProvider(moduleConfig);
+ }
+
+ /** Called once when the session is created */
+ @Override
+ public String getUserID(Subject subject, String workspaceName) throws RepositoryException {
+ boolean isAnonymous = !subject.getPrincipals(AnonymousPrincipal.class).isEmpty();
+ boolean isDataAdmin = !subject.getPrincipals(DataAdminPrincipal.class).isEmpty();
+ boolean isJackrabbitSystem = !subject.getPrincipals(SystemPrincipal.class).isEmpty();
+ Set<X500Principal> userPrincipal = subject.getPrincipals(X500Principal.class);
+ boolean isRegularUser = !userPrincipal.isEmpty();
+ CmsSession cmsSession = null;
+ if (cmsBundleContext != null) {
+ cmsSession = CmsSession.getCmsSession(cmsBundleContext, subject);
+ if (log.isTraceEnabled())
+ log.trace("Opening JCR session for CMS session " + cmsSession);
+ }
+
+ if (isAnonymous) {
+ if (isDataAdmin || isJackrabbitSystem || isRegularUser)
+ throw new IllegalStateException("Inconsistent " + subject);
+ else
+ return NodeConstants.ROLE_ANONYMOUS;
+ } else if (isRegularUser) {// must be before DataAdmin
+ if (isAnonymous || isJackrabbitSystem)
+ throw new IllegalStateException("Inconsistent " + subject);
+ else {
+ if (userPrincipal.size() > 1) {
+ StringBuilder buf = new StringBuilder();
+ for (X500Principal principal : userPrincipal)
+ buf.append(' ').append('\"').append(principal).append('\"');
+ throw new RuntimeException("Multiple user principals:" + buf);
+ }
+ return userPrincipal.iterator().next().getName();
+ }
+ } else if (isDataAdmin) {
+ if (isAnonymous || isJackrabbitSystem || isRegularUser)
+ throw new IllegalStateException("Inconsistent " + subject);
+ else {
+ assert !subject.getPrincipals(AdminPrincipal.class).isEmpty();
+ return NodeConstants.ROLE_DATA_ADMIN;
+ }
+ } else if (isJackrabbitSystem) {
+ if (isAnonymous || isDataAdmin || isRegularUser)
+ throw new IllegalStateException("Inconsistent " + subject);
+ else
+ return super.getUserID(subject, workspaceName);
+ } else {
+ throw new IllegalStateException("Unrecognized subject type: " + subject);
+ }
+ }
+
+ @Override
+ protected WorkspaceAccessManager createDefaultWorkspaceAccessManager() {
+ WorkspaceAccessManager wam = super.createDefaultWorkspaceAccessManager();
+ ArgeoWorkspaceAccessManagerImpl workspaceAccessManager = new ArgeoWorkspaceAccessManagerImpl(wam);
+ if (log.isTraceEnabled())
+ log.trace("Created workspace access manager");
+ return workspaceAccessManager;
+ }
+
+ private class ArgeoWorkspaceAccessManagerImpl implements SecurityConstants, WorkspaceAccessManager {
+ private final WorkspaceAccessManager wam;
+
+ public ArgeoWorkspaceAccessManagerImpl(WorkspaceAccessManager wam) {
+ super();
+ this.wam = wam;
+ }
+
+ public void init(Session systemSession) throws RepositoryException {
+ wam.init(systemSession);
+ Repository repository = systemSession.getRepository();
+ if (log.isTraceEnabled())
+ log.trace("Initialised workspace access manager on repository " + repository
+ + ", systemSession workspace: " + systemSession.getWorkspace().getName());
+ }
+
+ public void close() throws RepositoryException {
+ }
+
+ public boolean grants(Set<Principal> principals, String workspaceName) throws RepositoryException {
+ // TODO: implements finer access to workspaces
+ if (log.isTraceEnabled())
+ log.trace("Grants " + new HashSet<>(principals) + " access to workspace '" + workspaceName + "'");
+ return true;
+ // return wam.grants(principals, workspaceName);
+ }
+ }
+
+}
--- /dev/null
+package org.argeo.security.jackrabbit;
+
+import java.util.Map;
+import java.util.Set;
+
+import javax.security.auth.Subject;
+import javax.security.auth.callback.CallbackHandler;
+import javax.security.auth.login.LoginException;
+import javax.security.auth.spi.LoginModule;
+import javax.security.auth.x500.X500Principal;
+
+import org.apache.jackrabbit.core.security.AnonymousPrincipal;
+import org.apache.jackrabbit.core.security.SecurityConstants;
+import org.apache.jackrabbit.core.security.principal.AdminPrincipal;
+import org.argeo.api.security.DataAdminPrincipal;
+
+/** JAAS login module used when initiating a new Jackrabbit session. */
+public class SystemJackrabbitLoginModule implements LoginModule {
+ private Subject subject;
+
+ @Override
+ public void initialize(Subject subject, CallbackHandler callbackHandler, Map<String, ?> sharedState,
+ Map<String, ?> options) {
+ this.subject = subject;
+ }
+
+ @Override
+ public boolean login() throws LoginException {
+ return true;
+ }
+
+ @Override
+ public boolean commit() throws LoginException {
+ Set<org.argeo.api.security.AnonymousPrincipal> anonPrincipal = subject
+ .getPrincipals(org.argeo.api.security.AnonymousPrincipal.class);
+ if (!anonPrincipal.isEmpty()) {
+ subject.getPrincipals().add(new AnonymousPrincipal());
+ return true;
+ }
+
+ Set<DataAdminPrincipal> initPrincipal = subject.getPrincipals(DataAdminPrincipal.class);
+ if (!initPrincipal.isEmpty()) {
+ subject.getPrincipals().add(new AdminPrincipal(SecurityConstants.ADMIN_ID));
+ return true;
+ }
+
+ Set<X500Principal> userPrincipal = subject.getPrincipals(X500Principal.class);
+ if (userPrincipal.isEmpty())
+ throw new LoginException("Subject must be pre-authenticated");
+ if (userPrincipal.size() > 1)
+ throw new LoginException("Multiple user principals " + userPrincipal);
+
+ return true;
+ }
+
+ @Override
+ public boolean abort() throws LoginException {
+ return true;
+ }
+
+ @Override
+ public boolean logout() throws LoginException {
+ subject.getPrincipals().removeAll(subject.getPrincipals(AnonymousPrincipal.class));
+ subject.getPrincipals().removeAll(subject.getPrincipals(AdminPrincipal.class));
+ return true;
+ }
+}
--- /dev/null
+/** Integration of Jackrabbit with Argeo security model. */
+package org.argeo.security.jackrabbit;
\ No newline at end of file
org.eclipse.jetty.websocket.api,\
org.eclipse.jetty.websocket.common,\
org.osgi.service.http,\
-org.argeo.cms.auth,\
-org.argeo.api,\
*
\ No newline at end of file
+++ /dev/null
-package org.argeo.security.jackrabbit;
-
-import java.security.Principal;
-import java.util.Map;
-import java.util.Set;
-
-import javax.jcr.RepositoryException;
-import javax.jcr.Session;
-
-import org.apache.jackrabbit.core.security.authorization.acl.ACLProvider;
-
-/** Argeo specific access control provider */
-public class ArgeoAccessControlProvider extends ACLProvider {
-
- @SuppressWarnings({ "rawtypes", "unchecked" })
- @Override
- public void init(Session systemSession, Map configuration) throws RepositoryException {
- if (!configuration.containsKey(PARAM_ALLOW_UNKNOWN_PRINCIPALS))
- configuration.put(PARAM_ALLOW_UNKNOWN_PRINCIPALS, "true");
- if (!configuration.containsKey(PARAM_OMIT_DEFAULT_PERMISSIONS))
- configuration.put(PARAM_OMIT_DEFAULT_PERMISSIONS, "true");
- super.init(systemSession, configuration);
- }
-
- @Override
- public boolean canAccessRoot(Set<Principal> principals) throws RepositoryException {
- return super.canAccessRoot(principals);
- }
-
-}
+++ /dev/null
-/*
- * Copyright (C) 2007-2012 Argeo GmbH
- *
- * 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.
- */
-package org.argeo.security.jackrabbit;
-
-import javax.jcr.PathNotFoundException;
-import javax.jcr.RepositoryException;
-import javax.jcr.security.Privilege;
-
-import org.apache.jackrabbit.core.id.ItemId;
-import org.apache.jackrabbit.core.security.DefaultAccessManager;
-import org.apache.jackrabbit.spi.Path;
-
-/**
- * Intermediary class in order to have a consistent naming in config files. Does
- * nothing for the time being, but may in the future.
- */
-public class ArgeoAccessManager extends DefaultAccessManager {
-
- @Override
- public boolean canRead(Path itemPath, ItemId itemId)
- throws RepositoryException {
- return super.canRead(itemPath, itemId);
- }
-
- @Override
- public Privilege[] getPrivileges(String absPath)
- throws PathNotFoundException, RepositoryException {
- return super.getPrivileges(absPath);
- }
-
- @Override
- public boolean hasPrivileges(String absPath, Privilege[] privileges)
- throws PathNotFoundException, RepositoryException {
- return super.hasPrivileges(absPath, privileges);
- }
-
-}
+++ /dev/null
-/*
- * Copyright (C) 2007-2012 Argeo GmbH
- *
- * 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.
- */
-package org.argeo.security.jackrabbit;
-
-import java.security.Principal;
-import java.util.HashSet;
-import java.util.Properties;
-import java.util.Set;
-
-import javax.jcr.Repository;
-import javax.jcr.RepositoryException;
-import javax.jcr.Session;
-import javax.security.auth.Subject;
-import javax.security.auth.x500.X500Principal;
-
-import org.apache.commons.logging.Log;
-import org.apache.commons.logging.LogFactory;
-import org.apache.jackrabbit.api.security.user.UserManager;
-import org.apache.jackrabbit.core.DefaultSecurityManager;
-import org.apache.jackrabbit.core.security.AMContext;
-import org.apache.jackrabbit.core.security.AccessManager;
-import org.apache.jackrabbit.core.security.SecurityConstants;
-import org.apache.jackrabbit.core.security.SystemPrincipal;
-import org.apache.jackrabbit.core.security.authorization.WorkspaceAccessManager;
-import org.apache.jackrabbit.core.security.principal.AdminPrincipal;
-import org.apache.jackrabbit.core.security.principal.PrincipalProvider;
-import org.argeo.api.NodeConstants;
-import org.argeo.api.security.AnonymousPrincipal;
-import org.argeo.api.security.DataAdminPrincipal;
-import org.argeo.cms.auth.CmsSession;
-import org.osgi.framework.BundleContext;
-import org.osgi.framework.FrameworkUtil;
-
-/** Customises Jackrabbit security. */
-public class ArgeoSecurityManager extends DefaultSecurityManager {
- private final static Log log = LogFactory.getLog(ArgeoSecurityManager.class);
-
- private BundleContext cmsBundleContext = null;
-
- public ArgeoSecurityManager() {
- if (FrameworkUtil.getBundle(CmsSession.class) != null) {
- cmsBundleContext = FrameworkUtil.getBundle(CmsSession.class).getBundleContext();
- }
- }
-
- @Override
- public AccessManager getAccessManager(Session session, AMContext amContext) throws RepositoryException {
- synchronized (getSystemSession()) {
- return super.getAccessManager(session, amContext);
- }
- }
-
- @Override
- public UserManager getUserManager(Session session) throws RepositoryException {
- synchronized (getSystemSession()) {
- return super.getUserManager(session);
- }
- }
-
- @Override
- protected PrincipalProvider createDefaultPrincipalProvider(Properties[] moduleConfig) throws RepositoryException {
- return super.createDefaultPrincipalProvider(moduleConfig);
- }
-
- /** Called once when the session is created */
- @Override
- public String getUserID(Subject subject, String workspaceName) throws RepositoryException {
- boolean isAnonymous = !subject.getPrincipals(AnonymousPrincipal.class).isEmpty();
- boolean isDataAdmin = !subject.getPrincipals(DataAdminPrincipal.class).isEmpty();
- boolean isJackrabbitSystem = !subject.getPrincipals(SystemPrincipal.class).isEmpty();
- Set<X500Principal> userPrincipal = subject.getPrincipals(X500Principal.class);
- boolean isRegularUser = !userPrincipal.isEmpty();
- CmsSession cmsSession = null;
- if (cmsBundleContext != null) {
- cmsSession = CmsSession.getCmsSession(cmsBundleContext, subject);
- if (log.isTraceEnabled())
- log.trace("Opening JCR session for CMS session " + cmsSession);
- }
-
- if (isAnonymous) {
- if (isDataAdmin || isJackrabbitSystem || isRegularUser)
- throw new IllegalStateException("Inconsistent " + subject);
- else
- return NodeConstants.ROLE_ANONYMOUS;
- } else if (isRegularUser) {// must be before DataAdmin
- if (isAnonymous || isJackrabbitSystem)
- throw new IllegalStateException("Inconsistent " + subject);
- else {
- if (userPrincipal.size() > 1) {
- StringBuilder buf = new StringBuilder();
- for (X500Principal principal : userPrincipal)
- buf.append(' ').append('\"').append(principal).append('\"');
- throw new RuntimeException("Multiple user principals:" + buf);
- }
- return userPrincipal.iterator().next().getName();
- }
- } else if (isDataAdmin) {
- if (isAnonymous || isJackrabbitSystem || isRegularUser)
- throw new IllegalStateException("Inconsistent " + subject);
- else {
- assert !subject.getPrincipals(AdminPrincipal.class).isEmpty();
- return NodeConstants.ROLE_DATA_ADMIN;
- }
- } else if (isJackrabbitSystem) {
- if (isAnonymous || isDataAdmin || isRegularUser)
- throw new IllegalStateException("Inconsistent " + subject);
- else
- return super.getUserID(subject, workspaceName);
- } else {
- throw new IllegalStateException("Unrecognized subject type: " + subject);
- }
- }
-
- @Override
- protected WorkspaceAccessManager createDefaultWorkspaceAccessManager() {
- WorkspaceAccessManager wam = super.createDefaultWorkspaceAccessManager();
- ArgeoWorkspaceAccessManagerImpl workspaceAccessManager = new ArgeoWorkspaceAccessManagerImpl(wam);
- if (log.isTraceEnabled())
- log.trace("Created workspace access manager");
- return workspaceAccessManager;
- }
-
- private class ArgeoWorkspaceAccessManagerImpl implements SecurityConstants, WorkspaceAccessManager {
- private final WorkspaceAccessManager wam;
-
- public ArgeoWorkspaceAccessManagerImpl(WorkspaceAccessManager wam) {
- super();
- this.wam = wam;
- }
-
- public void init(Session systemSession) throws RepositoryException {
- wam.init(systemSession);
- Repository repository = systemSession.getRepository();
- if (log.isTraceEnabled())
- log.trace("Initialised workspace access manager on repository " + repository
- + ", systemSession workspace: " + systemSession.getWorkspace().getName());
- }
-
- public void close() throws RepositoryException {
- }
-
- public boolean grants(Set<Principal> principals, String workspaceName) throws RepositoryException {
- // TODO: implements finer access to workspaces
- if (log.isTraceEnabled())
- log.trace("Grants " + new HashSet<>(principals) + " access to workspace '" + workspaceName + "'");
- return true;
- // return wam.grants(principals, workspaceName);
- }
- }
-
-}
+++ /dev/null
-package org.argeo.security.jackrabbit;
-
-import java.util.Map;
-import java.util.Set;
-
-import javax.security.auth.Subject;
-import javax.security.auth.callback.CallbackHandler;
-import javax.security.auth.login.LoginException;
-import javax.security.auth.spi.LoginModule;
-import javax.security.auth.x500.X500Principal;
-
-import org.apache.jackrabbit.core.security.AnonymousPrincipal;
-import org.apache.jackrabbit.core.security.SecurityConstants;
-import org.apache.jackrabbit.core.security.principal.AdminPrincipal;
-import org.argeo.api.security.DataAdminPrincipal;
-
-public class SystemJackrabbitLoginModule implements LoginModule {
- private Subject subject;
-
- @Override
- public void initialize(Subject subject, CallbackHandler callbackHandler, Map<String, ?> sharedState,
- Map<String, ?> options) {
- this.subject = subject;
- }
-
- @Override
- public boolean login() throws LoginException {
- return true;
- }
-
- @Override
- public boolean commit() throws LoginException {
- Set<org.argeo.api.security.AnonymousPrincipal> anonPrincipal = subject.getPrincipals(org.argeo.api.security.AnonymousPrincipal.class);
- if (!anonPrincipal.isEmpty()) {
- subject.getPrincipals().add(new AnonymousPrincipal());
- return true;
- }
-
- Set<DataAdminPrincipal> initPrincipal = subject.getPrincipals(DataAdminPrincipal.class);
- if (!initPrincipal.isEmpty()) {
- subject.getPrincipals().add(new AdminPrincipal(SecurityConstants.ADMIN_ID));
- return true;
- }
-
- Set<X500Principal> userPrincipal = subject.getPrincipals(X500Principal.class);
- if (userPrincipal.isEmpty())
- throw new LoginException("Subject must be pre-authenticated");
- if (userPrincipal.size() > 1)
- throw new LoginException("Multiple user principals " + userPrincipal);
-
- return true;
- }
-
- @Override
- public boolean abort() throws LoginException {
- return true;
- }
-
- @Override
- public boolean logout() throws LoginException {
- subject.getPrincipals().removeAll(subject.getPrincipals(AnonymousPrincipal.class));
- subject.getPrincipals().removeAll(subject.getPrincipals(AdminPrincipal.class));
- return true;
- }
-}
+++ /dev/null
-/** Integration of Jackrabbit with Argeo security model. */
-package org.argeo.security.jackrabbit;
\ No newline at end of file
<module>org.argeo.cms.e4</module>
<module>org.argeo.cms.e4.rap</module>
<!-- Third Parties Extensions -->
- <module>org.argeo.ext.jackrabbit</module>
+<!-- <module>org.argeo.ext.jackrabbit</module> -->
<module>org.argeo.ext.equinox.jetty</module>
<!-- Distribution -->
<module>dep</module>