mirror of
https://github.com/Alfresco/alfresco-community-repo.git
synced 2025-08-07 17:49:17 +00:00
Merged DAVEW_V3.2 to HEAD
13659: Fix NTLMAuthenticationFilter to call super.afterPropertiesSet() 13658: MOB-424: Utility to Dump JMX Data - new enterprise distributable jmx-dumper.jar - command line invocation via "java -jar jmx-dumper.jar" - admin web access via http://localhost:8080/alfresco/faces/jsp/admin/jmx-dumper.jsp 13575: Preconfigured authentication stacks for alfresco, LDAP, Kerberos and NTLM. TODO: file server config. 13493: Initial work to enable selection, configuration, testing and hot-swapping of different authentication subsystems via JMX or admin UI. 13309: Changes to allow datasource and property configuration via JNDI - Move AVM catalina .jars into 3rd-party/lib/virtual-tomcat so that they don't get automatically included in the .war file and hence stop JNDI lookups from working - Allow JNDI lookup of datasource – use standard app server mechanisms for managing it but still fall back to 'normal' one - Allow properties to be overridden by JNDI env-entries as well as system properties. Including hibernate dialect ones. Web.xml can then declare required env-entries and these can be defined on deployment. - Rewire iBatis so that no config file edits are necessary when dialect is changed - Use proxy around datasource so that auto-commit is always activated for iBatis git-svn-id: https://svn.alfresco.com/repos/alfresco-enterprise/alfresco/HEAD/root@13668 c4b6b30b-aa2e-2d43-bbcb-ca4b014f7261
This commit is contained in:
@@ -5,7 +5,7 @@
|
||||
"http://ibatis.apache.org/dtd/sql-map-config-2.dtd">
|
||||
|
||||
<sqlMapConfig>
|
||||
<!-- note: dialect property is provided by SqlMapClientFactoryBean -->
|
||||
<!-- note: dialect property must be set in properties passed to SqlMapClientFactoryBean -->
|
||||
<sqlMap resource="alfresco/activities/${hibernate.dialect}/ActivityPost.xml"/>
|
||||
<sqlMap resource="alfresco/activities/${hibernate.dialect}/ActivityFeed.xml"/>
|
||||
<sqlMap resource="alfresco/activities/${hibernate.dialect}/ActivityFeedControl.xml"/>
|
||||
|
@@ -14,15 +14,32 @@
|
||||
<property name="maxFeedItems" value="100"/>
|
||||
</bean>
|
||||
|
||||
<bean id="iBatisDataSource" parent="dataSource">
|
||||
<property name="defaultAutoCommit" >
|
||||
<value>true</value>
|
||||
<bean id="iBatisDataSource" class="org.springframework.aop.framework.ProxyFactoryBean">
|
||||
<property name="proxyInterfaces">
|
||||
<value>javax.sql.DataSource</value>
|
||||
</property>
|
||||
<property name="target"><ref bean="dataSource"/></property>
|
||||
<property name="interceptorNames">
|
||||
<list>
|
||||
<idref local="iBatisDataSource_autcommit" />
|
||||
</list>
|
||||
</property>
|
||||
</bean>
|
||||
|
||||
<bean id="sqlMapClient" class="org.alfresco.repo.domain.ibatis.AlfrescoSqlMapClientFactoryBean" singleton="true">
|
||||
<bean id="iBatisDataSource_autcommit" class="org.springframework.aop.support.NameMatchMethodPointcutAdvisor">
|
||||
<property name="advice">
|
||||
<bean class="org.alfresco.util.AutoCommitInterceptor" />
|
||||
</property>
|
||||
<property name="mappedName">
|
||||
<value>getConnection</value>
|
||||
</property>
|
||||
</bean>
|
||||
|
||||
<bean id="sqlMapClient" class="org.springframework.orm.ibatis.SqlMapClientFactoryBean" singleton="true">
|
||||
<property name="configLocation"><value>classpath:alfresco/activities/activities-SqlMapConfig.xml</value></property>
|
||||
<property name="dataSource" ref="iBatisDataSource"/>
|
||||
<!-- NOTE: although we use iBatis here rather than Hibernate, for consistency we make use of single SQL dialect property (hibernate.dialect) for consistency -->
|
||||
<property name="sqlMapClientProperties" ref="hibernateConfigProperties"/>
|
||||
</bean>
|
||||
|
||||
<bean id="postDaoService" class="org.alfresco.repo.activities.ibatis.IBatisActivityPostDaoServiceImpl">
|
||||
|
@@ -74,30 +74,26 @@
|
||||
<!-- The authroity DAO implements an interface extended from the Acegi -->
|
||||
<!-- DAO that supports CRUD. -->
|
||||
|
||||
<bean id="authenticationDao" class="org.alfresco.repo.security.authentication.RepositoryAuthenticationDao">
|
||||
<property name="nodeService">
|
||||
<ref bean="nodeService" />
|
||||
<bean id="alfrescoAuthentication" class="org.alfresco.repo.management.DefaultManagedApplicationContextFactory"/>
|
||||
<bean id="kerberosAuthentication" class="org.alfresco.repo.management.DefaultManagedApplicationContextFactory"/>
|
||||
<bean id="ldapAuthentication" class="org.alfresco.repo.management.DefaultManagedApplicationContextFactory"/>
|
||||
<bean id="ntlmAuthentication" class="org.alfresco.repo.management.DefaultManagedApplicationContextFactory"/>
|
||||
|
||||
<bean id="authenticationSelector" class="org.alfresco.repo.management.SwitchableManagedApplicationContextFactory">
|
||||
<property name="sourceBeanName">
|
||||
<value>alfrescoAuthentication</value>
|
||||
</property>
|
||||
<property name="tenantService">
|
||||
<ref bean="tenantService"/>
|
||||
</bean>
|
||||
|
||||
<bean id="authenticationDao" class="org.alfresco.repo.management.ManagedSubsystemProxyFactory">
|
||||
<property name="sourceApplicationContextFactory">
|
||||
<ref bean="authenticationSelector" />
|
||||
</property>
|
||||
<property name="dictionaryService">
|
||||
<ref bean="dictionaryService" />
|
||||
</property>
|
||||
<property name="namespaceService">
|
||||
<ref bean="namespaceService" />
|
||||
</property>
|
||||
<property name="searchService">
|
||||
<ref bean="admSearchService" />
|
||||
</property>
|
||||
<property name="retryingTransactionHelper">
|
||||
<ref bean="retryingTransactionHelper"/>
|
||||
</property>
|
||||
<property name="userNameMatcher">
|
||||
<ref bean="userNameMatcher" />
|
||||
</property>
|
||||
<property name="passwordEncoder">
|
||||
<ref bean="passwordEncoder" />
|
||||
<property name="interfaces">
|
||||
<list>
|
||||
<value>org.alfresco.repo.security.authentication.AuthenticationComponent</value>
|
||||
<value>org.alfresco.repo.security.authentication.MutableAuthenticationDao</value>
|
||||
</list>
|
||||
</property>
|
||||
</bean>
|
||||
|
||||
@@ -161,29 +157,7 @@
|
||||
</property>
|
||||
</bean>
|
||||
|
||||
<bean id="authenticationComponent"
|
||||
class="org.alfresco.repo.security.authentication.AuthenticationComponentImpl"
|
||||
parent="authenticationComponentBase">
|
||||
<property name="authenticationDao">
|
||||
<ref bean="authenticationDao" />
|
||||
</property>
|
||||
<property name="authenticationManager">
|
||||
<ref bean="authenticationManager" />
|
||||
</property>
|
||||
<property name="allowGuestLogin">
|
||||
<value>true</value>
|
||||
</property>
|
||||
<property name="nodeService">
|
||||
<ref bean="nodeService" />
|
||||
</property>
|
||||
<property name="personService">
|
||||
<ref bean="personService" />
|
||||
</property>
|
||||
<property name="transactionService">
|
||||
<ref bean="transactionService" />
|
||||
</property>
|
||||
</bean>
|
||||
|
||||
<alias name="authenticationDao" alias="authenticationComponent"/>
|
||||
|
||||
<!-- Simple Authentication component that rejects all authentication requests -->
|
||||
<!-- Use this defintion for Novell IChain integration. -->
|
||||
|
@@ -25,29 +25,13 @@
|
||||
<property name="authorityDAO">
|
||||
<ref bean="authorityDAO" />
|
||||
</property>
|
||||
<property name="authenticationService">
|
||||
<ref bean="authenticationService" />
|
||||
</property>
|
||||
<property name="permissionServiceSPI">
|
||||
<ref bean="permissionServiceImpl" />
|
||||
</property>
|
||||
<!-- -->
|
||||
<!-- A list of users with admin rights. -->
|
||||
<!-- -->
|
||||
<!-- If the security framework is case sensitive these values should -->
|
||||
<!-- be case sensitive user names. If the security framework is not -->
|
||||
<!-- case sensitive these values should be the lower-case user names. -->
|
||||
<!-- -->
|
||||
<!-- By default this includes: -->
|
||||
<!-- admin (the user name of default alfresco admin user) -->
|
||||
<!-- administrator (the windows default admin user) -->
|
||||
<!-- -->
|
||||
<!-- This assumes that user names are not case sensitive. -->
|
||||
<!-- -->
|
||||
<property name="adminUsers">
|
||||
<set>
|
||||
<value>admin</value>
|
||||
<value>administrator</value>
|
||||
</set>
|
||||
</property>
|
||||
<!-- -->
|
||||
<!-- A list of groups with admin rights. -->
|
||||
<!-- -->
|
||||
<property name="adminGroups">
|
||||
|
@@ -15,7 +15,7 @@
|
||||
|
||||
<!-- load common properties -->
|
||||
<bean id="repository-properties"
|
||||
class="org.springframework.beans.factory.config.PropertyPlaceholderConfigurer">
|
||||
class="org.alfresco.config.JndiPropertyPlaceholderConfigurer">
|
||||
<property name="ignoreUnresolvablePlaceholders">
|
||||
<value>true</value>
|
||||
</property>
|
||||
@@ -42,7 +42,7 @@
|
||||
<!-- or custom-db-and-data-context.xml file. -->
|
||||
|
||||
<bean id="shared-properties"
|
||||
class="org.springframework.beans.factory.config.PropertyPlaceholderConfigurer">
|
||||
class="org.alfresco.config.JndiPropertyPlaceholderConfigurer">
|
||||
<property name="ignoreUnresolvablePlaceholders">
|
||||
<value>true</value>
|
||||
</property>
|
||||
@@ -181,7 +181,7 @@
|
||||
|
||||
|
||||
<!-- Datasource bean -->
|
||||
<bean id="dataSource" class="org.apache.commons.dbcp.BasicDataSource" destroy-method="close">
|
||||
<bean id="defaultDataSource" class="org.apache.commons.dbcp.BasicDataSource" destroy-method="close">
|
||||
<property name="driverClassName">
|
||||
<value>${db.driver}</value>
|
||||
</property>
|
||||
@@ -208,6 +208,15 @@
|
||||
</property>
|
||||
</bean>
|
||||
|
||||
<bean id="dataSource" class="org.springframework.jndi.JndiObjectFactoryBean">
|
||||
<property name="jndiName">
|
||||
<value>java:comp/env/jdbc/dataSource</value>
|
||||
</property>
|
||||
<property name="defaultObject">
|
||||
<ref bean="defaultDataSource" />
|
||||
</property>
|
||||
</bean>
|
||||
|
||||
<!-- Characterset decoder -->
|
||||
<bean id="charset.finder" class="org.alfresco.repo.content.encoding.ContentCharsetFinder">
|
||||
<property name="defaultCharset">
|
||||
|
@@ -4,7 +4,7 @@
|
||||
<beans>
|
||||
|
||||
<!-- load hibernate configuration properties -->
|
||||
<bean id="hibernateConfigProperties" class="org.alfresco.config.SystemPropertiesFactoryBean">
|
||||
<bean id="hibernateConfigProperties" class="org.alfresco.config.JndiPropertiesFactoryBean">
|
||||
<property name="systemProperties">
|
||||
<list>
|
||||
<value>hibernate.dialect</value>
|
||||
|
@@ -0,0 +1,52 @@
|
||||
<?xml version='1.0' encoding='UTF-8'?>
|
||||
<!DOCTYPE beans PUBLIC '-//SPRING//DTD BEAN//EN' 'http://www.springframework.org/dtd/spring-beans.dtd'>
|
||||
<beans>
|
||||
<bean id="authenticationComponent" class="org.alfresco.repo.security.authentication.AuthenticationComponentImpl"
|
||||
parent="authenticationComponentBase">
|
||||
<property name="authenticationDao">
|
||||
<ref bean="authenticationDao" />
|
||||
</property>
|
||||
<property name="authenticationManager">
|
||||
<ref bean="authenticationManager" />
|
||||
</property>
|
||||
<property name="allowGuestLogin">
|
||||
<value>${alfresco.authentication.allowGuestLogin}</value>
|
||||
</property>
|
||||
<property name="nodeService">
|
||||
<ref bean="nodeService" />
|
||||
</property>
|
||||
<property name="personService">
|
||||
<ref bean="personService" />
|
||||
</property>
|
||||
<property name="transactionService">
|
||||
<ref bean="transactionService" />
|
||||
</property>
|
||||
</bean>
|
||||
|
||||
<bean id="authenticationDao" class="org.alfresco.repo.security.authentication.RepositoryAuthenticationDao">
|
||||
<property name="nodeService">
|
||||
<ref bean="nodeService" />
|
||||
</property>
|
||||
<property name="tenantService">
|
||||
<ref bean="tenantService" />
|
||||
</property>
|
||||
<property name="dictionaryService">
|
||||
<ref bean="dictionaryService" />
|
||||
</property>
|
||||
<property name="namespaceService">
|
||||
<ref bean="namespaceService" />
|
||||
</property>
|
||||
<property name="searchService">
|
||||
<ref bean="admSearchService" />
|
||||
</property>
|
||||
<property name="retryingTransactionHelper">
|
||||
<ref bean="retryingTransactionHelper" />
|
||||
</property>
|
||||
<property name="userNameMatcher">
|
||||
<ref bean="userNameMatcher" />
|
||||
</property>
|
||||
<property name="passwordEncoder">
|
||||
<ref bean="passwordEncoder" />
|
||||
</property>
|
||||
</bean>
|
||||
</beans>
|
@@ -0,0 +1 @@
|
||||
alfresco.authentication.allowGuestLogin=true
|
@@ -10,10 +10,10 @@
|
||||
class="org.alfresco.repo.security.authentication.jaas.JAASAuthenticationComponent"
|
||||
parent="authenticationComponentBase">
|
||||
<property name="realm">
|
||||
<value>DEFAULT.REALM</value>
|
||||
<value>${kerberos.authentication.realm}</value>
|
||||
</property>
|
||||
<property name="jaasConfigEntryName">
|
||||
<value>Alfresco</value>
|
||||
<value>${kerberos.authentication.user.configEntryName}</value>
|
||||
</property>
|
||||
<property name="nodeService">
|
||||
<ref bean="nodeService" />
|
||||
@@ -24,6 +24,9 @@
|
||||
<property name="transactionService">
|
||||
<ref bean="transactionService" />
|
||||
</property>
|
||||
<property name="defaultAdministratorUserNames">
|
||||
<value>${kerberos.authentication.defaultAdministratorUserNames}</value>
|
||||
</property>
|
||||
</bean>
|
||||
|
||||
<!-- DAO that rejects changes - JAAS is read only at the moment. -->
|
@@ -0,0 +1,3 @@
|
||||
kerberos.authentication.realm=ALFRESCO.ORG
|
||||
kerberos.authentication.user.configEntryName=Alfresco
|
||||
kerberos.authentication.defaultAdministratorUserNames=
|
@@ -2,18 +2,6 @@
|
||||
<!DOCTYPE beans PUBLIC '-//SPRING//DTD BEAN//EN' 'http://www.springframework.org/dtd/spring-beans.dtd'>
|
||||
|
||||
<beans>
|
||||
|
||||
<!-- The main configuration has moved into a properties file -->
|
||||
|
||||
<bean name="ldapAuthenticationPlaceholderConfigurer" class="org.springframework.beans.factory.config.PropertyPlaceholderConfigurer">
|
||||
<property name="ignoreUnresolvablePlaceholders">
|
||||
<value>true</value>
|
||||
</property>
|
||||
<property name="locations">
|
||||
<value>classpath:alfresco/extension/ldap-authentication.properties</value>
|
||||
</property>
|
||||
</bean>
|
||||
|
||||
<!-- DAO that rejects changes - LDAP is read only at the moment. It does allow users to be deleted with out warnings from the UI. -->
|
||||
|
||||
<bean id="authenticationDao" class="org.alfresco.repo.security.authentication.DefaultMutableAuthenticationDao" >
|
||||
@@ -68,6 +56,12 @@
|
||||
<property name="escapeCommasInUid">
|
||||
<value>${ldap.authentication.escapeCommasInUid}</value>
|
||||
</property>
|
||||
<property name="allowGuestLogin">
|
||||
<value>${ldap.authentication.allowGuestLogin}</value>
|
||||
</property>
|
||||
<property name="defaultAdministratorUserNames">
|
||||
<value>${ldap.authentication.defaultAdministratorUserNames}</value>
|
||||
</property>
|
||||
</bean>
|
||||
|
||||
<!--
|
@@ -1,7 +1,7 @@
|
||||
#
|
||||
# This properties file brings together the common options for LDAP authentication rather than editing the bean definitions
|
||||
#
|
||||
|
||||
ldap.authentication.allowGuestLogin=true
|
||||
# How to map the user id entered by the user to taht passed through to LDAP
|
||||
# - simple
|
||||
# - this must be a DN and would be something like
|
||||
@@ -35,3 +35,6 @@ ldap.authentication.escapeCommasInBind=false
|
||||
# pulled in as part of an LDAP sync
|
||||
# If this option is set to true it will break the default home folder provider as space names can not contain \
|
||||
ldap.authentication.escapeCommasInUid=false
|
||||
|
||||
# Comma separated list of user names who should be considered users by default
|
||||
ldap.authentication.defaultAdministratorUserNames=
|
@@ -3,21 +3,48 @@
|
||||
|
||||
<beans>
|
||||
|
||||
<bean name="ldapSynchronisationPlaceholderConfigurer" class="org.springframework.beans.factory.config.PropertyPlaceholderConfigurer">
|
||||
<property name="ignoreUnresolvablePlaceholders">
|
||||
<value>true</value>
|
||||
</property>
|
||||
<property name="locations">
|
||||
<value>classpath:alfresco/extension/ldap-synchronisation.properties</value>
|
||||
</property>
|
||||
</bean>
|
||||
|
||||
<!--
|
||||
Wire up the same context as used for LDAP authentication. You could use another context: just replace this
|
||||
alias with the bean definition
|
||||
|
||||
This bean is used to provide read only access to users and groups to pull them out of the LDAP reopsitory
|
||||
|
||||
-->
|
||||
|
||||
<alias alias="ldapSyncInitialDirContextFactory" name="ldapInitialDirContextFactory"/>
|
||||
<bean id="ldapInitialDirContextFactory" class="org.alfresco.repo.security.authentication.ldap.LDAPInitialDirContextFactoryImpl">
|
||||
<property name="initialDirContextEnvironment">
|
||||
<map>
|
||||
<!-- The LDAP provider -->
|
||||
<entry key="java.naming.factory.initial">
|
||||
<value>${ldap.synchronisation.java.naming.factory.initial}</value>
|
||||
</entry>
|
||||
|
||||
<!-- The url to the LDAP server -->
|
||||
<!-- Note you can use space separated urls - they will be tried in turn until one works -->
|
||||
<!-- This could be used to authenticate against one or more ldap servers (you will not know which one ....) -->
|
||||
<entry key="java.naming.provider.url">
|
||||
<value>${ldap.synchronisation.java.naming.provider.url}</value>
|
||||
</entry>
|
||||
|
||||
<!-- The authentication mechanism to use -->
|
||||
<!-- Some sasl authentication mechanisms may require a realm to be set -->
|
||||
<!-- java.naming.security.sasl.realm -->
|
||||
<!-- The available options will depend on your LDAP provider -->
|
||||
<entry key="java.naming.security.authentication">
|
||||
<value>${ldap.synchronisation.java.naming.security.authentication}</value>
|
||||
</entry>
|
||||
|
||||
<!-- The id of a user who can read group and user information -->
|
||||
<!-- This does not go through the pattern substitution defined above and is used "as is" -->
|
||||
<entry key="java.naming.security.principal">
|
||||
<value>${ldap.synchronisation.java.naming.security.principal}</value>
|
||||
</entry>
|
||||
|
||||
<!-- The password for the user defined above -->
|
||||
<entry key="java.naming.security.credentials">
|
||||
<value>${ldap.authentication.java.naming.security.credentials}</value>
|
||||
</entry>
|
||||
</map>
|
||||
</property>
|
||||
</bean>
|
||||
|
||||
<!-- Ldap Syncronisation support -->
|
||||
|
@@ -2,6 +2,21 @@
|
||||
# This properties file is used to configure LDAP syncronisation
|
||||
#
|
||||
|
||||
# The LDAP context factory to use
|
||||
ldap.synchronisation.java.naming.factory.initial=com.sun.jndi.ldap.LdapCtxFactory
|
||||
|
||||
# The URL to connect to the LDAP server
|
||||
ldap.synchronisation.java.naming.provider.url=ldap://openldap.domain.com:389
|
||||
|
||||
# The synchronisation mechanism to use
|
||||
ldap.synchronisation.java.naming.security.authentication=DIGEST-MD5
|
||||
|
||||
# The default principal to use (only used for LDAP sync)
|
||||
ldap.synchronisation.java.naming.security.principal=reader
|
||||
|
||||
# The password for the default principal (only used for LDAP sync)
|
||||
ldap.synchronisation.java.naming.security.credentials=secret
|
||||
|
||||
# The query to find the people to import
|
||||
ldap.synchronisation.personQuery=(objectclass=inetOrgPerson)
|
||||
|
@@ -0,0 +1,5 @@
|
||||
ntlm.authentication.useLocalServer=false
|
||||
ntlm.authentication.domain=DOMAIN
|
||||
ntlm.authentication.servers=
|
||||
ntlm.authentication.guestAccess=false
|
||||
ntlm.authentication.defaultAdministratorUserNames=
|
@@ -27,10 +27,13 @@
|
||||
class="org.alfresco.repo.security.authentication.ntlm.NTLMAuthenticationComponentImpl"
|
||||
parent="authenticationComponentBase">
|
||||
<property name="useLocalServer">
|
||||
<value>false</value>
|
||||
<value>${ntlm.authentication.useLocalServer}</value>
|
||||
</property>
|
||||
<property name="domain">
|
||||
<value>${ntlm.authentication.domain}</value>
|
||||
</property>
|
||||
<property name="servers">
|
||||
<value>192.168.0.1</value>
|
||||
<value>${ntlm.authentication.servers}</value>
|
||||
</property>
|
||||
<property name="personService">
|
||||
<ref bean="personService" />
|
||||
@@ -42,7 +45,10 @@
|
||||
<ref bean="transactionComponent" />
|
||||
</property>
|
||||
<property name="guestAccess">
|
||||
<value>false</value>
|
||||
<value>${ntlm.authentication.guestAccess}</value>
|
||||
</property>
|
||||
<property name="defaultAdministratorUserNames">
|
||||
<value>${ntlm.authentication.defaultAdministratorUserNames}</value>
|
||||
</property>
|
||||
</bean>
|
||||
|
@@ -0,0 +1,162 @@
|
||||
/*
|
||||
* Copyright (C) 2005-2009 Alfresco Software Limited.
|
||||
*
|
||||
* This program is free software; you can redistribute it and/or
|
||||
* modify it under the terms of the GNU General Public License
|
||||
* as published by the Free Software Foundation; either version 2
|
||||
* of the License, or (at your option) any later version.
|
||||
|
||||
* This program is distributed in the hope that it will be useful,
|
||||
* but WITHOUT ANY WARRANTY; without even the implied warranty of
|
||||
* MERCHANTABILITY or FITNESS FOR A PARTICULAR PURPOSE. See the
|
||||
* GNU General Public License for more details.
|
||||
|
||||
* You should have received a copy of the GNU General Public License
|
||||
* along with this program; if not, write to the Free Software
|
||||
* Foundation, Inc., 51 Franklin Street, Fifth Floor, Boston, MA 02110-1301, USA.
|
||||
|
||||
* As a special exception to the terms and conditions of version 2.0 of
|
||||
* the GPL, you may redistribute this Program in connection with Free/Libre
|
||||
* and Open Source Software ("FLOSS") applications as described in Alfresco's
|
||||
* FLOSS exception. You should have received a copy of the text describing
|
||||
* the FLOSS exception, and it is also available here:
|
||||
* http://www.alfresco.com/legal/licensing"
|
||||
*/
|
||||
package org.alfresco.repo.management;
|
||||
|
||||
import java.util.Properties;
|
||||
|
||||
import org.alfresco.service.Managed;
|
||||
import org.springframework.beans.BeansException;
|
||||
import org.springframework.beans.factory.BeanNameAware;
|
||||
import org.springframework.beans.factory.InitializingBean;
|
||||
import org.springframework.beans.factory.config.BeanFactoryPostProcessor;
|
||||
import org.springframework.beans.factory.config.PropertiesFactoryBean;
|
||||
import org.springframework.beans.factory.config.PropertyPlaceholderConfigurer;
|
||||
import org.springframework.context.ApplicationContext;
|
||||
import org.springframework.context.ApplicationContextAware;
|
||||
import org.springframework.context.support.ClassPathXmlApplicationContext;
|
||||
|
||||
/**
|
||||
* A factory allowing initialisation of an entire 'subsystem' in a child application context. As with other
|
||||
* {@link ManagedBean}s, can be stopped, reconfigured, started and tested. Doesn't actually implement FactoryBean
|
||||
* because we need first class access to the factory itself to be able to configure its properties.
|
||||
*/
|
||||
public class DefaultManagedApplicationContextFactory implements ManagedApplicationContextFactory,
|
||||
InitializingBean, ApplicationContextAware, BeanNameAware
|
||||
{
|
||||
private static final long serialVersionUID = 6368629257690177326L;
|
||||
private ApplicationContext parent;
|
||||
private String beanName;
|
||||
private ClassPathXmlApplicationContext applicationContext;
|
||||
private Properties properties;
|
||||
|
||||
/*
|
||||
* (non-Javadoc)
|
||||
* @see org.springframework.context.ApplicationContextAware#setApplicationContext(org.springframework.context.
|
||||
* ApplicationContext)
|
||||
*/
|
||||
public void setApplicationContext(ApplicationContext applicationContext) throws BeansException
|
||||
{
|
||||
this.parent = applicationContext;
|
||||
}
|
||||
|
||||
/*
|
||||
* (non-Javadoc)
|
||||
* @see org.springframework.beans.factory.BeanNameAware#setBeanName(java.lang.String)
|
||||
*/
|
||||
public void setBeanName(String name)
|
||||
{
|
||||
this.beanName = name;
|
||||
}
|
||||
|
||||
/**
|
||||
* @param properties
|
||||
* the properties to set
|
||||
*/
|
||||
@Managed(category="management")
|
||||
public void setProperties(Properties properties)
|
||||
{
|
||||
this.properties = properties;
|
||||
}
|
||||
|
||||
/**
|
||||
* @return the properties
|
||||
*/
|
||||
public Properties getProperties()
|
||||
{
|
||||
return this.properties;
|
||||
}
|
||||
|
||||
/*
|
||||
* (non-Javadoc)
|
||||
* @see org.springframework.beans.factory.InitializingBean#afterPropertiesSet()
|
||||
*/
|
||||
public void afterPropertiesSet() throws Exception
|
||||
{
|
||||
PropertiesFactoryBean factory = new PropertiesFactoryBean();
|
||||
if (this.properties != null)
|
||||
{
|
||||
factory.setLocalOverride(true);
|
||||
factory.setProperties(this.properties);
|
||||
}
|
||||
factory.setLocations(this.parent.getResources("classpath*:alfresco/subsystems/" + this.beanName
|
||||
+ "/*.properties"));
|
||||
factory.afterPropertiesSet();
|
||||
this.properties = (Properties) factory.getObject();
|
||||
}
|
||||
|
||||
/*
|
||||
* (non-Javadoc)
|
||||
* @see org.alfresco.enterprise.repo.management.ConfigurableBean#onStart()
|
||||
*/
|
||||
public void onStart()
|
||||
{
|
||||
this.applicationContext = new ClassPathXmlApplicationContext(new String[]
|
||||
{
|
||||
"classpath*:alfresco/subsystems/" + this.beanName + "/*-context.xml"
|
||||
}, false, this.parent);
|
||||
// Add all the post processors of the parent, e.g. to make sure system placeholders get expanded properly
|
||||
for (Object postProcessor : this.parent.getBeansOfType(BeanFactoryPostProcessor.class).values())
|
||||
{
|
||||
this.applicationContext.addBeanFactoryPostProcessor((BeanFactoryPostProcessor) postProcessor);
|
||||
}
|
||||
// Add a property placeholder configurer, with the subsystem-scoped default properties
|
||||
PropertyPlaceholderConfigurer configurer = new PropertyPlaceholderConfigurer();
|
||||
configurer.setProperties(this.properties);
|
||||
configurer.setIgnoreUnresolvablePlaceholders(true);
|
||||
this.applicationContext.addBeanFactoryPostProcessor(configurer);
|
||||
this.applicationContext.setClassLoader(parent.getClassLoader());
|
||||
this.applicationContext.refresh();
|
||||
}
|
||||
|
||||
/*
|
||||
* (non-Javadoc)
|
||||
* @see org.alfresco.enterprise.repo.management.ConfigurableBean#onTest()
|
||||
*/
|
||||
public void onTest()
|
||||
{
|
||||
this.applicationContext.getBean("testBean");
|
||||
}
|
||||
|
||||
/*
|
||||
* (non-Javadoc)
|
||||
* @see org.springframework.beans.factory.DisposableBean#destroy()
|
||||
*/
|
||||
public void destroy() throws Exception
|
||||
{
|
||||
if (this.applicationContext != null)
|
||||
{
|
||||
this.applicationContext.close();
|
||||
this.applicationContext = null;
|
||||
}
|
||||
}
|
||||
|
||||
/* (non-Javadoc)
|
||||
* @see org.alfresco.repo.management.ManagedApplicationContextFactory#getApplicationContext()
|
||||
*/
|
||||
public ApplicationContext getApplicationContext()
|
||||
{
|
||||
return this.applicationContext;
|
||||
}
|
||||
}
|
350
source/java/org/alfresco/repo/management/JmxDumpUtil.java
Normal file
350
source/java/org/alfresco/repo/management/JmxDumpUtil.java
Normal file
@@ -0,0 +1,350 @@
|
||||
/*
|
||||
* Copyright (C) 2005-2009 Alfresco Software Limited.
|
||||
*
|
||||
* This program is free software; you can redistribute it and/or
|
||||
* modify it under the terms of the GNU General Public License
|
||||
* as published by the Free Software Foundation; either version 2
|
||||
* of the License, or (at your option) any later version.
|
||||
|
||||
* This program is distributed in the hope that it will be useful,
|
||||
* but WITHOUT ANY WARRANTY; without even the implied warranty of
|
||||
* MERCHANTABILITY or FITNESS FOR A PARTICULAR PURPOSE. See the
|
||||
* GNU General Public License for more details.
|
||||
|
||||
* You should have received a copy of the GNU General Public License
|
||||
* along with this program; if not, write to the Free Software
|
||||
* Foundation, Inc., 51 Franklin Street, Fifth Floor, Boston, MA 02110-1301, USA.
|
||||
|
||||
* As a special exception to the terms and conditions of version 2.0 of
|
||||
* the GPL, you may redistribute this Program in connection with Free/Libre
|
||||
* and Open Source Software ("FLOSS") applications as described in Alfresco's
|
||||
* FLOSS exception. You should have received a copy of the text describing
|
||||
* the FLOSS exception, and it is also available here:
|
||||
* http://www.alfresco.com/legal/licensing"
|
||||
*/
|
||||
package org.alfresco.repo.management;
|
||||
|
||||
import java.io.IOException;
|
||||
import java.io.PrintWriter;
|
||||
import java.lang.reflect.Array;
|
||||
import java.util.Map;
|
||||
import java.util.Set;
|
||||
import java.util.TreeMap;
|
||||
import java.util.TreeSet;
|
||||
|
||||
import javax.management.JMException;
|
||||
import javax.management.MBeanAttributeInfo;
|
||||
import javax.management.MBeanInfo;
|
||||
import javax.management.MBeanServerConnection;
|
||||
import javax.management.ObjectName;
|
||||
import javax.management.openmbean.CompositeData;
|
||||
|
||||
/**
|
||||
* A utility class providing a method to dump a local or remote MBeanServer's entire object tree for support purposes.
|
||||
* Nested arrays and CompositeData objects in MBean attribute values are handled.
|
||||
*
|
||||
* @author dward
|
||||
*/
|
||||
public class JmxDumpUtil
|
||||
{
|
||||
/** Table header for attribute names. */
|
||||
private static final String NAME_HEADER = "Attribute Name";
|
||||
|
||||
/** Table header for attribute values. */
|
||||
private static final String VALUE_HEADER = "Attribute Value";
|
||||
|
||||
/** Place holder for nulls. */
|
||||
private static final String NULL_VALUE = "<null>";
|
||||
|
||||
/** Place holder for unreadable values. */
|
||||
private static final String UNREADABLE_VALUE = "<not readable>";
|
||||
|
||||
/**
|
||||
* Dumps a local or remote MBeanServer's entire object tree for support purposes. Nested arrays and CompositeData
|
||||
* objects in MBean attribute values are handled.
|
||||
*
|
||||
* @param connection
|
||||
* the server connection (or server itself)
|
||||
* @param out
|
||||
* PrintWriter to write the output to
|
||||
* @throws IOException
|
||||
* Signals that an I/O exception has occurred.
|
||||
*/
|
||||
public static void dumpConnection(MBeanServerConnection connection, PrintWriter out) throws IOException
|
||||
{
|
||||
// Get all the object names
|
||||
Set<ObjectName> objectNames = connection.queryNames(null, null);
|
||||
|
||||
// Sort the names
|
||||
objectNames = new TreeSet<ObjectName>(objectNames);
|
||||
|
||||
// Dump each MBean
|
||||
for (ObjectName objectName : objectNames)
|
||||
{
|
||||
try
|
||||
{
|
||||
printMBeanInfo(connection, objectName, out);
|
||||
}
|
||||
catch (JMException e)
|
||||
{
|
||||
// Sometimes beans can disappear while we are examining them
|
||||
}
|
||||
}
|
||||
}
|
||||
|
||||
/**
|
||||
* Dumps the details of a single MBean.
|
||||
*
|
||||
* @param connection
|
||||
* the server connection (or server itself)
|
||||
* @param objectName
|
||||
* the object name
|
||||
* @param out
|
||||
* PrintWriter to write the output to
|
||||
* @throws IOException
|
||||
* Signals that an I/O exception has occurred.
|
||||
* @throws JMException
|
||||
* Signals a JMX error
|
||||
*/
|
||||
private static void printMBeanInfo(MBeanServerConnection connection, ObjectName objectName, PrintWriter out)
|
||||
throws IOException, JMException
|
||||
{
|
||||
Map<String, Object> attributes = new TreeMap<String, Object>();
|
||||
MBeanInfo info = connection.getMBeanInfo(objectName);
|
||||
attributes.put("** Object Name", objectName.toString());
|
||||
attributes.put("** Object Type", info.getClassName());
|
||||
for (MBeanAttributeInfo element : info.getAttributes())
|
||||
{
|
||||
Object value;
|
||||
if (element.isReadable())
|
||||
{
|
||||
try
|
||||
{
|
||||
value = connection.getAttribute(objectName, element.getName());
|
||||
}
|
||||
catch (Exception e)
|
||||
{
|
||||
value = JmxDumpUtil.UNREADABLE_VALUE;
|
||||
}
|
||||
}
|
||||
else
|
||||
{
|
||||
value = JmxDumpUtil.UNREADABLE_VALUE;
|
||||
}
|
||||
attributes.put(element.getName(), value);
|
||||
}
|
||||
tabulate(JmxDumpUtil.NAME_HEADER, JmxDumpUtil.VALUE_HEADER, attributes, out, 0);
|
||||
}
|
||||
|
||||
/**
|
||||
* Dumps the details of a single CompositeData object.
|
||||
*
|
||||
* @param composite
|
||||
* the composite object
|
||||
* @param out
|
||||
* PrintWriter to write the output to
|
||||
* @param nestLevel
|
||||
* the nesting level
|
||||
* @throws IOException
|
||||
* Signals that an I/O exception has occurred.
|
||||
*/
|
||||
private static void printCompositeInfo(CompositeData composite, PrintWriter out, int nestLevel) throws IOException
|
||||
{
|
||||
Map<String, Object> attributes = new TreeMap<String, Object>();
|
||||
for (String key : composite.getCompositeType().keySet())
|
||||
{
|
||||
Object value;
|
||||
try
|
||||
{
|
||||
value = composite.get(key);
|
||||
}
|
||||
catch (Exception e)
|
||||
{
|
||||
value = JmxDumpUtil.UNREADABLE_VALUE;
|
||||
}
|
||||
attributes.put(key, value);
|
||||
}
|
||||
tabulate(JmxDumpUtil.NAME_HEADER, JmxDumpUtil.VALUE_HEADER, attributes, out, nestLevel);
|
||||
}
|
||||
|
||||
/**
|
||||
* Tabulates a given String -> Object Map.
|
||||
*
|
||||
* @param keyHeader
|
||||
* the key header
|
||||
* @param valueHeader
|
||||
* the value header
|
||||
* @param rows
|
||||
* Map containing key value pairs forming the rows
|
||||
* @param out
|
||||
* PrintWriter to write the output to
|
||||
* @param nestLevel
|
||||
* the nesting level
|
||||
* @throws IOException
|
||||
* Signals that an I/O exception has occurred.
|
||||
*/
|
||||
private static void tabulate(String keyHeader, String valueHeader, Map<String, Object> rows, PrintWriter out,
|
||||
int nestLevel) throws IOException
|
||||
{
|
||||
if (rows.isEmpty())
|
||||
{
|
||||
return;
|
||||
}
|
||||
// Calculate column lengths
|
||||
int maxKeyLength = keyHeader.length(), maxValLength = valueHeader.length();
|
||||
for (Map.Entry<String, Object> entry : rows.entrySet())
|
||||
{
|
||||
maxKeyLength = Math.max(maxKeyLength, entry.getKey().length());
|
||||
maxValLength = Math.max(maxValLength, getValueLength(entry.getValue()));
|
||||
}
|
||||
// Output Header
|
||||
outputRow(out, maxKeyLength, keyHeader, valueHeader, nestLevel);
|
||||
indent(out, nestLevel);
|
||||
for (int col = 0; col < maxKeyLength; col++)
|
||||
{
|
||||
out.print('-');
|
||||
}
|
||||
out.print(' ');
|
||||
for (int col = 0; col < maxValLength; col++)
|
||||
{
|
||||
out.print('-');
|
||||
}
|
||||
out.println();
|
||||
|
||||
// Output Body
|
||||
for (Map.Entry<String, Object> entry : rows.entrySet())
|
||||
{
|
||||
outputRow(out, maxKeyLength, entry.getKey(), entry.getValue(), nestLevel);
|
||||
}
|
||||
out.println();
|
||||
}
|
||||
|
||||
/**
|
||||
* Outputs spaces in the left hand margin appropriate for the given nesting level.
|
||||
*
|
||||
* @param out
|
||||
* PrintWriter to write the output to
|
||||
* @param nestLevel
|
||||
* the nesting level
|
||||
*/
|
||||
private static void indent(PrintWriter out, int nestLevel)
|
||||
{
|
||||
int size = nestLevel * 3;
|
||||
for (int i = 0; i < size; i++)
|
||||
{
|
||||
out.print(' ');
|
||||
}
|
||||
}
|
||||
|
||||
/**
|
||||
* Outputs a single row in a two-column table. The first column is padded with spaces so that the second column is
|
||||
* aligned.
|
||||
*
|
||||
* @param out
|
||||
* PrintWriter to write the output to
|
||||
* @param maxKeyLength
|
||||
* maximum number of characters in the first column
|
||||
* @param key
|
||||
* the first column value
|
||||
* @param value
|
||||
* the second column value
|
||||
* @param nestLevel
|
||||
* the nesting level
|
||||
* @throws IOException
|
||||
* Signals that an I/O exception has occurred.
|
||||
*/
|
||||
private static void outputRow(PrintWriter out, int maxKeyLength, String key, Object value, int nestLevel)
|
||||
throws IOException
|
||||
{
|
||||
indent(out, nestLevel);
|
||||
out.print(key);
|
||||
for (int i = key.length() - 1; i < maxKeyLength; i++)
|
||||
{
|
||||
out.print(' ');
|
||||
}
|
||||
outputValue(out, value, nestLevel);
|
||||
}
|
||||
|
||||
/**
|
||||
* Outputs a single value, dealing with nested arrays and CompositeData objects.
|
||||
*
|
||||
* @param out
|
||||
* PrintWriter to write the output to
|
||||
* @param value
|
||||
* the value to output
|
||||
* @param nestLevel
|
||||
* the nesting level
|
||||
* @throws IOException
|
||||
* Signals that an I/O exception has occurred.
|
||||
*/
|
||||
private static void outputValue(PrintWriter out, Object value, int nestLevel) throws IOException
|
||||
{
|
||||
if (value == null)
|
||||
{
|
||||
out.println(JmxDumpUtil.NULL_VALUE);
|
||||
}
|
||||
else if (value.getClass().isArray())
|
||||
{
|
||||
int length = Array.getLength(value);
|
||||
if (length == 0)
|
||||
{
|
||||
out.println("[]");
|
||||
}
|
||||
else
|
||||
{
|
||||
out.println();
|
||||
indent(out, nestLevel + 1);
|
||||
out.println('[');
|
||||
for (int i = 0; i < length; i++)
|
||||
{
|
||||
indent(out, nestLevel + 2);
|
||||
outputValue(out, Array.get(value, i), nestLevel + 2);
|
||||
if (i + 1 < length)
|
||||
{
|
||||
indent(out, nestLevel + 1);
|
||||
out.println(',');
|
||||
}
|
||||
}
|
||||
indent(out, nestLevel + 1);
|
||||
out.println(']');
|
||||
}
|
||||
}
|
||||
else if (value instanceof CompositeData)
|
||||
{
|
||||
out.println();
|
||||
indent(out, nestLevel + 1);
|
||||
out.println('[');
|
||||
printCompositeInfo((CompositeData) value, out, nestLevel + 2);
|
||||
indent(out, nestLevel + 1);
|
||||
out.println(']');
|
||||
}
|
||||
else
|
||||
{
|
||||
out.println(value.toString());
|
||||
}
|
||||
}
|
||||
|
||||
/**
|
||||
* Gets the number of characters required to encode a value.
|
||||
*
|
||||
* @param value
|
||||
* the value to be encoded
|
||||
* @return the number of characters
|
||||
*/
|
||||
private static int getValueLength(Object value)
|
||||
{
|
||||
if (value == null)
|
||||
{
|
||||
return JmxDumpUtil.NULL_VALUE.length();
|
||||
}
|
||||
else if (value.getClass().isArray() || value instanceof CompositeData)
|
||||
{
|
||||
// We continue arrays and composites on a new line
|
||||
return 0;
|
||||
}
|
||||
else
|
||||
{
|
||||
return value.toString().length();
|
||||
}
|
||||
}
|
||||
}
|
@@ -0,0 +1,45 @@
|
||||
/*
|
||||
* Copyright (C) 2005-2009 Alfresco Software Limited.
|
||||
*
|
||||
* This program is free software; you can redistribute it and/or
|
||||
* modify it under the terms of the GNU General Public License
|
||||
* as published by the Free Software Foundation; either version 2
|
||||
* of the License, or (at your option) any later version.
|
||||
|
||||
* This program is distributed in the hope that it will be useful,
|
||||
* but WITHOUT ANY WARRANTY; without even the implied warranty of
|
||||
* MERCHANTABILITY or FITNESS FOR A PARTICULAR PURPOSE. See the
|
||||
* GNU General Public License for more details.
|
||||
|
||||
* You should have received a copy of the GNU General Public License
|
||||
* along with this program; if not, write to the Free Software
|
||||
* Foundation, Inc., 51 Franklin Street, Fifth Floor, Boston, MA 02110-1301, USA.
|
||||
|
||||
* As a special exception to the terms and conditions of version 2.0 of
|
||||
* the GPL, you may redistribute this Program in connection with Free/Libre
|
||||
* and Open Source Software ("FLOSS") applications as described in Alfresco's
|
||||
* FLOSS exception. You should have received a copy of the text describing
|
||||
* the FLOSS exception, and it is also available here:
|
||||
* http://www.alfresco.com/legal/licensing"
|
||||
*/
|
||||
package org.alfresco.repo.management;
|
||||
|
||||
import org.springframework.context.ApplicationContext;
|
||||
|
||||
/**
|
||||
* An interface for {@link ManagedBean}s providing access to a child application context corresonding to a particular
|
||||
* subsystem. As with other {@link ManagedBean}s, can be stopped, reconfigured, started and tested. Doesn't actually
|
||||
* implement FactoryBean because we need first class access to the factory itself to be able to configure its
|
||||
* properties.
|
||||
*
|
||||
* @author dward
|
||||
*/
|
||||
public interface ManagedApplicationContextFactory extends ManagedBean
|
||||
{
|
||||
/**
|
||||
* Gets the application context, configured according to the properties of the factory.
|
||||
*
|
||||
* @return the application context
|
||||
*/
|
||||
public ApplicationContext getApplicationContext();
|
||||
}
|
47
source/java/org/alfresco/repo/management/ManagedBean.java
Normal file
47
source/java/org/alfresco/repo/management/ManagedBean.java
Normal file
@@ -0,0 +1,47 @@
|
||||
/*
|
||||
* Copyright (C) 2005-2009 Alfresco Software Limited.
|
||||
*
|
||||
* This program is free software; you can redistribute it and/or
|
||||
* modify it under the terms of the GNU General Public License
|
||||
* as published by the Free Software Foundation; either version 2
|
||||
* of the License, or (at your option) any later version.
|
||||
|
||||
* This program is distributed in the hope that it will be useful,
|
||||
* but WITHOUT ANY WARRANTY; without even the implied warranty of
|
||||
* MERCHANTABILITY or FITNESS FOR A PARTICULAR PURPOSE. See the
|
||||
* GNU General Public License for more details.
|
||||
|
||||
* You should have received a copy of the GNU General Public License
|
||||
* along with this program; if not, write to the Free Software
|
||||
* Foundation, Inc., 51 Franklin Street, Fifth Floor, Boston, MA 02110-1301, USA.
|
||||
|
||||
* As a special exception to the terms and conditions of version 2.0 of
|
||||
* the GPL, you may redistribute this Program in connection with Free/Libre
|
||||
* and Open Source Software ("FLOSS") applications as described in Alfresco's
|
||||
* FLOSS exception. You should have received a copy of the text describing
|
||||
* the FLOSS exception, and it is also available here:
|
||||
* http://www.alfresco.com/legal/licensing"
|
||||
*/
|
||||
package org.alfresco.repo.management;
|
||||
|
||||
import org.springframework.beans.factory.DisposableBean;
|
||||
|
||||
/**
|
||||
* An interface for beans that can be reconfigured using an administration UI or JMX console. A bean in use must be
|
||||
* 'stopped' before it can be configured with {@link #destroy}. After reconfiguration, it can then be put back into use
|
||||
* with {@link #onStart} and if this is successful, further tests can be carried out with {@link #onTest}.
|
||||
*
|
||||
* @author dward
|
||||
*/
|
||||
public interface ManagedBean extends DisposableBean
|
||||
{
|
||||
/**
|
||||
* Puts the bean into use after its properties have been set.
|
||||
*/
|
||||
public void onStart();
|
||||
|
||||
/**
|
||||
* Carries out tests on the bean after it has been started.
|
||||
*/
|
||||
public void onTest();
|
||||
}
|
@@ -0,0 +1,103 @@
|
||||
/*
|
||||
* Copyright (C) 2005-2009 Alfresco Software Limited.
|
||||
*
|
||||
* This program is free software; you can redistribute it and/or
|
||||
* modify it under the terms of the GNU General Public License
|
||||
* as published by the Free Software Foundation; either version 2
|
||||
* of the License, or (at your option) any later version.
|
||||
|
||||
* This program is distributed in the hope that it will be useful,
|
||||
* but WITHOUT ANY WARRANTY; without even the implied warranty of
|
||||
* MERCHANTABILITY or FITNESS FOR A PARTICULAR PURPOSE. See the
|
||||
* GNU General Public License for more details.
|
||||
|
||||
* You should have received a copy of the GNU General Public License
|
||||
* along with this program; if not, write to the Free Software
|
||||
* Foundation, Inc., 51 Franklin Street, Fifth Floor, Boston, MA 02110-1301, USA.
|
||||
|
||||
* As a special exception to the terms and conditions of version 2.0 of
|
||||
* the GPL, you may redistribute this Program in connection with Free/Libre
|
||||
* and Open Source Software ("FLOSS") applications as described in Alfresco's
|
||||
* FLOSS exception. You should have received a copy of the text describing
|
||||
* the FLOSS exception, and it is also available here:
|
||||
* http://www.alfresco.com/legal/licensing"
|
||||
*/
|
||||
package org.alfresco.repo.management;
|
||||
|
||||
import java.lang.reflect.Method;
|
||||
import java.util.Map;
|
||||
|
||||
import org.aopalliance.intercept.MethodInterceptor;
|
||||
import org.aopalliance.intercept.MethodInvocation;
|
||||
import org.springframework.aop.framework.ProxyFactoryBean;
|
||||
import org.springframework.aop.support.DefaultPointcutAdvisor;
|
||||
|
||||
/**
|
||||
* A factory bean, normally used in conjunction with {@link DefaultManagedApplicationContextFactory} allowing selected
|
||||
* interfaces in a child application context to be proxied by a bean in the parent application context. This allows
|
||||
* 'hot-swapping' and reconfiguration of entire subsystems.
|
||||
*/
|
||||
public class ManagedSubsystemProxyFactory extends ProxyFactoryBean
|
||||
{
|
||||
private static final long serialVersionUID = -4186421942840611218L;
|
||||
|
||||
/** The source application context factory. */
|
||||
private ManagedApplicationContextFactory sourceApplicationContextFactory;
|
||||
|
||||
/** An optional bean name to look up in the source application context **/
|
||||
private String sourceBeanName;
|
||||
|
||||
/**
|
||||
* Instantiates a new managed subsystem proxy factory.
|
||||
*/
|
||||
public ManagedSubsystemProxyFactory()
|
||||
{
|
||||
addAdvisor(new DefaultPointcutAdvisor(new MethodInterceptor()
|
||||
{
|
||||
public Object invoke(MethodInvocation mi) throws Throwable
|
||||
{
|
||||
Method method = mi.getMethod();
|
||||
if (ManagedSubsystemProxyFactory.this.sourceBeanName == null)
|
||||
{
|
||||
Map<?, ?> beans = ManagedSubsystemProxyFactory.this.sourceApplicationContextFactory
|
||||
.getApplicationContext().getBeansOfType(method.getDeclaringClass());
|
||||
if (beans.size() != 1)
|
||||
{
|
||||
throw new RuntimeException("Don't know where to route call to method " + method);
|
||||
}
|
||||
return method.invoke(beans.values().iterator().next(), mi.getArguments());
|
||||
}
|
||||
else
|
||||
{
|
||||
Object bean = ManagedSubsystemProxyFactory.this.sourceApplicationContextFactory
|
||||
.getApplicationContext().getBean(ManagedSubsystemProxyFactory.this.sourceBeanName);
|
||||
return method.invoke(bean, mi.getArguments());
|
||||
|
||||
}
|
||||
}
|
||||
}));
|
||||
}
|
||||
|
||||
/**
|
||||
* Sets the source application context factory.
|
||||
*
|
||||
* @param sourceApplicationContextFactory
|
||||
* the sourceApplicationContextFactory to set
|
||||
*/
|
||||
public void setSourceApplicationContextFactory(ManagedApplicationContextFactory sourceApplicationContextFactory)
|
||||
{
|
||||
this.sourceApplicationContextFactory = sourceApplicationContextFactory;
|
||||
}
|
||||
|
||||
/**
|
||||
* Sets optional bean name to target all calls to in the source application context. If not set, an appropriate
|
||||
* bean is looked up based on method class.
|
||||
*
|
||||
* @param sourceBeanName
|
||||
* the sourceBeanName to set
|
||||
*/
|
||||
public void setSourceBeanName(String sourceBeanName)
|
||||
{
|
||||
this.sourceBeanName = sourceBeanName;
|
||||
}
|
||||
}
|
@@ -0,0 +1,131 @@
|
||||
/*
|
||||
* Copyright (C) 2005-2009 Alfresco Software Limited.
|
||||
*
|
||||
* This program is free software; you can redistribute it and/or
|
||||
* modify it under the terms of the GNU General Public License
|
||||
* as published by the Free Software Foundation; either version 2
|
||||
* of the License, or (at your option) any later version.
|
||||
|
||||
* This program is distributed in the hope that it will be useful,
|
||||
* but WITHOUT ANY WARRANTY; without even the implied warranty of
|
||||
* MERCHANTABILITY or FITNESS FOR A PARTICULAR PURPOSE. See the
|
||||
* GNU General Public License for more details.
|
||||
|
||||
* You should have received a copy of the GNU General Public License
|
||||
* along with this program; if not, write to the Free Software
|
||||
* Foundation, Inc., 51 Franklin Street, Fifth Floor, Boston, MA 02110-1301, USA.
|
||||
|
||||
* As a special exception to the terms and conditions of version 2.0 of
|
||||
* the GPL, you may redistribute this Program in connection with Free/Libre
|
||||
* and Open Source Software ("FLOSS") applications as described in Alfresco's
|
||||
* FLOSS exception. You should have received a copy of the text describing
|
||||
* the FLOSS exception, and it is also available here:
|
||||
* http://www.alfresco.com/legal/licensing"
|
||||
*/
|
||||
package org.alfresco.repo.management;
|
||||
|
||||
import org.alfresco.service.Managed;
|
||||
import org.springframework.beans.BeansException;
|
||||
import org.springframework.context.ApplicationContext;
|
||||
import org.springframework.context.ApplicationContextAware;
|
||||
|
||||
/**
|
||||
* A configurable proxy for a set of {@link ManagedApplicationContextFactory} beans that allows dynamic selection of one
|
||||
* or more alternative subsystems via {@link #setSourceBeanName}. As with other {@link ManagedBean}s, can be stopped,
|
||||
* reconfigured, started and tested. Doesn't actually implement FactoryBean because we need first class access to the
|
||||
* factory itself to be able to configure its properties.
|
||||
*/
|
||||
public class SwitchableManagedApplicationContextFactory implements ApplicationContextAware,
|
||||
ManagedApplicationContextFactory
|
||||
{
|
||||
/** The parent application context. */
|
||||
private ApplicationContext parent;
|
||||
|
||||
/** The bean name of the source {@link ManagedApplicationContextFactory}. */
|
||||
private String sourceBeanName;
|
||||
|
||||
/** The current source application context factory. */
|
||||
private ManagedApplicationContextFactory sourceApplicationContextFactory;
|
||||
|
||||
/**
|
||||
* Sets the bean name of the source {@link ManagedApplicationContextFactory}.
|
||||
*
|
||||
* @param sourceBeanName
|
||||
* the bean name
|
||||
* @throws Exception
|
||||
* on error
|
||||
*/
|
||||
@Managed(category = "management")
|
||||
public synchronized void setSourceBeanName(String sourceBeanName) throws Exception
|
||||
{
|
||||
if (this.sourceApplicationContextFactory != null)
|
||||
{
|
||||
destroy();
|
||||
this.sourceBeanName = sourceBeanName;
|
||||
onStart();
|
||||
}
|
||||
else
|
||||
{
|
||||
this.sourceBeanName = sourceBeanName;
|
||||
}
|
||||
}
|
||||
|
||||
/*
|
||||
* (non-Javadoc)
|
||||
* @see org.springframework.context.ApplicationContextAware#setApplicationContext(org.springframework.context.
|
||||
* ApplicationContext)
|
||||
*/
|
||||
public void setApplicationContext(ApplicationContext applicationContext) throws BeansException
|
||||
{
|
||||
this.parent = applicationContext;
|
||||
}
|
||||
|
||||
/*
|
||||
* (non-Javadoc)
|
||||
* @see org.alfresco.enterprise.repo.management.ConfigurableBean#onStart()
|
||||
*/
|
||||
public synchronized void onStart()
|
||||
{
|
||||
this.sourceApplicationContextFactory = (ManagedApplicationContextFactory) this.parent
|
||||
.getBean(this.sourceBeanName);
|
||||
this.sourceApplicationContextFactory.onStart();
|
||||
}
|
||||
|
||||
/*
|
||||
* (non-Javadoc)
|
||||
* @see org.alfresco.enterprise.repo.management.ConfigurableBean#onTest()
|
||||
*/
|
||||
public synchronized void onTest()
|
||||
{
|
||||
if (this.sourceApplicationContextFactory != null)
|
||||
{
|
||||
this.sourceApplicationContextFactory.onTest();
|
||||
}
|
||||
}
|
||||
|
||||
/*
|
||||
* (non-Javadoc)
|
||||
* @see org.springframework.beans.factory.DisposableBean#destroy()
|
||||
*/
|
||||
public synchronized void destroy() throws Exception
|
||||
{
|
||||
if (this.sourceApplicationContextFactory != null)
|
||||
{
|
||||
this.sourceApplicationContextFactory.destroy();
|
||||
}
|
||||
this.sourceApplicationContextFactory = null;
|
||||
}
|
||||
|
||||
/*
|
||||
* (non-Javadoc)
|
||||
* @see org.alfresco.repo.management.ManagedApplicationContextFactory#getApplicationContext()
|
||||
*/
|
||||
public synchronized ApplicationContext getApplicationContext()
|
||||
{
|
||||
if (this.sourceApplicationContextFactory == null)
|
||||
{
|
||||
onStart();
|
||||
}
|
||||
return this.sourceApplicationContextFactory.getApplicationContext();
|
||||
}
|
||||
}
|
@@ -24,6 +24,11 @@
|
||||
*/
|
||||
package org.alfresco.repo.security.authentication;
|
||||
|
||||
import java.util.Arrays;
|
||||
import java.util.Collections;
|
||||
import java.util.Set;
|
||||
import java.util.TreeSet;
|
||||
|
||||
import net.sf.acegisecurity.Authentication;
|
||||
import net.sf.acegisecurity.GrantedAuthority;
|
||||
import net.sf.acegisecurity.GrantedAuthorityImpl;
|
||||
@@ -66,6 +71,8 @@ public abstract class AbstractAuthenticationComponent implements AuthenticationC
|
||||
|
||||
private TransactionService transactionService;
|
||||
|
||||
private Set<String> defaultAdministratorUserNames = Collections.emptySet();
|
||||
|
||||
private boolean autoCreatePeopleOnLogin = true;
|
||||
|
||||
public AbstractAuthenticationComponent()
|
||||
@@ -494,4 +501,39 @@ public abstract class AbstractAuthenticationComponent implements AuthenticationC
|
||||
}
|
||||
}
|
||||
}
|
||||
|
||||
/*
|
||||
* (non-Javadoc)
|
||||
* @see org.alfresco.repo.security.authentication.AuthenticationComponent#getDefaultAdministratorUserNames()
|
||||
*/
|
||||
public Set<String> getDefaultAdministratorUserNames()
|
||||
{
|
||||
return this.defaultAdministratorUserNames;
|
||||
}
|
||||
|
||||
/**
|
||||
* Sets the user names who for this particular authentication system should be considered administrators by default.
|
||||
*
|
||||
* @param defaultAdministratorUserNames
|
||||
* a set of user names
|
||||
*/
|
||||
public void setDefaultAdministratorUserNames(Set<String> defaultAdministratorUserNames)
|
||||
{
|
||||
this.defaultAdministratorUserNames = defaultAdministratorUserNames;
|
||||
}
|
||||
|
||||
/**
|
||||
* Convenience method to allow the administrator user names to be specified as a comma separated list
|
||||
*
|
||||
* @param defaultAdministratorUserNames
|
||||
*/
|
||||
public void setDefaultAdministratorUserNames(String defaultAdministratorUserNames)
|
||||
{
|
||||
Set<String> nameSet = new TreeSet<String>();
|
||||
if (!defaultAdministratorUserNames.isEmpty())
|
||||
{
|
||||
nameSet.addAll(Arrays.asList(defaultAdministratorUserNames.split(",")));
|
||||
}
|
||||
setDefaultAdministratorUserNames(nameSet);
|
||||
}
|
||||
}
|
||||
|
@@ -24,6 +24,8 @@
|
||||
*/
|
||||
package org.alfresco.repo.security.authentication;
|
||||
|
||||
import java.util.Set;
|
||||
|
||||
import net.sf.acegisecurity.Authentication;
|
||||
|
||||
public interface AuthenticationComponent
|
||||
@@ -134,4 +136,13 @@ public interface AuthenticationComponent
|
||||
* Get the MD4 password hash, as required by NTLM based authentication methods.
|
||||
*/
|
||||
public String getMD4HashedPassword(String userName);
|
||||
|
||||
/**
|
||||
* Gets a set of user names who for this particular authentication system should be considered administrators by
|
||||
* default. If the security framework is case sensitive these values should be case sensitive user names. If the
|
||||
* security framework is not case sensitive these values should be the lower-case user names.
|
||||
*
|
||||
* @return a set of user names
|
||||
*/
|
||||
public Set<String> getDefaultAdministratorUserNames();
|
||||
}
|
||||
|
@@ -26,6 +26,8 @@ package org.alfresco.repo.security.authentication;
|
||||
|
||||
import java.io.PrintWriter;
|
||||
import java.io.StringWriter;
|
||||
import java.util.Collections;
|
||||
import java.util.Set;
|
||||
|
||||
import net.sf.acegisecurity.AuthenticationManager;
|
||||
import net.sf.acegisecurity.UserDetails;
|
||||
@@ -59,7 +61,7 @@ public class AuthenticationComponentImpl extends AbstractAuthenticationComponent
|
||||
*
|
||||
* @param authenticationDao
|
||||
*/
|
||||
@Managed(category="Security")
|
||||
@Managed(category = "Security")
|
||||
public void setAuthenticationDao(MutableAuthenticationDao authenticationDao)
|
||||
{
|
||||
this.authenticationDao = authenticationDao;
|
||||
@@ -68,13 +70,14 @@ public class AuthenticationComponentImpl extends AbstractAuthenticationComponent
|
||||
/**
|
||||
* Authenticate
|
||||
*/
|
||||
@Override
|
||||
protected void authenticateImpl(String userName, char[] password) throws AuthenticationException
|
||||
{
|
||||
try
|
||||
{
|
||||
UsernamePasswordAuthenticationToken authentication = new UsernamePasswordAuthenticationToken(userName,
|
||||
new String(password));
|
||||
authenticationManager.authenticate(authentication);
|
||||
this.authenticationManager.authenticate(authentication);
|
||||
setCurrentUser(userName);
|
||||
|
||||
}
|
||||
@@ -92,28 +95,28 @@ public class AuthenticationComponentImpl extends AbstractAuthenticationComponent
|
||||
}
|
||||
}
|
||||
|
||||
|
||||
/**
|
||||
* We actually have an acegi object so override the default method.
|
||||
*/
|
||||
@Override
|
||||
protected UserDetails getUserDetails(String userName)
|
||||
{
|
||||
return (UserDetails) authenticationDao.loadUserByUsername(userName);
|
||||
return this.authenticationDao.loadUserByUsername(userName);
|
||||
}
|
||||
|
||||
|
||||
/**
|
||||
* Get the password hash from the DAO
|
||||
*/
|
||||
@Override
|
||||
public String getMD4HashedPassword(String userName)
|
||||
{
|
||||
return authenticationDao.getMD4HashedPassword(userName);
|
||||
return this.authenticationDao.getMD4HashedPassword(userName);
|
||||
}
|
||||
|
||||
|
||||
/**
|
||||
* This implementation supported MD4 password hashes.
|
||||
*/
|
||||
@Override
|
||||
public NTLMMode getNTLMMode()
|
||||
{
|
||||
return NTLMMode.MD4_PROVIDER;
|
||||
@@ -125,5 +128,13 @@ public class AuthenticationComponentImpl extends AbstractAuthenticationComponent
|
||||
return true;
|
||||
}
|
||||
|
||||
|
||||
/*
|
||||
* (non-Javadoc)
|
||||
* @see org.alfresco.repo.security.authentication.AuthenticationComponent#getDefaultAdministratorUserNames()
|
||||
*/
|
||||
@Override
|
||||
public Set<String> getDefaultAdministratorUserNames()
|
||||
{
|
||||
return Collections.singleton(AuthenticationUtil.getAdminUserName());
|
||||
}
|
||||
}
|
||||
|
@@ -303,4 +303,13 @@ public class AuthenticationServiceImpl extends AbstractAuthenticationService
|
||||
{
|
||||
return Collections.singleton(ticketComponent);
|
||||
}
|
||||
|
||||
/*
|
||||
* (non-Javadoc)
|
||||
* @see org.alfresco.service.cmr.security.AuthenticationService#getDefaultAdministratorUserNames()
|
||||
*/
|
||||
public Set<String> getDefaultAdministratorUserNames()
|
||||
{
|
||||
return authenticationComponent.getDefaultAdministratorUserNames();
|
||||
}
|
||||
}
|
||||
|
@@ -26,6 +26,8 @@ package org.alfresco.repo.security.authentication;
|
||||
|
||||
import java.util.ArrayList;
|
||||
import java.util.List;
|
||||
import java.util.Set;
|
||||
import java.util.TreeSet;
|
||||
|
||||
import net.sf.acegisecurity.Authentication;
|
||||
|
||||
@@ -434,4 +436,17 @@ public class ChainingAuthenticationComponentImpl implements AuthenticationCompon
|
||||
}
|
||||
}
|
||||
|
||||
/*
|
||||
* (non-Javadoc)
|
||||
* @see org.alfresco.repo.security.authentication.AuthenticationComponent#getDefaultAdministratorUserNames()
|
||||
*/
|
||||
public Set<String> getDefaultAdministratorUserNames()
|
||||
{
|
||||
Set<String> defaultAdministratorUserNames = new TreeSet<String>();
|
||||
for (AuthenticationComponent authComponent : getUsableAuthenticationComponents())
|
||||
{
|
||||
defaultAdministratorUserNames.addAll(authComponent.getDefaultAdministratorUserNames());
|
||||
}
|
||||
return defaultAdministratorUserNames;
|
||||
}
|
||||
}
|
||||
|
@@ -28,6 +28,7 @@ import java.util.ArrayList;
|
||||
import java.util.HashSet;
|
||||
import java.util.List;
|
||||
import java.util.Set;
|
||||
import java.util.TreeSet;
|
||||
|
||||
import org.alfresco.service.Managed;
|
||||
import org.alfresco.service.cmr.security.AuthenticationService;
|
||||
@@ -470,4 +471,13 @@ public class ChainingAuthenticationServiceImpl extends AbstractAuthenticationSer
|
||||
return tcs;
|
||||
}
|
||||
|
||||
public Set<String> getDefaultAdministratorUserNames()
|
||||
{
|
||||
Set<String> defaultAdministratorUserNames = new TreeSet<String>();
|
||||
for (AuthenticationService authService : getUsableAuthenticationServices())
|
||||
{
|
||||
defaultAdministratorUserNames.addAll(authService.getDefaultAdministratorUserNames());
|
||||
}
|
||||
return defaultAdministratorUserNames;
|
||||
}
|
||||
}
|
||||
|
@@ -473,6 +473,11 @@ public class TestAuthenticationServiceImpl implements AuthenticationService
|
||||
return authentication;
|
||||
}
|
||||
|
||||
public Set<String> getDefaultAdministratorUserNames()
|
||||
{
|
||||
return Collections.singleton(AuthenticationUtil.getAdminUserName());
|
||||
}
|
||||
|
||||
private static final String SYSTEM_USER_NAME = "System";
|
||||
|
||||
}
|
||||
|
@@ -52,16 +52,11 @@ import org.alfresco.jlan.server.auth.passthru.PassthruServers;
|
||||
import org.alfresco.jlan.smb.Protocol;
|
||||
import org.alfresco.jlan.smb.SMBException;
|
||||
import org.alfresco.jlan.smb.SMBStatus;
|
||||
import org.alfresco.model.ContentModel;
|
||||
import org.alfresco.repo.security.authentication.AbstractAuthenticationComponent;
|
||||
import org.alfresco.repo.security.authentication.AuthenticationException;
|
||||
import org.alfresco.repo.security.authentication.NTLMMode;
|
||||
import org.alfresco.service.Managed;
|
||||
import org.alfresco.service.cmr.repository.NodeRef;
|
||||
import org.alfresco.service.cmr.repository.NodeService;
|
||||
import org.alfresco.service.cmr.security.NoSuchPersonException;
|
||||
import org.alfresco.service.cmr.security.PersonService;
|
||||
import org.alfresco.service.transaction.TransactionService;
|
||||
import org.apache.commons.logging.Log;
|
||||
import org.apache.commons.logging.LogFactory;
|
||||
|
||||
@@ -284,7 +279,8 @@ public class NTLMAuthenticationComponentImpl extends AbstractAuthenticationCompo
|
||||
*/
|
||||
@Managed(category="Security")
|
||||
public void setDomain(String domain) {
|
||||
|
||||
if (!domain.isEmpty())
|
||||
{
|
||||
// Check if the passthru server list is already configured
|
||||
|
||||
if ( m_passthruServers.getTotalServerCount() > 0)
|
||||
@@ -301,6 +297,7 @@ public class NTLMAuthenticationComponentImpl extends AbstractAuthenticationCompo
|
||||
throw new AlfrescoRuntimeException("Failed to set passthru domain, " + ex);
|
||||
}
|
||||
}
|
||||
}
|
||||
|
||||
/**
|
||||
* Set the server(s) to authenticate against
|
||||
@@ -309,16 +306,18 @@ public class NTLMAuthenticationComponentImpl extends AbstractAuthenticationCompo
|
||||
*/
|
||||
@Managed(category="Security")
|
||||
public void setServers(String servers) {
|
||||
|
||||
if (!servers.isEmpty())
|
||||
{
|
||||
// Check if the passthru server list is already configured
|
||||
|
||||
if ( m_passthruServers.getTotalServerCount() > 0)
|
||||
if (m_passthruServers.getTotalServerCount() > 0)
|
||||
throw new AlfrescoRuntimeException("Passthru server list already configured");
|
||||
|
||||
// Configure the passthru authenticaiton list using a list of server names/addresses
|
||||
|
||||
m_passthruServers.setServerList(servers);
|
||||
}
|
||||
}
|
||||
|
||||
/**
|
||||
* Use the local server as the authentication server
|
||||
|
@@ -36,6 +36,7 @@ import org.alfresco.repo.tenant.TenantService;
|
||||
import org.alfresco.service.cmr.repository.NodeRef;
|
||||
import org.alfresco.service.cmr.repository.NodeService;
|
||||
import org.alfresco.service.cmr.repository.datatype.DefaultTypeConverter;
|
||||
import org.alfresco.service.cmr.security.AuthenticationService;
|
||||
import org.alfresco.service.cmr.security.AuthorityService;
|
||||
import org.alfresco.service.cmr.security.AuthorityType;
|
||||
import org.alfresco.service.cmr.security.PermissionService;
|
||||
@@ -61,6 +62,8 @@ public class AuthorityServiceImpl implements AuthorityService, InitializingBean
|
||||
|
||||
private AuthorityDAO authorityDAO;
|
||||
|
||||
private AuthenticationService authenticationService;
|
||||
|
||||
private PermissionServiceSPI permissionServiceSPI;
|
||||
|
||||
private Set<String> adminSet = Collections.singleton(PermissionService.ADMINISTRATOR_AUTHORITY);
|
||||
@@ -69,8 +72,6 @@ public class AuthorityServiceImpl implements AuthorityService, InitializingBean
|
||||
|
||||
private Set<String> allSet = Collections.singleton(PermissionService.ALL_AUTHORITIES);
|
||||
|
||||
private Set<String> adminUsers = Collections.emptySet();
|
||||
|
||||
private Set<String> adminGroups = Collections.emptySet();
|
||||
|
||||
public AuthorityServiceImpl()
|
||||
@@ -98,6 +99,11 @@ public class AuthorityServiceImpl implements AuthorityService, InitializingBean
|
||||
this.authorityDAO = authorityDAO;
|
||||
}
|
||||
|
||||
public void setAuthenticationService(AuthenticationService authenticationService)
|
||||
{
|
||||
this.authenticationService = authenticationService;
|
||||
}
|
||||
|
||||
public void setPermissionServiceSPI(PermissionServiceSPI permissionServiceSPI)
|
||||
{
|
||||
this.permissionServiceSPI = permissionServiceSPI;
|
||||
@@ -108,11 +114,6 @@ public class AuthorityServiceImpl implements AuthorityService, InitializingBean
|
||||
logger.warn("Bean property 'authenticationService' no longer required on 'AuthorityServiceImpl'.");
|
||||
}
|
||||
|
||||
public void setAdminUsers(Set<String> adminUsers)
|
||||
{
|
||||
this.adminUsers = adminUsers;
|
||||
}
|
||||
|
||||
public void setAdminGroups(Set<String> adminGroups)
|
||||
{
|
||||
this.adminGroups = adminGroups;
|
||||
@@ -170,6 +171,8 @@ public class AuthorityServiceImpl implements AuthorityService, InitializingBean
|
||||
// Work out mapped roles
|
||||
|
||||
// Check named admin users
|
||||
Set<String> adminUsers = this.authenticationService.getDefaultAdministratorUserNames();
|
||||
|
||||
// note: for multi-tenancy, this currently relies on a naming convention which assumes that all tenant admins will
|
||||
// have the same base name as the default non-tenant specific admin. Typically "admin" is the default required admin user,
|
||||
// although, if for example "bob" is also listed as an admin then all tenant-specific bob's will also have admin authority
|
||||
|
@@ -231,5 +231,13 @@ public interface AuthenticationService
|
||||
*/
|
||||
@Auditable
|
||||
public Set<String> getDomiansThatAllowUserPasswordChanges();
|
||||
|
||||
/**
|
||||
* Gets a set of user names who should be considered administrators by default.
|
||||
*
|
||||
* @return a set of user names
|
||||
*/
|
||||
@Auditable
|
||||
public Set<String> getDefaultAdministratorUserNames();
|
||||
}
|
||||
|
||||
|
45
source/java/org/alfresco/util/AutoCommitInterceptor.java
Normal file
45
source/java/org/alfresco/util/AutoCommitInterceptor.java
Normal file
@@ -0,0 +1,45 @@
|
||||
/*
|
||||
* Copyright (C) 2005-2009 Alfresco Software Limited.
|
||||
*
|
||||
* This program is free software; you can redistribute it and/or
|
||||
* modify it under the terms of the GNU General Public License
|
||||
* as published by the Free Software Foundation; either version 2
|
||||
* of the License, or (at your option) any later version.
|
||||
|
||||
* This program is distributed in the hope that it will be useful,
|
||||
* but WITHOUT ANY WARRANTY; without even the implied warranty of
|
||||
* MERCHANTABILITY or FITNESS FOR A PARTICULAR PURPOSE. See the
|
||||
* GNU General Public License for more details.
|
||||
|
||||
* You should have received a copy of the GNU General Public License
|
||||
* along with this program; if not, write to the Free Software
|
||||
* Foundation, Inc., 51 Franklin Street, Fifth Floor, Boston, MA 02110-1301, USA.
|
||||
|
||||
* As a special exception to the terms and conditions of version 2.0 of
|
||||
* the GPL, you may redistribute this Program in connection with Free/Libre
|
||||
* and Open Source Software ("FLOSS") applications as described in Alfresco's
|
||||
* FLOSS exception. You should have received a copy of the text describing
|
||||
* the FLOSS exception, and it is also available here:
|
||||
* http://www.alfresco.com/legal/licensing"
|
||||
*/
|
||||
package org.alfresco.util;
|
||||
|
||||
import java.sql.Connection;
|
||||
|
||||
import org.aopalliance.intercept.MethodInterceptor;
|
||||
import org.aopalliance.intercept.MethodInvocation;
|
||||
|
||||
/**
|
||||
* Can be used to wrap a datasource to ensure that the connections that it returns have auto-commit switched on.
|
||||
*
|
||||
* @author dward
|
||||
*/
|
||||
public class AutoCommitInterceptor implements MethodInterceptor
|
||||
{
|
||||
public Object invoke(MethodInvocation mi) throws Throwable
|
||||
{
|
||||
Connection result = (Connection) mi.proceed();
|
||||
result.setAutoCommit(true);
|
||||
return result;
|
||||
}
|
||||
}
|
Reference in New Issue
Block a user