From: Mathieu Baudier Date: Wed, 5 Jan 2022 11:36:42 +0000 (+0100) Subject: Massive Argeo APIs refactoring X-Git-Tag: argeo-commons-2.3.5~96 X-Git-Url: https://git.argeo.org/?p=lgpl%2Fargeo-commons.git;a=commitdiff_plain;h=b71546ddc74d6ca49d252806aafd491c75dfe1fb Massive Argeo APIs refactoring --- diff --git a/org.argeo.api/bnd.bnd b/org.argeo.api/bnd.bnd index 0dfe09663..a8a1e4f6a 100644 --- a/org.argeo.api/bnd.bnd +++ b/org.argeo.api/bnd.bnd @@ -1,5 +1,4 @@ Import-Package: javax.naming.*,\ javax.security.* -Export-Package: org.argeo.api.*,\ -org.apache.commons.logging;version=1.2.666 \ No newline at end of file +Export-Package: org.argeo.api.* \ No newline at end of file diff --git a/org.argeo.api/src/org/apache/commons/logging/Log.java b/org.argeo.api/src/org/apache/commons/logging/Log.java deleted file mode 100644 index 4c4f8b407..000000000 --- a/org.argeo.api/src/org/apache/commons/logging/Log.java +++ /dev/null @@ -1,151 +0,0 @@ -package org.apache.commons.logging; - -import java.lang.System.Logger; -import java.lang.System.Logger.Level; -import java.util.Objects; - -/** A pseudo implementation of Apache Commons Logging. */ -public interface Log { - Logger getLogger(); - - default boolean isDebugEnabled() { - return getLogger().isLoggable(Level.DEBUG); - } - - default boolean isErrorEnabled() { - return getLogger().isLoggable(Level.ERROR); - } - - default boolean isInfoEnabled() { - return getLogger().isLoggable(Level.INFO); - } - - default boolean isTraceEnabled() { - return getLogger().isLoggable(Level.TRACE); - } - - default boolean isWarnEnabled() { - return getLogger().isLoggable(Level.WARNING); - } - - /* - * TRACE - */ - - default void trace(String message) { - getLogger().log(Level.TRACE, message); - } - - default void trace(Object message) { - getLogger().log(Level.TRACE, Objects.requireNonNull(message)); - } - - default void trace(String message, Throwable t) { - getLogger().log(Level.TRACE, message, t); - } - - default void trace(Object message, Throwable t) { - trace(Objects.requireNonNull(message).toString(), t); - } - - default void trace(String format, Object... arguments) { - getLogger().log(Level.TRACE, format, arguments); - } - - /* - * DEBUG - */ - - default void debug(String message) { - getLogger().log(Level.DEBUG, message); - } - - default void debug(Object message) { - getLogger().log(Level.DEBUG, message); - } - - default void debug(String message, Throwable t) { - getLogger().log(Level.DEBUG, message, t); - } - - default void debug(Object message, Throwable t) { - debug(Objects.requireNonNull(message).toString(), t); - } - - default void debug(String format, Object... arguments) { - getLogger().log(Level.DEBUG, format, arguments); - } - - /* - * INFO - */ - - default void info(String message) { - getLogger().log(Level.INFO, message); - } - - default void info(Object message) { - getLogger().log(Level.INFO, message); - } - - default void info(String message, Throwable t) { - getLogger().log(Level.INFO, message, t); - } - - default void info(Object message, Throwable t) { - info(Objects.requireNonNull(message).toString(), t); - } - - default void info(String format, Object... arguments) { - getLogger().log(Level.INFO, format, arguments); - } - - /* - * WARN - */ - - default void warn(String message) { - getLogger().log(Level.WARNING, message); - } - - default void warn(Object message) { - getLogger().log(Level.WARNING, message); - } - - default void warn(String message, Throwable t) { - getLogger().log(Level.WARNING, message, t); - } - - default void warn(Object message, Throwable t) { - warn(Objects.requireNonNull(message).toString(), t); - } - - default void warn(String format, Object... arguments) { - getLogger().log(Level.WARNING, format, arguments); - } - - /* - * ERROR - */ - - default void error(String message) { - getLogger().log(Level.ERROR, message); - } - - default void error(Object message) { - getLogger().log(Level.ERROR, message); - } - - default void error(String message, Throwable t) { - getLogger().log(Level.ERROR, message, t); - } - - default void error(Object message, Throwable t) { - error(Objects.requireNonNull(message).toString(), t); - } - - default void error(String format, Object... arguments) { - getLogger().log(Level.ERROR, format, arguments); - } - -} diff --git a/org.argeo.api/src/org/apache/commons/logging/LogFactory.java b/org.argeo.api/src/org/apache/commons/logging/LogFactory.java deleted file mode 100644 index e95b7923e..000000000 --- a/org.argeo.api/src/org/apache/commons/logging/LogFactory.java +++ /dev/null @@ -1,31 +0,0 @@ -package org.apache.commons.logging; - -import java.lang.System.Logger; -import java.util.Objects; - -/** A pseudo implementation of Apache Commons Logging. */ -public abstract class LogFactory { - public static Log getLog(Class clss) { - return getLog(Objects.requireNonNull(clss).getName()); - } - - public static Log getLog(String name) { - Logger logger = System.getLogger(Objects.requireNonNull(name)); - return new LoggerWrapper(logger); - } - - static class LoggerWrapper implements Log { - private final Logger logger; - - LoggerWrapper(Logger logger) { - super(); - this.logger = logger; - } - - @Override - public Logger getLogger() { - return logger; - } - - } -} diff --git a/org.argeo.api/src/org/argeo/api/ArgeoLogListener.java b/org.argeo.api/src/org/argeo/api/ArgeoLogListener.java deleted file mode 100644 index 51861fded..000000000 --- a/org.argeo.api/src/org/argeo/api/ArgeoLogListener.java +++ /dev/null @@ -1,24 +0,0 @@ -package org.argeo.api; - -/** Framework agnostic interface for log notifications */ -public interface ArgeoLogListener { - /** - * Appends a log - * - * @param username - * authentified user, null for anonymous - * @param level - * INFO, DEBUG, WARN, etc. (logging framework specific) - * @param category - * hierarchy (logging framework specific) - * @param thread - * name of the thread which logged this message - * @param msg - * any object as long as its toString() method returns the - * message - * @param exception - * exception in log4j ThrowableStrRep format - */ - public void appendLog(String username, Long timestamp, String level, - String category, String thread, Object msg, String[] exception); -} diff --git a/org.argeo.api/src/org/argeo/api/ArgeoLogger.java b/org.argeo.api/src/org/argeo/api/ArgeoLogger.java deleted file mode 100644 index dbcd7d72e..000000000 --- a/org.argeo.api/src/org/argeo/api/ArgeoLogger.java +++ /dev/null @@ -1,31 +0,0 @@ -package org.argeo.api; - -/** - * Logging framework agnostic identifying a logging service, to which one can - * register - */ -public interface ArgeoLogger { - /** - * Register for events by threads with the same authentication (or all - * threads if admin) - */ - public void register(ArgeoLogListener listener, - Integer numberOfPreviousEvents); - - /** - * For admin use only: register for all users - * - * @param listener - * the log listener - * @param numberOfPreviousEvents - * the number of previous events to notify - * @param everything - * if true even anonymous is logged - */ - public void registerForAll(ArgeoLogListener listener, - Integer numberOfPreviousEvents, boolean everything); - - public void unregister(ArgeoLogListener listener); - - public void unregisterForAll(ArgeoLogListener listener); -} diff --git a/org.argeo.api/src/org/argeo/api/DataAdminLoginModule.java b/org.argeo.api/src/org/argeo/api/DataAdminLoginModule.java deleted file mode 100644 index 295196ad4..000000000 --- a/org.argeo.api/src/org/argeo/api/DataAdminLoginModule.java +++ /dev/null @@ -1,48 +0,0 @@ -package org.argeo.api; - -import java.util.Map; - -import javax.security.auth.AuthPermission; -import javax.security.auth.Subject; -import javax.security.auth.callback.CallbackHandler; -import javax.security.auth.login.LoginException; -import javax.security.auth.spi.LoginModule; - -import org.argeo.api.security.DataAdminPrincipal; - -/** - * Log-in a system process as data admin. Protection is via - * {@link AuthPermission} on this login module, so if it can be accessed it will - * always succeed. - */ -public class DataAdminLoginModule implements LoginModule { - private Subject subject; - - @Override - public void initialize(Subject subject, CallbackHandler callbackHandler, Map sharedState, - Map options) { - this.subject = subject; - } - - @Override - public boolean login() throws LoginException { - return true; - } - - @Override - public boolean commit() throws LoginException { - subject.getPrincipals().add(new DataAdminPrincipal()); - return true; - } - - @Override - public boolean abort() throws LoginException { - return true; - } - - @Override - public boolean logout() throws LoginException { - subject.getPrincipals().removeAll(subject.getPrincipals(DataAdminPrincipal.class)); - return true; - } -} diff --git a/org.argeo.api/src/org/argeo/api/NodeConstants.java b/org.argeo.api/src/org/argeo/api/NodeConstants.java deleted file mode 100644 index e53730ea7..000000000 --- a/org.argeo.api/src/org/argeo/api/NodeConstants.java +++ /dev/null @@ -1,136 +0,0 @@ -package org.argeo.api; - -public interface NodeConstants { - /* - * DN ATTRIBUTES (RFC 4514) - */ - String CN = "cn"; - String L = "l"; - String ST = "st"; - String O = "o"; - String OU = "ou"; - String C = "c"; - String STREET = "street"; - String DC = "dc"; - String UID = "uid"; - - /* - * STANDARD ATTRIBUTES - */ - String LABELED_URI = "labeledUri"; - - /* - * COMMON NAMES - */ - String NODE = "node"; - - /* - * JCR CONVENTIONS - */ - String NODE_REPOSITORY = NODE; - String EGO_REPOSITORY = "ego"; - String SYS_WORKSPACE = "sys"; - String HOME_WORKSPACE = "home"; - String SRV_WORKSPACE = "srv"; - String GUESTS_WORKSPACE = "guests"; - String PUBLIC_WORKSPACE = "public"; - String SECURITY_WORKSPACE = "security"; - - /* - * BASE DNs - */ - String DEPLOY_BASEDN = "ou=deploy,ou=node"; - - /* - * STANDARD VALUES - */ - String DEFAULT = "default"; - - /* - * RESERVED ROLES - */ - String ROLES_BASEDN = "ou=roles,ou=node"; - String TOKENS_BASEDN = "ou=tokens,ou=node"; - String ROLE_ADMIN = "cn=admin," + ROLES_BASEDN; - String ROLE_USER_ADMIN = "cn=userAdmin," + ROLES_BASEDN; - String ROLE_DATA_ADMIN = "cn=dataAdmin," + ROLES_BASEDN; - // Special system groups that cannot be edited: - // user U anonymous = everyone - String ROLE_USER = "cn=user," + ROLES_BASEDN; - String ROLE_ANONYMOUS = "cn=anonymous," + ROLES_BASEDN; - // Account lifecycle - String ROLE_REGISTERING = "cn=registering," + ROLES_BASEDN; - - /* - * LOGIN CONTEXTS - */ - String LOGIN_CONTEXT_NODE = "NODE"; - String LOGIN_CONTEXT_USER = "USER"; - String LOGIN_CONTEXT_ANONYMOUS = "ANONYMOUS"; - String LOGIN_CONTEXT_DATA_ADMIN = "DATA_ADMIN"; - String LOGIN_CONTEXT_SINGLE_USER = "SINGLE_USER"; - String LOGIN_CONTEXT_KEYRING = "KEYRING"; - - /* - * PATHS - */ - String PATH_DATA = "/data"; - String PATH_JCR = "/jcr"; - String PATH_FILES = "/files"; - // String PATH_JCR_PUB = "/pub"; - - /* - * FILE SYSTEMS - */ - String SCHEME_NODE = NODE; - - /* - * KERBEROS - */ - String NODE_SERVICE = NODE; - - /* - * INIT FRAMEWORK PROPERTIES - */ - String NODE_INIT = "argeo.node.init"; - String I18N_DEFAULT_LOCALE = "argeo.i18n.defaultLocale"; - String I18N_LOCALES = "argeo.i18n.locales"; - // Node Security - String ROLES_URI = "argeo.node.roles.uri"; - String TOKENS_URI = "argeo.node.tokens.uri"; - /** URI to an LDIF file or LDAP server used as initialization or backend */ - String USERADMIN_URIS = "argeo.node.useradmin.uris"; - // Transaction manager - String TRANSACTION_MANAGER = "argeo.node.transaction.manager"; - String TRANSACTION_MANAGER_SIMPLE = "simple"; - String TRANSACTION_MANAGER_BITRONIX = "bitronix"; - // Node - /** Properties configuring the node repository */ - String NODE_REPO_PROP_PREFIX = "argeo.node.repo."; - /** Additional standalone repositories, related to data models. */ - String NODE_REPOS_PROP_PREFIX = "argeo.node.repos."; - // HTTP - String HTTP_PORT = "org.osgi.service.http.port"; - String HTTP_PORT_SECURE = "org.osgi.service.http.port.secure"; - /** - * The HTTP header used to convey the DN of a client verified by a reverse - * proxy. Typically SSL_CLIENT_S_DN for Apache. - */ - String HTTP_PROXY_SSL_DN = "argeo.http.proxy.ssl.dn"; - - /* - * PIDs - */ - String NODE_STATE_PID = "org.argeo.api.state"; - String NODE_DEPLOYMENT_PID = "org.argeo.api.deployment"; - String NODE_INSTANCE_PID = "org.argeo.api.instance"; - - String NODE_KEYRING_PID = "org.argeo.api.keyring"; - String NODE_FS_PROVIDER_PID = "org.argeo.api.fsProvider"; - - /* - * FACTORY PIDs - */ - String NODE_REPOS_FACTORY_PID = "org.argeo.api.repos"; - String NODE_USER_ADMIN_PID = "org.argeo.api.userAdmin"; -} diff --git a/org.argeo.api/src/org/argeo/api/NodeDeployment.java b/org.argeo.api/src/org/argeo/api/NodeDeployment.java deleted file mode 100644 index 35436a8c3..000000000 --- a/org.argeo.api/src/org/argeo/api/NodeDeployment.java +++ /dev/null @@ -1,12 +0,0 @@ -package org.argeo.api; - -import java.util.Dictionary; - -/** A configured node deployment. */ -public interface NodeDeployment { - Long getAvailableSince(); - - void addFactoryDeployConfig(String factoryPid, Dictionary props); - Dictionary getProps(String factoryPid, String cn); - -} diff --git a/org.argeo.api/src/org/argeo/api/NodeInstance.java b/org.argeo.api/src/org/argeo/api/NodeInstance.java deleted file mode 100644 index 167ba81d5..000000000 --- a/org.argeo.api/src/org/argeo/api/NodeInstance.java +++ /dev/null @@ -1,15 +0,0 @@ -package org.argeo.api; - -import javax.naming.ldap.LdapName; - -/** The structured data */ -public interface NodeInstance { - /** - * To be used as an identifier of a workgroup, typically as a value for the - * 'businessCategory' attribute in LDAP. - */ - public final static String WORKGROUP = "workgroup"; - - /** Mark this group as a workgroup */ - void createWorkgroup(LdapName groupDn); -} diff --git a/org.argeo.api/src/org/argeo/api/NodeOID.java b/org.argeo.api/src/org/argeo/api/NodeOID.java deleted file mode 100644 index ade116342..000000000 --- a/org.argeo.api/src/org/argeo/api/NodeOID.java +++ /dev/null @@ -1,11 +0,0 @@ -package org.argeo.api; - -interface NodeOID { - String BASE = "1.3.6.1.4.1" + ".48308" + ".1"; - - // ATTRIBUTE TYPES - String ATTRIBUTE_TYPES = BASE + ".4"; - - // OBJECT CLASSES - String OBJECT_CLASSES = BASE + ".6"; -} diff --git a/org.argeo.api/src/org/argeo/api/NodeState.java b/org.argeo.api/src/org/argeo/api/NodeState.java deleted file mode 100644 index a824ac278..000000000 --- a/org.argeo.api/src/org/argeo/api/NodeState.java +++ /dev/null @@ -1,16 +0,0 @@ -package org.argeo.api; - -import java.util.List; -import java.util.Locale; - -/** A running node process. */ -public interface NodeState { - Locale getDefaultLocale(); - - List getLocales(); - - String getHostname(); - - Long getAvailableSince(); - -} diff --git a/org.argeo.api/src/org/argeo/api/cms/AnonymousPrincipal.java b/org.argeo.api/src/org/argeo/api/cms/AnonymousPrincipal.java new file mode 100644 index 000000000..63ee34853 --- /dev/null +++ b/org.argeo.api/src/org/argeo/api/cms/AnonymousPrincipal.java @@ -0,0 +1,28 @@ +package org.argeo.api.cms; + +import java.security.Principal; + +/** Marker for anonymous users. */ +public final class AnonymousPrincipal implements Principal { + private final String name = CmsConstants.ROLE_ANONYMOUS; + + @Override + public String getName() { + return name; + } + + @Override + public int hashCode() { + return name.hashCode(); + } + + @Override + public boolean equals(Object obj) { + return this == obj; + } + + @Override + public String toString() { + return name.toString(); + } +} diff --git a/org.argeo.api/src/org/argeo/api/cms/CmsAuth.java b/org.argeo.api/src/org/argeo/api/cms/CmsAuth.java new file mode 100644 index 000000000..decea3550 --- /dev/null +++ b/org.argeo.api/src/org/argeo/api/cms/CmsAuth.java @@ -0,0 +1,46 @@ +package org.argeo.api.cms; + +import javax.security.auth.callback.CallbackHandler; +import javax.security.auth.login.LoginContext; +import javax.security.auth.login.LoginException; + +/** The type of login context to use. */ +public enum CmsAuth { + NODE, USER, ANONYMOUS, DATA_ADMIN, SINGLE_USER, KEYRING; + + public String getLoginContextName() { + return name(); + } + + @Override + public String toString() { + return getLoginContextName(); + } + + public LoginContext newLoginContext(CallbackHandler callbackHandler) throws LoginException { + return new LoginContext(getLoginContextName(), callbackHandler); + } + + /* + * LOGIN CONTEXTS + */ + /** @deprecated Use enum instead. */ + @Deprecated + public static final String LOGIN_CONTEXT_NODE = NODE.getLoginContextName(); + /** @deprecated Use enum instead. */ + @Deprecated + public static final String LOGIN_CONTEXT_USER = USER.getLoginContextName(); + /** @deprecated Use enum instead. */ + @Deprecated + public static final String LOGIN_CONTEXT_ANONYMOUS = ANONYMOUS.getLoginContextName(); + /** @deprecated Use enum instead. */ + @Deprecated + public static final String LOGIN_CONTEXT_DATA_ADMIN = DATA_ADMIN.getLoginContextName(); + /** @deprecated Use enum instead. */ + @Deprecated + public static final String LOGIN_CONTEXT_SINGLE_USER = SINGLE_USER.getLoginContextName(); + /** @deprecated Use enum instead. */ + @Deprecated + public static final String LOGIN_CONTEXT_KEYRING = KEYRING.getLoginContextName(); + +} diff --git a/org.argeo.api/src/org/argeo/api/cms/CmsConstants.java b/org.argeo.api/src/org/argeo/api/cms/CmsConstants.java new file mode 100644 index 000000000..8fe9846f4 --- /dev/null +++ b/org.argeo.api/src/org/argeo/api/cms/CmsConstants.java @@ -0,0 +1,126 @@ +package org.argeo.api.cms; + +public interface CmsConstants { + /* + * DN ATTRIBUTES (RFC 4514) + */ + String CN = "cn"; + String L = "l"; + String ST = "st"; + String O = "o"; + String OU = "ou"; + String C = "c"; + String STREET = "street"; + String DC = "dc"; + String UID = "uid"; + + /* + * STANDARD ATTRIBUTES + */ + String LABELED_URI = "labeledUri"; + + /* + * COMMON NAMES + */ + String NODE = "node"; + + /* + * JCR CONVENTIONS + */ + String NODE_REPOSITORY = NODE; + String EGO_REPOSITORY = "ego"; + String SYS_WORKSPACE = "sys"; + String HOME_WORKSPACE = "home"; + String SRV_WORKSPACE = "srv"; + String GUESTS_WORKSPACE = "guests"; + String PUBLIC_WORKSPACE = "public"; + String SECURITY_WORKSPACE = "security"; + + /* + * BASE DNs + */ + String DEPLOY_BASEDN = "ou=deploy,ou=node"; + + /* + * STANDARD VALUES + */ + String DEFAULT = "default"; + + /* + * RESERVED ROLES + */ + String ROLES_BASEDN = "ou=roles,ou=node"; + String TOKENS_BASEDN = "ou=tokens,ou=node"; + String ROLE_ADMIN = "cn=admin," + ROLES_BASEDN; + String ROLE_USER_ADMIN = "cn=userAdmin," + ROLES_BASEDN; + String ROLE_DATA_ADMIN = "cn=dataAdmin," + ROLES_BASEDN; + // Special system groups that cannot be edited: + // user U anonymous = everyone + String ROLE_USER = "cn=user," + ROLES_BASEDN; + String ROLE_ANONYMOUS = "cn=anonymous," + ROLES_BASEDN; + // Account lifecycle + String ROLE_REGISTERING = "cn=registering," + ROLES_BASEDN; + + /* + * PATHS + */ + String PATH_DATA = "/data"; + String PATH_JCR = "/jcr"; + String PATH_FILES = "/files"; + // String PATH_JCR_PUB = "/pub"; + + /* + * FILE SYSTEMS + */ + String SCHEME_NODE = NODE; + + /* + * KERBEROS + */ + String NODE_SERVICE = NODE; + + /* + * INIT FRAMEWORK PROPERTIES + */ + String NODE_INIT = "argeo.node.init"; + String I18N_DEFAULT_LOCALE = "argeo.i18n.defaultLocale"; + String I18N_LOCALES = "argeo.i18n.locales"; + // Node Security + String ROLES_URI = "argeo.node.roles.uri"; + String TOKENS_URI = "argeo.node.tokens.uri"; + /** URI to an LDIF file or LDAP server used as initialization or backend */ + String USERADMIN_URIS = "argeo.node.useradmin.uris"; + // Transaction manager + String TRANSACTION_MANAGER = "argeo.node.transaction.manager"; + String TRANSACTION_MANAGER_SIMPLE = "simple"; + String TRANSACTION_MANAGER_BITRONIX = "bitronix"; + // Node + /** Properties configuring the node repository */ + String NODE_REPO_PROP_PREFIX = "argeo.node.repo."; + /** Additional standalone repositories, related to data models. */ + String NODE_REPOS_PROP_PREFIX = "argeo.node.repos."; + // HTTP + String HTTP_PORT = "org.osgi.service.http.port"; + String HTTP_PORT_SECURE = "org.osgi.service.http.port.secure"; + /** + * The HTTP header used to convey the DN of a client verified by a reverse + * proxy. Typically SSL_CLIENT_S_DN for Apache. + */ + String HTTP_PROXY_SSL_DN = "argeo.http.proxy.ssl.dn"; + + /* + * PIDs + */ + String NODE_STATE_PID = "org.argeo.api.state"; + String NODE_DEPLOYMENT_PID = "org.argeo.api.deployment"; + String NODE_INSTANCE_PID = "org.argeo.api.instance"; + + String NODE_KEYRING_PID = "org.argeo.api.keyring"; + String NODE_FS_PROVIDER_PID = "org.argeo.api.fsProvider"; + + /* + * FACTORY PIDs + */ + String NODE_REPOS_FACTORY_PID = "org.argeo.api.repos"; + String NODE_USER_ADMIN_PID = "org.argeo.api.userAdmin"; +} diff --git a/org.argeo.api/src/org/argeo/api/cms/CmsData.java b/org.argeo.api/src/org/argeo/api/cms/CmsData.java new file mode 100644 index 000000000..a12a3ce7f --- /dev/null +++ b/org.argeo.api/src/org/argeo/api/cms/CmsData.java @@ -0,0 +1,15 @@ +package org.argeo.api.cms; + +import javax.naming.ldap.LdapName; + +/** The structured data */ +public interface CmsData { + /** + * To be used as an identifier of a workgroup, typically as a value for the + * 'businessCategory' attribute in LDAP. + */ + public final static String WORKGROUP = "workgroup"; + + /** Mark this group as a workgroup */ + void createWorkgroup(LdapName groupDn); +} diff --git a/org.argeo.api/src/org/argeo/api/cms/CmsDeployment.java b/org.argeo.api/src/org/argeo/api/cms/CmsDeployment.java new file mode 100644 index 000000000..9498f96f3 --- /dev/null +++ b/org.argeo.api/src/org/argeo/api/cms/CmsDeployment.java @@ -0,0 +1,12 @@ +package org.argeo.api.cms; + +import java.util.Dictionary; + +/** A configured node deployment. */ +public interface CmsDeployment { + Long getAvailableSince(); + + void addFactoryDeployConfig(String factoryPid, Dictionary props); + Dictionary getProps(String factoryPid, String cn); + +} diff --git a/org.argeo.api/src/org/argeo/api/cms/CmsLog.java b/org.argeo.api/src/org/argeo/api/cms/CmsLog.java new file mode 100644 index 000000000..206cfd649 --- /dev/null +++ b/org.argeo.api/src/org/argeo/api/cms/CmsLog.java @@ -0,0 +1,182 @@ +package org.argeo.api.cms; + +import java.lang.System.Logger; +import java.lang.System.Logger.Level; +import java.util.Objects; + +/** + * A Commons Logging / SLF4J style logging utilities wrapping a standard Java + * platform {@link Logger}. + */ +public interface CmsLog { + Logger getLogger(); + + default boolean isDebugEnabled() { + return getLogger().isLoggable(Level.DEBUG); + } + + default boolean isErrorEnabled() { + return getLogger().isLoggable(Level.ERROR); + } + + default boolean isInfoEnabled() { + return getLogger().isLoggable(Level.INFO); + } + + default boolean isTraceEnabled() { + return getLogger().isLoggable(Level.TRACE); + } + + default boolean isWarnEnabled() { + return getLogger().isLoggable(Level.WARNING); + } + + /* + * TRACE + */ + + default void trace(String message) { + getLogger().log(Level.TRACE, message); + } + + default void trace(Object message) { + getLogger().log(Level.TRACE, Objects.requireNonNull(message)); + } + + default void trace(String message, Throwable t) { + getLogger().log(Level.TRACE, message, t); + } + + default void trace(Object message, Throwable t) { + trace(Objects.requireNonNull(message).toString(), t); + } + + default void trace(String format, Object... arguments) { + getLogger().log(Level.TRACE, format, arguments); + } + + /* + * DEBUG + */ + + default void debug(String message) { + getLogger().log(Level.DEBUG, message); + } + + default void debug(Object message) { + getLogger().log(Level.DEBUG, message); + } + + default void debug(String message, Throwable t) { + getLogger().log(Level.DEBUG, message, t); + } + + default void debug(Object message, Throwable t) { + debug(Objects.requireNonNull(message).toString(), t); + } + + default void debug(String format, Object... arguments) { + getLogger().log(Level.DEBUG, format, arguments); + } + + /* + * INFO + */ + + default void info(String message) { + getLogger().log(Level.INFO, message); + } + + default void info(Object message) { + getLogger().log(Level.INFO, message); + } + + default void info(String message, Throwable t) { + getLogger().log(Level.INFO, message, t); + } + + default void info(Object message, Throwable t) { + info(Objects.requireNonNull(message).toString(), t); + } + + default void info(String format, Object... arguments) { + getLogger().log(Level.INFO, format, arguments); + } + + /* + * WARN + */ + + default void warn(String message) { + getLogger().log(Level.WARNING, message); + } + + default void warn(Object message) { + getLogger().log(Level.WARNING, message); + } + + default void warn(String message, Throwable t) { + getLogger().log(Level.WARNING, message, t); + } + + default void warn(Object message, Throwable t) { + warn(Objects.requireNonNull(message).toString(), t); + } + + default void warn(String format, Object... arguments) { + getLogger().log(Level.WARNING, format, arguments); + } + + /* + * ERROR + */ + + default void error(String message) { + getLogger().log(Level.ERROR, message); + } + + default void error(Object message) { + getLogger().log(Level.ERROR, message); + } + + default void error(String message, Throwable t) { + getLogger().log(Level.ERROR, message, t); + } + + default void error(Object message, Throwable t) { + error(Objects.requireNonNull(message).toString(), t); + } + + default void error(String format, Object... arguments) { + getLogger().log(Level.ERROR, format, arguments); + } + + /* + * STATIC UTILITIES + */ + + static CmsLog getLog(Class clss) { + return getLog(Objects.requireNonNull(clss).getName()); + } + + static CmsLog getLog(String name) { + Logger logger = System.getLogger(Objects.requireNonNull(name)); + return new LoggerWrapper(logger); + } + + /** A trivial implementation wrapping a platform logger. */ + static class LoggerWrapper implements CmsLog { + private final Logger logger; + + LoggerWrapper(Logger logger) { + this.logger = logger; + } + + @Override + public Logger getLogger() { + return logger; + } + + } + +} diff --git a/org.argeo.api/src/org/argeo/api/cms/CmsState.java b/org.argeo.api/src/org/argeo/api/cms/CmsState.java new file mode 100644 index 000000000..26427003e --- /dev/null +++ b/org.argeo.api/src/org/argeo/api/cms/CmsState.java @@ -0,0 +1,16 @@ +package org.argeo.api.cms; + +import java.util.List; +import java.util.Locale; + +/** A running node process. */ +public interface CmsState { + Locale getDefaultLocale(); + + List getLocales(); + + String getHostname(); + + Long getAvailableSince(); + +} diff --git a/org.argeo.api/src/org/argeo/api/cms/DataAdminPrincipal.java b/org.argeo.api/src/org/argeo/api/cms/DataAdminPrincipal.java new file mode 100644 index 000000000..bc12bcbe2 --- /dev/null +++ b/org.argeo.api/src/org/argeo/api/cms/DataAdminPrincipal.java @@ -0,0 +1,29 @@ +package org.argeo.api.cms; + +import java.security.Principal; + +/** Allows to modify any data. */ +public final class DataAdminPrincipal implements Principal { + private final String name = CmsConstants.ROLE_DATA_ADMIN; + + @Override + public String getName() { + return name; + } + + @Override + public int hashCode() { + return name.hashCode(); + } + + @Override + public boolean equals(Object obj) { + return obj instanceof DataAdminPrincipal; + } + + @Override + public String toString() { + return name.toString(); + } + +} diff --git a/org.argeo.api/src/org/argeo/api/package-info.java b/org.argeo.api/src/org/argeo/api/package-info.java deleted file mode 100644 index 1ea483a0c..000000000 --- a/org.argeo.api/src/org/argeo/api/package-info.java +++ /dev/null @@ -1,5 +0,0 @@ -/** - * Abstractions or constants related to an Argeo Node, an active repository of - * linked data. - */ -package org.argeo.api; \ No newline at end of file diff --git a/org.argeo.api/src/org/argeo/api/security/AnonymousPrincipal.java b/org.argeo.api/src/org/argeo/api/security/AnonymousPrincipal.java deleted file mode 100644 index d07b055ef..000000000 --- a/org.argeo.api/src/org/argeo/api/security/AnonymousPrincipal.java +++ /dev/null @@ -1,36 +0,0 @@ -package org.argeo.api.security; - -import java.security.Principal; - -import javax.naming.ldap.LdapName; - -import org.argeo.api.NodeConstants; - -/** Marker for anonymous users. */ -public final class AnonymousPrincipal implements Principal { - private final String name = NodeConstants.ROLE_ANONYMOUS; - - @Override - public String getName() { - return name; - } - - @Override - public int hashCode() { - return name.hashCode(); - } - - @Override - public boolean equals(Object obj) { - return this == obj; - } - - @Override - public String toString() { - return name.toString(); - } - - public LdapName getLdapName(){ - return NodeSecurityUtils.ROLE_ANONYMOUS_NAME; - } -} diff --git a/org.argeo.api/src/org/argeo/api/security/CryptoKeyring.java b/org.argeo.api/src/org/argeo/api/security/CryptoKeyring.java deleted file mode 100644 index 5ac73c6cd..000000000 --- a/org.argeo.api/src/org/argeo/api/security/CryptoKeyring.java +++ /dev/null @@ -1,10 +0,0 @@ -package org.argeo.api.security; - -/** - * Marker interface for an advanced keyring based on cryptography. - */ -public interface CryptoKeyring extends Keyring { - public void changePassword(char[] oldPassword, char[] newPassword); - - public void unlock(char[] password); -} diff --git a/org.argeo.api/src/org/argeo/api/security/DataAdminPrincipal.java b/org.argeo.api/src/org/argeo/api/security/DataAdminPrincipal.java deleted file mode 100644 index 7581d8db0..000000000 --- a/org.argeo.api/src/org/argeo/api/security/DataAdminPrincipal.java +++ /dev/null @@ -1,31 +0,0 @@ -package org.argeo.api.security; - -import java.security.Principal; - -import org.argeo.api.NodeConstants; - -/** Allows to modify any data. */ -public final class DataAdminPrincipal implements Principal { - private final String name = NodeConstants.ROLE_DATA_ADMIN; - - @Override - public String getName() { - return name; - } - - @Override - public int hashCode() { - return name.hashCode(); - } - - @Override - public boolean equals(Object obj) { - return obj instanceof DataAdminPrincipal; - } - - @Override - public String toString() { - return name.toString(); - } - -} diff --git a/org.argeo.api/src/org/argeo/api/security/Keyring.java b/org.argeo.api/src/org/argeo/api/security/Keyring.java deleted file mode 100644 index e0aa854e6..000000000 --- a/org.argeo.api/src/org/argeo/api/security/Keyring.java +++ /dev/null @@ -1,26 +0,0 @@ -package org.argeo.api.security; - -import java.io.InputStream; - -/** - * Access to private (typically encrypted) data. The keyring is responsible for - * retrieving the necessary credentials. Experimental. This API may - * change. - */ -public interface Keyring { - /** - * Returns the confidential information as chars. Must ask for it if it is - * not stored. - */ - public char[] getAsChars(String path); - - /** - * Returns the confidential information as a stream. Must ask for it if it - * is not stored. - */ - public InputStream getAsStream(String path); - - public void set(String path, char[] arr); - - public void set(String path, InputStream in); -} diff --git a/org.argeo.api/src/org/argeo/api/security/NodeSecurityUtils.java b/org.argeo.api/src/org/argeo/api/security/NodeSecurityUtils.java deleted file mode 100644 index 245851285..000000000 --- a/org.argeo.api/src/org/argeo/api/security/NodeSecurityUtils.java +++ /dev/null @@ -1,40 +0,0 @@ -package org.argeo.api.security; - -import java.util.Arrays; -import java.util.Collections; -import java.util.List; - -import javax.naming.InvalidNameException; -import javax.naming.ldap.LdapName; - -import org.argeo.api.NodeConstants; - -public class NodeSecurityUtils { - public final static LdapName ROLE_ADMIN_NAME, ROLE_DATA_ADMIN_NAME, ROLE_ANONYMOUS_NAME, ROLE_USER_NAME, - ROLE_USER_ADMIN_NAME; - public final static List RESERVED_ROLES; - static { - try { - ROLE_ADMIN_NAME = new LdapName(NodeConstants.ROLE_ADMIN); - ROLE_DATA_ADMIN_NAME = new LdapName(NodeConstants.ROLE_DATA_ADMIN); - ROLE_USER_NAME = new LdapName(NodeConstants.ROLE_USER); - ROLE_USER_ADMIN_NAME = new LdapName(NodeConstants.ROLE_USER_ADMIN); - ROLE_ANONYMOUS_NAME = new LdapName(NodeConstants.ROLE_ANONYMOUS); - RESERVED_ROLES = Collections.unmodifiableList(Arrays.asList( - new LdapName[] { ROLE_ADMIN_NAME, ROLE_ANONYMOUS_NAME, ROLE_USER_NAME, ROLE_USER_ADMIN_NAME })); - } catch (InvalidNameException e) { - throw new Error("Cannot initialize login module class", e); - } - } - - public static void checkUserName(LdapName name) throws IllegalArgumentException { - if (RESERVED_ROLES.contains(name)) - throw new IllegalArgumentException(name + " is a reserved name"); - } - - public static void checkImpliedPrincipalName(LdapName roleName) throws IllegalArgumentException { -// if (ROLE_USER_NAME.equals(roleName) || ROLE_ANONYMOUS_NAME.equals(roleName)) -// throw new IllegalArgumentException(roleName + " cannot be listed as role"); - } - -} diff --git a/org.argeo.api/src/org/argeo/api/security/PBEKeySpecCallback.java b/org.argeo.api/src/org/argeo/api/security/PBEKeySpecCallback.java deleted file mode 100644 index 81fc7244c..000000000 --- a/org.argeo.api/src/org/argeo/api/security/PBEKeySpecCallback.java +++ /dev/null @@ -1,63 +0,0 @@ -package org.argeo.api.security; - -import javax.crypto.spec.PBEKeySpec; -import javax.security.auth.callback.Callback; -import javax.security.auth.callback.PasswordCallback; - -/** - * All information required to set up a {@link PBEKeySpec} bar the password - * itself (use a {@link PasswordCallback}) - */ -public class PBEKeySpecCallback implements Callback { - private String secretKeyFactory; - private byte[] salt; - private Integer iterationCount; - /** Can be null for some algorithms */ - private Integer keyLength; - /** Can be null, will trigger secret key encryption if not */ - private String secretKeyEncryption; - - private String encryptedPasswordHashCipher; - private byte[] encryptedPasswordHash; - - public void set(String secretKeyFactory, byte[] salt, - Integer iterationCount, Integer keyLength, - String secretKeyEncryption) { - this.secretKeyFactory = secretKeyFactory; - this.salt = salt; - this.iterationCount = iterationCount; - this.keyLength = keyLength; - this.secretKeyEncryption = secretKeyEncryption; -// this.encryptedPasswordHashCipher = encryptedPasswordHashCipher; -// this.encryptedPasswordHash = encryptedPasswordHash; - } - - public String getSecretKeyFactory() { - return secretKeyFactory; - } - - public byte[] getSalt() { - return salt; - } - - public Integer getIterationCount() { - return iterationCount; - } - - public Integer getKeyLength() { - return keyLength; - } - - public String getSecretKeyEncryption() { - return secretKeyEncryption; - } - - public String getEncryptedPasswordHashCipher() { - return encryptedPasswordHashCipher; - } - - public byte[] getEncryptedPasswordHash() { - return encryptedPasswordHash; - } - -} diff --git a/org.argeo.api/src/org/argeo/api/security/package-info.java b/org.argeo.api/src/org/argeo/api/security/package-info.java deleted file mode 100644 index 4af616975..000000000 --- a/org.argeo.api/src/org/argeo/api/security/package-info.java +++ /dev/null @@ -1,2 +0,0 @@ -/** Security related API. */ -package org.argeo.api.security; \ No newline at end of file diff --git a/org.argeo.api/src/org/argeo/api/tabular/ArrayTabularRow.java b/org.argeo.api/src/org/argeo/api/tabular/ArrayTabularRow.java deleted file mode 100644 index 3a14151c9..000000000 --- a/org.argeo.api/src/org/argeo/api/tabular/ArrayTabularRow.java +++ /dev/null @@ -1,25 +0,0 @@ -package org.argeo.api.tabular; - -import java.util.List; - -/** Minimal tabular row wrapping an {@link Object} array */ -public class ArrayTabularRow implements TabularRow { - private final Object[] arr; - - public ArrayTabularRow(List objs) { - this.arr = objs.toArray(); - } - - public Object get(Integer col) { - return arr[col]; - } - - public int size() { - return arr.length; - } - - public Object[] toArray() { - return arr; - } - -} diff --git a/org.argeo.api/src/org/argeo/api/tabular/TabularColumn.java b/org.argeo.api/src/org/argeo/api/tabular/TabularColumn.java deleted file mode 100644 index 772ca5912..000000000 --- a/org.argeo.api/src/org/argeo/api/tabular/TabularColumn.java +++ /dev/null @@ -1,41 +0,0 @@ -package org.argeo.api.tabular; - -/** The column in a tabular content */ -public class TabularColumn { - private String name; - /** - * JCR types, see - * http://www.day.com/maven/javax.jcr/javadocs/jcr-2.0/index.html - * ?javax/jcr/PropertyType.html - */ - private Integer type; - - /** column with default type */ - public TabularColumn(String name) { - super(); - this.name = name; - } - - public TabularColumn(String name, Integer type) { - super(); - this.name = name; - this.type = type; - } - - public String getName() { - return name; - } - - public void setName(String name) { - this.name = name; - } - - public Integer getType() { - return type; - } - - public void setType(Integer type) { - this.type = type; - } - -} diff --git a/org.argeo.api/src/org/argeo/api/tabular/TabularContent.java b/org.argeo.api/src/org/argeo/api/tabular/TabularContent.java deleted file mode 100644 index 3c9d049c5..000000000 --- a/org.argeo.api/src/org/argeo/api/tabular/TabularContent.java +++ /dev/null @@ -1,14 +0,0 @@ -package org.argeo.api.tabular; - -import java.util.List; - -/** - * Content organized as a table, possibly with headers. Only JCR types are - * supported even though there is not direct dependency on JCR. - */ -public interface TabularContent { - /** The headers of this table or null is none available. */ - public List getColumns(); - - public TabularRowIterator read(); -} diff --git a/org.argeo.api/src/org/argeo/api/tabular/TabularRow.java b/org.argeo.api/src/org/argeo/api/tabular/TabularRow.java deleted file mode 100644 index a79b072da..000000000 --- a/org.argeo.api/src/org/argeo/api/tabular/TabularRow.java +++ /dev/null @@ -1,13 +0,0 @@ -package org.argeo.api.tabular; - -/** A row of tabular data */ -public interface TabularRow { - /** The value at this column index */ - public Object get(Integer col); - - /** The raw objects (direct references) */ - public Object[] toArray(); - - /** Number of columns */ - public int size(); -} diff --git a/org.argeo.api/src/org/argeo/api/tabular/TabularRowIterator.java b/org.argeo.api/src/org/argeo/api/tabular/TabularRowIterator.java deleted file mode 100644 index 27a9c6fdb..000000000 --- a/org.argeo.api/src/org/argeo/api/tabular/TabularRowIterator.java +++ /dev/null @@ -1,12 +0,0 @@ -package org.argeo.api.tabular; - -import java.util.Iterator; - -/** Navigation of rows */ -public interface TabularRowIterator extends Iterator { - /** - * Current row number, has to be incremented by each call to next() ; starts at 0, will - * therefore be 1 for the first row returned. - */ - public Long getCurrentRowNumber(); -} diff --git a/org.argeo.api/src/org/argeo/api/tabular/TabularWriter.java b/org.argeo.api/src/org/argeo/api/tabular/TabularWriter.java deleted file mode 100644 index c434ffac1..000000000 --- a/org.argeo.api/src/org/argeo/api/tabular/TabularWriter.java +++ /dev/null @@ -1,11 +0,0 @@ -package org.argeo.api.tabular; - - -/** Write to a tabular content */ -public interface TabularWriter { - /** Append a new row of data */ - public void appendRow(Object[] row); - - /** Finish persisting data and release resources */ - public void close(); -} diff --git a/org.argeo.api/src/org/argeo/api/tabular/package-info.java b/org.argeo.api/src/org/argeo/api/tabular/package-info.java deleted file mode 100644 index 738281f87..000000000 --- a/org.argeo.api/src/org/argeo/api/tabular/package-info.java +++ /dev/null @@ -1,2 +0,0 @@ -/** Tabular format API. */ -package org.argeo.api.tabular; \ No newline at end of file diff --git a/org.argeo.cms.e4/src/org/argeo/cms/e4/addons/AuthAddon.java b/org.argeo.cms.e4/src/org/argeo/cms/e4/addons/AuthAddon.java index 326a67e10..3d57e1659 100644 --- a/org.argeo.cms.e4/src/org/argeo/cms/e4/addons/AuthAddon.java +++ b/org.argeo.cms.e4/src/org/argeo/cms/e4/addons/AuthAddon.java @@ -7,8 +7,7 @@ import javax.annotation.PostConstruct; import javax.security.auth.Subject; import javax.servlet.http.HttpServletRequest; -import org.apache.commons.logging.Log; -import org.apache.commons.logging.LogFactory; +import org.argeo.api.cms.CmsLog; import org.argeo.cms.CmsException; import org.argeo.cms.auth.CurrentUser; import org.eclipse.e4.ui.model.application.MApplication; @@ -19,7 +18,7 @@ import org.eclipse.e4.ui.model.application.ui.basic.MTrimmedWindow; import org.eclipse.e4.ui.model.application.ui.basic.MWindow; public class AuthAddon { - private final static Log log = LogFactory.getLog(AuthAddon.class); + private final static CmsLog log = CmsLog.getLog(AuthAddon.class); public final static String AUTH = "auth."; diff --git a/org.argeo.cms.e4/src/org/argeo/cms/e4/handlers/ChangePassword.java b/org.argeo.cms.e4/src/org/argeo/cms/e4/handlers/ChangePassword.java index 1d3bab9f8..0ecd0a155 100644 --- a/org.argeo.cms.e4/src/org/argeo/cms/e4/handlers/ChangePassword.java +++ b/org.argeo.cms.e4/src/org/argeo/cms/e4/handlers/ChangePassword.java @@ -12,9 +12,9 @@ import javax.inject.Inject; import javax.naming.InvalidNameException; import javax.naming.ldap.LdapName; -import org.argeo.api.security.CryptoKeyring; import org.argeo.cms.CmsException; import org.argeo.cms.auth.CurrentUser; +import org.argeo.cms.security.CryptoKeyring; import org.argeo.cms.swt.dialogs.CmsMessageDialog; import org.argeo.eclipse.ui.dialogs.ErrorFeedback; import org.argeo.osgi.transaction.WorkTransaction; diff --git a/org.argeo.cms.e4/src/org/argeo/cms/e4/jcr/JcrBrowserView.java b/org.argeo.cms.e4/src/org/argeo/cms/e4/jcr/JcrBrowserView.java index f352f91aa..98e80936d 100644 --- a/org.argeo.cms.e4/src/org/argeo/cms/e4/jcr/JcrBrowserView.java +++ b/org.argeo.cms.e4/src/org/argeo/cms/e4/jcr/JcrBrowserView.java @@ -16,10 +16,10 @@ import javax.jcr.observation.Event; import javax.jcr.observation.EventListener; import javax.jcr.observation.ObservationManager; -import org.argeo.api.NodeConstants; -import org.argeo.api.security.CryptoKeyring; -import org.argeo.api.security.Keyring; +import org.argeo.api.cms.CmsConstants; import org.argeo.cms.CmsException; +import org.argeo.cms.security.CryptoKeyring; +import org.argeo.cms.security.Keyring; import org.argeo.cms.swt.CmsSwtUtils; import org.argeo.cms.ui.jcr.JcrBrowserUtils; import org.argeo.cms.ui.jcr.NodeContentProvider; @@ -100,7 +100,7 @@ public class JcrBrowserView { top.setLayout(CmsSwtUtils.noSpaceGridLayout()); try { - this.userSession = this.nodeRepository.login(NodeConstants.HOME_WORKSPACE); + this.userSession = this.nodeRepository.login(CmsConstants.HOME_WORKSPACE); } catch (RepositoryException e) { throw new CmsException("Cannot open user session", e); } diff --git a/org.argeo.cms.e4/src/org/argeo/cms/e4/jcr/handlers/AddRemoteRepository.java b/org.argeo.cms.e4/src/org/argeo/cms/e4/jcr/handlers/AddRemoteRepository.java index cf7aac86a..dc47f6edf 100644 --- a/org.argeo.cms.e4/src/org/argeo/cms/e4/jcr/handlers/AddRemoteRepository.java +++ b/org.argeo.cms.e4/src/org/argeo/cms/e4/jcr/handlers/AddRemoteRepository.java @@ -11,12 +11,12 @@ import javax.jcr.RepositoryFactory; import javax.jcr.Session; import javax.jcr.SimpleCredentials; -import org.argeo.api.NodeConstants; -import org.argeo.api.security.Keyring; +import org.argeo.api.cms.CmsConstants; import org.argeo.cms.ArgeoNames; import org.argeo.cms.ArgeoTypes; import org.argeo.cms.e4.jcr.JcrBrowserView; import org.argeo.cms.jcr.CmsJcrUtils; +import org.argeo.cms.security.Keyring; import org.argeo.eclipse.ui.EclipseUiException; import org.argeo.eclipse.ui.dialogs.ErrorFeedback; import org.argeo.jcr.JcrUtils; @@ -130,11 +130,11 @@ public class AddRemoteRepository { String checkedUriStr = checkedUri.toString(); Hashtable params = new Hashtable(); - params.put(NodeConstants.LABELED_URI, checkedUriStr); + params.put(CmsConstants.LABELED_URI, checkedUriStr); Repository repository = repositoryFactory.getRepository(params); if (username.getText().trim().equals("")) {// anonymous // FIXME make it more generic - session = repository.login(NodeConstants.SYS_WORKSPACE); + session = repository.login(CmsConstants.SYS_WORKSPACE); } else { // FIXME use getTextChars() when upgrading to 3.7 // see https://bugs.eclipse.org/bugs/show_bug.cgi?id=297412 diff --git a/org.argeo.cms.e4/src/org/argeo/cms/e4/maintenance/AbstractOsgiComposite.java b/org.argeo.cms.e4/src/org/argeo/cms/e4/maintenance/AbstractOsgiComposite.java index c9c18e9df..4fd1d68dc 100644 --- a/org.argeo.cms.e4/src/org/argeo/cms/e4/maintenance/AbstractOsgiComposite.java +++ b/org.argeo.cms.e4/src/org/argeo/cms/e4/maintenance/AbstractOsgiComposite.java @@ -2,8 +2,7 @@ package org.argeo.cms.e4.maintenance; import java.util.Collection; -import org.apache.commons.logging.Log; -import org.apache.commons.logging.LogFactory; +import org.argeo.api.cms.CmsLog; import org.argeo.cms.swt.CmsSwtUtils; import org.eclipse.swt.SWT; import org.eclipse.swt.layout.GridData; @@ -16,7 +15,7 @@ import org.osgi.framework.ServiceReference; abstract class AbstractOsgiComposite extends Composite { private static final long serialVersionUID = -4097415973477517137L; protected final BundleContext bc = FrameworkUtil.getBundle(getClass()).getBundleContext(); - protected final Log log = LogFactory.getLog(getClass()); + protected final CmsLog log = CmsLog.getLog(getClass()); public AbstractOsgiComposite(Composite parent, int style) { super(parent, style); diff --git a/org.argeo.cms.e4/src/org/argeo/cms/e4/maintenance/DataDeploymentUi.java b/org.argeo.cms.e4/src/org/argeo/cms/e4/maintenance/DataDeploymentUi.java index 22e80069d..ef95bde64 100644 --- a/org.argeo.cms.e4/src/org/argeo/cms/e4/maintenance/DataDeploymentUi.java +++ b/org.argeo.cms.e4/src/org/argeo/cms/e4/maintenance/DataDeploymentUi.java @@ -9,7 +9,7 @@ import java.util.Collection; import org.apache.jackrabbit.core.RepositoryContext; import org.apache.jackrabbit.core.config.RepositoryConfig; -import org.argeo.api.NodeConstants; +import org.argeo.api.cms.CmsConstants; import org.argeo.cms.swt.CmsSwtUtils; import org.eclipse.swt.SWT; import org.eclipse.swt.layout.GridData; @@ -82,12 +82,12 @@ class DataDeploymentUi extends AbstractOsgiComposite { private void initCurrentUi(Composite parent) { parent.setLayout(new GridLayout()); Collection> contexts = getServiceReferences(RepositoryContext.class, - "(" + NodeConstants.CN + "=*)"); + "(" + CmsConstants.CN + "=*)"); StringBuffer text = new StringBuffer(); text.append("Jackrabbit Repositories
"); for (ServiceReference sr : contexts) { RepositoryContext repositoryContext = bc.getService(sr); - String alias = sr.getProperty(NodeConstants.CN).toString(); + String alias = sr.getProperty(CmsConstants.CN).toString(); String rootNodeId = repositoryContext.getRootNodeId().toString(); RepositoryConfig repositoryConfig = repositoryContext.getRepositoryConfig(); Path repoHomePath = new File(repositoryConfig.getHomeDir()).toPath().toAbsolutePath(); diff --git a/org.argeo.cms.e4/src/org/argeo/cms/e4/maintenance/DeploymentEntryPoint.java b/org.argeo.cms.e4/src/org/argeo/cms/e4/maintenance/DeploymentEntryPoint.java index 505f67d81..6aaa1692f 100644 --- a/org.argeo.cms.e4/src/org/argeo/cms/e4/maintenance/DeploymentEntryPoint.java +++ b/org.argeo.cms.e4/src/org/argeo/cms/e4/maintenance/DeploymentEntryPoint.java @@ -3,9 +3,9 @@ package org.argeo.cms.e4.maintenance; import java.util.GregorianCalendar; import java.util.TimeZone; -import org.argeo.api.NodeConstants; -import org.argeo.api.NodeDeployment; -import org.argeo.api.NodeState; +import org.argeo.api.cms.CmsState; +import org.argeo.api.cms.CmsConstants; +import org.argeo.api.cms.CmsDeployment; import org.argeo.cms.swt.CmsSwtUtils; import org.eclipse.swt.SWT; import org.eclipse.swt.layout.FillLayout; @@ -62,18 +62,18 @@ class DeploymentEntryPoint { composite.setLayoutData(gridData); composite.setLayout(new FillLayout()); - ServiceReference nodeStateRef = bc.getServiceReference(NodeState.class); + ServiceReference nodeStateRef = bc.getServiceReference(CmsState.class); if (nodeStateRef == null) throw new IllegalStateException("No CMS state available"); - NodeState nodeState = bc.getService(nodeStateRef); - ServiceReference nodeDeploymentRef = bc.getServiceReference(NodeDeployment.class); + CmsState nodeState = bc.getService(nodeStateRef); + ServiceReference nodeDeploymentRef = bc.getServiceReference(CmsDeployment.class); Label label = new Label(composite, SWT.WRAP); CmsSwtUtils.markup(label); if (nodeDeploymentRef == null) { label.setText("Not yet deployed on
" + nodeState.getHostname() + "
, please configure below."); } else { - Object stateUuid = nodeStateRef.getProperty(NodeConstants.CN); - NodeDeployment nodeDeployment = bc.getService(nodeDeploymentRef); + Object stateUuid = nodeStateRef.getProperty(CmsConstants.CN); + CmsDeployment nodeDeployment = bc.getService(nodeDeploymentRef); GregorianCalendar calendar = new GregorianCalendar(); calendar.setTimeInMillis(nodeDeployment.getAvailableSince()); calendar.setTimeZone(TimeZone.getDefault()); diff --git a/org.argeo.cms.e4/src/org/argeo/cms/e4/users/AbstractRoleEditor.java b/org.argeo.cms.e4/src/org/argeo/cms/e4/users/AbstractRoleEditor.java index 31f2d1c8d..137f76242 100644 --- a/org.argeo.cms.e4/src/org/argeo/cms/e4/users/AbstractRoleEditor.java +++ b/org.argeo.cms.e4/src/org/argeo/cms/e4/users/AbstractRoleEditor.java @@ -12,7 +12,7 @@ import org.argeo.cms.ui.eclipse.forms.AbstractFormPart; import org.argeo.cms.ui.eclipse.forms.IManagedForm; import org.argeo.cms.ui.eclipse.forms.ManagedForm; import org.argeo.eclipse.ui.EclipseUiUtils; -import org.argeo.naming.LdapAttrs; +import org.argeo.util.naming.LdapAttrs; import org.eclipse.core.runtime.IProgressMonitor; import org.eclipse.e4.ui.di.Persist; import org.eclipse.e4.ui.model.application.ui.basic.MPart; diff --git a/org.argeo.cms.e4/src/org/argeo/cms/e4/users/GroupEditor.java b/org.argeo.cms.e4/src/org/argeo/cms/e4/users/GroupEditor.java index 2521612c7..239bb3156 100644 --- a/org.argeo.cms.e4/src/org/argeo/cms/e4/users/GroupEditor.java +++ b/org.argeo.cms.e4/src/org/argeo/cms/e4/users/GroupEditor.java @@ -1,9 +1,9 @@ package org.argeo.cms.e4.users; -import static org.argeo.api.NodeInstance.WORKGROUP; +import static org.argeo.api.cms.CmsData.WORKGROUP; import static org.argeo.cms.auth.UserAdminUtils.setProperty; -import static org.argeo.naming.LdapAttrs.businessCategory; -import static org.argeo.naming.LdapAttrs.description; +import static org.argeo.util.naming.LdapAttrs.businessCategory; +import static org.argeo.util.naming.LdapAttrs.description; import java.util.ArrayList; import java.util.Iterator; @@ -18,8 +18,8 @@ import javax.jcr.Session; import javax.naming.InvalidNameException; import javax.naming.ldap.LdapName; -import org.argeo.api.NodeConstants; -import org.argeo.api.NodeInstance; +import org.argeo.api.cms.CmsData; +import org.argeo.api.cms.CmsConstants; import org.argeo.cms.CmsException; import org.argeo.cms.auth.UserAdminUtils; import org.argeo.cms.e4.users.providers.CommonNameLP; @@ -34,8 +34,8 @@ import org.argeo.eclipse.ui.ColumnDefinition; import org.argeo.eclipse.ui.EclipseUiUtils; import org.argeo.eclipse.ui.parts.LdifUsersTable; import org.argeo.jcr.JcrUtils; -import org.argeo.naming.LdapAttrs; import org.argeo.osgi.transaction.WorkTransaction; +import org.argeo.util.naming.LdapAttrs; import org.eclipse.e4.ui.workbench.modeling.EPartService; import org.eclipse.jface.action.Action; import org.eclipse.jface.action.ToolBarManager; @@ -87,7 +87,7 @@ public class GroupEditor extends AbstractRoleEditor { @Inject private Repository repository; @Inject - private NodeInstance nodeInstance; + private CmsData nodeInstance; // private final UserAdminWrapper userAdminWrapper; private Session groupsSession; @@ -119,7 +119,7 @@ public class GroupEditor extends AbstractRoleEditor { @Override protected void createUi(Composite parent) { try { - groupsSession = repository.login(NodeConstants.SRV_WORKSPACE); + groupsSession = repository.login(CmsConstants.SRV_WORKSPACE); } catch (RepositoryException e) { throw new CmsException("Cannot retrieve session", e); } diff --git a/org.argeo.cms.e4/src/org/argeo/cms/e4/users/GroupsView.java b/org.argeo.cms.e4/src/org/argeo/cms/e4/users/GroupsView.java index 9104a6a61..ddad34fd1 100644 --- a/org.argeo.cms.e4/src/org/argeo/cms/e4/users/GroupsView.java +++ b/org.argeo.cms.e4/src/org/argeo/cms/e4/users/GroupsView.java @@ -7,9 +7,8 @@ import javax.annotation.PostConstruct; import javax.annotation.PreDestroy; import javax.inject.Inject; -import org.apache.commons.logging.Log; -import org.apache.commons.logging.LogFactory; -import org.argeo.api.NodeConstants; +import org.argeo.api.cms.CmsConstants; +import org.argeo.api.cms.CmsLog; import org.argeo.cms.CmsException; import org.argeo.cms.auth.CurrentUser; import org.argeo.cms.e4.users.providers.CommonNameLP; @@ -27,8 +26,8 @@ import org.argeo.cms.e4.users.providers.UserDragListener; import org.argeo.eclipse.ui.ColumnDefinition; import org.argeo.eclipse.ui.EclipseUiUtils; import org.argeo.eclipse.ui.parts.LdifUsersTable; -import org.argeo.naming.LdapAttrs; -import org.argeo.naming.LdapObjs; +import org.argeo.util.naming.LdapAttrs; +import org.argeo.util.naming.LdapObjs; import org.eclipse.e4.ui.di.Focus; import org.eclipse.e4.ui.workbench.modeling.EPartService; import org.eclipse.e4.ui.workbench.modeling.ESelectionService; @@ -56,7 +55,7 @@ import org.osgi.service.useradmin.UserAdminListener; /** List all groups with filter */ public class GroupsView { - private final static Log log = LogFactory.getLog(GroupsView.class); + private final static CmsLog log = CmsLog.getLog(GroupsView.class); // public final static String ID = WorkbenchUiPlugin.PLUGIN_ID + ".groupsView"; @Inject @@ -155,14 +154,14 @@ public class GroupsView { public MyUserTableViewer(Composite parent, int style) { super(parent, style); - showSystemRoles = CurrentUser.isInRole(NodeConstants.ROLE_ADMIN); + showSystemRoles = CurrentUser.isInRole(CmsConstants.ROLE_ADMIN); } protected void populateStaticFilters(Composite staticFilterCmp) { staticFilterCmp.setLayout(new GridLayout()); final Button showSystemRoleBtn = new Button(staticFilterCmp, SWT.CHECK); showSystemRoleBtn.setText("Show system roles"); - showSystemRoles = CurrentUser.isInRole(NodeConstants.ROLE_ADMIN); + showSystemRoles = CurrentUser.isInRole(CmsConstants.ROLE_ADMIN); showSystemRoleBtn.setSelection(showSystemRoles); showSystemRoleBtn.addSelectionListener(new SelectionAdapter() { @@ -195,11 +194,11 @@ public class GroupsView { builder.append("(&(").append(LdapAttrs.objectClass.name()).append("=") .append(LdapObjs.groupOfNames.name()).append(")"); // hide tokens - builder.append("(!(").append(LdapAttrs.DN).append("=*").append(NodeConstants.TOKENS_BASEDN) + builder.append("(!(").append(LdapAttrs.DN).append("=*").append(CmsConstants.TOKENS_BASEDN) .append("))"); if (!showSystemRoles) - builder.append("(!(").append(LdapAttrs.DN).append("=*").append(NodeConstants.ROLES_BASEDN) + builder.append("(!(").append(LdapAttrs.DN).append("=*").append(CmsConstants.ROLES_BASEDN) .append("))"); builder.append("(|"); builder.append(tmpBuilder.toString()); @@ -208,12 +207,12 @@ public class GroupsView { if (!showSystemRoles) builder.append("(&(").append(LdapAttrs.objectClass.name()).append("=") .append(LdapObjs.groupOfNames.name()).append(")(!(").append(LdapAttrs.DN).append("=*") - .append(NodeConstants.ROLES_BASEDN).append("))(!(").append(LdapAttrs.DN).append("=*") - .append(NodeConstants.TOKENS_BASEDN).append(")))"); + .append(CmsConstants.ROLES_BASEDN).append("))(!(").append(LdapAttrs.DN).append("=*") + .append(CmsConstants.TOKENS_BASEDN).append(")))"); else builder.append("(&(").append(LdapAttrs.objectClass.name()).append("=") .append(LdapObjs.groupOfNames.name()).append(")(!(").append(LdapAttrs.DN).append("=*") - .append(NodeConstants.TOKENS_BASEDN).append(")))"); + .append(CmsConstants.TOKENS_BASEDN).append(")))"); } roles = userAdminWrapper.getUserAdmin().getRoles(builder.toString()); diff --git a/org.argeo.cms.e4/src/org/argeo/cms/e4/users/UserAdminWrapper.java b/org.argeo.cms.e4/src/org/argeo/cms/e4/users/UserAdminWrapper.java index d1bdd775a..16aa78316 100644 --- a/org.argeo.cms.e4/src/org/argeo/cms/e4/users/UserAdminWrapper.java +++ b/org.argeo.cms.e4/src/org/argeo/cms/e4/users/UserAdminWrapper.java @@ -8,7 +8,7 @@ import java.util.LinkedHashMap; import java.util.List; import java.util.Map; -import org.argeo.api.NodeConstants; +import org.argeo.api.cms.CmsConstants; import org.argeo.cms.CmsException; import org.argeo.osgi.transaction.WorkTransaction; import org.argeo.osgi.useradmin.UserAdminConf; @@ -95,9 +95,9 @@ public class UserAdminWrapper { if (onlyWritable && readOnly) continue; - if (baseDn.equalsIgnoreCase(NodeConstants.ROLES_BASEDN)) + if (baseDn.equalsIgnoreCase(CmsConstants.ROLES_BASEDN)) continue; - if (baseDn.equalsIgnoreCase(NodeConstants.TOKENS_BASEDN)) + if (baseDn.equalsIgnoreCase(CmsConstants.TOKENS_BASEDN)) continue; dns.put(baseDn, UserAdminConf.propertiesAsUri(userDirectories.get(userDirectory)).toString()); diff --git a/org.argeo.cms.e4/src/org/argeo/cms/e4/users/UserBatchUpdateWizard.java b/org.argeo.cms.e4/src/org/argeo/cms/e4/users/UserBatchUpdateWizard.java index 4073a209b..a38d171ef 100644 --- a/org.argeo.cms.e4/src/org/argeo/cms/e4/users/UserBatchUpdateWizard.java +++ b/org.argeo.cms.e4/src/org/argeo/cms/e4/users/UserBatchUpdateWizard.java @@ -5,9 +5,8 @@ import java.util.HashMap; import java.util.List; import java.util.Map; -import org.apache.commons.logging.Log; -import org.apache.commons.logging.LogFactory; -import org.argeo.api.NodeConstants; +import org.argeo.api.cms.CmsConstants; +import org.argeo.api.cms.CmsLog; import org.argeo.cms.CmsException; import org.argeo.cms.auth.CurrentUser; import org.argeo.cms.auth.UserAdminUtils; @@ -18,9 +17,9 @@ import org.argeo.cms.e4.users.providers.UserNameLP; import org.argeo.eclipse.ui.ColumnDefinition; import org.argeo.eclipse.ui.EclipseUiUtils; import org.argeo.eclipse.ui.parts.LdifUsersTable; -import org.argeo.naming.LdapAttrs; -import org.argeo.naming.LdapObjs; import org.argeo.osgi.transaction.WorkTransaction; +import org.argeo.util.naming.LdapAttrs; +import org.argeo.util.naming.LdapObjs; import org.eclipse.jface.dialogs.IPageChangeProvider; import org.eclipse.jface.dialogs.IPageChangedListener; import org.eclipse.jface.dialogs.MessageDialog; @@ -47,7 +46,7 @@ import org.osgi.service.useradmin.UserAdminEvent; /** Wizard to update users */ public class UserBatchUpdateWizard extends Wizard { - private final static Log log = LogFactory.getLog(UserBatchUpdateWizard.class); + private final static CmsLog log = CmsLog.getLog(UserBatchUpdateWizard.class); private UserAdminWrapper userAdminWrapper; // pages @@ -463,7 +462,7 @@ public class UserBatchUpdateWizard extends Wizard { columnDefs.add(new ColumnDefinition(new DomainNameLP(), "Domain", 200)); // Only show technical DN to admin - if (CurrentUser.isInRole(NodeConstants.ROLE_ADMIN)) + if (CurrentUser.isInRole(CmsConstants.ROLE_ADMIN)) columnDefs.add(new ColumnDefinition(new UserNameLP(), "Distinguished Name", 300)); userTableCmp = new ChooseUserTableViewer(pageCmp, SWT.MULTI | SWT.H_SCROLL | SWT.V_SCROLL); @@ -562,7 +561,7 @@ public class UserBatchUpdateWizard extends Wizard { columnDefs.add(new ColumnDefinition(new MailLP(), "E-mail", 150)); columnDefs.add(new ColumnDefinition(new DomainNameLP(), "Domain", 200)); // Only show technical DN to admin - if (CurrentUser.isInRole(NodeConstants.ROLE_ADMIN)) + if (CurrentUser.isInRole(CmsConstants.ROLE_ADMIN)) columnDefs.add(new ColumnDefinition(new UserNameLP(), "Distinguished Name", 300)); userTableCmp = new ChosenUsersTableViewer(pageCmp, SWT.MULTI | SWT.H_SCROLL | SWT.V_SCROLL); userTableCmp.setLayoutData(EclipseUiUtils.fillAll()); diff --git a/org.argeo.cms.e4/src/org/argeo/cms/e4/users/UserEditor.java b/org.argeo.cms.e4/src/org/argeo/cms/e4/users/UserEditor.java index a93100120..66f442082 100644 --- a/org.argeo.cms.e4/src/org/argeo/cms/e4/users/UserEditor.java +++ b/org.argeo.cms.e4/src/org/argeo/cms/e4/users/UserEditor.java @@ -1,11 +1,11 @@ package org.argeo.cms.e4.users; import static org.argeo.cms.auth.UserAdminUtils.getProperty; -import static org.argeo.naming.LdapAttrs.cn; -import static org.argeo.naming.LdapAttrs.givenName; -import static org.argeo.naming.LdapAttrs.mail; -import static org.argeo.naming.LdapAttrs.sn; -import static org.argeo.naming.LdapAttrs.uid; +import static org.argeo.util.naming.LdapAttrs.cn; +import static org.argeo.util.naming.LdapAttrs.givenName; +import static org.argeo.util.naming.LdapAttrs.mail; +import static org.argeo.util.naming.LdapAttrs.sn; +import static org.argeo.util.naming.LdapAttrs.uid; import java.util.ArrayList; import java.util.Iterator; @@ -13,7 +13,7 @@ import java.util.List; import javax.inject.Inject; -import org.argeo.api.NodeConstants; +import org.argeo.api.cms.CmsConstants; import org.argeo.cms.auth.CurrentUser; import org.argeo.cms.auth.UserAdminUtils; import org.argeo.cms.e4.users.providers.CommonNameLP; @@ -27,7 +27,7 @@ import org.argeo.cms.ui.eclipse.forms.IManagedForm; import org.argeo.eclipse.ui.ColumnDefinition; import org.argeo.eclipse.ui.EclipseUiUtils; import org.argeo.eclipse.ui.parts.LdifUsersTable; -import org.argeo.naming.LdapAttrs; +import org.argeo.util.naming.LdapAttrs; import org.eclipse.e4.ui.workbench.modeling.EPartService; import org.eclipse.jface.action.Action; import org.eclipse.jface.action.ToolBarManager; @@ -370,7 +370,7 @@ public class UserEditor extends AbstractRoleEditor { staticFilterCmp.setLayout(new GridLayout()); showSystemRoleBtn = new Button(staticFilterCmp, SWT.CHECK); showSystemRoleBtn.setText("Show system roles"); - boolean showSysRole = CurrentUser.isInRole(NodeConstants.ROLE_ADMIN); + boolean showSysRole = CurrentUser.isInRole(CmsConstants.ROLE_ADMIN); showSystemRoleBtn.setSelection(showSysRole); userFilter.setShowSystemRole(showSysRole); showSystemRoleBtn.addSelectionListener(new SelectionAdapter() { diff --git a/org.argeo.cms.e4/src/org/argeo/cms/e4/users/UserTableDefaultDClickListener.java b/org.argeo.cms.e4/src/org/argeo/cms/e4/users/UserTableDefaultDClickListener.java index a9a4ede0a..c6d024ebc 100644 --- a/org.argeo.cms.e4/src/org/argeo/cms/e4/users/UserTableDefaultDClickListener.java +++ b/org.argeo.cms.e4/src/org/argeo/cms/e4/users/UserTableDefaultDClickListener.java @@ -1,7 +1,7 @@ package org.argeo.cms.e4.users; import org.argeo.cms.e4.CmsE4Utils; -import org.argeo.naming.LdapAttrs; +import org.argeo.util.naming.LdapAttrs; import org.eclipse.e4.ui.workbench.modeling.EPartService; import org.eclipse.jface.viewers.DoubleClickEvent; import org.eclipse.jface.viewers.IDoubleClickListener; diff --git a/org.argeo.cms.e4/src/org/argeo/cms/e4/users/UsersView.java b/org.argeo.cms.e4/src/org/argeo/cms/e4/users/UsersView.java index 4b94f5cc8..877a925c6 100644 --- a/org.argeo.cms.e4/src/org/argeo/cms/e4/users/UsersView.java +++ b/org.argeo.cms.e4/src/org/argeo/cms/e4/users/UsersView.java @@ -7,7 +7,7 @@ import javax.annotation.PostConstruct; import javax.annotation.PreDestroy; import javax.inject.Inject; -import org.argeo.api.NodeConstants; +import org.argeo.api.cms.CmsConstants; import org.argeo.cms.CmsException; import org.argeo.cms.auth.CurrentUser; import org.argeo.cms.e4.users.providers.CommonNameLP; @@ -18,8 +18,8 @@ import org.argeo.cms.e4.users.providers.UserNameLP; import org.argeo.eclipse.ui.ColumnDefinition; import org.argeo.eclipse.ui.EclipseUiUtils; import org.argeo.eclipse.ui.parts.LdifUsersTable; -import org.argeo.naming.LdapAttrs; -import org.argeo.naming.LdapObjs; +import org.argeo.util.naming.LdapAttrs; +import org.argeo.util.naming.LdapObjs; import org.eclipse.e4.ui.di.Focus; import org.eclipse.e4.ui.workbench.modeling.EPartService; import org.eclipse.e4.ui.workbench.modeling.ESelectionService; @@ -66,7 +66,7 @@ public class UsersView { columnDefs.add(new ColumnDefinition(new MailLP(), "E-mail", 150)); columnDefs.add(new ColumnDefinition(new DomainNameLP(), "Domain", 200)); // Only show technical DN to admin - if (CurrentUser.isInRole(NodeConstants.ROLE_ADMIN)) + if (CurrentUser.isInRole(CmsConstants.ROLE_ADMIN)) columnDefs.add(new ColumnDefinition(new UserNameLP(), "Distinguished Name", 300)); // Create and configure the table diff --git a/org.argeo.cms.e4/src/org/argeo/cms/e4/users/handlers/NewGroup.java b/org.argeo.cms.e4/src/org/argeo/cms/e4/users/handlers/NewGroup.java index e49b11074..d2ffa791b 100644 --- a/org.argeo.cms.e4/src/org/argeo/cms/e4/users/handlers/NewGroup.java +++ b/org.argeo.cms.e4/src/org/argeo/cms/e4/users/handlers/NewGroup.java @@ -9,8 +9,8 @@ import org.argeo.cms.CmsException; import org.argeo.cms.e4.users.UserAdminWrapper; import org.argeo.eclipse.ui.EclipseUiUtils; import org.argeo.eclipse.ui.dialogs.ErrorFeedback; -import org.argeo.naming.LdapAttrs; import org.argeo.osgi.useradmin.UserAdminConf; +import org.argeo.util.naming.LdapAttrs; import org.eclipse.e4.core.di.annotations.Execute; import org.eclipse.jface.wizard.Wizard; import org.eclipse.jface.wizard.WizardDialog; diff --git a/org.argeo.cms.e4/src/org/argeo/cms/e4/users/handlers/NewUser.java b/org.argeo.cms.e4/src/org/argeo/cms/e4/users/handlers/NewUser.java index 1faa90de2..07d82c749 100644 --- a/org.argeo.cms.e4/src/org/argeo/cms/e4/users/handlers/NewUser.java +++ b/org.argeo.cms.e4/src/org/argeo/cms/e4/users/handlers/NewUser.java @@ -15,8 +15,8 @@ import org.argeo.cms.e4.users.UiAdminUtils; import org.argeo.cms.e4.users.UserAdminWrapper; import org.argeo.eclipse.ui.EclipseUiUtils; import org.argeo.eclipse.ui.dialogs.ErrorFeedback; -import org.argeo.naming.LdapAttrs; import org.argeo.osgi.useradmin.UserAdminConf; +import org.argeo.util.naming.LdapAttrs; import org.eclipse.e4.core.di.annotations.Execute; import org.eclipse.jface.wizard.Wizard; import org.eclipse.jface.wizard.WizardDialog; diff --git a/org.argeo.cms.e4/src/org/argeo/cms/e4/users/providers/CommonNameLP.java b/org.argeo.cms.e4/src/org/argeo/cms/e4/users/providers/CommonNameLP.java index eb8819425..2d8db67d7 100644 --- a/org.argeo.cms.e4/src/org/argeo/cms/e4/users/providers/CommonNameLP.java +++ b/org.argeo.cms.e4/src/org/argeo/cms/e4/users/providers/CommonNameLP.java @@ -1,7 +1,7 @@ package org.argeo.cms.e4.users.providers; import org.argeo.cms.auth.UserAdminUtils; -import org.argeo.naming.LdapAttrs; +import org.argeo.util.naming.LdapAttrs; import org.osgi.service.useradmin.User; /** Simply declare a label provider that returns the common name of a user */ diff --git a/org.argeo.cms.e4/src/org/argeo/cms/e4/users/providers/MailLP.java b/org.argeo.cms.e4/src/org/argeo/cms/e4/users/providers/MailLP.java index a312c0dfc..52d3b858f 100644 --- a/org.argeo.cms.e4/src/org/argeo/cms/e4/users/providers/MailLP.java +++ b/org.argeo.cms.e4/src/org/argeo/cms/e4/users/providers/MailLP.java @@ -1,7 +1,7 @@ package org.argeo.cms.e4.users.providers; import org.argeo.cms.auth.UserAdminUtils; -import org.argeo.naming.LdapAttrs; +import org.argeo.util.naming.LdapAttrs; import org.osgi.service.useradmin.User; /** Simply declare a label provider that returns the Primary Mail of a user */ diff --git a/org.argeo.cms.e4/src/org/argeo/cms/e4/users/providers/RoleIconLP.java b/org.argeo.cms.e4/src/org/argeo/cms/e4/users/providers/RoleIconLP.java index d9a75b89e..49a2026c9 100644 --- a/org.argeo.cms.e4/src/org/argeo/cms/e4/users/providers/RoleIconLP.java +++ b/org.argeo.cms.e4/src/org/argeo/cms/e4/users/providers/RoleIconLP.java @@ -1,10 +1,10 @@ package org.argeo.cms.e4.users.providers; -import org.argeo.api.NodeConstants; -import org.argeo.api.NodeInstance; +import org.argeo.api.cms.CmsData; +import org.argeo.api.cms.CmsConstants; import org.argeo.cms.auth.UserAdminUtils; import org.argeo.cms.e4.users.SecurityAdminImages; -import org.argeo.naming.LdapAttrs; +import org.argeo.util.naming.LdapAttrs; import org.eclipse.swt.graphics.Image; import org.osgi.service.useradmin.Role; import org.osgi.service.useradmin.User; @@ -22,11 +22,11 @@ public class RoleIconLP extends UserAdminAbstractLP { public Image getImage(Object element) { User user = (User) element; String dn = user.getName(); - if (dn.endsWith(NodeConstants.ROLES_BASEDN)) + if (dn.endsWith(CmsConstants.ROLES_BASEDN)) return SecurityAdminImages.ICON_ROLE; else if (user.getType() == Role.GROUP) { String businessCategory = UserAdminUtils.getProperty(user, LdapAttrs.businessCategory); - if (businessCategory != null && businessCategory.equals(NodeInstance.WORKGROUP)) + if (businessCategory != null && businessCategory.equals(CmsData.WORKGROUP)) return SecurityAdminImages.ICON_WORKGROUP; return SecurityAdminImages.ICON_GROUP; } else diff --git a/org.argeo.cms.e4/src/org/argeo/cms/e4/users/providers/UserFilter.java b/org.argeo.cms.e4/src/org/argeo/cms/e4/users/providers/UserFilter.java index e090fe251..154b04725 100644 --- a/org.argeo.cms.e4/src/org/argeo/cms/e4/users/providers/UserFilter.java +++ b/org.argeo.cms.e4/src/org/argeo/cms/e4/users/providers/UserFilter.java @@ -2,9 +2,9 @@ package org.argeo.cms.e4.users.providers; import static org.argeo.eclipse.ui.EclipseUiUtils.notEmpty; -import org.argeo.api.NodeConstants; +import org.argeo.api.cms.CmsConstants; import org.argeo.cms.auth.UserAdminUtils; -import org.argeo.naming.LdapAttrs; +import org.argeo.util.naming.LdapAttrs; import org.eclipse.jface.viewers.Viewer; import org.eclipse.jface.viewers.ViewerFilter; import org.osgi.service.useradmin.User; @@ -37,7 +37,7 @@ public class UserFilter extends ViewerFilter { @Override public boolean select(Viewer viewer, Object parentElement, Object element) { User user = (User) element; - if (!showSystemRole && user.getName().matches(".*(" + NodeConstants.ROLES_BASEDN + ")")) + if (!showSystemRole && user.getName().matches(".*(" + CmsConstants.ROLES_BASEDN + ")")) // UserAdminUtils.getProperty(user, LdifName.dn.name()) // .toLowerCase().endsWith(AuthConstants.ROLES_BASEDN)) return false; diff --git a/org.argeo.cms.jcr/src/org/argeo/cms/fs/CmsFsUtils.java b/org.argeo.cms.jcr/src/org/argeo/cms/fs/CmsFsUtils.java index e152c002e..40d38eec2 100644 --- a/org.argeo.cms.jcr/src/org/argeo/cms/fs/CmsFsUtils.java +++ b/org.argeo.cms.jcr/src/org/argeo/cms/fs/CmsFsUtils.java @@ -16,13 +16,13 @@ import javax.jcr.Session; import javax.jcr.query.Query; import javax.jcr.query.QueryManager; -import org.argeo.api.NodeConstants; +import org.argeo.api.cms.CmsConstants; import org.argeo.jcr.Jcr; /** Utilities around documents. */ public class CmsFsUtils { // TODO make it more robust and configurable - private static String baseWorkspaceName = NodeConstants.SYS_WORKSPACE; + private static String baseWorkspaceName = CmsConstants.SYS_WORKSPACE; public static Node getNode(Repository repository, Path path) { String workspaceName = path.getNameCount() == 0 ? baseWorkspaceName : path.getName(0).toString(); @@ -75,7 +75,7 @@ public class CmsFsUtils { : '/' + workspaceName + Jcr.getPath(node); URI uri; try { - uri = new URI(NodeConstants.SCHEME_NODE, null, fullPath, null); + uri = new URI(CmsConstants.SCHEME_NODE, null, fullPath, null); } catch (URISyntaxException e) { throw new IllegalArgumentException("Cannot interpret " + fullPath + " as an URI", e); } diff --git a/org.argeo.cms.jcr/src/org/argeo/cms/internal/jcr/JcrInitUtils.java b/org.argeo.cms.jcr/src/org/argeo/cms/internal/jcr/JcrInitUtils.java index 27f011b13..0536fb645 100644 --- a/org.argeo.cms.jcr/src/org/argeo/cms/internal/jcr/JcrInitUtils.java +++ b/org.argeo.cms.jcr/src/org/argeo/cms/internal/jcr/JcrInitUtils.java @@ -11,30 +11,29 @@ import javax.jcr.Repository; import javax.jcr.RepositoryException; import javax.jcr.RepositoryFactory; -import org.apache.commons.logging.Log; -import org.apache.commons.logging.LogFactory; -import org.argeo.api.NodeConstants; -import org.argeo.api.NodeDeployment; +import org.argeo.api.cms.CmsDeployment; +import org.argeo.api.cms.CmsLog; +import org.argeo.api.cms.CmsConstants; import org.argeo.jackrabbit.client.ClientDavexRepositoryFactory; import org.argeo.jcr.JcrException; -import org.argeo.naming.LdapAttrs; +import org.argeo.util.naming.LdapAttrs; import org.osgi.framework.BundleContext; import org.osgi.framework.Constants; import org.osgi.framework.FrameworkUtil; /** JCR specific init utilities. */ public class JcrInitUtils { - private final static Log log = LogFactory.getLog(JcrInitUtils.class); + private final static CmsLog log = CmsLog.getLog(JcrInitUtils.class); private final static BundleContext bundleContext = FrameworkUtil.getBundle(JcrInitUtils.class).getBundleContext(); - public static void addToDeployment(NodeDeployment nodeDeployment) { + public static void addToDeployment(CmsDeployment nodeDeployment) { // node repository // Dictionary provided = null; - Dictionary provided = nodeDeployment.getProps(NodeConstants.NODE_REPOS_FACTORY_PID, - NodeConstants.NODE); + Dictionary provided = nodeDeployment.getProps(CmsConstants.NODE_REPOS_FACTORY_PID, + CmsConstants.NODE); Dictionary nodeConfig = JcrInitUtils.getNodeRepositoryConfig(provided); // node repository is mandatory - nodeDeployment.addFactoryDeployConfig(NodeConstants.NODE_REPOS_FACTORY_PID, nodeConfig); + nodeDeployment.addFactoryDeployConfig(CmsConstants.NODE_REPOS_FACTORY_PID, nodeConfig); // additional repositories // dataModels: for (DataModels.DataModel dataModel : dataModels.getNonAbstractDataModels()) { @@ -52,25 +51,25 @@ public class JcrInitUtils { public static Dictionary getNodeRepositoryConfig(Dictionary provided) { Dictionary props = provided != null ? provided : new Hashtable(); for (RepoConf repoConf : RepoConf.values()) { - Object value = getFrameworkProp(NodeConstants.NODE_REPO_PROP_PREFIX + repoConf.name()); + Object value = getFrameworkProp(CmsConstants.NODE_REPO_PROP_PREFIX + repoConf.name()); if (value != null) { props.put(repoConf.name(), value); if (log.isDebugEnabled()) log.debug("Set node repo configuration " + repoConf.name() + " to " + value); } } - props.put(NodeConstants.CN, NodeConstants.NODE_REPOSITORY); + props.put(CmsConstants.CN, CmsConstants.NODE_REPOSITORY); return props; } public static Dictionary getRepositoryConfig(String dataModelName, Dictionary provided) { - if (dataModelName.equals(NodeConstants.NODE_REPOSITORY) || dataModelName.equals(NodeConstants.EGO_REPOSITORY)) + if (dataModelName.equals(CmsConstants.NODE_REPOSITORY) || dataModelName.equals(CmsConstants.EGO_REPOSITORY)) throw new IllegalArgumentException("Data model '" + dataModelName + "' is reserved."); Dictionary props = provided != null ? provided : new Hashtable(); for (RepoConf repoConf : RepoConf.values()) { Object value = getFrameworkProp( - NodeConstants.NODE_REPOS_PROP_PREFIX + dataModelName + '.' + repoConf.name()); + CmsConstants.NODE_REPOS_PROP_PREFIX + dataModelName + '.' + repoConf.name()); if (value != null) { props.put(repoConf.name(), value); if (log.isDebugEnabled()) @@ -78,7 +77,7 @@ public class JcrInitUtils { } } if (props.size() != 0) - props.put(NodeConstants.CN, dataModelName); + props.put(CmsConstants.CN, dataModelName); return props; } @@ -86,7 +85,7 @@ public class JcrInitUtils { try { Repository repository = createRemoteRepository(new URI(uri)); Hashtable properties = new Hashtable<>(); - properties.put(NodeConstants.CN, NodeConstants.NODE_INIT); + properties.put(CmsConstants.CN, CmsConstants.NODE_INIT); properties.put(LdapAttrs.labeledURI.name(), uri); properties.put(Constants.SERVICE_RANKING, -1000); bundleContext.registerService(Repository.class, repository, properties); @@ -102,7 +101,7 @@ public class JcrInitUtils { Map params = new HashMap(); params.put(ClientDavexRepositoryFactory.JACKRABBIT_DAVEX_URI, uri.toString()); // TODO make it configurable - params.put(ClientDavexRepositoryFactory.JACKRABBIT_REMOTE_DEFAULT_WORKSPACE, NodeConstants.SYS_WORKSPACE); + params.put(ClientDavexRepositoryFactory.JACKRABBIT_REMOTE_DEFAULT_WORKSPACE, CmsConstants.SYS_WORKSPACE); return repositoryFactory.getRepository(params); } diff --git a/org.argeo.cms.jcr/src/org/argeo/cms/internal/jcr/RepoConf.java b/org.argeo.cms.jcr/src/org/argeo/cms/internal/jcr/RepoConf.java index a48adccab..a45656cf5 100644 --- a/org.argeo.cms.jcr/src/org/argeo/cms/internal/jcr/RepoConf.java +++ b/org.argeo.cms.jcr/src/org/argeo/cms/internal/jcr/RepoConf.java @@ -1,6 +1,6 @@ package org.argeo.cms.internal.jcr; -import org.argeo.api.NodeConstants; +import org.argeo.api.cms.CmsConstants; import org.argeo.osgi.metatype.EnumAD; import org.argeo.osgi.metatype.EnumOCD; @@ -9,7 +9,7 @@ public enum RepoConf implements EnumAD { /** Repository type */ type("h2"), /** Default workspace */ - defaultWorkspace(NodeConstants.SYS_WORKSPACE), + defaultWorkspace(CmsConstants.SYS_WORKSPACE), /** Database URL */ dburl(null), /** Database user */ diff --git a/org.argeo.cms.jcr/src/org/argeo/cms/internal/jcr/RepositoryBuilder.java b/org.argeo.cms.jcr/src/org/argeo/cms/internal/jcr/RepositoryBuilder.java index 22d763a79..3db97167c 100644 --- a/org.argeo.cms.jcr/src/org/argeo/cms/internal/jcr/RepositoryBuilder.java +++ b/org.argeo.cms.jcr/src/org/argeo/cms/internal/jcr/RepositoryBuilder.java @@ -14,20 +14,19 @@ import java.util.UUID; import javax.jcr.RepositoryException; -import org.apache.commons.logging.Log; -import org.apache.commons.logging.LogFactory; import org.apache.jackrabbit.core.RepositoryContext; import org.apache.jackrabbit.core.RepositoryImpl; import org.apache.jackrabbit.core.cache.CacheManager; import org.apache.jackrabbit.core.config.RepositoryConfig; import org.apache.jackrabbit.core.config.RepositoryConfigurationParser; -import org.argeo.api.NodeConstants; +import org.argeo.api.cms.CmsConstants; +import org.argeo.api.cms.CmsLog; import org.argeo.cms.jcr.internal.CmsPaths; import org.xml.sax.InputSource; /** Can interpret properties in order to create an actual JCR repository. */ public class RepositoryBuilder { - private final static Log log = LogFactory.getLog(RepositoryBuilder.class); + private final static CmsLog log = CmsLog.getLog(RepositoryBuilder.class); public RepositoryContext createRepositoryContext(Dictionary properties) throws RepositoryException, IOException { @@ -99,7 +98,7 @@ public class RepositoryBuilder { String homeUri = props.getProperty(RepoConf.labeledUri.name()); Path homePath; if (homeUri == null) { - String cn = props.getProperty(NodeConstants.CN); + String cn = props.getProperty(CmsConstants.CN); assert cn != null; if (clusterId != null) { homePath = CmsPaths.getRepoDirPath(cn + '/' + clusterId); diff --git a/org.argeo.cms.jcr/src/org/argeo/cms/jcr/CmsJcrUtils.java b/org.argeo.cms.jcr/src/org/argeo/cms/jcr/CmsJcrUtils.java index ff128a29d..b5d9adfca 100644 --- a/org.argeo.cms.jcr/src/org/argeo/cms/jcr/CmsJcrUtils.java +++ b/org.argeo.cms.jcr/src/org/argeo/cms/jcr/CmsJcrUtils.java @@ -18,19 +18,20 @@ import javax.security.auth.Subject; import javax.security.auth.login.LoginContext; import javax.security.auth.login.LoginException; -import org.argeo.api.NodeConstants; +import org.argeo.api.cms.CmsAuth; +import org.argeo.api.cms.CmsConstants; /** Utilities related to Argeo model in JCR */ public class CmsJcrUtils { /** * Wraps the call to the repository factory based on parameter - * {@link NodeConstants#CN} in order to simplify it and protect against future + * {@link CmsConstants#CN} in order to simplify it and protect against future * API changes. */ public static Repository getRepositoryByAlias(RepositoryFactory repositoryFactory, String alias) { try { Map parameters = new HashMap(); - parameters.put(NodeConstants.CN, alias); + parameters.put(CmsConstants.CN, alias); return repositoryFactory.getRepository(parameters); } catch (RepositoryException e) { throw new RuntimeException("Unexpected exception when trying to retrieve repository with alias " + alias, @@ -40,7 +41,7 @@ public class CmsJcrUtils { /** * Wraps the call to the repository factory based on parameter - * {@link NodeConstants#LABELED_URI} in order to simplify it and protect against + * {@link CmsConstants#LABELED_URI} in order to simplify it and protect against * future API changes. */ public static Repository getRepositoryByUri(RepositoryFactory repositoryFactory, String uri) { @@ -49,15 +50,15 @@ public class CmsJcrUtils { /** * Wraps the call to the repository factory based on parameter - * {@link NodeConstants#LABELED_URI} in order to simplify it and protect against + * {@link CmsConstants#LABELED_URI} in order to simplify it and protect against * future API changes. */ public static Repository getRepositoryByUri(RepositoryFactory repositoryFactory, String uri, String alias) { try { Map parameters = new HashMap(); - parameters.put(NodeConstants.LABELED_URI, uri); + parameters.put(CmsConstants.LABELED_URI, uri); if (alias != null) - parameters.put(NodeConstants.CN, alias); + parameters.put(CmsConstants.CN, alias); return repositoryFactory.getRepository(parameters); } catch (RepositoryException e) { throw new RuntimeException("Unexpected exception when trying to retrieve repository with uri " + uri, e); @@ -113,7 +114,7 @@ public class CmsJcrUtils { private static void checkUserWorkspace(Session session, String username) { String workspaceName = session.getWorkspace().getName(); - if (!NodeConstants.HOME_WORKSPACE.equals(workspaceName)) + if (!CmsConstants.HOME_WORKSPACE.equals(workspaceName)) throw new IllegalArgumentException(workspaceName + " is not the home workspace for user " + username); } @@ -167,7 +168,7 @@ public class CmsJcrUtils { private static void checkGroupWorkspace(Session session, String groupname) { String workspaceName = session.getWorkspace().getName(); - if (!NodeConstants.SRV_WORKSPACE.equals(workspaceName)) + if (!CmsConstants.SRV_WORKSPACE.equals(workspaceName)) throw new IllegalArgumentException(workspaceName + " is not the group workspace for group " + groupname); } @@ -218,7 +219,7 @@ public class CmsJcrUtils { */ public static String getDataPath(String cn, Node node) { assert node != null; - StringBuilder buf = new StringBuilder(NodeConstants.PATH_DATA); + StringBuilder buf = new StringBuilder(CmsConstants.PATH_DATA); try { return buf.append('/').append(cn).append('/').append(node.getSession().getWorkspace().getName()) .append(node.getPath()).toString(); @@ -232,20 +233,20 @@ public class CmsJcrUtils { * repository and the name of the workspace. */ public static String getDataPath(Node node) { - return getDataPath(NodeConstants.NODE, node); + return getDataPath(CmsConstants.NODE, node); } /** * Open a JCR session with full read/write rights on the data, as - * {@link NodeConstants#ROLE_USER_ADMIN}, using the - * {@link NodeConstants#LOGIN_CONTEXT_DATA_ADMIN} login context. For security + * {@link CmsConstants#ROLE_USER_ADMIN}, using the + * {@link CmsAuth#LOGIN_CONTEXT_DATA_ADMIN} login context. For security * hardened deployement, use {@link AuthPermission} on this login context. */ public static Session openDataAdminSession(Repository repository, String workspaceName) { ClassLoader currentCl = Thread.currentThread().getContextClassLoader(); LoginContext loginContext; try { - loginContext = new LoginContext(NodeConstants.LOGIN_CONTEXT_DATA_ADMIN); + loginContext = new LoginContext(CmsAuth.LOGIN_CONTEXT_DATA_ADMIN); loginContext.login(); } catch (LoginException e1) { throw new RuntimeException("Could not login as data admin", e1); diff --git a/org.argeo.cms.jcr/src/org/argeo/cms/jcr/internal/CmsFsProvider.java b/org.argeo.cms.jcr/src/org/argeo/cms/jcr/internal/CmsFsProvider.java index bfbca733e..50ef25e9a 100644 --- a/org.argeo.cms.jcr/src/org/argeo/cms/jcr/internal/CmsFsProvider.java +++ b/org.argeo.cms.jcr/src/org/argeo/cms/jcr/internal/CmsFsProvider.java @@ -18,7 +18,7 @@ import javax.jcr.RepositoryFactory; import javax.jcr.Session; import javax.jcr.nodetype.NodeType; -import org.argeo.api.NodeConstants; +import org.argeo.api.cms.CmsConstants; import org.argeo.cms.auth.CurrentUser; import org.argeo.cms.jcr.CmsJcrUtils; import org.argeo.jackrabbit.fs.AbstractJackrabbitFsProvider; @@ -35,7 +35,7 @@ public class CmsFsProvider extends AbstractJackrabbitFsProvider { @Override public String getScheme() { - return NodeConstants.SCHEME_NODE; + return CmsConstants.SCHEME_NODE; } @Override @@ -60,7 +60,7 @@ public class CmsFsProvider extends AbstractJackrabbitFsProvider { return fileSystem; } else { Repository repository = bc.getService( - bc.getServiceReferences(Repository.class, "(cn=" + NodeConstants.EGO_REPOSITORY + ")") + bc.getServiceReferences(Repository.class, "(cn=" + CmsConstants.EGO_REPOSITORY + ")") .iterator().next()); // Session session = repository.login(); CmsFileSystem fileSystem = new CmsFileSystem(this, repository); @@ -97,7 +97,7 @@ public class CmsFsProvider extends AbstractJackrabbitFsProvider { public Node getUserHome(Repository repository) { try { - Session session = repository.login(NodeConstants.HOME_WORKSPACE); + Session session = repository.login(CmsConstants.HOME_WORKSPACE); return CmsJcrUtils.getUserHome(session); } catch (RepositoryException e) { throw new IllegalStateException("Cannot get user home", e); diff --git a/org.argeo.cms.jcr/src/org/argeo/cms/jcr/internal/CmsWorkspaceIndexer.java b/org.argeo.cms.jcr/src/org/argeo/cms/jcr/internal/CmsWorkspaceIndexer.java index 7afa1d8d2..69b98dc3a 100644 --- a/org.argeo.cms.jcr/src/org/argeo/cms/jcr/internal/CmsWorkspaceIndexer.java +++ b/org.argeo.cms.jcr/src/org/argeo/cms/jcr/internal/CmsWorkspaceIndexer.java @@ -16,15 +16,14 @@ import javax.jcr.observation.EventIterator; import javax.jcr.observation.EventListener; import javax.jcr.version.VersionManager; -import org.apache.commons.logging.Log; -import org.apache.commons.logging.LogFactory; import org.apache.jackrabbit.api.JackrabbitValue; import org.apache.jackrabbit.core.RepositoryImpl; +import org.argeo.api.cms.CmsLog; import org.argeo.jcr.JcrUtils; /** Ensure consistency of files, folder and last modified nodes. */ class CmsWorkspaceIndexer implements EventListener { - private final static Log log = LogFactory.getLog(CmsWorkspaceIndexer.class); + private final static CmsLog log = CmsLog.getLog(CmsWorkspaceIndexer.class); // private final static String MIX_ETAG = "mix:etag"; private final static String JCR_ETAG = "jcr:etag"; diff --git a/org.argeo.cms.jcr/src/org/argeo/cms/jcr/internal/DataModels.java b/org.argeo.cms.jcr/src/org/argeo/cms/jcr/internal/DataModels.java index 3d0f3a167..5a790f2ea 100644 --- a/org.argeo.cms.jcr/src/org/argeo/cms/jcr/internal/DataModels.java +++ b/org.argeo.cms.jcr/src/org/argeo/cms/jcr/internal/DataModels.java @@ -8,8 +8,7 @@ import java.util.List; import java.util.Map; import java.util.TreeMap; -import org.apache.commons.logging.Log; -import org.apache.commons.logging.LogFactory; +import org.argeo.api.cms.CmsLog; import org.argeo.cms.CmsException; import org.argeo.cms.osgi.DataModelNamespace; import org.osgi.framework.Bundle; @@ -21,7 +20,7 @@ import org.osgi.framework.wiring.BundleWire; import org.osgi.framework.wiring.BundleWiring; class DataModels implements BundleListener { - private final static Log log = LogFactory.getLog(DataModels.class); + private final static CmsLog log = CmsLog.getLog(DataModels.class); private Map dataModels = new TreeMap<>(); diff --git a/org.argeo.cms.jcr/src/org/argeo/cms/jcr/internal/EgoRepository.java b/org.argeo.cms.jcr/src/org/argeo/cms/jcr/internal/EgoRepository.java index 368c3ba52..298025096 100644 --- a/org.argeo.cms.jcr/src/org/argeo/cms/jcr/internal/EgoRepository.java +++ b/org.argeo.cms.jcr/src/org/argeo/cms/jcr/internal/EgoRepository.java @@ -17,7 +17,8 @@ import javax.naming.ldap.LdapName; import javax.security.auth.Subject; import javax.security.auth.login.LoginContext; -import org.argeo.api.NodeConstants; +import org.argeo.api.cms.CmsAuth; +import org.argeo.api.cms.CmsConstants; import org.argeo.cms.CmsException; import org.argeo.cms.jcr.CmsJcrUtils; import org.argeo.jcr.JcrException; @@ -38,19 +39,19 @@ class EgoRepository extends JcrRepositoryWrapper implements KernelConstants { private SimpleDateFormat usersDatePath = new SimpleDateFormat("YYYY/MM"); - private String defaultHomeWorkspace = NodeConstants.HOME_WORKSPACE; - private String defaultGroupsWorkspace = NodeConstants.SRV_WORKSPACE; + private String defaultHomeWorkspace = CmsConstants.HOME_WORKSPACE; + private String defaultGroupsWorkspace = CmsConstants.SRV_WORKSPACE; // private String defaultGuestsWorkspace = NodeConstants.GUESTS_WORKSPACE; private final boolean remote; public EgoRepository(Repository repository, boolean remote) { super(repository); this.remote = remote; - putDescriptor(NodeConstants.CN, NodeConstants.EGO_REPOSITORY); + putDescriptor(CmsConstants.CN, CmsConstants.EGO_REPOSITORY); if (!remote) { LoginContext lc; try { - lc = new LoginContext(NodeConstants.LOGIN_CONTEXT_DATA_ADMIN); + lc = new LoginContext(CmsAuth.LOGIN_CONTEXT_DATA_ADMIN); lc.login(); } catch (javax.security.auth.login.LoginException e1) { throw new IllegalStateException("Cannot login as system", e1); @@ -112,7 +113,7 @@ class EgoRepository extends JcrRepositoryWrapper implements KernelConstants { String username = session.getUserID(); if (username == null || username.toString().equals("")) return; - if (session.getUserID().equals(NodeConstants.ROLE_ANONYMOUS)) + if (session.getUserID().equals(CmsConstants.ROLE_ANONYMOUS)) return; String userHomeWorkspace = getUserHomeWorkspace(); @@ -155,7 +156,7 @@ class EgoRepository extends JcrRepositoryWrapper implements KernelConstants { // if (workspaceName != null) // return; // skip system users - if (username.endsWith(NodeConstants.ROLES_BASEDN)) + if (username.endsWith(CmsConstants.ROLES_BASEDN)) return; try { diff --git a/org.argeo.cms.jcr/src/org/argeo/cms/jcr/internal/JackrabbitLocalRepository.java b/org.argeo.cms.jcr/src/org/argeo/cms/jcr/internal/JackrabbitLocalRepository.java index 71e25cf8b..bad9fdfd5 100644 --- a/org.argeo.cms.jcr/src/org/argeo/cms/jcr/internal/JackrabbitLocalRepository.java +++ b/org.argeo.cms.jcr/src/org/argeo/cms/jcr/internal/JackrabbitLocalRepository.java @@ -6,13 +6,12 @@ import java.util.TreeMap; import javax.jcr.RepositoryException; import javax.jcr.Session; -import org.apache.commons.logging.Log; -import org.apache.commons.logging.LogFactory; import org.apache.jackrabbit.core.RepositoryImpl; -import org.argeo.api.NodeConstants; +import org.argeo.api.cms.CmsConstants; +import org.argeo.api.cms.CmsLog; class JackrabbitLocalRepository extends LocalRepository { - private final static Log log = LogFactory.getLog(JackrabbitLocalRepository.class); + private final static CmsLog log = CmsLog.getLog(JackrabbitLocalRepository.class); final String SECURITY_WORKSPACE = "security"; private Map workspaceMonitors = new TreeMap<>(); @@ -45,7 +44,7 @@ class JackrabbitLocalRepository extends LocalRepository { private void addMonitor(String realWorkspaceName) { if (realWorkspaceName.equals(SECURITY_WORKSPACE)) return; - if (!NodeConstants.NODE_REPOSITORY.equals(getCn())) + if (!CmsConstants.NODE_REPOSITORY.equals(getCn())) return; if (!workspaceMonitors.containsKey(realWorkspaceName)) { diff --git a/org.argeo.cms.jcr/src/org/argeo/cms/jcr/internal/JcrDeployment.java b/org.argeo.cms.jcr/src/org/argeo/cms/jcr/internal/JcrDeployment.java index 9915fb037..b541b41a4 100644 --- a/org.argeo.cms.jcr/src/org/argeo/cms/jcr/internal/JcrDeployment.java +++ b/org.argeo.cms.jcr/src/org/argeo/cms/jcr/internal/JcrDeployment.java @@ -26,15 +26,12 @@ import javax.jcr.Session; import javax.security.auth.callback.CallbackHandler; import javax.servlet.Servlet; -import org.apache.commons.logging.Log; -import org.apache.commons.logging.LogFactory; import org.apache.jackrabbit.commons.cnd.CndImporter; import org.apache.jackrabbit.core.RepositoryContext; import org.apache.jackrabbit.core.RepositoryImpl; -import org.argeo.api.NodeConstants; -import org.argeo.api.NodeDeployment; -import org.argeo.api.security.CryptoKeyring; -import org.argeo.api.security.Keyring; +import org.argeo.api.cms.CmsDeployment; +import org.argeo.api.cms.CmsLog; +import org.argeo.api.cms.CmsConstants; import org.argeo.cms.ArgeoNames; import org.argeo.cms.internal.jcr.JcrInitUtils; import org.argeo.cms.jcr.CmsJcrUtils; @@ -42,11 +39,13 @@ import org.argeo.cms.jcr.internal.servlet.CmsRemotingServlet; import org.argeo.cms.jcr.internal.servlet.CmsWebDavServlet; import org.argeo.cms.jcr.internal.servlet.JcrHttpUtils; import org.argeo.cms.osgi.DataModelNamespace; +import org.argeo.cms.security.CryptoKeyring; +import org.argeo.cms.security.Keyring; import org.argeo.jcr.Jcr; import org.argeo.jcr.JcrException; import org.argeo.jcr.JcrUtils; -import org.argeo.naming.LdapAttrs; import org.argeo.util.LangUtils; +import org.argeo.util.naming.LdapAttrs; import org.osgi.framework.Bundle; import org.osgi.framework.BundleContext; import org.osgi.framework.Constants; @@ -62,7 +61,7 @@ import org.osgi.util.tracker.ServiceTracker; /** Implementation of a CMS deployment. */ public class JcrDeployment { - private final Log log = LogFactory.getLog(getClass()); + private final CmsLog log = CmsLog.getLog(getClass()); private final BundleContext bc = FrameworkUtil.getBundle(getClass()).getBundleContext(); private DataModels dataModels; @@ -73,7 +72,7 @@ public class JcrDeployment { // Readiness private boolean nodeAvailable = false; - NodeDeployment nodeDeployment; + CmsDeployment nodeDeployment; public JcrDeployment() { dataModels = new DataModels(bc); @@ -107,7 +106,7 @@ public class JcrDeployment { } - public void setNodeDeployment(NodeDeployment nodeDeployment) { + public void setNodeDeployment(CmsDeployment nodeDeployment) { this.nodeDeployment = nodeDeployment; } @@ -144,7 +143,7 @@ public class JcrDeployment { // } // home - prepareDataModel(NodeConstants.NODE_REPOSITORY, deployedNodeRepository, publishAsLocalRepo); + prepareDataModel(CmsConstants.NODE_REPOSITORY, deployedNodeRepository, publishAsLocalRepo); // init from backup // if (deployConfig.isFirstInit()) { @@ -162,7 +161,7 @@ public class JcrDeployment { Collection> initRepositorySr; try { initRepositorySr = bc.getServiceReferences(Repository.class, - "(" + NodeConstants.CN + "=" + NodeConstants.NODE_INIT + ")"); + "(" + CmsConstants.CN + "=" + CmsConstants.NODE_INIT + ")"); } catch (InvalidSyntaxException e1) { throw new IllegalArgumentException(e1); } @@ -241,11 +240,11 @@ public class JcrDeployment { // Publish home with the highest service ranking Hashtable regProps = new Hashtable<>(); - regProps.put(NodeConstants.CN, NodeConstants.EGO_REPOSITORY); + regProps.put(CmsConstants.CN, CmsConstants.EGO_REPOSITORY); regProps.put(Constants.SERVICE_RANKING, Integer.MAX_VALUE); Repository egoRepository = new EgoRepository(deployedRepository, false); bc.registerService(Repository.class, egoRepository, regProps); - registerRepositoryServlets(NodeConstants.EGO_REPOSITORY, egoRepository); + registerRepositoryServlets(CmsConstants.EGO_REPOSITORY, egoRepository); // Keyring only if Argeo extensions are available if (argeoDataModelExtensionsAvailable) { @@ -257,7 +256,7 @@ public class JcrDeployment { CallbackHandler callbackHandler = bc.getService(reference); nodeKeyring.setDefaultCallbackHandler(callbackHandler); bc.registerService(LangUtils.names(Keyring.class, CryptoKeyring.class, ManagedService.class), - nodeKeyring, LangUtils.dict(Constants.SERVICE_PID, NodeConstants.NODE_KEYRING_PID)); + nodeKeyring, LangUtils.dict(Constants.SERVICE_PID, CmsConstants.NODE_KEYRING_PID)); return callbackHandler; } @@ -274,7 +273,7 @@ public class JcrDeployment { BundleWiring wiring = bundle.adapt(BundleWiring.class); if (wiring == null) continue bundles; - if (NodeConstants.NODE_REPOSITORY.equals(cn))// process all data models + if (CmsConstants.NODE_REPOSITORY.equals(cn))// process all data models processWiring(cn, adminSession, wiring, processed, false, publishAsLocalRepo); else { List capabilities = wiring.getCapabilities(CMS_DATA_MODEL_NAMESPACE); @@ -348,7 +347,7 @@ public class JcrDeployment { boolean publishLocalRepo; if (isStandalone && name.equals(cn))// includes the node itself publishLocalRepo = true; - else if (!isStandalone && cn.equals(NodeConstants.NODE_REPOSITORY)) + else if (!isStandalone && cn.equals(CmsConstants.NODE_REPOSITORY)) publishLocalRepo = true; else publishLocalRepo = false; @@ -357,12 +356,12 @@ public class JcrDeployment { } boolean isStandalone(String dataModelName) { - return nodeDeployment.getProps(NodeConstants.NODE_REPOS_FACTORY_PID, dataModelName) != null; + return nodeDeployment.getProps(CmsConstants.NODE_REPOS_FACTORY_PID, dataModelName) != null; } private void publishLocalRepo(String dataModelName, Repository repository) { Hashtable properties = new Hashtable<>(); - properties.put(NodeConstants.CN, dataModelName); + properties.put(CmsConstants.CN, dataModelName); LocalRepository localRepository; String[] classes; if (repository instanceof RepositoryImpl) { @@ -405,14 +404,14 @@ public class JcrDeployment { ip.put(HttpWhiteboardConstants.HTTP_WHITEBOARD_SERVLET_PATTERN, "/" + alias + "/*"); ip.put(HttpWhiteboardConstants.HTTP_WHITEBOARD_CONTEXT_SELECT, - "(" + HttpWhiteboardConstants.HTTP_WHITEBOARD_CONTEXT_PATH + "=" + NodeConstants.PATH_DATA + ")"); + "(" + HttpWhiteboardConstants.HTTP_WHITEBOARD_CONTEXT_PATH + "=" + CmsConstants.PATH_DATA + ")"); bc.registerService(Servlet.class, webdavServlet, ip); } protected void registerRemotingServlet(String alias, Repository repository) { CmsRemotingServlet remotingServlet = new CmsRemotingServlet(alias, repository); Hashtable ip = new Hashtable<>(); - ip.put(NodeConstants.CN, alias); + ip.put(CmsConstants.CN, alias); // Properties ip = new Properties(); ip.put(HTTP_WHITEBOARD_SERVLET_INIT_PARAM_PREFIX + CmsRemotingServlet.INIT_PARAM_RESOURCE_PATH_PREFIX, "/" + alias); @@ -435,7 +434,7 @@ public class JcrDeployment { ip.put(HttpWhiteboardConstants.HTTP_WHITEBOARD_SERVLET_PATTERN, "/" + alias + "/*"); ip.put(HttpWhiteboardConstants.HTTP_WHITEBOARD_CONTEXT_SELECT, - "(" + HttpWhiteboardConstants.HTTP_WHITEBOARD_CONTEXT_PATH + "=" + NodeConstants.PATH_JCR + ")"); + "(" + HttpWhiteboardConstants.HTTP_WHITEBOARD_CONTEXT_PATH + "=" + CmsConstants.PATH_JCR + ")"); bc.registerService(Servlet.class, remotingServlet, ip); } @@ -448,10 +447,10 @@ public class JcrDeployment { @Override public RepositoryContext addingService(ServiceReference reference) { RepositoryContext repoContext = bc.getService(reference); - String cn = (String) reference.getProperty(NodeConstants.CN); + String cn = (String) reference.getProperty(CmsConstants.CN); if (cn != null) { List publishAsLocalRepo = new ArrayList<>(); - if (cn.equals(NodeConstants.NODE_REPOSITORY)) { + if (cn.equals(CmsConstants.NODE_REPOSITORY)) { // JackrabbitDataModelMigration.clearRepositoryCaches(repoContext.getRepositoryConfig()); prepareNodeRepository(repoContext.getRepository(), publishAsLocalRepo); // TODO separate home repository diff --git a/org.argeo.cms.jcr/src/org/argeo/cms/jcr/internal/JcrKeyring.java b/org.argeo.cms.jcr/src/org/argeo/cms/jcr/internal/JcrKeyring.java index 11a68ce24..17625f5d2 100644 --- a/org.argeo.cms.jcr/src/org/argeo/cms/jcr/internal/JcrKeyring.java +++ b/org.argeo.cms.jcr/src/org/argeo/cms/jcr/internal/JcrKeyring.java @@ -26,20 +26,19 @@ import javax.jcr.Session; import javax.jcr.query.Query; import org.apache.commons.io.IOUtils; -import org.apache.commons.logging.Log; -import org.apache.commons.logging.LogFactory; -import org.argeo.api.NodeConstants; -import org.argeo.api.security.PBEKeySpecCallback; +import org.argeo.api.cms.CmsConstants; +import org.argeo.api.cms.CmsLog; import org.argeo.cms.ArgeoNames; import org.argeo.cms.ArgeoTypes; import org.argeo.cms.jcr.CmsJcrUtils; import org.argeo.cms.security.AbstractKeyring; +import org.argeo.cms.security.PBEKeySpecCallback; import org.argeo.jcr.JcrException; import org.argeo.jcr.JcrUtils; /** JCR based implementation of a keyring */ public class JcrKeyring extends AbstractKeyring implements ArgeoNames { - private final static Log log = LogFactory.getLog(JcrKeyring.class); + private final static CmsLog log = CmsLog.getLog(JcrKeyring.class); /** * Stronger with 256, but causes problem with Oracle JVM, force 128 in this case */ @@ -96,7 +95,7 @@ public class JcrKeyring extends AbstractKeyring implements ArgeoNames { private Session login() { try { - return repository.login(NodeConstants.HOME_WORKSPACE); + return repository.login(CmsConstants.HOME_WORKSPACE); } catch (RepositoryException e) { throw new JcrException("Cannot login key ring session", e); } diff --git a/org.argeo.cms.jcr/src/org/argeo/cms/jcr/internal/KernelConstants.java b/org.argeo.cms.jcr/src/org/argeo/cms/jcr/internal/KernelConstants.java index 201f3ab28..93f29fbe8 100644 --- a/org.argeo.cms.jcr/src/org/argeo/cms/jcr/internal/KernelConstants.java +++ b/org.argeo.cms.jcr/src/org/argeo/cms/jcr/internal/KernelConstants.java @@ -1,6 +1,6 @@ package org.argeo.cms.jcr.internal; -import org.argeo.api.NodeConstants; +import org.argeo.api.cms.CmsConstants; /** Internal CMS constants. */ @Deprecated @@ -12,10 +12,10 @@ public interface KernelConstants { String DIR_TRANSACTIONS = "transactions"; // Files - String DEPLOY_CONFIG_PATH = DIR_NODE + '/' + NodeConstants.DEPLOY_BASEDN + ".ldif"; - String DEFAULT_KEYSTORE_PATH = DIR_NODE + '/' + NodeConstants.NODE + ".p12"; - String DEFAULT_PEM_KEY_PATH = DIR_NODE + '/' + NodeConstants.NODE + ".key"; - String DEFAULT_PEM_CERT_PATH = DIR_NODE + '/' + NodeConstants.NODE + ".crt"; + String DEPLOY_CONFIG_PATH = DIR_NODE + '/' + CmsConstants.DEPLOY_BASEDN + ".ldif"; + String DEFAULT_KEYSTORE_PATH = DIR_NODE + '/' + CmsConstants.NODE + ".p12"; + String DEFAULT_PEM_KEY_PATH = DIR_NODE + '/' + CmsConstants.NODE + ".key"; + String DEFAULT_PEM_CERT_PATH = DIR_NODE + '/' + CmsConstants.NODE + ".crt"; String NODE_KEY_TAB_PATH = DIR_NODE + "/krb5.keytab"; // Security diff --git a/org.argeo.cms.jcr/src/org/argeo/cms/jcr/internal/KernelUtils.java b/org.argeo.cms.jcr/src/org/argeo/cms/jcr/internal/KernelUtils.java index ed04518c0..edfe87a03 100644 --- a/org.argeo.cms.jcr/src/org/argeo/cms/jcr/internal/KernelUtils.java +++ b/org.argeo.cms.jcr/src/org/argeo/cms/jcr/internal/KernelUtils.java @@ -23,8 +23,8 @@ import javax.security.auth.Subject; import javax.security.auth.login.LoginContext; import javax.security.auth.login.LoginException; -import org.apache.commons.logging.Log; -import org.argeo.api.NodeConstants; +import org.argeo.api.cms.CmsAuth; +import org.argeo.api.cms.CmsLog; import org.argeo.cms.jcr.internal.osgi.CmsJcrActivator; import org.argeo.cms.osgi.DataModelNamespace; import org.osgi.framework.BundleContext; @@ -130,7 +130,7 @@ class KernelUtils implements KernelConstants { // } // } - static void logFrameworkProperties(Log log) { + static void logFrameworkProperties(CmsLog log) { BundleContext bc = getBundleContext(); for (Object sysProp : new TreeSet(System.getProperties().keySet())) { log.debug(sysProp + "=" + bc.getProperty(sysProp.toString())); @@ -185,7 +185,7 @@ class KernelUtils implements KernelConstants { Thread.currentThread().setContextClassLoader(KernelUtils.class.getClassLoader()); LoginContext loginContext; try { - loginContext = new LoginContext(NodeConstants.LOGIN_CONTEXT_DATA_ADMIN); + loginContext = new LoginContext(CmsAuth.LOGIN_CONTEXT_DATA_ADMIN); loginContext.login(); } catch (LoginException e1) { throw new IllegalStateException("Could not login as data admin", e1); diff --git a/org.argeo.cms.jcr/src/org/argeo/cms/jcr/internal/LocalRepository.java b/org.argeo.cms.jcr/src/org/argeo/cms/jcr/internal/LocalRepository.java index 0f95b09d9..0bac94cc0 100644 --- a/org.argeo.cms.jcr/src/org/argeo/cms/jcr/internal/LocalRepository.java +++ b/org.argeo.cms.jcr/src/org/argeo/cms/jcr/internal/LocalRepository.java @@ -2,7 +2,7 @@ package org.argeo.cms.jcr.internal; import javax.jcr.Repository; -import org.argeo.api.NodeConstants; +import org.argeo.api.cms.CmsConstants; import org.argeo.jcr.JcrRepositoryWrapper; class LocalRepository extends JcrRepositoryWrapper { @@ -13,7 +13,7 @@ class LocalRepository extends JcrRepositoryWrapper { this.cn = cn; // Map attrs = dataModelCapability.getAttributes(); // cn = (String) attrs.get(DataModelNamespace.NAME); - putDescriptor(NodeConstants.CN, cn); + putDescriptor(CmsConstants.CN, cn); } String getCn() { diff --git a/org.argeo.cms.jcr/src/org/argeo/cms/jcr/internal/NodeRepositoryFactory.java b/org.argeo.cms.jcr/src/org/argeo/cms/jcr/internal/NodeRepositoryFactory.java index f4feabb09..a4ab7cb23 100644 --- a/org.argeo.cms.jcr/src/org/argeo/cms/jcr/internal/NodeRepositoryFactory.java +++ b/org.argeo.cms.jcr/src/org/argeo/cms/jcr/internal/NodeRepositoryFactory.java @@ -10,10 +10,9 @@ import javax.jcr.Repository; import javax.jcr.RepositoryException; import javax.jcr.RepositoryFactory; -import org.apache.commons.logging.Log; -import org.apache.commons.logging.LogFactory; import org.apache.jackrabbit.jcr2dav.Jcr2davRepositoryFactory; -import org.argeo.api.NodeConstants; +import org.argeo.api.cms.CmsConstants; +import org.argeo.api.cms.CmsLog; import org.argeo.cms.internal.jcr.RepoConf; import org.argeo.cms.jcr.internal.osgi.CmsJcrActivator; import org.osgi.framework.BundleContext; @@ -25,7 +24,7 @@ import org.osgi.framework.ServiceReference; * {@link Repository} as OSGi services. */ public class NodeRepositoryFactory implements RepositoryFactory { - private final Log log = LogFactory.getLog(getClass()); + private final CmsLog log = CmsLog.getLog(getClass()); // private final BundleContext bundleContext = FrameworkUtil.getBundle(getClass()).getBundleContext(); // private Resource fileRepositoryConfiguration = new ClassPathResource( @@ -36,7 +35,7 @@ public class NodeRepositoryFactory implements RepositoryFactory { if (bundleContext != null) { try { Collection> srs = bundleContext.getServiceReferences(Repository.class, - "(" + NodeConstants.CN + "=" + alias + ")"); + "(" + CmsConstants.CN + "=" + alias + ")"); if (srs.size() == 0) throw new IllegalArgumentException("No repository with alias " + alias + " found in OSGi registry"); else if (srs.size() > 1) @@ -75,7 +74,7 @@ public class NodeRepositoryFactory implements RepositoryFactory { Repository repository; String uri = null; if (parameters.containsKey(RepoConf.labeledUri.name())) - uri = parameters.get(NodeConstants.LABELED_URI).toString(); + uri = parameters.get(CmsConstants.LABELED_URI).toString(); else if (parameters.containsKey(KernelConstants.JACKRABBIT_REPOSITORY_URI)) uri = parameters.get(KernelConstants.JACKRABBIT_REPOSITORY_URI).toString(); @@ -94,10 +93,10 @@ public class NodeRepositoryFactory implements RepositoryFactory { } - else if (parameters.containsKey(NodeConstants.CN)) { + else if (parameters.containsKey(CmsConstants.CN)) { // Properties properties = new Properties(); // properties.putAll(parameters); - String alias = parameters.get(NodeConstants.CN).toString(); + String alias = parameters.get(CmsConstants.CN).toString(); // publish(alias, repository, properties); // log.info("Registered JCR repository under alias '" + alias + "' // with properties " + properties); diff --git a/org.argeo.cms.jcr/src/org/argeo/cms/jcr/internal/RepositoryServiceFactory.java b/org.argeo.cms.jcr/src/org/argeo/cms/jcr/internal/RepositoryServiceFactory.java index 2a47d120c..042ddb5d5 100644 --- a/org.argeo.cms.jcr/src/org/argeo/cms/jcr/internal/RepositoryServiceFactory.java +++ b/org.argeo.cms.jcr/src/org/argeo/cms/jcr/internal/RepositoryServiceFactory.java @@ -8,10 +8,9 @@ import java.util.Map; import javax.jcr.Repository; import javax.jcr.RepositoryFactory; -import org.apache.commons.logging.Log; -import org.apache.commons.logging.LogFactory; import org.apache.jackrabbit.core.RepositoryContext; -import org.argeo.api.NodeConstants; +import org.argeo.api.cms.CmsConstants; +import org.argeo.api.cms.CmsLog; import org.argeo.cms.internal.jcr.RepoConf; import org.argeo.cms.internal.jcr.RepositoryBuilder; import org.argeo.cms.jcr.internal.osgi.CmsJcrActivator; @@ -22,7 +21,7 @@ import org.osgi.service.cm.ManagedServiceFactory; /** A {@link ManagedServiceFactory} creating or referencing JCR repositories. */ public class RepositoryServiceFactory implements ManagedServiceFactory { - private final static Log log = LogFactory.getLog(RepositoryServiceFactory.class); + private final static CmsLog log = CmsLog.getLog(RepositoryServiceFactory.class); // private final BundleContext bc = FrameworkUtil.getBundle(RepositoryServiceFactory.class).getBundleContext(); private Map repositories = new HashMap(); @@ -55,16 +54,16 @@ public class RepositoryServiceFactory implements ManagedServiceFactory { Dictionary props = LangUtils.dict(Constants.SERVICE_PID, pid); // props.put(ArgeoJcrConstants.JCR_REPOSITORY_URI, // properties.get(RepoConf.labeledUri.name())); - Object cn = properties.get(NodeConstants.CN); + Object cn = properties.get(CmsConstants.CN); if (cn != null) { - props.put(NodeConstants.CN, cn); + props.put(CmsConstants.CN, cn); // props.put(NodeConstants.JCR_REPOSITORY_ALIAS, cn); pidToCn.put(pid, cn); } CmsJcrActivator.registerService(RepositoryContext.class, repositoryContext, props); } else { try { - Object cn = properties.get(NodeConstants.CN); + Object cn = properties.get(CmsConstants.CN); Object defaultWorkspace = properties.get(RepoConf.defaultWorkspace.name()); if (defaultWorkspace == null) defaultWorkspace = RepoConf.defaultWorkspace.getDefault(); @@ -83,16 +82,16 @@ public class RepositoryServiceFactory implements ManagedServiceFactory { new URI(uri.getScheme(), null, uri.getHost(), uri.getPort(), uri.getPath(), null, null) .toString()); if (cn != null) { - props.put(NodeConstants.CN, cn); + props.put(CmsConstants.CN, cn); // props.put(NodeConstants.JCR_REPOSITORY_ALIAS, cn); pidToCn.put(pid, cn); } CmsJcrActivator.registerService(Repository.class, repository, props); // home - if (cn.equals(NodeConstants.NODE_REPOSITORY)) { - Dictionary homeProps = LangUtils.dict(NodeConstants.CN, - NodeConstants.EGO_REPOSITORY); + if (cn.equals(CmsConstants.NODE_REPOSITORY)) { + Dictionary homeProps = LangUtils.dict(CmsConstants.CN, + CmsConstants.EGO_REPOSITORY); EgoRepository homeRepository = new EgoRepository(repository, true); CmsJcrActivator.registerService(Repository.class, homeRepository, homeProps); } diff --git a/org.argeo.cms.jcr/src/org/argeo/cms/jcr/internal/StatisticsThread.java b/org.argeo.cms.jcr/src/org/argeo/cms/jcr/internal/StatisticsThread.java index b5ec05005..5a2cd5b7b 100644 --- a/org.argeo.cms.jcr/src/org/argeo/cms/jcr/internal/StatisticsThread.java +++ b/org.argeo.cms.jcr/src/org/argeo/cms/jcr/internal/StatisticsThread.java @@ -3,17 +3,16 @@ package org.argeo.cms.jcr.internal; import java.io.File; import java.lang.management.ManagementFactory; -import org.apache.commons.logging.Log; -import org.apache.commons.logging.LogFactory; import org.apache.jackrabbit.api.stats.RepositoryStatistics; import org.apache.jackrabbit.stats.RepositoryStatisticsImpl; +import org.argeo.api.cms.CmsLog; /** * Background thread started by the kernel, which gather statistics and * monitor/control other processes. */ public class StatisticsThread extends Thread { - private final static Log log = LogFactory.getLog(StatisticsThread.class); + private final static CmsLog log = CmsLog.getLog(StatisticsThread.class); private RepositoryStatisticsImpl repoStats; @@ -25,8 +24,8 @@ public class StatisticsThread extends Thread { private boolean running = true; - private Log kernelStatsLog = LogFactory.getLog("argeo.stats.kernel"); - private Log nodeStatsLog = LogFactory.getLog("argeo.stats.node"); + private CmsLog kernelStatsLog = CmsLog.getLog("argeo.stats.kernel"); + private CmsLog nodeStatsLog = CmsLog.getLog("argeo.stats.node"); @SuppressWarnings("unused") private long cycle = 0l; diff --git a/org.argeo.cms.jcr/src/org/argeo/cms/jcr/internal/osgi/CmsJcrActivator.java b/org.argeo.cms.jcr/src/org/argeo/cms/jcr/internal/osgi/CmsJcrActivator.java index 1fb81b717..677fc73da 100644 --- a/org.argeo.cms.jcr/src/org/argeo/cms/jcr/internal/osgi/CmsJcrActivator.java +++ b/org.argeo.cms.jcr/src/org/argeo/cms/jcr/internal/osgi/CmsJcrActivator.java @@ -7,7 +7,7 @@ import java.util.List; import javax.jcr.RepositoryFactory; -import org.argeo.api.NodeConstants; +import org.argeo.api.cms.CmsConstants; import org.argeo.cms.jcr.internal.CmsFsProvider; import org.argeo.cms.jcr.internal.StatisticsThread; import org.argeo.cms.jcr.internal.NodeRepositoryFactory; @@ -46,7 +46,7 @@ public class CmsJcrActivator implements BundleActivator { repositoryServiceFactory = new RepositoryServiceFactory(); // stopHooks.add(() -> repositoryServiceFactory.shutdown()); registerService(ManagedServiceFactory.class, repositoryServiceFactory, - LangUtils.dict(Constants.SERVICE_PID, NodeConstants.NODE_REPOS_FACTORY_PID)); + LangUtils.dict(Constants.SERVICE_PID, CmsConstants.NODE_REPOS_FACTORY_PID)); NodeRepositoryFactory repositoryFactory = new NodeRepositoryFactory(); registerService(RepositoryFactory.class, repositoryFactory, null); @@ -64,7 +64,7 @@ public class CmsJcrActivator implements BundleActivator { // log.debug("Installed FileSystemProvider " + fsp); // } registerService(FileSystemProvider.class, cmsFsProvider, - LangUtils.dict(Constants.SERVICE_PID, NodeConstants.NODE_FS_PROVIDER_PID)); + LangUtils.dict(Constants.SERVICE_PID, CmsConstants.NODE_FS_PROVIDER_PID)); // jcrDeployment = new JcrDeployment(); // jcrDeployment.init(); diff --git a/org.argeo.cms.jcr/src/org/argeo/cms/jcr/internal/servlet/CmsRemotingServlet.java b/org.argeo.cms.jcr/src/org/argeo/cms/jcr/internal/servlet/CmsRemotingServlet.java index 929620315..fa3f87f67 100644 --- a/org.argeo.cms.jcr/src/org/argeo/cms/jcr/internal/servlet/CmsRemotingServlet.java +++ b/org.argeo.cms.jcr/src/org/argeo/cms/jcr/internal/servlet/CmsRemotingServlet.java @@ -6,7 +6,7 @@ import javax.jcr.Repository; import org.apache.jackrabbit.server.SessionProvider; import org.apache.jackrabbit.server.remoting.davex.JcrRemotingServlet; -import org.argeo.api.NodeConstants; +import org.argeo.api.cms.CmsConstants; /** A {@link JcrRemotingServlet} based on {@link CmsSessionProvider}. */ public class CmsRemotingServlet extends JcrRemotingServlet { @@ -29,7 +29,7 @@ public class CmsRemotingServlet extends JcrRemotingServlet { public void setRepository(Repository repository, Map properties) { this.repository = repository; - String alias = properties.get(NodeConstants.CN); + String alias = properties.get(CmsConstants.CN); if (alias != null) sessionProvider = new CmsSessionProvider(alias); else diff --git a/org.argeo.cms.jcr/src/org/argeo/cms/jcr/internal/servlet/CmsSessionProvider.java b/org.argeo.cms.jcr/src/org/argeo/cms/jcr/internal/servlet/CmsSessionProvider.java index 45ca33855..0f27fd005 100644 --- a/org.argeo.cms.jcr/src/org/argeo/cms/jcr/internal/servlet/CmsSessionProvider.java +++ b/org.argeo.cms.jcr/src/org/argeo/cms/jcr/internal/servlet/CmsSessionProvider.java @@ -16,11 +16,10 @@ import javax.security.auth.Subject; import javax.servlet.ServletException; import javax.servlet.http.HttpServletRequest; -import org.apache.commons.logging.Log; -import org.apache.commons.logging.LogFactory; import org.apache.jackrabbit.server.SessionProvider; -import org.argeo.api.NodeConstants; import org.argeo.api.cms.CmsSession; +import org.argeo.api.cms.CmsLog; +import org.argeo.api.cms.CmsConstants; import org.argeo.jcr.JcrUtils; /** @@ -30,7 +29,7 @@ import org.argeo.jcr.JcrUtils; public class CmsSessionProvider implements SessionProvider, Serializable { private static final long serialVersionUID = -1358136599534938466L; - private final static Log log = LogFactory.getLog(CmsSessionProvider.class); + private final static CmsLog log = CmsLog.getLog(CmsSessionProvider.class); private final String alias; @@ -92,7 +91,7 @@ public class CmsSessionProvider implements SessionProvider, Serializable { checkValid(); // FIXME make it more robust if (workspace == null) - workspace = NodeConstants.SYS_WORKSPACE; + workspace = CmsConstants.SYS_WORKSPACE; String path = cn + '/' + workspace; if (dataSessionsInUse.contains(path)) { try { diff --git a/org.argeo.cms.jcr/src/org/argeo/cms/jcr/internal/servlet/CmsWebDavServlet.java b/org.argeo.cms.jcr/src/org/argeo/cms/jcr/internal/servlet/CmsWebDavServlet.java index 1557c4bc1..0f0858f51 100644 --- a/org.argeo.cms.jcr/src/org/argeo/cms/jcr/internal/servlet/CmsWebDavServlet.java +++ b/org.argeo.cms.jcr/src/org/argeo/cms/jcr/internal/servlet/CmsWebDavServlet.java @@ -5,7 +5,7 @@ import java.util.Map; import javax.jcr.Repository; import org.apache.jackrabbit.webdav.simple.SimpleWebdavServlet; -import org.argeo.api.NodeConstants; +import org.argeo.api.cms.CmsConstants; /** A {@link SimpleWebdavServlet} based on {@link CmsSessionProvider}. */ public class CmsWebDavServlet extends SimpleWebdavServlet { @@ -27,7 +27,7 @@ public class CmsWebDavServlet extends SimpleWebdavServlet { public void setRepository(Repository repository, Map properties) { this.repository = repository; - String alias = properties.get(NodeConstants.CN); + String alias = properties.get(CmsConstants.CN); if (alias != null) setSessionProvider(new CmsSessionProvider(alias)); else diff --git a/org.argeo.cms.jcr/src/org/argeo/cms/jcr/internal/servlet/JcrHttpUtils.java b/org.argeo.cms.jcr/src/org/argeo/cms/jcr/internal/servlet/JcrHttpUtils.java index c2746126a..11e903db8 100644 --- a/org.argeo.cms.jcr/src/org/argeo/cms/jcr/internal/servlet/JcrHttpUtils.java +++ b/org.argeo.cms.jcr/src/org/argeo/cms/jcr/internal/servlet/JcrHttpUtils.java @@ -5,7 +5,7 @@ import java.util.Enumeration; import javax.servlet.http.HttpServletRequest; import javax.servlet.http.HttpServletResponse; -import org.apache.commons.logging.Log; +import org.argeo.api.cms.CmsLog; public class JcrHttpUtils { public final static String HEADER_AUTHORIZATION = "Authorization"; @@ -20,7 +20,7 @@ public class JcrHttpUtils { || userAgent.contains("opera") || userAgent.contains("browser"); } - public static void logResponseHeaders(Log log, HttpServletResponse response) { + public static void logResponseHeaders(CmsLog log, HttpServletResponse response) { if (!log.isDebugEnabled()) return; for (String headerName : response.getHeaderNames()) { @@ -29,7 +29,7 @@ public class JcrHttpUtils { } } - public static void logRequestHeaders(Log log, HttpServletRequest request) { + public static void logRequestHeaders(CmsLog log, HttpServletRequest request) { if (!log.isDebugEnabled()) return; for (Enumeration headerNames = request.getHeaderNames(); headerNames.hasMoreElements();) { @@ -40,7 +40,7 @@ public class JcrHttpUtils { log.debug(request.getRequestURI() + "\n"); } - public static void logRequest(Log log, HttpServletRequest request) { + public static void logRequest(CmsLog log, HttpServletRequest request) { log.debug("contextPath=" + request.getContextPath()); log.debug("servletPath=" + request.getServletPath()); log.debug("requestURI=" + request.getRequestURI()); diff --git a/org.argeo.cms.jcr/src/org/argeo/cms/jcr/internal/servlet/LinkServlet.java b/org.argeo.cms.jcr/src/org/argeo/cms/jcr/internal/servlet/LinkServlet.java index feaa00f30..62cdc5f6b 100644 --- a/org.argeo.cms.jcr/src/org/argeo/cms/jcr/internal/servlet/LinkServlet.java +++ b/org.argeo.cms.jcr/src/org/argeo/cms/jcr/internal/servlet/LinkServlet.java @@ -25,7 +25,8 @@ import javax.servlet.http.HttpServlet; import javax.servlet.http.HttpServletRequest; import javax.servlet.http.HttpServletResponse; -import org.argeo.api.NodeConstants; +import org.argeo.api.cms.CmsAuth; +import org.argeo.api.cms.CmsConstants; import org.argeo.cms.CmsException; import org.argeo.cms.jcr.CmsJcrUtils; import org.argeo.jcr.JcrUtils; @@ -88,7 +89,7 @@ public class LinkServlet extends HttpServlet { @Override public Session run() throws Exception { Collection> srs = bc.getServiceReferences(Repository.class, - "(" + NodeConstants.CN + "=" + NodeConstants.EGO_REPOSITORY + ")"); + "(" + CmsConstants.CN + "=" + CmsConstants.EGO_REPOSITORY + ")"); Repository repository = bc.getService(srs.iterator().next()); return repository.login(); } @@ -196,7 +197,7 @@ public class LinkServlet extends HttpServlet { private String getDataUrl(Node node, HttpServletRequest request) throws RepositoryException { try { StringBuilder buf = getServerBaseUrl(request); - buf.append(CmsJcrUtils.getDataPath(NodeConstants.EGO_REPOSITORY, node)); + buf.append(CmsJcrUtils.getDataPath(CmsConstants.EGO_REPOSITORY, node)); return new URL(buf.toString()).toString(); } catch (MalformedURLException e) { throw new CmsException("Cannot build data URL for " + node, e); @@ -247,7 +248,7 @@ public class LinkServlet extends HttpServlet { Subject subject = new Subject(); LoginContext lc; try { - lc = new LoginContext(NodeConstants.LOGIN_CONTEXT_ANONYMOUS, subject); + lc = new LoginContext(CmsAuth.LOGIN_CONTEXT_ANONYMOUS, subject); lc.login(); return subject; } catch (LoginException e) { diff --git a/org.argeo.cms.jcr/src/org/argeo/cms/jcr/tabular/CsvTabularWriter.java b/org.argeo.cms.jcr/src/org/argeo/cms/jcr/tabular/CsvTabularWriter.java new file mode 100644 index 000000000..ccd543f4d --- /dev/null +++ b/org.argeo.cms.jcr/src/org/argeo/cms/jcr/tabular/CsvTabularWriter.java @@ -0,0 +1,23 @@ +package org.argeo.cms.jcr.tabular; + +import java.io.OutputStream; + +import org.argeo.cms.tabular.TabularWriter; +import org.argeo.util.CsvWriter; + +/** Write tabular content in a stream as CSV. Wraps a {@link CsvWriter}. */ +public class CsvTabularWriter implements TabularWriter { + private CsvWriter csvWriter; + + public CsvTabularWriter(OutputStream out) { + this.csvWriter = new CsvWriter(out); + } + + public void appendRow(Object[] row) { + csvWriter.writeLine(row); + } + + public void close() { + } + +} diff --git a/org.argeo.cms.jcr/src/org/argeo/cms/jcr/tabular/JcrTabularRowIterator.java b/org.argeo.cms.jcr/src/org/argeo/cms/jcr/tabular/JcrTabularRowIterator.java new file mode 100644 index 000000000..d1d9b583b --- /dev/null +++ b/org.argeo.cms.jcr/src/org/argeo/cms/jcr/tabular/JcrTabularRowIterator.java @@ -0,0 +1,170 @@ +package org.argeo.cms.jcr.tabular; + +import java.io.InputStream; +import java.util.ArrayList; +import java.util.List; +import java.util.concurrent.ArrayBlockingQueue; + +import javax.jcr.Binary; +import javax.jcr.Node; +import javax.jcr.NodeIterator; +import javax.jcr.Property; +import javax.jcr.PropertyType; +import javax.jcr.RepositoryException; + +import org.apache.commons.io.IOUtils; +import org.argeo.cms.ArgeoTypes; +import org.argeo.cms.tabular.ArrayTabularRow; +import org.argeo.cms.tabular.TabularColumn; +import org.argeo.cms.tabular.TabularRow; +import org.argeo.cms.tabular.TabularRowIterator; +import org.argeo.jcr.JcrException; +import org.argeo.util.CsvParser; + +/** Iterates over the rows of a {@link ArgeoTypes#ARGEO_TABLE} node. */ +public class JcrTabularRowIterator implements TabularRowIterator { + private Boolean hasNext = null; + private Boolean parsingCompleted = false; + + private Long currentRowNumber = 0l; + + private List header = new ArrayList(); + + /** referenced so that we can close it */ + private Binary binary; + private InputStream in; + + private CsvParser csvParser; + private ArrayBlockingQueue> textLines; + + public JcrTabularRowIterator(Node tableNode) { + try { + for (NodeIterator it = tableNode.getNodes(); it.hasNext();) { + Node node = it.nextNode(); + if (node.isNodeType(ArgeoTypes.ARGEO_COLUMN)) { + Integer type = PropertyType.valueFromName(node.getProperty( + Property.JCR_REQUIRED_TYPE).getString()); + TabularColumn tc = new TabularColumn(node.getProperty( + Property.JCR_TITLE).getString(), type); + header.add(tc); + } + } + Node contentNode = tableNode.getNode(Property.JCR_CONTENT); + if (contentNode.isNodeType(ArgeoTypes.ARGEO_CSV)) { + textLines = new ArrayBlockingQueue>(1000); + csvParser = new CsvParser() { + protected void processLine(Integer lineNumber, + List header, List tokens) { + try { + textLines.put(tokens); + } catch (InterruptedException e) { + // TODO Auto-generated catch block + e.printStackTrace(); + } + // textLines.add(tokens); + if (hasNext == null) { + hasNext = true; + synchronized (JcrTabularRowIterator.this) { + JcrTabularRowIterator.this.notifyAll(); + } + } + } + }; + csvParser.setNoHeader(true); + binary = contentNode.getProperty(Property.JCR_DATA).getBinary(); + in = binary.getStream(); + Thread thread = new Thread(contentNode.getPath() + " reader") { + public void run() { + try { + csvParser.parse(in); + } finally { + parsingCompleted = true; + IOUtils.closeQuietly(in); + } + } + }; + thread.start(); + } + } catch (RepositoryException e) { + throw new JcrException("Cannot read table " + tableNode, e); + } + } + + public synchronized boolean hasNext() { + // we don't know if there is anything available + // while (hasNext == null) + // try { + // wait(); + // } catch (InterruptedException e) { + // // silent + // // FIXME better deal with interruption + // Thread.currentThread().interrupt(); + // break; + // } + + // buffer not empty + if (!textLines.isEmpty()) + return true; + + // maybe the parsing is finished but the flag has not been set + while (!parsingCompleted && textLines.isEmpty()) + try { + wait(100); + } catch (InterruptedException e) { + // silent + // FIXME better deal with interruption + Thread.currentThread().interrupt(); + break; + } + + // buffer not empty + if (!textLines.isEmpty()) + return true; + + // (parsingCompleted && textLines.isEmpty()) + return false; + + // if (!hasNext && textLines.isEmpty()) { + // if (in != null) { + // IOUtils.closeQuietly(in); + // in = null; + // } + // if (binary != null) { + // JcrUtils.closeQuietly(binary); + // binary = null; + // } + // return false; + // } else + // return true; + } + + public synchronized TabularRow next() { + try { + List tokens = textLines.take(); + List objs = new ArrayList(tokens.size()); + for (String token : tokens) { + // TODO convert to other formats using header + objs.add(token); + } + currentRowNumber++; + return new ArrayTabularRow(objs); + } catch (InterruptedException e) { + // silent + // FIXME better deal with interruption + } + return null; + } + + public void remove() { + throw new UnsupportedOperationException(); + } + + public Long getCurrentRowNumber() { + return currentRowNumber; + } + + public List getHeader() { + return header; + } + +} diff --git a/org.argeo.cms.jcr/src/org/argeo/cms/jcr/tabular/JcrTabularWriter.java b/org.argeo.cms.jcr/src/org/argeo/cms/jcr/tabular/JcrTabularWriter.java new file mode 100644 index 000000000..cc3e0d7a9 --- /dev/null +++ b/org.argeo.cms.jcr/src/org/argeo/cms/jcr/tabular/JcrTabularWriter.java @@ -0,0 +1,82 @@ +package org.argeo.cms.jcr.tabular; + +import java.io.ByteArrayInputStream; +import java.io.ByteArrayOutputStream; +import java.io.InputStream; +import java.util.List; + +import javax.jcr.Binary; +import javax.jcr.Node; +import javax.jcr.Property; +import javax.jcr.PropertyType; +import javax.jcr.RepositoryException; + +import org.apache.commons.io.IOUtils; +import org.argeo.cms.ArgeoTypes; +import org.argeo.cms.tabular.TabularColumn; +import org.argeo.cms.tabular.TabularWriter; +import org.argeo.jcr.JcrException; +import org.argeo.jcr.JcrUtils; +import org.argeo.util.CsvWriter; + +/** Write / reference tabular content in a JCR repository. */ +public class JcrTabularWriter implements TabularWriter { + private Node contentNode; + private ByteArrayOutputStream out; + private CsvWriter csvWriter; + + @SuppressWarnings("unused") + private final List columns; + + /** Creates a table node */ + public JcrTabularWriter(Node tableNode, List columns, + String contentNodeType) { + try { + this.columns = columns; + for (TabularColumn column : columns) { + String normalized = JcrUtils.replaceInvalidChars(column + .getName()); + Node columnNode = tableNode.addNode(normalized, + ArgeoTypes.ARGEO_COLUMN); + columnNode.setProperty(Property.JCR_TITLE, column.getName()); + if (column.getType() != null) + columnNode.setProperty(Property.JCR_REQUIRED_TYPE, + PropertyType.nameFromValue(column.getType())); + else + columnNode.setProperty(Property.JCR_REQUIRED_TYPE, + PropertyType.TYPENAME_STRING); + } + contentNode = tableNode.addNode(Property.JCR_CONTENT, + contentNodeType); + if (contentNodeType.equals(ArgeoTypes.ARGEO_CSV)) { + contentNode.setProperty(Property.JCR_MIMETYPE, "text/csv"); + contentNode.setProperty(Property.JCR_ENCODING, "UTF-8"); + out = new ByteArrayOutputStream(); + csvWriter = new CsvWriter(out); + } + } catch (RepositoryException e) { + throw new JcrException("Cannot create table node " + tableNode, e); + } + } + + public void appendRow(Object[] row) { + csvWriter.writeLine(row); + } + + public void close() { + Binary binary = null; + InputStream in = null; + try { + // TODO parallelize with pipes and writing from another thread + in = new ByteArrayInputStream(out.toByteArray()); + binary = contentNode.getSession().getValueFactory() + .createBinary(in); + contentNode.setProperty(Property.JCR_DATA, binary); + } catch (RepositoryException e) { + throw new JcrException("Cannot store data in " + contentNode, e); + } finally { + IOUtils.closeQuietly(in); + JcrUtils.closeQuietly(binary); + } + } +} diff --git a/org.argeo.cms.jcr/src/org/argeo/cms/jcr/tabular/package-info.java b/org.argeo.cms.jcr/src/org/argeo/cms/jcr/tabular/package-info.java new file mode 100644 index 000000000..506a6ac98 --- /dev/null +++ b/org.argeo.cms.jcr/src/org/argeo/cms/jcr/tabular/package-info.java @@ -0,0 +1,2 @@ +/** Argeo CMS implementation of the Argeo Tabular API (CSV, JCR). */ +package org.argeo.cms.jcr.tabular; \ No newline at end of file diff --git a/org.argeo.cms.jcr/src/org/argeo/cms/tabular/CsvTabularWriter.java b/org.argeo.cms.jcr/src/org/argeo/cms/tabular/CsvTabularWriter.java deleted file mode 100644 index 6f78672d5..000000000 --- a/org.argeo.cms.jcr/src/org/argeo/cms/tabular/CsvTabularWriter.java +++ /dev/null @@ -1,23 +0,0 @@ -package org.argeo.cms.tabular; - -import java.io.OutputStream; - -import org.argeo.api.tabular.TabularWriter; -import org.argeo.util.CsvWriter; - -/** Write tabular content in a stream as CSV. Wraps a {@link CsvWriter}. */ -public class CsvTabularWriter implements TabularWriter { - private CsvWriter csvWriter; - - public CsvTabularWriter(OutputStream out) { - this.csvWriter = new CsvWriter(out); - } - - public void appendRow(Object[] row) { - csvWriter.writeLine(row); - } - - public void close() { - } - -} diff --git a/org.argeo.cms.jcr/src/org/argeo/cms/tabular/JcrTabularRowIterator.java b/org.argeo.cms.jcr/src/org/argeo/cms/tabular/JcrTabularRowIterator.java deleted file mode 100644 index 23bc8e83d..000000000 --- a/org.argeo.cms.jcr/src/org/argeo/cms/tabular/JcrTabularRowIterator.java +++ /dev/null @@ -1,170 +0,0 @@ -package org.argeo.cms.tabular; - -import java.io.InputStream; -import java.util.ArrayList; -import java.util.List; -import java.util.concurrent.ArrayBlockingQueue; - -import javax.jcr.Binary; -import javax.jcr.Node; -import javax.jcr.NodeIterator; -import javax.jcr.Property; -import javax.jcr.PropertyType; -import javax.jcr.RepositoryException; - -import org.apache.commons.io.IOUtils; -import org.argeo.api.tabular.ArrayTabularRow; -import org.argeo.api.tabular.TabularColumn; -import org.argeo.api.tabular.TabularRow; -import org.argeo.api.tabular.TabularRowIterator; -import org.argeo.cms.ArgeoTypes; -import org.argeo.jcr.JcrException; -import org.argeo.util.CsvParser; - -/** Iterates over the rows of a {@link ArgeoTypes#ARGEO_TABLE} node. */ -public class JcrTabularRowIterator implements TabularRowIterator { - private Boolean hasNext = null; - private Boolean parsingCompleted = false; - - private Long currentRowNumber = 0l; - - private List header = new ArrayList(); - - /** referenced so that we can close it */ - private Binary binary; - private InputStream in; - - private CsvParser csvParser; - private ArrayBlockingQueue> textLines; - - public JcrTabularRowIterator(Node tableNode) { - try { - for (NodeIterator it = tableNode.getNodes(); it.hasNext();) { - Node node = it.nextNode(); - if (node.isNodeType(ArgeoTypes.ARGEO_COLUMN)) { - Integer type = PropertyType.valueFromName(node.getProperty( - Property.JCR_REQUIRED_TYPE).getString()); - TabularColumn tc = new TabularColumn(node.getProperty( - Property.JCR_TITLE).getString(), type); - header.add(tc); - } - } - Node contentNode = tableNode.getNode(Property.JCR_CONTENT); - if (contentNode.isNodeType(ArgeoTypes.ARGEO_CSV)) { - textLines = new ArrayBlockingQueue>(1000); - csvParser = new CsvParser() { - protected void processLine(Integer lineNumber, - List header, List tokens) { - try { - textLines.put(tokens); - } catch (InterruptedException e) { - // TODO Auto-generated catch block - e.printStackTrace(); - } - // textLines.add(tokens); - if (hasNext == null) { - hasNext = true; - synchronized (JcrTabularRowIterator.this) { - JcrTabularRowIterator.this.notifyAll(); - } - } - } - }; - csvParser.setNoHeader(true); - binary = contentNode.getProperty(Property.JCR_DATA).getBinary(); - in = binary.getStream(); - Thread thread = new Thread(contentNode.getPath() + " reader") { - public void run() { - try { - csvParser.parse(in); - } finally { - parsingCompleted = true; - IOUtils.closeQuietly(in); - } - } - }; - thread.start(); - } - } catch (RepositoryException e) { - throw new JcrException("Cannot read table " + tableNode, e); - } - } - - public synchronized boolean hasNext() { - // we don't know if there is anything available - // while (hasNext == null) - // try { - // wait(); - // } catch (InterruptedException e) { - // // silent - // // FIXME better deal with interruption - // Thread.currentThread().interrupt(); - // break; - // } - - // buffer not empty - if (!textLines.isEmpty()) - return true; - - // maybe the parsing is finished but the flag has not been set - while (!parsingCompleted && textLines.isEmpty()) - try { - wait(100); - } catch (InterruptedException e) { - // silent - // FIXME better deal with interruption - Thread.currentThread().interrupt(); - break; - } - - // buffer not empty - if (!textLines.isEmpty()) - return true; - - // (parsingCompleted && textLines.isEmpty()) - return false; - - // if (!hasNext && textLines.isEmpty()) { - // if (in != null) { - // IOUtils.closeQuietly(in); - // in = null; - // } - // if (binary != null) { - // JcrUtils.closeQuietly(binary); - // binary = null; - // } - // return false; - // } else - // return true; - } - - public synchronized TabularRow next() { - try { - List tokens = textLines.take(); - List objs = new ArrayList(tokens.size()); - for (String token : tokens) { - // TODO convert to other formats using header - objs.add(token); - } - currentRowNumber++; - return new ArrayTabularRow(objs); - } catch (InterruptedException e) { - // silent - // FIXME better deal with interruption - } - return null; - } - - public void remove() { - throw new UnsupportedOperationException(); - } - - public Long getCurrentRowNumber() { - return currentRowNumber; - } - - public List getHeader() { - return header; - } - -} diff --git a/org.argeo.cms.jcr/src/org/argeo/cms/tabular/JcrTabularWriter.java b/org.argeo.cms.jcr/src/org/argeo/cms/tabular/JcrTabularWriter.java deleted file mode 100644 index 29933cd75..000000000 --- a/org.argeo.cms.jcr/src/org/argeo/cms/tabular/JcrTabularWriter.java +++ /dev/null @@ -1,82 +0,0 @@ -package org.argeo.cms.tabular; - -import java.io.ByteArrayInputStream; -import java.io.ByteArrayOutputStream; -import java.io.InputStream; -import java.util.List; - -import javax.jcr.Binary; -import javax.jcr.Node; -import javax.jcr.Property; -import javax.jcr.PropertyType; -import javax.jcr.RepositoryException; - -import org.apache.commons.io.IOUtils; -import org.argeo.api.tabular.TabularColumn; -import org.argeo.api.tabular.TabularWriter; -import org.argeo.cms.ArgeoTypes; -import org.argeo.jcr.JcrException; -import org.argeo.jcr.JcrUtils; -import org.argeo.util.CsvWriter; - -/** Write / reference tabular content in a JCR repository. */ -public class JcrTabularWriter implements TabularWriter { - private Node contentNode; - private ByteArrayOutputStream out; - private CsvWriter csvWriter; - - @SuppressWarnings("unused") - private final List columns; - - /** Creates a table node */ - public JcrTabularWriter(Node tableNode, List columns, - String contentNodeType) { - try { - this.columns = columns; - for (TabularColumn column : columns) { - String normalized = JcrUtils.replaceInvalidChars(column - .getName()); - Node columnNode = tableNode.addNode(normalized, - ArgeoTypes.ARGEO_COLUMN); - columnNode.setProperty(Property.JCR_TITLE, column.getName()); - if (column.getType() != null) - columnNode.setProperty(Property.JCR_REQUIRED_TYPE, - PropertyType.nameFromValue(column.getType())); - else - columnNode.setProperty(Property.JCR_REQUIRED_TYPE, - PropertyType.TYPENAME_STRING); - } - contentNode = tableNode.addNode(Property.JCR_CONTENT, - contentNodeType); - if (contentNodeType.equals(ArgeoTypes.ARGEO_CSV)) { - contentNode.setProperty(Property.JCR_MIMETYPE, "text/csv"); - contentNode.setProperty(Property.JCR_ENCODING, "UTF-8"); - out = new ByteArrayOutputStream(); - csvWriter = new CsvWriter(out); - } - } catch (RepositoryException e) { - throw new JcrException("Cannot create table node " + tableNode, e); - } - } - - public void appendRow(Object[] row) { - csvWriter.writeLine(row); - } - - public void close() { - Binary binary = null; - InputStream in = null; - try { - // TODO parallelize with pipes and writing from another thread - in = new ByteArrayInputStream(out.toByteArray()); - binary = contentNode.getSession().getValueFactory() - .createBinary(in); - contentNode.setProperty(Property.JCR_DATA, binary); - } catch (RepositoryException e) { - throw new JcrException("Cannot store data in " + contentNode, e); - } finally { - IOUtils.closeQuietly(in); - JcrUtils.closeQuietly(binary); - } - } -} diff --git a/org.argeo.cms.jcr/src/org/argeo/cms/tabular/package-info.java b/org.argeo.cms.jcr/src/org/argeo/cms/tabular/package-info.java deleted file mode 100644 index a95d86604..000000000 --- a/org.argeo.cms.jcr/src/org/argeo/cms/tabular/package-info.java +++ /dev/null @@ -1,2 +0,0 @@ -/** Argeo CMS implementation of the Argeo Tabular API (CSV, JCR). */ -package org.argeo.cms.tabular; \ No newline at end of file diff --git a/org.argeo.cms.jcr/src/org/argeo/jackrabbit/JackrabbitDataModelMigration.java b/org.argeo.cms.jcr/src/org/argeo/jackrabbit/JackrabbitDataModelMigration.java index 1a4c8a3ca..8c267e314 100644 --- a/org.argeo.cms.jcr/src/org/argeo/jackrabbit/JackrabbitDataModelMigration.java +++ b/org.argeo.cms.jcr/src/org/argeo/jackrabbit/JackrabbitDataModelMigration.java @@ -9,12 +9,11 @@ import javax.jcr.RepositoryException; import javax.jcr.Session; import org.apache.commons.io.IOUtils; -import org.apache.commons.logging.Log; -import org.apache.commons.logging.LogFactory; import org.apache.jackrabbit.commons.cnd.CndImporter; import org.apache.jackrabbit.commons.cnd.ParseException; import org.apache.jackrabbit.core.config.RepositoryConfig; import org.apache.jackrabbit.core.fs.FileSystemException; +import org.argeo.api.cms.CmsLog; import org.argeo.jcr.JcrCallback; import org.argeo.jcr.JcrException; import org.argeo.jcr.JcrUtils; @@ -22,7 +21,7 @@ import org.argeo.jcr.JcrUtils; /** Migrate the data in a Jackrabbit repository. */ @Deprecated public class JackrabbitDataModelMigration implements Comparable { - private final static Log log = LogFactory.getLog(JackrabbitDataModelMigration.class); + private final static CmsLog log = CmsLog.getLog(JackrabbitDataModelMigration.class); private String dataModelNodePath; private String targetVersion; diff --git a/org.argeo.cms.jcr/src/org/argeo/jackrabbit/security/JackrabbitSecurityUtils.java b/org.argeo.cms.jcr/src/org/argeo/jackrabbit/security/JackrabbitSecurityUtils.java index a75c79541..f98cf9947 100644 --- a/org.argeo.cms.jcr/src/org/argeo/jackrabbit/security/JackrabbitSecurityUtils.java +++ b/org.argeo.cms.jcr/src/org/argeo/jackrabbit/security/JackrabbitSecurityUtils.java @@ -8,15 +8,14 @@ import javax.jcr.RepositoryException; import javax.jcr.Session; import javax.jcr.security.Privilege; -import org.apache.commons.logging.Log; -import org.apache.commons.logging.LogFactory; import org.apache.jackrabbit.api.security.JackrabbitAccessControlList; import org.apache.jackrabbit.api.security.JackrabbitAccessControlManager; +import org.argeo.api.cms.CmsLog; import org.argeo.jcr.JcrUtils; /** Utilities around Jackrabbit security extensions. */ public class JackrabbitSecurityUtils { - private final static Log log = LogFactory.getLog(JackrabbitSecurityUtils.class); + private final static CmsLog log = CmsLog.getLog(JackrabbitSecurityUtils.class); /** * Convenience method for denying a single privilege to a principal (user or diff --git a/org.argeo.cms.jcr/src/org/argeo/jcr/DefaultJcrListener.java b/org.argeo.cms.jcr/src/org/argeo/jcr/DefaultJcrListener.java index fc6888851..d873ef652 100644 --- a/org.argeo.cms.jcr/src/org/argeo/jcr/DefaultJcrListener.java +++ b/org.argeo.cms.jcr/src/org/argeo/jcr/DefaultJcrListener.java @@ -7,12 +7,11 @@ import javax.jcr.observation.EventIterator; import javax.jcr.observation.EventListener; import javax.jcr.observation.ObservationManager; -import org.apache.commons.logging.Log; -import org.apache.commons.logging.LogFactory; +import org.argeo.api.cms.CmsLog; /** To be overridden */ public class DefaultJcrListener implements EventListener { - private final static Log log = LogFactory.getLog(DefaultJcrListener.class); + private final static CmsLog log = CmsLog.getLog(DefaultJcrListener.class); private Session session; private String path = "/"; private Boolean deep = true; diff --git a/org.argeo.cms.jcr/src/org/argeo/jcr/ThreadBoundJcrSessionFactory.java b/org.argeo.cms.jcr/src/org/argeo/jcr/ThreadBoundJcrSessionFactory.java index 1e23338b5..2208627ab 100644 --- a/org.argeo.cms.jcr/src/org/argeo/jcr/ThreadBoundJcrSessionFactory.java +++ b/org.argeo.cms.jcr/src/org/argeo/jcr/ThreadBoundJcrSessionFactory.java @@ -17,13 +17,12 @@ import javax.jcr.RepositoryException; import javax.jcr.Session; import javax.jcr.SimpleCredentials; -import org.apache.commons.logging.Log; -import org.apache.commons.logging.LogFactory; +import org.argeo.api.cms.CmsLog; /** Proxy JCR sessions and attach them to calling threads. */ @Deprecated public abstract class ThreadBoundJcrSessionFactory { - private final static Log log = LogFactory.getLog(ThreadBoundJcrSessionFactory.class); + private final static CmsLog log = CmsLog.getLog(ThreadBoundJcrSessionFactory.class); private Repository repository; /** can be injected as list, only used if repository is null */ diff --git a/org.argeo.cms.jcr/src/org/argeo/jcr/proxy/AbstractUrlProxy.java b/org.argeo.cms.jcr/src/org/argeo/jcr/proxy/AbstractUrlProxy.java index 0984276dd..0177636f8 100644 --- a/org.argeo.cms.jcr/src/org/argeo/jcr/proxy/AbstractUrlProxy.java +++ b/org.argeo.cms.jcr/src/org/argeo/jcr/proxy/AbstractUrlProxy.java @@ -12,14 +12,13 @@ import javax.jcr.RepositoryException; import javax.jcr.Session; import javax.jcr.nodetype.NodeType; -import org.apache.commons.logging.Log; -import org.apache.commons.logging.LogFactory; +import org.argeo.api.cms.CmsLog; import org.argeo.jcr.JcrException; import org.argeo.jcr.JcrUtils; /** Base class for URL based proxys. */ public abstract class AbstractUrlProxy implements ResourceProxy { - private final static Log log = LogFactory.getLog(AbstractUrlProxy.class); + private final static CmsLog log = CmsLog.getLog(AbstractUrlProxy.class); private Repository jcrRepository; private Session jcrAdminSession; diff --git a/org.argeo.cms.jcr/src/org/argeo/jcr/proxy/ResourceProxyServlet.java b/org.argeo.cms.jcr/src/org/argeo/jcr/proxy/ResourceProxyServlet.java index d77bd49dc..a8e00df60 100644 --- a/org.argeo.cms.jcr/src/org/argeo/jcr/proxy/ResourceProxyServlet.java +++ b/org.argeo.cms.jcr/src/org/argeo/jcr/proxy/ResourceProxyServlet.java @@ -13,9 +13,8 @@ import javax.servlet.http.HttpServletResponse; import org.apache.commons.io.FilenameUtils; import org.apache.commons.io.IOUtils; -import org.apache.commons.logging.Log; -import org.apache.commons.logging.LogFactory; import org.argeo.jcr.JcrException; +import org.argeo.api.cms.CmsLog; import org.argeo.jcr.Bin; import org.argeo.jcr.JcrUtils; @@ -23,7 +22,7 @@ import org.argeo.jcr.JcrUtils; public class ResourceProxyServlet extends HttpServlet { private static final long serialVersionUID = -8886549549223155801L; - private final static Log log = LogFactory + private final static CmsLog log = CmsLog .getLog(ResourceProxyServlet.class); private ResourceProxy proxy; diff --git a/org.argeo.cms.jcr/src/org/argeo/jcr/unit/AbstractJcrTestCase.java b/org.argeo.cms.jcr/src/org/argeo/jcr/unit/AbstractJcrTestCase.java index dc2963a51..84e8cd31a 100644 --- a/org.argeo.cms.jcr/src/org/argeo/jcr/unit/AbstractJcrTestCase.java +++ b/org.argeo.cms.jcr/src/org/argeo/jcr/unit/AbstractJcrTestCase.java @@ -13,15 +13,14 @@ import javax.security.auth.login.LoginContext; import javax.security.auth.login.LoginException; import org.apache.commons.io.FileUtils; -import org.apache.commons.logging.Log; -import org.apache.commons.logging.LogFactory; +import org.argeo.api.cms.CmsLog; import org.argeo.jcr.JcrException; import junit.framework.TestCase; /** Base for unit tests with a JCR repository. */ public abstract class AbstractJcrTestCase extends TestCase { - private final static Log log = LogFactory.getLog(AbstractJcrTestCase.class); + private final static CmsLog log = CmsLog.getLog(AbstractJcrTestCase.class); private Repository repository; private Session session = null; diff --git a/org.argeo.cms.jcr/src/org/argeo/maintenance/AbstractMaintenanceService.java b/org.argeo.cms.jcr/src/org/argeo/maintenance/AbstractMaintenanceService.java index 804ab9758..3c8f296c4 100644 --- a/org.argeo.cms.jcr/src/org/argeo/maintenance/AbstractMaintenanceService.java +++ b/org.argeo.cms.jcr/src/org/argeo/maintenance/AbstractMaintenanceService.java @@ -10,20 +10,19 @@ import javax.jcr.Repository; import javax.jcr.RepositoryException; import javax.jcr.Session; -import org.apache.commons.logging.Log; -import org.apache.commons.logging.LogFactory; +import org.argeo.api.cms.CmsLog; import org.argeo.cms.jcr.CmsJcrUtils; import org.argeo.jcr.Jcr; import org.argeo.jcr.JcrUtils; -import org.argeo.naming.Distinguished; import org.argeo.osgi.transaction.WorkTransaction; +import org.argeo.util.naming.Distinguished; import org.osgi.service.useradmin.Group; import org.osgi.service.useradmin.Role; import org.osgi.service.useradmin.UserAdmin; /** Make sure roles and access rights are properly configured. */ public abstract class AbstractMaintenanceService { - private final static Log log = LogFactory.getLog(AbstractMaintenanceService.class); + private final static CmsLog log = CmsLog.getLog(AbstractMaintenanceService.class); private Repository repository; // private UserAdminService userAdminService; diff --git a/org.argeo.cms.jcr/src/org/argeo/maintenance/SimpleRoleRegistration.java b/org.argeo.cms.jcr/src/org/argeo/maintenance/SimpleRoleRegistration.java index 07dc39985..ebb8c534d 100644 --- a/org.argeo.cms.jcr/src/org/argeo/maintenance/SimpleRoleRegistration.java +++ b/org.argeo.cms.jcr/src/org/argeo/maintenance/SimpleRoleRegistration.java @@ -7,8 +7,7 @@ import java.util.Map; import javax.naming.InvalidNameException; import javax.naming.ldap.LdapName; -import org.apache.commons.logging.Log; -import org.apache.commons.logging.LogFactory; +import org.argeo.api.cms.CmsLog; import org.argeo.osgi.transaction.WorkTransaction; import org.osgi.service.useradmin.Role; import org.osgi.service.useradmin.UserAdmin; @@ -18,7 +17,7 @@ import org.osgi.service.useradmin.UserAdmin; * is already registered. */ public class SimpleRoleRegistration implements Runnable { - private final static Log log = LogFactory.getLog(SimpleRoleRegistration.class); + private final static CmsLog log = CmsLog.getLog(SimpleRoleRegistration.class); private String role; private List roles = new ArrayList(); diff --git a/org.argeo.cms.jcr/src/org/argeo/maintenance/backup/LogicalBackup.java b/org.argeo.cms.jcr/src/org/argeo/maintenance/backup/LogicalBackup.java index c2a3582e7..00d4be8b0 100644 --- a/org.argeo.cms.jcr/src/org/argeo/maintenance/backup/LogicalBackup.java +++ b/org.argeo.cms.jcr/src/org/argeo/maintenance/backup/LogicalBackup.java @@ -41,11 +41,10 @@ import javax.jcr.RepositoryFactory; import javax.jcr.Session; import org.apache.commons.io.IOUtils; -import org.apache.commons.logging.Log; -import org.apache.commons.logging.LogFactory; import org.apache.jackrabbit.api.JackrabbitSession; import org.apache.jackrabbit.api.JackrabbitValue; -import org.argeo.api.NodeConstants; +import org.argeo.api.cms.CmsConstants; +import org.argeo.api.cms.CmsLog; import org.argeo.cms.jcr.CmsJcrUtils; import org.argeo.jackrabbit.client.ClientDavexRepositoryFactory; import org.argeo.jcr.Jcr; @@ -61,7 +60,7 @@ import org.osgi.framework.BundleContext; * recovery. */ public class LogicalBackup implements Runnable { - private final static Log log = LogFactory.getLog(LogicalBackup.class); + private final static CmsLog log = CmsLog.getLog(LogicalBackup.class); public final static String WORKSPACES_BASE = "workspaces/"; public final static String FILES_BASE = "files/"; @@ -369,7 +368,7 @@ public class LogicalBackup implements Runnable { Map params = new HashMap(); params.put(ClientDavexRepositoryFactory.JACKRABBIT_DAVEX_URI, uri.toString()); // TODO make it configurable - params.put(ClientDavexRepositoryFactory.JACKRABBIT_REMOTE_DEFAULT_WORKSPACE, NodeConstants.SYS_WORKSPACE); + params.put(ClientDavexRepositoryFactory.JACKRABBIT_REMOTE_DEFAULT_WORKSPACE, CmsConstants.SYS_WORKSPACE); return repositoryFactory.getRepository(params); } diff --git a/org.argeo.cms.jcr/src/org/argeo/maintenance/backup/LogicalRestore.java b/org.argeo.cms.jcr/src/org/argeo/maintenance/backup/LogicalRestore.java index 057a12610..122c96701 100644 --- a/org.argeo.cms.jcr/src/org/argeo/maintenance/backup/LogicalRestore.java +++ b/org.argeo.cms.jcr/src/org/argeo/maintenance/backup/LogicalRestore.java @@ -11,9 +11,8 @@ import javax.jcr.Repository; import javax.jcr.RepositoryException; import javax.jcr.Session; -import org.apache.commons.logging.Log; -import org.apache.commons.logging.LogFactory; -import org.argeo.api.NodeConstants; +import org.argeo.api.cms.CmsConstants; +import org.argeo.api.cms.CmsLog; import org.argeo.cms.jcr.CmsJcrUtils; import org.argeo.jcr.Jcr; import org.argeo.jcr.JcrException; @@ -22,7 +21,7 @@ import org.osgi.framework.BundleContext; /** Restores a backup in the format defined by {@link LogicalBackup}. */ public class LogicalRestore implements Runnable { - private final static Log log = LogFactory.getLog(LogicalRestore.class); + private final static CmsLog log = CmsLog.getLog(LogicalRestore.class); private final Repository repository; private final BundleContext bundleContext; diff --git a/org.argeo.cms.jcr/src/org/argeo/security/jackrabbit/ArgeoSecurityManager.java b/org.argeo.cms.jcr/src/org/argeo/security/jackrabbit/ArgeoSecurityManager.java index 4b5945377..36ee547e5 100644 --- a/org.argeo.cms.jcr/src/org/argeo/security/jackrabbit/ArgeoSecurityManager.java +++ b/org.argeo.cms.jcr/src/org/argeo/security/jackrabbit/ArgeoSecurityManager.java @@ -13,8 +13,6 @@ 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; @@ -26,17 +24,18 @@ 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.cms.CmsSession; -import org.argeo.api.security.AnonymousPrincipal; -import org.argeo.api.security.DataAdminPrincipal; +import org.argeo.api.cms.DataAdminPrincipal; +import org.argeo.api.cms.CmsLog; +import org.argeo.api.cms.AnonymousPrincipal; +import org.argeo.api.cms.CmsConstants; import org.argeo.cms.osgi.CmsOsgiUtils; 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 final static CmsLog log = CmsLog.getLog(ArgeoSecurityManager.class); private BundleContext cmsBundleContext = null; @@ -94,7 +93,7 @@ public class ArgeoSecurityManager extends DefaultSecurityManager { if (isDataAdmin || isJackrabbitSystem || isRegularUser) throw new IllegalStateException("Inconsistent " + subject); else - return NodeConstants.ROLE_ANONYMOUS; + return CmsConstants.ROLE_ANONYMOUS; } else if (isRegularUser) {// must be before DataAdmin if (isAnonymous || isJackrabbitSystem) throw new IllegalStateException("Inconsistent " + subject); @@ -112,7 +111,7 @@ public class ArgeoSecurityManager extends DefaultSecurityManager { throw new IllegalStateException("Inconsistent " + subject); else { assert !subject.getPrincipals(AdminPrincipal.class).isEmpty(); - return NodeConstants.ROLE_DATA_ADMIN; + return CmsConstants.ROLE_DATA_ADMIN; } } else if (isJackrabbitSystem) { if (isAnonymous || isDataAdmin || isRegularUser) diff --git a/org.argeo.cms.jcr/src/org/argeo/security/jackrabbit/SystemJackrabbitLoginModule.java b/org.argeo.cms.jcr/src/org/argeo/security/jackrabbit/SystemJackrabbitLoginModule.java index 9c70e9b72..0f63957b7 100644 --- a/org.argeo.cms.jcr/src/org/argeo/security/jackrabbit/SystemJackrabbitLoginModule.java +++ b/org.argeo.cms.jcr/src/org/argeo/security/jackrabbit/SystemJackrabbitLoginModule.java @@ -12,7 +12,7 @@ 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; +import org.argeo.api.cms.DataAdminPrincipal; /** JAAS login module used when initiating a new Jackrabbit session. */ public class SystemJackrabbitLoginModule implements LoginModule { @@ -31,8 +31,8 @@ public class SystemJackrabbitLoginModule implements LoginModule { @Override public boolean commit() throws LoginException { - Set anonPrincipal = subject - .getPrincipals(org.argeo.api.security.AnonymousPrincipal.class); + Set anonPrincipal = subject + .getPrincipals(org.argeo.api.cms.AnonymousPrincipal.class); if (!anonPrincipal.isEmpty()) { subject.getPrincipals().add(new AnonymousPrincipal()); return true; diff --git a/org.argeo.cms.servlet/bnd.bnd b/org.argeo.cms.servlet/bnd.bnd index 011cbd6a3..14575ada8 100644 --- a/org.argeo.cms.servlet/bnd.bnd +++ b/org.argeo.cms.servlet/bnd.bnd @@ -3,7 +3,6 @@ org.osgi.service.http;version=0.0.0,\ org.osgi.service.http.whiteboard;version=0.0.0,\ org.osgi.framework.namespace;version=0.0.0,\ org.argeo.cms.osgi,\ -org.argeo.api,\ * Service-Component:\ diff --git a/org.argeo.cms.servlet/src/org/argeo/cms/servlet/CmsServletContext.java b/org.argeo.cms.servlet/src/org/argeo/cms/servlet/CmsServletContext.java index ba19d0d5f..40404c5d4 100644 --- a/org.argeo.cms.servlet/src/org/argeo/cms/servlet/CmsServletContext.java +++ b/org.argeo.cms.servlet/src/org/argeo/cms/servlet/CmsServletContext.java @@ -11,9 +11,8 @@ import javax.security.auth.login.LoginException; import javax.servlet.http.HttpServletRequest; import javax.servlet.http.HttpServletResponse; -import org.apache.commons.logging.Log; -import org.apache.commons.logging.LogFactory; -import org.argeo.api.NodeConstants; +import org.argeo.api.cms.CmsAuth; +import org.argeo.api.cms.CmsLog; import org.argeo.cms.auth.RemoteAuthCallbackHandler; import org.argeo.cms.auth.RemoteAuthUtils; import org.argeo.cms.servlet.internal.HttpUtils; @@ -26,7 +25,7 @@ import org.osgi.service.http.context.ServletContextHelper; * pre-authenticated. */ public class CmsServletContext extends ServletContextHelper { - private final static Log log = LogFactory.getLog(CmsServletContext.class); + private final static CmsLog log = CmsLog.getLog(CmsServletContext.class); // use CMS bundle for resources private Bundle bundle = FrameworkUtil.getBundle(getClass()); @@ -44,7 +43,7 @@ public class CmsServletContext extends ServletContextHelper { HttpUtils.logRequestHeaders(log, request); LoginContext lc; try { - lc = new LoginContext(NodeConstants.LOGIN_CONTEXT_USER, + lc = CmsAuth.USER.newLoginContext( new RemoteAuthCallbackHandler(new ServletHttpRequest(request), new ServletHttpResponse(response))); lc.login(); } catch (LoginException e) { @@ -78,7 +77,7 @@ public class CmsServletContext extends ServletContextHelper { protected LoginContext processUnauthorized(HttpServletRequest request, HttpServletResponse response) { // anonymous try { - LoginContext lc = new LoginContext(NodeConstants.LOGIN_CONTEXT_ANONYMOUS, + LoginContext lc = new LoginContext(CmsAuth.LOGIN_CONTEXT_ANONYMOUS, new RemoteAuthCallbackHandler(new ServletHttpRequest(request), new ServletHttpResponse(response))); lc.login(); return lc; diff --git a/org.argeo.cms.servlet/src/org/argeo/cms/servlet/internal/HttpUtils.java b/org.argeo.cms.servlet/src/org/argeo/cms/servlet/internal/HttpUtils.java index 5f8c8c560..70f2cc6b0 100644 --- a/org.argeo.cms.servlet/src/org/argeo/cms/servlet/internal/HttpUtils.java +++ b/org.argeo.cms.servlet/src/org/argeo/cms/servlet/internal/HttpUtils.java @@ -5,7 +5,7 @@ import java.util.Enumeration; import javax.servlet.http.HttpServletRequest; import javax.servlet.http.HttpServletResponse; -import org.apache.commons.logging.Log; +import org.argeo.api.cms.CmsLog; public class HttpUtils { public final static String HEADER_AUTHORIZATION = "Authorization"; @@ -17,7 +17,7 @@ public class HttpUtils { || userAgent.contains("opera") || userAgent.contains("browser"); } - public static void logResponseHeaders(Log log, HttpServletResponse response) { + public static void logResponseHeaders(CmsLog log, HttpServletResponse response) { if (!log.isDebugEnabled()) return; for (String headerName : response.getHeaderNames()) { @@ -26,7 +26,7 @@ public class HttpUtils { } } - public static void logRequestHeaders(Log log, HttpServletRequest request) { + public static void logRequestHeaders(CmsLog log, HttpServletRequest request) { if (!log.isDebugEnabled()) return; for (Enumeration headerNames = request.getHeaderNames(); headerNames.hasMoreElements();) { @@ -37,7 +37,7 @@ public class HttpUtils { log.debug(request.getRequestURI() + "\n"); } - public static void logRequest(Log log, HttpServletRequest request) { + public static void logRequest(CmsLog log, HttpServletRequest request) { log.debug("contextPath=" + request.getContextPath()); log.debug("servletPath=" + request.getServletPath()); log.debug("requestURI=" + request.getRequestURI()); diff --git a/org.argeo.cms.swt/src/org/argeo/cms/swt/auth/CmsLogin.java b/org.argeo.cms.swt/src/org/argeo/cms/swt/auth/CmsLogin.java index 66bccc07a..42eedf1a3 100644 --- a/org.argeo.cms.swt/src/org/argeo/cms/swt/auth/CmsLogin.java +++ b/org.argeo.cms.swt/src/org/argeo/cms/swt/auth/CmsLogin.java @@ -17,11 +17,10 @@ import javax.security.auth.callback.UnsupportedCallbackException; import javax.security.auth.login.LoginContext; import javax.security.auth.login.LoginException; -import org.apache.commons.logging.Log; -import org.apache.commons.logging.LogFactory; -import org.argeo.api.NodeConstants; -import org.argeo.api.NodeState; import org.argeo.api.cms.CmsView; +import org.argeo.api.cms.CmsLog; +import org.argeo.api.cms.CmsAuth; +import org.argeo.api.cms.CmsState; import org.argeo.cms.CmsMsg; import org.argeo.cms.LocaleUtils; import org.argeo.cms.auth.RemoteAuthCallback; @@ -48,7 +47,7 @@ import org.eclipse.swt.widgets.Shell; import org.eclipse.swt.widgets.Text; public class CmsLogin implements CmsStyles, CallbackHandler { - private final static Log log = LogFactory.getLog(CmsLogin.class); + private final static CmsLog log = CmsLog.getLog(CmsLogin.class); private Composite parent; private Text usernameT, passwordT; @@ -65,7 +64,7 @@ public class CmsLogin implements CmsStyles, CallbackHandler { public CmsLogin(CmsView cmsView) { this.cmsView = cmsView; - NodeState nodeState = null;// = Activator.getNodeState(); + CmsState nodeState = null;// = Activator.getNodeState(); if (nodeState != null) { defaultLocale = nodeState.getDefaultLocale(); List locales = nodeState.getLocales(); @@ -272,9 +271,9 @@ public class CmsLogin implements CmsStyles, CallbackHandler { // loginContext.logout(); LoginContext loginContext; if (subject == null) - loginContext = new LoginContext(NodeConstants.LOGIN_CONTEXT_USER, this); + loginContext = new LoginContext(CmsAuth.LOGIN_CONTEXT_USER, this); else - loginContext = new LoginContext(NodeConstants.LOGIN_CONTEXT_USER, subject, this); + loginContext = new LoginContext(CmsAuth.LOGIN_CONTEXT_USER, subject, this); loginContext.login(); cmsView.authChange(loginContext); return true; diff --git a/org.argeo.cms.swt/src/org/argeo/cms/swt/dialogs/ChangePasswordDialog.java b/org.argeo.cms.swt/src/org/argeo/cms/swt/dialogs/ChangePasswordDialog.java index 2cf0c8c57..8ff086283 100644 --- a/org.argeo.cms.swt/src/org/argeo/cms/swt/dialogs/ChangePasswordDialog.java +++ b/org.argeo.cms.swt/src/org/argeo/cms/swt/dialogs/ChangePasswordDialog.java @@ -3,9 +3,8 @@ package org.argeo.cms.swt.dialogs; import java.security.PrivilegedAction; import java.util.Arrays; -import org.apache.commons.logging.Log; -import org.apache.commons.logging.LogFactory; import org.argeo.api.cms.CmsView; +import org.argeo.api.cms.CmsLog; import org.argeo.cms.CmsMsg; import org.argeo.cms.CmsUserManager; import org.argeo.cms.swt.CmsSwtUtils; @@ -18,7 +17,7 @@ import org.eclipse.swt.widgets.Text; /** Dialog to change a password. */ public class ChangePasswordDialog extends CmsMessageDialog { - private final static Log log = LogFactory.getLog(ChangePasswordDialog.class); + private final static CmsLog log = CmsLog.getLog(ChangePasswordDialog.class); private CmsUserManager cmsUserManager; private CmsView cmsView; diff --git a/org.argeo.cms.swt/src/org/argeo/cms/swt/dialogs/CmsFeedback.java b/org.argeo.cms.swt/src/org/argeo/cms/swt/dialogs/CmsFeedback.java index 512829873..a01c919e9 100644 --- a/org.argeo.cms.swt/src/org/argeo/cms/swt/dialogs/CmsFeedback.java +++ b/org.argeo.cms.swt/src/org/argeo/cms/swt/dialogs/CmsFeedback.java @@ -3,8 +3,7 @@ package org.argeo.cms.swt.dialogs; import java.io.PrintWriter; import java.io.StringWriter; -import org.apache.commons.logging.Log; -import org.apache.commons.logging.LogFactory; +import org.argeo.api.cms.CmsLog; import org.argeo.cms.CmsMsg; import org.argeo.cms.swt.Selected; import org.eclipse.swt.SWT; @@ -19,7 +18,7 @@ import org.eclipse.swt.widgets.Text; /** A dialog feedback based on a {@link LightweightDialog}. */ public class CmsFeedback extends LightweightDialog { - private final static Log log = LogFactory.getLog(CmsFeedback.class); + private final static CmsLog log = CmsLog.getLog(CmsFeedback.class); private String message; private Throwable exception; diff --git a/org.argeo.cms.swt/src/org/argeo/cms/swt/dialogs/LightweightDialog.java b/org.argeo.cms.swt/src/org/argeo/cms/swt/dialogs/LightweightDialog.java index 2f00a37a6..bf6417bea 100644 --- a/org.argeo.cms.swt/src/org/argeo/cms/swt/dialogs/LightweightDialog.java +++ b/org.argeo.cms.swt/src/org/argeo/cms/swt/dialogs/LightweightDialog.java @@ -1,7 +1,6 @@ package org.argeo.cms.swt.dialogs; -import org.apache.commons.logging.Log; -import org.apache.commons.logging.LogFactory; +import org.argeo.api.cms.CmsLog; import org.argeo.eclipse.ui.EclipseUiException; import org.eclipse.swt.SWT; import org.eclipse.swt.events.FocusEvent; @@ -19,7 +18,7 @@ import org.eclipse.swt.widgets.Shell; /** Generic lightweight dialog, not based on JFace. */ public class LightweightDialog { - private final static Log log = LogFactory.getLog(LightweightDialog.class); + private final static CmsLog log = CmsLog.getLog(LightweightDialog.class); // must be the same value as org.eclipse.jface.window.Window#OK public final static int OK = 0; diff --git a/org.argeo.cms.swt/src/org/argeo/cms/swt/useradmin/PickUpUserDialog.java b/org.argeo.cms.swt/src/org/argeo/cms/swt/useradmin/PickUpUserDialog.java index 6f5aa9dc1..ed1bfd868 100644 --- a/org.argeo.cms.swt/src/org/argeo/cms/swt/useradmin/PickUpUserDialog.java +++ b/org.argeo.cms.swt/src/org/argeo/cms/swt/useradmin/PickUpUserDialog.java @@ -3,13 +3,13 @@ package org.argeo.cms.swt.useradmin; import java.util.ArrayList; import java.util.List; -import org.argeo.api.NodeConstants; +import org.argeo.api.cms.CmsConstants; import org.argeo.eclipse.ui.ColumnDefinition; import org.argeo.eclipse.ui.EclipseUiException; import org.argeo.eclipse.ui.EclipseUiUtils; import org.argeo.eclipse.ui.parts.LdifUsersTable; -import org.argeo.naming.LdapAttrs; -import org.argeo.naming.LdapObjs; +import org.argeo.util.naming.LdapAttrs; +import org.argeo.util.naming.LdapObjs; import org.eclipse.jface.dialogs.MessageDialog; import org.eclipse.jface.dialogs.TrayDialog; import org.eclipse.jface.viewers.DoubleClickEvent; @@ -214,7 +214,7 @@ public class PickUpUserDialog extends TrayDialog { if (!showSystemRoleBtn.getSelection()) typeStr = "(& " + typeStr + "(!(" + LdapAttrs.DN + "=*" - + NodeConstants.ROLES_BASEDN + ")))"; + + CmsConstants.ROLES_BASEDN + ")))"; if (filterBuilder.length() > 1) { builder.append("(&" + typeStr); diff --git a/org.argeo.cms.swt/src/org/argeo/cms/swt/useradmin/UserLP.java b/org.argeo.cms.swt/src/org/argeo/cms/swt/useradmin/UserLP.java index 88573cd0d..d1c90a43f 100644 --- a/org.argeo.cms.swt/src/org/argeo/cms/swt/useradmin/UserLP.java +++ b/org.argeo.cms.swt/src/org/argeo/cms/swt/useradmin/UserLP.java @@ -1,6 +1,6 @@ package org.argeo.cms.swt.useradmin; -import org.argeo.api.NodeConstants; +import org.argeo.api.cms.CmsConstants; import org.argeo.cms.auth.UserAdminUtils; import org.eclipse.jface.resource.JFaceResources; import org.eclipse.jface.viewers.ColumnLabelProvider; @@ -46,7 +46,7 @@ class UserLP extends ColumnLabelProvider { if (COL_ICON.equals(currType)) { User user = (User) element; String dn = user.getName(); - if (dn.endsWith(NodeConstants.ROLES_BASEDN)) + if (dn.endsWith(CmsConstants.ROLES_BASEDN)) return UsersImages.ICON_ROLE; else if (user.getType() == Role.GROUP) return UsersImages.ICON_GROUP; diff --git a/org.argeo.cms.swt/src/org/argeo/eclipse/ui/dialogs/ErrorFeedback.java b/org.argeo.cms.swt/src/org/argeo/eclipse/ui/dialogs/ErrorFeedback.java index f3d0531e1..a388e745e 100644 --- a/org.argeo.cms.swt/src/org/argeo/eclipse/ui/dialogs/ErrorFeedback.java +++ b/org.argeo.cms.swt/src/org/argeo/eclipse/ui/dialogs/ErrorFeedback.java @@ -3,8 +3,7 @@ package org.argeo.eclipse.ui.dialogs; import java.io.PrintWriter; import java.io.StringWriter; -import org.apache.commons.logging.Log; -import org.apache.commons.logging.LogFactory; +import org.argeo.api.cms.CmsLog; import org.eclipse.jface.dialogs.IMessageProvider; import org.eclipse.jface.dialogs.TitleAreaDialog; import org.eclipse.swt.SWT; @@ -26,7 +25,7 @@ import org.eclipse.swt.widgets.Text; public class ErrorFeedback extends TitleAreaDialog { private static final long serialVersionUID = -8918084784628179044L; - private final static Log log = LogFactory.getLog(ErrorFeedback.class); + private final static CmsLog log = CmsLog.getLog(ErrorFeedback.class); private final String message; private final Throwable exception; diff --git a/org.argeo.cms.swt/src/org/argeo/eclipse/ui/dialogs/FeedbackDialog.java b/org.argeo.cms.swt/src/org/argeo/eclipse/ui/dialogs/FeedbackDialog.java index 825879cf9..f2715bc05 100644 --- a/org.argeo.cms.swt/src/org/argeo/eclipse/ui/dialogs/FeedbackDialog.java +++ b/org.argeo.cms.swt/src/org/argeo/eclipse/ui/dialogs/FeedbackDialog.java @@ -3,8 +3,7 @@ package org.argeo.eclipse.ui.dialogs; import java.io.PrintWriter; import java.io.StringWriter; -import org.apache.commons.logging.Log; -import org.apache.commons.logging.LogFactory; +import org.argeo.api.cms.CmsLog; import org.argeo.eclipse.ui.EclipseUiException; import org.eclipse.swt.SWT; import org.eclipse.swt.events.ShellAdapter; @@ -27,7 +26,7 @@ import org.eclipse.swt.widgets.Text; */ @Deprecated public class FeedbackDialog extends LightweightDialog { - private final static Log log = LogFactory.getLog(FeedbackDialog.class); + private final static CmsLog log = CmsLog.getLog(FeedbackDialog.class); private String message; private Throwable exception; diff --git a/org.argeo.cms.swt/src/org/argeo/eclipse/ui/dialogs/LightweightDialog.java b/org.argeo.cms.swt/src/org/argeo/eclipse/ui/dialogs/LightweightDialog.java index d00365bf2..615e1417a 100644 --- a/org.argeo.cms.swt/src/org/argeo/eclipse/ui/dialogs/LightweightDialog.java +++ b/org.argeo.cms.swt/src/org/argeo/eclipse/ui/dialogs/LightweightDialog.java @@ -1,7 +1,6 @@ package org.argeo.eclipse.ui.dialogs; -import org.apache.commons.logging.Log; -import org.apache.commons.logging.LogFactory; +import org.argeo.api.cms.CmsLog; import org.argeo.eclipse.ui.EclipseUiException; import org.eclipse.swt.SWT; import org.eclipse.swt.events.FocusEvent; @@ -20,7 +19,7 @@ import org.eclipse.swt.widgets.Shell; /** Generic lightweight dialog, not based on JFace. */ @Deprecated public class LightweightDialog { - private final static Log log = LogFactory.getLog(LightweightDialog.class); + private final static CmsLog log = CmsLog.getLog(LightweightDialog.class); // must be the same value as org.eclipse.jface.window.Window#OK public final static int OK = 0; diff --git a/org.argeo.cms.swt/src/org/argeo/eclipse/ui/fs/AdvancedFsBrowser.java b/org.argeo.cms.swt/src/org/argeo/eclipse/ui/fs/AdvancedFsBrowser.java index 136eb5055..c01b2d751 100644 --- a/org.argeo.cms.swt/src/org/argeo/eclipse/ui/fs/AdvancedFsBrowser.java +++ b/org.argeo.cms.swt/src/org/argeo/eclipse/ui/fs/AdvancedFsBrowser.java @@ -6,8 +6,7 @@ import java.nio.file.Files; import java.nio.file.Path; import java.util.LinkedHashMap; -import org.apache.commons.logging.Log; -import org.apache.commons.logging.LogFactory; +import org.argeo.api.cms.CmsLog; import org.argeo.eclipse.ui.EclipseUiUtils; import org.eclipse.jface.viewers.ISelectionChangedListener; import org.eclipse.jface.viewers.IStructuredSelection; @@ -33,7 +32,7 @@ import org.eclipse.swt.widgets.Text; /** Simple UI provider that populates a composite parent given a NIO path */ public class AdvancedFsBrowser { - private final static Log log = LogFactory.getLog(AdvancedFsBrowser.class); + private final static CmsLog log = CmsLog.getLog(AdvancedFsBrowser.class); // Some local constants to experiment. should be cleaned // private final static int THUMBNAIL_WIDTH = 400; diff --git a/org.argeo.cms.swt/src/org/argeo/eclipse/ui/fs/SimpleFsBrowser.java b/org.argeo.cms.swt/src/org/argeo/eclipse/ui/fs/SimpleFsBrowser.java index ff93d8251..2e3d6b405 100644 --- a/org.argeo.cms.swt/src/org/argeo/eclipse/ui/fs/SimpleFsBrowser.java +++ b/org.argeo.cms.swt/src/org/argeo/eclipse/ui/fs/SimpleFsBrowser.java @@ -5,8 +5,7 @@ import java.nio.file.Path; import java.util.ArrayList; import java.util.List; -import org.apache.commons.logging.Log; -import org.apache.commons.logging.LogFactory; +import org.argeo.api.cms.CmsLog; import org.argeo.eclipse.ui.ColumnDefinition; import org.argeo.eclipse.ui.EclipseUiUtils; import org.eclipse.jface.viewers.DoubleClickEvent; @@ -30,7 +29,7 @@ import org.eclipse.swt.widgets.Table; * the left hand side and a simple table on the right hand side. */ public class SimpleFsBrowser extends Composite { - private final static Log log = LogFactory.getLog(SimpleFsBrowser.class); + private final static CmsLog log = CmsLog.getLog(SimpleFsBrowser.class); private static final long serialVersionUID = -40347919096946585L; private Path currSelected; diff --git a/org.argeo.cms.swt/src/org/argeo/eclipse/ui/fs/SimpleFsTreeBrowser.java b/org.argeo.cms.swt/src/org/argeo/eclipse/ui/fs/SimpleFsTreeBrowser.java index f8128d96c..401e5cb5e 100644 --- a/org.argeo.cms.swt/src/org/argeo/eclipse/ui/fs/SimpleFsTreeBrowser.java +++ b/org.argeo.cms.swt/src/org/argeo/eclipse/ui/fs/SimpleFsTreeBrowser.java @@ -5,8 +5,7 @@ import java.nio.file.Path; import java.util.ArrayList; import java.util.List; -import org.apache.commons.logging.Log; -import org.apache.commons.logging.LogFactory; +import org.argeo.api.cms.CmsLog; import org.argeo.eclipse.ui.ColumnDefinition; import org.argeo.eclipse.ui.EclipseUiUtils; import org.eclipse.jface.viewers.ISelectionChangedListener; @@ -24,7 +23,7 @@ import org.eclipse.swt.widgets.Tree; /** A simple Java 7 nio files browser with a tree */ public class SimpleFsTreeBrowser extends Composite { - private final static Log log = LogFactory.getLog(SimpleFsTreeBrowser.class); + private final static CmsLog log = CmsLog.getLog(SimpleFsTreeBrowser.class); private static final long serialVersionUID = -40347919096946585L; private Path currSelected; diff --git a/org.argeo.cms.tp/bnd.bnd b/org.argeo.cms.tp/bnd.bnd index 66c0c1b30..23eb6d78d 100644 --- a/org.argeo.cms.tp/bnd.bnd +++ b/org.argeo.cms.tp/bnd.bnd @@ -1,2 +1,6 @@ +Export-Package: \ +org.apache.commons.logging;version=1.2.555,\ +* + Import-Package: \ *;resolution:=optional diff --git a/org.argeo.cms.tp/src/org/apache/commons/logging/Log.java b/org.argeo.cms.tp/src/org/apache/commons/logging/Log.java new file mode 100644 index 000000000..bf9a94c4b --- /dev/null +++ b/org.argeo.cms.tp/src/org/apache/commons/logging/Log.java @@ -0,0 +1,7 @@ +package org.apache.commons.logging; + +/** An Apache logging facade. */ +@Deprecated +public interface Log extends org.argeo.api.cms.CmsLog { + +} diff --git a/org.argeo.cms.tp/src/org/apache/commons/logging/LogFactory.java b/org.argeo.cms.tp/src/org/apache/commons/logging/LogFactory.java new file mode 100644 index 000000000..6a2e8f846 --- /dev/null +++ b/org.argeo.cms.tp/src/org/apache/commons/logging/LogFactory.java @@ -0,0 +1,32 @@ +package org.apache.commons.logging; + +import java.lang.System.Logger; +import java.util.Objects; + +/** A pseudo implementation of Apache Commons Logging. */ +@Deprecated +public abstract class LogFactory { + public static Log getLog(Class clss) { + return getLog(Objects.requireNonNull(clss).getName()); + } + + public static Log getLog(String name) { + Logger logger = System.getLogger(Objects.requireNonNull(name)); + return new LoggerWrapper(logger); + } + + static class LoggerWrapper implements Log { + private final Logger logger; + + LoggerWrapper(Logger logger) { + super(); + this.logger = logger; + } + + @Override + public Logger getLogger() { + return logger; + } + + } +} diff --git a/org.argeo.cms.tp/src/org/slf4j/impl/ArgeoLogger.java b/org.argeo.cms.tp/src/org/slf4j/impl/ArgeoLogger.java index 676303750..67b236a8e 100644 --- a/org.argeo.cms.tp/src/org/slf4j/impl/ArgeoLogger.java +++ b/org.argeo.cms.tp/src/org/slf4j/impl/ArgeoLogger.java @@ -1,13 +1,13 @@ package org.slf4j.impl; -import org.apache.commons.logging.Log; +import org.argeo.api.cms.CmsLog; import org.slf4j.helpers.MarkerIgnoringBase; class ArgeoLogger extends MarkerIgnoringBase { private static final long serialVersionUID = -7719157836932627307L; - private final Log log; + private final CmsLog log; - protected ArgeoLogger(String name, Log log) { + protected ArgeoLogger(String name, CmsLog log) { this.name = name; this.log = log; } diff --git a/org.argeo.cms.tp/src/org/slf4j/impl/StaticLoggerBinder.java b/org.argeo.cms.tp/src/org/slf4j/impl/StaticLoggerBinder.java index 19943a157..224b99bce 100644 --- a/org.argeo.cms.tp/src/org/slf4j/impl/StaticLoggerBinder.java +++ b/org.argeo.cms.tp/src/org/slf4j/impl/StaticLoggerBinder.java @@ -1,7 +1,6 @@ package org.slf4j.impl; -import org.apache.commons.logging.Log; -import org.apache.commons.logging.LogFactory; +import org.argeo.api.cms.CmsLog; import org.slf4j.ILoggerFactory; import org.slf4j.spi.LoggerFactoryBinder; @@ -34,7 +33,7 @@ public class StaticLoggerBinder implements LoggerFactoryBinder { @Override public org.slf4j.Logger getLogger(String name) { - Log logger = LogFactory.getLog(name); + CmsLog logger = CmsLog.getLog(name); return new ArgeoLogger(name, logger); } diff --git a/org.argeo.cms.ui/src/org/argeo/cms/ui/CmsConstants.java b/org.argeo.cms.ui/src/org/argeo/cms/ui/CmsConstants.java deleted file mode 100644 index 8c324ad74..000000000 --- a/org.argeo.cms.ui/src/org/argeo/cms/ui/CmsConstants.java +++ /dev/null @@ -1,28 +0,0 @@ -package org.argeo.cms.ui; - -import org.argeo.api.cms.Cms2DSize; - -/** Commons constants */ -@Deprecated -public interface CmsConstants { - // DATAKEYS -// public final static String STYLE = EclipseUiConstants.CSS_CLASS; -// public final static String MARKUP = EclipseUiConstants.MARKUP_SUPPORT; - @Deprecated - /* RWT.CUSTOM_ITEM_HEIGHT */ - public final static String ITEM_HEIGHT = "org.eclipse.rap.rwt.customItemHeight"; - - // EVENT DETAILS - @Deprecated - /* RWT.HYPERLINK */ - public final static int HYPERLINK = 1 << 26; - - // STANDARD RESOURCES - public final static String LOADING_IMAGE = "icons/loading.gif"; - - public final static String NO_IMAGE = "icons/noPic-square-640px.png"; - public final static Cms2DSize NO_IMAGE_SIZE = new Cms2DSize(320, 320); - public final static Float NO_IMAGE_RATIO = 1f; - // MISCEALLENEOUS - String DATE_TIME_FORMAT = "dd/MM/yyyy, HH:mm"; -} diff --git a/org.argeo.cms.ui/src/org/argeo/cms/ui/CmsUiConstants.java b/org.argeo.cms.ui/src/org/argeo/cms/ui/CmsUiConstants.java new file mode 100644 index 000000000..9df61dcca --- /dev/null +++ b/org.argeo.cms.ui/src/org/argeo/cms/ui/CmsUiConstants.java @@ -0,0 +1,28 @@ +package org.argeo.cms.ui; + +import org.argeo.api.cms.Cms2DSize; + +/** Commons constants */ +@Deprecated +public interface CmsUiConstants { + // DATAKEYS +// public final static String STYLE = EclipseUiConstants.CSS_CLASS; +// public final static String MARKUP = EclipseUiConstants.MARKUP_SUPPORT; + @Deprecated + /* RWT.CUSTOM_ITEM_HEIGHT */ + public final static String ITEM_HEIGHT = "org.eclipse.rap.rwt.customItemHeight"; + + // EVENT DETAILS + @Deprecated + /* RWT.HYPERLINK */ + public final static int HYPERLINK = 1 << 26; + + // STANDARD RESOURCES + public final static String LOADING_IMAGE = "icons/loading.gif"; + + public final static String NO_IMAGE = "icons/noPic-square-640px.png"; + public final static Cms2DSize NO_IMAGE_SIZE = new Cms2DSize(320, 320); + public final static Float NO_IMAGE_RATIO = 1f; + // MISCEALLENEOUS + String DATE_TIME_FORMAT = "dd/MM/yyyy, HH:mm"; +} diff --git a/org.argeo.cms.ui/src/org/argeo/cms/ui/forms/FormPageViewer.java b/org.argeo.cms.ui/src/org/argeo/cms/ui/forms/FormPageViewer.java index bf0e86bea..cc732d49d 100644 --- a/org.argeo.cms.ui/src/org/argeo/cms/ui/forms/FormPageViewer.java +++ b/org.argeo.cms.ui/src/org/argeo/cms/ui/forms/FormPageViewer.java @@ -14,11 +14,10 @@ import javax.jcr.Session; import javax.jcr.Value; import javax.jcr.ValueFormatException; -import org.apache.commons.logging.Log; -import org.apache.commons.logging.LogFactory; import org.argeo.api.cms.Cms2DSize; import org.argeo.api.cms.CmsEditable; import org.argeo.api.cms.CmsImageManager; +import org.argeo.api.cms.CmsLog; import org.argeo.cms.swt.CmsSwtUtils; import org.argeo.cms.ui.viewers.AbstractPageViewer; import org.argeo.cms.ui.viewers.EditablePart; @@ -62,7 +61,7 @@ import org.eclipse.swt.widgets.Text; /** Manage life cycle of a form page that is linked to a given node */ public class FormPageViewer extends AbstractPageViewer { - private final static Log log = LogFactory.getLog(FormPageViewer.class); + private final static CmsLog log = CmsLog.getLog(FormPageViewer.class); private static final long serialVersionUID = 5277789504209413500L; private final Section mainSection; diff --git a/org.argeo.cms.ui/src/org/argeo/cms/ui/forms/FormUtils.java b/org.argeo.cms.ui/src/org/argeo/cms/ui/forms/FormUtils.java index 822473973..1a445bd76 100644 --- a/org.argeo.cms.ui/src/org/argeo/cms/ui/forms/FormUtils.java +++ b/org.argeo.cms.ui/src/org/argeo/cms/ui/forms/FormUtils.java @@ -9,9 +9,8 @@ import java.util.GregorianCalendar; import javax.jcr.Node; import javax.jcr.RepositoryException; -import org.apache.commons.logging.Log; -import org.apache.commons.logging.LogFactory; import org.argeo.api.cms.CmsView; +import org.argeo.api.cms.CmsLog; import org.argeo.cms.CmsException; import org.argeo.cms.ui.util.CmsUiUtils; import org.argeo.eclipse.ui.EclipseUiUtils; @@ -29,7 +28,7 @@ import org.eclipse.swt.widgets.Text; /** Utilitary methods to ease implementation of CMS forms */ public class FormUtils { - private final static Log log = LogFactory.getLog(FormUtils.class); + private final static CmsLog log = CmsLog.getLog(FormUtils.class); public final static String DEFAULT_SHORT_DATE_FORMAT = "dd/MM/yyyy"; diff --git a/org.argeo.cms.ui/src/org/argeo/cms/ui/fs/FileDrop.java b/org.argeo.cms.ui/src/org/argeo/cms/ui/fs/FileDrop.java index d50b8d84d..e875b5a3d 100644 --- a/org.argeo.cms.ui/src/org/argeo/cms/ui/fs/FileDrop.java +++ b/org.argeo.cms.ui/src/org/argeo/cms/ui/fs/FileDrop.java @@ -3,8 +3,7 @@ package org.argeo.cms.ui.fs; import java.io.IOException; import java.io.InputStream; -import org.apache.commons.logging.Log; -import org.apache.commons.logging.LogFactory; +import org.argeo.api.cms.CmsLog; import org.argeo.eclipse.ui.specific.FileDropAdapter; import org.eclipse.swt.dnd.DND; import org.eclipse.swt.dnd.DropTarget; @@ -13,7 +12,7 @@ import org.eclipse.swt.widgets.Control; /** Allows a control to receive file drops. */ public class FileDrop { - private final static Log log = LogFactory.getLog(FileDrop.class); + private final static CmsLog log = CmsLog.getLog(FileDrop.class); public void createDropTarget(Control control) { FileDropAdapter fileDropAdapter = new FileDropAdapter() { diff --git a/org.argeo.cms.ui/src/org/argeo/cms/ui/fs/FsContextMenu.java b/org.argeo.cms.ui/src/org/argeo/cms/ui/fs/FsContextMenu.java index 03ec415d8..c548e2aa0 100644 --- a/org.argeo.cms.ui/src/org/argeo/cms/ui/fs/FsContextMenu.java +++ b/org.argeo.cms.ui/src/org/argeo/cms/ui/fs/FsContextMenu.java @@ -15,8 +15,7 @@ import java.util.List; import java.util.Map; import org.apache.commons.io.IOUtils; -import org.apache.commons.logging.Log; -import org.apache.commons.logging.LogFactory; +import org.argeo.api.cms.CmsLog; import org.argeo.cms.CmsException; import org.argeo.cms.swt.CmsSwtUtils; import org.argeo.eclipse.ui.EclipseUiUtils; @@ -40,7 +39,7 @@ import org.eclipse.swt.widgets.Shell; public class FsContextMenu extends Shell { private static final long serialVersionUID = -9120261153509855795L; - private final static Log log = LogFactory.getLog(FsContextMenu.class); + private final static CmsLog log = CmsLog.getLog(FsContextMenu.class); // Default known actions public final static String ACTION_ID_CREATE_FOLDER = "createFolder"; diff --git a/org.argeo.cms.ui/src/org/argeo/cms/ui/internal/Activator.java b/org.argeo.cms.ui/src/org/argeo/cms/ui/internal/Activator.java index 9ffddd8f3..e10da3aed 100644 --- a/org.argeo.cms.ui/src/org/argeo/cms/ui/internal/Activator.java +++ b/org.argeo.cms.ui/src/org/argeo/cms/ui/internal/Activator.java @@ -1,6 +1,6 @@ package org.argeo.cms.ui.internal; -import org.argeo.api.NodeState; +import org.argeo.api.cms.CmsState; import org.osgi.framework.BundleActivator; import org.osgi.framework.BundleContext; import org.osgi.util.tracker.ServiceTracker; @@ -10,7 +10,7 @@ public class Activator implements BundleActivator { // avoid dependency to RWT OSGi private final static String CONTEXT_NAME_PROP = "contextName"; - private static ServiceTracker nodeState; + private static ServiceTracker nodeState; // @Override public void start(BundleContext bc) throws Exception { @@ -19,7 +19,7 @@ public class Activator implements BundleActivator { // LangUtils.dico(CONTEXT_NAME_PROP, "system")); // bc.registerService(ApplicationConfiguration.class, new UserUi(), LangUtils.dico(CONTEXT_NAME_PROP, "user")); - nodeState = new ServiceTracker<>(bc, NodeState.class, null); + nodeState = new ServiceTracker<>(bc, CmsState.class, null); nodeState.open(); } @@ -31,7 +31,7 @@ public class Activator implements BundleActivator { } } - public static NodeState getNodeState() { + public static CmsState getNodeState() { return nodeState.getService(); } } diff --git a/org.argeo.cms.ui/src/org/argeo/cms/ui/jcr/DefaultRepositoryRegister.java b/org.argeo.cms.ui/src/org/argeo/cms/ui/jcr/DefaultRepositoryRegister.java index f8a115af0..380634118 100644 --- a/org.argeo.cms.ui/src/org/argeo/cms/ui/jcr/DefaultRepositoryRegister.java +++ b/org.argeo.cms.ui/src/org/argeo/cms/ui/jcr/DefaultRepositoryRegister.java @@ -8,16 +8,15 @@ import java.util.TreeMap; import javax.jcr.Repository; import javax.jcr.RepositoryException; -import org.apache.commons.logging.Log; -import org.apache.commons.logging.LogFactory; -import org.argeo.api.NodeConstants; +import org.argeo.api.cms.CmsConstants; +import org.argeo.api.cms.CmsLog; public class DefaultRepositoryRegister extends Observable implements RepositoryRegister { /** Key for a JCR repository alias */ - private final static String CN = NodeConstants.CN; + private final static String CN = CmsConstants.CN; /** Key for a JCR repository URI */ // public final static String JCR_REPOSITORY_URI = "argeo.jcr.repository.uri"; - private final static Log log = LogFactory.getLog(DefaultRepositoryRegister.class); + private final static CmsLog log = CmsLog.getLog(DefaultRepositoryRegister.class); /** Read only map which will be directly exposed. */ private Map repositories = Collections.unmodifiableMap(new TreeMap()); diff --git a/org.argeo.cms.ui/src/org/argeo/cms/ui/jcr/NodeContentProvider.java b/org.argeo.cms.ui/src/org/argeo/cms/ui/jcr/NodeContentProvider.java index 602ae7f6c..00449df26 100644 --- a/org.argeo.cms.ui/src/org/argeo/cms/ui/jcr/NodeContentProvider.java +++ b/org.argeo.cms.ui/src/org/argeo/cms/ui/jcr/NodeContentProvider.java @@ -11,9 +11,9 @@ import javax.jcr.RepositoryFactory; import javax.jcr.Session; import javax.jcr.nodetype.NodeType; -import org.argeo.api.NodeConstants; -import org.argeo.api.security.Keyring; +import org.argeo.api.cms.CmsConstants; import org.argeo.cms.jcr.CmsJcrUtils; +import org.argeo.cms.security.Keyring; import org.argeo.cms.ui.jcr.model.RepositoriesElem; import org.argeo.cms.ui.jcr.model.SingleJcrNodeElem; import org.argeo.eclipse.ui.TreeParent; @@ -62,7 +62,7 @@ public class NodeContentProvider implements ITreeContentProvider { if (homeNode != null) homeNode.dispose(); homeNode = new SingleJcrNodeElem(null, userHome, - userSession.getUserID(), NodeConstants.EGO_REPOSITORY); + userSession.getUserID(), CmsConstants.EGO_REPOSITORY); } } if (repositoryRegister != null) { diff --git a/org.argeo.cms.ui/src/org/argeo/cms/ui/jcr/NodeLabelProvider.java b/org.argeo.cms.ui/src/org/argeo/cms/ui/jcr/NodeLabelProvider.java index e4e800471..a5751c083 100644 --- a/org.argeo.cms.ui/src/org/argeo/cms/ui/jcr/NodeLabelProvider.java +++ b/org.argeo.cms.ui/src/org/argeo/cms/ui/jcr/NodeLabelProvider.java @@ -6,8 +6,7 @@ import javax.jcr.Property; import javax.jcr.RepositoryException; import javax.jcr.nodetype.NodeType; -import org.apache.commons.logging.Log; -import org.apache.commons.logging.LogFactory; +import org.argeo.api.cms.CmsLog; import org.argeo.cms.ui.jcr.model.RemoteRepositoryElem; import org.argeo.cms.ui.jcr.model.RepositoriesElem; import org.argeo.cms.ui.jcr.model.RepositoryElem; @@ -21,7 +20,7 @@ import org.eclipse.swt.graphics.Image; public class NodeLabelProvider extends ColumnLabelProvider { private static final long serialVersionUID = -3662051696443321843L; - private final static Log log = LogFactory.getLog(NodeLabelProvider.class); + private final static CmsLog log = CmsLog.getLog(NodeLabelProvider.class); public String getText(Object element) { try { diff --git a/org.argeo.cms.ui/src/org/argeo/cms/ui/jcr/PropertyLabelProvider.java b/org.argeo.cms.ui/src/org/argeo/cms/ui/jcr/PropertyLabelProvider.java index 6b77b370e..37b90f7ee 100644 --- a/org.argeo.cms.ui/src/org/argeo/cms/ui/jcr/PropertyLabelProvider.java +++ b/org.argeo.cms.ui/src/org/argeo/cms/ui/jcr/PropertyLabelProvider.java @@ -8,7 +8,7 @@ import javax.jcr.PropertyType; import javax.jcr.RepositoryException; import javax.jcr.Value; -import org.argeo.cms.ui.CmsConstants; +import org.argeo.cms.ui.CmsUiConstants; import org.argeo.eclipse.ui.EclipseUiException; import org.argeo.jcr.JcrUtils; import org.eclipse.jface.viewers.ColumnLabelProvider; @@ -25,7 +25,7 @@ public class PropertyLabelProvider extends ColumnLabelProvider { public static final int COLUMN_ATTRIBUTES = 3; // Utils - protected DateFormat timeFormatter = new SimpleDateFormat(CmsConstants.DATE_TIME_FORMAT); + protected DateFormat timeFormatter = new SimpleDateFormat(CmsUiConstants.DATE_TIME_FORMAT); public void update(ViewerCell cell) { Object element = cell.getElement(); diff --git a/org.argeo.cms.ui/src/org/argeo/cms/ui/jcr/model/RemoteRepositoryElem.java b/org.argeo.cms.ui/src/org/argeo/cms/ui/jcr/model/RemoteRepositoryElem.java index 3c035fc77..428e7f1cd 100644 --- a/org.argeo.cms.ui/src/org/argeo/cms/ui/jcr/model/RemoteRepositoryElem.java +++ b/org.argeo.cms.ui/src/org/argeo/cms/ui/jcr/model/RemoteRepositoryElem.java @@ -9,9 +9,9 @@ import javax.jcr.RepositoryFactory; import javax.jcr.Session; import javax.jcr.SimpleCredentials; -import org.argeo.api.security.Keyring; import org.argeo.cms.ArgeoNames; import org.argeo.cms.jcr.CmsJcrUtils; +import org.argeo.cms.security.Keyring; import org.argeo.eclipse.ui.EclipseUiException; import org.argeo.eclipse.ui.TreeParent; diff --git a/org.argeo.cms.ui/src/org/argeo/cms/ui/jcr/model/RepositoriesElem.java b/org.argeo.cms.ui/src/org/argeo/cms/ui/jcr/model/RepositoriesElem.java index f5306d639..858633202 100644 --- a/org.argeo.cms.ui/src/org/argeo/cms/ui/jcr/model/RepositoriesElem.java +++ b/org.argeo.cms.ui/src/org/argeo/cms/ui/jcr/model/RepositoriesElem.java @@ -9,9 +9,9 @@ import javax.jcr.RepositoryException; import javax.jcr.RepositoryFactory; import javax.jcr.Session; -import org.argeo.api.security.Keyring; import org.argeo.cms.ArgeoNames; import org.argeo.cms.jcr.CmsJcrUtils; +import org.argeo.cms.security.Keyring; import org.argeo.cms.ui.jcr.RepositoryRegister; import org.argeo.eclipse.ui.EclipseUiException; import org.argeo.eclipse.ui.TreeParent; diff --git a/org.argeo.cms.ui/src/org/argeo/cms/ui/jcr/model/RepositoryElem.java b/org.argeo.cms.ui/src/org/argeo/cms/ui/jcr/model/RepositoryElem.java index 5503484e0..afff3ef9e 100644 --- a/org.argeo.cms.ui/src/org/argeo/cms/ui/jcr/model/RepositoryElem.java +++ b/org.argeo.cms.ui/src/org/argeo/cms/ui/jcr/model/RepositoryElem.java @@ -4,7 +4,7 @@ import javax.jcr.Repository; import javax.jcr.RepositoryException; import javax.jcr.Session; -import org.argeo.api.NodeConstants; +import org.argeo.api.cms.CmsConstants; import org.argeo.eclipse.ui.EclipseUiException; import org.argeo.eclipse.ui.TreeParent; import org.argeo.jcr.JcrUtils; @@ -31,7 +31,7 @@ public class RepositoryElem extends TreeParent { public void login() { try { - defaultSession = repositoryLogin(NodeConstants.SYS_WORKSPACE); + defaultSession = repositoryLogin(CmsConstants.SYS_WORKSPACE); String[] wkpNames = defaultSession.getWorkspace().getAccessibleWorkspaceNames(); for (String wkpName : wkpNames) { if (wkpName.equals(defaultSession.getWorkspace().getName())) diff --git a/org.argeo.cms.ui/src/org/argeo/cms/ui/util/CmsLink.java b/org.argeo.cms.ui/src/org/argeo/cms/ui/util/CmsLink.java index af7e4020d..3821e6045 100644 --- a/org.argeo.cms.ui/src/org/argeo/cms/ui/util/CmsLink.java +++ b/org.argeo.cms.ui/src/org/argeo/cms/ui/util/CmsLink.java @@ -8,9 +8,8 @@ import java.net.URL; import javax.jcr.Node; import javax.jcr.RepositoryException; -import org.apache.commons.logging.Log; -import org.apache.commons.logging.LogFactory; import org.argeo.api.cms.CmsStyle; +import org.argeo.api.cms.CmsLog; import org.argeo.cms.auth.CurrentUser; import org.argeo.cms.jcr.CmsJcrUtils; import org.argeo.cms.swt.CmsSwtUtils; @@ -29,7 +28,7 @@ import org.osgi.framework.BundleContext; /** A link to an internal or external location. */ public class CmsLink implements CmsUiProvider { - private final static Log log = LogFactory.getLog(CmsLink.class); + private final static CmsLog log = CmsLog.getLog(CmsLink.class); private BundleContext bundleContext; private String label; diff --git a/org.argeo.cms.ui/src/org/argeo/cms/ui/util/CmsUiUtils.java b/org.argeo.cms.ui/src/org/argeo/cms/ui/util/CmsUiUtils.java index ef4f7fa44..8b384799f 100644 --- a/org.argeo.cms.ui/src/org/argeo/cms/ui/util/CmsUiUtils.java +++ b/org.argeo.cms.ui/src/org/argeo/cms/ui/util/CmsUiUtils.java @@ -12,12 +12,12 @@ import javax.jcr.Node; import javax.jcr.RepositoryException; import javax.servlet.http.HttpServletRequest; -import org.argeo.api.NodeConstants; import org.argeo.api.cms.Cms2DSize; import org.argeo.api.cms.CmsView; +import org.argeo.api.cms.CmsConstants; import org.argeo.cms.jcr.CmsJcrUtils; import org.argeo.cms.swt.CmsSwtUtils; -import org.argeo.cms.ui.CmsConstants; +import org.argeo.cms.ui.CmsUiConstants; import org.argeo.jcr.JcrUtils; import org.eclipse.rap.rwt.RWT; import org.eclipse.rap.rwt.service.ResourceManager; @@ -74,7 +74,7 @@ public class CmsUiUtils { /** A path in the node repository */ public static String getDataPath(Node node) { - return getDataPath(NodeConstants.EGO_REPOSITORY, node); + return getDataPath(CmsConstants.EGO_REPOSITORY, node); } public static String getDataPath(String cn, Node node) { @@ -114,7 +114,7 @@ public class CmsUiUtils { @Deprecated public static void setItemHeight(Table table, int height) { - table.setData(CmsConstants.ITEM_HEIGHT, height); + table.setData(CmsUiConstants.ITEM_HEIGHT, height); } // @@ -175,18 +175,18 @@ public class CmsUiUtils { public static String noImg(Cms2DSize size) { ResourceManager rm = RWT.getResourceManager(); - return CmsUiUtils.img(rm.getLocation(CmsConstants.NO_IMAGE), size); + return CmsUiUtils.img(rm.getLocation(CmsUiConstants.NO_IMAGE), size); } public static String noImg() { - return noImg(CmsConstants.NO_IMAGE_SIZE); + return noImg(CmsUiConstants.NO_IMAGE_SIZE); } public static Image noImage(Cms2DSize size) { ResourceManager rm = RWT.getResourceManager(); InputStream in = null; try { - in = rm.getRegisteredContent(CmsConstants.NO_IMAGE); + in = rm.getRegisteredContent(CmsUiConstants.NO_IMAGE); ImageData id = new ImageData(in); ImageData scaled = id.scaledTo(size.getWidth(), size.getHeight()); Image image = new Image(Display.getCurrent(), scaled); diff --git a/org.argeo.cms.ui/src/org/argeo/cms/ui/util/DefaultImageManager.java b/org.argeo.cms.ui/src/org/argeo/cms/ui/util/DefaultImageManager.java index d7f3d7c03..1fc9bd1be 100644 --- a/org.argeo.cms.ui/src/org/argeo/cms/ui/util/DefaultImageManager.java +++ b/org.argeo.cms.ui/src/org/argeo/cms/ui/util/DefaultImageManager.java @@ -4,7 +4,7 @@ import static javax.jcr.Node.JCR_CONTENT; import static javax.jcr.Property.JCR_DATA; import static javax.jcr.nodetype.NodeType.NT_FILE; import static javax.jcr.nodetype.NodeType.NT_RESOURCE; -import static org.argeo.cms.ui.CmsConstants.NO_IMAGE_SIZE; +import static org.argeo.cms.ui.CmsUiConstants.NO_IMAGE_SIZE; import java.io.ByteArrayInputStream; import java.io.IOException; @@ -18,10 +18,9 @@ import javax.jcr.Property; import javax.jcr.RepositoryException; import org.apache.commons.io.IOUtils; -import org.apache.commons.logging.Log; -import org.apache.commons.logging.LogFactory; import org.argeo.api.cms.Cms2DSize; import org.argeo.api.cms.CmsImageManager; +import org.argeo.api.cms.CmsLog; import org.argeo.jcr.JcrException; import org.argeo.jcr.JcrUtils; import org.eclipse.rap.rwt.RWT; @@ -36,7 +35,7 @@ import org.eclipse.swt.widgets.Label; /** Manages only public images so far. */ public class DefaultImageManager implements CmsImageManager { - private final static Log log = LogFactory.getLog(DefaultImageManager.class); + private final static CmsLog log = CmsLog.getLog(DefaultImageManager.class); // private MimetypesFileTypeMap fileTypeMap = new MimetypesFileTypeMap(); public Boolean load(Node node, Control control, Cms2DSize preferredSize) { diff --git a/org.argeo.cms.ui/src/org/argeo/cms/ui/viewers/AbstractPageViewer.java b/org.argeo.cms.ui/src/org/argeo/cms/ui/viewers/AbstractPageViewer.java index 60cb22843..ef24ee0d5 100644 --- a/org.argeo.cms.ui/src/org/argeo/cms/ui/viewers/AbstractPageViewer.java +++ b/org.argeo.cms.ui/src/org/argeo/cms/ui/viewers/AbstractPageViewer.java @@ -11,9 +11,8 @@ import javax.jcr.RepositoryException; import javax.jcr.Session; import javax.security.auth.Subject; -import org.apache.commons.logging.Log; -import org.apache.commons.logging.LogFactory; import org.argeo.api.cms.CmsEditable; +import org.argeo.api.cms.CmsLog; import org.argeo.cms.ui.widgets.ScrolledPage; import org.argeo.jcr.JcrException; import org.eclipse.jface.viewers.ContentViewer; @@ -33,7 +32,7 @@ import org.xml.sax.SAXParseException; public abstract class AbstractPageViewer extends ContentViewer implements Observer { private static final long serialVersionUID = 5438688173410341485L; - private final static Log log = LogFactory.getLog(AbstractPageViewer.class); + private final static CmsLog log = CmsLog.getLog(AbstractPageViewer.class); private final boolean readOnly; /** The basis for the layouts, typically a ScrolledPage. */ diff --git a/org.argeo.cms.ui/src/org/argeo/cms/ui/widgets/EditableImage.java b/org.argeo.cms.ui/src/org/argeo/cms/ui/widgets/EditableImage.java index e5f269a40..c2393f267 100644 --- a/org.argeo.cms.ui/src/org/argeo/cms/ui/widgets/EditableImage.java +++ b/org.argeo.cms.ui/src/org/argeo/cms/ui/widgets/EditableImage.java @@ -3,9 +3,8 @@ package org.argeo.cms.ui.widgets; import javax.jcr.Node; import javax.jcr.RepositoryException; -import org.apache.commons.logging.Log; -import org.apache.commons.logging.LogFactory; import org.argeo.api.cms.Cms2DSize; +import org.argeo.api.cms.CmsLog; import org.argeo.cms.swt.CmsSwtUtils; import org.argeo.cms.ui.util.CmsUiUtils; import org.eclipse.swt.graphics.Point; @@ -17,7 +16,7 @@ import org.eclipse.swt.widgets.Text; /** A stylable and editable image. */ public abstract class EditableImage extends StyledControl { private static final long serialVersionUID = -5689145523114022890L; - private final static Log log = LogFactory.getLog(EditableImage.class); + private final static CmsLog log = CmsLog.getLog(EditableImage.class); private Cms2DSize preferredImageSize; private Boolean loaded = false; diff --git a/org.argeo.cms.ui/src/org/argeo/cms/ui/widgets/StyledControl.java b/org.argeo.cms.ui/src/org/argeo/cms/ui/widgets/StyledControl.java index 84e4cce86..e3a5cb473 100644 --- a/org.argeo.cms.ui/src/org/argeo/cms/ui/widgets/StyledControl.java +++ b/org.argeo.cms.ui/src/org/argeo/cms/ui/widgets/StyledControl.java @@ -3,7 +3,7 @@ package org.argeo.cms.ui.widgets; import javax.jcr.Item; import org.argeo.cms.swt.CmsSwtUtils; -import org.argeo.cms.ui.CmsConstants; +import org.argeo.cms.ui.CmsUiConstants; import org.argeo.eclipse.ui.specific.EclipseUiSpecificUtils; import org.eclipse.swt.SWT; import org.eclipse.swt.events.FocusListener; @@ -12,7 +12,7 @@ import org.eclipse.swt.widgets.Composite; import org.eclipse.swt.widgets.Control; /** Editable text part displaying styled text. */ -public abstract class StyledControl extends JcrComposite implements CmsConstants { +public abstract class StyledControl extends JcrComposite implements CmsUiConstants { private static final long serialVersionUID = -6372283442330912755L; private Control control; diff --git a/org.argeo.cms.ui/src/org/argeo/eclipse/ui/jcr/AbstractNodeContentProvider.java b/org.argeo.cms.ui/src/org/argeo/eclipse/ui/jcr/AbstractNodeContentProvider.java index 8f7c2f99a..fdafa982e 100644 --- a/org.argeo.cms.ui/src/org/argeo/eclipse/ui/jcr/AbstractNodeContentProvider.java +++ b/org.argeo.cms.ui/src/org/argeo/eclipse/ui/jcr/AbstractNodeContentProvider.java @@ -8,8 +8,7 @@ import javax.jcr.NodeIterator; import javax.jcr.RepositoryException; import javax.jcr.Session; -import org.apache.commons.logging.Log; -import org.apache.commons.logging.LogFactory; +import org.argeo.api.cms.CmsLog; import org.argeo.eclipse.ui.AbstractTreeContentProvider; import org.argeo.eclipse.ui.EclipseUiException; @@ -18,7 +17,7 @@ public abstract class AbstractNodeContentProvider extends AbstractTreeContentProvider { private static final long serialVersionUID = -4905836490027272569L; - private final static Log log = LogFactory + private final static CmsLog log = CmsLog .getLog(AbstractNodeContentProvider.class); private Session session; diff --git a/org.argeo.cms.ui/src/org/argeo/eclipse/ui/jcr/AsyncUiEventListener.java b/org.argeo.cms.ui/src/org/argeo/eclipse/ui/jcr/AsyncUiEventListener.java index ae5c2936d..b880a63c5 100644 --- a/org.argeo.cms.ui/src/org/argeo/eclipse/ui/jcr/AsyncUiEventListener.java +++ b/org.argeo.cms.ui/src/org/argeo/eclipse/ui/jcr/AsyncUiEventListener.java @@ -8,8 +8,7 @@ import javax.jcr.observation.Event; import javax.jcr.observation.EventIterator; import javax.jcr.observation.EventListener; -import org.apache.commons.logging.Log; -import org.apache.commons.logging.LogFactory; +import org.argeo.api.cms.CmsLog; import org.argeo.eclipse.ui.EclipseUiException; import org.eclipse.swt.widgets.Display; @@ -19,7 +18,7 @@ import org.eclipse.swt.widgets.Display; public abstract class AsyncUiEventListener implements EventListener { // private final static Log logSuper = LogFactory // .getLog(AsyncUiEventListener.class); - private final Log logThis = LogFactory.getLog(getClass()); + private final CmsLog logThis = CmsLog.getLog(getClass()); private final Display display; @@ -39,7 +38,7 @@ public abstract class AsyncUiEventListener implements EventListener { return true; } - protected Log getLog() { + protected CmsLog getLog() { return logThis; } diff --git a/org.argeo.cms/src/org/argeo/cms/ArgeoLogListener.java b/org.argeo.cms/src/org/argeo/cms/ArgeoLogListener.java new file mode 100644 index 000000000..e4a9941c7 --- /dev/null +++ b/org.argeo.cms/src/org/argeo/cms/ArgeoLogListener.java @@ -0,0 +1,24 @@ +package org.argeo.cms; + +/** Framework agnostic interface for log notifications */ +public interface ArgeoLogListener { + /** + * Appends a log + * + * @param username + * authentified user, null for anonymous + * @param level + * INFO, DEBUG, WARN, etc. (logging framework specific) + * @param category + * hierarchy (logging framework specific) + * @param thread + * name of the thread which logged this message + * @param msg + * any object as long as its toString() method returns the + * message + * @param exception + * exception in log4j ThrowableStrRep format + */ + public void appendLog(String username, Long timestamp, String level, + String category, String thread, Object msg, String[] exception); +} diff --git a/org.argeo.cms/src/org/argeo/cms/ArgeoLogger.java b/org.argeo.cms/src/org/argeo/cms/ArgeoLogger.java new file mode 100644 index 000000000..81a40f50c --- /dev/null +++ b/org.argeo.cms/src/org/argeo/cms/ArgeoLogger.java @@ -0,0 +1,31 @@ +package org.argeo.cms; + +/** + * Logging framework agnostic identifying a logging service, to which one can + * register + */ +public interface ArgeoLogger { + /** + * Register for events by threads with the same authentication (or all + * threads if admin) + */ + public void register(ArgeoLogListener listener, + Integer numberOfPreviousEvents); + + /** + * For admin use only: register for all users + * + * @param listener + * the log listener + * @param numberOfPreviousEvents + * the number of previous events to notify + * @param everything + * if true even anonymous is logged + */ + public void registerForAll(ArgeoLogListener listener, + Integer numberOfPreviousEvents, boolean everything); + + public void unregister(ArgeoLogListener listener); + + public void unregisterForAll(ArgeoLogListener listener); +} diff --git a/org.argeo.cms/src/org/argeo/cms/LocaleUtils.java b/org.argeo.cms/src/org/argeo/cms/LocaleUtils.java index ec8c97f79..f02e6a2b4 100644 --- a/org.argeo.cms/src/org/argeo/cms/LocaleUtils.java +++ b/org.argeo.cms/src/org/argeo/cms/LocaleUtils.java @@ -8,15 +8,14 @@ import java.util.ResourceBundle; import javax.security.auth.Subject; -import org.apache.commons.logging.Log; -import org.apache.commons.logging.LogFactory; +import org.argeo.api.cms.CmsLog; import org.argeo.cms.auth.CurrentUser; /** Utilities simplifying the development of localization enums. */ public class LocaleUtils { final static String DEFAULT_OSGI_l10N_BUNDLE = "/OSGI-INF/l10n/bundle"; - private final static Log log = LogFactory.getLog(LocaleUtils.class); + private final static CmsLog log = CmsLog.getLog(LocaleUtils.class); private final static ThreadLocal threadLocale = new ThreadLocal<>(); diff --git a/org.argeo.cms/src/org/argeo/cms/auth/AnonymousLoginModule.java b/org.argeo.cms/src/org/argeo/cms/auth/AnonymousLoginModule.java index 0217eb8ef..de3a30270 100644 --- a/org.argeo.cms/src/org/argeo/cms/auth/AnonymousLoginModule.java +++ b/org.argeo.cms/src/org/argeo/cms/auth/AnonymousLoginModule.java @@ -8,8 +8,7 @@ import javax.security.auth.callback.CallbackHandler; import javax.security.auth.login.LoginException; import javax.security.auth.spi.LoginModule; -import org.apache.commons.logging.Log; -import org.apache.commons.logging.LogFactory; +import org.argeo.api.cms.CmsLog; import org.osgi.framework.BundleContext; import org.osgi.framework.FrameworkUtil; import org.osgi.service.useradmin.Authorization; @@ -17,7 +16,7 @@ import org.osgi.service.useradmin.UserAdmin; /** Anonymous CMS user */ public class AnonymousLoginModule implements LoginModule { - private final static Log log = LogFactory.getLog(AnonymousLoginModule.class); + private final static CmsLog log = CmsLog.getLog(AnonymousLoginModule.class); private Subject subject; private Map sharedState = null; diff --git a/org.argeo.cms/src/org/argeo/cms/auth/CmsAuthUtils.java b/org.argeo.cms/src/org/argeo/cms/auth/CmsAuthUtils.java index 33a9d7ae4..72676611e 100644 --- a/org.argeo.cms/src/org/argeo/cms/auth/CmsAuthUtils.java +++ b/org.argeo.cms/src/org/argeo/cms/auth/CmsAuthUtils.java @@ -11,15 +11,15 @@ import javax.naming.ldap.LdapName; import javax.security.auth.Subject; import javax.security.auth.x500.X500Principal; -import org.argeo.api.NodeConstants; import org.argeo.api.cms.CmsSession; import org.argeo.api.cms.CmsSessionId; -import org.argeo.api.security.AnonymousPrincipal; -import org.argeo.api.security.DataAdminPrincipal; -import org.argeo.api.security.NodeSecurityUtils; +import org.argeo.api.cms.DataAdminPrincipal; +import org.argeo.api.cms.AnonymousPrincipal; +import org.argeo.api.cms.CmsConstants; import org.argeo.cms.internal.auth.CmsSessionImpl; import org.argeo.cms.internal.auth.ImpliedByPrincipal; import org.argeo.cms.internal.http.WebCmsSessionImpl; +import org.argeo.cms.security.NodeSecurityUtils; import org.argeo.osgi.useradmin.AuthenticatingUser; import org.osgi.framework.BundleContext; import org.osgi.framework.InvalidSyntaxException; @@ -131,7 +131,7 @@ class CmsAuthUtils { assert httpSession != null; String httpSessId = httpSession.getId(); boolean anonymous = authorization.getName() == null; - String remoteUser = !anonymous ? authorization.getName() : NodeConstants.ROLE_ANONYMOUS; + String remoteUser = !anonymous ? authorization.getName() : CmsConstants.ROLE_ANONYMOUS; request.setAttribute(HttpContext.REMOTE_USER, remoteUser); request.setAttribute(HttpContext.AUTHORIZATION, authorization); diff --git a/org.argeo.cms/src/org/argeo/cms/auth/CurrentUser.java b/org.argeo.cms/src/org/argeo/cms/auth/CurrentUser.java index 9808305ce..afb6360b4 100644 --- a/org.argeo.cms/src/org/argeo/cms/auth/CurrentUser.java +++ b/org.argeo.cms/src/org/argeo/cms/auth/CurrentUser.java @@ -13,9 +13,9 @@ import java.util.UUID; import javax.security.auth.Subject; import javax.security.auth.x500.X500Principal; -import org.argeo.api.NodeConstants; import org.argeo.api.cms.CmsSession; import org.argeo.api.cms.CmsSessionId; +import org.argeo.api.cms.CmsConstants; import org.argeo.cms.internal.auth.CmsSessionImpl; import org.argeo.cms.internal.auth.ImpliedByPrincipal; import org.argeo.cms.internal.kernel.Activator; @@ -86,7 +86,7 @@ public final class CurrentUser { if (subject == null) throw new IllegalArgumentException("Subject cannot be null"); if (subject.getPrincipals(X500Principal.class).size() != 1) - return NodeConstants.ROLE_ANONYMOUS; + return CmsConstants.ROLE_ANONYMOUS; Principal principal = subject.getPrincipals(X500Principal.class).iterator().next(); return principal.getName(); } @@ -118,7 +118,7 @@ public final class CurrentUser { if (subject == null) return true; String username = getUsername(subject); - return username == null || username.equalsIgnoreCase(NodeConstants.ROLE_ANONYMOUS); + return username == null || username.equalsIgnoreCase(CmsConstants.ROLE_ANONYMOUS); } public CmsSession getCmsSession() { diff --git a/org.argeo.cms/src/org/argeo/cms/auth/DataAdminLoginModule.java b/org.argeo.cms/src/org/argeo/cms/auth/DataAdminLoginModule.java new file mode 100644 index 000000000..ea1046be9 --- /dev/null +++ b/org.argeo.cms/src/org/argeo/cms/auth/DataAdminLoginModule.java @@ -0,0 +1,48 @@ +package org.argeo.cms.auth; + +import java.util.Map; + +import javax.security.auth.AuthPermission; +import javax.security.auth.Subject; +import javax.security.auth.callback.CallbackHandler; +import javax.security.auth.login.LoginException; +import javax.security.auth.spi.LoginModule; + +import org.argeo.api.cms.DataAdminPrincipal; + +/** + * Log-in a system process as data admin. Protection is via + * {@link AuthPermission} on this login module, so if it can be accessed it will + * always succeed. + */ +public class DataAdminLoginModule implements LoginModule { + private Subject subject; + + @Override + public void initialize(Subject subject, CallbackHandler callbackHandler, Map sharedState, + Map options) { + this.subject = subject; + } + + @Override + public boolean login() throws LoginException { + return true; + } + + @Override + public boolean commit() throws LoginException { + subject.getPrincipals().add(new DataAdminPrincipal()); + return true; + } + + @Override + public boolean abort() throws LoginException { + return true; + } + + @Override + public boolean logout() throws LoginException { + subject.getPrincipals().removeAll(subject.getPrincipals(DataAdminPrincipal.class)); + return true; + } +} diff --git a/org.argeo.cms/src/org/argeo/cms/auth/IdentLoginModule.java b/org.argeo.cms/src/org/argeo/cms/auth/IdentLoginModule.java index 32219dd87..ccf7fc724 100644 --- a/org.argeo.cms/src/org/argeo/cms/auth/IdentLoginModule.java +++ b/org.argeo.cms/src/org/argeo/cms/auth/IdentLoginModule.java @@ -10,14 +10,13 @@ import javax.security.auth.callback.UnsupportedCallbackException; import javax.security.auth.login.LoginException; import javax.security.auth.spi.LoginModule; -import org.apache.commons.logging.Log; -import org.apache.commons.logging.LogFactory; +import org.argeo.api.cms.CmsLog; +import org.argeo.cms.auth.ident.IdentClient; import org.argeo.cms.internal.kernel.Activator; -import org.argeo.ident.IdentClient; /** Use an ident service to identify. */ public class IdentLoginModule implements LoginModule { - private final static Log log = LogFactory.getLog(IdentLoginModule.class); + private final static CmsLog log = CmsLog.getLog(IdentLoginModule.class); private CallbackHandler callbackHandler = null; private Map sharedState = null; diff --git a/org.argeo.cms/src/org/argeo/cms/auth/KeyringLoginModule.java b/org.argeo.cms/src/org/argeo/cms/auth/KeyringLoginModule.java index 920c76b65..c49a59ef1 100644 --- a/org.argeo.cms/src/org/argeo/cms/auth/KeyringLoginModule.java +++ b/org.argeo.cms/src/org/argeo/cms/auth/KeyringLoginModule.java @@ -15,7 +15,7 @@ import javax.security.auth.callback.PasswordCallback; import javax.security.auth.login.LoginException; import javax.security.auth.spi.LoginModule; -import org.argeo.api.security.PBEKeySpecCallback; +import org.argeo.cms.security.PBEKeySpecCallback; import org.argeo.util.PasswordEncryption; /** Adds a secret key to the private credentials */ diff --git a/org.argeo.cms/src/org/argeo/cms/auth/RemoteSessionLoginModule.java b/org.argeo.cms/src/org/argeo/cms/auth/RemoteSessionLoginModule.java index ecbc844b5..4d3617eef 100644 --- a/org.argeo.cms/src/org/argeo/cms/auth/RemoteSessionLoginModule.java +++ b/org.argeo.cms/src/org/argeo/cms/auth/RemoteSessionLoginModule.java @@ -14,8 +14,7 @@ import javax.security.auth.callback.UnsupportedCallbackException; import javax.security.auth.login.LoginException; import javax.security.auth.spi.LoginModule; -import org.apache.commons.logging.Log; -import org.apache.commons.logging.LogFactory; +import org.argeo.api.cms.CmsLog; import org.argeo.cms.internal.auth.CmsSessionImpl; import org.argeo.cms.internal.kernel.Activator; import org.osgi.framework.BundleContext; @@ -25,7 +24,7 @@ import org.osgi.service.useradmin.Authorization; /** Use the HTTP session as the basis for authentication. */ public class RemoteSessionLoginModule implements LoginModule { - private final static Log log = LogFactory.getLog(RemoteSessionLoginModule.class); + private final static CmsLog log = CmsLog.getLog(RemoteSessionLoginModule.class); private Subject subject = null; private CallbackHandler callbackHandler = null; diff --git a/org.argeo.cms/src/org/argeo/cms/auth/SingleUserLoginModule.java b/org.argeo.cms/src/org/argeo/cms/auth/SingleUserLoginModule.java index 649ecc464..08380ac5a 100644 --- a/org.argeo.cms/src/org/argeo/cms/auth/SingleUserLoginModule.java +++ b/org.argeo.cms/src/org/argeo/cms/auth/SingleUserLoginModule.java @@ -13,16 +13,15 @@ import javax.security.auth.login.LoginException; import javax.security.auth.spi.LoginModule; import javax.security.auth.x500.X500Principal; -import org.apache.commons.logging.Log; -import org.apache.commons.logging.LogFactory; -import org.argeo.naming.LdapAttrs; +import org.argeo.api.cms.CmsLog; import org.argeo.osgi.useradmin.IpaUtils; import org.argeo.osgi.useradmin.OsUserUtils; +import org.argeo.util.naming.LdapAttrs; import org.osgi.service.useradmin.Authorization; /** Login module for when the system is owned by a single user. */ public class SingleUserLoginModule implements LoginModule { - private final static Log log = LogFactory.getLog(SingleUserLoginModule.class); + private final static CmsLog log = CmsLog.getLog(SingleUserLoginModule.class); private Subject subject; private Map sharedState = null; diff --git a/org.argeo.cms/src/org/argeo/cms/auth/SpnegoLoginModule.java b/org.argeo.cms/src/org/argeo/cms/auth/SpnegoLoginModule.java index 568e2f6e0..c94480cb5 100644 --- a/org.argeo.cms/src/org/argeo/cms/auth/SpnegoLoginModule.java +++ b/org.argeo.cms/src/org/argeo/cms/auth/SpnegoLoginModule.java @@ -8,8 +8,7 @@ import javax.security.auth.callback.CallbackHandler; import javax.security.auth.login.LoginException; import javax.security.auth.spi.LoginModule; -import org.apache.commons.logging.Log; -import org.apache.commons.logging.LogFactory; +import org.argeo.api.cms.CmsLog; import org.argeo.cms.internal.kernel.Activator; import org.ietf.jgss.GSSContext; import org.ietf.jgss.GSSCredential; @@ -19,7 +18,7 @@ import org.ietf.jgss.GSSName; /** SPNEGO login */ public class SpnegoLoginModule implements LoginModule { - private final static Log log = LogFactory.getLog(SpnegoLoginModule.class); + private final static CmsLog log = CmsLog.getLog(SpnegoLoginModule.class); private Subject subject; private Map sharedState = null; diff --git a/org.argeo.cms/src/org/argeo/cms/auth/UserAdminLoginModule.java b/org.argeo.cms/src/org/argeo/cms/auth/UserAdminLoginModule.java index 188e86058..b9f8d4a51 100644 --- a/org.argeo.cms/src/org/argeo/cms/auth/UserAdminLoginModule.java +++ b/org.argeo.cms/src/org/argeo/cms/auth/UserAdminLoginModule.java @@ -1,6 +1,6 @@ package org.argeo.cms.auth; -import static org.argeo.naming.LdapAttrs.cn; +import static org.argeo.util.naming.LdapAttrs.cn; import java.io.IOException; import java.security.PrivilegedAction; @@ -24,15 +24,14 @@ import javax.security.auth.login.CredentialNotFoundException; import javax.security.auth.login.LoginException; import javax.security.auth.spi.LoginModule; -import org.apache.commons.logging.Log; -import org.apache.commons.logging.LogFactory; -import org.argeo.api.NodeConstants; -import org.argeo.api.security.CryptoKeyring; +import org.argeo.api.cms.CmsConstants; +import org.argeo.api.cms.CmsLog; import org.argeo.cms.internal.kernel.Activator; -import org.argeo.naming.LdapAttrs; +import org.argeo.cms.security.CryptoKeyring; import org.argeo.osgi.useradmin.AuthenticatingUser; import org.argeo.osgi.useradmin.IpaUtils; import org.argeo.osgi.useradmin.TokenUtils; +import org.argeo.util.naming.LdapAttrs; import org.osgi.framework.BundleContext; import org.osgi.framework.FrameworkUtil; import org.osgi.framework.ServiceReference; @@ -46,7 +45,7 @@ import org.osgi.service.useradmin.UserAdmin; * authentication. */ public class UserAdminLoginModule implements LoginModule { - private final static Log log = LogFactory.getLog(UserAdminLoginModule.class); + private final static CmsLog log = CmsLog.getLog(UserAdminLoginModule.class); private Subject subject; private CallbackHandler callbackHandler; @@ -337,7 +336,7 @@ public class UserAdminLoginModule implements LoginModule { } protected Group searchForToken(UserAdmin userAdmin, String token) { - String dn = cn + "=" + token + "," + NodeConstants.TOKENS_BASEDN; + String dn = cn + "=" + token + "," + CmsConstants.TOKENS_BASEDN; Group tokenGroup = (Group) userAdmin.getRole(dn); return tokenGroup; } diff --git a/org.argeo.cms/src/org/argeo/cms/auth/UserAdminUtils.java b/org.argeo.cms/src/org/argeo/cms/auth/UserAdminUtils.java index ad53086f5..eed38cc32 100644 --- a/org.argeo.cms/src/org/argeo/cms/auth/UserAdminUtils.java +++ b/org.argeo.cms/src/org/argeo/cms/auth/UserAdminUtils.java @@ -6,8 +6,8 @@ import javax.naming.InvalidNameException; import javax.naming.ldap.LdapName; import javax.naming.ldap.Rdn; -import org.argeo.api.NodeConstants; -import org.argeo.naming.LdapAttrs; +import org.argeo.api.cms.CmsConstants; +import org.argeo.util.naming.LdapAttrs; import org.osgi.service.useradmin.Role; import org.osgi.service.useradmin.User; import org.osgi.service.useradmin.UserAdmin; @@ -135,9 +135,9 @@ public class UserAdminUtils { /** Simply retrieves a display name of the relevant domain */ public final static String getDomainName(User user) { String dn = user.getName(); - if (dn.endsWith(NodeConstants.ROLES_BASEDN)) + if (dn.endsWith(CmsConstants.ROLES_BASEDN)) return "System roles"; - if (dn.endsWith(NodeConstants.TOKENS_BASEDN)) + if (dn.endsWith(CmsConstants.TOKENS_BASEDN)) return "Tokens"; try { // FIXME deal with non-DC diff --git a/org.argeo.cms/src/org/argeo/cms/auth/ident/IdentClient.java b/org.argeo.cms/src/org/argeo/cms/auth/ident/IdentClient.java new file mode 100644 index 000000000..c55ec68a2 --- /dev/null +++ b/org.argeo.cms/src/org/argeo/cms/auth/ident/IdentClient.java @@ -0,0 +1,124 @@ +package org.argeo.cms.auth.ident; + +import java.io.BufferedReader; +import java.io.IOException; +import java.io.InputStreamReader; +import java.io.OutputStream; +import java.net.ConnectException; +import java.net.Socket; +import java.nio.charset.StandardCharsets; +import java.nio.file.Files; +import java.nio.file.Path; +import java.nio.file.Paths; +import java.util.List; +import java.util.StringTokenizer; + +/** + * A simple ident client, supporting authd OpenSSL encrypted username. + * + * @see RFC 1413 https://tools.ietf.org/html/rfc1413 + */ +public class IdentClient { + public final static int DEFAULT_IDENT_PORT = 113; + public final static String AUTHD_PASSPHRASE_PATH = "/etc/ident.key"; + final static String NO_USER = "NO-USER"; + + private final String host; + private final int port; + + private OpenSslDecryptor openSslDecryptor = new OpenSslDecryptor(); + private String identPassphrase = null; + + public IdentClient(String host) { + this(host, readPassphrase(AUTHD_PASSPHRASE_PATH), DEFAULT_IDENT_PORT); + } + + public IdentClient(String host, Path passPhrasePath) { + this(host, readPassphrase(passPhrasePath), DEFAULT_IDENT_PORT); + } + + public IdentClient(String host, String identPassphrase) { + this(host, identPassphrase, DEFAULT_IDENT_PORT); + } + + public IdentClient(String host, String identPassphrase, int port) { + this.host = host; + this.identPassphrase = identPassphrase; + this.port = port; + } + + /** @return the username or null if none */ + public String getUsername(int serverPort, int clientPort) { + String answer; + try (Socket socket = new Socket(host, port)) { + String msg = clientPort + "," + serverPort + "\n"; + OutputStream out = socket.getOutputStream(); + out.write(msg.getBytes(StandardCharsets.US_ASCII)); + out.flush(); + BufferedReader reader = new BufferedReader(new InputStreamReader(socket.getInputStream())); + answer = reader.readLine(); + } catch (ConnectException e) { + System.err.println( + "Ident client is configured but no ident server available on " + host + " (port " + port + ")"); + return null; + } catch (Exception e) { + throw new RuntimeException("Cannot read from ident server on " + host + " (port " + port + ")", e); + } + StringTokenizer st = new StringTokenizer(answer, " :\n"); + String username = null; + while (st.hasMoreTokens()) + username = st.nextToken(); + + if (username.equals(NO_USER)) + return null; + + if (identPassphrase != null && username.startsWith("[")) { + String encrypted = username.substring(1, username.length() - 1); + username = openSslDecryptor.decryptAuthd(encrypted, identPassphrase).trim(); + } +// System.out.println(username); + return username; + } + + public void setOpenSslDecryptor(OpenSslDecryptor openSslDecryptor) { + this.openSslDecryptor = openSslDecryptor; + } + + public static String readPassphrase(String filePath) { + return readPassphrase(Paths.get(filePath)); + } + + /** @return the first line of the file. */ + public static String readPassphrase(Path path) { + if (!isPathAvailable(path)) + return null; + List lines; + try { + lines = Files.readAllLines(path); + } catch (IOException e) { + throw new IllegalStateException("Cannot read " + path, e); + } + if (lines.size() == 0) + return null; + String passphrase = lines.get(0); + return passphrase; + } + + public static boolean isDefaultAuthdPassphraseFileAvailable() { + return isPathAvailable(Paths.get(AUTHD_PASSPHRASE_PATH)); + } + + public static boolean isPathAvailable(Path path) { + if (!Files.exists(path)) + return false; + if (!Files.isReadable(path)) + return false; + return true; + } + + public static void main(String[] args) { + IdentClient identClient = new IdentClient("127.0.0.1", "changeit"); + String username = identClient.getUsername(7070, 55958); + System.out.println(username); + } +} diff --git a/org.argeo.cms/src/org/argeo/cms/auth/ident/OpenSslDecryptor.java b/org.argeo.cms/src/org/argeo/cms/auth/ident/OpenSslDecryptor.java new file mode 100644 index 000000000..ce7bee940 --- /dev/null +++ b/org.argeo.cms/src/org/argeo/cms/auth/ident/OpenSslDecryptor.java @@ -0,0 +1,162 @@ +package org.argeo.cms.auth.ident; + +import java.nio.charset.StandardCharsets; +import java.security.GeneralSecurityException; +import java.security.MessageDigest; +import java.util.Arrays; +import java.util.Base64; + +import javax.crypto.BadPaddingException; +import javax.crypto.Cipher; +import javax.crypto.IllegalBlockSizeException; +import javax.crypto.spec.IvParameterSpec; +import javax.crypto.spec.SecretKeySpec; + +/** + * Decrypts OpenSSL encrypted data. + * + * From + * https://stackoverflow.com/questions/11783062/how-to-decrypt-file-in-java-encrypted-with-openssl-command-using-aes + * + * See also + * https://stackoverflow.com/questions/54171959/badpadding-exception-when-trying-to-decrypt-aes-based-encrypted-text/54173509#54173509 + * for new default message digest (not yet in CentOS 7 as of July 2019) + */ +public class OpenSslDecryptor { + private static final int INDEX_KEY = 0; + private static final int INDEX_IV = 1; + private static final int ITERATIONS = 1; + + private static final int SALT_OFFSET = 8; + private static final int SALT_SIZE = 8; + private static final int CIPHERTEXT_OFFSET = SALT_OFFSET + SALT_SIZE; + + /** In bits. */ + private final int keySize; + + private Cipher cipher; + private MessageDigest messageDigest; + + public OpenSslDecryptor() { + /* + * Changed to SHA-256 from OpenSSL v1.1.0 (see + * https://stackoverflow.com/questions/39637388/encryption-decryption-doesnt- + * work-well-between-two-different-openssl-versions) + */ + this(128, "MD5"); + } + + public OpenSslDecryptor(int keySize, String messageDigest) { + this.keySize = keySize; + try { + this.cipher = Cipher.getInstance("AES/CBC/PKCS5Padding"); + this.messageDigest = MessageDigest.getInstance(messageDigest); + } catch (GeneralSecurityException e) { + throw new IllegalArgumentException("Cannot initialise decryptor", e); + } + } + + public String decryptAuthd(String dataBase64, String passphrase) { + try { + byte[] headerSaltAndCipherText = Base64.getDecoder().decode(dataBase64); + + boolean withSalt = true; + byte[] salt = withSalt ? Arrays.copyOfRange(headerSaltAndCipherText, SALT_OFFSET, SALT_OFFSET + SALT_SIZE) + : null; + byte[] encrypted = withSalt + ? Arrays.copyOfRange(headerSaltAndCipherText, CIPHERTEXT_OFFSET, headerSaltAndCipherText.length) + : headerSaltAndCipherText; + + final byte[][] keyAndIV = EVP_BytesToKey(keySize / Byte.SIZE, cipher.getBlockSize(), messageDigest, salt, + passphrase.getBytes(StandardCharsets.US_ASCII), ITERATIONS); + SecretKeySpec key = new SecretKeySpec(keyAndIV[INDEX_KEY], "AES"); + IvParameterSpec iv = new IvParameterSpec(keyAndIV[INDEX_IV]); + + cipher.init(Cipher.DECRYPT_MODE, key, iv); + byte[] decrypted = cipher.doFinal(encrypted); + + String answer = new String(decrypted, StandardCharsets.US_ASCII); + return answer; + } catch (BadPaddingException e) { + throw new IllegalStateException("Bad password, algorithm, mode or padding;" + + " no salt, wrong number of iterations or corrupted ciphertext.", e); + } catch (IllegalBlockSizeException e) { + throw new IllegalStateException("Bad algorithm, mode or corrupted (resized) ciphertext.", e); + } catch (GeneralSecurityException e) { + throw new IllegalStateException(e); + } + } + + private static byte[][] EVP_BytesToKey(int key_len, int iv_len, MessageDigest md, byte[] salt, byte[] data, + int count) { + byte[][] both = new byte[2][]; + byte[] key = new byte[key_len]; + int key_ix = 0; + byte[] iv = new byte[iv_len]; + int iv_ix = 0; + both[0] = key; + both[1] = iv; + byte[] md_buf = null; + int nkey = key_len; + int niv = iv_len; + int i = 0; + if (data == null) { + return both; + } + int addmd = 0; + for (;;) { + md.reset(); + if (addmd++ > 0) { + md.update(md_buf); + } + md.update(data); + if (null != salt) { + md.update(salt, 0, 8); + } + md_buf = md.digest(); + for (i = 1; i < count; i++) { + md.reset(); + md.update(md_buf); + md_buf = md.digest(); + } + i = 0; + if (nkey > 0) { + for (;;) { + if (nkey == 0) + break; + if (i == md_buf.length) + break; + key[key_ix++] = md_buf[i]; + nkey--; + i++; + } + } + if (niv > 0 && i != md_buf.length) { + for (;;) { + if (niv == 0) + break; + if (i == md_buf.length) + break; + iv[iv_ix++] = md_buf[i]; + niv--; + i++; + } + } + if (nkey == 0 && niv == 0) { + break; + } + } + for (i = 0; i < md_buf.length; i++) { + md_buf[i] = 0; + } + return both; + } + + public static void main(String[] args) { + String dataBase64 = args[0]; + String passphrase = args[1]; + OpenSslDecryptor decryptor = new OpenSslDecryptor(); + System.out.println(decryptor.decryptAuthd(dataBase64, passphrase)); + } + +} \ No newline at end of file diff --git a/org.argeo.cms/src/org/argeo/cms/auth/ident/package-info.java b/org.argeo.cms/src/org/argeo/cms/auth/ident/package-info.java new file mode 100644 index 000000000..7fbd5c6e2 --- /dev/null +++ b/org.argeo.cms/src/org/argeo/cms/auth/ident/package-info.java @@ -0,0 +1,2 @@ +/** Ident authentication protocol support. */ +package org.argeo.cms.auth.ident; \ No newline at end of file diff --git a/org.argeo.cms/src/org/argeo/cms/internal/auth/CmsSessionImpl.java b/org.argeo.cms/src/org/argeo/cms/internal/auth/CmsSessionImpl.java index 4e9b4e072..b0824e84b 100644 --- a/org.argeo.cms/src/org/argeo/cms/internal/auth/CmsSessionImpl.java +++ b/org.argeo.cms/src/org/argeo/cms/internal/auth/CmsSessionImpl.java @@ -21,11 +21,10 @@ import javax.security.auth.login.LoginContext; import javax.security.auth.login.LoginException; import javax.security.auth.x500.X500Principal; -import org.apache.commons.logging.Log; -import org.apache.commons.logging.LogFactory; -import org.argeo.api.NodeConstants; import org.argeo.api.cms.CmsSession; -import org.argeo.api.security.NodeSecurityUtils; +import org.argeo.api.cms.CmsLog; +import org.argeo.cms.security.NodeSecurityUtils; +import org.argeo.api.cms.CmsAuth; import org.osgi.framework.BundleContext; import org.osgi.framework.FrameworkUtil; import org.osgi.framework.InvalidSyntaxException; @@ -37,7 +36,7 @@ import org.osgi.service.useradmin.Authorization; public class CmsSessionImpl implements CmsSession, Serializable { private static final long serialVersionUID = 1867719354246307225L; private final static BundleContext bc = FrameworkUtil.getBundle(CmsSessionImpl.class).getBundleContext(); - private final static Log log = LogFactory.getLog(CmsSessionImpl.class); + private final static CmsLog log = CmsLog.getLog(CmsSessionImpl.class); // private final Subject initialSubject; private transient AccessControlContext accessControlContext; @@ -96,9 +95,9 @@ public class CmsSessionImpl implements CmsSession, Serializable { try { LoginContext lc; if (isAnonymous()) { - lc = new LoginContext(NodeConstants.LOGIN_CONTEXT_ANONYMOUS, getSubject()); + lc = new LoginContext(CmsAuth.LOGIN_CONTEXT_ANONYMOUS, getSubject()); } else { - lc = new LoginContext(NodeConstants.LOGIN_CONTEXT_USER, getSubject()); + lc = new LoginContext(CmsAuth.LOGIN_CONTEXT_USER, getSubject()); } lc.logout(); } catch (LoginException e) { diff --git a/org.argeo.cms/src/org/argeo/cms/internal/auth/CmsUserManagerImpl.java b/org.argeo.cms/src/org/argeo/cms/internal/auth/CmsUserManagerImpl.java index 5485fc5ee..19136606d 100644 --- a/org.argeo.cms/src/org/argeo/cms/internal/auth/CmsUserManagerImpl.java +++ b/org.argeo.cms/src/org/argeo/cms/internal/auth/CmsUserManagerImpl.java @@ -1,8 +1,8 @@ package org.argeo.cms.internal.auth; -import static org.argeo.naming.LdapAttrs.cn; -import static org.argeo.naming.LdapAttrs.description; -import static org.argeo.naming.LdapAttrs.owner; +import static org.argeo.util.naming.LdapAttrs.cn; +import static org.argeo.util.naming.LdapAttrs.description; +import static org.argeo.util.naming.LdapAttrs.owner; import java.time.ZoneOffset; import java.time.ZonedDateTime; @@ -23,19 +23,18 @@ import javax.naming.InvalidNameException; import javax.naming.ldap.LdapName; import javax.security.auth.Subject; -import org.apache.commons.logging.Log; -import org.apache.commons.logging.LogFactory; -import org.argeo.api.NodeConstants; +import org.argeo.api.cms.CmsConstants; +import org.argeo.api.cms.CmsLog; import org.argeo.cms.CmsUserManager; import org.argeo.cms.auth.CurrentUser; import org.argeo.cms.auth.UserAdminUtils; -import org.argeo.naming.LdapAttrs; -import org.argeo.naming.NamingUtils; -import org.argeo.naming.SharedSecret; import org.argeo.osgi.transaction.WorkTransaction; import org.argeo.osgi.useradmin.TokenUtils; import org.argeo.osgi.useradmin.UserAdminConf; import org.argeo.osgi.useradmin.UserDirectory; +import org.argeo.util.naming.LdapAttrs; +import org.argeo.util.naming.NamingUtils; +import org.argeo.util.naming.SharedSecret; import org.osgi.framework.InvalidSyntaxException; import org.osgi.service.useradmin.Authorization; import org.osgi.service.useradmin.Group; @@ -56,7 +55,7 @@ import org.osgi.service.useradmin.UserAdmin; * */ public class CmsUserManagerImpl implements CmsUserManager { - private final static Log log = LogFactory.getLog(CmsUserManagerImpl.class); + private final static CmsLog log = CmsLog.getLog(CmsUserManagerImpl.class); private UserAdmin userAdmin; // private Map serviceProperties; @@ -152,7 +151,7 @@ public class CmsUserManagerImpl implements CmsUserManager { List users = new ArrayList(); for (Role role : roles) { if ((includeUsers && role.getType() == Role.USER || role.getType() == Role.GROUP) && !users.contains(role) - && (includeSystemRoles || !role.getName().toLowerCase().endsWith(NodeConstants.ROLES_BASEDN))) { + && (includeSystemRoles || !role.getName().toLowerCase().endsWith(CmsConstants.ROLES_BASEDN))) { if (match(role, filter)) users.add((User) role); } @@ -234,9 +233,9 @@ public class CmsUserManagerImpl implements CmsUserManager { if (onlyWritable && readOnly) continue; - if (baseDn.equalsIgnoreCase(NodeConstants.ROLES_BASEDN)) + if (baseDn.equalsIgnoreCase(CmsConstants.ROLES_BASEDN)) continue; - if (baseDn.equalsIgnoreCase(NodeConstants.TOKENS_BASEDN)) + if (baseDn.equalsIgnoreCase(CmsConstants.TOKENS_BASEDN)) continue; dns.put(baseDn, UserAdminConf.propertiesAsUri(userDirectories.get(userDirectory)).toString()); @@ -364,7 +363,7 @@ public class CmsUserManagerImpl implements CmsUserManager { public void expireAuthToken(String token) { try { userTransaction.begin(); - String dn = cn + "=" + token + "," + NodeConstants.TOKENS_BASEDN; + String dn = cn + "=" + token + "," + CmsConstants.TOKENS_BASEDN; Group tokenGroup = (Group) userAdmin.getRole(dn); String ldapDate = NamingUtils.instantToLdapDate(ZonedDateTime.now(ZoneOffset.UTC)); tokenGroup.getProperties().put(description.name(), ldapDate); @@ -385,7 +384,7 @@ public class CmsUserManagerImpl implements CmsUserManager { @Override public void expireAuthTokens(Subject subject) { - Set tokens = TokenUtils.tokensUsed(subject, NodeConstants.TOKENS_BASEDN); + Set tokens = TokenUtils.tokensUsed(subject, CmsConstants.TOKENS_BASEDN); for (String token : tokens) expireAuthToken(token); } @@ -400,7 +399,7 @@ public class CmsUserManagerImpl implements CmsUserManager { try { userTransaction.begin(); User user = (User) userAdmin.getRole(userDn); - String tokenDn = cn + "=" + token + "," + NodeConstants.TOKENS_BASEDN; + String tokenDn = cn + "=" + token + "," + CmsConstants.TOKENS_BASEDN; Group tokenGroup = (Group) userAdmin.createRole(tokenDn, Role.GROUP); if (roles != null) for (String role : roles) { @@ -408,7 +407,7 @@ public class CmsUserManagerImpl implements CmsUserManager { if (r != null) tokenGroup.addMember(r); else { - if (!role.equals(NodeConstants.ROLE_USER)) { + if (!role.equals(CmsConstants.ROLE_USER)) { throw new IllegalStateException( "Cannot add role " + role + " to token " + token + " for " + userDn); } diff --git a/org.argeo.cms/src/org/argeo/cms/internal/kernel/Activator.java b/org.argeo.cms/src/org/argeo/cms/internal/kernel/Activator.java index 8d68be643..535c32853 100644 --- a/org.argeo.cms/src/org/argeo/cms/internal/kernel/Activator.java +++ b/org.argeo.cms/src/org/argeo/cms/internal/kernel/Activator.java @@ -11,14 +11,13 @@ import java.util.concurrent.Executors; import javax.security.auth.login.Configuration; -import org.apache.commons.logging.Log; -import org.apache.commons.logging.LogFactory; -import org.argeo.api.ArgeoLogger; -import org.argeo.api.NodeConstants; -import org.argeo.api.NodeDeployment; -import org.argeo.api.NodeInstance; -import org.argeo.api.NodeState; -import org.argeo.ident.IdentClient; +import org.argeo.api.cms.CmsState; +import org.argeo.api.cms.CmsLog; +import org.argeo.api.cms.CmsConstants; +import org.argeo.api.cms.CmsData; +import org.argeo.api.cms.CmsDeployment; +import org.argeo.cms.ArgeoLogger; +import org.argeo.cms.auth.ident.IdentClient; import org.ietf.jgss.GSSCredential; import org.osgi.framework.Bundle; import org.osgi.framework.BundleActivator; @@ -40,7 +39,7 @@ import org.osgi.util.tracker.ServiceTracker; * bundle (and only it) */ public class Activator implements BundleActivator { - private final static Log log = LogFactory.getLog(Activator.class); + private final static CmsLog log = CmsLog.getLog(Activator.class); private static Activator instance; @@ -52,9 +51,9 @@ public class Activator implements BundleActivator { private LogReaderService logReaderService; private NodeLogger logger; - private CmsState nodeState; - private CmsDeployment nodeDeployment; - private CmsInstance nodeInstance; + private CmsStateImpl nodeState; + private CmsDeploymentImpl nodeDeployment; + private CmsDataImpl nodeInstance; private ServiceTracker userAdminSt; private ExecutorService internalExecutorService; @@ -162,16 +161,16 @@ public class Activator implements BundleActivator { private void initNode() throws IOException { // Node state - nodeState = new CmsState(); - registerService(NodeState.class, nodeState, null); + nodeState = new CmsStateImpl(); + registerService(CmsState.class, nodeState, null); // Node deployment - nodeDeployment = new CmsDeployment(); + nodeDeployment = new CmsDeploymentImpl(); // registerService(NodeDeployment.class, nodeDeployment, null); // Node instance - nodeInstance = new CmsInstance(); - registerService(NodeInstance.class, nodeInstance, null); + nodeInstance = new CmsDataImpl(); + registerService(CmsData.class, nodeInstance, null); } public static void registerService(Class clss, T service, Dictionary properties) { @@ -218,7 +217,7 @@ public class Activator implements BundleActivator { // return bundleContext.getService(sr); // } - public static NodeState getNodeState() { + public static CmsState getNodeState() { return instance.nodeState; } @@ -236,7 +235,7 @@ public class Activator implements BundleActivator { } public static String getHttpProxySslHeader() { - return KernelUtils.getFrameworkProp(NodeConstants.HTTP_PROXY_SSL_DN); + return KernelUtils.getFrameworkProp(CmsConstants.HTTP_PROXY_SSL_DN); } public static IdentClient getIdentClient(String remoteAddr) { diff --git a/org.argeo.cms/src/org/argeo/cms/internal/kernel/CmsDataImpl.java b/org.argeo.cms/src/org/argeo/cms/internal/kernel/CmsDataImpl.java new file mode 100644 index 000000000..3b197e24c --- /dev/null +++ b/org.argeo.cms/src/org/argeo/cms/internal/kernel/CmsDataImpl.java @@ -0,0 +1,56 @@ +package org.argeo.cms.internal.kernel; + +import javax.naming.ldap.LdapName; + +import org.argeo.api.cms.CmsData; +import org.argeo.api.cms.CmsLog; +import org.osgi.framework.BundleContext; +import org.osgi.framework.FrameworkUtil; + +public class CmsDataImpl implements CmsData { + private final CmsLog log = CmsLog.getLog(getClass()); + private final BundleContext bc = FrameworkUtil.getBundle(getClass()).getBundleContext(); + +// private EgoRepository egoRepository; + + public CmsDataImpl() { + initTrackers(); + } + + private void initTrackers() { + // node repository +// new ServiceTracker(bc, Repository.class, null) { +// @Override +// public Repository addingService(ServiceReference reference) { +// Object cn = reference.getProperty(NodeConstants.CN); +// if (cn != null && cn.equals(NodeConstants.EGO_REPOSITORY)) { +//// egoRepository = (EgoRepository) bc.getService(reference); +// if (log.isTraceEnabled()) +// log.trace("Home repository is available"); +// } +// return super.addingService(reference); +// } +// +// @Override +// public void removedService(ServiceReference reference, Repository service) { +// super.removedService(reference, service); +//// egoRepository = null; +// } +// +// }.open(); + } + + public void shutdown() { + + } + + @Override + public void createWorkgroup(LdapName dn) { +// if (egoRepository == null) +// throw new CmsException("Ego repository is not available"); +// // TODO add check that the group exists +// egoRepository.createWorkgroup(dn); + throw new UnsupportedOperationException(); + } + +} diff --git a/org.argeo.cms/src/org/argeo/cms/internal/kernel/CmsDeployment.java b/org.argeo.cms/src/org/argeo/cms/internal/kernel/CmsDeployment.java deleted file mode 100644 index b24fb0a12..000000000 --- a/org.argeo.cms/src/org/argeo/cms/internal/kernel/CmsDeployment.java +++ /dev/null @@ -1,244 +0,0 @@ -package org.argeo.cms.internal.kernel; - -import java.io.IOException; -import java.lang.management.ManagementFactory; -import java.net.URL; -import java.util.Dictionary; - -import org.apache.commons.logging.Log; -import org.apache.commons.logging.LogFactory; -import org.argeo.api.NodeConstants; -import org.argeo.api.NodeDeployment; -import org.argeo.api.NodeState; -import org.argeo.osgi.transaction.WorkTransaction; -import org.argeo.osgi.useradmin.UserAdminConf; -import org.eclipse.equinox.http.jetty.JettyConfigurator; -import org.osgi.framework.BundleContext; -import org.osgi.framework.FrameworkUtil; -import org.osgi.framework.ServiceReference; -import org.osgi.service.cm.Configuration; -import org.osgi.service.cm.ConfigurationAdmin; -import org.osgi.service.http.HttpService; -import org.osgi.service.useradmin.Group; -import org.osgi.service.useradmin.Role; -import org.osgi.service.useradmin.UserAdmin; -import org.osgi.util.tracker.ServiceTracker; - -/** Implementation of a CMS deployment. */ -public class CmsDeployment implements NodeDeployment { - private final Log log = LogFactory.getLog(getClass()); - private final BundleContext bc = FrameworkUtil.getBundle(getClass()).getBundleContext(); - - private DeployConfig deployConfig; - - private Long availableSince; - - // Readiness - private boolean nodeAvailable = false; - private boolean userAdminAvailable = false; - private boolean httpExpected = false; - private boolean httpAvailable = false; - - public CmsDeployment() { -// ServiceReference nodeStateSr = bc.getServiceReference(NodeState.class); -// if (nodeStateSr == null) -// throw new CmsException("No node state available"); - -// NodeState nodeState = bc.getService(nodeStateSr); -// cleanState = nodeState.isClean(); - -// nodeHttp = new NodeHttp(); - initTrackers(); - } - - private void initTrackers() { - ServiceTracker httpSt = new ServiceTracker(bc, HttpService.class, null) { - - @Override - public HttpService addingService(ServiceReference sr) { - httpAvailable = true; - Object httpPort = sr.getProperty("http.port"); - Object httpsPort = sr.getProperty("https.port"); - log.info(httpPortsMsg(httpPort, httpsPort)); - checkReadiness(); - return super.addingService(sr); - } - }; - // httpSt.open(); - KernelUtils.asyncOpen(httpSt); - - ServiceTracker userAdminSt = new ServiceTracker(bc, UserAdmin.class, null) { - @Override - public UserAdmin addingService(ServiceReference reference) { - UserAdmin userAdmin = super.addingService(reference); - addStandardSystemRoles(userAdmin); - userAdminAvailable = true; - checkReadiness(); - return userAdmin; - } - }; - // userAdminSt.open(); - KernelUtils.asyncOpen(userAdminSt); - - ServiceTracker confAdminSt = new ServiceTracker(bc, - ConfigurationAdmin.class, null) { - @Override - public ConfigurationAdmin addingService(ServiceReference reference) { - ConfigurationAdmin configurationAdmin = bc.getService(reference); - 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 IllegalStateException("Cannot analyse clean state", e); - } - deployConfig = new DeployConfig(configurationAdmin, isClean); - Activator.registerService(NodeDeployment.class, CmsDeployment.this, null); -// JcrInitUtils.addToDeployment(CmsDeployment.this); - httpExpected = deployConfig.getProps(KernelConstants.JETTY_FACTORY_PID, "default") != null; - try { - Configuration[] configs = configurationAdmin - .listConfigurations("(service.factoryPid=" + NodeConstants.NODE_USER_ADMIN_PID + ")"); - - boolean hasDomain = false; - for (Configuration config : configs) { - Object realm = config.getProperties().get(UserAdminConf.realm.name()); - if (realm != null) { - log.debug("Found realm: " + realm); - hasDomain = true; - } - } - if (hasDomain) { - loadIpaJaasConfiguration(); - } - } catch (Exception e) { - throw new IllegalStateException("Cannot initialize config", e); - } - return super.addingService(reference); - } - }; - // confAdminSt.open(); - KernelUtils.asyncOpen(confAdminSt); - } - - public void addFactoryDeployConfig(String factoryPid, Dictionary props) { - deployConfig.putFactoryDeployConfig(factoryPid, props); - deployConfig.save(); - try { - deployConfig.loadConfigs(); - } catch (IOException e) { - throw new IllegalStateException(e); - } - } - - public Dictionary getProps(String factoryPid, String cn) { - return deployConfig.getProps(factoryPid, cn); - } - - private String httpPortsMsg(Object httpPort, Object httpsPort) { - return (httpPort != null ? "HTTP " + httpPort + " " : " ") + (httpsPort != null ? "HTTPS " + httpsPort : ""); - } - - private void addStandardSystemRoles(UserAdmin userAdmin) { - // we assume UserTransaction is already available (TODO make it more robust) - WorkTransaction userTransaction = bc.getService(bc.getServiceReference(WorkTransaction.class)); - try { - userTransaction.begin(); - Role adminRole = userAdmin.getRole(NodeConstants.ROLE_ADMIN); - if (adminRole == null) { - adminRole = userAdmin.createRole(NodeConstants.ROLE_ADMIN, Role.GROUP); - } - if (userAdmin.getRole(NodeConstants.ROLE_USER_ADMIN) == null) { - Group userAdminRole = (Group) userAdmin.createRole(NodeConstants.ROLE_USER_ADMIN, Role.GROUP); - userAdminRole.addMember(adminRole); - } - userTransaction.commit(); - } catch (Exception e) { - try { - userTransaction.rollback(); - } catch (Exception e1) { - // silent - } - throw new IllegalStateException("Cannot add standard system roles", e); - } - } - - private void loadIpaJaasConfiguration() { - if (System.getProperty(KernelConstants.JAAS_CONFIG_PROP) == null) { - String jaasConfig = KernelConstants.JAAS_CONFIG_IPA; - URL url = getClass().getClassLoader().getResource(jaasConfig); - KernelUtils.setJaasConfiguration(url); - log.debug("Set IPA JAAS configuration."); - } - } - - public void shutdown() { -// if (nodeHttp != null) -// nodeHttp.destroy(); - - try { - JettyConfigurator.stopServer(KernelConstants.DEFAULT_JETTY_SERVER); - } catch (Exception e) { - log.error("Cannot stop default Jetty server.", e); - } - - if (deployConfig != null) { - new Thread(() -> deployConfig.save(), "Save Argeo Deploy Config").start(); - } - } - - /** - * Checks whether the deployment is available according to expectations, and - * mark it as available. - */ - private synchronized void checkReadiness() { - if (isAvailable()) - return; - if (nodeAvailable && userAdminAvailable && (httpExpected ? httpAvailable : true)) { - String data = KernelUtils.getFrameworkProp(KernelUtils.OSGI_INSTANCE_AREA); - String state = KernelUtils.getFrameworkProp(KernelUtils.OSGI_CONFIGURATION_AREA); - availableSince = System.currentTimeMillis(); - long jvmUptime = ManagementFactory.getRuntimeMXBean().getUptime(); - String jvmUptimeStr = " in " + (jvmUptime / 1000) + "." + (jvmUptime % 1000) + "s"; - log.info("## ARGEO NODE AVAILABLE" + (log.isDebugEnabled() ? jvmUptimeStr : "") + " ##"); - if (log.isDebugEnabled()) { - log.debug("## state: " + state); - if (data != null) - log.debug("## data: " + data); - } - long begin = bc.getService(bc.getServiceReference(NodeState.class)).getAvailableSince(); - long initDuration = System.currentTimeMillis() - begin; - if (log.isTraceEnabled()) - log.trace("Kernel initialization took " + initDuration + "ms"); - tributeToFreeSoftware(initDuration); - } - } - - final private void tributeToFreeSoftware(long initDuration) { - if (log.isTraceEnabled()) { - long ms = initDuration / 100; - log.trace("Spend " + ms + "ms" + " reflecting on the progress brought to mankind" + " by Free Software..."); - long beginNano = System.nanoTime(); - try { - Thread.sleep(ms, 0); - } catch (InterruptedException e) { - // silent - } - long durationNano = System.nanoTime() - beginNano; - final double M = 1000d * 1000d; - double sleepAccuracy = ((double) durationNano) / (ms * M); - log.trace("Sleep accuracy: " + String.format("%.2f", 100 - (sleepAccuracy * 100 - 100)) + " %"); - } - } - - @Override - public synchronized Long getAvailableSince() { - return availableSince; - } - - public synchronized boolean isAvailable() { - return availableSince != null; - } - -} diff --git a/org.argeo.cms/src/org/argeo/cms/internal/kernel/CmsDeploymentImpl.java b/org.argeo.cms/src/org/argeo/cms/internal/kernel/CmsDeploymentImpl.java new file mode 100644 index 000000000..4c7cb1dbe --- /dev/null +++ b/org.argeo.cms/src/org/argeo/cms/internal/kernel/CmsDeploymentImpl.java @@ -0,0 +1,243 @@ +package org.argeo.cms.internal.kernel; + +import java.io.IOException; +import java.lang.management.ManagementFactory; +import java.net.URL; +import java.util.Dictionary; + +import org.argeo.api.cms.CmsState; +import org.argeo.api.cms.CmsLog; +import org.argeo.api.cms.CmsConstants; +import org.argeo.api.cms.CmsDeployment; +import org.argeo.osgi.transaction.WorkTransaction; +import org.argeo.osgi.useradmin.UserAdminConf; +import org.eclipse.equinox.http.jetty.JettyConfigurator; +import org.osgi.framework.BundleContext; +import org.osgi.framework.FrameworkUtil; +import org.osgi.framework.ServiceReference; +import org.osgi.service.cm.Configuration; +import org.osgi.service.cm.ConfigurationAdmin; +import org.osgi.service.http.HttpService; +import org.osgi.service.useradmin.Group; +import org.osgi.service.useradmin.Role; +import org.osgi.service.useradmin.UserAdmin; +import org.osgi.util.tracker.ServiceTracker; + +/** Implementation of a CMS deployment. */ +public class CmsDeploymentImpl implements CmsDeployment { + private final CmsLog log = CmsLog.getLog(getClass()); + private final BundleContext bc = FrameworkUtil.getBundle(getClass()).getBundleContext(); + + private DeployConfig deployConfig; + + private Long availableSince; + + // Readiness + private boolean nodeAvailable = false; + private boolean userAdminAvailable = false; + private boolean httpExpected = false; + private boolean httpAvailable = false; + + public CmsDeploymentImpl() { +// ServiceReference nodeStateSr = bc.getServiceReference(NodeState.class); +// if (nodeStateSr == null) +// throw new CmsException("No node state available"); + +// NodeState nodeState = bc.getService(nodeStateSr); +// cleanState = nodeState.isClean(); + +// nodeHttp = new NodeHttp(); + initTrackers(); + } + + private void initTrackers() { + ServiceTracker httpSt = new ServiceTracker(bc, HttpService.class, null) { + + @Override + public HttpService addingService(ServiceReference sr) { + httpAvailable = true; + Object httpPort = sr.getProperty("http.port"); + Object httpsPort = sr.getProperty("https.port"); + log.info(httpPortsMsg(httpPort, httpsPort)); + checkReadiness(); + return super.addingService(sr); + } + }; + // httpSt.open(); + KernelUtils.asyncOpen(httpSt); + + ServiceTracker userAdminSt = new ServiceTracker(bc, UserAdmin.class, null) { + @Override + public UserAdmin addingService(ServiceReference reference) { + UserAdmin userAdmin = super.addingService(reference); + addStandardSystemRoles(userAdmin); + userAdminAvailable = true; + checkReadiness(); + return userAdmin; + } + }; + // userAdminSt.open(); + KernelUtils.asyncOpen(userAdminSt); + + ServiceTracker confAdminSt = new ServiceTracker(bc, + ConfigurationAdmin.class, null) { + @Override + public ConfigurationAdmin addingService(ServiceReference reference) { + ConfigurationAdmin configurationAdmin = bc.getService(reference); + boolean isClean; + try { + Configuration[] confs = configurationAdmin + .listConfigurations("(service.factoryPid=" + CmsConstants.NODE_USER_ADMIN_PID + ")"); + isClean = confs == null || confs.length == 0; + } catch (Exception e) { + throw new IllegalStateException("Cannot analyse clean state", e); + } + deployConfig = new DeployConfig(configurationAdmin, isClean); + Activator.registerService(CmsDeployment.class, CmsDeploymentImpl.this, null); +// JcrInitUtils.addToDeployment(CmsDeployment.this); + httpExpected = deployConfig.getProps(KernelConstants.JETTY_FACTORY_PID, "default") != null; + try { + Configuration[] configs = configurationAdmin + .listConfigurations("(service.factoryPid=" + CmsConstants.NODE_USER_ADMIN_PID + ")"); + + boolean hasDomain = false; + for (Configuration config : configs) { + Object realm = config.getProperties().get(UserAdminConf.realm.name()); + if (realm != null) { + log.debug("Found realm: " + realm); + hasDomain = true; + } + } + if (hasDomain) { + loadIpaJaasConfiguration(); + } + } catch (Exception e) { + throw new IllegalStateException("Cannot initialize config", e); + } + return super.addingService(reference); + } + }; + // confAdminSt.open(); + KernelUtils.asyncOpen(confAdminSt); + } + + public void addFactoryDeployConfig(String factoryPid, Dictionary props) { + deployConfig.putFactoryDeployConfig(factoryPid, props); + deployConfig.save(); + try { + deployConfig.loadConfigs(); + } catch (IOException e) { + throw new IllegalStateException(e); + } + } + + public Dictionary getProps(String factoryPid, String cn) { + return deployConfig.getProps(factoryPid, cn); + } + + private String httpPortsMsg(Object httpPort, Object httpsPort) { + return (httpPort != null ? "HTTP " + httpPort + " " : " ") + (httpsPort != null ? "HTTPS " + httpsPort : ""); + } + + private void addStandardSystemRoles(UserAdmin userAdmin) { + // we assume UserTransaction is already available (TODO make it more robust) + WorkTransaction userTransaction = bc.getService(bc.getServiceReference(WorkTransaction.class)); + try { + userTransaction.begin(); + Role adminRole = userAdmin.getRole(CmsConstants.ROLE_ADMIN); + if (adminRole == null) { + adminRole = userAdmin.createRole(CmsConstants.ROLE_ADMIN, Role.GROUP); + } + if (userAdmin.getRole(CmsConstants.ROLE_USER_ADMIN) == null) { + Group userAdminRole = (Group) userAdmin.createRole(CmsConstants.ROLE_USER_ADMIN, Role.GROUP); + userAdminRole.addMember(adminRole); + } + userTransaction.commit(); + } catch (Exception e) { + try { + userTransaction.rollback(); + } catch (Exception e1) { + // silent + } + throw new IllegalStateException("Cannot add standard system roles", e); + } + } + + private void loadIpaJaasConfiguration() { + if (System.getProperty(KernelConstants.JAAS_CONFIG_PROP) == null) { + String jaasConfig = KernelConstants.JAAS_CONFIG_IPA; + URL url = getClass().getClassLoader().getResource(jaasConfig); + KernelUtils.setJaasConfiguration(url); + log.debug("Set IPA JAAS configuration."); + } + } + + public void shutdown() { +// if (nodeHttp != null) +// nodeHttp.destroy(); + + try { + JettyConfigurator.stopServer(KernelConstants.DEFAULT_JETTY_SERVER); + } catch (Exception e) { + log.error("Cannot stop default Jetty server.", e); + } + + if (deployConfig != null) { + new Thread(() -> deployConfig.save(), "Save Argeo Deploy Config").start(); + } + } + + /** + * Checks whether the deployment is available according to expectations, and + * mark it as available. + */ + private synchronized void checkReadiness() { + if (isAvailable()) + return; + if (nodeAvailable && userAdminAvailable && (httpExpected ? httpAvailable : true)) { + String data = KernelUtils.getFrameworkProp(KernelUtils.OSGI_INSTANCE_AREA); + String state = KernelUtils.getFrameworkProp(KernelUtils.OSGI_CONFIGURATION_AREA); + availableSince = System.currentTimeMillis(); + long jvmUptime = ManagementFactory.getRuntimeMXBean().getUptime(); + String jvmUptimeStr = " in " + (jvmUptime / 1000) + "." + (jvmUptime % 1000) + "s"; + log.info("## ARGEO NODE AVAILABLE" + (log.isDebugEnabled() ? jvmUptimeStr : "") + " ##"); + if (log.isDebugEnabled()) { + log.debug("## state: " + state); + if (data != null) + log.debug("## data: " + data); + } + long begin = bc.getService(bc.getServiceReference(CmsState.class)).getAvailableSince(); + long initDuration = System.currentTimeMillis() - begin; + if (log.isTraceEnabled()) + log.trace("Kernel initialization took " + initDuration + "ms"); + tributeToFreeSoftware(initDuration); + } + } + + final private void tributeToFreeSoftware(long initDuration) { + if (log.isTraceEnabled()) { + long ms = initDuration / 100; + log.trace("Spend " + ms + "ms" + " reflecting on the progress brought to mankind" + " by Free Software..."); + long beginNano = System.nanoTime(); + try { + Thread.sleep(ms, 0); + } catch (InterruptedException e) { + // silent + } + long durationNano = System.nanoTime() - beginNano; + final double M = 1000d * 1000d; + double sleepAccuracy = ((double) durationNano) / (ms * M); + log.trace("Sleep accuracy: " + String.format("%.2f", 100 - (sleepAccuracy * 100 - 100)) + " %"); + } + } + + @Override + public synchronized Long getAvailableSince() { + return availableSince; + } + + public synchronized boolean isAvailable() { + return availableSince != null; + } + +} diff --git a/org.argeo.cms/src/org/argeo/cms/internal/kernel/CmsInstance.java b/org.argeo.cms/src/org/argeo/cms/internal/kernel/CmsInstance.java deleted file mode 100644 index 0d65a6c0b..000000000 --- a/org.argeo.cms/src/org/argeo/cms/internal/kernel/CmsInstance.java +++ /dev/null @@ -1,57 +0,0 @@ -package org.argeo.cms.internal.kernel; - -import javax.naming.ldap.LdapName; - -import org.apache.commons.logging.Log; -import org.apache.commons.logging.LogFactory; -import org.argeo.api.NodeInstance; -import org.osgi.framework.BundleContext; -import org.osgi.framework.FrameworkUtil; - -public class CmsInstance implements NodeInstance { - private final Log log = LogFactory.getLog(getClass()); - private final BundleContext bc = FrameworkUtil.getBundle(getClass()).getBundleContext(); - -// private EgoRepository egoRepository; - - public CmsInstance() { - initTrackers(); - } - - private void initTrackers() { - // node repository -// new ServiceTracker(bc, Repository.class, null) { -// @Override -// public Repository addingService(ServiceReference reference) { -// Object cn = reference.getProperty(NodeConstants.CN); -// if (cn != null && cn.equals(NodeConstants.EGO_REPOSITORY)) { -//// egoRepository = (EgoRepository) bc.getService(reference); -// if (log.isTraceEnabled()) -// log.trace("Home repository is available"); -// } -// return super.addingService(reference); -// } -// -// @Override -// public void removedService(ServiceReference reference, Repository service) { -// super.removedService(reference, service); -//// egoRepository = null; -// } -// -// }.open(); - } - - public void shutdown() { - - } - - @Override - public void createWorkgroup(LdapName dn) { -// if (egoRepository == null) -// throw new CmsException("Ego repository is not available"); -// // TODO add check that the group exists -// egoRepository.createWorkgroup(dn); - throw new UnsupportedOperationException(); - } - -} diff --git a/org.argeo.cms/src/org/argeo/cms/internal/kernel/CmsShutdown.java b/org.argeo.cms/src/org/argeo/cms/internal/kernel/CmsShutdown.java index bfc58501c..eb7657edc 100644 --- a/org.argeo.cms/src/org/argeo/cms/internal/kernel/CmsShutdown.java +++ b/org.argeo.cms/src/org/argeo/cms/internal/kernel/CmsShutdown.java @@ -1,7 +1,6 @@ package org.argeo.cms.internal.kernel; -import org.apache.commons.logging.Log; -import org.apache.commons.logging.LogFactory; +import org.argeo.api.cms.CmsLog; import org.osgi.framework.Bundle; import org.osgi.framework.FrameworkEvent; import org.osgi.framework.FrameworkUtil; @@ -14,7 +13,7 @@ class CmsShutdown extends Thread { public final int EXIT_TIMEOUT = 2; public final int EXIT_UNKNOWN = 3; - private final Log log = LogFactory.getLog(CmsShutdown.class); + private final CmsLog log = CmsLog.getLog(CmsShutdown.class); // private final BundleContext bc = // FrameworkUtil.getBundle(CmsShutdown.class).getBundleContext(); private final Framework framework; diff --git a/org.argeo.cms/src/org/argeo/cms/internal/kernel/CmsState.java b/org.argeo.cms/src/org/argeo/cms/internal/kernel/CmsState.java deleted file mode 100644 index 219f2d53c..000000000 --- a/org.argeo.cms/src/org/argeo/cms/internal/kernel/CmsState.java +++ /dev/null @@ -1,213 +0,0 @@ -package org.argeo.cms.internal.kernel; - -import static java.util.Locale.ENGLISH; - -import java.net.InetAddress; -import java.net.UnknownHostException; -import java.util.ArrayList; -import java.util.List; -import java.util.Locale; - -import org.apache.commons.logging.Log; -import org.apache.commons.logging.LogFactory; -import org.argeo.api.NodeConstants; -import org.argeo.api.NodeState; -import org.argeo.cms.LocaleUtils; -import org.argeo.osgi.transaction.SimpleTransactionManager; -import org.argeo.osgi.transaction.WorkControl; -import org.argeo.osgi.transaction.WorkTransaction; -import org.argeo.util.LangUtils; -import org.osgi.framework.Constants; -import org.osgi.service.cm.ManagedServiceFactory; - -/** - * Implementation of a {@link NodeState}, initialising the required services. - */ -public class CmsState implements NodeState { - private final static Log log = LogFactory.getLog(CmsState.class); -// private final BundleContext bc = FrameworkUtil.getBundle(CmsState.class).getBundleContext(); - - // REFERENCES - private Long availableSince; - - // i18n - private Locale defaultLocale; - private List locales = null; - - private ThreadGroup threadGroup = new ThreadGroup("CMS"); - private List stopHooks = new ArrayList<>(); - - private final String stateUuid; -// private final boolean cleanState; - private String hostname; - - 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) { - log.error("Cannot set hostname: " + e); - } - - availableSince = System.currentTimeMillis(); - if (log.isDebugEnabled()) - // log.debug("## CMS starting... stateUuid=" + this.stateUuid + (cleanState ? " - // (clean state) " : " ")); - log.debug("## CMS starting... (" + stateUuid + ")"); - - initI18n(); - initServices(); - - } - - private void initI18n() { - Object defaultLocaleValue = KernelUtils.getFrameworkProp(NodeConstants.I18N_DEFAULT_LOCALE); - defaultLocale = defaultLocaleValue != null ? new Locale(defaultLocaleValue.toString()) - : new Locale(ENGLISH.getLanguage()); - locales = LocaleUtils.asLocaleList(KernelUtils.getFrameworkProp(NodeConstants.I18N_LOCALES)); - } - - private void initServices() { - // JTA - String tmType = KernelUtils.getFrameworkProp(NodeConstants.TRANSACTION_MANAGER, - NodeConstants.TRANSACTION_MANAGER_SIMPLE); - if (NodeConstants.TRANSACTION_MANAGER_SIMPLE.equals(tmType)) { - initSimpleTransactionManager(); - } else if (NodeConstants.TRANSACTION_MANAGER_BITRONIX.equals(tmType)) { -// initBitronixTransactionManager(); - throw new UnsupportedOperationException( - "Bitronix is not supported anymore, but could be again if there is enough interest."); - } else { - throw new IllegalArgumentException("Usupported transaction manager type " + tmType); - } - - // POI -// POIXMLTypeLoader.setClassLoader(CTConnection.class.getClassLoader()); - - // Tika -// OpenDocumentParser odfParser = new OpenDocumentParser(); -// bc.registerService(Parser.class, odfParser, new Hashtable()); -// PDFParser pdfParser = new PDFParser(); -// bc.registerService(Parser.class, pdfParser, new Hashtable()); -// OOXMLParser ooxmlParser = new OOXMLParser(); -// bc.registerService(Parser.class, ooxmlParser, new Hashtable()); -// TesseractOCRParser ocrParser = new TesseractOCRParser(); -// ocrParser.setLanguage("ara"); -// bc.registerService(Parser.class, ocrParser, new Hashtable()); - -// // JCR -// RepositoryServiceFactory repositoryServiceFactory = new RepositoryServiceFactory(); -// stopHooks.add(() -> repositoryServiceFactory.shutdown()); -// Activator.registerService(ManagedServiceFactory.class, repositoryServiceFactory, -// LangUtils.dict(Constants.SERVICE_PID, NodeConstants.NODE_REPOS_FACTORY_PID)); -// -// NodeRepositoryFactory repositoryFactory = new NodeRepositoryFactory(); -// Activator.registerService(RepositoryFactory.class, repositoryFactory, null); - - // Security - NodeUserAdmin userAdmin = new NodeUserAdmin(NodeConstants.ROLES_BASEDN, NodeConstants.TOKENS_BASEDN); - stopHooks.add(() -> userAdmin.destroy()); - Activator.registerService(ManagedServiceFactory.class, userAdmin, - LangUtils.dict(Constants.SERVICE_PID, NodeConstants.NODE_USER_ADMIN_PID)); - - } - - private void initSimpleTransactionManager() { - SimpleTransactionManager transactionManager = new SimpleTransactionManager(); - Activator.registerService(WorkControl.class, transactionManager, null); - Activator.registerService(WorkTransaction.class, transactionManager, null); -// Activator.registerService(TransactionManager.class, transactionManager, null); -// Activator.registerService(UserTransaction.class, transactionManager, null); - // TODO TransactionSynchronizationRegistry - } - -// private void initBitronixTransactionManager() { -// // TODO manage it in a managed service, as startup could be long -// ServiceReference existingTm = bc.getServiceReference(TransactionManager.class); -// if (existingTm != null) { -// if (log.isDebugEnabled()) -// log.debug("Using provided transaction manager " + existingTm); -// return; -// } -// -// if (!TransactionManagerServices.isTransactionManagerRunning()) { -// bitronix.tm.Configuration tmConf = TransactionManagerServices.getConfiguration(); -// tmConf.setServerId(UUID.randomUUID().toString()); -// -// Bundle bitronixBundle = FrameworkUtil.getBundle(bitronix.tm.Configuration.class); -// File tmBaseDir = bitronixBundle.getDataFile(KernelConstants.DIR_TRANSACTIONS); -// File tmDir1 = new File(tmBaseDir, "btm1"); -// tmDir1.mkdirs(); -// tmConf.setLogPart1Filename(new File(tmDir1, tmDir1.getName() + ".tlog").getAbsolutePath()); -// File tmDir2 = new File(tmBaseDir, "btm2"); -// tmDir2.mkdirs(); -// tmConf.setLogPart2Filename(new File(tmDir2, tmDir2.getName() + ".tlog").getAbsolutePath()); -// } -// BitronixTransactionManager transactionManager = getTransactionManager(); -// stopHooks.add(() -> transactionManager.shutdown()); -// BitronixTransactionSynchronizationRegistry transactionSynchronizationRegistry = getTransactionSynchronizationRegistry(); -// // register -// bc.registerService(TransactionManager.class, transactionManager, null); -// bc.registerService(UserTransaction.class, transactionManager, null); -// bc.registerService(TransactionSynchronizationRegistry.class, transactionSynchronizationRegistry, null); -// if (log.isDebugEnabled()) -// log.debug("Initialised default Bitronix transaction manager"); -// } - - void shutdown() { - if (log.isDebugEnabled()) - log.debug("CMS stopping... (" + this.stateUuid + ")"); - - // 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 ##"); - } - - /** Apply shutdown hoos in reverse order. */ - private void applyStopHooks() { - for (int i = stopHooks.size() - 1; i >= 0; i--) { - try { - stopHooks.get(i).run(); - } catch (Exception e) { - log.error("Could not run shutdown hook #" + i); - } - } - // Clean hanging Gogo shell thread - new GogoShellKiller().start(); - } - -// @Override -// public boolean isClean() { -// return cleanState; -// } - - @Override - public Long getAvailableSince() { - return availableSince; - } - - /* - * ACCESSORS - */ - public Locale getDefaultLocale() { - return defaultLocale; - } - - public List getLocales() { - return locales; - } - - public String getHostname() { - return hostname; - } -} diff --git a/org.argeo.cms/src/org/argeo/cms/internal/kernel/CmsStateImpl.java b/org.argeo.cms/src/org/argeo/cms/internal/kernel/CmsStateImpl.java new file mode 100644 index 000000000..6bc8ac888 --- /dev/null +++ b/org.argeo.cms/src/org/argeo/cms/internal/kernel/CmsStateImpl.java @@ -0,0 +1,212 @@ +package org.argeo.cms.internal.kernel; + +import static java.util.Locale.ENGLISH; + +import java.net.InetAddress; +import java.net.UnknownHostException; +import java.util.ArrayList; +import java.util.List; +import java.util.Locale; + +import org.argeo.api.cms.CmsState; +import org.argeo.api.cms.CmsLog; +import org.argeo.api.cms.CmsConstants; +import org.argeo.cms.LocaleUtils; +import org.argeo.osgi.transaction.SimpleTransactionManager; +import org.argeo.osgi.transaction.WorkControl; +import org.argeo.osgi.transaction.WorkTransaction; +import org.argeo.util.LangUtils; +import org.osgi.framework.Constants; +import org.osgi.service.cm.ManagedServiceFactory; + +/** + * Implementation of a {@link CmsState}, initialising the required services. + */ +public class CmsStateImpl implements CmsState { + private final static CmsLog log = CmsLog.getLog(CmsStateImpl.class); +// private final BundleContext bc = FrameworkUtil.getBundle(CmsState.class).getBundleContext(); + + // REFERENCES + private Long availableSince; + + // i18n + private Locale defaultLocale; + private List locales = null; + + private ThreadGroup threadGroup = new ThreadGroup("CMS"); + private List stopHooks = new ArrayList<>(); + + private final String stateUuid; +// private final boolean cleanState; + private String hostname; + + public CmsStateImpl() { +// this.stateUuid = stateUuid; + this.stateUuid = KernelUtils.getFrameworkProp(Constants.FRAMEWORK_UUID); +// this.cleanState = stateUuid.equals(frameworkUuid); + try { + this.hostname = InetAddress.getLocalHost().getHostName(); + } catch (UnknownHostException e) { + log.error("Cannot set hostname: " + e); + } + + availableSince = System.currentTimeMillis(); + if (log.isDebugEnabled()) + // log.debug("## CMS starting... stateUuid=" + this.stateUuid + (cleanState ? " + // (clean state) " : " ")); + log.debug("## CMS starting... (" + stateUuid + ")"); + + initI18n(); + initServices(); + + } + + private void initI18n() { + Object defaultLocaleValue = KernelUtils.getFrameworkProp(CmsConstants.I18N_DEFAULT_LOCALE); + defaultLocale = defaultLocaleValue != null ? new Locale(defaultLocaleValue.toString()) + : new Locale(ENGLISH.getLanguage()); + locales = LocaleUtils.asLocaleList(KernelUtils.getFrameworkProp(CmsConstants.I18N_LOCALES)); + } + + private void initServices() { + // JTA + String tmType = KernelUtils.getFrameworkProp(CmsConstants.TRANSACTION_MANAGER, + CmsConstants.TRANSACTION_MANAGER_SIMPLE); + if (CmsConstants.TRANSACTION_MANAGER_SIMPLE.equals(tmType)) { + initSimpleTransactionManager(); + } else if (CmsConstants.TRANSACTION_MANAGER_BITRONIX.equals(tmType)) { +// initBitronixTransactionManager(); + throw new UnsupportedOperationException( + "Bitronix is not supported anymore, but could be again if there is enough interest."); + } else { + throw new IllegalArgumentException("Usupported transaction manager type " + tmType); + } + + // POI +// POIXMLTypeLoader.setClassLoader(CTConnection.class.getClassLoader()); + + // Tika +// OpenDocumentParser odfParser = new OpenDocumentParser(); +// bc.registerService(Parser.class, odfParser, new Hashtable()); +// PDFParser pdfParser = new PDFParser(); +// bc.registerService(Parser.class, pdfParser, new Hashtable()); +// OOXMLParser ooxmlParser = new OOXMLParser(); +// bc.registerService(Parser.class, ooxmlParser, new Hashtable()); +// TesseractOCRParser ocrParser = new TesseractOCRParser(); +// ocrParser.setLanguage("ara"); +// bc.registerService(Parser.class, ocrParser, new Hashtable()); + +// // JCR +// RepositoryServiceFactory repositoryServiceFactory = new RepositoryServiceFactory(); +// stopHooks.add(() -> repositoryServiceFactory.shutdown()); +// Activator.registerService(ManagedServiceFactory.class, repositoryServiceFactory, +// LangUtils.dict(Constants.SERVICE_PID, NodeConstants.NODE_REPOS_FACTORY_PID)); +// +// NodeRepositoryFactory repositoryFactory = new NodeRepositoryFactory(); +// Activator.registerService(RepositoryFactory.class, repositoryFactory, null); + + // Security + NodeUserAdmin userAdmin = new NodeUserAdmin(CmsConstants.ROLES_BASEDN, CmsConstants.TOKENS_BASEDN); + stopHooks.add(() -> userAdmin.destroy()); + Activator.registerService(ManagedServiceFactory.class, userAdmin, + LangUtils.dict(Constants.SERVICE_PID, CmsConstants.NODE_USER_ADMIN_PID)); + + } + + private void initSimpleTransactionManager() { + SimpleTransactionManager transactionManager = new SimpleTransactionManager(); + Activator.registerService(WorkControl.class, transactionManager, null); + Activator.registerService(WorkTransaction.class, transactionManager, null); +// Activator.registerService(TransactionManager.class, transactionManager, null); +// Activator.registerService(UserTransaction.class, transactionManager, null); + // TODO TransactionSynchronizationRegistry + } + +// private void initBitronixTransactionManager() { +// // TODO manage it in a managed service, as startup could be long +// ServiceReference existingTm = bc.getServiceReference(TransactionManager.class); +// if (existingTm != null) { +// if (log.isDebugEnabled()) +// log.debug("Using provided transaction manager " + existingTm); +// return; +// } +// +// if (!TransactionManagerServices.isTransactionManagerRunning()) { +// bitronix.tm.Configuration tmConf = TransactionManagerServices.getConfiguration(); +// tmConf.setServerId(UUID.randomUUID().toString()); +// +// Bundle bitronixBundle = FrameworkUtil.getBundle(bitronix.tm.Configuration.class); +// File tmBaseDir = bitronixBundle.getDataFile(KernelConstants.DIR_TRANSACTIONS); +// File tmDir1 = new File(tmBaseDir, "btm1"); +// tmDir1.mkdirs(); +// tmConf.setLogPart1Filename(new File(tmDir1, tmDir1.getName() + ".tlog").getAbsolutePath()); +// File tmDir2 = new File(tmBaseDir, "btm2"); +// tmDir2.mkdirs(); +// tmConf.setLogPart2Filename(new File(tmDir2, tmDir2.getName() + ".tlog").getAbsolutePath()); +// } +// BitronixTransactionManager transactionManager = getTransactionManager(); +// stopHooks.add(() -> transactionManager.shutdown()); +// BitronixTransactionSynchronizationRegistry transactionSynchronizationRegistry = getTransactionSynchronizationRegistry(); +// // register +// bc.registerService(TransactionManager.class, transactionManager, null); +// bc.registerService(UserTransaction.class, transactionManager, null); +// bc.registerService(TransactionSynchronizationRegistry.class, transactionSynchronizationRegistry, null); +// if (log.isDebugEnabled()) +// log.debug("Initialised default Bitronix transaction manager"); +// } + + void shutdown() { + if (log.isDebugEnabled()) + log.debug("CMS stopping... (" + this.stateUuid + ")"); + + // 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 ##"); + } + + /** Apply shutdown hoos in reverse order. */ + private void applyStopHooks() { + for (int i = stopHooks.size() - 1; i >= 0; i--) { + try { + stopHooks.get(i).run(); + } catch (Exception e) { + log.error("Could not run shutdown hook #" + i); + } + } + // Clean hanging Gogo shell thread + new GogoShellKiller().start(); + } + +// @Override +// public boolean isClean() { +// return cleanState; +// } + + @Override + public Long getAvailableSince() { + return availableSince; + } + + /* + * ACCESSORS + */ + public Locale getDefaultLocale() { + return defaultLocale; + } + + public List getLocales() { + return locales; + } + + public String getHostname() { + return hostname; + } +} diff --git a/org.argeo.cms/src/org/argeo/cms/internal/kernel/DeployConfig.java b/org.argeo.cms/src/org/argeo/cms/internal/kernel/DeployConfig.java index 2f60b7337..4a88dd1b4 100644 --- a/org.argeo.cms/src/org/argeo/cms/internal/kernel/DeployConfig.java +++ b/org.argeo.cms/src/org/argeo/cms/internal/kernel/DeployConfig.java @@ -18,13 +18,12 @@ import javax.naming.directory.BasicAttributes; import javax.naming.ldap.LdapName; import javax.naming.ldap.Rdn; -import org.apache.commons.logging.Log; -import org.apache.commons.logging.LogFactory; -import org.argeo.api.NodeConstants; -import org.argeo.naming.AttributesDictionary; -import org.argeo.naming.LdifParser; -import org.argeo.naming.LdifWriter; +import org.argeo.api.cms.CmsConstants; +import org.argeo.api.cms.CmsLog; import org.argeo.osgi.useradmin.UserAdminConf; +import org.argeo.util.naming.AttributesDictionary; +import org.argeo.util.naming.LdifParser; +import org.argeo.util.naming.LdifWriter; import org.eclipse.equinox.http.jetty.JettyConfigurator; import org.osgi.framework.BundleContext; import org.osgi.framework.FrameworkUtil; @@ -35,7 +34,7 @@ import org.osgi.service.cm.ConfigurationListener; /** Manages the LDIF-based deployment configuration. */ class DeployConfig implements ConfigurationListener { - private final Log log = LogFactory.getLog(getClass()); + private final CmsLog log = CmsLog.getLog(getClass()); private final BundleContext bc = FrameworkUtil.getBundle(getClass()).getBundleContext(); private static Path deployConfigPath = KernelUtils.getOsgiInstancePath(KernelConstants.DEPLOY_CONFIG_PATH); @@ -92,16 +91,16 @@ class DeployConfig implements ConfigurationListener { Dictionary userDirectoryConfig = userDirectoryConfigs.get(i); String baseDn = (String) userDirectoryConfig.get(UserAdminConf.baseDn.name()); String cn; - if (NodeConstants.ROLES_BASEDN.equals(baseDn)) + if (CmsConstants.ROLES_BASEDN.equals(baseDn)) cn = ROLES; else cn = UserAdminConf.baseDnHash(userDirectoryConfig); activeCns.add(cn); - userDirectoryConfig.put(NodeConstants.CN, cn); - putFactoryDeployConfig(NodeConstants.NODE_USER_ADMIN_PID, userDirectoryConfig); + userDirectoryConfig.put(CmsConstants.CN, cn); + putFactoryDeployConfig(CmsConstants.NODE_USER_ADMIN_PID, userDirectoryConfig); } // disable others - LdapName userAdminFactoryName = serviceFactoryDn(NodeConstants.NODE_USER_ADMIN_PID); + LdapName userAdminFactoryName = serviceFactoryDn(CmsConstants.NODE_USER_ADMIN_PID); for (LdapName name : deployConfigs.keySet()) { if (name.startsWith(userAdminFactoryName) && !name.equals(userAdminFactoryName)) { // try { @@ -125,7 +124,7 @@ class DeployConfig implements ConfigurationListener { // webServerConfig.put("customizer.class", "org.argeo.equinox.jetty.CmsJettyCustomizer"); // putFactoryDeployConfig(KernelConstants.JETTY_FACTORY_PID, webServerConfig); // } - LdapName defaultHttpServiceDn = serviceDn(KernelConstants.JETTY_FACTORY_PID, NodeConstants.DEFAULT); + LdapName defaultHttpServiceDn = serviceDn(KernelConstants.JETTY_FACTORY_PID, CmsConstants.DEFAULT); if (deployConfigs.containsKey(defaultHttpServiceDn)) { // remove old default configs since we have now to start Jetty servlet bridge // indirectly @@ -139,7 +138,7 @@ class DeployConfig implements ConfigurationListener { // Explicitly configures Jetty so that the default server is not started by the // activator of the Equinox Jetty bundle. Dictionary webServerConfig = InitUtils - .getHttpServerConfig(getProps(KernelConstants.JETTY_FACTORY_PID, NodeConstants.DEFAULT)); + .getHttpServerConfig(getProps(KernelConstants.JETTY_FACTORY_PID, CmsConstants.DEFAULT)); // if (!webServerConfig.isEmpty()) { // webServerConfig.put("customizer.class", KernelConstants.CMS_JETTY_CUSTOMIZER_CLASS); // @@ -203,8 +202,8 @@ class DeployConfig implements ConfigurationListener { deployConfigs: for (LdapName dn : deployConfigs.keySet()) { Rdn lastRdn = dn.getRdn(dn.size() - 1); LdapName prefix = (LdapName) dn.getPrefix(dn.size() - 1); - if (prefix.toString().equals(NodeConstants.DEPLOY_BASEDN)) { - if (lastRdn.getType().equals(NodeConstants.CN)) { + if (prefix.toString().equals(CmsConstants.DEPLOY_BASEDN)) { + if (lastRdn.getType().equals(CmsConstants.CN)) { // service String pid = lastRdn.getValue().toString(); Configuration conf = configurationAdmin.getConfiguration(pid); @@ -220,7 +219,7 @@ class DeployConfig implements ConfigurationListener { continue deployConfigs; // service factory service Rdn beforeLastRdn = dn.getRdn(dn.size() - 2); - assert beforeLastRdn.getType().equals(NodeConstants.OU); + assert beforeLastRdn.getType().equals(CmsConstants.OU); String factoryPid = beforeLastRdn.getValue().toString(); Configuration conf = configurationAdmin.createFactoryConfiguration(factoryPid.toString(), null); if (systemRolesDn.equals(dn)) { @@ -253,7 +252,7 @@ class DeployConfig implements ConfigurationListener { for (LdapName dn : deployConfigs.keySet()) { if (dn.startsWith(serviceFactoryDn)) { Rdn lastRdn = dn.getRdn(dn.size() - 1); - assert lastRdn.getType().equals(NodeConstants.CN); + assert lastRdn.getType().equals(CmsConstants.CN); Object value = conf.getProperties().get(lastRdn.getType()); assert value != null; if (value.equals(lastRdn.getValue())) { @@ -263,7 +262,7 @@ class DeployConfig implements ConfigurationListener { } } - Object cn = conf.getProperties().get(NodeConstants.CN); + Object cn = conf.getProperties().get(CmsConstants.CN); if (cn == null) throw new IllegalArgumentException("Properties must contain cn"); if (serviceDn == null) { @@ -299,12 +298,12 @@ class DeployConfig implements ConfigurationListener { } void putFactoryDeployConfig(String factoryPid, Dictionary props) { - Object cn = props.get(NodeConstants.CN); + Object cn = props.get(CmsConstants.CN); if (cn == null) throw new IllegalArgumentException("cn must be set in properties"); LdapName serviceFactoryDn = serviceFactoryDn(factoryPid); if (!deployConfigs.containsKey(serviceFactoryDn)) - deployConfigs.put(serviceFactoryDn, new BasicAttributes(NodeConstants.OU, factoryPid)); + deployConfigs.put(serviceFactoryDn, new BasicAttributes(CmsConstants.OU, factoryPid)); LdapName serviceDn = serviceDn(factoryPid, cn.toString()); Attributes attrs = new BasicAttributes(); AttributesDictionary.copy(props, attrs); @@ -313,7 +312,7 @@ class DeployConfig implements ConfigurationListener { void putDeployConfig(String servicePid, Dictionary props) { LdapName serviceDn = serviceDn(servicePid); - Attributes attrs = new BasicAttributes(NodeConstants.CN, servicePid); + Attributes attrs = new BasicAttributes(CmsConstants.CN, servicePid); AttributesDictionary.copy(props, attrs); deployConfigs.put(serviceDn, attrs); } @@ -332,7 +331,7 @@ class DeployConfig implements ConfigurationListener { */ private LdapName serviceFactoryDn(String factoryPid) { try { - return new LdapName(NodeConstants.OU + "=" + factoryPid + "," + NodeConstants.DEPLOY_BASEDN); + return new LdapName(CmsConstants.OU + "=" + factoryPid + "," + CmsConstants.DEPLOY_BASEDN); } catch (InvalidNameException e) { throw new IllegalArgumentException("Cannot generate DN from " + factoryPid, e); } @@ -340,7 +339,7 @@ class DeployConfig implements ConfigurationListener { private LdapName serviceDn(String servicePid) { try { - return new LdapName(NodeConstants.CN + "=" + servicePid + "," + NodeConstants.DEPLOY_BASEDN); + return new LdapName(CmsConstants.CN + "=" + servicePid + "," + CmsConstants.DEPLOY_BASEDN); } catch (InvalidNameException e) { throw new IllegalArgumentException("Cannot generate DN from " + servicePid, e); } @@ -348,7 +347,7 @@ class DeployConfig implements ConfigurationListener { private LdapName serviceDn(String factoryPid, String cn) { try { - return (LdapName) serviceFactoryDn(factoryPid).add(new Rdn(NodeConstants.CN, cn)); + return (LdapName) serviceFactoryDn(factoryPid).add(new Rdn(CmsConstants.CN, cn)); } catch (InvalidNameException e) { throw new IllegalArgumentException("Cannot generate DN from " + factoryPid + " and " + cn, e); } diff --git a/org.argeo.cms/src/org/argeo/cms/internal/kernel/InitUtils.java b/org.argeo.cms/src/org/argeo/cms/internal/kernel/InitUtils.java index 98b625a98..a2006a704 100644 --- a/org.argeo.cms/src/org/argeo/cms/internal/kernel/InitUtils.java +++ b/org.argeo.cms/src/org/argeo/cms/internal/kernel/InitUtils.java @@ -21,9 +21,8 @@ import java.util.List; import javax.security.auth.x500.X500Principal; import org.apache.commons.io.FileUtils; -import org.apache.commons.logging.Log; -import org.apache.commons.logging.LogFactory; -import org.argeo.api.NodeConstants; +import org.argeo.api.cms.CmsConstants; +import org.argeo.api.cms.CmsLog; import org.argeo.cms.internal.http.InternalHttpConstants; import org.argeo.osgi.useradmin.UserAdminConf; @@ -32,7 +31,7 @@ import org.argeo.osgi.useradmin.UserAdminConf; * configuration. */ class InitUtils { - private final static Log log = LogFactory.getLog(InitUtils.class); + private final static CmsLog log = CmsLog.getLog(InitUtils.class); /** Override the provided config with the framework properties */ @@ -118,7 +117,7 @@ class InitUtils { if (webSocketEnabled != null && webSocketEnabled.equals("true")) props.put(InternalHttpConstants.WEBSOCKET_ENABLED, true); - props.put(NodeConstants.CN, NodeConstants.DEFAULT); + props.put(CmsConstants.CN, CmsConstants.DEFAULT); } return props; } @@ -129,8 +128,8 @@ class InitUtils { List uris = new ArrayList<>(); // node roles - String nodeRolesUri = getFrameworkProp(NodeConstants.ROLES_URI); - String baseNodeRoleDn = NodeConstants.ROLES_BASEDN; + String nodeRolesUri = getFrameworkProp(CmsConstants.ROLES_URI); + String baseNodeRoleDn = CmsConstants.ROLES_BASEDN; if (nodeRolesUri == null) { nodeRolesUri = baseNodeRoleDn + ".ldif"; File nodeRolesFile = new File(nodeBaseDir, nodeRolesUri); @@ -146,8 +145,8 @@ class InitUtils { uris.add(nodeRolesUri); // node tokens - String nodeTokensUri = getFrameworkProp(NodeConstants.TOKENS_URI); - String baseNodeTokensDn = NodeConstants.TOKENS_BASEDN; + String nodeTokensUri = getFrameworkProp(CmsConstants.TOKENS_URI); + String baseNodeTokensDn = CmsConstants.TOKENS_BASEDN; if (nodeTokensUri == null) { nodeTokensUri = baseNodeTokensDn + ".ldif"; File nodeTokensFile = new File(nodeBaseDir, nodeTokensUri); @@ -163,7 +162,7 @@ class InitUtils { uris.add(nodeTokensUri); // Business roles - String userAdminUris = getFrameworkProp(NodeConstants.USERADMIN_URIS); + String userAdminUris = getFrameworkProp(CmsConstants.USERADMIN_URIS); if (userAdminUris == null) { String demoBaseDn = "dc=example,dc=com"; userAdminUris = demoBaseDn + ".ldif"; @@ -220,7 +219,7 @@ class InitUtils { * some files (typically LDIF, etc). */ static void prepareFirstInitInstanceArea() { - String nodeInits = getFrameworkProp(NodeConstants.NODE_INIT); + String nodeInits = getFrameworkProp(CmsConstants.NODE_INIT); if (nodeInits == null) nodeInits = "../../init"; diff --git a/org.argeo.cms/src/org/argeo/cms/internal/kernel/KernelConstants.java b/org.argeo.cms/src/org/argeo/cms/internal/kernel/KernelConstants.java index 7d14ae9e6..90f2382d7 100644 --- a/org.argeo.cms/src/org/argeo/cms/internal/kernel/KernelConstants.java +++ b/org.argeo.cms/src/org/argeo/cms/internal/kernel/KernelConstants.java @@ -1,6 +1,6 @@ package org.argeo.cms.internal.kernel; -import org.argeo.api.NodeConstants; +import org.argeo.api.cms.CmsConstants; /** Internal CMS constants. */ public interface KernelConstants { @@ -11,10 +11,10 @@ public interface KernelConstants { String DIR_TRANSACTIONS = "transactions"; // Files - String DEPLOY_CONFIG_PATH = DIR_NODE + '/' + NodeConstants.DEPLOY_BASEDN + ".ldif"; - String DEFAULT_KEYSTORE_PATH = DIR_NODE + '/' + NodeConstants.NODE + ".p12"; - String DEFAULT_PEM_KEY_PATH = DIR_NODE + '/' + NodeConstants.NODE + ".key"; - String DEFAULT_PEM_CERT_PATH = DIR_NODE + '/' + NodeConstants.NODE + ".crt"; + String DEPLOY_CONFIG_PATH = DIR_NODE + '/' + CmsConstants.DEPLOY_BASEDN + ".ldif"; + String DEFAULT_KEYSTORE_PATH = DIR_NODE + '/' + CmsConstants.NODE + ".p12"; + String DEFAULT_PEM_KEY_PATH = DIR_NODE + '/' + CmsConstants.NODE + ".key"; + String DEFAULT_PEM_CERT_PATH = DIR_NODE + '/' + CmsConstants.NODE + ".crt"; String NODE_KEY_TAB_PATH = DIR_NODE + "/krb5.keytab"; // Security diff --git a/org.argeo.cms/src/org/argeo/cms/internal/kernel/KernelUtils.java b/org.argeo.cms/src/org/argeo/cms/internal/kernel/KernelUtils.java index f29d9e98e..f267933cf 100644 --- a/org.argeo.cms/src/org/argeo/cms/internal/kernel/KernelUtils.java +++ b/org.argeo.cms/src/org/argeo/cms/internal/kernel/KernelUtils.java @@ -15,7 +15,7 @@ import java.util.Properties; import java.util.TreeMap; import java.util.TreeSet; -import org.apache.commons.logging.Log; +import org.argeo.api.cms.CmsLog; import org.argeo.cms.osgi.DataModelNamespace; import org.osgi.framework.BundleContext; import org.osgi.util.tracker.ServiceTracker; @@ -120,7 +120,7 @@ class KernelUtils implements KernelConstants { // } // } - static void logFrameworkProperties(Log log) { + static void logFrameworkProperties(CmsLog log) { BundleContext bc = getBundleContext(); for (Object sysProp : new TreeSet(System.getProperties().keySet())) { log.debug(sysProp + "=" + bc.getProperty(sysProp.toString())); diff --git a/org.argeo.cms/src/org/argeo/cms/internal/kernel/NodeLogger.java b/org.argeo.cms/src/org/argeo/cms/internal/kernel/NodeLogger.java index 89c7e05a6..0b4103794 100644 --- a/org.argeo.cms/src/org/argeo/cms/internal/kernel/NodeLogger.java +++ b/org.argeo.cms/src/org/argeo/cms/internal/kernel/NodeLogger.java @@ -23,11 +23,10 @@ import java.util.Properties; import java.util.concurrent.BlockingQueue; import java.util.concurrent.LinkedBlockingQueue; -import org.apache.commons.logging.Log; -import org.apache.commons.logging.LogFactory; -import org.argeo.api.ArgeoLogListener; -import org.argeo.api.ArgeoLogger; -import org.argeo.api.NodeConstants; +import org.argeo.api.cms.CmsConstants; +import org.argeo.api.cms.CmsLog; +import org.argeo.cms.ArgeoLogListener; +import org.argeo.cms.ArgeoLogger; import org.argeo.cms.CmsException; import org.argeo.cms.auth.CurrentUser; import org.argeo.osgi.useradmin.UserAdminConf; @@ -151,7 +150,7 @@ class NodeLogger implements ArgeoLogger, LogListener { // @Override public void logged(LogEntry status) { - Log pluginLog = LogFactory.getLog(status.getBundle().getSymbolicName()); + CmsLog pluginLog = CmsLog.getLog(status.getBundle().getSymbolicName()); LogLevel severity = status.getLogLevel(); if (severity.equals(LogLevel.ERROR) && pluginLog.isErrorEnabled()) { // FIXME Fix Argeo TP @@ -190,9 +189,9 @@ class NodeLogger implements ArgeoLogger, LogListener { } else { sb.append(arrayToString(objectClasses)); } - Object cn = sr.getProperty(NodeConstants.CN); + Object cn = sr.getProperty(CmsConstants.CN); if (cn != null) - sb.append(" " + NodeConstants.CN + ": " + cn); + sb.append(" " + CmsConstants.CN + ": " + cn); Object factoryPid = sr.getProperty(ConfigurationAdmin.SERVICE_FACTORYPID); if (factoryPid != null) sb.append(" " + ConfigurationAdmin.SERVICE_FACTORYPID + ": " + factoryPid); diff --git a/org.argeo.cms/src/org/argeo/cms/internal/kernel/NodeUserAdmin.java b/org.argeo.cms/src/org/argeo/cms/internal/kernel/NodeUserAdmin.java index 11efa9e0f..17daa3e14 100644 --- a/org.argeo.cms/src/org/argeo/cms/internal/kernel/NodeUserAdmin.java +++ b/org.argeo.cms/src/org/argeo/cms/internal/kernel/NodeUserAdmin.java @@ -31,14 +31,13 @@ import org.apache.commons.httpclient.auth.CredentialsProvider; import org.apache.commons.httpclient.params.DefaultHttpParams; import org.apache.commons.httpclient.params.HttpMethodParams; import org.apache.commons.httpclient.params.HttpParams; -import org.apache.commons.logging.Log; -import org.apache.commons.logging.LogFactory; -import org.argeo.api.NodeConstants; +import org.argeo.api.cms.CmsAuth; +import org.argeo.api.cms.CmsConstants; +import org.argeo.api.cms.CmsLog; import org.argeo.cms.CmsUserManager; import org.argeo.cms.internal.auth.CmsUserManagerImpl; import org.argeo.cms.internal.http.client.HttpCredentialProvider; import org.argeo.cms.internal.http.client.SpnegoAuthScheme; -import org.argeo.naming.DnsBrowser; import org.argeo.osgi.transaction.WorkControl; import org.argeo.osgi.transaction.WorkTransaction; import org.argeo.osgi.useradmin.AbstractUserDirectory; @@ -48,6 +47,7 @@ import org.argeo.osgi.useradmin.LdifUserAdmin; import org.argeo.osgi.useradmin.OsUserDirectory; import org.argeo.osgi.useradmin.UserAdminConf; import org.argeo.osgi.useradmin.UserDirectory; +import org.argeo.util.naming.DnsBrowser; import org.ietf.jgss.GSSCredential; import org.ietf.jgss.GSSException; import org.ietf.jgss.GSSManager; @@ -67,7 +67,7 @@ import org.osgi.util.tracker.ServiceTracker; * roles. */ class NodeUserAdmin extends AggregatingUserAdmin implements ManagedServiceFactory, KernelConstants { - private final static Log log = LogFactory.getLog(NodeUserAdmin.class); + private final static CmsLog log = CmsLog.getLog(NodeUserAdmin.class); // private final BundleContext bc = FrameworkUtil.getBundle(getClass()).getBundleContext(); // OSGi @@ -166,7 +166,7 @@ class NodeUserAdmin extends AggregatingUserAdmin implements ManagedServiceFactor if (isSystemRolesBaseDn(baseDn)) { // publishes only when system roles are available Dictionary userAdminregProps = new Hashtable<>(); - userAdminregProps.put(NodeConstants.CN, NodeConstants.DEFAULT); + userAdminregProps.put(CmsConstants.CN, CmsConstants.DEFAULT); userAdminregProps.put(Constants.SERVICE_RANKING, Integer.MAX_VALUE); Activator.registerService(UserAdmin.class, this, userAdminregProps); } @@ -205,9 +205,9 @@ class NodeUserAdmin extends AggregatingUserAdmin implements ManagedServiceFactor @Override protected void addAbstractSystemRoles(Authorization rawAuthorization, Set sysRoles) { if (rawAuthorization.getName() == null) { - sysRoles.add(NodeConstants.ROLE_ANONYMOUS); + sysRoles.add(CmsConstants.ROLE_ANONYMOUS); } else { - sysRoles.add(NodeConstants.ROLE_USER); + sysRoles.add(CmsConstants.ROLE_USER); } } @@ -235,7 +235,7 @@ class NodeUserAdmin extends AggregatingUserAdmin implements ManagedServiceFactor } }; try { - LoginContext nodeLc = new LoginContext(NodeConstants.LOGIN_CONTEXT_NODE, callbackHandler); + LoginContext nodeLc = new LoginContext(CmsAuth.LOGIN_CONTEXT_NODE, callbackHandler); nodeLc.login(); acceptorCredentials = logInAsAcceptor(nodeLc.getSubject(), servicePrincipal); } catch (LoginException e) { diff --git a/org.argeo.cms/src/org/argeo/cms/internal/kernel/jaas-ipa.cfg b/org.argeo.cms/src/org/argeo/cms/internal/kernel/jaas-ipa.cfg index cf16719bd..c7c804c64 100644 --- a/org.argeo.cms/src/org/argeo/cms/internal/kernel/jaas-ipa.cfg +++ b/org.argeo.cms/src/org/argeo/cms/internal/kernel/jaas-ipa.cfg @@ -11,7 +11,7 @@ ANONYMOUS { }; DATA_ADMIN { - org.argeo.api.DataAdminLoginModule requisite; + org.argeo.cms.auth.DataAdminLoginModule requisite; }; NODE { @@ -19,7 +19,7 @@ NODE { keyTab="${osgi.instance.area}node/krb5.keytab" useKeyTab=true storeKey=true; - org.argeo.api.DataAdminLoginModule requisite; + org.argeo.cms.auth.DataAdminLoginModule requisite; }; KEYRING { diff --git a/org.argeo.cms/src/org/argeo/cms/internal/kernel/jaas.cfg b/org.argeo.cms/src/org/argeo/cms/internal/kernel/jaas.cfg index 441e1bf2a..364977d4b 100644 --- a/org.argeo.cms/src/org/argeo/cms/internal/kernel/jaas.cfg +++ b/org.argeo.cms/src/org/argeo/cms/internal/kernel/jaas.cfg @@ -10,11 +10,11 @@ ANONYMOUS { }; DATA_ADMIN { - org.argeo.api.DataAdminLoginModule requisite; + org.argeo.cms.auth.DataAdminLoginModule requisite; }; NODE { - org.argeo.api.DataAdminLoginModule requisite; + org.argeo.cms.auth.DataAdminLoginModule requisite; }; KEYRING { diff --git a/org.argeo.cms/src/org/argeo/cms/security/AbstractKeyring.java b/org.argeo.cms/src/org/argeo/cms/security/AbstractKeyring.java index cc8294da7..08ac54936 100644 --- a/org.argeo.cms/src/org/argeo/cms/security/AbstractKeyring.java +++ b/org.argeo.cms/src/org/argeo/cms/security/AbstractKeyring.java @@ -26,10 +26,7 @@ import javax.security.auth.login.LoginContext; import javax.security.auth.login.LoginException; import org.apache.commons.io.IOUtils; -import org.argeo.api.NodeConstants; -import org.argeo.api.security.CryptoKeyring; -import org.argeo.api.security.Keyring; -import org.argeo.api.security.PBEKeySpecCallback; +import org.argeo.api.cms.CmsAuth; import org.argeo.cms.CmsException; /** username / password based keyring. TODO internationalize */ @@ -77,7 +74,7 @@ public abstract class AbstractKeyring implements Keyring, CryptoKeyring { ClassLoader currentContextClassLoader = Thread.currentThread().getContextClassLoader(); Thread.currentThread().setContextClassLoader(getClass().getClassLoader()); try { - LoginContext loginContext = new LoginContext(NodeConstants.LOGIN_CONTEXT_KEYRING, subject, + LoginContext loginContext = new LoginContext(CmsAuth.LOGIN_CONTEXT_KEYRING, subject, callbackHandler); loginContext.login(); // FIXME will login even if password is wrong diff --git a/org.argeo.cms/src/org/argeo/cms/security/CryptoKeyring.java b/org.argeo.cms/src/org/argeo/cms/security/CryptoKeyring.java new file mode 100644 index 000000000..df26c6b41 --- /dev/null +++ b/org.argeo.cms/src/org/argeo/cms/security/CryptoKeyring.java @@ -0,0 +1,10 @@ +package org.argeo.cms.security; + +/** + * Marker interface for an advanced keyring based on cryptography. + */ +public interface CryptoKeyring extends Keyring { + public void changePassword(char[] oldPassword, char[] newPassword); + + public void unlock(char[] password); +} diff --git a/org.argeo.cms/src/org/argeo/cms/security/Keyring.java b/org.argeo.cms/src/org/argeo/cms/security/Keyring.java new file mode 100644 index 000000000..53740c693 --- /dev/null +++ b/org.argeo.cms/src/org/argeo/cms/security/Keyring.java @@ -0,0 +1,26 @@ +package org.argeo.cms.security; + +import java.io.InputStream; + +/** + * Access to private (typically encrypted) data. The keyring is responsible for + * retrieving the necessary credentials. Experimental. This API may + * change. + */ +public interface Keyring { + /** + * Returns the confidential information as chars. Must ask for it if it is + * not stored. + */ + public char[] getAsChars(String path); + + /** + * Returns the confidential information as a stream. Must ask for it if it + * is not stored. + */ + public InputStream getAsStream(String path); + + public void set(String path, char[] arr); + + public void set(String path, InputStream in); +} diff --git a/org.argeo.cms/src/org/argeo/cms/security/NodeSecurityUtils.java b/org.argeo.cms/src/org/argeo/cms/security/NodeSecurityUtils.java new file mode 100644 index 000000000..fb5394058 --- /dev/null +++ b/org.argeo.cms/src/org/argeo/cms/security/NodeSecurityUtils.java @@ -0,0 +1,40 @@ +package org.argeo.cms.security; + +import java.util.Arrays; +import java.util.Collections; +import java.util.List; + +import javax.naming.InvalidNameException; +import javax.naming.ldap.LdapName; + +import org.argeo.api.cms.CmsConstants; + +public class NodeSecurityUtils { + public final static LdapName ROLE_ADMIN_NAME, ROLE_DATA_ADMIN_NAME, ROLE_ANONYMOUS_NAME, ROLE_USER_NAME, + ROLE_USER_ADMIN_NAME; + public final static List RESERVED_ROLES; + static { + try { + ROLE_ADMIN_NAME = new LdapName(CmsConstants.ROLE_ADMIN); + ROLE_DATA_ADMIN_NAME = new LdapName(CmsConstants.ROLE_DATA_ADMIN); + ROLE_USER_NAME = new LdapName(CmsConstants.ROLE_USER); + ROLE_USER_ADMIN_NAME = new LdapName(CmsConstants.ROLE_USER_ADMIN); + ROLE_ANONYMOUS_NAME = new LdapName(CmsConstants.ROLE_ANONYMOUS); + RESERVED_ROLES = Collections.unmodifiableList(Arrays.asList( + new LdapName[] { ROLE_ADMIN_NAME, ROLE_ANONYMOUS_NAME, ROLE_USER_NAME, ROLE_USER_ADMIN_NAME })); + } catch (InvalidNameException e) { + throw new Error("Cannot initialize login module class", e); + } + } + + public static void checkUserName(LdapName name) throws IllegalArgumentException { + if (RESERVED_ROLES.contains(name)) + throw new IllegalArgumentException(name + " is a reserved name"); + } + + public static void checkImpliedPrincipalName(LdapName roleName) throws IllegalArgumentException { +// if (ROLE_USER_NAME.equals(roleName) || ROLE_ANONYMOUS_NAME.equals(roleName)) +// throw new IllegalArgumentException(roleName + " cannot be listed as role"); + } + +} diff --git a/org.argeo.cms/src/org/argeo/cms/security/PBEKeySpecCallback.java b/org.argeo.cms/src/org/argeo/cms/security/PBEKeySpecCallback.java new file mode 100644 index 000000000..13e8d753b --- /dev/null +++ b/org.argeo.cms/src/org/argeo/cms/security/PBEKeySpecCallback.java @@ -0,0 +1,63 @@ +package org.argeo.cms.security; + +import javax.crypto.spec.PBEKeySpec; +import javax.security.auth.callback.Callback; +import javax.security.auth.callback.PasswordCallback; + +/** + * All information required to set up a {@link PBEKeySpec} bar the password + * itself (use a {@link PasswordCallback}) + */ +public class PBEKeySpecCallback implements Callback { + private String secretKeyFactory; + private byte[] salt; + private Integer iterationCount; + /** Can be null for some algorithms */ + private Integer keyLength; + /** Can be null, will trigger secret key encryption if not */ + private String secretKeyEncryption; + + private String encryptedPasswordHashCipher; + private byte[] encryptedPasswordHash; + + public void set(String secretKeyFactory, byte[] salt, + Integer iterationCount, Integer keyLength, + String secretKeyEncryption) { + this.secretKeyFactory = secretKeyFactory; + this.salt = salt; + this.iterationCount = iterationCount; + this.keyLength = keyLength; + this.secretKeyEncryption = secretKeyEncryption; +// this.encryptedPasswordHashCipher = encryptedPasswordHashCipher; +// this.encryptedPasswordHash = encryptedPasswordHash; + } + + public String getSecretKeyFactory() { + return secretKeyFactory; + } + + public byte[] getSalt() { + return salt; + } + + public Integer getIterationCount() { + return iterationCount; + } + + public Integer getKeyLength() { + return keyLength; + } + + public String getSecretKeyEncryption() { + return secretKeyEncryption; + } + + public String getEncryptedPasswordHashCipher() { + return encryptedPasswordHashCipher; + } + + public byte[] getEncryptedPasswordHash() { + return encryptedPasswordHash; + } + +} diff --git a/org.argeo.cms/src/org/argeo/cms/tabular/ArrayTabularRow.java b/org.argeo.cms/src/org/argeo/cms/tabular/ArrayTabularRow.java new file mode 100644 index 000000000..cfd482729 --- /dev/null +++ b/org.argeo.cms/src/org/argeo/cms/tabular/ArrayTabularRow.java @@ -0,0 +1,25 @@ +package org.argeo.cms.tabular; + +import java.util.List; + +/** Minimal tabular row wrapping an {@link Object} array */ +public class ArrayTabularRow implements TabularRow { + private final Object[] arr; + + public ArrayTabularRow(List objs) { + this.arr = objs.toArray(); + } + + public Object get(Integer col) { + return arr[col]; + } + + public int size() { + return arr.length; + } + + public Object[] toArray() { + return arr; + } + +} diff --git a/org.argeo.cms/src/org/argeo/cms/tabular/TabularColumn.java b/org.argeo.cms/src/org/argeo/cms/tabular/TabularColumn.java new file mode 100644 index 000000000..7f7ac1e61 --- /dev/null +++ b/org.argeo.cms/src/org/argeo/cms/tabular/TabularColumn.java @@ -0,0 +1,41 @@ +package org.argeo.cms.tabular; + +/** The column in a tabular content */ +public class TabularColumn { + private String name; + /** + * JCR types, see + * http://www.day.com/maven/javax.jcr/javadocs/jcr-2.0/index.html + * ?javax/jcr/PropertyType.html + */ + private Integer type; + + /** column with default type */ + public TabularColumn(String name) { + super(); + this.name = name; + } + + public TabularColumn(String name, Integer type) { + super(); + this.name = name; + this.type = type; + } + + public String getName() { + return name; + } + + public void setName(String name) { + this.name = name; + } + + public Integer getType() { + return type; + } + + public void setType(Integer type) { + this.type = type; + } + +} diff --git a/org.argeo.cms/src/org/argeo/cms/tabular/TabularContent.java b/org.argeo.cms/src/org/argeo/cms/tabular/TabularContent.java new file mode 100644 index 000000000..c6d2ab88d --- /dev/null +++ b/org.argeo.cms/src/org/argeo/cms/tabular/TabularContent.java @@ -0,0 +1,14 @@ +package org.argeo.cms.tabular; + +import java.util.List; + +/** + * Content organized as a table, possibly with headers. Only JCR types are + * supported even though there is not direct dependency on JCR. + */ +public interface TabularContent { + /** The headers of this table or null is none available. */ + public List getColumns(); + + public TabularRowIterator read(); +} diff --git a/org.argeo.cms/src/org/argeo/cms/tabular/TabularRow.java b/org.argeo.cms/src/org/argeo/cms/tabular/TabularRow.java new file mode 100644 index 000000000..69b973252 --- /dev/null +++ b/org.argeo.cms/src/org/argeo/cms/tabular/TabularRow.java @@ -0,0 +1,13 @@ +package org.argeo.cms.tabular; + +/** A row of tabular data */ +public interface TabularRow { + /** The value at this column index */ + public Object get(Integer col); + + /** The raw objects (direct references) */ + public Object[] toArray(); + + /** Number of columns */ + public int size(); +} diff --git a/org.argeo.cms/src/org/argeo/cms/tabular/TabularRowIterator.java b/org.argeo.cms/src/org/argeo/cms/tabular/TabularRowIterator.java new file mode 100644 index 000000000..7ad8719e5 --- /dev/null +++ b/org.argeo.cms/src/org/argeo/cms/tabular/TabularRowIterator.java @@ -0,0 +1,12 @@ +package org.argeo.cms.tabular; + +import java.util.Iterator; + +/** Navigation of rows */ +public interface TabularRowIterator extends Iterator { + /** + * Current row number, has to be incremented by each call to next() ; starts at 0, will + * therefore be 1 for the first row returned. + */ + public Long getCurrentRowNumber(); +} diff --git a/org.argeo.cms/src/org/argeo/cms/tabular/TabularWriter.java b/org.argeo.cms/src/org/argeo/cms/tabular/TabularWriter.java new file mode 100644 index 000000000..34fc85b7f --- /dev/null +++ b/org.argeo.cms/src/org/argeo/cms/tabular/TabularWriter.java @@ -0,0 +1,11 @@ +package org.argeo.cms.tabular; + + +/** Write to a tabular content */ +public interface TabularWriter { + /** Append a new row of data */ + public void appendRow(Object[] row); + + /** Finish persisting data and release resources */ + public void close(); +} diff --git a/org.argeo.cms/src/org/argeo/cms/tabular/package-info.java b/org.argeo.cms/src/org/argeo/cms/tabular/package-info.java new file mode 100644 index 000000000..6cb48d07f --- /dev/null +++ b/org.argeo.cms/src/org/argeo/cms/tabular/package-info.java @@ -0,0 +1,2 @@ +/** Tabular format API. */ +package org.argeo.cms.tabular; \ No newline at end of file diff --git a/org.argeo.init/bnd.bnd b/org.argeo.init/bnd.bnd index 122d7f586..5074d5d1b 100644 --- a/org.argeo.init/bnd.bnd +++ b/org.argeo.init/bnd.bnd @@ -6,6 +6,3 @@ Bundle-Activator: org.argeo.init.osgi.Activator Import-Package: \ org.osgi.*;version=0.0.0,\ java.util.logging.*;resolution:=optional - -Private-Package: * -Export-Package: !* diff --git a/org.argeo.util/src/org/argeo/ident/IdentClient.java b/org.argeo.util/src/org/argeo/ident/IdentClient.java deleted file mode 100644 index c42da9778..000000000 --- a/org.argeo.util/src/org/argeo/ident/IdentClient.java +++ /dev/null @@ -1,124 +0,0 @@ -package org.argeo.ident; - -import java.io.BufferedReader; -import java.io.IOException; -import java.io.InputStreamReader; -import java.io.OutputStream; -import java.net.ConnectException; -import java.net.Socket; -import java.nio.charset.StandardCharsets; -import java.nio.file.Files; -import java.nio.file.Path; -import java.nio.file.Paths; -import java.util.List; -import java.util.StringTokenizer; - -/** - * A simple ident client, supporting authd OpenSSL encrypted username. - * - * @see RFC 1413 https://tools.ietf.org/html/rfc1413 - */ -public class IdentClient { - public final static int DEFAULT_IDENT_PORT = 113; - public final static String AUTHD_PASSPHRASE_PATH = "/etc/ident.key"; - final static String NO_USER = "NO-USER"; - - private final String host; - private final int port; - - private OpenSslDecryptor openSslDecryptor = new OpenSslDecryptor(); - private String identPassphrase = null; - - public IdentClient(String host) { - this(host, readPassphrase(AUTHD_PASSPHRASE_PATH), DEFAULT_IDENT_PORT); - } - - public IdentClient(String host, Path passPhrasePath) { - this(host, readPassphrase(passPhrasePath), DEFAULT_IDENT_PORT); - } - - public IdentClient(String host, String identPassphrase) { - this(host, identPassphrase, DEFAULT_IDENT_PORT); - } - - public IdentClient(String host, String identPassphrase, int port) { - this.host = host; - this.identPassphrase = identPassphrase; - this.port = port; - } - - /** @return the username or null if none */ - public String getUsername(int serverPort, int clientPort) { - String answer; - try (Socket socket = new Socket(host, port)) { - String msg = clientPort + "," + serverPort + "\n"; - OutputStream out = socket.getOutputStream(); - out.write(msg.getBytes(StandardCharsets.US_ASCII)); - out.flush(); - BufferedReader reader = new BufferedReader(new InputStreamReader(socket.getInputStream())); - answer = reader.readLine(); - } catch (ConnectException e) { - System.err.println( - "Ident client is configured but no ident server available on " + host + " (port " + port + ")"); - return null; - } catch (Exception e) { - throw new RuntimeException("Cannot read from ident server on " + host + " (port " + port + ")", e); - } - StringTokenizer st = new StringTokenizer(answer, " :\n"); - String username = null; - while (st.hasMoreTokens()) - username = st.nextToken(); - - if (username.equals(NO_USER)) - return null; - - if (identPassphrase != null && username.startsWith("[")) { - String encrypted = username.substring(1, username.length() - 1); - username = openSslDecryptor.decryptAuthd(encrypted, identPassphrase).trim(); - } -// System.out.println(username); - return username; - } - - public void setOpenSslDecryptor(OpenSslDecryptor openSslDecryptor) { - this.openSslDecryptor = openSslDecryptor; - } - - public static String readPassphrase(String filePath) { - return readPassphrase(Paths.get(filePath)); - } - - /** @return the first line of the file. */ - public static String readPassphrase(Path path) { - if (!isPathAvailable(path)) - return null; - List lines; - try { - lines = Files.readAllLines(path); - } catch (IOException e) { - throw new IllegalStateException("Cannot read " + path, e); - } - if (lines.size() == 0) - return null; - String passphrase = lines.get(0); - return passphrase; - } - - public static boolean isDefaultAuthdPassphraseFileAvailable() { - return isPathAvailable(Paths.get(AUTHD_PASSPHRASE_PATH)); - } - - public static boolean isPathAvailable(Path path) { - if (!Files.exists(path)) - return false; - if (!Files.isReadable(path)) - return false; - return true; - } - - public static void main(String[] args) { - IdentClient identClient = new IdentClient("127.0.0.1", "changeit"); - String username = identClient.getUsername(7070, 55958); - System.out.println(username); - } -} diff --git a/org.argeo.util/src/org/argeo/ident/OpenSslDecryptor.java b/org.argeo.util/src/org/argeo/ident/OpenSslDecryptor.java deleted file mode 100644 index 702b09bfe..000000000 --- a/org.argeo.util/src/org/argeo/ident/OpenSslDecryptor.java +++ /dev/null @@ -1,162 +0,0 @@ -package org.argeo.ident; - -import java.nio.charset.StandardCharsets; -import java.security.GeneralSecurityException; -import java.security.MessageDigest; -import java.util.Arrays; -import java.util.Base64; - -import javax.crypto.BadPaddingException; -import javax.crypto.Cipher; -import javax.crypto.IllegalBlockSizeException; -import javax.crypto.spec.IvParameterSpec; -import javax.crypto.spec.SecretKeySpec; - -/** - * Decrypts OpenSSL encrypted data. - * - * From - * https://stackoverflow.com/questions/11783062/how-to-decrypt-file-in-java-encrypted-with-openssl-command-using-aes - * - * See also - * https://stackoverflow.com/questions/54171959/badpadding-exception-when-trying-to-decrypt-aes-based-encrypted-text/54173509#54173509 - * for new default message digest (not yet in CentOS 7 as of July 2019) - */ -public class OpenSslDecryptor { - private static final int INDEX_KEY = 0; - private static final int INDEX_IV = 1; - private static final int ITERATIONS = 1; - - private static final int SALT_OFFSET = 8; - private static final int SALT_SIZE = 8; - private static final int CIPHERTEXT_OFFSET = SALT_OFFSET + SALT_SIZE; - - /** In bits. */ - private final int keySize; - - private Cipher cipher; - private MessageDigest messageDigest; - - public OpenSslDecryptor() { - /* - * Changed to SHA-256 from OpenSSL v1.1.0 (see - * https://stackoverflow.com/questions/39637388/encryption-decryption-doesnt- - * work-well-between-two-different-openssl-versions) - */ - this(128, "MD5"); - } - - public OpenSslDecryptor(int keySize, String messageDigest) { - this.keySize = keySize; - try { - this.cipher = Cipher.getInstance("AES/CBC/PKCS5Padding"); - this.messageDigest = MessageDigest.getInstance(messageDigest); - } catch (GeneralSecurityException e) { - throw new IllegalArgumentException("Cannot initialise decryptor", e); - } - } - - public String decryptAuthd(String dataBase64, String passphrase) { - try { - byte[] headerSaltAndCipherText = Base64.getDecoder().decode(dataBase64); - - boolean withSalt = true; - byte[] salt = withSalt ? Arrays.copyOfRange(headerSaltAndCipherText, SALT_OFFSET, SALT_OFFSET + SALT_SIZE) - : null; - byte[] encrypted = withSalt - ? Arrays.copyOfRange(headerSaltAndCipherText, CIPHERTEXT_OFFSET, headerSaltAndCipherText.length) - : headerSaltAndCipherText; - - final byte[][] keyAndIV = EVP_BytesToKey(keySize / Byte.SIZE, cipher.getBlockSize(), messageDigest, salt, - passphrase.getBytes(StandardCharsets.US_ASCII), ITERATIONS); - SecretKeySpec key = new SecretKeySpec(keyAndIV[INDEX_KEY], "AES"); - IvParameterSpec iv = new IvParameterSpec(keyAndIV[INDEX_IV]); - - cipher.init(Cipher.DECRYPT_MODE, key, iv); - byte[] decrypted = cipher.doFinal(encrypted); - - String answer = new String(decrypted, StandardCharsets.US_ASCII); - return answer; - } catch (BadPaddingException e) { - throw new IllegalStateException("Bad password, algorithm, mode or padding;" - + " no salt, wrong number of iterations or corrupted ciphertext.", e); - } catch (IllegalBlockSizeException e) { - throw new IllegalStateException("Bad algorithm, mode or corrupted (resized) ciphertext.", e); - } catch (GeneralSecurityException e) { - throw new IllegalStateException(e); - } - } - - private static byte[][] EVP_BytesToKey(int key_len, int iv_len, MessageDigest md, byte[] salt, byte[] data, - int count) { - byte[][] both = new byte[2][]; - byte[] key = new byte[key_len]; - int key_ix = 0; - byte[] iv = new byte[iv_len]; - int iv_ix = 0; - both[0] = key; - both[1] = iv; - byte[] md_buf = null; - int nkey = key_len; - int niv = iv_len; - int i = 0; - if (data == null) { - return both; - } - int addmd = 0; - for (;;) { - md.reset(); - if (addmd++ > 0) { - md.update(md_buf); - } - md.update(data); - if (null != salt) { - md.update(salt, 0, 8); - } - md_buf = md.digest(); - for (i = 1; i < count; i++) { - md.reset(); - md.update(md_buf); - md_buf = md.digest(); - } - i = 0; - if (nkey > 0) { - for (;;) { - if (nkey == 0) - break; - if (i == md_buf.length) - break; - key[key_ix++] = md_buf[i]; - nkey--; - i++; - } - } - if (niv > 0 && i != md_buf.length) { - for (;;) { - if (niv == 0) - break; - if (i == md_buf.length) - break; - iv[iv_ix++] = md_buf[i]; - niv--; - i++; - } - } - if (nkey == 0 && niv == 0) { - break; - } - } - for (i = 0; i < md_buf.length; i++) { - md_buf[i] = 0; - } - return both; - } - - public static void main(String[] args) { - String dataBase64 = args[0]; - String passphrase = args[1]; - OpenSslDecryptor decryptor = new OpenSslDecryptor(); - System.out.println(decryptor.decryptAuthd(dataBase64, passphrase)); - } - -} \ No newline at end of file diff --git a/org.argeo.util/src/org/argeo/ident/package-info.java b/org.argeo.util/src/org/argeo/ident/package-info.java deleted file mode 100644 index 35dd1a29e..000000000 --- a/org.argeo.util/src/org/argeo/ident/package-info.java +++ /dev/null @@ -1,2 +0,0 @@ -/** Ident authentication protocol support. */ -package org.argeo.ident; \ No newline at end of file diff --git a/org.argeo.util/src/org/argeo/naming/AttributesDictionary.java b/org.argeo.util/src/org/argeo/naming/AttributesDictionary.java deleted file mode 100644 index e04721610..000000000 --- a/org.argeo.util/src/org/argeo/naming/AttributesDictionary.java +++ /dev/null @@ -1,171 +0,0 @@ -package org.argeo.naming; - -import java.util.Dictionary; -import java.util.Enumeration; - -import javax.naming.NamingEnumeration; -import javax.naming.NamingException; -import javax.naming.directory.Attribute; -import javax.naming.directory.Attributes; -import javax.naming.directory.BasicAttribute; - -public class AttributesDictionary extends Dictionary { - private final Attributes attributes; - - /** The provided attributes is wrapped, not copied. */ - public AttributesDictionary(Attributes attributes) { - if (attributes == null) - throw new IllegalArgumentException("Attributes cannot be null"); - this.attributes = attributes; - } - - @Override - public int size() { - return attributes.size(); - } - - @Override - public boolean isEmpty() { - return attributes.size() == 0; - } - - @Override - public Enumeration keys() { - NamingEnumeration namingEnumeration = attributes.getIDs(); - return new Enumeration() { - - @Override - public boolean hasMoreElements() { - return namingEnumeration.hasMoreElements(); - } - - @Override - public String nextElement() { - return namingEnumeration.nextElement(); - } - - }; - } - - @Override - public Enumeration elements() { - NamingEnumeration namingEnumeration = attributes.getIDs(); - return new Enumeration() { - - @Override - public boolean hasMoreElements() { - return namingEnumeration.hasMoreElements(); - } - - @Override - public Object nextElement() { - String key = namingEnumeration.nextElement(); - return get(key); - } - - }; - } - - @Override - /** @returns a String or String[] */ - public Object get(Object key) { - try { - if (key == null) - throw new IllegalArgumentException("Key cannot be null"); - Attribute attr = attributes.get(key.toString()); - if (attr == null) - return null; - if (attr.size() == 0) - throw new IllegalStateException("There must be at least one value"); - else if (attr.size() == 1) { - return attr.get().toString(); - } else {// multiple - String[] res = new String[attr.size()]; - for (int i = 0; i < attr.size(); i++) { - Object value = attr.get(); - if (value == null) - throw new RuntimeException("Values cannot be null"); - res[i] = attr.get(i).toString(); - } - return res; - } - } catch (NamingException e) { - throw new RuntimeException("Cannot get value for " + key, e); - } - } - - @Override - public Object put(String key, Object value) { - if (key == null) - throw new IllegalArgumentException("Key cannot be null"); - if (value == null) - throw new IllegalArgumentException("Value cannot be null"); - - Object oldValue = get(key); - Attribute attr = attributes.get(key); - if (attr == null) { - attr = new BasicAttribute(key); - attributes.put(attr); - } - - if (value instanceof String[]) { - String[] values = (String[]) value; - // clean additional values - for (int i = values.length; i < attr.size(); i++) - attr.remove(i); - // set values - for (int i = 0; i < values.length; i++) { - attr.set(i, values[i]); - } - } else { - if (attr.size() > 1) - throw new IllegalArgumentException("Attribute " + key + " is multi-valued"); - if (attr.size() == 1) { - try { - if (!attr.get(0).equals(value)) - attr.set(0, value.toString()); - } catch (NamingException e) { - throw new RuntimeException("Cannot check existing value", e); - } - } else { - attr.add(value.toString()); - } - } - return oldValue; - } - - @Override - public Object remove(Object key) { - if (key == null) - throw new IllegalArgumentException("Key cannot be null"); - Object oldValue = get(key); - if (oldValue == null) - return null; - return attributes.remove(key.toString()); - } - - /** - * Copy the content of an {@link Attributes} to the provided - * {@link Dictionary}. - */ - public static void copy(Attributes attributes, Dictionary dictionary) { - AttributesDictionary ad = new AttributesDictionary(attributes); - Enumeration keys = ad.keys(); - while (keys.hasMoreElements()) { - String key = keys.nextElement(); - dictionary.put(key, ad.get(key)); - } - } - - /** - * Copy a {@link Dictionary} into an {@link Attributes}. - */ - public static void copy(Dictionary dictionary, Attributes attributes) { - AttributesDictionary ad = new AttributesDictionary(attributes); - Enumeration keys = dictionary.keys(); - while (keys.hasMoreElements()) { - String key = keys.nextElement(); - ad.put(key, dictionary.get(key)); - } - } -} diff --git a/org.argeo.util/src/org/argeo/naming/AuthPassword.java b/org.argeo.util/src/org/argeo/naming/AuthPassword.java deleted file mode 100644 index 6d4c62b3f..000000000 --- a/org.argeo.util/src/org/argeo/naming/AuthPassword.java +++ /dev/null @@ -1,140 +0,0 @@ -package org.argeo.naming; - -import java.io.IOException; -import java.util.Arrays; -import java.util.StringTokenizer; - -import javax.naming.NamingEnumeration; -import javax.naming.NamingException; -import javax.naming.directory.Attribute; -import javax.naming.directory.Attributes; -import javax.security.auth.callback.Callback; -import javax.security.auth.callback.CallbackHandler; -import javax.security.auth.callback.NameCallback; -import javax.security.auth.callback.PasswordCallback; -import javax.security.auth.callback.UnsupportedCallbackException; - -import org.argeo.osgi.useradmin.UserDirectoryException; - -/** LDAP authPassword field according to RFC 3112 */ -public class AuthPassword implements CallbackHandler { - private final String authScheme; - private final String authInfo; - private final String authValue; - - public AuthPassword(String value) { - StringTokenizer st = new StringTokenizer(value, "$"); - // TODO make it more robust, deal with bad formatting - this.authScheme = st.nextToken().trim(); - this.authInfo = st.nextToken().trim(); - this.authValue = st.nextToken().trim(); - - String expectedAuthScheme = getExpectedAuthScheme(); - if (expectedAuthScheme != null && !authScheme.equals(expectedAuthScheme)) - throw new IllegalArgumentException( - "Auth scheme " + authScheme + " is not compatible with " + expectedAuthScheme); - } - - protected AuthPassword(String authInfo, String authValue) { - this.authScheme = getExpectedAuthScheme(); - if (authScheme == null) - throw new IllegalArgumentException("Expected auth scheme cannot be null"); - this.authInfo = authInfo; - this.authValue = authValue; - } - - protected AuthPassword(AuthPassword authPassword) { - this.authScheme = authPassword.getAuthScheme(); - this.authInfo = authPassword.getAuthInfo(); - this.authValue = authPassword.getAuthValue(); - } - - protected String getExpectedAuthScheme() { - return null; - } - - protected boolean matchAuthValue(Object object) { - return authValue.equals(object.toString()); - } - - @Override - public boolean equals(Object obj) { - if (!(obj instanceof AuthPassword)) - return false; - AuthPassword authPassword = (AuthPassword) obj; - return authScheme.equals(authPassword.authScheme) && authInfo.equals(authPassword.authInfo) - && authValue.equals(authValue); - } - - public boolean keyEquals(AuthPassword authPassword) { - return authScheme.equals(authPassword.authScheme) && authInfo.equals(authPassword.authInfo); - } - - @Override - public int hashCode() { - return authValue.hashCode(); - } - - @Override - public String toString() { - return toAuthPassword(); - } - - public final String toAuthPassword() { - return getAuthScheme() + '$' + authInfo + '$' + authValue; - } - - public String getAuthScheme() { - return authScheme; - } - - public String getAuthInfo() { - return authInfo; - } - - public String getAuthValue() { - return authValue; - } - - public static AuthPassword matchAuthValue(Attributes attributes, char[] value) { - try { - Attribute authPassword = attributes.get(LdapAttrs.authPassword.name()); - if (authPassword != null) { - NamingEnumeration values = authPassword.getAll(); - while (values.hasMore()) { - Object val = values.next(); - AuthPassword token = new AuthPassword(val.toString()); - String auth; - if (Arrays.binarySearch(value, '$') >= 0) { - auth = token.authInfo + '$' + token.authValue; - } else { - auth = token.authValue; - } - if (Arrays.equals(auth.toCharArray(), value)) - return token; - // if (token.matchAuthValue(value)) - // return token; - } - } - return null; - } catch (NamingException e) { - throw new UserDirectoryException("Cannot check attribute", e); - } - } - - public static boolean remove(Attributes attributes, AuthPassword value) { - Attribute authPassword = attributes.get(LdapAttrs.authPassword.name()); - return authPassword.remove(value.toAuthPassword()); - } - - @Override - public void handle(Callback[] callbacks) throws IOException, UnsupportedCallbackException { - for (Callback callback : callbacks) { - if (callback instanceof NameCallback) - ((NameCallback) callback).setName(toAuthPassword()); - else if (callback instanceof PasswordCallback) - ((PasswordCallback) callback).setPassword(getAuthValue().toCharArray()); - } - } - -} diff --git a/org.argeo.util/src/org/argeo/naming/Distinguished.java b/org.argeo.util/src/org/argeo/naming/Distinguished.java deleted file mode 100644 index 8b9c4b92b..000000000 --- a/org.argeo.util/src/org/argeo/naming/Distinguished.java +++ /dev/null @@ -1,36 +0,0 @@ -package org.argeo.naming; - -import java.util.EnumSet; -import java.util.Set; -import java.util.TreeSet; - -import javax.naming.InvalidNameException; -import javax.naming.ldap.LdapName; - -/** - * An object that can be identified with an X.500 distinguished name. - * - * @see https://tools.ietf.org/html/rfc1779 - */ -public interface Distinguished { - /** The related distinguished name. */ - String dn(); - - /** The related distinguished name as an {@link LdapName}. */ - default LdapName distinguishedName() { - try { - return new LdapName(dn()); - } catch (InvalidNameException e) { - throw new IllegalArgumentException("Distinguished name " + dn() + " is not properly formatted.", e); - } - } - - /** List all DNs of an enumeration as strings. */ - static Set enumToDns(EnumSet enumSet) { - Set res = new TreeSet<>(); - for (Enum enm : enumSet) { - res.add(((Distinguished) enm).dn()); - } - return res; - } -} diff --git a/org.argeo.util/src/org/argeo/naming/DnsBrowser.java b/org.argeo.util/src/org/argeo/naming/DnsBrowser.java deleted file mode 100644 index d9358c083..000000000 --- a/org.argeo.util/src/org/argeo/naming/DnsBrowser.java +++ /dev/null @@ -1,179 +0,0 @@ -package org.argeo.naming; - -import java.io.Closeable; -import java.io.IOException; -import java.io.PrintStream; -import java.util.ArrayList; -import java.util.Base64; -import java.util.Collections; -import java.util.Hashtable; -import java.util.List; -import java.util.Map; -import java.util.SortedSet; -import java.util.TreeMap; -import java.util.TreeSet; - -import javax.naming.Binding; -import javax.naming.NamingEnumeration; -import javax.naming.NamingException; -import javax.naming.directory.Attribute; -import javax.naming.directory.Attributes; -import javax.naming.directory.DirContext; -import javax.naming.directory.InitialDirContext; - -public class DnsBrowser implements Closeable { - private final DirContext initialCtx; - - public DnsBrowser() throws NamingException { - this(null); - } - - public DnsBrowser(String dnsServerUrls) throws NamingException { - Hashtable env = new Hashtable<>(); - env.put("java.naming.factory.initial", "com.sun.jndi.dns.DnsContextFactory"); - if (dnsServerUrls != null) - env.put("java.naming.provider.url", dnsServerUrls); - initialCtx = new InitialDirContext(env); - } - - public Map> getAllRecords(String name) throws NamingException { - Map> res = new TreeMap<>(); - Attributes attrs = initialCtx.getAttributes(name); - NamingEnumeration ids = attrs.getIDs(); - while (ids.hasMore()) { - String recordType = ids.next(); - List lst = new ArrayList(); - res.put(recordType, lst); - Attribute attr = attrs.get(recordType); - addValues(attr, lst); - } - return Collections.unmodifiableMap(res); - } - - /** - * Return a single record (typically A, AAAA, etc. or null if not available. - * Will fail if multiple records. - */ - public String getRecord(String name, String recordType) throws NamingException { - Attributes attrs = initialCtx.getAttributes(name, new String[] { recordType }); - if (attrs.size() == 0) - return null; - Attribute attr = attrs.get(recordType); - if (attr.size() > 1) - throw new IllegalArgumentException("Multiple record type " + recordType); - assert attr.size() != 0; - Object value = attr.get(); - assert value != null; - return value.toString(); - } - - /** - * Return records of a given type. - */ - public List getRecords(String name, String recordType) throws NamingException { - List res = new ArrayList(); - Attributes attrs = initialCtx.getAttributes(name, new String[] { recordType }); - Attribute attr = attrs.get(recordType); - addValues(attr, res); - return res; - } - - /** Ordered, with preferred first. */ - public List getSrvRecordsAsHosts(String name, boolean withPort) throws NamingException { - List raw = getRecords(name, "SRV"); - if (raw.size() == 0) - return null; - SortedSet res = new TreeSet<>(); - for (int i = 0; i < raw.size(); i++) { - String record = raw.get(i); - String[] arr = record.split(" "); - Integer priority = Integer.parseInt(arr[0]); - Integer weight = Integer.parseInt(arr[1]); - Integer port = Integer.parseInt(arr[2]); - String hostname = arr[3]; - SrvRecord order = new SrvRecord(priority, weight, port, hostname); - res.add(order); - } - List lst = new ArrayList<>(); - for (SrvRecord order : res) { - lst.add(order.toHost(withPort)); - } - return Collections.unmodifiableList(lst); - } - - private void addValues(Attribute attr, List lst) throws NamingException { - NamingEnumeration values = attr.getAll(); - while (values.hasMore()) { - Object value = values.next(); - if (value != null) { - if (value instanceof byte[]) { - String str = Base64.getEncoder().encodeToString((byte[]) value); - lst.add(str); - } else - lst.add(value.toString()); - } - } - - } - - public List listEntries(String name) throws NamingException { - List res = new ArrayList(); - NamingEnumeration ne = initialCtx.listBindings(name); - while (ne.hasMore()) { - Binding b = ne.next(); - res.add(b.getName()); - } - return Collections.unmodifiableList(res); - } - - @Override - public void close() throws IOException { - destroy(); - } - - public void destroy() { - try { - initialCtx.close(); - } catch (NamingException e) { - // silent - } - } - - public static void main(String[] args) { - if (args.length == 0) { - printUsage(System.err); - System.exit(1); - } - try (DnsBrowser dnsBrowser = new DnsBrowser()) { - String hostname = args[0]; - String recordType = args.length > 1 ? args[1] : "A"; - if (recordType.equals("*")) { - Map> records = dnsBrowser.getAllRecords(hostname); - for (String type : records.keySet()) { - for (String record : records.get(type)) { - String typeLabel; - if ("44".equals(type)) - typeLabel = "SSHFP"; - else if ("46".equals(type)) - typeLabel = "RRSIG"; - else if ("48".equals(type)) - typeLabel = "DNSKEY"; - else - typeLabel = type; - System.out.println(typeLabel + "\t" + record); - } - } - } else { - System.out.println(dnsBrowser.getRecord(hostname, recordType)); - } - - } catch (Exception e) { - e.printStackTrace(); - } - } - - public static void printUsage(PrintStream out) { - out.println("java org.argeo.naming.DnsBrowser [ | *]"); - } - -} \ No newline at end of file diff --git a/org.argeo.util/src/org/argeo/naming/LdapAttrs.csv b/org.argeo.util/src/org/argeo/naming/LdapAttrs.csv deleted file mode 100644 index 676d72720..000000000 --- a/org.argeo.util/src/org/argeo/naming/LdapAttrs.csv +++ /dev/null @@ -1,129 +0,0 @@ -uid,,,0.9.2342.19200300.100.1.1,,RFC 4519 -mail,,,0.9.2342.19200300.100.1.3,,RFC 4524 -info,,,0.9.2342.19200300.100.1.4,,RFC 4524 -drink,,,0.9.2342.19200300.100.1.5,,RFC 4524 -roomNumber,,,0.9.2342.19200300.100.1.6,,RFC 4524 -photo,,,0.9.2342.19200300.100.1.7,,RFC 2798 -userClass,,,0.9.2342.19200300.100.1.8,,RFC 4524 -host,,,0.9.2342.19200300.100.1.9,,RFC 4524 -manager,,,0.9.2342.19200300.100.1.10,,RFC 4524 -documentIdentifier,,,0.9.2342.19200300.100.1.11,,RFC 4524 -documentTitle,,,0.9.2342.19200300.100.1.12,,RFC 4524 -documentVersion,,,0.9.2342.19200300.100.1.13,,RFC 4524 -documentAuthor,,,0.9.2342.19200300.100.1.14,,RFC 4524 -documentLocation,,,0.9.2342.19200300.100.1.15,,RFC 4524 -homePhone,,,0.9.2342.19200300.100.1.20,,RFC 4524 -secretary,,,0.9.2342.19200300.100.1.21,,RFC 4524 -dc,,,0.9.2342.19200300.100.1.25,,RFC 4519 -associatedDomain,,,0.9.2342.19200300.100.1.37,,RFC 4524 -associatedName,,,0.9.2342.19200300.100.1.38,,RFC 4524 -homePostalAddress,,,0.9.2342.19200300.100.1.39,,RFC 4524 -personalTitle,,,0.9.2342.19200300.100.1.40,,RFC 4524 -mobile,,,0.9.2342.19200300.100.1.41,,RFC 4524 -pager,,,0.9.2342.19200300.100.1.42,,RFC 4524 -co,,,0.9.2342.19200300.100.1.43,,RFC 4524 -uniqueIdentifier,,,0.9.2342.19200300.100.1.44,,RFC 4524 -organizationalStatus,,,0.9.2342.19200300.100.1.45,,RFC 4524 -buildingName,,,0.9.2342.19200300.100.1.48,,RFC 4524 -audio,,,0.9.2342.19200300.100.1.55,,RFC 2798 -documentPublisher,,,0.9.2342.19200300.100.1.56,,RFC 4524 -jpegPhoto,,,0.9.2342.19200300.100.1.60,,RFC 2798 -vendorName,,,1.3.6.1.1.4,,RFC 3045 -vendorVersion,,,1.3.6.1.1.5,,RFC 3045 -entryUUID,,,1.3.6.1.1.16.4,,RFC 4530 -entryDN,,,1.3.6.1.1.20,,RFC 5020 -labeledURI,,,1.3.6.1.4.1.250.1.57,,RFC 2798 -numSubordinates,,,1.3.6.1.4.1.453.16.2.103,,draft-ietf-boreham-numsubordinates -namingContexts,,,1.3.6.1.4.1.1466.101.120.5,,RFC 4512 -altServer,,,1.3.6.1.4.1.1466.101.120.6,,RFC 4512 -supportedExtension,,,1.3.6.1.4.1.1466.101.120.7,,RFC 4512 -supportedControl,,,1.3.6.1.4.1.1466.101.120.13,,RFC 4512 -supportedSASLMechanisms,,,1.3.6.1.4.1.1466.101.120.14,,RFC 4512 -supportedLDAPVersion,,,1.3.6.1.4.1.1466.101.120.15,,RFC 4512 -ldapSyntaxes,,,1.3.6.1.4.1.1466.101.120.16,,RFC 4512 -supportedAuthPasswordSchemes,,,1.3.6.1.4.1.4203.1.3.3,,RFC 3112 -authPassword,,,1.3.6.1.4.1.4203.1.3.4,,RFC 3112 -supportedFeatures,,,1.3.6.1.4.1.4203.1.3.5,,RFC 4512 -inheritable,,,1.3.6.1.4.1.7628.5.4.1,,draft-ietf-ldup-subentry -blockInheritance,,,1.3.6.1.4.1.7628.5.4.2,,draft-ietf-ldup-subentry -objectClass,,,2.5.4.0,,RFC 4512 -aliasedObjectName,,,2.5.4.1,,RFC 4512 -cn,,,2.5.4.3,,RFC 4519 -sn,,,2.5.4.4,,RFC 4519 -serialNumber,,,2.5.4.5,,RFC 4519 -c,,,2.5.4.6,,RFC 4519 -l,,,2.5.4.7,,RFC 4519 -st,,,2.5.4.8,,RFC 4519 -street,,,2.5.4.9,,RFC 4519 -o,,,2.5.4.10,,RFC 4519 -ou,,,2.5.4.11,,RFC 4519 -title,,,2.5.4.12,,RFC 4519 -description,,,2.5.4.13,,RFC 4519 -searchGuide,,,2.5.4.14,,RFC 4519 -businessCategory,,,2.5.4.15,,RFC 4519 -postalAddress,,,2.5.4.16,,RFC 4519 -postalCode,,,2.5.4.17,,RFC 4519 -postOfficeBox,,,2.5.4.18,,RFC 4519 -physicalDeliveryOfficeName,,,2.5.4.19,,RFC 4519 -telephoneNumber,,,2.5.4.20,,RFC 4519 -telexNumber,,,2.5.4.21,,RFC 4519 -teletexTerminalIdentifier,,,2.5.4.22,,RFC 4519 -facsimileTelephoneNumber,,,2.5.4.23,,RFC 4519 -x121Address,,,2.5.4.24,,RFC 4519 -internationalISDNNumber,,,2.5.4.25,,RFC 4519 -registeredAddress,,,2.5.4.26,,RFC 4519 -destinationIndicator,,,2.5.4.27,,RFC 4519 -preferredDeliveryMethod,,,2.5.4.28,,RFC 4519 -member,,,2.5.4.31,,RFC 4519 -owner,,,2.5.4.32,,RFC 4519 -roleOccupant,,,2.5.4.33,,RFC 4519 -seeAlso,,,2.5.4.34,,RFC 4519 -userPassword,,,2.5.4.35,,RFC 4519 -userCertificate,,,2.5.4.36,,RFC 4523 -cACertificate,,,2.5.4.37,,RFC 4523 -authorityRevocationList,,,2.5.4.38,,RFC 4523 -certificateRevocationList,,,2.5.4.39,,RFC 4523 -crossCertificatePair,,,2.5.4.40,,RFC 4523 -name,,,2.5.4.41,,RFC 4519 -givenName,,,2.5.4.42,,RFC 4519 -initials,,,2.5.4.43,,RFC 4519 -generationQualifier,,,2.5.4.44,,RFC 4519 -x500UniqueIdentifier,,,2.5.4.45,,RFC 4519 -dnQualifier,,,2.5.4.46,,RFC 4519 -enhancedSearchGuide,,,2.5.4.47,,RFC 4519 -distinguishedName,,,2.5.4.49,,RFC 4519 -uniqueMember,,,2.5.4.50,,RFC 4519 -houseIdentifier,,,2.5.4.51,,RFC 4519 -supportedAlgorithms,,,2.5.4.52,,RFC 4523 -deltaRevocationList,,,2.5.4.53,,RFC 4523 -createTimestamp,,,2.5.18.1,,RFC 4512 -modifyTimestamp,,,2.5.18.2,,RFC 4512 -creatorsName,,,2.5.18.3,,RFC 4512 -modifiersName,,,2.5.18.4,,RFC 4512 -subschemaSubentry,,,2.5.18.10,,RFC 4512 -dITStructureRules,,,2.5.21.1,,RFC 4512 -dITContentRules,,,2.5.21.2,,RFC 4512 -matchingRules,,,2.5.21.4,,RFC 4512 -attributeTypes,,,2.5.21.5,,RFC 4512 -objectClasses,,,2.5.21.6,,RFC 4512 -nameForms,,,2.5.21.7,,RFC 4512 -matchingRuleUse,,,2.5.21.8,,RFC 4512 -structuralObjectClass,,,2.5.21.9,,RFC 4512 -governingStructureRule,,,2.5.21.10,,RFC 4512 -carLicense,,,2.16.840.1.113730.3.1.1,,RFC 2798 -departmentNumber,,,2.16.840.1.113730.3.1.2,,RFC 2798 -employeeNumber,,,2.16.840.1.113730.3.1.3,,RFC 2798 -employeeType,,,2.16.840.1.113730.3.1.4,,RFC 2798 -changeNumber,,,2.16.840.1.113730.3.1.5,,draft-good-ldap-changelog -targetDN,,,2.16.840.1.113730.3.1.6,,draft-good-ldap-changelog -changeType,,,2.16.840.1.113730.3.1.7,,draft-good-ldap-changelog -changes,,,2.16.840.1.113730.3.1.8,,draft-good-ldap-changelog -newRDN,,,2.16.840.1.113730.3.1.9,,draft-good-ldap-changelog -deleteOldRDN,,,2.16.840.1.113730.3.1.10,,draft-good-ldap-changelog -newSuperior,,,2.16.840.1.113730.3.1.11,,draft-good-ldap-changelog -ref,,,2.16.840.1.113730.3.1.34,,RFC 3296 -changelog,,,2.16.840.1.113730.3.1.35,,draft-good-ldap-changelog -preferredLanguage,,,2.16.840.1.113730.3.1.39,,RFC 2798 -userSMIMECertificate,,,2.16.840.1.113730.3.1.40,,RFC 2798 -userPKCS12,,,2.16.840.1.113730.3.1.216,,RFC 2798 -displayName,,,2.16.840.1.113730.3.1.241,,RFC 2798 diff --git a/org.argeo.util/src/org/argeo/naming/LdapAttrs.java b/org.argeo.util/src/org/argeo/naming/LdapAttrs.java deleted file mode 100644 index cfabeb7d6..000000000 --- a/org.argeo.util/src/org/argeo/naming/LdapAttrs.java +++ /dev/null @@ -1,341 +0,0 @@ -package org.argeo.naming; - -/** - * Standard LDAP attributes as per:
- * - Standard LDAP
- * - Kerberos - * LDAP (partial) - */ -public enum LdapAttrs implements SpecifiedName { - /** */ - uid("0.9.2342.19200300.100.1.1", "RFC 4519"), - /** */ - mail("0.9.2342.19200300.100.1.3", "RFC 4524"), - /** */ - info("0.9.2342.19200300.100.1.4", "RFC 4524"), - /** */ - drink("0.9.2342.19200300.100.1.5", "RFC 4524"), - /** */ - roomNumber("0.9.2342.19200300.100.1.6", "RFC 4524"), - /** */ - photo("0.9.2342.19200300.100.1.7", "RFC 2798"), - /** */ - userClass("0.9.2342.19200300.100.1.8", "RFC 4524"), - /** */ - host("0.9.2342.19200300.100.1.9", "RFC 4524"), - /** */ - manager("0.9.2342.19200300.100.1.10", "RFC 4524"), - /** */ - documentIdentifier("0.9.2342.19200300.100.1.11", "RFC 4524"), - /** */ - documentTitle("0.9.2342.19200300.100.1.12", "RFC 4524"), - /** */ - documentVersion("0.9.2342.19200300.100.1.13", "RFC 4524"), - /** */ - documentAuthor("0.9.2342.19200300.100.1.14", "RFC 4524"), - /** */ - documentLocation("0.9.2342.19200300.100.1.15", "RFC 4524"), - /** */ - homePhone("0.9.2342.19200300.100.1.20", "RFC 4524"), - /** */ - secretary("0.9.2342.19200300.100.1.21", "RFC 4524"), - /** */ - dc("0.9.2342.19200300.100.1.25", "RFC 4519"), - /** */ - associatedDomain("0.9.2342.19200300.100.1.37", "RFC 4524"), - /** */ - associatedName("0.9.2342.19200300.100.1.38", "RFC 4524"), - /** */ - homePostalAddress("0.9.2342.19200300.100.1.39", "RFC 4524"), - /** */ - personalTitle("0.9.2342.19200300.100.1.40", "RFC 4524"), - /** */ - mobile("0.9.2342.19200300.100.1.41", "RFC 4524"), - /** */ - pager("0.9.2342.19200300.100.1.42", "RFC 4524"), - /** */ - co("0.9.2342.19200300.100.1.43", "RFC 4524"), - /** */ - uniqueIdentifier("0.9.2342.19200300.100.1.44", "RFC 4524"), - /** */ - organizationalStatus("0.9.2342.19200300.100.1.45", "RFC 4524"), - /** */ - buildingName("0.9.2342.19200300.100.1.48", "RFC 4524"), - /** */ - audio("0.9.2342.19200300.100.1.55", "RFC 2798"), - /** */ - documentPublisher("0.9.2342.19200300.100.1.56", "RFC 4524"), - /** */ - jpegPhoto("0.9.2342.19200300.100.1.60", "RFC 2798"), - /** */ - vendorName("1.3.6.1.1.4", "RFC 3045"), - /** */ - vendorVersion("1.3.6.1.1.5", "RFC 3045"), - /** */ - entryUUID("1.3.6.1.1.16.4", "RFC 4530"), - /** */ - entryDN("1.3.6.1.1.20", "RFC 5020"), - /** */ - labeledURI("1.3.6.1.4.1.250.1.57", "RFC 2798"), - /** */ - numSubordinates("1.3.6.1.4.1.453.16.2.103", "draft-ietf-boreham-numsubordinates"), - /** */ - namingContexts("1.3.6.1.4.1.1466.101.120.5", "RFC 4512"), - /** */ - altServer("1.3.6.1.4.1.1466.101.120.6", "RFC 4512"), - /** */ - supportedExtension("1.3.6.1.4.1.1466.101.120.7", "RFC 4512"), - /** */ - supportedControl("1.3.6.1.4.1.1466.101.120.13", "RFC 4512"), - /** */ - supportedSASLMechanisms("1.3.6.1.4.1.1466.101.120.14", "RFC 4512"), - /** */ - supportedLDAPVersion("1.3.6.1.4.1.1466.101.120.15", "RFC 4512"), - /** */ - ldapSyntaxes("1.3.6.1.4.1.1466.101.120.16", "RFC 4512"), - /** */ - supportedAuthPasswordSchemes("1.3.6.1.4.1.4203.1.3.3", "RFC 3112"), - /** */ - authPassword("1.3.6.1.4.1.4203.1.3.4", "RFC 3112"), - /** */ - supportedFeatures("1.3.6.1.4.1.4203.1.3.5", "RFC 4512"), - /** */ - inheritable("1.3.6.1.4.1.7628.5.4.1", "draft-ietf-ldup-subentry"), - /** */ - blockInheritance("1.3.6.1.4.1.7628.5.4.2", "draft-ietf-ldup-subentry"), - /** */ - objectClass("2.5.4.0", "RFC 4512"), - /** */ - aliasedObjectName("2.5.4.1", "RFC 4512"), - /** */ - cn("2.5.4.3", "RFC 4519"), - /** */ - sn("2.5.4.4", "RFC 4519"), - /** */ - serialNumber("2.5.4.5", "RFC 4519"), - /** */ - c("2.5.4.6", "RFC 4519"), - /** */ - l("2.5.4.7", "RFC 4519"), - /** */ - st("2.5.4.8", "RFC 4519"), - /** */ - street("2.5.4.9", "RFC 4519"), - /** */ - o("2.5.4.10", "RFC 4519"), - /** */ - ou("2.5.4.11", "RFC 4519"), - /** */ - title("2.5.4.12", "RFC 4519"), - /** */ - description("2.5.4.13", "RFC 4519"), - /** */ - searchGuide("2.5.4.14", "RFC 4519"), - /** */ - businessCategory("2.5.4.15", "RFC 4519"), - /** */ - postalAddress("2.5.4.16", "RFC 4519"), - /** */ - postalCode("2.5.4.17", "RFC 4519"), - /** */ - postOfficeBox("2.5.4.18", "RFC 4519"), - /** */ - physicalDeliveryOfficeName("2.5.4.19", "RFC 4519"), - /** */ - telephoneNumber("2.5.4.20", "RFC 4519"), - /** */ - telexNumber("2.5.4.21", "RFC 4519"), - /** */ - teletexTerminalIdentifier("2.5.4.22", "RFC 4519"), - /** */ - facsimileTelephoneNumber("2.5.4.23", "RFC 4519"), - /** */ - x121Address("2.5.4.24", "RFC 4519"), - /** */ - internationalISDNNumber("2.5.4.25", "RFC 4519"), - /** */ - registeredAddress("2.5.4.26", "RFC 4519"), - /** */ - destinationIndicator("2.5.4.27", "RFC 4519"), - /** */ - preferredDeliveryMethod("2.5.4.28", "RFC 4519"), - /** */ - member("2.5.4.31", "RFC 4519"), - /** */ - owner("2.5.4.32", "RFC 4519"), - /** */ - roleOccupant("2.5.4.33", "RFC 4519"), - /** */ - seeAlso("2.5.4.34", "RFC 4519"), - /** */ - userPassword("2.5.4.35", "RFC 4519"), - /** */ - userCertificate("2.5.4.36", "RFC 4523"), - /** */ - cACertificate("2.5.4.37", "RFC 4523"), - /** */ - authorityRevocationList("2.5.4.38", "RFC 4523"), - /** */ - certificateRevocationList("2.5.4.39", "RFC 4523"), - /** */ - crossCertificatePair("2.5.4.40", "RFC 4523"), - /** */ - name("2.5.4.41", "RFC 4519"), - /** */ - givenName("2.5.4.42", "RFC 4519"), - /** */ - initials("2.5.4.43", "RFC 4519"), - /** */ - generationQualifier("2.5.4.44", "RFC 4519"), - /** */ - x500UniqueIdentifier("2.5.4.45", "RFC 4519"), - /** */ - dnQualifier("2.5.4.46", "RFC 4519"), - /** */ - enhancedSearchGuide("2.5.4.47", "RFC 4519"), - /** */ - distinguishedName("2.5.4.49", "RFC 4519"), - /** */ - uniqueMember("2.5.4.50", "RFC 4519"), - /** */ - houseIdentifier("2.5.4.51", "RFC 4519"), - /** */ - supportedAlgorithms("2.5.4.52", "RFC 4523"), - /** */ - deltaRevocationList("2.5.4.53", "RFC 4523"), - /** */ - createTimestamp("2.5.18.1", "RFC 4512"), - /** */ - modifyTimestamp("2.5.18.2", "RFC 4512"), - /** */ - creatorsName("2.5.18.3", "RFC 4512"), - /** */ - modifiersName("2.5.18.4", "RFC 4512"), - /** */ - subschemaSubentry("2.5.18.10", "RFC 4512"), - /** */ - dITStructureRules("2.5.21.1", "RFC 4512"), - /** */ - dITContentRules("2.5.21.2", "RFC 4512"), - /** */ - matchingRules("2.5.21.4", "RFC 4512"), - /** */ - attributeTypes("2.5.21.5", "RFC 4512"), - /** */ - objectClasses("2.5.21.6", "RFC 4512"), - /** */ - nameForms("2.5.21.7", "RFC 4512"), - /** */ - matchingRuleUse("2.5.21.8", "RFC 4512"), - /** */ - structuralObjectClass("2.5.21.9", "RFC 4512"), - /** */ - governingStructureRule("2.5.21.10", "RFC 4512"), - /** */ - carLicense("2.16.840.1.113730.3.1.1", "RFC 2798"), - /** */ - departmentNumber("2.16.840.1.113730.3.1.2", "RFC 2798"), - /** */ - employeeNumber("2.16.840.1.113730.3.1.3", "RFC 2798"), - /** */ - employeeType("2.16.840.1.113730.3.1.4", "RFC 2798"), - /** */ - changeNumber("2.16.840.1.113730.3.1.5", "draft-good-ldap-changelog"), - /** */ - targetDN("2.16.840.1.113730.3.1.6", "draft-good-ldap-changelog"), - /** */ - changeType("2.16.840.1.113730.3.1.7", "draft-good-ldap-changelog"), - /** */ - changes("2.16.840.1.113730.3.1.8", "draft-good-ldap-changelog"), - /** */ - newRDN("2.16.840.1.113730.3.1.9", "draft-good-ldap-changelog"), - /** */ - deleteOldRDN("2.16.840.1.113730.3.1.10", "draft-good-ldap-changelog"), - /** */ - newSuperior("2.16.840.1.113730.3.1.11", "draft-good-ldap-changelog"), - /** */ - ref("2.16.840.1.113730.3.1.34", "RFC 3296"), - /** */ - changelog("2.16.840.1.113730.3.1.35", "draft-good-ldap-changelog"), - /** */ - preferredLanguage("2.16.840.1.113730.3.1.39", "RFC 2798"), - /** */ - userSMIMECertificate("2.16.840.1.113730.3.1.40", "RFC 2798"), - /** */ - userPKCS12("2.16.840.1.113730.3.1.216", "RFC 2798"), - /** */ - displayName("2.16.840.1.113730.3.1.241", "RFC 2798"), - - // Sun memberOf - memberOf("1.2.840.113556.1.2.102", "389 DS memberOf"), - - // KERBEROS (partial) - krbPrincipalName("2.16.840.1.113719.1.301.6.8.1", "Novell Kerberos Schema Definitions"), - - // RFC 2985 and RFC 3039 (partial) - dateOfBirth("1.3.6.1.5.5.7.9.1", "RFC 2985"), - /** */ - placeOfBirth("1.3.6.1.5.5.7.9.2", "RFC 2985"), - /** */ - gender("1.3.6.1.5.5.7.9.3", "RFC 2985"), - /** */ - countryOfCitizenship("1.3.6.1.5.5.7.9.4", "RFC 2985"), - /** */ - countryOfResidence("1.3.6.1.5.5.7.9.5", "RFC 2985"), - // - ; - - public final static String DN = "dn"; - -// private final static String LDAP_ = "ldap:"; - - private final String oid, spec; - - LdapAttrs(String oid, String spec) { - this.oid = oid; - this.spec = spec; - } - - @Override - public String getID() { - return oid; - } - - @Override - public String getSpec() { - return spec; - } - - public String getPrefix() { - return prefix(); - } - - public static String prefix() { - return "ldap"; - } - - public String property() { - return qualified(); - } - - public String qualified() { - String prefix = getPrefix(); - return prefix != null ? prefix + ":" + name() : name(); - } - - public String getNamespace() { - return namespace(); - } - - public static String namespace() { - return "http://www.argeo.org/ns/ldap"; - } - - @Override - public final String toString() { - // must return the name - return name(); - } - -} diff --git a/org.argeo.util/src/org/argeo/naming/LdapObjs.csv b/org.argeo.util/src/org/argeo/naming/LdapObjs.csv deleted file mode 100644 index 3d907cbeb..000000000 --- a/org.argeo.util/src/org/argeo/naming/LdapObjs.csv +++ /dev/null @@ -1,42 +0,0 @@ -account,,,0.9.2342.19200300.100.4.5,,RFC 4524 -document,,,0.9.2342.19200300.100.4.6,,RFC 4524 -room,,,0.9.2342.19200300.100.4.7,,RFC 4524 -documentSeries,,,0.9.2342.19200300.100.4.9,,RFC 4524 -domain,,,0.9.2342.19200300.100.4.13,,RFC 4524 -rFC822localPart,,,0.9.2342.19200300.100.4.14,,RFC 4524 -domainRelatedObject,,,0.9.2342.19200300.100.4.17,,RFC 4524 -friendlyCountry,,,0.9.2342.19200300.100.4.18,,RFC 4524 -simpleSecurityObject,,,0.9.2342.19200300.100.4.19,,RFC 4524 -uidObject,,,1.3.6.1.1.3.1,,RFC 4519 -extensibleObject,,,1.3.6.1.4.1.1466.101.120.111,,RFC 4512 -dcObject,,,1.3.6.1.4.1.1466.344,,RFC 4519 -authPasswordObject,,,1.3.6.1.4.1.4203.1.4.7,,RFC 3112 -namedObject,,,1.3.6.1.4.1.5322.13.1.1,,draft-howard-namedobject -inheritableLDAPSubEntry,,,1.3.6.1.4.1.7628.5.6.1.1,,draft-ietf-ldup-subentry -top,,,2.5.6.0,,RFC 4512 -alias,,,2.5.6.1,,RFC 4512 -country,,,2.5.6.2,,RFC 4519 -locality,,,2.5.6.3,,RFC 4519 -organization,,,2.5.6.4,,RFC 4519 -organizationalUnit,,,2.5.6.5,,RFC 4519 -person,,,2.5.6.6,,RFC 4519 -organizationalPerson,,,2.5.6.7,,RFC 4519 -organizationalRole,,,2.5.6.8,,RFC 4519 -groupOfNames,,,2.5.6.9,,RFC 4519 -residentialPerson,,,2.5.6.10,,RFC 4519 -applicationProcess,,,2.5.6.11,,RFC 4519 -device,,,2.5.6.14,,RFC 4519 -strongAuthenticationUser,,,2.5.6.15,,RFC 4523 -certificationAuthority,,,2.5.6.16,,RFC 4523 -certificationAuthority-V2,,,2.5.6.16.2,,RFC 4523 -groupOfUniqueNames,,,2.5.6.17,,RFC 4519 -userSecurityInformation,,,2.5.6.18,,RFC 4523 -cRLDistributionPoint,,,2.5.6.19,,RFC 4523 -pkiUser,,,2.5.6.21,,RFC 4523 -pkiCA,,,2.5.6.22,,RFC 4523 -deltaCRL,,,2.5.6.23,,RFC 4523 -subschema,,,2.5.20.1,,RFC 4512 -ldapSubEntry,,,2.16.840.1.113719.2.142.6.1.1,,draft-ietf-ldup-subentry -changeLogEntry,,,2.16.840.1.113730.3.2.1,,draft-good-ldap-changelog -inetOrgPerson,,,2.16.840.1.113730.3.2.2,,RFC 2798 -referral,,,2.16.840.1.113730.3.2.6,,RFC 3296 diff --git a/org.argeo.util/src/org/argeo/naming/LdapObjs.java b/org.argeo.util/src/org/argeo/naming/LdapObjs.java deleted file mode 100644 index 061167513..000000000 --- a/org.argeo.util/src/org/argeo/naming/LdapObjs.java +++ /dev/null @@ -1,114 +0,0 @@ -package org.argeo.naming; - -/** - * Standard LDAP object classes as per - * https://www.ldap.com/ldap- - * oid-reference - */ -public enum LdapObjs implements SpecifiedName { - account("0.9.2342.19200300.100.4.5", "RFC 4524"), - /** */ - document("0.9.2342.19200300.100.4.6", "RFC 4524"), - /** */ - room("0.9.2342.19200300.100.4.7", "RFC 4524"), - /** */ - documentSeries("0.9.2342.19200300.100.4.9", "RFC 4524"), - /** */ - domain("0.9.2342.19200300.100.4.13", "RFC 4524"), - /** */ - rFC822localPart("0.9.2342.19200300.100.4.14", "RFC 4524"), - /** */ - domainRelatedObject("0.9.2342.19200300.100.4.17", "RFC 4524"), - /** */ - friendlyCountry("0.9.2342.19200300.100.4.18", "RFC 4524"), - /** */ - simpleSecurityObject("0.9.2342.19200300.100.4.19", "RFC 4524"), - /** */ - uidObject("1.3.6.1.1.3.1", "RFC 4519"), - /** */ - extensibleObject("1.3.6.1.4.1.1466.101.120.111", "RFC 4512"), - /** */ - dcObject("1.3.6.1.4.1.1466.344", "RFC 4519"), - /** */ - authPasswordObject("1.3.6.1.4.1.4203.1.4.7", "RFC 3112"), - /** */ - namedObject("1.3.6.1.4.1.5322.13.1.1", "draft-howard-namedobject"), - /** */ - inheritableLDAPSubEntry("1.3.6.1.4.1.7628.5.6.1.1", "draft-ietf-ldup-subentry"), - /** */ - top("2.5.6.0", "RFC 4512"), - /** */ - alias("2.5.6.1", "RFC 4512"), - /** */ - country("2.5.6.2", "RFC 4519"), - /** */ - locality("2.5.6.3", "RFC 4519"), - /** */ - organization("2.5.6.4", "RFC 4519"), - /** */ - organizationalUnit("2.5.6.5", "RFC 4519"), - /** */ - person("2.5.6.6", "RFC 4519"), - /** */ - organizationalPerson("2.5.6.7", "RFC 4519"), - /** */ - organizationalRole("2.5.6.8", "RFC 4519"), - /** */ - groupOfNames("2.5.6.9", "RFC 4519"), - /** */ - residentialPerson("2.5.6.10", "RFC 4519"), - /** */ - applicationProcess("2.5.6.11", "RFC 4519"), - /** */ - device("2.5.6.14", "RFC 4519"), - /** */ - strongAuthenticationUser("2.5.6.15", "RFC 4523"), - /** */ - certificationAuthority("2.5.6.16", "RFC 4523"), - // /** Should be certificationAuthority-V2 */ - // certificationAuthority_V2("2.5.6.16.2", "RFC 4523") { - // }, - /** */ - groupOfUniqueNames("2.5.6.17", "RFC 4519"), - /** */ - userSecurityInformation("2.5.6.18", "RFC 4523"), - /** */ - cRLDistributionPoint("2.5.6.19", "RFC 4523"), - /** */ - pkiUser("2.5.6.21", "RFC 4523"), - /** */ - pkiCA("2.5.6.22", "RFC 4523"), - /** */ - deltaCRL("2.5.6.23", "RFC 4523"), - /** */ - subschema("2.5.20.1", "RFC 4512"), - /** */ - ldapSubEntry("2.16.840.1.113719.2.142.6.1.1", "draft-ietf-ldup-subentry"), - /** */ - changeLogEntry("2.16.840.1.113730.3.2.1", "draft-good-ldap-changelog"), - /** */ - inetOrgPerson("2.16.840.1.113730.3.2.2", "RFC 2798"), - /** */ - referral("2.16.840.1.113730.3.2.6", "RFC 3296"); - - private final static String LDAP_ = "ldap:"; - private final String oid, spec; - - private LdapObjs(String oid, String spec) { - this.oid = oid; - this.spec = spec; - } - - public String getOid() { - return oid; - } - - public String getSpec() { - return spec; - } - - public String property() { - return new StringBuilder(LDAP_).append(name()).toString(); - } - -} diff --git a/org.argeo.util/src/org/argeo/naming/LdifParser.java b/org.argeo.util/src/org/argeo/naming/LdifParser.java deleted file mode 100644 index cc1957058..000000000 --- a/org.argeo.util/src/org/argeo/naming/LdifParser.java +++ /dev/null @@ -1,161 +0,0 @@ -package org.argeo.naming; - -import java.io.BufferedReader; -import java.io.IOException; -import java.io.InputStream; -import java.io.InputStreamReader; -import java.io.Reader; -import java.nio.charset.Charset; -import java.nio.charset.StandardCharsets; -import java.util.ArrayList; -import java.util.Base64; -import java.util.List; -import java.util.SortedMap; -import java.util.TreeMap; - -import javax.naming.InvalidNameException; -import javax.naming.NamingException; -import javax.naming.directory.Attribute; -import javax.naming.directory.Attributes; -import javax.naming.directory.BasicAttribute; -import javax.naming.directory.BasicAttributes; -import javax.naming.ldap.LdapName; -import javax.naming.ldap.Rdn; - -import org.argeo.osgi.useradmin.UserDirectoryException; - -/** Basic LDIF parser. */ -public class LdifParser { - private final static Charset DEFAULT_CHARSET = StandardCharsets.UTF_8; - - protected Attributes addAttributes(SortedMap res, int lineNumber, LdapName currentDn, - Attributes currentAttributes) { - try { - Rdn nameRdn = currentDn.getRdn(currentDn.size() - 1); - Attribute nameAttr = currentAttributes.get(nameRdn.getType()); - if (nameAttr == null) - currentAttributes.put(nameRdn.getType(), nameRdn.getValue()); - else if (!nameAttr.get().equals(nameRdn.getValue())) - throw new UserDirectoryException( - "Attribute " + nameAttr.getID() + "=" + nameAttr.get() + " not consistent with DN " + currentDn - + " (shortly before line " + lineNumber + " in LDIF file)"); - Attributes previous = res.put(currentDn, currentAttributes); - return previous; - } catch (NamingException e) { - throw new UserDirectoryException("Cannot add " + currentDn, e); - } - } - - /** With UTF-8 charset */ - public SortedMap read(InputStream in) throws IOException { - try (Reader reader = new InputStreamReader(in, DEFAULT_CHARSET)) { - return read(reader); - } finally { - try { - in.close(); - } catch (IOException e) { - // silent - } - } - } - - /** Will close the reader. */ - public SortedMap read(Reader reader) throws IOException { - SortedMap res = new TreeMap(); - try { - List lines = new ArrayList<>(); - try (BufferedReader br = new BufferedReader(reader)) { - String line; - while ((line = br.readLine()) != null) { - lines.add(line); - } - } - if (lines.size() == 0) - return res; - // add an empty new line since the last line is not checked - if (!lines.get(lines.size() - 1).equals("")) - lines.add(""); - - LdapName currentDn = null; - Attributes currentAttributes = null; - StringBuilder currentEntry = new StringBuilder(); - - readLines: for (int lineNumber = 0; lineNumber < lines.size(); lineNumber++) { - String line = lines.get(lineNumber); - boolean isLastLine = false; - if (lineNumber == lines.size() - 1) - isLastLine = true; - if (line.startsWith(" ")) { - currentEntry.append(line.substring(1)); - if (!isLastLine) - continue readLines; - } - - if (currentEntry.length() != 0 || isLastLine) { - // read previous attribute - StringBuilder attrId = new StringBuilder(8); - boolean isBase64 = false; - readAttrId: for (int i = 0; i < currentEntry.length(); i++) { - char c = currentEntry.charAt(i); - if (c == ':') { - if (i + 1 < currentEntry.length() && currentEntry.charAt(i + 1) == ':') - isBase64 = true; - currentEntry.delete(0, i + (isBase64 ? 2 : 1)); - break readAttrId; - } else { - attrId.append(c); - } - } - - String attributeId = attrId.toString(); - // TODO should we really trim the end of the string as well? - String cleanValueStr = currentEntry.toString().trim(); - Object attributeValue = isBase64 ? Base64.getDecoder().decode(cleanValueStr) : cleanValueStr; - - // manage DN attributes - if (attributeId.equals(LdapAttrs.DN) || isLastLine) { - if (currentDn != null) { - // - // ADD - // - Attributes previous = addAttributes(res, lineNumber, currentDn, currentAttributes); - if (previous != null) { -// log.warn("There was already an entry with DN " + currentDn -// + ", which has been discarded by a subsequent one."); - } - } - - if (attributeId.equals(LdapAttrs.DN)) - try { - currentDn = new LdapName(attributeValue.toString()); - currentAttributes = new BasicAttributes(true); - } catch (InvalidNameException e) { -// log.error(attributeValue + " not a valid DN, skipping the entry."); - currentDn = null; - currentAttributes = null; - } - } - - // store attribute - if (currentAttributes != null) { - Attribute attribute = currentAttributes.get(attributeId); - if (attribute == null) { - attribute = new BasicAttribute(attributeId); - currentAttributes.put(attribute); - } - attribute.add(attributeValue); - } - currentEntry = new StringBuilder(); - } - currentEntry.append(line); - } - } finally { - try { - reader.close(); - } catch (IOException e) { - // silent - } - } - return res; - } -} \ No newline at end of file diff --git a/org.argeo.util/src/org/argeo/naming/LdifWriter.java b/org.argeo.util/src/org/argeo/naming/LdifWriter.java deleted file mode 100644 index 98d2df055..000000000 --- a/org.argeo.util/src/org/argeo/naming/LdifWriter.java +++ /dev/null @@ -1,106 +0,0 @@ -package org.argeo.naming; - -import static org.argeo.naming.LdapAttrs.DN; -import static org.argeo.naming.LdapAttrs.member; -import static org.argeo.naming.LdapAttrs.objectClass; -import static org.argeo.naming.LdapAttrs.uniqueMember; - -import java.io.IOException; -import java.io.OutputStream; -import java.io.OutputStreamWriter; -import java.io.Writer; -import java.nio.charset.Charset; -import java.nio.charset.StandardCharsets; -import java.util.Base64; -import java.util.Map; -import java.util.SortedSet; -import java.util.TreeSet; - -import javax.naming.NamingEnumeration; -import javax.naming.NamingException; -import javax.naming.directory.Attribute; -import javax.naming.directory.Attributes; -import javax.naming.ldap.LdapName; -import javax.naming.ldap.Rdn; - -import org.argeo.osgi.useradmin.UserDirectoryException; - -/** Basic LDIF writer */ -public class LdifWriter { - private final static Charset DEFAULT_CHARSET = StandardCharsets.UTF_8; - private final Writer writer; - - /** Writer must be closed by caller */ - public LdifWriter(Writer writer) { - this.writer = writer; - } - - /** Stream must be closed by caller */ - public LdifWriter(OutputStream out) { - this(new OutputStreamWriter(out, DEFAULT_CHARSET)); - } - - public void writeEntry(LdapName name, Attributes attributes) throws IOException { - try { - // check consistency - Rdn nameRdn = name.getRdn(name.size() - 1); - Attribute nameAttr = attributes.get(nameRdn.getType()); - if (!nameAttr.get().equals(nameRdn.getValue())) - throw new UserDirectoryException( - "Attribute " + nameAttr.getID() + "=" + nameAttr.get() + " not consistent with DN " + name); - - writer.append(DN + ": ").append(name.toString()).append('\n'); - Attribute objectClassAttr = attributes.get(objectClass.name()); - if (objectClassAttr != null) - writeAttribute(objectClassAttr); - attributes: for (NamingEnumeration attrs = attributes.getAll(); attrs.hasMore();) { - Attribute attribute = attrs.next(); - if (attribute.getID().equals(DN) || attribute.getID().equals(objectClass.name())) - continue attributes;// skip DN attribute - if (attribute.getID().equals(member.name()) || attribute.getID().equals(uniqueMember.name())) - continue attributes;// skip member and uniqueMember attributes, so that they are always written last - writeAttribute(attribute); - } - // write member and uniqueMember attributes last - for (NamingEnumeration attrs = attributes.getAll(); attrs.hasMore();) { - Attribute attribute = attrs.next(); - if (attribute.getID().equals(member.name()) || attribute.getID().equals(uniqueMember.name())) - writeMemberAttribute(attribute); - } - writer.append('\n'); - writer.flush(); - } catch (NamingException e) { - throw new UserDirectoryException("Cannot write LDIF", e); - } - } - - public void write(Map entries) throws IOException { - for (LdapName dn : entries.keySet()) - writeEntry(dn, entries.get(dn)); - } - - protected void writeAttribute(Attribute attribute) throws NamingException, IOException { - for (NamingEnumeration attrValues = attribute.getAll(); attrValues.hasMore();) { - Object value = attrValues.next(); - if (value instanceof byte[]) { - String encoded = Base64.getEncoder().encodeToString((byte[]) value); - writer.append(attribute.getID()).append(":: ").append(encoded).append('\n'); - } else { - writer.append(attribute.getID()).append(": ").append(value.toString()).append('\n'); - } - } - } - - protected void writeMemberAttribute(Attribute attribute) throws NamingException, IOException { - // Note: duplicate entries will be swallowed - SortedSet values = new TreeSet<>(); - for (NamingEnumeration attrValues = attribute.getAll(); attrValues.hasMore();) { - String value = attrValues.next().toString(); - values.add(value); - } - - for (String value : values) { - writer.append(attribute.getID()).append(": ").append(value).append('\n'); - } - } -} diff --git a/org.argeo.util/src/org/argeo/naming/NamingUtils.java b/org.argeo.util/src/org/argeo/naming/NamingUtils.java deleted file mode 100644 index 5a868ddb4..000000000 --- a/org.argeo.util/src/org/argeo/naming/NamingUtils.java +++ /dev/null @@ -1,106 +0,0 @@ -package org.argeo.naming; - -import java.io.UnsupportedEncodingException; -import java.net.URI; -import java.net.URLDecoder; -import java.nio.charset.StandardCharsets; -import java.time.Instant; -import java.time.OffsetDateTime; -import java.time.ZoneOffset; -import java.time.ZonedDateTime; -import java.time.format.DateTimeFormatter; -import java.time.format.DateTimeParseException; -import java.time.temporal.ChronoField; -import java.util.Calendar; -import java.util.GregorianCalendar; -import java.util.LinkedHashMap; -import java.util.LinkedList; -import java.util.List; -import java.util.Map; - -public class NamingUtils { - /** As per https://tools.ietf.org/html/rfc4517#section-3.3.13 */ - private final static DateTimeFormatter utcLdapDate = DateTimeFormatter.ofPattern("uuuuMMddHHmmssX") - .withZone(ZoneOffset.UTC); - - /** @return null if not parseable */ - public static Instant ldapDateToInstant(String ldapDate) { - try { - return OffsetDateTime.parse(ldapDate, utcLdapDate).toInstant(); - } catch (DateTimeParseException e) { - return null; - } - } - - /** @return null if not parseable */ - public static ZonedDateTime ldapDateToZonedDateTime(String ldapDate) { - try { - return OffsetDateTime.parse(ldapDate, utcLdapDate).toZonedDateTime(); - } catch (DateTimeParseException e) { - return null; - } - } - - public static Calendar ldapDateToCalendar(String ldapDate) { - OffsetDateTime instant = OffsetDateTime.parse(ldapDate, utcLdapDate); - GregorianCalendar calendar = new GregorianCalendar(); - calendar.set(Calendar.DAY_OF_MONTH, instant.get(ChronoField.DAY_OF_MONTH)); - calendar.set(Calendar.MONTH, instant.get(ChronoField.MONTH_OF_YEAR)); - calendar.set(Calendar.YEAR, instant.get(ChronoField.YEAR)); - return calendar; - } - - public static String instantToLdapDate(ZonedDateTime instant) { - return utcLdapDate.format(instant.withZoneSameInstant(ZoneOffset.UTC)); - } - - public static String getQueryValue(Map> query, String key) { - if (!query.containsKey(key)) - return null; - List val = query.get(key); - if (val.size() == 1) - return val.get(0); - else - throw new IllegalArgumentException("There are " + val.size() + " value(s) for " + key); - } - - public static Map> queryToMap(URI uri) { - return queryToMap(uri.getQuery()); - } - - private static Map> queryToMap(String queryPart) { - try { - final Map> query_pairs = new LinkedHashMap>(); - if (queryPart == null) - return query_pairs; - final String[] pairs = queryPart.split("&"); - for (String pair : pairs) { - final int idx = pair.indexOf("="); - final String key = idx > 0 ? URLDecoder.decode(pair.substring(0, idx), StandardCharsets.UTF_8.name()) - : pair; - if (!query_pairs.containsKey(key)) { - query_pairs.put(key, new LinkedList()); - } - final String value = idx > 0 && pair.length() > idx + 1 - ? URLDecoder.decode(pair.substring(idx + 1), StandardCharsets.UTF_8.name()) - : null; - query_pairs.get(key).add(value); - } - return query_pairs; - } catch (UnsupportedEncodingException e) { - throw new IllegalArgumentException("Cannot convert " + queryPart + " to map", e); - } - } - - private NamingUtils() { - - } - - public static void main(String args[]) { - ZonedDateTime now = ZonedDateTime.now().withZoneSameInstant(ZoneOffset.UTC); - String str = utcLdapDate.format(now); - System.out.println(str); - utcLdapDate.parse(str); - utcLdapDate.parse("19520512000000Z"); - } -} diff --git a/org.argeo.util/src/org/argeo/naming/SharedSecret.java b/org.argeo.util/src/org/argeo/naming/SharedSecret.java deleted file mode 100644 index 369b411fc..000000000 --- a/org.argeo.util/src/org/argeo/naming/SharedSecret.java +++ /dev/null @@ -1,46 +0,0 @@ -package org.argeo.naming; - -import java.time.Instant; -import java.time.ZoneOffset; -import java.time.ZonedDateTime; - -public class SharedSecret extends AuthPassword { - public final static String X_SHARED_SECRET = "X-SharedSecret"; - private final Instant expiry; - - public SharedSecret(String authInfo, String authValue) { - super(authInfo, authValue); - expiry = null; - } - - public SharedSecret(AuthPassword authPassword) { - super(authPassword); - String authInfo = getAuthInfo(); - if (authInfo.length() == 16) { - expiry = NamingUtils.ldapDateToInstant(authInfo); - } else { - expiry = null; - } - } - - public SharedSecret(ZonedDateTime expiryTimestamp, String value) { - super(NamingUtils.instantToLdapDate(expiryTimestamp), value); - expiry = expiryTimestamp.withZoneSameInstant(ZoneOffset.UTC).toInstant(); - } - - public SharedSecret(int hours, String value) { - this(ZonedDateTime.now().plusHours(hours), value); - } - - @Override - protected String getExpectedAuthScheme() { - return X_SHARED_SECRET; - } - - public boolean isExpired() { - if (expiry == null) - return false; - return expiry.isBefore(Instant.now()); - } - -} diff --git a/org.argeo.util/src/org/argeo/naming/SpecifiedName.java b/org.argeo.util/src/org/argeo/naming/SpecifiedName.java deleted file mode 100644 index 28cc2f9da..000000000 --- a/org.argeo.util/src/org/argeo/naming/SpecifiedName.java +++ /dev/null @@ -1,20 +0,0 @@ -package org.argeo.naming; - -/** - * A name which has been specified and for which an id has been defined - * (typically an OID). - */ -public interface SpecifiedName { - /** The name */ - String name(); - - /** An RFC or the URLof some specification */ - default String getSpec() { - return null; - } - - /** Typically an OID */ - default String getID() { - return getClass().getName() + "." + name(); - } -} diff --git a/org.argeo.util/src/org/argeo/naming/SrvRecord.java b/org.argeo.util/src/org/argeo/naming/SrvRecord.java deleted file mode 100644 index 8ecc94457..000000000 --- a/org.argeo.util/src/org/argeo/naming/SrvRecord.java +++ /dev/null @@ -1,52 +0,0 @@ -package org.argeo.naming; - -class SrvRecord implements Comparable { - private final Integer priority; - private final Integer weight; - private final Integer port; - private final String hostname; - - public SrvRecord(Integer priority, Integer weight, Integer port, String hostname) { - this.priority = priority; - this.weight = weight; - this.port = port; - this.hostname = hostname; - } - - @Override - public int compareTo(SrvRecord other) { - // https: // en.wikipedia.org/wiki/SRV_record - if (priority != other.priority) - return priority - other.priority; - if (weight != other.weight) - return other.weight - other.weight; - String host = toHost(false); - String otherHost = other.toHost(false); - if (host.length() == otherHost.length()) - return host.compareTo(otherHost); - else - return host.length() - otherHost.length(); - } - - @Override - public boolean equals(Object obj) { - if (obj instanceof SrvRecord) { - SrvRecord other = (SrvRecord) obj; - return priority == other.priority && weight == other.weight && port == other.port - && hostname.equals(other.hostname); - } - return false; - } - - @Override - public String toString() { - return priority + " " + weight; - } - - public String toHost(boolean withPort) { - String hostStr = hostname; - if (hostname.charAt(hostname.length() - 1) == '.') - hostStr = hostname.substring(0, hostname.length() - 1); - return hostStr + (withPort ? ":" + port : ""); - } -} diff --git a/org.argeo.util/src/org/argeo/naming/package-info.java b/org.argeo.util/src/org/argeo/naming/package-info.java deleted file mode 100644 index 95e7de313..000000000 --- a/org.argeo.util/src/org/argeo/naming/package-info.java +++ /dev/null @@ -1,2 +0,0 @@ -/** Generic naming and LDAP support. */ -package org.argeo.naming; \ No newline at end of file diff --git a/org.argeo.util/src/org/argeo/osgi/metatype/EnumAD.java b/org.argeo.util/src/org/argeo/osgi/metatype/EnumAD.java index 44b429934..0fc4f32aa 100644 --- a/org.argeo.util/src/org/argeo/osgi/metatype/EnumAD.java +++ b/org.argeo.util/src/org/argeo/osgi/metatype/EnumAD.java @@ -1,6 +1,6 @@ package org.argeo.osgi.metatype; -import org.argeo.naming.SpecifiedName; +import org.argeo.util.naming.SpecifiedName; import org.osgi.service.metatype.AttributeDefinition; public interface EnumAD extends SpecifiedName, AttributeDefinition { diff --git a/org.argeo.util/src/org/argeo/osgi/useradmin/AbstractUserDirectory.java b/org.argeo.util/src/org/argeo/osgi/useradmin/AbstractUserDirectory.java index 7279877e0..095439093 100644 --- a/org.argeo.util/src/org/argeo/osgi/useradmin/AbstractUserDirectory.java +++ b/org.argeo.util/src/org/argeo/osgi/useradmin/AbstractUserDirectory.java @@ -1,11 +1,11 @@ package org.argeo.osgi.useradmin; -import static org.argeo.naming.LdapAttrs.objectClass; -import static org.argeo.naming.LdapObjs.extensibleObject; -import static org.argeo.naming.LdapObjs.inetOrgPerson; -import static org.argeo.naming.LdapObjs.organizationalPerson; -import static org.argeo.naming.LdapObjs.person; -import static org.argeo.naming.LdapObjs.top; +import static org.argeo.util.naming.LdapAttrs.objectClass; +import static org.argeo.util.naming.LdapObjs.extensibleObject; +import static org.argeo.util.naming.LdapObjs.inetOrgPerson; +import static org.argeo.util.naming.LdapObjs.organizationalPerson; +import static org.argeo.util.naming.LdapObjs.person; +import static org.argeo.util.naming.LdapObjs.top; import java.io.File; import java.net.URI; @@ -28,8 +28,8 @@ import javax.naming.directory.BasicAttributes; import javax.naming.ldap.LdapName; import javax.naming.ldap.Rdn; -import org.argeo.naming.LdapAttrs; import org.argeo.osgi.transaction.WorkControl; +import org.argeo.util.naming.LdapAttrs; import org.osgi.framework.Filter; import org.osgi.framework.FrameworkUtil; import org.osgi.framework.InvalidSyntaxException; diff --git a/org.argeo.util/src/org/argeo/osgi/useradmin/IpaUtils.java b/org.argeo.util/src/org/argeo/osgi/useradmin/IpaUtils.java index d56c06ac0..a9bc9417f 100644 --- a/org.argeo.util/src/org/argeo/osgi/useradmin/IpaUtils.java +++ b/org.argeo.util/src/org/argeo/osgi/useradmin/IpaUtils.java @@ -13,8 +13,8 @@ import javax.naming.InvalidNameException; import javax.naming.NamingException; import javax.naming.ldap.LdapName; -import org.argeo.naming.DnsBrowser; -import org.argeo.naming.LdapAttrs; +import org.argeo.util.naming.DnsBrowser; +import org.argeo.util.naming.LdapAttrs; /** Free IPA specific conventions. */ public class IpaUtils { diff --git a/org.argeo.util/src/org/argeo/osgi/useradmin/LdapConnection.java b/org.argeo.util/src/org/argeo/osgi/useradmin/LdapConnection.java index 3e869f3b0..ed69eb16b 100644 --- a/org.argeo.util/src/org/argeo/osgi/useradmin/LdapConnection.java +++ b/org.argeo.util/src/org/argeo/osgi/useradmin/LdapConnection.java @@ -15,7 +15,7 @@ import javax.naming.directory.SearchResult; import javax.naming.ldap.InitialLdapContext; import javax.naming.ldap.LdapName; -import org.argeo.naming.LdapAttrs; +import org.argeo.util.naming.LdapAttrs; /** A synchronized wrapper for a single {@link InitialLdapContext}. */ // TODO implement multiple contexts and connection pooling. diff --git a/org.argeo.util/src/org/argeo/osgi/useradmin/LdapUserAdmin.java b/org.argeo.util/src/org/argeo/osgi/useradmin/LdapUserAdmin.java index cd28748f5..f8396085b 100644 --- a/org.argeo.util/src/org/argeo/osgi/useradmin/LdapUserAdmin.java +++ b/org.argeo.util/src/org/argeo/osgi/useradmin/LdapUserAdmin.java @@ -1,6 +1,6 @@ package org.argeo.osgi.useradmin; -import static org.argeo.naming.LdapAttrs.objectClass; +import static org.argeo.util.naming.LdapAttrs.objectClass; import java.util.ArrayList; import java.util.Dictionary; diff --git a/org.argeo.util/src/org/argeo/osgi/useradmin/LdifAuthorization.java b/org.argeo.util/src/org/argeo/osgi/useradmin/LdifAuthorization.java index 354f8c0e2..15afe08b1 100644 --- a/org.argeo.util/src/org/argeo/osgi/useradmin/LdifAuthorization.java +++ b/org.argeo.util/src/org/argeo/osgi/useradmin/LdifAuthorization.java @@ -5,7 +5,7 @@ import java.util.Collections; import java.util.Dictionary; import java.util.List; -import org.argeo.naming.LdapAttrs; +import org.argeo.util.naming.LdapAttrs; import org.osgi.service.useradmin.Authorization; import org.osgi.service.useradmin.Role; import org.osgi.service.useradmin.User; diff --git a/org.argeo.util/src/org/argeo/osgi/useradmin/LdifUser.java b/org.argeo.util/src/org/argeo/osgi/useradmin/LdifUser.java index b3e7f5955..6e8ad2711 100644 --- a/org.argeo.util/src/org/argeo/osgi/useradmin/LdifUser.java +++ b/org.argeo.util/src/org/argeo/osgi/useradmin/LdifUser.java @@ -22,9 +22,9 @@ import javax.naming.directory.Attributes; import javax.naming.directory.BasicAttribute; import javax.naming.ldap.LdapName; -import org.argeo.naming.AuthPassword; -import org.argeo.naming.LdapAttrs; -import org.argeo.naming.SharedSecret; +import org.argeo.util.naming.AuthPassword; +import org.argeo.util.naming.LdapAttrs; +import org.argeo.util.naming.SharedSecret; /** Directory user implementation */ class LdifUser implements DirectoryUser { diff --git a/org.argeo.util/src/org/argeo/osgi/useradmin/LdifUserAdmin.java b/org.argeo.util/src/org/argeo/osgi/useradmin/LdifUserAdmin.java index c32bbc53f..8b1206a72 100644 --- a/org.argeo.util/src/org/argeo/osgi/useradmin/LdifUserAdmin.java +++ b/org.argeo.util/src/org/argeo/osgi/useradmin/LdifUserAdmin.java @@ -1,7 +1,7 @@ package org.argeo.osgi.useradmin; -import static org.argeo.naming.LdapAttrs.objectClass; -import static org.argeo.naming.LdapObjs.inetOrgPerson; +import static org.argeo.util.naming.LdapAttrs.objectClass; +import static org.argeo.util.naming.LdapObjs.inetOrgPerson; import java.io.File; import java.io.FileOutputStream; @@ -25,8 +25,8 @@ import javax.naming.NamingEnumeration; import javax.naming.directory.Attributes; import javax.naming.ldap.LdapName; -import org.argeo.naming.LdifParser; -import org.argeo.naming.LdifWriter; +import org.argeo.util.naming.LdifParser; +import org.argeo.util.naming.LdifWriter; import org.osgi.framework.Filter; import org.osgi.service.useradmin.Role; import org.osgi.service.useradmin.User; diff --git a/org.argeo.util/src/org/argeo/osgi/useradmin/OsUserDirectory.java b/org.argeo.util/src/org/argeo/osgi/useradmin/OsUserDirectory.java index fe1ca7643..dd16e1a3b 100644 --- a/org.argeo.util/src/org/argeo/osgi/useradmin/OsUserDirectory.java +++ b/org.argeo.util/src/org/argeo/osgi/useradmin/OsUserDirectory.java @@ -11,7 +11,7 @@ import javax.naming.directory.Attributes; import javax.naming.directory.BasicAttributes; import javax.naming.ldap.LdapName; -import org.argeo.naming.LdapAttrs; +import org.argeo.util.naming.LdapAttrs; import org.osgi.framework.Filter; import org.osgi.service.useradmin.User; diff --git a/org.argeo.util/src/org/argeo/osgi/useradmin/TokenUtils.java b/org.argeo.util/src/org/argeo/osgi/useradmin/TokenUtils.java index 83c1d76f6..4b00e6c6a 100644 --- a/org.argeo.util/src/org/argeo/osgi/useradmin/TokenUtils.java +++ b/org.argeo.util/src/org/argeo/osgi/useradmin/TokenUtils.java @@ -1,7 +1,7 @@ package org.argeo.osgi.useradmin; -import static org.argeo.naming.LdapAttrs.description; -import static org.argeo.naming.LdapAttrs.owner; +import static org.argeo.util.naming.LdapAttrs.description; +import static org.argeo.util.naming.LdapAttrs.owner; import java.security.Principal; import java.time.Instant; @@ -12,7 +12,7 @@ import javax.naming.InvalidNameException; import javax.naming.ldap.LdapName; import javax.security.auth.Subject; -import org.argeo.naming.NamingUtils; +import org.argeo.util.naming.NamingUtils; import org.osgi.service.useradmin.Group; /** diff --git a/org.argeo.util/src/org/argeo/osgi/useradmin/UserAdminConf.java b/org.argeo.util/src/org/argeo/osgi/useradmin/UserAdminConf.java index ec41978dc..8941f98b4 100644 --- a/org.argeo.util/src/org/argeo/osgi/useradmin/UserAdminConf.java +++ b/org.argeo.util/src/org/argeo/osgi/useradmin/UserAdminConf.java @@ -12,7 +12,7 @@ import java.util.Map; import javax.naming.Context; import javax.naming.ldap.LdapName; -import org.argeo.naming.NamingUtils; +import org.argeo.util.naming.NamingUtils; /** Properties used to configure user admins. */ public enum UserAdminConf { diff --git a/org.argeo.util/src/org/argeo/util/naming/AttributesDictionary.java b/org.argeo.util/src/org/argeo/util/naming/AttributesDictionary.java new file mode 100644 index 000000000..7c645f3a3 --- /dev/null +++ b/org.argeo.util/src/org/argeo/util/naming/AttributesDictionary.java @@ -0,0 +1,171 @@ +package org.argeo.util.naming; + +import java.util.Dictionary; +import java.util.Enumeration; + +import javax.naming.NamingEnumeration; +import javax.naming.NamingException; +import javax.naming.directory.Attribute; +import javax.naming.directory.Attributes; +import javax.naming.directory.BasicAttribute; + +public class AttributesDictionary extends Dictionary { + private final Attributes attributes; + + /** The provided attributes is wrapped, not copied. */ + public AttributesDictionary(Attributes attributes) { + if (attributes == null) + throw new IllegalArgumentException("Attributes cannot be null"); + this.attributes = attributes; + } + + @Override + public int size() { + return attributes.size(); + } + + @Override + public boolean isEmpty() { + return attributes.size() == 0; + } + + @Override + public Enumeration keys() { + NamingEnumeration namingEnumeration = attributes.getIDs(); + return new Enumeration() { + + @Override + public boolean hasMoreElements() { + return namingEnumeration.hasMoreElements(); + } + + @Override + public String nextElement() { + return namingEnumeration.nextElement(); + } + + }; + } + + @Override + public Enumeration elements() { + NamingEnumeration namingEnumeration = attributes.getIDs(); + return new Enumeration() { + + @Override + public boolean hasMoreElements() { + return namingEnumeration.hasMoreElements(); + } + + @Override + public Object nextElement() { + String key = namingEnumeration.nextElement(); + return get(key); + } + + }; + } + + @Override + /** @returns a String or String[] */ + public Object get(Object key) { + try { + if (key == null) + throw new IllegalArgumentException("Key cannot be null"); + Attribute attr = attributes.get(key.toString()); + if (attr == null) + return null; + if (attr.size() == 0) + throw new IllegalStateException("There must be at least one value"); + else if (attr.size() == 1) { + return attr.get().toString(); + } else {// multiple + String[] res = new String[attr.size()]; + for (int i = 0; i < attr.size(); i++) { + Object value = attr.get(); + if (value == null) + throw new RuntimeException("Values cannot be null"); + res[i] = attr.get(i).toString(); + } + return res; + } + } catch (NamingException e) { + throw new RuntimeException("Cannot get value for " + key, e); + } + } + + @Override + public Object put(String key, Object value) { + if (key == null) + throw new IllegalArgumentException("Key cannot be null"); + if (value == null) + throw new IllegalArgumentException("Value cannot be null"); + + Object oldValue = get(key); + Attribute attr = attributes.get(key); + if (attr == null) { + attr = new BasicAttribute(key); + attributes.put(attr); + } + + if (value instanceof String[]) { + String[] values = (String[]) value; + // clean additional values + for (int i = values.length; i < attr.size(); i++) + attr.remove(i); + // set values + for (int i = 0; i < values.length; i++) { + attr.set(i, values[i]); + } + } else { + if (attr.size() > 1) + throw new IllegalArgumentException("Attribute " + key + " is multi-valued"); + if (attr.size() == 1) { + try { + if (!attr.get(0).equals(value)) + attr.set(0, value.toString()); + } catch (NamingException e) { + throw new RuntimeException("Cannot check existing value", e); + } + } else { + attr.add(value.toString()); + } + } + return oldValue; + } + + @Override + public Object remove(Object key) { + if (key == null) + throw new IllegalArgumentException("Key cannot be null"); + Object oldValue = get(key); + if (oldValue == null) + return null; + return attributes.remove(key.toString()); + } + + /** + * Copy the content of an {@link Attributes} to the provided + * {@link Dictionary}. + */ + public static void copy(Attributes attributes, Dictionary dictionary) { + AttributesDictionary ad = new AttributesDictionary(attributes); + Enumeration keys = ad.keys(); + while (keys.hasMoreElements()) { + String key = keys.nextElement(); + dictionary.put(key, ad.get(key)); + } + } + + /** + * Copy a {@link Dictionary} into an {@link Attributes}. + */ + public static void copy(Dictionary dictionary, Attributes attributes) { + AttributesDictionary ad = new AttributesDictionary(attributes); + Enumeration keys = dictionary.keys(); + while (keys.hasMoreElements()) { + String key = keys.nextElement(); + ad.put(key, dictionary.get(key)); + } + } +} diff --git a/org.argeo.util/src/org/argeo/util/naming/AuthPassword.java b/org.argeo.util/src/org/argeo/util/naming/AuthPassword.java new file mode 100644 index 000000000..973b90f0f --- /dev/null +++ b/org.argeo.util/src/org/argeo/util/naming/AuthPassword.java @@ -0,0 +1,140 @@ +package org.argeo.util.naming; + +import java.io.IOException; +import java.util.Arrays; +import java.util.StringTokenizer; + +import javax.naming.NamingEnumeration; +import javax.naming.NamingException; +import javax.naming.directory.Attribute; +import javax.naming.directory.Attributes; +import javax.security.auth.callback.Callback; +import javax.security.auth.callback.CallbackHandler; +import javax.security.auth.callback.NameCallback; +import javax.security.auth.callback.PasswordCallback; +import javax.security.auth.callback.UnsupportedCallbackException; + +import org.argeo.osgi.useradmin.UserDirectoryException; + +/** LDAP authPassword field according to RFC 3112 */ +public class AuthPassword implements CallbackHandler { + private final String authScheme; + private final String authInfo; + private final String authValue; + + public AuthPassword(String value) { + StringTokenizer st = new StringTokenizer(value, "$"); + // TODO make it more robust, deal with bad formatting + this.authScheme = st.nextToken().trim(); + this.authInfo = st.nextToken().trim(); + this.authValue = st.nextToken().trim(); + + String expectedAuthScheme = getExpectedAuthScheme(); + if (expectedAuthScheme != null && !authScheme.equals(expectedAuthScheme)) + throw new IllegalArgumentException( + "Auth scheme " + authScheme + " is not compatible with " + expectedAuthScheme); + } + + protected AuthPassword(String authInfo, String authValue) { + this.authScheme = getExpectedAuthScheme(); + if (authScheme == null) + throw new IllegalArgumentException("Expected auth scheme cannot be null"); + this.authInfo = authInfo; + this.authValue = authValue; + } + + protected AuthPassword(AuthPassword authPassword) { + this.authScheme = authPassword.getAuthScheme(); + this.authInfo = authPassword.getAuthInfo(); + this.authValue = authPassword.getAuthValue(); + } + + protected String getExpectedAuthScheme() { + return null; + } + + protected boolean matchAuthValue(Object object) { + return authValue.equals(object.toString()); + } + + @Override + public boolean equals(Object obj) { + if (!(obj instanceof AuthPassword)) + return false; + AuthPassword authPassword = (AuthPassword) obj; + return authScheme.equals(authPassword.authScheme) && authInfo.equals(authPassword.authInfo) + && authValue.equals(authValue); + } + + public boolean keyEquals(AuthPassword authPassword) { + return authScheme.equals(authPassword.authScheme) && authInfo.equals(authPassword.authInfo); + } + + @Override + public int hashCode() { + return authValue.hashCode(); + } + + @Override + public String toString() { + return toAuthPassword(); + } + + public final String toAuthPassword() { + return getAuthScheme() + '$' + authInfo + '$' + authValue; + } + + public String getAuthScheme() { + return authScheme; + } + + public String getAuthInfo() { + return authInfo; + } + + public String getAuthValue() { + return authValue; + } + + public static AuthPassword matchAuthValue(Attributes attributes, char[] value) { + try { + Attribute authPassword = attributes.get(LdapAttrs.authPassword.name()); + if (authPassword != null) { + NamingEnumeration values = authPassword.getAll(); + while (values.hasMore()) { + Object val = values.next(); + AuthPassword token = new AuthPassword(val.toString()); + String auth; + if (Arrays.binarySearch(value, '$') >= 0) { + auth = token.authInfo + '$' + token.authValue; + } else { + auth = token.authValue; + } + if (Arrays.equals(auth.toCharArray(), value)) + return token; + // if (token.matchAuthValue(value)) + // return token; + } + } + return null; + } catch (NamingException e) { + throw new UserDirectoryException("Cannot check attribute", e); + } + } + + public static boolean remove(Attributes attributes, AuthPassword value) { + Attribute authPassword = attributes.get(LdapAttrs.authPassword.name()); + return authPassword.remove(value.toAuthPassword()); + } + + @Override + public void handle(Callback[] callbacks) throws IOException, UnsupportedCallbackException { + for (Callback callback : callbacks) { + if (callback instanceof NameCallback) + ((NameCallback) callback).setName(toAuthPassword()); + else if (callback instanceof PasswordCallback) + ((PasswordCallback) callback).setPassword(getAuthValue().toCharArray()); + } + } + +} diff --git a/org.argeo.util/src/org/argeo/util/naming/Distinguished.java b/org.argeo.util/src/org/argeo/util/naming/Distinguished.java new file mode 100644 index 000000000..6aefc1617 --- /dev/null +++ b/org.argeo.util/src/org/argeo/util/naming/Distinguished.java @@ -0,0 +1,36 @@ +package org.argeo.util.naming; + +import java.util.EnumSet; +import java.util.Set; +import java.util.TreeSet; + +import javax.naming.InvalidNameException; +import javax.naming.ldap.LdapName; + +/** + * An object that can be identified with an X.500 distinguished name. + * + * @see https://tools.ietf.org/html/rfc1779 + */ +public interface Distinguished { + /** The related distinguished name. */ + String dn(); + + /** The related distinguished name as an {@link LdapName}. */ + default LdapName distinguishedName() { + try { + return new LdapName(dn()); + } catch (InvalidNameException e) { + throw new IllegalArgumentException("Distinguished name " + dn() + " is not properly formatted.", e); + } + } + + /** List all DNs of an enumeration as strings. */ + static Set enumToDns(EnumSet enumSet) { + Set res = new TreeSet<>(); + for (Enum enm : enumSet) { + res.add(((Distinguished) enm).dn()); + } + return res; + } +} diff --git a/org.argeo.util/src/org/argeo/util/naming/DnsBrowser.java b/org.argeo.util/src/org/argeo/util/naming/DnsBrowser.java new file mode 100644 index 000000000..1a67eea36 --- /dev/null +++ b/org.argeo.util/src/org/argeo/util/naming/DnsBrowser.java @@ -0,0 +1,179 @@ +package org.argeo.util.naming; + +import java.io.Closeable; +import java.io.IOException; +import java.io.PrintStream; +import java.util.ArrayList; +import java.util.Base64; +import java.util.Collections; +import java.util.Hashtable; +import java.util.List; +import java.util.Map; +import java.util.SortedSet; +import java.util.TreeMap; +import java.util.TreeSet; + +import javax.naming.Binding; +import javax.naming.NamingEnumeration; +import javax.naming.NamingException; +import javax.naming.directory.Attribute; +import javax.naming.directory.Attributes; +import javax.naming.directory.DirContext; +import javax.naming.directory.InitialDirContext; + +public class DnsBrowser implements Closeable { + private final DirContext initialCtx; + + public DnsBrowser() throws NamingException { + this(null); + } + + public DnsBrowser(String dnsServerUrls) throws NamingException { + Hashtable env = new Hashtable<>(); + env.put("java.naming.factory.initial", "com.sun.jndi.dns.DnsContextFactory"); + if (dnsServerUrls != null) + env.put("java.naming.provider.url", dnsServerUrls); + initialCtx = new InitialDirContext(env); + } + + public Map> getAllRecords(String name) throws NamingException { + Map> res = new TreeMap<>(); + Attributes attrs = initialCtx.getAttributes(name); + NamingEnumeration ids = attrs.getIDs(); + while (ids.hasMore()) { + String recordType = ids.next(); + List lst = new ArrayList(); + res.put(recordType, lst); + Attribute attr = attrs.get(recordType); + addValues(attr, lst); + } + return Collections.unmodifiableMap(res); + } + + /** + * Return a single record (typically A, AAAA, etc. or null if not available. + * Will fail if multiple records. + */ + public String getRecord(String name, String recordType) throws NamingException { + Attributes attrs = initialCtx.getAttributes(name, new String[] { recordType }); + if (attrs.size() == 0) + return null; + Attribute attr = attrs.get(recordType); + if (attr.size() > 1) + throw new IllegalArgumentException("Multiple record type " + recordType); + assert attr.size() != 0; + Object value = attr.get(); + assert value != null; + return value.toString(); + } + + /** + * Return records of a given type. + */ + public List getRecords(String name, String recordType) throws NamingException { + List res = new ArrayList(); + Attributes attrs = initialCtx.getAttributes(name, new String[] { recordType }); + Attribute attr = attrs.get(recordType); + addValues(attr, res); + return res; + } + + /** Ordered, with preferred first. */ + public List getSrvRecordsAsHosts(String name, boolean withPort) throws NamingException { + List raw = getRecords(name, "SRV"); + if (raw.size() == 0) + return null; + SortedSet res = new TreeSet<>(); + for (int i = 0; i < raw.size(); i++) { + String record = raw.get(i); + String[] arr = record.split(" "); + Integer priority = Integer.parseInt(arr[0]); + Integer weight = Integer.parseInt(arr[1]); + Integer port = Integer.parseInt(arr[2]); + String hostname = arr[3]; + SrvRecord order = new SrvRecord(priority, weight, port, hostname); + res.add(order); + } + List lst = new ArrayList<>(); + for (SrvRecord order : res) { + lst.add(order.toHost(withPort)); + } + return Collections.unmodifiableList(lst); + } + + private void addValues(Attribute attr, List lst) throws NamingException { + NamingEnumeration values = attr.getAll(); + while (values.hasMore()) { + Object value = values.next(); + if (value != null) { + if (value instanceof byte[]) { + String str = Base64.getEncoder().encodeToString((byte[]) value); + lst.add(str); + } else + lst.add(value.toString()); + } + } + + } + + public List listEntries(String name) throws NamingException { + List res = new ArrayList(); + NamingEnumeration ne = initialCtx.listBindings(name); + while (ne.hasMore()) { + Binding b = ne.next(); + res.add(b.getName()); + } + return Collections.unmodifiableList(res); + } + + @Override + public void close() throws IOException { + destroy(); + } + + public void destroy() { + try { + initialCtx.close(); + } catch (NamingException e) { + // silent + } + } + + public static void main(String[] args) { + if (args.length == 0) { + printUsage(System.err); + System.exit(1); + } + try (DnsBrowser dnsBrowser = new DnsBrowser()) { + String hostname = args[0]; + String recordType = args.length > 1 ? args[1] : "A"; + if (recordType.equals("*")) { + Map> records = dnsBrowser.getAllRecords(hostname); + for (String type : records.keySet()) { + for (String record : records.get(type)) { + String typeLabel; + if ("44".equals(type)) + typeLabel = "SSHFP"; + else if ("46".equals(type)) + typeLabel = "RRSIG"; + else if ("48".equals(type)) + typeLabel = "DNSKEY"; + else + typeLabel = type; + System.out.println(typeLabel + "\t" + record); + } + } + } else { + System.out.println(dnsBrowser.getRecord(hostname, recordType)); + } + + } catch (Exception e) { + e.printStackTrace(); + } + } + + public static void printUsage(PrintStream out) { + out.println("java org.argeo.naming.DnsBrowser [ | *]"); + } + +} \ No newline at end of file diff --git a/org.argeo.util/src/org/argeo/util/naming/LdapAttrs.csv b/org.argeo.util/src/org/argeo/util/naming/LdapAttrs.csv new file mode 100644 index 000000000..676d72720 --- /dev/null +++ b/org.argeo.util/src/org/argeo/util/naming/LdapAttrs.csv @@ -0,0 +1,129 @@ +uid,,,0.9.2342.19200300.100.1.1,,RFC 4519 +mail,,,0.9.2342.19200300.100.1.3,,RFC 4524 +info,,,0.9.2342.19200300.100.1.4,,RFC 4524 +drink,,,0.9.2342.19200300.100.1.5,,RFC 4524 +roomNumber,,,0.9.2342.19200300.100.1.6,,RFC 4524 +photo,,,0.9.2342.19200300.100.1.7,,RFC 2798 +userClass,,,0.9.2342.19200300.100.1.8,,RFC 4524 +host,,,0.9.2342.19200300.100.1.9,,RFC 4524 +manager,,,0.9.2342.19200300.100.1.10,,RFC 4524 +documentIdentifier,,,0.9.2342.19200300.100.1.11,,RFC 4524 +documentTitle,,,0.9.2342.19200300.100.1.12,,RFC 4524 +documentVersion,,,0.9.2342.19200300.100.1.13,,RFC 4524 +documentAuthor,,,0.9.2342.19200300.100.1.14,,RFC 4524 +documentLocation,,,0.9.2342.19200300.100.1.15,,RFC 4524 +homePhone,,,0.9.2342.19200300.100.1.20,,RFC 4524 +secretary,,,0.9.2342.19200300.100.1.21,,RFC 4524 +dc,,,0.9.2342.19200300.100.1.25,,RFC 4519 +associatedDomain,,,0.9.2342.19200300.100.1.37,,RFC 4524 +associatedName,,,0.9.2342.19200300.100.1.38,,RFC 4524 +homePostalAddress,,,0.9.2342.19200300.100.1.39,,RFC 4524 +personalTitle,,,0.9.2342.19200300.100.1.40,,RFC 4524 +mobile,,,0.9.2342.19200300.100.1.41,,RFC 4524 +pager,,,0.9.2342.19200300.100.1.42,,RFC 4524 +co,,,0.9.2342.19200300.100.1.43,,RFC 4524 +uniqueIdentifier,,,0.9.2342.19200300.100.1.44,,RFC 4524 +organizationalStatus,,,0.9.2342.19200300.100.1.45,,RFC 4524 +buildingName,,,0.9.2342.19200300.100.1.48,,RFC 4524 +audio,,,0.9.2342.19200300.100.1.55,,RFC 2798 +documentPublisher,,,0.9.2342.19200300.100.1.56,,RFC 4524 +jpegPhoto,,,0.9.2342.19200300.100.1.60,,RFC 2798 +vendorName,,,1.3.6.1.1.4,,RFC 3045 +vendorVersion,,,1.3.6.1.1.5,,RFC 3045 +entryUUID,,,1.3.6.1.1.16.4,,RFC 4530 +entryDN,,,1.3.6.1.1.20,,RFC 5020 +labeledURI,,,1.3.6.1.4.1.250.1.57,,RFC 2798 +numSubordinates,,,1.3.6.1.4.1.453.16.2.103,,draft-ietf-boreham-numsubordinates +namingContexts,,,1.3.6.1.4.1.1466.101.120.5,,RFC 4512 +altServer,,,1.3.6.1.4.1.1466.101.120.6,,RFC 4512 +supportedExtension,,,1.3.6.1.4.1.1466.101.120.7,,RFC 4512 +supportedControl,,,1.3.6.1.4.1.1466.101.120.13,,RFC 4512 +supportedSASLMechanisms,,,1.3.6.1.4.1.1466.101.120.14,,RFC 4512 +supportedLDAPVersion,,,1.3.6.1.4.1.1466.101.120.15,,RFC 4512 +ldapSyntaxes,,,1.3.6.1.4.1.1466.101.120.16,,RFC 4512 +supportedAuthPasswordSchemes,,,1.3.6.1.4.1.4203.1.3.3,,RFC 3112 +authPassword,,,1.3.6.1.4.1.4203.1.3.4,,RFC 3112 +supportedFeatures,,,1.3.6.1.4.1.4203.1.3.5,,RFC 4512 +inheritable,,,1.3.6.1.4.1.7628.5.4.1,,draft-ietf-ldup-subentry +blockInheritance,,,1.3.6.1.4.1.7628.5.4.2,,draft-ietf-ldup-subentry +objectClass,,,2.5.4.0,,RFC 4512 +aliasedObjectName,,,2.5.4.1,,RFC 4512 +cn,,,2.5.4.3,,RFC 4519 +sn,,,2.5.4.4,,RFC 4519 +serialNumber,,,2.5.4.5,,RFC 4519 +c,,,2.5.4.6,,RFC 4519 +l,,,2.5.4.7,,RFC 4519 +st,,,2.5.4.8,,RFC 4519 +street,,,2.5.4.9,,RFC 4519 +o,,,2.5.4.10,,RFC 4519 +ou,,,2.5.4.11,,RFC 4519 +title,,,2.5.4.12,,RFC 4519 +description,,,2.5.4.13,,RFC 4519 +searchGuide,,,2.5.4.14,,RFC 4519 +businessCategory,,,2.5.4.15,,RFC 4519 +postalAddress,,,2.5.4.16,,RFC 4519 +postalCode,,,2.5.4.17,,RFC 4519 +postOfficeBox,,,2.5.4.18,,RFC 4519 +physicalDeliveryOfficeName,,,2.5.4.19,,RFC 4519 +telephoneNumber,,,2.5.4.20,,RFC 4519 +telexNumber,,,2.5.4.21,,RFC 4519 +teletexTerminalIdentifier,,,2.5.4.22,,RFC 4519 +facsimileTelephoneNumber,,,2.5.4.23,,RFC 4519 +x121Address,,,2.5.4.24,,RFC 4519 +internationalISDNNumber,,,2.5.4.25,,RFC 4519 +registeredAddress,,,2.5.4.26,,RFC 4519 +destinationIndicator,,,2.5.4.27,,RFC 4519 +preferredDeliveryMethod,,,2.5.4.28,,RFC 4519 +member,,,2.5.4.31,,RFC 4519 +owner,,,2.5.4.32,,RFC 4519 +roleOccupant,,,2.5.4.33,,RFC 4519 +seeAlso,,,2.5.4.34,,RFC 4519 +userPassword,,,2.5.4.35,,RFC 4519 +userCertificate,,,2.5.4.36,,RFC 4523 +cACertificate,,,2.5.4.37,,RFC 4523 +authorityRevocationList,,,2.5.4.38,,RFC 4523 +certificateRevocationList,,,2.5.4.39,,RFC 4523 +crossCertificatePair,,,2.5.4.40,,RFC 4523 +name,,,2.5.4.41,,RFC 4519 +givenName,,,2.5.4.42,,RFC 4519 +initials,,,2.5.4.43,,RFC 4519 +generationQualifier,,,2.5.4.44,,RFC 4519 +x500UniqueIdentifier,,,2.5.4.45,,RFC 4519 +dnQualifier,,,2.5.4.46,,RFC 4519 +enhancedSearchGuide,,,2.5.4.47,,RFC 4519 +distinguishedName,,,2.5.4.49,,RFC 4519 +uniqueMember,,,2.5.4.50,,RFC 4519 +houseIdentifier,,,2.5.4.51,,RFC 4519 +supportedAlgorithms,,,2.5.4.52,,RFC 4523 +deltaRevocationList,,,2.5.4.53,,RFC 4523 +createTimestamp,,,2.5.18.1,,RFC 4512 +modifyTimestamp,,,2.5.18.2,,RFC 4512 +creatorsName,,,2.5.18.3,,RFC 4512 +modifiersName,,,2.5.18.4,,RFC 4512 +subschemaSubentry,,,2.5.18.10,,RFC 4512 +dITStructureRules,,,2.5.21.1,,RFC 4512 +dITContentRules,,,2.5.21.2,,RFC 4512 +matchingRules,,,2.5.21.4,,RFC 4512 +attributeTypes,,,2.5.21.5,,RFC 4512 +objectClasses,,,2.5.21.6,,RFC 4512 +nameForms,,,2.5.21.7,,RFC 4512 +matchingRuleUse,,,2.5.21.8,,RFC 4512 +structuralObjectClass,,,2.5.21.9,,RFC 4512 +governingStructureRule,,,2.5.21.10,,RFC 4512 +carLicense,,,2.16.840.1.113730.3.1.1,,RFC 2798 +departmentNumber,,,2.16.840.1.113730.3.1.2,,RFC 2798 +employeeNumber,,,2.16.840.1.113730.3.1.3,,RFC 2798 +employeeType,,,2.16.840.1.113730.3.1.4,,RFC 2798 +changeNumber,,,2.16.840.1.113730.3.1.5,,draft-good-ldap-changelog +targetDN,,,2.16.840.1.113730.3.1.6,,draft-good-ldap-changelog +changeType,,,2.16.840.1.113730.3.1.7,,draft-good-ldap-changelog +changes,,,2.16.840.1.113730.3.1.8,,draft-good-ldap-changelog +newRDN,,,2.16.840.1.113730.3.1.9,,draft-good-ldap-changelog +deleteOldRDN,,,2.16.840.1.113730.3.1.10,,draft-good-ldap-changelog +newSuperior,,,2.16.840.1.113730.3.1.11,,draft-good-ldap-changelog +ref,,,2.16.840.1.113730.3.1.34,,RFC 3296 +changelog,,,2.16.840.1.113730.3.1.35,,draft-good-ldap-changelog +preferredLanguage,,,2.16.840.1.113730.3.1.39,,RFC 2798 +userSMIMECertificate,,,2.16.840.1.113730.3.1.40,,RFC 2798 +userPKCS12,,,2.16.840.1.113730.3.1.216,,RFC 2798 +displayName,,,2.16.840.1.113730.3.1.241,,RFC 2798 diff --git a/org.argeo.util/src/org/argeo/util/naming/LdapAttrs.java b/org.argeo.util/src/org/argeo/util/naming/LdapAttrs.java new file mode 100644 index 000000000..7dcba0992 --- /dev/null +++ b/org.argeo.util/src/org/argeo/util/naming/LdapAttrs.java @@ -0,0 +1,341 @@ +package org.argeo.util.naming; + +/** + * Standard LDAP attributes as per:
+ * - Standard LDAP
+ * - Kerberos + * LDAP (partial) + */ +public enum LdapAttrs implements SpecifiedName { + /** */ + uid("0.9.2342.19200300.100.1.1", "RFC 4519"), + /** */ + mail("0.9.2342.19200300.100.1.3", "RFC 4524"), + /** */ + info("0.9.2342.19200300.100.1.4", "RFC 4524"), + /** */ + drink("0.9.2342.19200300.100.1.5", "RFC 4524"), + /** */ + roomNumber("0.9.2342.19200300.100.1.6", "RFC 4524"), + /** */ + photo("0.9.2342.19200300.100.1.7", "RFC 2798"), + /** */ + userClass("0.9.2342.19200300.100.1.8", "RFC 4524"), + /** */ + host("0.9.2342.19200300.100.1.9", "RFC 4524"), + /** */ + manager("0.9.2342.19200300.100.1.10", "RFC 4524"), + /** */ + documentIdentifier("0.9.2342.19200300.100.1.11", "RFC 4524"), + /** */ + documentTitle("0.9.2342.19200300.100.1.12", "RFC 4524"), + /** */ + documentVersion("0.9.2342.19200300.100.1.13", "RFC 4524"), + /** */ + documentAuthor("0.9.2342.19200300.100.1.14", "RFC 4524"), + /** */ + documentLocation("0.9.2342.19200300.100.1.15", "RFC 4524"), + /** */ + homePhone("0.9.2342.19200300.100.1.20", "RFC 4524"), + /** */ + secretary("0.9.2342.19200300.100.1.21", "RFC 4524"), + /** */ + dc("0.9.2342.19200300.100.1.25", "RFC 4519"), + /** */ + associatedDomain("0.9.2342.19200300.100.1.37", "RFC 4524"), + /** */ + associatedName("0.9.2342.19200300.100.1.38", "RFC 4524"), + /** */ + homePostalAddress("0.9.2342.19200300.100.1.39", "RFC 4524"), + /** */ + personalTitle("0.9.2342.19200300.100.1.40", "RFC 4524"), + /** */ + mobile("0.9.2342.19200300.100.1.41", "RFC 4524"), + /** */ + pager("0.9.2342.19200300.100.1.42", "RFC 4524"), + /** */ + co("0.9.2342.19200300.100.1.43", "RFC 4524"), + /** */ + uniqueIdentifier("0.9.2342.19200300.100.1.44", "RFC 4524"), + /** */ + organizationalStatus("0.9.2342.19200300.100.1.45", "RFC 4524"), + /** */ + buildingName("0.9.2342.19200300.100.1.48", "RFC 4524"), + /** */ + audio("0.9.2342.19200300.100.1.55", "RFC 2798"), + /** */ + documentPublisher("0.9.2342.19200300.100.1.56", "RFC 4524"), + /** */ + jpegPhoto("0.9.2342.19200300.100.1.60", "RFC 2798"), + /** */ + vendorName("1.3.6.1.1.4", "RFC 3045"), + /** */ + vendorVersion("1.3.6.1.1.5", "RFC 3045"), + /** */ + entryUUID("1.3.6.1.1.16.4", "RFC 4530"), + /** */ + entryDN("1.3.6.1.1.20", "RFC 5020"), + /** */ + labeledURI("1.3.6.1.4.1.250.1.57", "RFC 2798"), + /** */ + numSubordinates("1.3.6.1.4.1.453.16.2.103", "draft-ietf-boreham-numsubordinates"), + /** */ + namingContexts("1.3.6.1.4.1.1466.101.120.5", "RFC 4512"), + /** */ + altServer("1.3.6.1.4.1.1466.101.120.6", "RFC 4512"), + /** */ + supportedExtension("1.3.6.1.4.1.1466.101.120.7", "RFC 4512"), + /** */ + supportedControl("1.3.6.1.4.1.1466.101.120.13", "RFC 4512"), + /** */ + supportedSASLMechanisms("1.3.6.1.4.1.1466.101.120.14", "RFC 4512"), + /** */ + supportedLDAPVersion("1.3.6.1.4.1.1466.101.120.15", "RFC 4512"), + /** */ + ldapSyntaxes("1.3.6.1.4.1.1466.101.120.16", "RFC 4512"), + /** */ + supportedAuthPasswordSchemes("1.3.6.1.4.1.4203.1.3.3", "RFC 3112"), + /** */ + authPassword("1.3.6.1.4.1.4203.1.3.4", "RFC 3112"), + /** */ + supportedFeatures("1.3.6.1.4.1.4203.1.3.5", "RFC 4512"), + /** */ + inheritable("1.3.6.1.4.1.7628.5.4.1", "draft-ietf-ldup-subentry"), + /** */ + blockInheritance("1.3.6.1.4.1.7628.5.4.2", "draft-ietf-ldup-subentry"), + /** */ + objectClass("2.5.4.0", "RFC 4512"), + /** */ + aliasedObjectName("2.5.4.1", "RFC 4512"), + /** */ + cn("2.5.4.3", "RFC 4519"), + /** */ + sn("2.5.4.4", "RFC 4519"), + /** */ + serialNumber("2.5.4.5", "RFC 4519"), + /** */ + c("2.5.4.6", "RFC 4519"), + /** */ + l("2.5.4.7", "RFC 4519"), + /** */ + st("2.5.4.8", "RFC 4519"), + /** */ + street("2.5.4.9", "RFC 4519"), + /** */ + o("2.5.4.10", "RFC 4519"), + /** */ + ou("2.5.4.11", "RFC 4519"), + /** */ + title("2.5.4.12", "RFC 4519"), + /** */ + description("2.5.4.13", "RFC 4519"), + /** */ + searchGuide("2.5.4.14", "RFC 4519"), + /** */ + businessCategory("2.5.4.15", "RFC 4519"), + /** */ + postalAddress("2.5.4.16", "RFC 4519"), + /** */ + postalCode("2.5.4.17", "RFC 4519"), + /** */ + postOfficeBox("2.5.4.18", "RFC 4519"), + /** */ + physicalDeliveryOfficeName("2.5.4.19", "RFC 4519"), + /** */ + telephoneNumber("2.5.4.20", "RFC 4519"), + /** */ + telexNumber("2.5.4.21", "RFC 4519"), + /** */ + teletexTerminalIdentifier("2.5.4.22", "RFC 4519"), + /** */ + facsimileTelephoneNumber("2.5.4.23", "RFC 4519"), + /** */ + x121Address("2.5.4.24", "RFC 4519"), + /** */ + internationalISDNNumber("2.5.4.25", "RFC 4519"), + /** */ + registeredAddress("2.5.4.26", "RFC 4519"), + /** */ + destinationIndicator("2.5.4.27", "RFC 4519"), + /** */ + preferredDeliveryMethod("2.5.4.28", "RFC 4519"), + /** */ + member("2.5.4.31", "RFC 4519"), + /** */ + owner("2.5.4.32", "RFC 4519"), + /** */ + roleOccupant("2.5.4.33", "RFC 4519"), + /** */ + seeAlso("2.5.4.34", "RFC 4519"), + /** */ + userPassword("2.5.4.35", "RFC 4519"), + /** */ + userCertificate("2.5.4.36", "RFC 4523"), + /** */ + cACertificate("2.5.4.37", "RFC 4523"), + /** */ + authorityRevocationList("2.5.4.38", "RFC 4523"), + /** */ + certificateRevocationList("2.5.4.39", "RFC 4523"), + /** */ + crossCertificatePair("2.5.4.40", "RFC 4523"), + /** */ + name("2.5.4.41", "RFC 4519"), + /** */ + givenName("2.5.4.42", "RFC 4519"), + /** */ + initials("2.5.4.43", "RFC 4519"), + /** */ + generationQualifier("2.5.4.44", "RFC 4519"), + /** */ + x500UniqueIdentifier("2.5.4.45", "RFC 4519"), + /** */ + dnQualifier("2.5.4.46", "RFC 4519"), + /** */ + enhancedSearchGuide("2.5.4.47", "RFC 4519"), + /** */ + distinguishedName("2.5.4.49", "RFC 4519"), + /** */ + uniqueMember("2.5.4.50", "RFC 4519"), + /** */ + houseIdentifier("2.5.4.51", "RFC 4519"), + /** */ + supportedAlgorithms("2.5.4.52", "RFC 4523"), + /** */ + deltaRevocationList("2.5.4.53", "RFC 4523"), + /** */ + createTimestamp("2.5.18.1", "RFC 4512"), + /** */ + modifyTimestamp("2.5.18.2", "RFC 4512"), + /** */ + creatorsName("2.5.18.3", "RFC 4512"), + /** */ + modifiersName("2.5.18.4", "RFC 4512"), + /** */ + subschemaSubentry("2.5.18.10", "RFC 4512"), + /** */ + dITStructureRules("2.5.21.1", "RFC 4512"), + /** */ + dITContentRules("2.5.21.2", "RFC 4512"), + /** */ + matchingRules("2.5.21.4", "RFC 4512"), + /** */ + attributeTypes("2.5.21.5", "RFC 4512"), + /** */ + objectClasses("2.5.21.6", "RFC 4512"), + /** */ + nameForms("2.5.21.7", "RFC 4512"), + /** */ + matchingRuleUse("2.5.21.8", "RFC 4512"), + /** */ + structuralObjectClass("2.5.21.9", "RFC 4512"), + /** */ + governingStructureRule("2.5.21.10", "RFC 4512"), + /** */ + carLicense("2.16.840.1.113730.3.1.1", "RFC 2798"), + /** */ + departmentNumber("2.16.840.1.113730.3.1.2", "RFC 2798"), + /** */ + employeeNumber("2.16.840.1.113730.3.1.3", "RFC 2798"), + /** */ + employeeType("2.16.840.1.113730.3.1.4", "RFC 2798"), + /** */ + changeNumber("2.16.840.1.113730.3.1.5", "draft-good-ldap-changelog"), + /** */ + targetDN("2.16.840.1.113730.3.1.6", "draft-good-ldap-changelog"), + /** */ + changeType("2.16.840.1.113730.3.1.7", "draft-good-ldap-changelog"), + /** */ + changes("2.16.840.1.113730.3.1.8", "draft-good-ldap-changelog"), + /** */ + newRDN("2.16.840.1.113730.3.1.9", "draft-good-ldap-changelog"), + /** */ + deleteOldRDN("2.16.840.1.113730.3.1.10", "draft-good-ldap-changelog"), + /** */ + newSuperior("2.16.840.1.113730.3.1.11", "draft-good-ldap-changelog"), + /** */ + ref("2.16.840.1.113730.3.1.34", "RFC 3296"), + /** */ + changelog("2.16.840.1.113730.3.1.35", "draft-good-ldap-changelog"), + /** */ + preferredLanguage("2.16.840.1.113730.3.1.39", "RFC 2798"), + /** */ + userSMIMECertificate("2.16.840.1.113730.3.1.40", "RFC 2798"), + /** */ + userPKCS12("2.16.840.1.113730.3.1.216", "RFC 2798"), + /** */ + displayName("2.16.840.1.113730.3.1.241", "RFC 2798"), + + // Sun memberOf + memberOf("1.2.840.113556.1.2.102", "389 DS memberOf"), + + // KERBEROS (partial) + krbPrincipalName("2.16.840.1.113719.1.301.6.8.1", "Novell Kerberos Schema Definitions"), + + // RFC 2985 and RFC 3039 (partial) + dateOfBirth("1.3.6.1.5.5.7.9.1", "RFC 2985"), + /** */ + placeOfBirth("1.3.6.1.5.5.7.9.2", "RFC 2985"), + /** */ + gender("1.3.6.1.5.5.7.9.3", "RFC 2985"), + /** */ + countryOfCitizenship("1.3.6.1.5.5.7.9.4", "RFC 2985"), + /** */ + countryOfResidence("1.3.6.1.5.5.7.9.5", "RFC 2985"), + // + ; + + public final static String DN = "dn"; + +// private final static String LDAP_ = "ldap:"; + + private final String oid, spec; + + LdapAttrs(String oid, String spec) { + this.oid = oid; + this.spec = spec; + } + + @Override + public String getID() { + return oid; + } + + @Override + public String getSpec() { + return spec; + } + + public String getPrefix() { + return prefix(); + } + + public static String prefix() { + return "ldap"; + } + + public String property() { + return qualified(); + } + + public String qualified() { + String prefix = getPrefix(); + return prefix != null ? prefix + ":" + name() : name(); + } + + public String getNamespace() { + return namespace(); + } + + public static String namespace() { + return "http://www.argeo.org/ns/ldap"; + } + + @Override + public final String toString() { + // must return the name + return name(); + } + +} diff --git a/org.argeo.util/src/org/argeo/util/naming/LdapObjs.csv b/org.argeo.util/src/org/argeo/util/naming/LdapObjs.csv new file mode 100644 index 000000000..3d907cbeb --- /dev/null +++ b/org.argeo.util/src/org/argeo/util/naming/LdapObjs.csv @@ -0,0 +1,42 @@ +account,,,0.9.2342.19200300.100.4.5,,RFC 4524 +document,,,0.9.2342.19200300.100.4.6,,RFC 4524 +room,,,0.9.2342.19200300.100.4.7,,RFC 4524 +documentSeries,,,0.9.2342.19200300.100.4.9,,RFC 4524 +domain,,,0.9.2342.19200300.100.4.13,,RFC 4524 +rFC822localPart,,,0.9.2342.19200300.100.4.14,,RFC 4524 +domainRelatedObject,,,0.9.2342.19200300.100.4.17,,RFC 4524 +friendlyCountry,,,0.9.2342.19200300.100.4.18,,RFC 4524 +simpleSecurityObject,,,0.9.2342.19200300.100.4.19,,RFC 4524 +uidObject,,,1.3.6.1.1.3.1,,RFC 4519 +extensibleObject,,,1.3.6.1.4.1.1466.101.120.111,,RFC 4512 +dcObject,,,1.3.6.1.4.1.1466.344,,RFC 4519 +authPasswordObject,,,1.3.6.1.4.1.4203.1.4.7,,RFC 3112 +namedObject,,,1.3.6.1.4.1.5322.13.1.1,,draft-howard-namedobject +inheritableLDAPSubEntry,,,1.3.6.1.4.1.7628.5.6.1.1,,draft-ietf-ldup-subentry +top,,,2.5.6.0,,RFC 4512 +alias,,,2.5.6.1,,RFC 4512 +country,,,2.5.6.2,,RFC 4519 +locality,,,2.5.6.3,,RFC 4519 +organization,,,2.5.6.4,,RFC 4519 +organizationalUnit,,,2.5.6.5,,RFC 4519 +person,,,2.5.6.6,,RFC 4519 +organizationalPerson,,,2.5.6.7,,RFC 4519 +organizationalRole,,,2.5.6.8,,RFC 4519 +groupOfNames,,,2.5.6.9,,RFC 4519 +residentialPerson,,,2.5.6.10,,RFC 4519 +applicationProcess,,,2.5.6.11,,RFC 4519 +device,,,2.5.6.14,,RFC 4519 +strongAuthenticationUser,,,2.5.6.15,,RFC 4523 +certificationAuthority,,,2.5.6.16,,RFC 4523 +certificationAuthority-V2,,,2.5.6.16.2,,RFC 4523 +groupOfUniqueNames,,,2.5.6.17,,RFC 4519 +userSecurityInformation,,,2.5.6.18,,RFC 4523 +cRLDistributionPoint,,,2.5.6.19,,RFC 4523 +pkiUser,,,2.5.6.21,,RFC 4523 +pkiCA,,,2.5.6.22,,RFC 4523 +deltaCRL,,,2.5.6.23,,RFC 4523 +subschema,,,2.5.20.1,,RFC 4512 +ldapSubEntry,,,2.16.840.1.113719.2.142.6.1.1,,draft-ietf-ldup-subentry +changeLogEntry,,,2.16.840.1.113730.3.2.1,,draft-good-ldap-changelog +inetOrgPerson,,,2.16.840.1.113730.3.2.2,,RFC 2798 +referral,,,2.16.840.1.113730.3.2.6,,RFC 3296 diff --git a/org.argeo.util/src/org/argeo/util/naming/LdapObjs.java b/org.argeo.util/src/org/argeo/util/naming/LdapObjs.java new file mode 100644 index 000000000..c616d1491 --- /dev/null +++ b/org.argeo.util/src/org/argeo/util/naming/LdapObjs.java @@ -0,0 +1,114 @@ +package org.argeo.util.naming; + +/** + * Standard LDAP object classes as per + * https://www.ldap.com/ldap- + * oid-reference + */ +public enum LdapObjs implements SpecifiedName { + account("0.9.2342.19200300.100.4.5", "RFC 4524"), + /** */ + document("0.9.2342.19200300.100.4.6", "RFC 4524"), + /** */ + room("0.9.2342.19200300.100.4.7", "RFC 4524"), + /** */ + documentSeries("0.9.2342.19200300.100.4.9", "RFC 4524"), + /** */ + domain("0.9.2342.19200300.100.4.13", "RFC 4524"), + /** */ + rFC822localPart("0.9.2342.19200300.100.4.14", "RFC 4524"), + /** */ + domainRelatedObject("0.9.2342.19200300.100.4.17", "RFC 4524"), + /** */ + friendlyCountry("0.9.2342.19200300.100.4.18", "RFC 4524"), + /** */ + simpleSecurityObject("0.9.2342.19200300.100.4.19", "RFC 4524"), + /** */ + uidObject("1.3.6.1.1.3.1", "RFC 4519"), + /** */ + extensibleObject("1.3.6.1.4.1.1466.101.120.111", "RFC 4512"), + /** */ + dcObject("1.3.6.1.4.1.1466.344", "RFC 4519"), + /** */ + authPasswordObject("1.3.6.1.4.1.4203.1.4.7", "RFC 3112"), + /** */ + namedObject("1.3.6.1.4.1.5322.13.1.1", "draft-howard-namedobject"), + /** */ + inheritableLDAPSubEntry("1.3.6.1.4.1.7628.5.6.1.1", "draft-ietf-ldup-subentry"), + /** */ + top("2.5.6.0", "RFC 4512"), + /** */ + alias("2.5.6.1", "RFC 4512"), + /** */ + country("2.5.6.2", "RFC 4519"), + /** */ + locality("2.5.6.3", "RFC 4519"), + /** */ + organization("2.5.6.4", "RFC 4519"), + /** */ + organizationalUnit("2.5.6.5", "RFC 4519"), + /** */ + person("2.5.6.6", "RFC 4519"), + /** */ + organizationalPerson("2.5.6.7", "RFC 4519"), + /** */ + organizationalRole("2.5.6.8", "RFC 4519"), + /** */ + groupOfNames("2.5.6.9", "RFC 4519"), + /** */ + residentialPerson("2.5.6.10", "RFC 4519"), + /** */ + applicationProcess("2.5.6.11", "RFC 4519"), + /** */ + device("2.5.6.14", "RFC 4519"), + /** */ + strongAuthenticationUser("2.5.6.15", "RFC 4523"), + /** */ + certificationAuthority("2.5.6.16", "RFC 4523"), + // /** Should be certificationAuthority-V2 */ + // certificationAuthority_V2("2.5.6.16.2", "RFC 4523") { + // }, + /** */ + groupOfUniqueNames("2.5.6.17", "RFC 4519"), + /** */ + userSecurityInformation("2.5.6.18", "RFC 4523"), + /** */ + cRLDistributionPoint("2.5.6.19", "RFC 4523"), + /** */ + pkiUser("2.5.6.21", "RFC 4523"), + /** */ + pkiCA("2.5.6.22", "RFC 4523"), + /** */ + deltaCRL("2.5.6.23", "RFC 4523"), + /** */ + subschema("2.5.20.1", "RFC 4512"), + /** */ + ldapSubEntry("2.16.840.1.113719.2.142.6.1.1", "draft-ietf-ldup-subentry"), + /** */ + changeLogEntry("2.16.840.1.113730.3.2.1", "draft-good-ldap-changelog"), + /** */ + inetOrgPerson("2.16.840.1.113730.3.2.2", "RFC 2798"), + /** */ + referral("2.16.840.1.113730.3.2.6", "RFC 3296"); + + private final static String LDAP_ = "ldap:"; + private final String oid, spec; + + private LdapObjs(String oid, String spec) { + this.oid = oid; + this.spec = spec; + } + + public String getOid() { + return oid; + } + + public String getSpec() { + return spec; + } + + public String property() { + return new StringBuilder(LDAP_).append(name()).toString(); + } + +} diff --git a/org.argeo.util/src/org/argeo/util/naming/LdifParser.java b/org.argeo.util/src/org/argeo/util/naming/LdifParser.java new file mode 100644 index 000000000..d68173a2a --- /dev/null +++ b/org.argeo.util/src/org/argeo/util/naming/LdifParser.java @@ -0,0 +1,161 @@ +package org.argeo.util.naming; + +import java.io.BufferedReader; +import java.io.IOException; +import java.io.InputStream; +import java.io.InputStreamReader; +import java.io.Reader; +import java.nio.charset.Charset; +import java.nio.charset.StandardCharsets; +import java.util.ArrayList; +import java.util.Base64; +import java.util.List; +import java.util.SortedMap; +import java.util.TreeMap; + +import javax.naming.InvalidNameException; +import javax.naming.NamingException; +import javax.naming.directory.Attribute; +import javax.naming.directory.Attributes; +import javax.naming.directory.BasicAttribute; +import javax.naming.directory.BasicAttributes; +import javax.naming.ldap.LdapName; +import javax.naming.ldap.Rdn; + +import org.argeo.osgi.useradmin.UserDirectoryException; + +/** Basic LDIF parser. */ +public class LdifParser { + private final static Charset DEFAULT_CHARSET = StandardCharsets.UTF_8; + + protected Attributes addAttributes(SortedMap res, int lineNumber, LdapName currentDn, + Attributes currentAttributes) { + try { + Rdn nameRdn = currentDn.getRdn(currentDn.size() - 1); + Attribute nameAttr = currentAttributes.get(nameRdn.getType()); + if (nameAttr == null) + currentAttributes.put(nameRdn.getType(), nameRdn.getValue()); + else if (!nameAttr.get().equals(nameRdn.getValue())) + throw new UserDirectoryException( + "Attribute " + nameAttr.getID() + "=" + nameAttr.get() + " not consistent with DN " + currentDn + + " (shortly before line " + lineNumber + " in LDIF file)"); + Attributes previous = res.put(currentDn, currentAttributes); + return previous; + } catch (NamingException e) { + throw new UserDirectoryException("Cannot add " + currentDn, e); + } + } + + /** With UTF-8 charset */ + public SortedMap read(InputStream in) throws IOException { + try (Reader reader = new InputStreamReader(in, DEFAULT_CHARSET)) { + return read(reader); + } finally { + try { + in.close(); + } catch (IOException e) { + // silent + } + } + } + + /** Will close the reader. */ + public SortedMap read(Reader reader) throws IOException { + SortedMap res = new TreeMap(); + try { + List lines = new ArrayList<>(); + try (BufferedReader br = new BufferedReader(reader)) { + String line; + while ((line = br.readLine()) != null) { + lines.add(line); + } + } + if (lines.size() == 0) + return res; + // add an empty new line since the last line is not checked + if (!lines.get(lines.size() - 1).equals("")) + lines.add(""); + + LdapName currentDn = null; + Attributes currentAttributes = null; + StringBuilder currentEntry = new StringBuilder(); + + readLines: for (int lineNumber = 0; lineNumber < lines.size(); lineNumber++) { + String line = lines.get(lineNumber); + boolean isLastLine = false; + if (lineNumber == lines.size() - 1) + isLastLine = true; + if (line.startsWith(" ")) { + currentEntry.append(line.substring(1)); + if (!isLastLine) + continue readLines; + } + + if (currentEntry.length() != 0 || isLastLine) { + // read previous attribute + StringBuilder attrId = new StringBuilder(8); + boolean isBase64 = false; + readAttrId: for (int i = 0; i < currentEntry.length(); i++) { + char c = currentEntry.charAt(i); + if (c == ':') { + if (i + 1 < currentEntry.length() && currentEntry.charAt(i + 1) == ':') + isBase64 = true; + currentEntry.delete(0, i + (isBase64 ? 2 : 1)); + break readAttrId; + } else { + attrId.append(c); + } + } + + String attributeId = attrId.toString(); + // TODO should we really trim the end of the string as well? + String cleanValueStr = currentEntry.toString().trim(); + Object attributeValue = isBase64 ? Base64.getDecoder().decode(cleanValueStr) : cleanValueStr; + + // manage DN attributes + if (attributeId.equals(LdapAttrs.DN) || isLastLine) { + if (currentDn != null) { + // + // ADD + // + Attributes previous = addAttributes(res, lineNumber, currentDn, currentAttributes); + if (previous != null) { +// log.warn("There was already an entry with DN " + currentDn +// + ", which has been discarded by a subsequent one."); + } + } + + if (attributeId.equals(LdapAttrs.DN)) + try { + currentDn = new LdapName(attributeValue.toString()); + currentAttributes = new BasicAttributes(true); + } catch (InvalidNameException e) { +// log.error(attributeValue + " not a valid DN, skipping the entry."); + currentDn = null; + currentAttributes = null; + } + } + + // store attribute + if (currentAttributes != null) { + Attribute attribute = currentAttributes.get(attributeId); + if (attribute == null) { + attribute = new BasicAttribute(attributeId); + currentAttributes.put(attribute); + } + attribute.add(attributeValue); + } + currentEntry = new StringBuilder(); + } + currentEntry.append(line); + } + } finally { + try { + reader.close(); + } catch (IOException e) { + // silent + } + } + return res; + } +} \ No newline at end of file diff --git a/org.argeo.util/src/org/argeo/util/naming/LdifWriter.java b/org.argeo.util/src/org/argeo/util/naming/LdifWriter.java new file mode 100644 index 000000000..457380b9b --- /dev/null +++ b/org.argeo.util/src/org/argeo/util/naming/LdifWriter.java @@ -0,0 +1,106 @@ +package org.argeo.util.naming; + +import static org.argeo.util.naming.LdapAttrs.DN; +import static org.argeo.util.naming.LdapAttrs.member; +import static org.argeo.util.naming.LdapAttrs.objectClass; +import static org.argeo.util.naming.LdapAttrs.uniqueMember; + +import java.io.IOException; +import java.io.OutputStream; +import java.io.OutputStreamWriter; +import java.io.Writer; +import java.nio.charset.Charset; +import java.nio.charset.StandardCharsets; +import java.util.Base64; +import java.util.Map; +import java.util.SortedSet; +import java.util.TreeSet; + +import javax.naming.NamingEnumeration; +import javax.naming.NamingException; +import javax.naming.directory.Attribute; +import javax.naming.directory.Attributes; +import javax.naming.ldap.LdapName; +import javax.naming.ldap.Rdn; + +import org.argeo.osgi.useradmin.UserDirectoryException; + +/** Basic LDIF writer */ +public class LdifWriter { + private final static Charset DEFAULT_CHARSET = StandardCharsets.UTF_8; + private final Writer writer; + + /** Writer must be closed by caller */ + public LdifWriter(Writer writer) { + this.writer = writer; + } + + /** Stream must be closed by caller */ + public LdifWriter(OutputStream out) { + this(new OutputStreamWriter(out, DEFAULT_CHARSET)); + } + + public void writeEntry(LdapName name, Attributes attributes) throws IOException { + try { + // check consistency + Rdn nameRdn = name.getRdn(name.size() - 1); + Attribute nameAttr = attributes.get(nameRdn.getType()); + if (!nameAttr.get().equals(nameRdn.getValue())) + throw new UserDirectoryException( + "Attribute " + nameAttr.getID() + "=" + nameAttr.get() + " not consistent with DN " + name); + + writer.append(DN + ": ").append(name.toString()).append('\n'); + Attribute objectClassAttr = attributes.get(objectClass.name()); + if (objectClassAttr != null) + writeAttribute(objectClassAttr); + attributes: for (NamingEnumeration attrs = attributes.getAll(); attrs.hasMore();) { + Attribute attribute = attrs.next(); + if (attribute.getID().equals(DN) || attribute.getID().equals(objectClass.name())) + continue attributes;// skip DN attribute + if (attribute.getID().equals(member.name()) || attribute.getID().equals(uniqueMember.name())) + continue attributes;// skip member and uniqueMember attributes, so that they are always written last + writeAttribute(attribute); + } + // write member and uniqueMember attributes last + for (NamingEnumeration attrs = attributes.getAll(); attrs.hasMore();) { + Attribute attribute = attrs.next(); + if (attribute.getID().equals(member.name()) || attribute.getID().equals(uniqueMember.name())) + writeMemberAttribute(attribute); + } + writer.append('\n'); + writer.flush(); + } catch (NamingException e) { + throw new UserDirectoryException("Cannot write LDIF", e); + } + } + + public void write(Map entries) throws IOException { + for (LdapName dn : entries.keySet()) + writeEntry(dn, entries.get(dn)); + } + + protected void writeAttribute(Attribute attribute) throws NamingException, IOException { + for (NamingEnumeration attrValues = attribute.getAll(); attrValues.hasMore();) { + Object value = attrValues.next(); + if (value instanceof byte[]) { + String encoded = Base64.getEncoder().encodeToString((byte[]) value); + writer.append(attribute.getID()).append(":: ").append(encoded).append('\n'); + } else { + writer.append(attribute.getID()).append(": ").append(value.toString()).append('\n'); + } + } + } + + protected void writeMemberAttribute(Attribute attribute) throws NamingException, IOException { + // Note: duplicate entries will be swallowed + SortedSet values = new TreeSet<>(); + for (NamingEnumeration attrValues = attribute.getAll(); attrValues.hasMore();) { + String value = attrValues.next().toString(); + values.add(value); + } + + for (String value : values) { + writer.append(attribute.getID()).append(": ").append(value).append('\n'); + } + } +} diff --git a/org.argeo.util/src/org/argeo/util/naming/NamingUtils.java b/org.argeo.util/src/org/argeo/util/naming/NamingUtils.java new file mode 100644 index 000000000..ff4ed31b4 --- /dev/null +++ b/org.argeo.util/src/org/argeo/util/naming/NamingUtils.java @@ -0,0 +1,106 @@ +package org.argeo.util.naming; + +import java.io.UnsupportedEncodingException; +import java.net.URI; +import java.net.URLDecoder; +import java.nio.charset.StandardCharsets; +import java.time.Instant; +import java.time.OffsetDateTime; +import java.time.ZoneOffset; +import java.time.ZonedDateTime; +import java.time.format.DateTimeFormatter; +import java.time.format.DateTimeParseException; +import java.time.temporal.ChronoField; +import java.util.Calendar; +import java.util.GregorianCalendar; +import java.util.LinkedHashMap; +import java.util.LinkedList; +import java.util.List; +import java.util.Map; + +public class NamingUtils { + /** As per https://tools.ietf.org/html/rfc4517#section-3.3.13 */ + private final static DateTimeFormatter utcLdapDate = DateTimeFormatter.ofPattern("uuuuMMddHHmmssX") + .withZone(ZoneOffset.UTC); + + /** @return null if not parseable */ + public static Instant ldapDateToInstant(String ldapDate) { + try { + return OffsetDateTime.parse(ldapDate, utcLdapDate).toInstant(); + } catch (DateTimeParseException e) { + return null; + } + } + + /** @return null if not parseable */ + public static ZonedDateTime ldapDateToZonedDateTime(String ldapDate) { + try { + return OffsetDateTime.parse(ldapDate, utcLdapDate).toZonedDateTime(); + } catch (DateTimeParseException e) { + return null; + } + } + + public static Calendar ldapDateToCalendar(String ldapDate) { + OffsetDateTime instant = OffsetDateTime.parse(ldapDate, utcLdapDate); + GregorianCalendar calendar = new GregorianCalendar(); + calendar.set(Calendar.DAY_OF_MONTH, instant.get(ChronoField.DAY_OF_MONTH)); + calendar.set(Calendar.MONTH, instant.get(ChronoField.MONTH_OF_YEAR)); + calendar.set(Calendar.YEAR, instant.get(ChronoField.YEAR)); + return calendar; + } + + public static String instantToLdapDate(ZonedDateTime instant) { + return utcLdapDate.format(instant.withZoneSameInstant(ZoneOffset.UTC)); + } + + public static String getQueryValue(Map> query, String key) { + if (!query.containsKey(key)) + return null; + List val = query.get(key); + if (val.size() == 1) + return val.get(0); + else + throw new IllegalArgumentException("There are " + val.size() + " value(s) for " + key); + } + + public static Map> queryToMap(URI uri) { + return queryToMap(uri.getQuery()); + } + + private static Map> queryToMap(String queryPart) { + try { + final Map> query_pairs = new LinkedHashMap>(); + if (queryPart == null) + return query_pairs; + final String[] pairs = queryPart.split("&"); + for (String pair : pairs) { + final int idx = pair.indexOf("="); + final String key = idx > 0 ? URLDecoder.decode(pair.substring(0, idx), StandardCharsets.UTF_8.name()) + : pair; + if (!query_pairs.containsKey(key)) { + query_pairs.put(key, new LinkedList()); + } + final String value = idx > 0 && pair.length() > idx + 1 + ? URLDecoder.decode(pair.substring(idx + 1), StandardCharsets.UTF_8.name()) + : null; + query_pairs.get(key).add(value); + } + return query_pairs; + } catch (UnsupportedEncodingException e) { + throw new IllegalArgumentException("Cannot convert " + queryPart + " to map", e); + } + } + + private NamingUtils() { + + } + + public static void main(String args[]) { + ZonedDateTime now = ZonedDateTime.now().withZoneSameInstant(ZoneOffset.UTC); + String str = utcLdapDate.format(now); + System.out.println(str); + utcLdapDate.parse(str); + utcLdapDate.parse("19520512000000Z"); + } +} diff --git a/org.argeo.util/src/org/argeo/util/naming/NodeOID.java b/org.argeo.util/src/org/argeo/util/naming/NodeOID.java new file mode 100644 index 000000000..d72c31e9f --- /dev/null +++ b/org.argeo.util/src/org/argeo/util/naming/NodeOID.java @@ -0,0 +1,11 @@ +package org.argeo.util.naming; + +interface NodeOID { + String BASE = "1.3.6.1.4.1" + ".48308" + ".1"; + + // ATTRIBUTE TYPES + String ATTRIBUTE_TYPES = BASE + ".4"; + + // OBJECT CLASSES + String OBJECT_CLASSES = BASE + ".6"; +} diff --git a/org.argeo.util/src/org/argeo/util/naming/SharedSecret.java b/org.argeo.util/src/org/argeo/util/naming/SharedSecret.java new file mode 100644 index 000000000..7f0575407 --- /dev/null +++ b/org.argeo.util/src/org/argeo/util/naming/SharedSecret.java @@ -0,0 +1,46 @@ +package org.argeo.util.naming; + +import java.time.Instant; +import java.time.ZoneOffset; +import java.time.ZonedDateTime; + +public class SharedSecret extends AuthPassword { + public final static String X_SHARED_SECRET = "X-SharedSecret"; + private final Instant expiry; + + public SharedSecret(String authInfo, String authValue) { + super(authInfo, authValue); + expiry = null; + } + + public SharedSecret(AuthPassword authPassword) { + super(authPassword); + String authInfo = getAuthInfo(); + if (authInfo.length() == 16) { + expiry = NamingUtils.ldapDateToInstant(authInfo); + } else { + expiry = null; + } + } + + public SharedSecret(ZonedDateTime expiryTimestamp, String value) { + super(NamingUtils.instantToLdapDate(expiryTimestamp), value); + expiry = expiryTimestamp.withZoneSameInstant(ZoneOffset.UTC).toInstant(); + } + + public SharedSecret(int hours, String value) { + this(ZonedDateTime.now().plusHours(hours), value); + } + + @Override + protected String getExpectedAuthScheme() { + return X_SHARED_SECRET; + } + + public boolean isExpired() { + if (expiry == null) + return false; + return expiry.isBefore(Instant.now()); + } + +} diff --git a/org.argeo.util/src/org/argeo/util/naming/SpecifiedName.java b/org.argeo.util/src/org/argeo/util/naming/SpecifiedName.java new file mode 100644 index 000000000..22f2a2d69 --- /dev/null +++ b/org.argeo.util/src/org/argeo/util/naming/SpecifiedName.java @@ -0,0 +1,20 @@ +package org.argeo.util.naming; + +/** + * A name which has been specified and for which an id has been defined + * (typically an OID). + */ +public interface SpecifiedName { + /** The name */ + String name(); + + /** An RFC or the URLof some specification */ + default String getSpec() { + return null; + } + + /** Typically an OID */ + default String getID() { + return getClass().getName() + "." + name(); + } +} diff --git a/org.argeo.util/src/org/argeo/util/naming/SrvRecord.java b/org.argeo.util/src/org/argeo/util/naming/SrvRecord.java new file mode 100644 index 000000000..f2476a930 --- /dev/null +++ b/org.argeo.util/src/org/argeo/util/naming/SrvRecord.java @@ -0,0 +1,52 @@ +package org.argeo.util.naming; + +class SrvRecord implements Comparable { + private final Integer priority; + private final Integer weight; + private final Integer port; + private final String hostname; + + public SrvRecord(Integer priority, Integer weight, Integer port, String hostname) { + this.priority = priority; + this.weight = weight; + this.port = port; + this.hostname = hostname; + } + + @Override + public int compareTo(SrvRecord other) { + // https: // en.wikipedia.org/wiki/SRV_record + if (priority != other.priority) + return priority - other.priority; + if (weight != other.weight) + return other.weight - other.weight; + String host = toHost(false); + String otherHost = other.toHost(false); + if (host.length() == otherHost.length()) + return host.compareTo(otherHost); + else + return host.length() - otherHost.length(); + } + + @Override + public boolean equals(Object obj) { + if (obj instanceof SrvRecord) { + SrvRecord other = (SrvRecord) obj; + return priority == other.priority && weight == other.weight && port == other.port + && hostname.equals(other.hostname); + } + return false; + } + + @Override + public String toString() { + return priority + " " + weight; + } + + public String toHost(boolean withPort) { + String hostStr = hostname; + if (hostname.charAt(hostname.length() - 1) == '.') + hostStr = hostname.substring(0, hostname.length() - 1); + return hostStr + (withPort ? ":" + port : ""); + } +} diff --git a/org.argeo.util/src/org/argeo/util/naming/package-info.java b/org.argeo.util/src/org/argeo/util/naming/package-info.java new file mode 100644 index 000000000..f62af365e --- /dev/null +++ b/org.argeo.util/src/org/argeo/util/naming/package-info.java @@ -0,0 +1,2 @@ +/** Generic naming and LDAP support. */ +package org.argeo.util.naming; \ No newline at end of file diff --git a/rap/org.argeo.cms.e4.rap/bnd.bnd b/rap/org.argeo.cms.e4.rap/bnd.bnd index 90dc8d42b..5bbe4bc4b 100644 --- a/rap/org.argeo.cms.e4.rap/bnd.bnd +++ b/rap/org.argeo.cms.e4.rap/bnd.bnd @@ -1,8 +1,7 @@ Bundle-ActivationPolicy: lazy Service-Component: OSGI-INF/cms-admin-rap.xml -Import-Package: org.argeo.api,\ -org.eclipse.swt,\ +Import-Package: org.eclipse.swt,\ org.eclipse.swt.graphics,\ org.eclipse.e4.ui.workbench,\ org.eclipse.rap.rwt.client,\ diff --git a/rap/org.argeo.cms.e4.rap/src/org/argeo/cms/e4/rap/CmsLoginLifecycle.java b/rap/org.argeo.cms.e4.rap/src/org/argeo/cms/e4/rap/CmsLoginLifecycle.java index 3ee8df1ef..ac9ab1dbe 100644 --- a/rap/org.argeo.cms.e4.rap/src/org/argeo/cms/e4/rap/CmsLoginLifecycle.java +++ b/rap/org.argeo.cms.e4.rap/src/org/argeo/cms/e4/rap/CmsLoginLifecycle.java @@ -7,11 +7,10 @@ import javax.security.auth.Subject; import javax.security.auth.login.LoginContext; import javax.security.auth.login.LoginException; -import org.apache.commons.logging.Log; -import org.apache.commons.logging.LogFactory; -import org.argeo.api.NodeConstants; +import org.argeo.api.cms.CmsAuth; import org.argeo.api.cms.CmsImageManager; import org.argeo.api.cms.CmsView; +import org.argeo.api.cms.CmsLog; import org.argeo.api.cms.UxContext; import org.argeo.cms.auth.CurrentUser; import org.argeo.cms.swt.CmsSwtUtils; @@ -33,7 +32,7 @@ import org.osgi.service.event.EventHandler; @SuppressWarnings("restriction") public class CmsLoginLifecycle implements CmsView { - private final static Log log = LogFactory.getLog(CmsLoginLifecycle.class); + private final static CmsLog log = CmsLog.getLog(CmsLoginLifecycle.class); private UxContext uxContext; private CmsImageManager imageManager; @@ -68,7 +67,7 @@ public class CmsLoginLifecycle implements CmsView { loginShell.setSubject(subject); try { // try pre-auth - loginContext = new LoginContext(NodeConstants.LOGIN_CONTEXT_USER, subject, loginShell); + loginContext = new LoginContext(CmsAuth.LOGIN_CONTEXT_USER, subject, loginShell); loginContext.login(); } catch (LoginException e) { loginShell.createUi(); diff --git a/rap/org.argeo.cms.e4.rap/src/org/argeo/cms/e4/rap/SimpleRapE4App.java b/rap/org.argeo.cms.e4.rap/src/org/argeo/cms/e4/rap/SimpleRapE4App.java index 12c4f6336..1bca333c9 100644 --- a/rap/org.argeo.cms.e4.rap/src/org/argeo/cms/e4/rap/SimpleRapE4App.java +++ b/rap/org.argeo.cms.e4.rap/src/org/argeo/cms/e4/rap/SimpleRapE4App.java @@ -3,14 +3,13 @@ package org.argeo.cms.e4.rap; import java.util.Enumeration; import org.apache.commons.io.FilenameUtils; -import org.apache.commons.logging.Log; -import org.apache.commons.logging.LogFactory; +import org.argeo.api.cms.CmsLog; import org.eclipse.rap.rwt.application.Application; import org.osgi.framework.Bundle; /** Simple RAP app which loads all e4xmi files. */ public class SimpleRapE4App extends AbstractRapE4App { - private final static Log log = LogFactory.getLog(SimpleRapE4App.class); + private final static CmsLog log = CmsLog.getLog(SimpleRapE4App.class); private String baseE4xmi = "/e4xmi"; diff --git a/rap/org.argeo.cms.ui.rap/bnd.bnd b/rap/org.argeo.cms.ui.rap/bnd.bnd index 30b21b019..5b0b8b9f6 100644 --- a/rap/org.argeo.cms.ui.rap/bnd.bnd +++ b/rap/org.argeo.cms.ui.rap/bnd.bnd @@ -1,6 +1,5 @@ Import-Package:\ org.eclipse.swt,\ -org.argeo.api,\ org.argeo.eclipse.ui,\ javax.jcr.nodetype,\ javax.jcr.security,\ diff --git a/rap/org.argeo.cms.ui.rap/src/org/argeo/cms/ui/script/AppUi.java b/rap/org.argeo.cms.ui.rap/src/org/argeo/cms/ui/script/AppUi.java index 30cff8f81..01ebb237e 100644 --- a/rap/org.argeo.cms.ui.rap/src/org/argeo/cms/ui/script/AppUi.java +++ b/rap/org.argeo.cms.ui.rap/src/org/argeo/cms/ui/script/AppUi.java @@ -9,7 +9,7 @@ import javax.jcr.RepositoryException; import javax.script.Invocable; import javax.script.ScriptException; -import org.argeo.api.NodeConstants; +import org.argeo.api.cms.CmsConstants; import org.argeo.cms.swt.CmsSwtUtils; import org.argeo.cms.swt.Selected; import org.argeo.cms.ui.CmsUiProvider; @@ -79,7 +79,7 @@ public class AppUi implements CmsUiProvider, Branding { EntryPointFactory entryPointFactory = new EntryPointFactory() { @Override public EntryPoint create() { - SimpleErgonomics ergonomics = new SimpleErgonomics(repository, NodeConstants.SYS_WORKSPACE, + SimpleErgonomics ergonomics = new SimpleErgonomics(repository, CmsConstants.SYS_WORKSPACE, "/home/root/argeo:keyring", AppUi.this, factoryProperties); // CmsUiProvider header = app.getHeader(); // if (header != null) diff --git a/rap/org.argeo.cms.ui.rap/src/org/argeo/cms/ui/script/CmsScriptApp.java b/rap/org.argeo.cms.ui.rap/src/org/argeo/cms/ui/script/CmsScriptApp.java index 9dd1509be..edf558e9c 100644 --- a/rap/org.argeo.cms.ui.rap/src/org/argeo/cms/ui/script/CmsScriptApp.java +++ b/rap/org.argeo.cms.ui.rap/src/org/argeo/cms/ui/script/CmsScriptApp.java @@ -20,11 +20,10 @@ import javax.script.ScriptEngine; import javax.servlet.http.HttpServletRequest; import javax.servlet.http.HttpServletResponse; -import org.apache.commons.logging.Log; -import org.apache.commons.logging.LogFactory; import org.argeo.api.cms.CmsTheme; +import org.argeo.api.cms.CmsLog; import org.argeo.cms.CmsException; -import org.argeo.cms.ui.CmsConstants; +import org.argeo.cms.ui.CmsUiConstants; import org.argeo.cms.ui.CmsUiProvider; import org.argeo.cms.ui.util.CmsUiUtils; import org.argeo.cms.web.BundleResourceLoader; @@ -50,7 +49,7 @@ public class CmsScriptApp implements Branding { private ScriptEngine scriptEngine; - private final static Log log = LogFactory.getLog(CmsScriptApp.class); + private final static CmsLog log = CmsLog.getLog(CmsScriptApp.class); private String webPath; private String repo = "(cn=node)"; @@ -90,9 +89,9 @@ public class CmsScriptApp implements Branding { application.setExceptionHandler(new CmsExceptionHandler()); // loading animated gif - application.addResource(CmsConstants.LOADING_IMAGE, createResourceLoader(CmsConstants.LOADING_IMAGE)); + application.addResource(CmsUiConstants.LOADING_IMAGE, createResourceLoader(CmsUiConstants.LOADING_IMAGE)); // empty image - application.addResource(CmsConstants.NO_IMAGE, createResourceLoader(CmsConstants.NO_IMAGE)); + application.addResource(CmsUiConstants.NO_IMAGE, createResourceLoader(CmsUiConstants.NO_IMAGE)); for (String resource : resources) { application.addResource(resource, bundleRL); diff --git a/rap/org.argeo.cms.ui.rap/src/org/argeo/cms/ui/script/CmsScriptRwtApplication.java b/rap/org.argeo.cms.ui.rap/src/org/argeo/cms/ui/script/CmsScriptRwtApplication.java index d7c1a63ce..499840a73 100644 --- a/rap/org.argeo.cms.ui.rap/src/org/argeo/cms/ui/script/CmsScriptRwtApplication.java +++ b/rap/org.argeo.cms.ui.rap/src/org/argeo/cms/ui/script/CmsScriptRwtApplication.java @@ -10,8 +10,7 @@ import javax.script.ScriptEngine; import javax.script.ScriptEngineManager; import javax.script.ScriptException; -import org.apache.commons.logging.Log; -import org.apache.commons.logging.LogFactory; +import org.argeo.api.cms.CmsLog; import org.argeo.cms.CmsException; import org.eclipse.rap.rwt.application.Application; import org.eclipse.rap.rwt.application.ApplicationConfiguration; @@ -23,7 +22,7 @@ public class CmsScriptRwtApplication implements ApplicationConfiguration { public final static String APP = "APP"; public final static String BC = "BC"; - private final Log log = LogFactory.getLog(CmsScriptRwtApplication.class); + private final CmsLog log = CmsLog.getLog(CmsScriptRwtApplication.class); BundleContext bundleContext; Repository repository; diff --git a/rap/org.argeo.cms.ui.rap/src/org/argeo/cms/ui/script/ScriptAppActivator.java b/rap/org.argeo.cms.ui.rap/src/org/argeo/cms/ui/script/ScriptAppActivator.java index 7813156ec..a55095371 100644 --- a/rap/org.argeo.cms.ui.rap/src/org/argeo/cms/ui/script/ScriptAppActivator.java +++ b/rap/org.argeo.cms.ui.rap/src/org/argeo/cms/ui/script/ScriptAppActivator.java @@ -2,8 +2,7 @@ package org.argeo.cms.ui.script; import javax.jcr.Repository; -import org.apache.commons.logging.Log; -import org.apache.commons.logging.LogFactory; +import org.argeo.api.cms.CmsLog; import org.osgi.framework.BundleActivator; import org.osgi.framework.BundleContext; import org.osgi.framework.FrameworkUtil; @@ -11,7 +10,7 @@ import org.osgi.framework.ServiceReference; import org.osgi.util.tracker.ServiceTracker; public class ScriptAppActivator implements BundleActivator { - private final static Log log = LogFactory.getLog(ScriptAppActivator.class); + private final static CmsLog log = CmsLog.getLog(ScriptAppActivator.class); @Override public void start(BundleContext context) throws Exception { diff --git a/rap/org.argeo.cms.ui.rap/src/org/argeo/cms/ui/script/ScriptUi.java b/rap/org.argeo.cms.ui.rap/src/org/argeo/cms/ui/script/ScriptUi.java index bf68fc299..0c870e1e8 100644 --- a/rap/org.argeo.cms.ui.rap/src/org/argeo/cms/ui/script/ScriptUi.java +++ b/rap/org.argeo.cms.ui.rap/src/org/argeo/cms/ui/script/ScriptUi.java @@ -8,15 +8,14 @@ import javax.script.Invocable; import javax.script.ScriptEngine; import javax.script.ScriptException; -import org.apache.commons.logging.Log; -import org.apache.commons.logging.LogFactory; +import org.argeo.api.cms.CmsLog; import org.argeo.cms.ui.CmsUiProvider; import org.eclipse.swt.widgets.Composite; import org.eclipse.swt.widgets.Control; import org.osgi.framework.BundleContext; class ScriptUi implements CmsUiProvider { - private final static Log log = LogFactory.getLog(ScriptUi.class); + private final static CmsLog log = CmsLog.getLog(ScriptUi.class); private boolean development = true; private ScriptEngine scriptEngine; diff --git a/rap/org.argeo.cms.ui.rap/src/org/argeo/cms/web/AbstractCmsEntryPoint.java b/rap/org.argeo.cms.ui.rap/src/org/argeo/cms/web/AbstractCmsEntryPoint.java index 7b7bddc5c..947a4d11a 100644 --- a/rap/org.argeo.cms.ui.rap/src/org/argeo/cms/web/AbstractCmsEntryPoint.java +++ b/rap/org.argeo.cms.ui.rap/src/org/argeo/cms/web/AbstractCmsEntryPoint.java @@ -1,6 +1,6 @@ package org.argeo.cms.web; -import static org.argeo.naming.SharedSecret.X_SHARED_SECRET; +import static org.argeo.util.naming.SharedSecret.X_SHARED_SECRET; import java.io.IOException; import java.security.PrivilegedAction; @@ -21,10 +21,9 @@ import javax.security.auth.login.LoginContext; import javax.security.auth.login.LoginException; import javax.servlet.http.HttpServletRequest; -import org.apache.commons.logging.Log; -import org.apache.commons.logging.LogFactory; -import org.argeo.api.NodeConstants; import org.argeo.api.cms.CmsView; +import org.argeo.api.cms.CmsLog; +import org.argeo.api.cms.CmsAuth; import org.argeo.cms.CmsException; import org.argeo.cms.auth.CurrentUser; import org.argeo.cms.auth.RemoteAuthCallback; @@ -35,8 +34,8 @@ import org.argeo.cms.swt.CmsStyles; import org.argeo.cms.swt.CmsSwtUtils; import org.argeo.eclipse.ui.specific.UiContext; import org.argeo.jcr.JcrUtils; -import org.argeo.naming.AuthPassword; -import org.argeo.naming.SharedSecret; +import org.argeo.util.naming.AuthPassword; +import org.argeo.util.naming.SharedSecret; import org.eclipse.rap.rwt.RWT; import org.eclipse.rap.rwt.application.AbstractEntryPoint; import org.eclipse.rap.rwt.client.WebClient; @@ -53,7 +52,7 @@ import org.eclipse.swt.widgets.Shell; public abstract class AbstractCmsEntryPoint extends AbstractEntryPoint implements CmsView { private static final long serialVersionUID = 906558779562569784L; - private final Log log = LogFactory.getLog(AbstractCmsEntryPoint.class); + private final CmsLog log = CmsLog.getLog(AbstractCmsEntryPoint.class); // private final Subject subject; private LoginContext loginContext; @@ -85,13 +84,13 @@ public abstract class AbstractCmsEntryPoint extends AbstractEntryPoint implement // Initial login LoginContext lc; try { - lc = new LoginContext(NodeConstants.LOGIN_CONTEXT_USER, + lc = new LoginContext(CmsAuth.LOGIN_CONTEXT_USER, new RemoteAuthCallbackHandler(new ServletHttpRequest(UiContext.getHttpRequest()), new ServletHttpResponse(UiContext.getHttpResponse()))); lc.login(); } catch (LoginException e) { try { - lc = new LoginContext(NodeConstants.LOGIN_CONTEXT_ANONYMOUS); + lc = new LoginContext(CmsAuth.LOGIN_CONTEXT_ANONYMOUS); lc.login(); } catch (LoginException e1) { throw new CmsException("Cannot log in as anonymous", e1); @@ -197,7 +196,7 @@ public abstract class AbstractCmsEntryPoint extends AbstractEntryPoint implement try { CurrentUser.logoutCmsSession(loginContext.getSubject()); loginContext.logout(); - LoginContext anonymousLc = new LoginContext(NodeConstants.LOGIN_CONTEXT_ANONYMOUS); + LoginContext anonymousLc = new LoginContext(CmsAuth.LOGIN_CONTEXT_ANONYMOUS); anonymousLc.login(); authChange(anonymousLc); } catch (LoginException e) { @@ -302,7 +301,7 @@ public abstract class AbstractCmsEntryPoint extends AbstractEntryPoint implement } } }; - LoginContext lc = new LoginContext(NodeConstants.LOGIN_CONTEXT_USER, token); + LoginContext lc = new LoginContext(CmsAuth.LOGIN_CONTEXT_USER, token); lc.login(); authChange(lc);// sets the node as well // } else { diff --git a/rap/org.argeo.cms.ui.rap/src/org/argeo/cms/web/CmsWebApp.java b/rap/org.argeo.cms.ui.rap/src/org/argeo/cms/web/CmsWebApp.java index e5b6c7efc..4008b49eb 100644 --- a/rap/org.argeo.cms.ui.rap/src/org/argeo/cms/web/CmsWebApp.java +++ b/rap/org.argeo.cms.ui.rap/src/org/argeo/cms/web/CmsWebApp.java @@ -5,12 +5,11 @@ import java.util.HashMap; import java.util.Map; import java.util.Set; -import org.apache.commons.logging.Log; -import org.apache.commons.logging.LogFactory; import org.argeo.api.cms.CmsApp; import org.argeo.api.cms.CmsAppListener; import org.argeo.api.cms.CmsTheme; import org.argeo.api.cms.CmsView; +import org.argeo.api.cms.CmsLog; import org.argeo.cms.swt.CmsSwtUtils; import org.argeo.util.LangUtils; import org.eclipse.rap.rwt.RWT; @@ -27,7 +26,7 @@ import org.osgi.service.event.EventAdmin; /** An RWT web app integrating with a {@link CmsApp}. */ public class CmsWebApp implements ApplicationConfiguration, ExceptionHandler, CmsAppListener { - private final static Log log = LogFactory.getLog(CmsWebApp.class); + private final static CmsLog log = CmsLog.getLog(CmsWebApp.class); private BundleContext bundleContext; private CmsApp cmsApp; diff --git a/rap/org.argeo.cms.ui.rap/src/org/argeo/cms/web/CmsWebEntryPoint.java b/rap/org.argeo.cms.ui.rap/src/org/argeo/cms/web/CmsWebEntryPoint.java index b0d1e842d..afc07c5b0 100644 --- a/rap/org.argeo.cms.ui.rap/src/org/argeo/cms/web/CmsWebEntryPoint.java +++ b/rap/org.argeo.cms.ui.rap/src/org/argeo/cms/web/CmsWebEntryPoint.java @@ -12,14 +12,13 @@ import javax.security.auth.Subject; import javax.security.auth.login.LoginContext; import javax.security.auth.login.LoginException; -import org.apache.commons.logging.Log; -import org.apache.commons.logging.LogFactory; -import org.argeo.api.NodeConstants; import org.argeo.api.cms.CmsApp; +import org.argeo.api.cms.CmsAuth; import org.argeo.api.cms.CmsImageManager; import org.argeo.api.cms.CmsSession; import org.argeo.api.cms.CmsUi; import org.argeo.api.cms.CmsView; +import org.argeo.api.cms.CmsLog; import org.argeo.api.cms.UxContext; import org.argeo.cms.LocaleUtils; import org.argeo.cms.auth.CurrentUser; @@ -50,7 +49,7 @@ import org.osgi.service.event.EventAdmin; @SuppressWarnings("restriction") public class CmsWebEntryPoint implements EntryPoint, CmsView, BrowserNavigationListener { private static final long serialVersionUID = 7733510691684570402L; - private final static Log log = LogFactory.getLog(CmsWebEntryPoint.class); + private final static CmsLog log = CmsLog.getLog(CmsWebEntryPoint.class); private EventAdmin eventAdmin; @@ -85,13 +84,13 @@ public class CmsWebEntryPoint implements EntryPoint, CmsView, BrowserNavigationL // Initial login LoginContext lc; try { - lc = new LoginContext(NodeConstants.LOGIN_CONTEXT_USER, + lc = new LoginContext(CmsAuth.LOGIN_CONTEXT_USER, new RemoteAuthCallbackHandler(new ServletHttpRequest(UiContext.getHttpRequest()), new ServletHttpResponse(UiContext.getHttpResponse()))); lc.login(); } catch (LoginException e) { try { - lc = new LoginContext(NodeConstants.LOGIN_CONTEXT_ANONYMOUS); + lc = new LoginContext(CmsAuth.LOGIN_CONTEXT_ANONYMOUS); lc.login(); } catch (LoginException e1) { throw new IllegalStateException("Cannot log in as anonymous", e1); @@ -156,7 +155,7 @@ public class CmsWebEntryPoint implements EntryPoint, CmsView, BrowserNavigationL try { CurrentUser.logoutCmsSession(loginContext.getSubject()); loginContext.logout(); - LoginContext anonymousLc = new LoginContext(NodeConstants.LOGIN_CONTEXT_ANONYMOUS); + LoginContext anonymousLc = new LoginContext(CmsAuth.LOGIN_CONTEXT_ANONYMOUS); anonymousLc.login(); authChange(anonymousLc); } catch (LoginException e) { diff --git a/rap/org.argeo.cms.ui.rap/src/org/argeo/cms/web/SimpleApp.java b/rap/org.argeo.cms.ui.rap/src/org/argeo/cms/web/SimpleApp.java index 4cd6874d0..f063117ae 100644 --- a/rap/org.argeo.cms.ui.rap/src/org/argeo/cms/web/SimpleApp.java +++ b/rap/org.argeo.cms.ui.rap/src/org/argeo/cms/web/SimpleApp.java @@ -20,12 +20,11 @@ import javax.jcr.Session; import javax.jcr.security.Privilege; import javax.jcr.version.VersionManager; -import org.apache.commons.logging.Log; -import org.apache.commons.logging.LogFactory; -import org.argeo.api.NodeConstants; +import org.argeo.api.cms.CmsConstants; +import org.argeo.api.cms.CmsLog; import org.argeo.cms.CmsException; import org.argeo.cms.jcr.CmsJcrUtils; -import org.argeo.cms.ui.CmsConstants; +import org.argeo.cms.ui.CmsUiConstants; import org.argeo.cms.ui.CmsUiProvider; import org.argeo.cms.ui.LifeCycleUiProvider; import org.argeo.cms.ui.util.CmsUiUtils; @@ -53,8 +52,8 @@ import org.osgi.framework.ServiceRegistration; /** A basic generic app based on {@link SimpleErgonomics}. */ @Deprecated -public class SimpleApp implements CmsConstants, ApplicationConfiguration { - private final static Log log = LogFactory.getLog(SimpleApp.class); +public class SimpleApp implements CmsUiConstants, ApplicationConfiguration { + private final static CmsLog log = CmsLog.getLog(SimpleApp.class); private String contextName = null; @@ -68,8 +67,8 @@ public class SimpleApp implements CmsConstants, ApplicationConfiguration { private Repository repository; private String workspace = null; private String jcrBasePath = "/"; - private List roPrincipals = Arrays.asList(NodeConstants.ROLE_ANONYMOUS, NodeConstants.ROLE_USER); - private List rwPrincipals = Arrays.asList(NodeConstants.ROLE_USER); + private List roPrincipals = Arrays.asList(CmsConstants.ROLE_ANONYMOUS, CmsConstants.ROLE_USER); + private List rwPrincipals = Arrays.asList(CmsConstants.ROLE_USER); private CmsUiProvider header; private Map pages = new LinkedHashMap(); diff --git a/rap/org.argeo.cms.ui.rap/src/org/argeo/cms/web/SimpleErgonomics.java b/rap/org.argeo.cms.ui.rap/src/org/argeo/cms/web/SimpleErgonomics.java index 6e1165cf3..26ca3705f 100644 --- a/rap/org.argeo.cms.ui.rap/src/org/argeo/cms/web/SimpleErgonomics.java +++ b/rap/org.argeo.cms.ui.rap/src/org/argeo/cms/web/SimpleErgonomics.java @@ -7,9 +7,8 @@ import javax.jcr.Node; import javax.jcr.Repository; import javax.jcr.RepositoryException; -import org.apache.commons.logging.Log; -import org.apache.commons.logging.LogFactory; import org.argeo.api.cms.CmsImageManager; +import org.argeo.api.cms.CmsLog; import org.argeo.api.cms.UxContext; import org.argeo.cms.CmsException; import org.argeo.cms.swt.CmsStyles; @@ -31,7 +30,7 @@ import org.eclipse.swt.widgets.Control; public class SimpleErgonomics extends AbstractCmsEntryPoint { private static final long serialVersionUID = 8743413921359548523L; - private final static Log log = LogFactory.getLog(SimpleErgonomics.class); + private final static CmsLog log = CmsLog.getLog(SimpleErgonomics.class); private boolean uiInitialized = false; private Composite headerArea; diff --git a/rap/org.argeo.cms.ui.rap/src/org/argeo/cms/web/WebThemeUtils.java b/rap/org.argeo.cms.ui.rap/src/org/argeo/cms/web/WebThemeUtils.java index a28b13fc6..ea2ebdfb4 100644 --- a/rap/org.argeo.cms.ui.rap/src/org/argeo/cms/web/WebThemeUtils.java +++ b/rap/org.argeo.cms.ui.rap/src/org/argeo/cms/web/WebThemeUtils.java @@ -1,14 +1,13 @@ package org.argeo.cms.web; -import org.apache.commons.logging.Log; -import org.apache.commons.logging.LogFactory; import org.argeo.api.cms.CmsTheme; +import org.argeo.api.cms.CmsLog; import org.eclipse.rap.rwt.application.Application; import org.eclipse.rap.rwt.service.ResourceLoader; /** Web specific utilities around theming. */ public class WebThemeUtils { - private final static Log log = LogFactory.getLog(WebThemeUtils.class); + private final static CmsLog log = CmsLog.getLog(WebThemeUtils.class); public static void apply(Application application, CmsTheme theme) { ResourceLoader resourceLoader = new CmsThemeResourceLoader(theme); diff --git a/rcp/org.argeo.cms.e4.rcp/bnd.bnd b/rcp/org.argeo.cms.e4.rcp/bnd.bnd index dca5b9189..ff79c8041 100644 --- a/rcp/org.argeo.cms.e4.rcp/bnd.bnd +++ b/rcp/org.argeo.cms.e4.rcp/bnd.bnd @@ -2,7 +2,6 @@ Bundle-SymbolicName: org.argeo.cms.e4.rcp;singleton=true Require-Bundle: org.eclipse.core.runtime -Import-Package: org.argeo.api,\ -!org.eclipse.core.runtime,\ +Import-Package: !org.eclipse.core.runtime,\ org.eclipse.swt,\ * diff --git a/rcp/org.argeo.cms.e4.rcp/src/org/argeo/cms/e4/rcp/CmsE4Application.java b/rcp/org.argeo.cms.e4.rcp/src/org/argeo/cms/e4/rcp/CmsE4Application.java index 9cf4c8c6b..5cc6a8394 100644 --- a/rcp/org.argeo.cms.e4.rcp/src/org/argeo/cms/e4/rcp/CmsE4Application.java +++ b/rcp/org.argeo.cms.e4.rcp/src/org/argeo/cms/e4/rcp/CmsE4Application.java @@ -7,7 +7,7 @@ import javax.security.auth.Subject; import javax.security.auth.login.LoginContext; import javax.security.auth.login.LoginException; -import org.argeo.api.NodeConstants; +import org.argeo.api.cms.CmsAuth; import org.argeo.api.cms.CmsImageManager; import org.argeo.api.cms.CmsView; import org.argeo.api.cms.UxContext; @@ -39,7 +39,7 @@ public class CmsE4Application implements IApplication, CmsView { loginShell.setSubject(subject); try { // try pre-auth - loginContext = new LoginContext(NodeConstants.LOGIN_CONTEXT_USER, subject, loginShell); + loginContext = new LoginContext(CmsAuth.LOGIN_CONTEXT_USER, subject, loginShell); loginContext.login(); } catch (LoginException e) { e.printStackTrace(); diff --git a/rcp/org.argeo.cms.ui.rcp/bnd.bnd b/rcp/org.argeo.cms.ui.rcp/bnd.bnd index c3704d8bf..72b00d2cd 100644 --- a/rcp/org.argeo.cms.ui.rcp/bnd.bnd +++ b/rcp/org.argeo.cms.ui.rcp/bnd.bnd @@ -2,7 +2,6 @@ Service-Component: OSGI-INF/cmsRcpApp.xml Import-Package:\ -org.argeo.api,\ org.argeo.cms.auth,\ org.eclipse.swt,\ org.eclipse.swt.graphics,\ diff --git a/rcp/org.argeo.cms.ui.rcp/src/org/argeo/cms/ui/rcp/CmsRcpApp.java b/rcp/org.argeo.cms.ui.rcp/src/org/argeo/cms/ui/rcp/CmsRcpApp.java index c2f3d65a6..8614d70b5 100644 --- a/rcp/org.argeo.cms.ui.rcp/src/org/argeo/cms/ui/rcp/CmsRcpApp.java +++ b/rcp/org.argeo.cms.ui.rcp/src/org/argeo/cms/ui/rcp/CmsRcpApp.java @@ -11,15 +11,14 @@ import javax.security.auth.Subject; import javax.security.auth.login.LoginContext; import javax.security.auth.login.LoginException; -import org.apache.commons.logging.Log; -import org.apache.commons.logging.LogFactory; -import org.argeo.api.NodeConstants; import org.argeo.api.cms.CmsApp; +import org.argeo.api.cms.CmsAuth; import org.argeo.api.cms.CmsImageManager; import org.argeo.api.cms.CmsSession; import org.argeo.api.cms.CmsTheme; import org.argeo.api.cms.CmsUi; import org.argeo.api.cms.CmsView; +import org.argeo.api.cms.CmsLog; import org.argeo.api.cms.UxContext; import org.argeo.cms.osgi.CmsOsgiUtils; import org.argeo.cms.swt.CmsSwtUtils; @@ -38,7 +37,7 @@ import org.osgi.service.event.EventAdmin; /** Runs a {@link CmsApp} as an SWT desktop application. */ @SuppressWarnings("restriction") public class CmsRcpApp implements CmsView { - private final static Log log = LogFactory.getLog(CmsRcpApp.class); + private final static CmsLog log = CmsLog.getLog(CmsRcpApp.class); private BundleContext bundleContext = FrameworkUtil.getBundle(CmsRcpApp.class).getBundleContext(); @@ -107,7 +106,7 @@ public class CmsRcpApp implements CmsView { try { // try pre-auth // loginContext = new LoginContext(NodeConstants.LOGIN_CONTEXT_USER, subject, loginShell); - loginContext = new LoginContext(NodeConstants.LOGIN_CONTEXT_SINGLE_USER); + loginContext = new LoginContext(CmsAuth.LOGIN_CONTEXT_SINGLE_USER); loginContext.login(); } catch (LoginException e) { throw new IllegalStateException("Could not log in.", e); @@ -129,7 +128,7 @@ public class CmsRcpApp implements CmsView { ui = cmsApp.initUi(parent); if (ui instanceof Composite) ((Composite) ui).setLayoutData(CmsSwtUtils.fillAll()); - //ui.setLayoutData(CmsUiUtils.fillAll()); + // ui.setLayoutData(CmsUiUtils.fillAll()); // we need ui to be set before refresh so that CmsView can store UI context data // in it. cmsApp.refreshUi(ui, null);