mirror of
https://github.com/Alfresco/alfresco-community-repo.git
synced 2025-07-24 17:32:48 +00:00
Merged V2.1 to HEAD
6466: Xml metadata. Support for pulling collections of values from XML 6470: Fix for AWC-1321 - Using zero as items per page gives error for Alfresco repos in OpenSearch 6471: Fix for AWC-1496 - OpenSearch dashlet can get in a state where search queries are not executed 6472: Fix for AWC-1495. Searching additional attributes now working correctly for folders. 6473: Fix for AR-1251 (Version error when saving new content via CIFS) 6474: Updated bundles and installers - added missing files back into Linux bundle 6475: LDAP and chainging authentication Resolved conflicted state of 'root\projects\repository\source\java\org\alfresco\repo\security\authentication\AuthenticationUtil.java' 6477: XForms WCM-696. 6478: Fix for WCM-567 (IndexOutOfBoundsException when stepping through wizard rapidly) 6480: Fix to issue when removing locks on directories. 6481: Updated installer and config wizard to fix download option and config behaviour when called from installer. 6482: Fix for WCM-1229 (properties sheet does not refresh) 6483: Fix for AR-1511 6484: Fix for AR-1351 6485: Missed a unit test update git-svn-id: https://svn.alfresco.com/repos/alfresco-enterprise/alfresco/HEAD/root@6737 c4b6b30b-aa2e-2d43-bbcb-ca4b014f7261
This commit is contained in:
@@ -74,7 +74,6 @@
|
|||||||
<!-- The authroity DAO implements an interface extended from the Acegi -->
|
<!-- The authroity DAO implements an interface extended from the Acegi -->
|
||||||
<!-- DAO that supports CRUD. -->
|
<!-- DAO that supports CRUD. -->
|
||||||
|
|
||||||
<alias name="authenticationDao" alias="alfDaoImpl"/> <!-- TODO: Remove -->
|
|
||||||
<bean id="authenticationDao" class="org.alfresco.repo.security.authentication.RepositoryAuthenticationDao">
|
<bean id="authenticationDao" class="org.alfresco.repo.security.authentication.RepositoryAuthenticationDao">
|
||||||
<property name="nodeService">
|
<property name="nodeService">
|
||||||
<ref bean="nodeService" />
|
<ref bean="nodeService" />
|
||||||
@@ -118,7 +117,6 @@
|
|||||||
<!-- The permissions service is required so that permissions can be -->
|
<!-- The permissions service is required so that permissions can be -->
|
||||||
<!-- cleaned up when a user is deleted. -->
|
<!-- cleaned up when a user is deleted. -->
|
||||||
|
|
||||||
<alias name="authenticationService" alias="authenticationServiceImpl"/> <!-- TODO: Remove -->
|
|
||||||
<bean id="authenticationService" class="org.alfresco.repo.security.authentication.AuthenticationServiceImpl">
|
<bean id="authenticationService" class="org.alfresco.repo.security.authentication.AuthenticationServiceImpl">
|
||||||
<property name="authenticationDao">
|
<property name="authenticationDao">
|
||||||
<ref bean="authenticationDao" />
|
<ref bean="authenticationDao" />
|
||||||
|
@@ -519,7 +519,7 @@
|
|||||||
<ref bean="policyComponent" />
|
<ref bean="policyComponent" />
|
||||||
</property>
|
</property>
|
||||||
<property name="authenticationService">
|
<property name="authenticationService">
|
||||||
<ref bean="authenticationServiceImpl"></ref>
|
<ref bean="authenticationService"></ref>
|
||||||
</property>
|
</property>
|
||||||
<property name="ownableService">
|
<property name="ownableService">
|
||||||
<ref bean="ownableService"></ref>
|
<ref bean="ownableService"></ref>
|
||||||
|
@@ -5,9 +5,9 @@
|
|||||||
|
|
||||||
|
|
||||||
|
|
||||||
<!-- Chaining -->
|
<!-- Chaining of both the services and components -->
|
||||||
|
|
||||||
<bean id="authenticationServiceImpl" class="org.alfresco.repo.security.authentication.ChainingAuthenticationServiceImpl">
|
<bean id="authenticationService" class="org.alfresco.repo.security.authentication.ChainingAuthenticationServiceImpl">
|
||||||
<property name="authenticationServices">
|
<property name="authenticationServices">
|
||||||
<list>
|
<list>
|
||||||
<ref bean="authenticationServiceImplJAAS"/>
|
<ref bean="authenticationServiceImplJAAS"/>
|
||||||
@@ -18,6 +18,17 @@
|
|||||||
</property>
|
</property>
|
||||||
</bean>
|
</bean>
|
||||||
|
|
||||||
|
<bean id="authenticationComponent" class="org.alfresco.repo.security.authentication.ChainingAuthenticationComponentImpl">
|
||||||
|
<property name="authenticationComponentss">
|
||||||
|
<list>
|
||||||
|
<ref bean="authenticationComponentImplJAAS"/>
|
||||||
|
</list>
|
||||||
|
</property>
|
||||||
|
<property name="mutableAuthenticationComponent">
|
||||||
|
<ref bean="authenticationComponentImplAlfresco"/>
|
||||||
|
</property>
|
||||||
|
</bean>
|
||||||
|
|
||||||
<!-- Alfresco Auth -->
|
<!-- Alfresco Auth -->
|
||||||
|
|
||||||
<bean id="authenticationServiceImplAlfresco" class="org.alfresco.repo.security.authentication.AuthenticationServiceImpl">
|
<bean id="authenticationServiceImplAlfresco" class="org.alfresco.repo.security.authentication.AuthenticationServiceImpl">
|
||||||
|
@@ -3,6 +3,17 @@
|
|||||||
|
|
||||||
<beans>
|
<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. -->
|
<!-- 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 name="authenticationDao" class="org.alfresco.repo.security.authentication.DefaultMutableAuthenticationDao" >
|
<bean name="authenticationDao" class="org.alfresco.repo.security.authentication.DefaultMutableAuthenticationDao" >
|
||||||
@@ -34,11 +45,11 @@
|
|||||||
"%s" - the user id is passed through without modification.
|
"%s" - the user id is passed through without modification.
|
||||||
Used for LDAP authentication such as DIGEST-MD5, anything that is not "simple".
|
Used for LDAP authentication such as DIGEST-MD5, anything that is not "simple".
|
||||||
|
|
||||||
"cn=%s,ou=London,dc=company,dc=com" - If the user types in "Joe Bloggs" the authentricate as "cn=Joe Bloggs,ou=London,dc=company,dc=com"
|
"cn=%s,ou=London,dc=company,dc=com" - If the user types in "Joe Bloggs" the authenticate as "cn=Joe Bloggs,ou=London,dc=company,dc=com"
|
||||||
Usually for simple authentication.
|
Usually for simple authentication. Simple authentication always uses the DN for the user.
|
||||||
|
|
||||||
-->
|
-->
|
||||||
<value>%s</value>
|
<value>${ldap.authentication.userNameFormat}</value>
|
||||||
</property>
|
</property>
|
||||||
</bean>
|
</bean>
|
||||||
|
|
||||||
@@ -54,14 +65,14 @@
|
|||||||
<map>
|
<map>
|
||||||
<!-- The LDAP provider -->
|
<!-- The LDAP provider -->
|
||||||
<entry key="java.naming.factory.initial">
|
<entry key="java.naming.factory.initial">
|
||||||
<value>com.sun.jndi.ldap.LdapCtxFactory</value>
|
<value>${ldap.authentication.java.naming.factory.initial}</value>
|
||||||
</entry>
|
</entry>
|
||||||
|
|
||||||
<!-- The url to the LDAP server -->
|
<!-- The url to the LDAP server -->
|
||||||
<!-- Note you can use space separated urls - they will be tried in turn until one works -->
|
<!-- 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 ....) -->
|
<!-- This could be used to authenticate against one or more ldap servers (you will not know which one ....) -->
|
||||||
<entry key="java.naming.provider.url">
|
<entry key="java.naming.provider.url">
|
||||||
<value>ldap://openldap.domain.com:389</value>
|
<value>${ldap.authentication.java.naming.provider.url}</value>
|
||||||
</entry>
|
</entry>
|
||||||
|
|
||||||
<!-- The authentication mechanism to use -->
|
<!-- The authentication mechanism to use -->
|
||||||
@@ -69,390 +80,21 @@
|
|||||||
<!-- java.naming.security.sasl.realm -->
|
<!-- java.naming.security.sasl.realm -->
|
||||||
<!-- The available options will depend on your LDAP provider -->
|
<!-- The available options will depend on your LDAP provider -->
|
||||||
<entry key="java.naming.security.authentication">
|
<entry key="java.naming.security.authentication">
|
||||||
<value>DIGEST-MD5</value>
|
<value>${ldap.authentication.java.naming.security.authentication}</value>
|
||||||
</entry>
|
</entry>
|
||||||
|
|
||||||
<!-- The id of a user who can read group and user information -->
|
<!-- 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" -->
|
<!-- This does not go through the pattern substitution defined above and is used "as is" -->
|
||||||
<entry key="java.naming.security.principal">
|
<entry key="java.naming.security.principal">
|
||||||
<value>reader</value>
|
<value>${ldap.authentication.java.naming.security.principal}</value>
|
||||||
</entry>
|
</entry>
|
||||||
|
|
||||||
<!-- The password for the user defined above -->
|
<!-- The password for the user defined above -->
|
||||||
<entry key="java.naming.security.credentials">
|
<entry key="java.naming.security.credentials">
|
||||||
<value>secret</value>
|
<value>${ldap.authentication.java.naming.security.credentials}</value>
|
||||||
</entry>
|
</entry>
|
||||||
</map>
|
</map>
|
||||||
</property>
|
</property>
|
||||||
</bean>
|
</bean>
|
||||||
|
|
||||||
<!-- Ldap Syncronisation support -->
|
|
||||||
|
|
||||||
<!--
|
|
||||||
|
|
||||||
There can be more than one stack of beans that import users or groups. For example, it may be easier
|
|
||||||
to have a version of ldapPeopleExportSource, and associated beans, for each sub-tree of your ldap directory
|
|
||||||
from which you want to import users. You could then limit users to be imported from two or more sub tress and ignore
|
|
||||||
users found else where. The same applies to the import of groups.
|
|
||||||
|
|
||||||
The defaults shown below are for OpenLDAP.
|
|
||||||
|
|
||||||
-->
|
|
||||||
|
|
||||||
|
|
||||||
<!-- Extract user information from LDAP and transform this to XML -->
|
|
||||||
|
|
||||||
<bean id="ldapPeopleExportSource" class="org.alfresco.repo.security.authentication.ldap.LDAPPersonExportSource">
|
|
||||||
<!--
|
|
||||||
The query to select objects that represent the users to import.
|
|
||||||
|
|
||||||
For Open LDAP, using a basic schema, the following is probably what you want:
|
|
||||||
(objectclass=inetOrgPerson)
|
|
||||||
|
|
||||||
For Active Directory:
|
|
||||||
(objectclass=user)
|
|
||||||
-->
|
|
||||||
<property name="personQuery">
|
|
||||||
<value>(objectclass=inetOrgPerson)</value>
|
|
||||||
</property>
|
|
||||||
|
|
||||||
<!--
|
|
||||||
The seach base restricts the LDAP query to a sub section of tree on the LDAP server.
|
|
||||||
-->
|
|
||||||
<property name="searchBase">
|
|
||||||
<value>dc=alfresco,dc=org</value>
|
|
||||||
</property>
|
|
||||||
|
|
||||||
<!--
|
|
||||||
The unique identifier for the user.
|
|
||||||
|
|
||||||
THIS MUST MATCH WHAT THE USER TYPES IN AT THE LOGIN PROMPT
|
|
||||||
|
|
||||||
For simple LDAP authentication this is likely to be "cn" or, less friendly, "distinguishedName"
|
|
||||||
|
|
||||||
In OpenLDAP, using other authentication mechanisms "uid", but this depends on how you map
|
|
||||||
from the id in the LDAP authentication request to search for the inetOrgPerson against which
|
|
||||||
to authenticate.
|
|
||||||
|
|
||||||
In Active Directory this is most likely to be "sAMAccountName"
|
|
||||||
|
|
||||||
This property is mandatory and must appear on all users found by the query defined above.
|
|
||||||
|
|
||||||
-->
|
|
||||||
<property name="userIdAttributeName">
|
|
||||||
<value>uid</value>
|
|
||||||
</property>
|
|
||||||
|
|
||||||
<!-- Services -->
|
|
||||||
<property name="LDAPInitialDirContextFactory">
|
|
||||||
<ref bean="ldapInitialDirContextFactory"/>
|
|
||||||
</property>
|
|
||||||
<property name="personService">
|
|
||||||
<ref bean="personService"></ref>
|
|
||||||
</property>
|
|
||||||
<property name="namespaceService">
|
|
||||||
<ref bean="namespaceService"/>
|
|
||||||
</property>
|
|
||||||
|
|
||||||
<!--
|
|
||||||
This property defines a mapping between attributes held on LDAP user objects and
|
|
||||||
the properties of user objects held in the repository. The key is the QName of an attribute in
|
|
||||||
the repository, the value is the attribute name from the user/inetOrgPerson/.. object in the
|
|
||||||
LDAP repository.
|
|
||||||
-->
|
|
||||||
<property name="attributeMapping">
|
|
||||||
<map>
|
|
||||||
<entry key="cm:userName">
|
|
||||||
<!-- Must match the same attribute as userIdAttributeName -->
|
|
||||||
<value>uid</value>
|
|
||||||
</entry>
|
|
||||||
<entry key="cm:firstName">
|
|
||||||
<!-- OpenLDAP: "givenName" -->
|
|
||||||
<!-- Active Directory: "givenName" -->
|
|
||||||
<value>givenName</value>
|
|
||||||
</entry>
|
|
||||||
<entry key="cm:lastName">
|
|
||||||
<!-- OpenLDAP: "sn" -->
|
|
||||||
<!-- Active Directory: "sn" -->
|
|
||||||
<value>sn</value>
|
|
||||||
</entry>
|
|
||||||
<entry key="cm:email">
|
|
||||||
<!-- OpenLDAP: "mail" -->
|
|
||||||
<!-- Active Directory: "???" -->
|
|
||||||
<value>mail</value>
|
|
||||||
</entry>
|
|
||||||
<entry key="cm:organizationId">
|
|
||||||
<!-- OpenLDAP: "o" -->
|
|
||||||
<!-- Active Directory: "???" -->
|
|
||||||
<value>o</value>
|
|
||||||
</entry>
|
|
||||||
<!-- Always use the default -->
|
|
||||||
<entry key="cm:homeFolderProvider">
|
|
||||||
<null/>
|
|
||||||
</entry>
|
|
||||||
</map>
|
|
||||||
</property>
|
|
||||||
<!-- Set a default home folder provider -->
|
|
||||||
<!-- Defaults only apply for values above -->
|
|
||||||
<property name="attributeDefaults">
|
|
||||||
<map>
|
|
||||||
<entry key="cm:homeFolderProvider">
|
|
||||||
<value>personalHomeFolderProvider</value>
|
|
||||||
</entry>
|
|
||||||
</map>
|
|
||||||
</property>
|
|
||||||
</bean>
|
|
||||||
|
|
||||||
<!-- Extract group information from LDAP and transform this to XML -->
|
|
||||||
|
|
||||||
<bean id="ldapGroupExportSource" class="org.alfresco.repo.security.authentication.ldap.LDAPGroupExportSource">
|
|
||||||
<!--
|
|
||||||
The query to select objects that represent the groups to import.
|
|
||||||
|
|
||||||
For Open LDAP, using a basic schema, the following is probably what you want:
|
|
||||||
(objectclass=groupOfNames)
|
|
||||||
|
|
||||||
For Active Directory:
|
|
||||||
(objectclass=group)
|
|
||||||
-->
|
|
||||||
<property name="groupQuery">
|
|
||||||
<value>(objectclass=groupOfNames)</value>
|
|
||||||
</property>
|
|
||||||
|
|
||||||
<!--
|
|
||||||
The seach base restricts the LDAP query to a sub section of tree on the LDAP server.
|
|
||||||
-->
|
|
||||||
<property name="searchBase">
|
|
||||||
<value>dc=alfresco,dc=org</value>
|
|
||||||
</property>
|
|
||||||
|
|
||||||
<!--
|
|
||||||
The unique identifier for the user. This must match the userIdAttributeName on the ldapPeopleExportSource bean above.
|
|
||||||
-->
|
|
||||||
<property name="userIdAttributeName">
|
|
||||||
<value>uid</value>
|
|
||||||
</property>
|
|
||||||
|
|
||||||
<!--
|
|
||||||
An attribute that is a unique identifier for each group found.
|
|
||||||
This is also the name of the group with the current group implementation.
|
|
||||||
This is mandatory for any groups found.
|
|
||||||
|
|
||||||
OpenLDAP: "cn" as it is mandatory on groupOfNames
|
|
||||||
Active Directory: "cn"
|
|
||||||
|
|
||||||
-->
|
|
||||||
<property name="groupIdAttributeName">
|
|
||||||
<value>cn</value>
|
|
||||||
</property>
|
|
||||||
|
|
||||||
<!--
|
|
||||||
The objectClass attribute for group members.
|
|
||||||
For each member of a group, the distinguished name is given.
|
|
||||||
The object is looked up by its DN. If the object is of this class it is treated as a group.
|
|
||||||
-->
|
|
||||||
<property name="groupType">
|
|
||||||
<value>groupOfNames</value>
|
|
||||||
</property>
|
|
||||||
|
|
||||||
<!--
|
|
||||||
The objectClass attribute for person members.
|
|
||||||
For each member of a group, the distinguished name is given.
|
|
||||||
The object is looked up by its DN. If the object is of this class it is treated as a person.
|
|
||||||
-->
|
|
||||||
<property name="personType">
|
|
||||||
<value>inetOrgPerson</value>
|
|
||||||
</property>
|
|
||||||
<property name="LDAPInitialDirContextFactory">
|
|
||||||
<ref bean="ldapInitialDirContextFactory"/>
|
|
||||||
</property>
|
|
||||||
<property name="namespaceService">
|
|
||||||
<ref bean="namespaceService"/>
|
|
||||||
</property>
|
|
||||||
|
|
||||||
<!--
|
|
||||||
The repeating attribute on group objects (found by query or as sub groups)
|
|
||||||
used to define membership of the group. This is assumed to hold distinguished names of
|
|
||||||
other groups or users/people; the above types are used to determine this.
|
|
||||||
|
|
||||||
OpenLDAP: "member" as it is mandatory on groupOfNames
|
|
||||||
Active Directory: "member"
|
|
||||||
|
|
||||||
-->
|
|
||||||
<property name="memberAttribute">
|
|
||||||
<value>member</value>
|
|
||||||
</property>
|
|
||||||
|
|
||||||
<property name="authorityDAO">
|
|
||||||
<ref bean="authorityDAO"/>
|
|
||||||
</property>
|
|
||||||
</bean>
|
|
||||||
|
|
||||||
<!-- Job definitions to import LDAP people and groups -->
|
|
||||||
<!-- The triggers register themselves with the scheduler -->
|
|
||||||
<!-- You may comment in the default scheduler to enable these triggers -->
|
|
||||||
<!-- If a cron base trigger is what you want seee scheduled-jobs-context.xml for examples. -->
|
|
||||||
|
|
||||||
<!-- Trigger to load poeple -->
|
|
||||||
<!-- Note you can have more than one initial (context, trigger, import job and export source) set -->
|
|
||||||
<!-- This would allow you to load people from more than one ldap store -->
|
|
||||||
|
|
||||||
<bean id="ldapPeopleTrigger" class="org.alfresco.util.TriggerBean">
|
|
||||||
<property name="jobDetail">
|
|
||||||
<bean id="ldapPeopleJobDetail" class="org.springframework.scheduling.quartz.JobDetailBean">
|
|
||||||
<property name="jobClass">
|
|
||||||
<value>org.alfresco.repo.importer.ImporterJob</value>
|
|
||||||
</property>
|
|
||||||
<property name="jobDataAsMap">
|
|
||||||
<map>
|
|
||||||
<entry key="bean">
|
|
||||||
<ref bean="ldapPeopleImport"/>
|
|
||||||
</entry>
|
|
||||||
</map>
|
|
||||||
</property>
|
|
||||||
</bean>
|
|
||||||
</property>
|
|
||||||
<!-- Start after 5 minutes of starting the repository -->
|
|
||||||
<property name="startDelay">
|
|
||||||
<value>300000</value>
|
|
||||||
</property>
|
|
||||||
<!-- Repeat every hour -->
|
|
||||||
<property name="repeatInterval">
|
|
||||||
<value>3600000</value>
|
|
||||||
</property>
|
|
||||||
<!-- Commented out to disable
|
|
||||||
<property name="scheduler">
|
|
||||||
<ref bean="schedulerFactory" />
|
|
||||||
</property>
|
|
||||||
-->
|
|
||||||
</bean>
|
|
||||||
|
|
||||||
<bean id="ldapGroupTrigger" class="org.alfresco.util.TriggerBean">
|
|
||||||
<property name="jobDetail">
|
|
||||||
<bean id="ldapGroupJobDetail" class="org.springframework.scheduling.quartz.JobDetailBean">
|
|
||||||
<property name="jobClass">
|
|
||||||
<value>org.alfresco.repo.importer.ImporterJob</value>
|
|
||||||
</property>
|
|
||||||
<property name="jobDataAsMap">
|
|
||||||
<map>
|
|
||||||
<entry key="bean">
|
|
||||||
<ref bean="ldapGroupImport"/>
|
|
||||||
</entry>
|
|
||||||
</map>
|
|
||||||
</property>
|
|
||||||
</bean>
|
|
||||||
</property>
|
|
||||||
<!-- Start after 5 minutes of starting the repository -->
|
|
||||||
<property name="startDelay">
|
|
||||||
<value>300000</value>
|
|
||||||
</property>
|
|
||||||
<!-- Repeat every hour -->
|
|
||||||
<property name="repeatInterval">
|
|
||||||
<value>3600000</value>
|
|
||||||
</property>
|
|
||||||
<!-- Commented out to disable
|
|
||||||
<property name="scheduler">
|
|
||||||
<ref bean="schedulerFactory" />
|
|
||||||
</property>
|
|
||||||
-->
|
|
||||||
</bean>
|
|
||||||
|
|
||||||
<!-- The bean that imports xml describing people -->
|
|
||||||
|
|
||||||
<bean id="ldapPeopleImport" class="org.alfresco.repo.importer.ExportSourceImporter">
|
|
||||||
<property name="importerService">
|
|
||||||
<ref bean="importerComponentWithBehaviour"/>
|
|
||||||
</property>
|
|
||||||
<property name="transactionService">
|
|
||||||
<ref bean="transactionComponent"/>
|
|
||||||
</property>
|
|
||||||
<property name="authenticationComponent">
|
|
||||||
<ref bean="authenticationComponent"/>
|
|
||||||
</property>
|
|
||||||
<property name="exportSource">
|
|
||||||
<ref bean="ldapPeopleExportSource"/>
|
|
||||||
</property>
|
|
||||||
|
|
||||||
<!-- The store that contains people - this should not be changed -->
|
|
||||||
<property name="storeRef">
|
|
||||||
<value>${spaces.store}</value>
|
|
||||||
</property>
|
|
||||||
|
|
||||||
<!-- The location of people nodes within the store defined above - this should not be changed -->
|
|
||||||
<property name="path">
|
|
||||||
<value>/${system.system_container.childname}/${system.people_container.childname}</value>
|
|
||||||
</property>
|
|
||||||
|
|
||||||
<!-- If true, clear all existing people before import, if false update/add people from the xml -->
|
|
||||||
<property name="clearAllChildren">
|
|
||||||
<value>false</value>
|
|
||||||
</property>
|
|
||||||
<property name="nodeService">
|
|
||||||
<ref bean="nodeService"/>
|
|
||||||
</property>
|
|
||||||
<property name="searchService">
|
|
||||||
<ref bean="searchService"/>
|
|
||||||
</property>
|
|
||||||
<property name="namespacePrefixResolver">
|
|
||||||
<ref bean="namespaceService"/>
|
|
||||||
</property>
|
|
||||||
|
|
||||||
|
|
||||||
<property name="caches">
|
|
||||||
<set>
|
|
||||||
<ref bean="permissionsAccessCache"/>
|
|
||||||
</set>
|
|
||||||
</property>
|
|
||||||
</bean>
|
|
||||||
|
|
||||||
<!-- The bean that imports xml descibing groups -->
|
|
||||||
|
|
||||||
<bean id="ldapGroupImport" class="org.alfresco.repo.importer.ExportSourceImporter">
|
|
||||||
<property name="importerService">
|
|
||||||
<ref bean="importerComponentWithBehaviour"/>
|
|
||||||
</property>
|
|
||||||
<property name="transactionService">
|
|
||||||
<ref bean="transactionComponent"/>
|
|
||||||
</property>
|
|
||||||
<property name="authenticationComponent">
|
|
||||||
<ref bean="authenticationComponent"/>
|
|
||||||
</property>
|
|
||||||
<property name="exportSource">
|
|
||||||
<ref bean="ldapGroupExportSource"/>
|
|
||||||
</property>
|
|
||||||
<!-- The store that contains group information - this should not be changed -->
|
|
||||||
<property name="storeRef">
|
|
||||||
<value>${alfresco_user_store.store}</value>
|
|
||||||
</property>
|
|
||||||
|
|
||||||
<!-- The location of group information in the store above - this should not be changed -->
|
|
||||||
<property name="path">
|
|
||||||
<value>/${alfresco_user_store.system_container.childname}/${alfresco_user_store.authorities_container.childname}</value>
|
|
||||||
</property>
|
|
||||||
|
|
||||||
<!-- If true, clear all existing groups before import, if false update/add groups from the xml -->
|
|
||||||
<property name="clearAllChildren">
|
|
||||||
<value>true</value>
|
|
||||||
</property>
|
|
||||||
<property name="nodeService">
|
|
||||||
<ref bean="nodeService"/>
|
|
||||||
</property>
|
|
||||||
<property name="searchService">
|
|
||||||
<ref bean="searchService"/>
|
|
||||||
</property>
|
|
||||||
<property name="namespacePrefixResolver">
|
|
||||||
<ref bean="namespaceService"/>
|
|
||||||
</property>
|
|
||||||
|
|
||||||
<!-- caches to clear on import of groups -->
|
|
||||||
<property name="caches">
|
|
||||||
<set>
|
|
||||||
<ref bean="userToAuthorityCache"/>
|
|
||||||
<ref bean="permissionsAccessCache"/>
|
|
||||||
</set>
|
|
||||||
</property>
|
|
||||||
|
|
||||||
<!-- userToAuthorityCache -->
|
|
||||||
</bean>
|
|
||||||
|
|
||||||
</beans>
|
</beans>
|
27
config/alfresco/extension/ldap-authentication.properties
Normal file
27
config/alfresco/extension/ldap-authentication.properties
Normal file
@@ -0,0 +1,27 @@
|
|||||||
|
#
|
||||||
|
# This properties file brings together the common options for LDAP authentication rather than editing the bean definitions
|
||||||
|
#
|
||||||
|
|
||||||
|
# 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
|
||||||
|
# CN=%s,DC=company,DC=com
|
||||||
|
# - digest
|
||||||
|
# - usually pass through what is entered
|
||||||
|
# %s
|
||||||
|
ldap.authentication.userNameFormat=%s
|
||||||
|
|
||||||
|
# The LDAP context factory to use
|
||||||
|
ldap.authentication.java.naming.factory.initial=com.sun.jndi.ldap.LdapCtxFactory
|
||||||
|
|
||||||
|
# The URL to connect to the LDAP server
|
||||||
|
ldap.authentication.java.naming.provider.url=ldap://openldap.domain.com:389
|
||||||
|
|
||||||
|
# The authentication mechanism to use
|
||||||
|
ldap.authentication.java.naming.security.authentication=DIGEST-MD5
|
||||||
|
|
||||||
|
# The default principal to use (only used for LDAP sync)
|
||||||
|
ldap.authentication.java.naming.security.principal=reader
|
||||||
|
|
||||||
|
# The password for the default principal (only used for LDAP sync)
|
||||||
|
ldap.authentication.java.naming.security.credentials=secret
|
@@ -0,0 +1,377 @@
|
|||||||
|
<?xml version='1.0' encoding='UTF-8'?>
|
||||||
|
<!DOCTYPE beans PUBLIC '-//SPRING//DTD BEAN//EN' 'http://www.springframework.org/dtd/spring-beans.dtd'>
|
||||||
|
|
||||||
|
<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
|
||||||
|
-->
|
||||||
|
|
||||||
|
<alias alias="ldapSyncInitialDirContextFactory" name="ldapInitialDirContextFactory"/>
|
||||||
|
|
||||||
|
<!-- Ldap Syncronisation support -->
|
||||||
|
|
||||||
|
<!--
|
||||||
|
|
||||||
|
There can be more than one stack of beans that import users or groups. For example, it may be easier
|
||||||
|
to have a version of ldapPeopleExportSource, and associated beans, for each sub-tree of your ldap directory
|
||||||
|
from which you want to import users. You could then limit users to be imported from two or more sub tress and ignore
|
||||||
|
users found else where. The same applies to the import of groups.
|
||||||
|
|
||||||
|
The defaults shown below are for OpenLDAP.
|
||||||
|
|
||||||
|
-->
|
||||||
|
|
||||||
|
|
||||||
|
<!-- Extract user information from LDAP and transform this to XML -->
|
||||||
|
|
||||||
|
<bean id="ldapPeopleExportSource" class="org.alfresco.repo.security.authentication.ldap.LDAPPersonExportSource">
|
||||||
|
<!--
|
||||||
|
The query to select objects that represent the users to import.
|
||||||
|
|
||||||
|
For Open LDAP, using a basic schema, the following is probably what you want:
|
||||||
|
(objectclass=inetOrgPerson)
|
||||||
|
|
||||||
|
For Active Directory:
|
||||||
|
(objectclass=user)
|
||||||
|
-->
|
||||||
|
<property name="personQuery">
|
||||||
|
<value>${ldap.synchronisation.personQuery}</value>
|
||||||
|
</property>
|
||||||
|
|
||||||
|
<!--
|
||||||
|
The seach base restricts the LDAP query to a sub section of tree on the LDAP server.
|
||||||
|
-->
|
||||||
|
<property name="searchBase">
|
||||||
|
<value>${ldap.synchronisation.personSearchBase}</value>
|
||||||
|
</property>
|
||||||
|
|
||||||
|
<!--
|
||||||
|
The unique identifier for the user.
|
||||||
|
|
||||||
|
THIS MUST MATCH WHAT THE USER TYPES IN AT THE LOGIN PROMPT
|
||||||
|
|
||||||
|
For simple LDAP authentication this is likely to be "cn" or, less friendly, "distinguishedName"
|
||||||
|
|
||||||
|
In OpenLDAP, using other authentication mechanisms "uid", but this depends on how you map
|
||||||
|
from the id in the LDAP authentication request to search for the inetOrgPerson against which
|
||||||
|
to authenticate.
|
||||||
|
|
||||||
|
In Active Directory this is most likely to be "sAMAccountName"
|
||||||
|
|
||||||
|
This property is mandatory and must appear on all users found by the query defined above.
|
||||||
|
|
||||||
|
-->
|
||||||
|
<property name="userIdAttributeName">
|
||||||
|
<value>${ldap.synchronisation.userIdAttributeName]</value>
|
||||||
|
</property>
|
||||||
|
|
||||||
|
<!-- Services -->
|
||||||
|
<property name="LDAPInitialDirContextFactory">
|
||||||
|
<ref bean="ldapSyncInitialDirContextFactory"/>
|
||||||
|
</property>
|
||||||
|
<property name="personService">
|
||||||
|
<ref bean="personService"></ref>
|
||||||
|
</property>
|
||||||
|
<property name="namespaceService">
|
||||||
|
<ref bean="namespaceService"/>
|
||||||
|
</property>
|
||||||
|
|
||||||
|
<!--
|
||||||
|
This property defines a mapping between attributes held on LDAP user objects and
|
||||||
|
the properties of user objects held in the repository. The key is the QName of an attribute in
|
||||||
|
the repository, the value is the attribute name from the user/inetOrgPerson/.. object in the
|
||||||
|
LDAP repository.
|
||||||
|
-->
|
||||||
|
<property name="attributeMapping">
|
||||||
|
<map>
|
||||||
|
<entry key="cm:userName">
|
||||||
|
<!-- Must match the same attribute as userIdAttributeName -->
|
||||||
|
<value>${ldap.synchronisation.userIdAttributeName}</value>
|
||||||
|
</entry>
|
||||||
|
<entry key="cm:firstName">
|
||||||
|
<!-- OpenLDAP: "givenName" -->
|
||||||
|
<!-- Active Directory: "givenName" -->
|
||||||
|
<value>${ldap.synchronisation.userFirstNameAttributeName}</value>
|
||||||
|
</entry>
|
||||||
|
<entry key="cm:lastName">
|
||||||
|
<!-- OpenLDAP: "sn" -->
|
||||||
|
<!-- Active Directory: "sn" -->
|
||||||
|
<value>${ldap.synchronisation.userLastNameAttributeName}</value>
|
||||||
|
</entry>
|
||||||
|
<entry key="cm:email">
|
||||||
|
<!-- OpenLDAP: "mail" -->
|
||||||
|
<!-- Active Directory: "???" -->
|
||||||
|
<value>${ldap.synchronisation.userEmailAttributeName}</value>
|
||||||
|
</entry>
|
||||||
|
<entry key="cm:organizationId">
|
||||||
|
<!-- OpenLDAP: "o" -->
|
||||||
|
<!-- Active Directory: "???" -->
|
||||||
|
<value>${ldap.synchronisation.userOrganizationalIdAttributeName}</value>
|
||||||
|
</entry>
|
||||||
|
<!-- Always use the default -->
|
||||||
|
<entry key="cm:homeFolderProvider">
|
||||||
|
<null/>
|
||||||
|
</entry>
|
||||||
|
</map>
|
||||||
|
</property>
|
||||||
|
<!-- Set a default home folder provider -->
|
||||||
|
<!-- Defaults only apply for values above -->
|
||||||
|
<property name="attributeDefaults">
|
||||||
|
<map>
|
||||||
|
<entry key="cm:homeFolderProvider">
|
||||||
|
<value>${ldap.synchronisation.defaultHomeFolderProvider}</value>
|
||||||
|
</entry>
|
||||||
|
</map>
|
||||||
|
</property>
|
||||||
|
</bean>
|
||||||
|
|
||||||
|
<!-- Extract group information from LDAP and transform this to XML -->
|
||||||
|
|
||||||
|
<bean id="ldapGroupExportSource" class="org.alfresco.repo.security.authentication.ldap.LDAPGroupExportSource">
|
||||||
|
<!--
|
||||||
|
The query to select objects that represent the groups to import.
|
||||||
|
|
||||||
|
For Open LDAP, using a basic schema, the following is probably what you want:
|
||||||
|
(objectclass=groupOfNames)
|
||||||
|
|
||||||
|
For Active Directory:
|
||||||
|
(objectclass=group)
|
||||||
|
-->
|
||||||
|
<property name="groupQuery">
|
||||||
|
<value>${ldap.synchronisation.groupQuery}</value>
|
||||||
|
</property>
|
||||||
|
|
||||||
|
<!--
|
||||||
|
The seach base restricts the LDAP query to a sub section of tree on the LDAP server.
|
||||||
|
-->
|
||||||
|
<property name="searchBase">
|
||||||
|
<value>${ldap.synchronisation.groupSearchBase}</value>
|
||||||
|
</property>
|
||||||
|
|
||||||
|
<!--
|
||||||
|
The unique identifier for the user. This must match the userIdAttributeName on the ldapPeopleExportSource bean above.
|
||||||
|
-->
|
||||||
|
<property name="userIdAttributeName">
|
||||||
|
<value>${ldap.synchronisation.userIdAttributeName}</value>
|
||||||
|
</property>
|
||||||
|
|
||||||
|
<!--
|
||||||
|
An attribute that is a unique identifier for each group found.
|
||||||
|
This is also the name of the group with the current group implementation.
|
||||||
|
This is mandatory for any groups found.
|
||||||
|
|
||||||
|
OpenLDAP: "cn" as it is mandatory on groupOfNames
|
||||||
|
Active Directory: "cn"
|
||||||
|
|
||||||
|
-->
|
||||||
|
<property name="groupIdAttributeName">
|
||||||
|
<value>${ldap.synchronisation.groupIdAttributeName}</value>
|
||||||
|
</property>
|
||||||
|
|
||||||
|
<!--
|
||||||
|
The objectClass attribute for group members.
|
||||||
|
For each member of a group, the distinguished name is given.
|
||||||
|
The object is looked up by its DN. If the object is of this class it is treated as a group.
|
||||||
|
-->
|
||||||
|
<property name="groupType">
|
||||||
|
<value>${ldap.synchronisation.groupType}</value>
|
||||||
|
</property>
|
||||||
|
|
||||||
|
<!--
|
||||||
|
The objectClass attribute for person members.
|
||||||
|
For each member of a group, the distinguished name is given.
|
||||||
|
The object is looked up by its DN. If the object is of this class it is treated as a person.
|
||||||
|
-->
|
||||||
|
<property name="personType">
|
||||||
|
<value>${ldap.synchronisation.personType}</value>
|
||||||
|
</property>
|
||||||
|
<property name="LDAPInitialDirContextFactory">
|
||||||
|
<ref bean="ldapSyncInitialDirContextFactory"/>
|
||||||
|
</property>
|
||||||
|
<property name="namespaceService">
|
||||||
|
<ref bean="namespaceService"/>
|
||||||
|
</property>
|
||||||
|
|
||||||
|
<!--
|
||||||
|
The repeating attribute on group objects (found by query or as sub groups)
|
||||||
|
used to define membership of the group. This is assumed to hold distinguished names of
|
||||||
|
other groups or users/people; the above types are used to determine this.
|
||||||
|
|
||||||
|
OpenLDAP: "member" as it is mandatory on groupOfNames
|
||||||
|
Active Directory: "member"
|
||||||
|
|
||||||
|
-->
|
||||||
|
<property name="memberAttribute">
|
||||||
|
<value>${ldap.synchronisation.groupMemberAttributeName}</value>
|
||||||
|
</property>
|
||||||
|
|
||||||
|
<property name="authorityDAO">
|
||||||
|
<ref bean="authorityDAO"/>
|
||||||
|
</property>
|
||||||
|
</bean>
|
||||||
|
|
||||||
|
<!-- Job definitions to import LDAP people and groups -->
|
||||||
|
<!-- The triggers register themselves with the scheduler -->
|
||||||
|
<!-- You may comment in the default scheduler to enable these triggers -->
|
||||||
|
<!-- If a cron base trigger is what you want seee scheduled-jobs-context.xml for examples. -->
|
||||||
|
|
||||||
|
<!-- Trigger to load poeple -->
|
||||||
|
<!-- Note you can have more than one initial (context, trigger, import job and export source) set -->
|
||||||
|
<!-- This would allow you to load people from more than one ldap store -->
|
||||||
|
|
||||||
|
<bean id="ldapPeopleTrigger" class="org.alfresco.util.CronTriggerBean">
|
||||||
|
<property name="jobDetail">
|
||||||
|
<bean id="ldapPeopleJobDetail" class="org.springframework.scheduling.quartz.JobDetailBean">
|
||||||
|
<property name="jobClass">
|
||||||
|
<value>org.alfresco.repo.importer.ImporterJob</value>
|
||||||
|
</property>
|
||||||
|
<property name="jobDataAsMap">
|
||||||
|
<map>
|
||||||
|
<entry key="bean">
|
||||||
|
<ref bean="ldapPeopleImport"/>
|
||||||
|
</entry>
|
||||||
|
</map>
|
||||||
|
</property>
|
||||||
|
</bean>
|
||||||
|
</property>
|
||||||
|
<property name="cronExpression">
|
||||||
|
<value>${ldap.synchronisation.import.person.cron}</value>
|
||||||
|
</property>
|
||||||
|
<property name="scheduler">
|
||||||
|
<ref bean="schedulerFactory" />
|
||||||
|
</property>
|
||||||
|
</bean>
|
||||||
|
|
||||||
|
<bean id="ldapGroupTrigger" class="org.alfresco.util.CronTriggerBean">
|
||||||
|
<property name="jobDetail">
|
||||||
|
<bean id="ldapGroupJobDetail" class="org.springframework.scheduling.quartz.JobDetailBean">
|
||||||
|
<property name="jobClass">
|
||||||
|
<value>org.alfresco.repo.importer.ImporterJob</value>
|
||||||
|
</property>
|
||||||
|
<property name="jobDataAsMap">
|
||||||
|
<map>
|
||||||
|
<entry key="bean">
|
||||||
|
<ref bean="ldapGroupImport"/>
|
||||||
|
</entry>
|
||||||
|
</map>
|
||||||
|
</property>
|
||||||
|
</bean>
|
||||||
|
</property>
|
||||||
|
<property name="cronExpression">
|
||||||
|
<value>${ldap.synchronisation.import.group.cron}</value>
|
||||||
|
</property>
|
||||||
|
<property name="scheduler">
|
||||||
|
<ref bean="schedulerFactory" />
|
||||||
|
</property>
|
||||||
|
</bean>
|
||||||
|
|
||||||
|
<!-- The bean that imports xml describing people -->
|
||||||
|
|
||||||
|
<bean id="ldapPeopleImport" class="org.alfresco.repo.importer.ExportSourceImporter">
|
||||||
|
<property name="importerService">
|
||||||
|
<ref bean="importerComponentWithBehaviour"/>
|
||||||
|
</property>
|
||||||
|
<property name="transactionService">
|
||||||
|
<ref bean="transactionComponent"/>
|
||||||
|
</property>
|
||||||
|
<property name="authenticationComponent">
|
||||||
|
<ref bean="authenticationComponent"/>
|
||||||
|
</property>
|
||||||
|
<property name="exportSource">
|
||||||
|
<ref bean="ldapPeopleExportSource"/>
|
||||||
|
</property>
|
||||||
|
|
||||||
|
<!-- The store that contains people - this should not be changed -->
|
||||||
|
<property name="storeRef">
|
||||||
|
<value>${spaces.store}</value>
|
||||||
|
</property>
|
||||||
|
|
||||||
|
<!-- The location of people nodes within the store defined above - this should not be changed -->
|
||||||
|
<property name="path">
|
||||||
|
<value>/${system.system_container.childname}/${system.people_container.childname}</value>
|
||||||
|
</property>
|
||||||
|
|
||||||
|
<!-- If true, clear all existing people before import, if false update/add people from the xml -->
|
||||||
|
<property name="clearAllChildren">
|
||||||
|
<value>false</value>
|
||||||
|
</property>
|
||||||
|
<property name="nodeService">
|
||||||
|
<ref bean="nodeService"/>
|
||||||
|
</property>
|
||||||
|
<property name="searchService">
|
||||||
|
<ref bean="searchService"/>
|
||||||
|
</property>
|
||||||
|
<property name="namespacePrefixResolver">
|
||||||
|
<ref bean="namespaceService"/>
|
||||||
|
</property>
|
||||||
|
|
||||||
|
|
||||||
|
<property name="caches">
|
||||||
|
<set>
|
||||||
|
<ref bean="permissionsAccessCache"/>
|
||||||
|
</set>
|
||||||
|
</property>
|
||||||
|
</bean>
|
||||||
|
|
||||||
|
<!-- The bean that imports xml descibing groups -->
|
||||||
|
|
||||||
|
<bean id="ldapGroupImport" class="org.alfresco.repo.importer.ExportSourceImporter">
|
||||||
|
<property name="importerService">
|
||||||
|
<ref bean="importerComponentWithBehaviour"/>
|
||||||
|
</property>
|
||||||
|
<property name="transactionService">
|
||||||
|
<ref bean="transactionComponent"/>
|
||||||
|
</property>
|
||||||
|
<property name="authenticationComponent">
|
||||||
|
<ref bean="authenticationComponent"/>
|
||||||
|
</property>
|
||||||
|
<property name="exportSource">
|
||||||
|
<ref bean="ldapGroupExportSource"/>
|
||||||
|
</property>
|
||||||
|
<!-- The store that contains group information - this should not be changed -->
|
||||||
|
<property name="storeRef">
|
||||||
|
<value>${alfresco_user_store.store}</value>
|
||||||
|
</property>
|
||||||
|
|
||||||
|
<!-- The location of group information in the store above - this should not be changed -->
|
||||||
|
<property name="path">
|
||||||
|
<value>/${alfresco_user_store.system_container.childname}/${alfresco_user_store.authorities_container.childname}</value>
|
||||||
|
</property>
|
||||||
|
|
||||||
|
<!-- If true, clear all existing groups before import, if false update/add groups from the xml -->
|
||||||
|
<property name="clearAllChildren">
|
||||||
|
<value>${ldap.synchronisation.import.group.clearAllChildren}</value>
|
||||||
|
</property>
|
||||||
|
<property name="nodeService">
|
||||||
|
<ref bean="nodeService"/>
|
||||||
|
</property>
|
||||||
|
<property name="searchService">
|
||||||
|
<ref bean="searchService"/>
|
||||||
|
</property>
|
||||||
|
<property name="namespacePrefixResolver">
|
||||||
|
<ref bean="namespaceService"/>
|
||||||
|
</property>
|
||||||
|
|
||||||
|
<!-- caches to clear on import of groups -->
|
||||||
|
<property name="caches">
|
||||||
|
<set>
|
||||||
|
<ref bean="userToAuthorityCache"/>
|
||||||
|
<ref bean="permissionsAccessCache"/>
|
||||||
|
</set>
|
||||||
|
</property>
|
||||||
|
|
||||||
|
<!-- userToAuthorityCache -->
|
||||||
|
</bean>
|
||||||
|
|
||||||
|
</beans>
|
59
config/alfresco/extension/ldap-synchronisation.properties
Normal file
59
config/alfresco/extension/ldap-synchronisation.properties
Normal file
@@ -0,0 +1,59 @@
|
|||||||
|
#
|
||||||
|
# This properties file is used to configure LDAP syncronisation
|
||||||
|
#
|
||||||
|
|
||||||
|
# The query to find the people to import
|
||||||
|
ldap.synchronisation.personQuery=(objectclass=inetOrgPerson)
|
||||||
|
|
||||||
|
# The search base of the query to find people to import
|
||||||
|
ldap.synchronisation.personSearchBase=dc=company,dc=com
|
||||||
|
|
||||||
|
# The attribute name on people objects found in LDAP to use as the uid in Alfresco
|
||||||
|
ldap.synchronisation.userIdAttributeName=uid
|
||||||
|
|
||||||
|
# The attribute on person objects in LDAP to map to the first name property in Alfresco
|
||||||
|
ldap.synchronisation.userFirstNameAttributeName=givenName
|
||||||
|
|
||||||
|
# The attribute on person objects in LDAP to map to the last name property in Alfresco
|
||||||
|
ldap.synchronisation.userLastNameAttributeName=sn
|
||||||
|
|
||||||
|
# The attribute on person objects in LDAP to map to the email property in Alfresco
|
||||||
|
ldap.synchronisation.userEmailAttributeName=mail
|
||||||
|
|
||||||
|
# The attribute on person objects in LDAP to map to the organizational id property in Alfresco
|
||||||
|
ldap.synchronisation.userOrganizationalIdAttributeName=o
|
||||||
|
|
||||||
|
# The default home folder provider to use for people created via LDAP import
|
||||||
|
ldap.synchronisation.defaultHomeFolderProvider=personalHomeFolderProvider
|
||||||
|
|
||||||
|
# The query to find group objects
|
||||||
|
ldap.synchronisation.groupQuery=(objectclass=groupOfNames)
|
||||||
|
|
||||||
|
# The search base to use to find group objects
|
||||||
|
ldap.synchronisation.groupSearchBase=dc=company,dc=com
|
||||||
|
|
||||||
|
# The attribute on LDAP group objects to map to the gid property in Alfrecso
|
||||||
|
ldap.synchronisation.groupIdAttributeName=cn
|
||||||
|
|
||||||
|
# The group type in LDAP
|
||||||
|
ldap.synchronisation.groupType=groupOfNames
|
||||||
|
|
||||||
|
# The person type in LDAP
|
||||||
|
ldap.synchronisation.personType=inetOrgPerson
|
||||||
|
|
||||||
|
# The attribute in LDAP on group objects that defines the DN for its members
|
||||||
|
ldap.synchronisation.groupMemberAttributeName=member
|
||||||
|
|
||||||
|
# The cron expression defining when people imports should take place
|
||||||
|
ldap.synchronisation.import.person.cron=0 0 * * * ?
|
||||||
|
|
||||||
|
# The cron expression defining when group imports should take place
|
||||||
|
ldap.synchronisation.import.group.cron=0 30 * * * ?
|
||||||
|
|
||||||
|
# Should all groups be cleared out at import time?
|
||||||
|
# - this is safe as groups are not used in Alfresco for other things (unlike person objects which you should never clear out during an import)
|
||||||
|
# - setting this to true means old group definitions will be tidied up.
|
||||||
|
ldap.synchronisation.import.group.clearAllChildren=true
|
||||||
|
|
||||||
|
|
||||||
|
|
@@ -219,6 +219,7 @@
|
|||||||
<mandatory>false</mandatory>
|
<mandatory>false</mandatory>
|
||||||
<many>true</many>
|
<many>true</many>
|
||||||
</target>
|
</target>
|
||||||
|
<duplicate>false</duplicate>
|
||||||
</child-association>
|
</child-association>
|
||||||
</associations>
|
</associations>
|
||||||
</type>
|
</type>
|
||||||
|
@@ -7,10 +7,13 @@
|
|||||||
<ref bean="nodeService"/>
|
<ref bean="nodeService"/>
|
||||||
</property>
|
</property>
|
||||||
<property name="authenticationService">
|
<property name="authenticationService">
|
||||||
<ref bean="authenticationServiceImpl"/>
|
<ref bean="authenticationService"/>
|
||||||
</property>
|
</property>
|
||||||
<property name="nodeOwnerCache">
|
<property name="nodeOwnerCache">
|
||||||
<ref bean="nodeOwnerCache"/>
|
<ref bean="nodeOwnerCache"/>
|
||||||
</property>
|
</property>
|
||||||
|
<property name="policyComponent">
|
||||||
|
<ref bean="policyComponent" />
|
||||||
|
</property>
|
||||||
</bean>
|
</bean>
|
||||||
</beans>
|
</beans>
|
@@ -204,7 +204,7 @@
|
|||||||
<ref bean="nodeService"></ref>
|
<ref bean="nodeService"></ref>
|
||||||
</property>
|
</property>
|
||||||
<property name="authenticationService">
|
<property name="authenticationService">
|
||||||
<ref bean="authenticationServiceImpl" />
|
<ref bean="authenticationService" />
|
||||||
</property>
|
</property>
|
||||||
<property name="maxPermissionCheckTimeMillis">
|
<property name="maxPermissionCheckTimeMillis">
|
||||||
<value>${system.acl.maxPermissionCheckTimeMillis}</value>
|
<value>${system.acl.maxPermissionCheckTimeMillis}</value>
|
||||||
|
@@ -101,6 +101,9 @@
|
|||||||
<property name="nodeService">
|
<property name="nodeService">
|
||||||
<ref bean="nodeService"/>
|
<ref bean="nodeService"/>
|
||||||
</property>
|
</property>
|
||||||
|
<property name="contentService">
|
||||||
|
<ref bean="contentService"/>
|
||||||
|
</property>
|
||||||
<property name="authenticationComponent">
|
<property name="authenticationComponent">
|
||||||
<ref bean="authenticationComponent"/>
|
<ref bean="authenticationComponent"/>
|
||||||
</property>
|
</property>
|
||||||
|
@@ -76,7 +76,7 @@ public class TestData
|
|||||||
public Object execute() throws Exception
|
public Object execute() throws Exception
|
||||||
{
|
{
|
||||||
// Bootstrap Users
|
// Bootstrap Users
|
||||||
MutableAuthenticationDao authDAO = (MutableAuthenticationDao) applicationContext.getBean("alfDaoImpl");
|
MutableAuthenticationDao authDAO = (MutableAuthenticationDao) applicationContext.getBean("authenticationDao");
|
||||||
if (authDAO.userExists("superuser") == false)
|
if (authDAO.userExists("superuser") == false)
|
||||||
{
|
{
|
||||||
authDAO.createUser("superuser", "".toCharArray());
|
authDAO.createUser("superuser", "".toCharArray());
|
||||||
|
@@ -120,7 +120,7 @@ public class AuditServiceTest extends BaseSpringTest
|
|||||||
authorityService = (AuthorityService) applicationContext.getBean("authorityService");
|
authorityService = (AuthorityService) applicationContext.getBean("authorityService");
|
||||||
|
|
||||||
authenticationComponent.setCurrentUser(authenticationComponent.getSystemUserName());
|
authenticationComponent.setCurrentUser(authenticationComponent.getSystemUserName());
|
||||||
authenticationDAO = (MutableAuthenticationDao) applicationContext.getBean("alfDaoImpl");
|
authenticationDAO = (MutableAuthenticationDao) applicationContext.getBean("authenticationDao");
|
||||||
|
|
||||||
auditService = (AuditService) applicationContext.getBean("AuditService");
|
auditService = (AuditService) applicationContext.getBean("AuditService");
|
||||||
auditEntry = (AuditEntry) applicationContext.getBean("auditModel");
|
auditEntry = (AuditEntry) applicationContext.getBean("auditModel");
|
||||||
|
@@ -177,7 +177,7 @@ public class AVMSubmitPackageHandler
|
|||||||
Map<String, AVMNodeDescriptor> list = fAVMService.getDirectoryListing(desc, true);
|
Map<String, AVMNodeDescriptor> list = fAVMService.getDirectoryListing(desc, true);
|
||||||
for (AVMNodeDescriptor child : list.values())
|
for (AVMNodeDescriptor child : list.values())
|
||||||
{
|
{
|
||||||
recursivelyRemoveLocks(webProject, child.getVersionID(), child.getPath());
|
recursivelyRemoveLocks(webProject, version, child.getPath());
|
||||||
}
|
}
|
||||||
}
|
}
|
||||||
}
|
}
|
||||||
|
@@ -57,6 +57,8 @@ import org.alfresco.util.PropertyCheck;
|
|||||||
import org.apache.commons.logging.Log;
|
import org.apache.commons.logging.Log;
|
||||||
import org.apache.commons.logging.LogFactory;
|
import org.apache.commons.logging.LogFactory;
|
||||||
import org.w3c.dom.Document;
|
import org.w3c.dom.Document;
|
||||||
|
import org.w3c.dom.Node;
|
||||||
|
import org.w3c.dom.NodeList;
|
||||||
|
|
||||||
/**
|
/**
|
||||||
* An extracter that pulls values from XML documents using configurable XPath
|
* An extracter that pulls values from XML documents using configurable XPath
|
||||||
@@ -248,7 +250,30 @@ public class XPathMetadataExtracter extends AbstractMappingMetadataExtracter imp
|
|||||||
String documentProperty = element.getKey();
|
String documentProperty = element.getKey();
|
||||||
XPathExpression xpathExpression = element.getValue();
|
XPathExpression xpathExpression = element.getValue();
|
||||||
// Execute it
|
// Execute it
|
||||||
String value = (String) xpathExpression.evaluate(document, XPathConstants.STRING);
|
NodeList nodeList = (NodeList) xpathExpression.evaluate(document, XPathConstants.NODESET);
|
||||||
|
// Convert the value
|
||||||
|
Serializable value = null;
|
||||||
|
int nodeCount = nodeList.getLength();
|
||||||
|
if (nodeCount == 0)
|
||||||
|
{
|
||||||
|
// No result
|
||||||
|
}
|
||||||
|
else if (nodeCount == 1)
|
||||||
|
{
|
||||||
|
Node node = nodeList.item(0);
|
||||||
|
// Get the string value
|
||||||
|
value = node.getTextContent();
|
||||||
|
}
|
||||||
|
else
|
||||||
|
{
|
||||||
|
// Make a collection of the values
|
||||||
|
ArrayList<String> stringValues = new ArrayList<String>(5);
|
||||||
|
for (int i = 0; i < nodeCount; i++)
|
||||||
|
{
|
||||||
|
stringValues.add(nodeList.item(i).getTextContent());
|
||||||
|
}
|
||||||
|
value = stringValues;
|
||||||
|
}
|
||||||
// Put the value
|
// Put the value
|
||||||
rawProperties.put(documentProperty, value);
|
rawProperties.put(documentProperty, value);
|
||||||
}
|
}
|
||||||
@@ -305,7 +330,7 @@ public class XPathMetadataExtracter extends AbstractMappingMetadataExtracter imp
|
|||||||
xpathExpressionMapping.put(documentProperty, xpathExpression);
|
xpathExpressionMapping.put(documentProperty, xpathExpression);
|
||||||
if (logger.isDebugEnabled())
|
if (logger.isDebugEnabled())
|
||||||
{
|
{
|
||||||
logger.debug("Added mapping from " + documentProperty + " to " + xpathExpression);
|
logger.debug("Added mapping from " + documentProperty + " to " + xpathStr);
|
||||||
}
|
}
|
||||||
}
|
}
|
||||||
// Done
|
// Done
|
||||||
|
@@ -26,15 +26,22 @@ package org.alfresco.repo.ownable.impl;
|
|||||||
|
|
||||||
import java.io.Serializable;
|
import java.io.Serializable;
|
||||||
import java.util.HashMap;
|
import java.util.HashMap;
|
||||||
|
import java.util.Map;
|
||||||
|
|
||||||
import org.alfresco.model.ContentModel;
|
import org.alfresco.model.ContentModel;
|
||||||
import org.alfresco.repo.cache.SimpleCache;
|
import org.alfresco.repo.cache.SimpleCache;
|
||||||
|
import org.alfresco.repo.node.NodeServicePolicies;
|
||||||
|
import org.alfresco.repo.policy.JavaBehaviour;
|
||||||
|
import org.alfresco.repo.policy.PolicyComponent;
|
||||||
|
import org.alfresco.service.cmr.repository.ChildAssociationRef;
|
||||||
import org.alfresco.service.cmr.repository.NodeRef;
|
import org.alfresco.service.cmr.repository.NodeRef;
|
||||||
import org.alfresco.service.cmr.repository.NodeService;
|
import org.alfresco.service.cmr.repository.NodeService;
|
||||||
import org.alfresco.service.cmr.repository.datatype.DefaultTypeConverter;
|
import org.alfresco.service.cmr.repository.datatype.DefaultTypeConverter;
|
||||||
import org.alfresco.service.cmr.security.AuthenticationService;
|
import org.alfresco.service.cmr.security.AuthenticationService;
|
||||||
import org.alfresco.service.cmr.security.OwnableService;
|
import org.alfresco.service.cmr.security.OwnableService;
|
||||||
|
import org.alfresco.service.namespace.NamespaceService;
|
||||||
import org.alfresco.service.namespace.QName;
|
import org.alfresco.service.namespace.QName;
|
||||||
|
import org.alfresco.util.EqualsHelper;
|
||||||
import org.springframework.beans.factory.InitializingBean;
|
import org.springframework.beans.factory.InitializingBean;
|
||||||
|
|
||||||
/**
|
/**
|
||||||
@@ -42,7 +49,8 @@ import org.springframework.beans.factory.InitializingBean;
|
|||||||
*
|
*
|
||||||
* @author Andy Hind
|
* @author Andy Hind
|
||||||
*/
|
*/
|
||||||
public class OwnableServiceImpl implements OwnableService, InitializingBean
|
public class OwnableServiceImpl implements OwnableService, InitializingBean, NodeServicePolicies.OnAddAspectPolicy, NodeServicePolicies.OnUpdatePropertiesPolicy,
|
||||||
|
NodeServicePolicies.OnRemoveAspectPolicy, NodeServicePolicies.OnDeleteNodePolicy
|
||||||
{
|
{
|
||||||
private NodeService nodeService;
|
private NodeService nodeService;
|
||||||
|
|
||||||
@@ -50,6 +58,8 @@ public class OwnableServiceImpl implements OwnableService, InitializingBean
|
|||||||
|
|
||||||
private SimpleCache<NodeRef, String> nodeOwnerCache;
|
private SimpleCache<NodeRef, String> nodeOwnerCache;
|
||||||
|
|
||||||
|
private PolicyComponent policyComponent;
|
||||||
|
|
||||||
public OwnableServiceImpl()
|
public OwnableServiceImpl()
|
||||||
{
|
{
|
||||||
super();
|
super();
|
||||||
@@ -67,8 +77,14 @@ public class OwnableServiceImpl implements OwnableService, InitializingBean
|
|||||||
this.authenticationService = authenticationService;
|
this.authenticationService = authenticationService;
|
||||||
}
|
}
|
||||||
|
|
||||||
|
public void setPolicyComponent(PolicyComponent policyComponent)
|
||||||
|
{
|
||||||
|
this.policyComponent = policyComponent;
|
||||||
|
}
|
||||||
|
|
||||||
/**
|
/**
|
||||||
* @param ownerCache a transactionally-safe cache of node owners
|
* @param ownerCache
|
||||||
|
* a transactionally-safe cache of node owners
|
||||||
*/
|
*/
|
||||||
public void setNodeOwnerCache(SimpleCache<NodeRef, String> ownerCache)
|
public void setNodeOwnerCache(SimpleCache<NodeRef, String> ownerCache)
|
||||||
{
|
{
|
||||||
@@ -89,6 +105,23 @@ public class OwnableServiceImpl implements OwnableService, InitializingBean
|
|||||||
{
|
{
|
||||||
throw new IllegalArgumentException("Property 'nodeOwnerCache' has not been set");
|
throw new IllegalArgumentException("Property 'nodeOwnerCache' has not been set");
|
||||||
}
|
}
|
||||||
|
if (policyComponent == null)
|
||||||
|
{
|
||||||
|
throw new IllegalArgumentException("Property 'policyComponent' has not been set");
|
||||||
|
}
|
||||||
|
|
||||||
|
policyComponent.bindClassBehaviour(QName.createQName(NamespaceService.ALFRESCO_URI, "onAddAspect"), ContentModel.ASPECT_OWNABLE, new JavaBehaviour(this, "onAddAspect"));
|
||||||
|
policyComponent.bindClassBehaviour(QName.createQName(NamespaceService.ALFRESCO_URI, "onUpdateProperties"), ContentModel.ASPECT_OWNABLE, new JavaBehaviour(this, "onUpdateProperties"));
|
||||||
|
policyComponent.bindClassBehaviour(QName.createQName(NamespaceService.ALFRESCO_URI, "onRemoveAspect"), ContentModel.ASPECT_OWNABLE, new JavaBehaviour(this,
|
||||||
|
"onRemoveAspect"));
|
||||||
|
policyComponent.bindClassBehaviour(QName.createQName(NamespaceService.ALFRESCO_URI, "onDeleteNode"), ContentModel.ASPECT_OWNABLE, new JavaBehaviour(this, "onDeleteNode"));
|
||||||
|
|
||||||
|
policyComponent.bindClassBehaviour(QName.createQName(NamespaceService.ALFRESCO_URI, "onAddAspect"), ContentModel.ASPECT_AUDITABLE, new JavaBehaviour(this, "onAddAspect"));
|
||||||
|
policyComponent.bindClassBehaviour(QName.createQName(NamespaceService.ALFRESCO_URI, "onUpdateProperties"), ContentModel.ASPECT_AUDITABLE, new JavaBehaviour(this, "onUpdateProperties"));
|
||||||
|
policyComponent.bindClassBehaviour(QName.createQName(NamespaceService.ALFRESCO_URI, "onRemoveAspect"), ContentModel.ASPECT_AUDITABLE, new JavaBehaviour(this,
|
||||||
|
"onRemoveAspect"));
|
||||||
|
policyComponent.bindClassBehaviour(QName.createQName(NamespaceService.ALFRESCO_URI, "onDeleteNode"), ContentModel.ASPECT_AUDITABLE, new JavaBehaviour(this, "onDeleteNode"));
|
||||||
|
|
||||||
}
|
}
|
||||||
|
|
||||||
// OwnableService implmentation
|
// OwnableService implmentation
|
||||||
@@ -104,7 +137,7 @@ public class OwnableServiceImpl implements OwnableService, InitializingBean
|
|||||||
{
|
{
|
||||||
userName = DefaultTypeConverter.INSTANCE.convert(String.class, nodeService.getProperty(nodeRef, ContentModel.PROP_OWNER));
|
userName = DefaultTypeConverter.INSTANCE.convert(String.class, nodeService.getProperty(nodeRef, ContentModel.PROP_OWNER));
|
||||||
}
|
}
|
||||||
else if(nodeService.hasAspect(nodeRef, ContentModel.ASPECT_AUDITABLE))
|
else if (nodeService.hasAspect(nodeRef, ContentModel.ASPECT_AUDITABLE))
|
||||||
{
|
{
|
||||||
userName = DefaultTypeConverter.INSTANCE.convert(String.class, nodeService.getProperty(nodeRef, ContentModel.PROP_CREATOR));
|
userName = DefaultTypeConverter.INSTANCE.convert(String.class, nodeService.getProperty(nodeRef, ContentModel.PROP_CREATOR));
|
||||||
}
|
}
|
||||||
@@ -138,4 +171,41 @@ public class OwnableServiceImpl implements OwnableService, InitializingBean
|
|||||||
{
|
{
|
||||||
return getOwner(nodeRef) != null;
|
return getOwner(nodeRef) != null;
|
||||||
}
|
}
|
||||||
|
|
||||||
|
public void onAddAspect(NodeRef nodeRef, QName aspectTypeQName)
|
||||||
|
{
|
||||||
|
nodeOwnerCache.remove(nodeRef);
|
||||||
|
}
|
||||||
|
|
||||||
|
public void onRemoveAspect(NodeRef nodeRef, QName aspectTypeQName)
|
||||||
|
{
|
||||||
|
nodeOwnerCache.remove(nodeRef);
|
||||||
|
}
|
||||||
|
|
||||||
|
public void onDeleteNode(ChildAssociationRef childAssocRef, boolean isNodeArchived)
|
||||||
|
{
|
||||||
|
nodeOwnerCache.remove(childAssocRef.getChildRef());
|
||||||
|
}
|
||||||
|
|
||||||
|
public void onUpdateProperties(NodeRef nodeRef, Map<QName, Serializable> before, Map<QName, Serializable> after)
|
||||||
|
{
|
||||||
|
Serializable pb = before.get(ContentModel.PROP_OWNER);
|
||||||
|
Serializable pa = after.get(ContentModel.PROP_OWNER);
|
||||||
|
|
||||||
|
if (!EqualsHelper.nullSafeEquals(pb, pa))
|
||||||
|
{
|
||||||
|
nodeOwnerCache.remove(nodeRef);
|
||||||
|
return;
|
||||||
|
}
|
||||||
|
|
||||||
|
pb = before.get(ContentModel.PROP_CREATOR);
|
||||||
|
pa = after.get(ContentModel.PROP_CREATOR);
|
||||||
|
|
||||||
|
if (!EqualsHelper.nullSafeEquals(pb, pa))
|
||||||
|
{
|
||||||
|
nodeOwnerCache.remove(nodeRef);
|
||||||
|
return;
|
||||||
|
}
|
||||||
|
|
||||||
|
}
|
||||||
}
|
}
|
||||||
|
@@ -24,6 +24,9 @@
|
|||||||
*/
|
*/
|
||||||
package org.alfresco.repo.ownable.impl;
|
package org.alfresco.repo.ownable.impl;
|
||||||
|
|
||||||
|
import java.io.Serializable;
|
||||||
|
import java.util.HashMap;
|
||||||
|
|
||||||
import javax.transaction.UserTransaction;
|
import javax.transaction.UserTransaction;
|
||||||
|
|
||||||
import junit.framework.TestCase;
|
import junit.framework.TestCase;
|
||||||
@@ -40,6 +43,7 @@ import org.alfresco.service.cmr.security.AccessStatus;
|
|||||||
import org.alfresco.service.cmr.security.AuthenticationService;
|
import org.alfresco.service.cmr.security.AuthenticationService;
|
||||||
import org.alfresco.service.cmr.security.OwnableService;
|
import org.alfresco.service.cmr.security.OwnableService;
|
||||||
import org.alfresco.service.cmr.security.PermissionService;
|
import org.alfresco.service.cmr.security.PermissionService;
|
||||||
|
import org.alfresco.service.namespace.QName;
|
||||||
import org.alfresco.service.transaction.TransactionService;
|
import org.alfresco.service.transaction.TransactionService;
|
||||||
import org.alfresco.util.ApplicationContextHelper;
|
import org.alfresco.util.ApplicationContextHelper;
|
||||||
import org.springframework.context.ApplicationContext;
|
import org.springframework.context.ApplicationContext;
|
||||||
@@ -85,7 +89,7 @@ public class OwnableServiceTest extends TestCase
|
|||||||
permissionService = (PermissionService) ctx.getBean("permissionService");
|
permissionService = (PermissionService) ctx.getBean("permissionService");
|
||||||
|
|
||||||
authenticationComponent.setCurrentUser(authenticationComponent.getSystemUserName());
|
authenticationComponent.setCurrentUser(authenticationComponent.getSystemUserName());
|
||||||
authenticationDAO = (MutableAuthenticationDao) ctx.getBean("alfDaoImpl");
|
authenticationDAO = (MutableAuthenticationDao) ctx.getBean("authenticationDao");
|
||||||
|
|
||||||
|
|
||||||
TransactionService transactionService = (TransactionService) ctx.getBean(ServiceRegistry.TRANSACTION_SERVICE.getLocalName());
|
TransactionService transactionService = (TransactionService) ctx.getBean(ServiceRegistry.TRANSACTION_SERVICE.getLocalName());
|
||||||
@@ -147,6 +151,14 @@ public class OwnableServiceTest extends TestCase
|
|||||||
assertFalse(nodeService.hasAspect(testNode, ContentModel.ASPECT_OWNABLE));
|
assertFalse(nodeService.hasAspect(testNode, ContentModel.ASPECT_OWNABLE));
|
||||||
assertTrue(dynamicAuthority.hasAuthority(testNode, "andy"));
|
assertTrue(dynamicAuthority.hasAuthority(testNode, "andy"));
|
||||||
|
|
||||||
|
assertEquals("andy", ownableService.getOwner(testNode));
|
||||||
|
|
||||||
|
nodeService.setProperty(testNode, ContentModel.PROP_CREATOR, "woof");
|
||||||
|
assertEquals("woof", ownableService.getOwner(testNode));
|
||||||
|
|
||||||
|
nodeService.setProperty(testNode, ContentModel.PROP_CREATOR, "andy");
|
||||||
|
assertEquals("andy", ownableService.getOwner(testNode));
|
||||||
|
|
||||||
permissionService.setInheritParentPermissions(testNode, false);
|
permissionService.setInheritParentPermissions(testNode, false);
|
||||||
|
|
||||||
|
|
||||||
@@ -189,6 +201,16 @@ public class OwnableServiceTest extends TestCase
|
|||||||
assertEquals(AccessStatus.ALLOWED, permissionService.hasPermission(testNode, PermissionService.TAKE_OWNERSHIP));
|
assertEquals(AccessStatus.ALLOWED, permissionService.hasPermission(testNode, PermissionService.TAKE_OWNERSHIP));
|
||||||
assertEquals(AccessStatus.ALLOWED, permissionService.hasPermission(testNode, PermissionService.SET_OWNER));
|
assertEquals(AccessStatus.ALLOWED, permissionService.hasPermission(testNode, PermissionService.SET_OWNER));
|
||||||
|
|
||||||
|
nodeService.setProperty(testNode, ContentModel.PROP_OWNER, "muppet");
|
||||||
|
assertEquals("muppet", ownableService.getOwner(testNode));
|
||||||
|
nodeService.removeAspect(testNode, ContentModel.ASPECT_OWNABLE);
|
||||||
|
assertEquals("andy", ownableService.getOwner(testNode));
|
||||||
|
|
||||||
|
HashMap<QName, Serializable> aspectProperties = new HashMap<QName, Serializable>();
|
||||||
|
aspectProperties.put(ContentModel.PROP_OWNER, "muppet");
|
||||||
|
nodeService.addAspect(testNode, ContentModel.ASPECT_OWNABLE, aspectProperties);
|
||||||
|
assertEquals("muppet", ownableService.getOwner(testNode));
|
||||||
|
|
||||||
|
|
||||||
}
|
}
|
||||||
|
|
||||||
|
@@ -26,9 +26,12 @@ package org.alfresco.repo.rule.ruletrigger;
|
|||||||
|
|
||||||
import java.util.List;
|
import java.util.List;
|
||||||
|
|
||||||
|
import org.alfresco.model.ContentModel;
|
||||||
import org.alfresco.repo.content.ContentServicePolicies;
|
import org.alfresco.repo.content.ContentServicePolicies;
|
||||||
|
import org.alfresco.repo.content.MimetypeMap;
|
||||||
import org.alfresco.repo.policy.JavaBehaviour;
|
import org.alfresco.repo.policy.JavaBehaviour;
|
||||||
import org.alfresco.service.cmr.repository.ChildAssociationRef;
|
import org.alfresco.service.cmr.repository.ChildAssociationRef;
|
||||||
|
import org.alfresco.service.cmr.repository.ContentReader;
|
||||||
import org.alfresco.service.cmr.repository.NodeRef;
|
import org.alfresco.service.cmr.repository.NodeRef;
|
||||||
import org.apache.commons.logging.Log;
|
import org.apache.commons.logging.Log;
|
||||||
import org.apache.commons.logging.LogFactory;
|
import org.apache.commons.logging.LogFactory;
|
||||||
@@ -87,9 +90,24 @@ public class OnContentUpdateRuleTrigger extends RuleTriggerAbstractBase
|
|||||||
*/
|
*/
|
||||||
public void onContentUpdate(NodeRef nodeRef, boolean newContent)
|
public void onContentUpdate(NodeRef nodeRef, boolean newContent)
|
||||||
{
|
{
|
||||||
if (newContent == this.onNewContent)
|
|
||||||
|
// Check the new content and make sure that we do indeed want to trigger the rule
|
||||||
|
boolean fail = false;
|
||||||
|
if (newContent == true)
|
||||||
|
{
|
||||||
|
ContentReader contentReader = this.contentService.getReader(nodeRef, ContentModel.PROP_CONTENT);
|
||||||
|
if (contentReader == null ||
|
||||||
|
contentReader.exists() == false ||
|
||||||
|
isZeroLengthOfficeDoc(contentReader) == true)
|
||||||
|
{
|
||||||
|
fail = true;
|
||||||
|
}
|
||||||
|
}
|
||||||
|
|
||||||
|
// Trigger the rules in the appropriate way
|
||||||
|
if (fail == false && newContent == this.onNewContent)
|
||||||
{
|
{
|
||||||
if (triggerParentRules == true)
|
if (triggerParentRules == true)
|
||||||
{
|
{
|
||||||
if (logger.isDebugEnabled() == true)
|
if (logger.isDebugEnabled() == true)
|
||||||
{
|
{
|
||||||
@@ -109,4 +127,23 @@ public class OnContentUpdateRuleTrigger extends RuleTriggerAbstractBase
|
|||||||
}
|
}
|
||||||
}
|
}
|
||||||
|
|
||||||
|
/**
|
||||||
|
* Indicates whether we are dealing with a zero length office document or not
|
||||||
|
*
|
||||||
|
* @param contentReader the content reader
|
||||||
|
* @return boolean true if zero length office document, false otherwise
|
||||||
|
*/
|
||||||
|
private boolean isZeroLengthOfficeDoc(ContentReader contentReader)
|
||||||
|
{
|
||||||
|
boolean result = false;
|
||||||
|
if (contentReader.getSize() == 0 &&
|
||||||
|
(MimetypeMap.MIMETYPE_WORD.equals(contentReader.getMimetype()) == true ||
|
||||||
|
MimetypeMap.MIMETYPE_EXCEL.equals(contentReader.getMimetype()) == true ||
|
||||||
|
MimetypeMap.MIMETYPE_PPT.equals(contentReader.getMimetype()) == true))
|
||||||
|
{
|
||||||
|
result = true;
|
||||||
|
}
|
||||||
|
return result;
|
||||||
|
}
|
||||||
|
|
||||||
}
|
}
|
||||||
|
@@ -30,6 +30,7 @@ import java.util.Set;
|
|||||||
import org.alfresco.repo.policy.PolicyComponent;
|
import org.alfresco.repo.policy.PolicyComponent;
|
||||||
import org.alfresco.repo.security.authentication.AuthenticationComponent;
|
import org.alfresco.repo.security.authentication.AuthenticationComponent;
|
||||||
import org.alfresco.service.cmr.dictionary.DictionaryService;
|
import org.alfresco.service.cmr.dictionary.DictionaryService;
|
||||||
|
import org.alfresco.service.cmr.repository.ContentService;
|
||||||
import org.alfresco.service.cmr.repository.NodeRef;
|
import org.alfresco.service.cmr.repository.NodeRef;
|
||||||
import org.alfresco.service.cmr.repository.NodeService;
|
import org.alfresco.service.cmr.repository.NodeService;
|
||||||
import org.alfresco.service.cmr.rule.RuleType;
|
import org.alfresco.service.cmr.rule.RuleType;
|
||||||
@@ -56,6 +57,11 @@ public abstract class RuleTriggerAbstractBase implements RuleTrigger
|
|||||||
*/
|
*/
|
||||||
protected NodeService nodeService;
|
protected NodeService nodeService;
|
||||||
|
|
||||||
|
/**
|
||||||
|
* The content service
|
||||||
|
*/
|
||||||
|
protected ContentService contentService;
|
||||||
|
|
||||||
/**
|
/**
|
||||||
* The authentication Component
|
* The authentication Component
|
||||||
*/
|
*/
|
||||||
@@ -92,6 +98,16 @@ public abstract class RuleTriggerAbstractBase implements RuleTrigger
|
|||||||
this.nodeService = nodeService;
|
this.nodeService = nodeService;
|
||||||
}
|
}
|
||||||
|
|
||||||
|
/**
|
||||||
|
* Set the content service
|
||||||
|
*
|
||||||
|
* @param contentService the content service
|
||||||
|
*/
|
||||||
|
public void setContentService(ContentService contentService)
|
||||||
|
{
|
||||||
|
this.contentService = contentService;
|
||||||
|
}
|
||||||
|
|
||||||
/**
|
/**
|
||||||
* Set the authenticationComponent
|
* Set the authenticationComponent
|
||||||
*/
|
*/
|
||||||
@@ -123,6 +139,7 @@ public abstract class RuleTriggerAbstractBase implements RuleTrigger
|
|||||||
|
|
||||||
/**
|
/**
|
||||||
* Registration of an interested rule type
|
* Registration of an interested rule type
|
||||||
|
*
|
||||||
*/
|
*/
|
||||||
public void registerRuleType(RuleType ruleType)
|
public void registerRuleType(RuleType ruleType)
|
||||||
{
|
{
|
||||||
|
@@ -98,7 +98,7 @@ public class SearchServiceTest extends TestCase
|
|||||||
nodeService = (NodeService) ctx.getBean("dbNodeService");
|
nodeService = (NodeService) ctx.getBean("dbNodeService");
|
||||||
authenticationComponent = (AuthenticationComponent) ctx.getBean("authenticationComponent");
|
authenticationComponent = (AuthenticationComponent) ctx.getBean("authenticationComponent");
|
||||||
authenticationService = (AuthenticationService) ctx.getBean("authenticationService");
|
authenticationService = (AuthenticationService) ctx.getBean("authenticationService");
|
||||||
authenticationDAO = (MutableAuthenticationDao) ctx.getBean("alfDaoImpl");
|
authenticationDAO = (MutableAuthenticationDao) ctx.getBean("authenticationDao");
|
||||||
pubSearchService = (SearchService) ctx.getBean("SearchService");
|
pubSearchService = (SearchService) ctx.getBean("SearchService");
|
||||||
pubPermissionService = (PermissionService) ctx.getBean("PermissionService");
|
pubPermissionService = (PermissionService) ctx.getBean("PermissionService");
|
||||||
|
|
||||||
|
@@ -28,10 +28,6 @@ import net.sf.acegisecurity.Authentication;
|
|||||||
import net.sf.acegisecurity.GrantedAuthority;
|
import net.sf.acegisecurity.GrantedAuthority;
|
||||||
import net.sf.acegisecurity.GrantedAuthorityImpl;
|
import net.sf.acegisecurity.GrantedAuthorityImpl;
|
||||||
import net.sf.acegisecurity.UserDetails;
|
import net.sf.acegisecurity.UserDetails;
|
||||||
import net.sf.acegisecurity.context.Context;
|
|
||||||
import net.sf.acegisecurity.context.ContextHolder;
|
|
||||||
import net.sf.acegisecurity.context.security.SecureContext;
|
|
||||||
import net.sf.acegisecurity.context.security.SecureContextImpl;
|
|
||||||
import net.sf.acegisecurity.providers.UsernamePasswordAuthenticationToken;
|
import net.sf.acegisecurity.providers.UsernamePasswordAuthenticationToken;
|
||||||
import net.sf.acegisecurity.providers.dao.User;
|
import net.sf.acegisecurity.providers.dao.User;
|
||||||
|
|
||||||
@@ -46,11 +42,9 @@ import org.alfresco.service.cmr.security.PermissionService;
|
|||||||
*/
|
*/
|
||||||
public abstract class AbstractAuthenticationComponent implements AuthenticationComponent
|
public abstract class AbstractAuthenticationComponent implements AuthenticationComponent
|
||||||
{
|
{
|
||||||
|
/**
|
||||||
// Name of the system user
|
* The abstract class keeps track of support for guest login
|
||||||
|
*/
|
||||||
static final String SYSTEM_USER_NAME = "System";
|
|
||||||
|
|
||||||
private Boolean allowGuestLogin = null;
|
private Boolean allowGuestLogin = null;
|
||||||
|
|
||||||
public AbstractAuthenticationComponent()
|
public AbstractAuthenticationComponent()
|
||||||
@@ -58,6 +52,11 @@ public abstract class AbstractAuthenticationComponent implements AuthenticationC
|
|||||||
super();
|
super();
|
||||||
}
|
}
|
||||||
|
|
||||||
|
/**
|
||||||
|
* Set if guest login is supported.
|
||||||
|
*
|
||||||
|
* @param allowGuestLogin
|
||||||
|
*/
|
||||||
public void setAllowGuestLogin(Boolean allowGuestLogin)
|
public void setAllowGuestLogin(Boolean allowGuestLogin)
|
||||||
{
|
{
|
||||||
this.allowGuestLogin = allowGuestLogin;
|
this.allowGuestLogin = allowGuestLogin;
|
||||||
@@ -65,6 +64,7 @@ public abstract class AbstractAuthenticationComponent implements AuthenticationC
|
|||||||
|
|
||||||
public void authenticate(String userName, char[] password) throws AuthenticationException
|
public void authenticate(String userName, char[] password) throws AuthenticationException
|
||||||
{
|
{
|
||||||
|
// Support guest login from the login screen
|
||||||
if ((userName != null) && (userName.equalsIgnoreCase(PermissionService.GUEST_AUTHORITY)))
|
if ((userName != null) && (userName.equalsIgnoreCase(PermissionService.GUEST_AUTHORITY)))
|
||||||
{
|
{
|
||||||
setGuestUserAsCurrentUser();
|
setGuestUserAsCurrentUser();
|
||||||
@@ -75,6 +75,14 @@ public abstract class AbstractAuthenticationComponent implements AuthenticationC
|
|||||||
}
|
}
|
||||||
}
|
}
|
||||||
|
|
||||||
|
/**
|
||||||
|
* Default unsupported authentication implementation
|
||||||
|
* - as of 2.1 this is the best way to implement your own authentication component as it will support guest login
|
||||||
|
* - prior to this direct over ride for authenticate(String , char[]) was used. This will still work.
|
||||||
|
*
|
||||||
|
* @param userName
|
||||||
|
* @param password
|
||||||
|
*/
|
||||||
protected void authenticateImpl(String userName, char[] password)
|
protected void authenticateImpl(String userName, char[] password)
|
||||||
{
|
{
|
||||||
throw new UnsupportedOperationException();
|
throw new UnsupportedOperationException();
|
||||||
@@ -97,11 +105,11 @@ public abstract class AbstractAuthenticationComponent implements AuthenticationC
|
|||||||
try
|
try
|
||||||
{
|
{
|
||||||
UserDetails ud = null;
|
UserDetails ud = null;
|
||||||
if (userName.equals(SYSTEM_USER_NAME))
|
if (userName.equals(AuthenticationUtil.SYSTEM_USER_NAME))
|
||||||
{
|
{
|
||||||
GrantedAuthority[] gas = new GrantedAuthority[1];
|
GrantedAuthority[] gas = new GrantedAuthority[1];
|
||||||
gas[0] = new GrantedAuthorityImpl("ROLE_SYSTEM");
|
gas[0] = new GrantedAuthorityImpl("ROLE_SYSTEM");
|
||||||
ud = new User(SYSTEM_USER_NAME, "", true, true, true, true, gas);
|
ud = new User(AuthenticationUtil.SYSTEM_USER_NAME, "", true, true, true, true, gas);
|
||||||
}
|
}
|
||||||
else if (userName.equalsIgnoreCase(PermissionService.GUEST_AUTHORITY))
|
else if (userName.equalsIgnoreCase(PermissionService.GUEST_AUTHORITY))
|
||||||
{
|
{
|
||||||
@@ -173,28 +181,6 @@ public abstract class AbstractAuthenticationComponent implements AuthenticationC
|
|||||||
return AuthenticationUtil.getCurrentUserName();
|
return AuthenticationUtil.getCurrentUserName();
|
||||||
}
|
}
|
||||||
|
|
||||||
/**
|
|
||||||
* Get the current user name
|
|
||||||
*
|
|
||||||
* @param authentication
|
|
||||||
* Authentication
|
|
||||||
* @return String
|
|
||||||
*/
|
|
||||||
private String getUserName(Authentication authentication)
|
|
||||||
{
|
|
||||||
String username;
|
|
||||||
if (authentication.getPrincipal() instanceof UserDetails)
|
|
||||||
{
|
|
||||||
username = ((UserDetails) authentication.getPrincipal()).getUsername();
|
|
||||||
}
|
|
||||||
else
|
|
||||||
{
|
|
||||||
username = authentication.getPrincipal().toString();
|
|
||||||
}
|
|
||||||
|
|
||||||
return username;
|
|
||||||
}
|
|
||||||
|
|
||||||
/**
|
/**
|
||||||
* Set the system user as the current user.
|
* Set the system user as the current user.
|
||||||
*
|
*
|
||||||
@@ -202,7 +188,7 @@ public abstract class AbstractAuthenticationComponent implements AuthenticationC
|
|||||||
*/
|
*/
|
||||||
public Authentication setSystemUserAsCurrentUser()
|
public Authentication setSystemUserAsCurrentUser()
|
||||||
{
|
{
|
||||||
return setCurrentUser(SYSTEM_USER_NAME);
|
return setCurrentUser(AuthenticationUtil.SYSTEM_USER_NAME);
|
||||||
}
|
}
|
||||||
|
|
||||||
/**
|
/**
|
||||||
@@ -212,7 +198,7 @@ public abstract class AbstractAuthenticationComponent implements AuthenticationC
|
|||||||
*/
|
*/
|
||||||
public String getSystemUserName()
|
public String getSystemUserName()
|
||||||
{
|
{
|
||||||
return SYSTEM_USER_NAME;
|
return AuthenticationUtil.SYSTEM_USER_NAME;
|
||||||
}
|
}
|
||||||
|
|
||||||
/**
|
/**
|
||||||
|
@@ -135,7 +135,7 @@ public class AuthenticationTest extends TestCase
|
|||||||
// ctx.getBean("permissionService");
|
// ctx.getBean("permissionService");
|
||||||
ticketsCache = (SimpleCache<String, Ticket>) ctx.getBean("ticketsCache");
|
ticketsCache = (SimpleCache<String, Ticket>) ctx.getBean("ticketsCache");
|
||||||
|
|
||||||
dao = (MutableAuthenticationDao) ctx.getBean("alfDaoImpl");
|
dao = (MutableAuthenticationDao) ctx.getBean("authenticationDao");
|
||||||
authenticationManager = (AuthenticationManager) ctx.getBean("authenticationManager");
|
authenticationManager = (AuthenticationManager) ctx.getBean("authenticationManager");
|
||||||
saltSource = (SaltSource) ctx.getBean("saltSource");
|
saltSource = (SaltSource) ctx.getBean("saltSource");
|
||||||
|
|
||||||
|
@@ -231,7 +231,6 @@ public abstract class AuthenticationUtil
|
|||||||
private static String getUserName(Authentication authentication)
|
private static String getUserName(Authentication authentication)
|
||||||
{
|
{
|
||||||
String username;
|
String username;
|
||||||
|
|
||||||
if (authentication.getPrincipal() instanceof UserDetails)
|
if (authentication.getPrincipal() instanceof UserDetails)
|
||||||
{
|
{
|
||||||
username = ((UserDetails) authentication.getPrincipal()).getUsername();
|
username = ((UserDetails) authentication.getPrincipal()).getUsername();
|
||||||
|
@@ -0,0 +1,400 @@
|
|||||||
|
/*
|
||||||
|
* Copyright (C) 2005-2007 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 recieved 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.security.authentication;
|
||||||
|
|
||||||
|
import java.util.ArrayList;
|
||||||
|
import java.util.List;
|
||||||
|
|
||||||
|
import net.sf.acegisecurity.Authentication;
|
||||||
|
|
||||||
|
import org.alfresco.service.cmr.security.PermissionService;
|
||||||
|
|
||||||
|
/**
|
||||||
|
* A chaining authentication component is required for all the beans that qire up an authentication component and not an
|
||||||
|
* authentication service. It supports chaining in much the same way and wires up components in the same way asthe
|
||||||
|
* chaining authentication service wires up services.
|
||||||
|
*
|
||||||
|
* @author andyh
|
||||||
|
*/
|
||||||
|
public class ChainingAuthenticationComponentImpl implements AuthenticationComponent
|
||||||
|
{
|
||||||
|
/**
|
||||||
|
* NLTM authentication mode - if unset - finds the first component that supports NTLM - if set - finds the first
|
||||||
|
* component that supports the specified mode.
|
||||||
|
*/
|
||||||
|
private NTLMMode ntlmMode = null;
|
||||||
|
|
||||||
|
/**
|
||||||
|
* The authentication components
|
||||||
|
*/
|
||||||
|
private List<AuthenticationComponent> authenticationComponents;
|
||||||
|
|
||||||
|
/**
|
||||||
|
* An authentication service that supports change (as wired in to the authentication service). It is never used for
|
||||||
|
* change it is to ensure it is at the top of the list (as required by the chaining authentication service)
|
||||||
|
*/
|
||||||
|
private AuthenticationComponent mutableAuthenticationComponent;
|
||||||
|
|
||||||
|
/**
|
||||||
|
* Get the authentication components
|
||||||
|
*
|
||||||
|
* @return - a list of authentication components
|
||||||
|
*/
|
||||||
|
public List<AuthenticationComponent> getAuthenticationComponents()
|
||||||
|
{
|
||||||
|
return authenticationComponents;
|
||||||
|
}
|
||||||
|
|
||||||
|
/**
|
||||||
|
* Set a list of authentication components
|
||||||
|
*
|
||||||
|
* @param authenticationComponents
|
||||||
|
*/
|
||||||
|
public void setAuthenticationComponents(List<AuthenticationComponent> authenticationComponents)
|
||||||
|
{
|
||||||
|
this.authenticationComponents = authenticationComponents;
|
||||||
|
}
|
||||||
|
|
||||||
|
/**
|
||||||
|
* Get the authentication service thta must be at the top of the list (this may be null)
|
||||||
|
*
|
||||||
|
* @return
|
||||||
|
*/
|
||||||
|
public AuthenticationComponent getMutableAuthenticationComponent()
|
||||||
|
{
|
||||||
|
return mutableAuthenticationComponent;
|
||||||
|
}
|
||||||
|
|
||||||
|
/**
|
||||||
|
* Set the authentication component at the top of the list.
|
||||||
|
*
|
||||||
|
* @param mutableAuthenticationComponent
|
||||||
|
*/
|
||||||
|
public void setMutableAuthenticationComponent(AuthenticationComponent mutableAuthenticationComponent)
|
||||||
|
{
|
||||||
|
this.mutableAuthenticationComponent = mutableAuthenticationComponent;
|
||||||
|
}
|
||||||
|
|
||||||
|
|
||||||
|
|
||||||
|
public void setNtlmMode(NTLMMode ntlmMode)
|
||||||
|
{
|
||||||
|
this.ntlmMode = ntlmMode;
|
||||||
|
}
|
||||||
|
|
||||||
|
/**
|
||||||
|
* Chain authentication with user name and password - tries all in order until one works, or fails.
|
||||||
|
*/
|
||||||
|
public void authenticate(String userName, char[] password) throws AuthenticationException
|
||||||
|
{
|
||||||
|
for (AuthenticationComponent authComponent : getUsableAuthenticationComponents())
|
||||||
|
{
|
||||||
|
try
|
||||||
|
{
|
||||||
|
authComponent.authenticate(userName, password);
|
||||||
|
return;
|
||||||
|
}
|
||||||
|
catch (AuthenticationException e)
|
||||||
|
{
|
||||||
|
// Ignore and chain
|
||||||
|
}
|
||||||
|
}
|
||||||
|
throw new AuthenticationException("Failed to authenticate");
|
||||||
|
}
|
||||||
|
|
||||||
|
/**
|
||||||
|
* NTLM passthrough authentication - if a mode is defined - the first PASS_THROUGH provider is used - if not, the
|
||||||
|
* first component that supports NTLM is used if it supports PASS_THROUGH
|
||||||
|
*/
|
||||||
|
public Authentication authenticate(Authentication token) throws AuthenticationException
|
||||||
|
{
|
||||||
|
if (ntlmMode != null)
|
||||||
|
{
|
||||||
|
switch (ntlmMode)
|
||||||
|
{
|
||||||
|
case NONE:
|
||||||
|
throw new AuthenticationException("NTLM is not supported");
|
||||||
|
case MD4_PROVIDER:
|
||||||
|
throw new AuthenticationException("NTLM passthrough is not supported then configured for MD4 hashing");
|
||||||
|
case PASS_THROUGH:
|
||||||
|
for (AuthenticationComponent authComponent : getUsableAuthenticationComponents())
|
||||||
|
{
|
||||||
|
if (authComponent.getNTLMMode() == NTLMMode.PASS_THROUGH)
|
||||||
|
{
|
||||||
|
return authComponent.authenticate(token);
|
||||||
|
}
|
||||||
|
}
|
||||||
|
throw new AuthenticationException("No NTLM passthrough authentication to use");
|
||||||
|
default:
|
||||||
|
throw new AuthenticationException("No NTLM passthrough authentication to use");
|
||||||
|
}
|
||||||
|
}
|
||||||
|
else
|
||||||
|
{
|
||||||
|
for (AuthenticationComponent authComponent : getUsableAuthenticationComponents())
|
||||||
|
{
|
||||||
|
if (authComponent.getNTLMMode() != NTLMMode.NONE)
|
||||||
|
{
|
||||||
|
if (authComponent.getNTLMMode() == NTLMMode.PASS_THROUGH)
|
||||||
|
{
|
||||||
|
return authComponent.authenticate(token);
|
||||||
|
}
|
||||||
|
else
|
||||||
|
{
|
||||||
|
throw new AuthenticationException("The first authentication component to support NTLM supports MD4 hashing");
|
||||||
|
}
|
||||||
|
}
|
||||||
|
}
|
||||||
|
throw new AuthenticationException("No NTLM passthrough authentication to use");
|
||||||
|
}
|
||||||
|
|
||||||
|
}
|
||||||
|
|
||||||
|
/**
|
||||||
|
* Clear the security context
|
||||||
|
*/
|
||||||
|
public void clearCurrentSecurityContext()
|
||||||
|
{
|
||||||
|
AuthenticationUtil.clearCurrentSecurityContext();
|
||||||
|
}
|
||||||
|
|
||||||
|
/**
|
||||||
|
* Get the current authentication
|
||||||
|
*/
|
||||||
|
public Authentication getCurrentAuthentication() throws AuthenticationException
|
||||||
|
{
|
||||||
|
return AuthenticationUtil.getCurrentAuthentication();
|
||||||
|
}
|
||||||
|
|
||||||
|
/**
|
||||||
|
* Get the current user name
|
||||||
|
*/
|
||||||
|
public String getCurrentUserName() throws AuthenticationException
|
||||||
|
{
|
||||||
|
return AuthenticationUtil.getCurrentUserName();
|
||||||
|
}
|
||||||
|
|
||||||
|
/**
|
||||||
|
* Get the guest user name
|
||||||
|
*/
|
||||||
|
public String getGuestUserName()
|
||||||
|
{
|
||||||
|
return PermissionService.GUEST_AUTHORITY.toLowerCase();
|
||||||
|
}
|
||||||
|
|
||||||
|
/**
|
||||||
|
* Get the MD4 password hash
|
||||||
|
*/
|
||||||
|
public String getMD4HashedPassword(String userName)
|
||||||
|
{
|
||||||
|
if (ntlmMode != null)
|
||||||
|
{
|
||||||
|
switch (ntlmMode)
|
||||||
|
{
|
||||||
|
case NONE:
|
||||||
|
throw new AuthenticationException("NTLM is not supported");
|
||||||
|
case PASS_THROUGH:
|
||||||
|
throw new AuthenticationException("NTLM passthrough is not supported then configured for MD4 hashing");
|
||||||
|
case MD4_PROVIDER:
|
||||||
|
for (AuthenticationComponent authComponent : getUsableAuthenticationComponents())
|
||||||
|
{
|
||||||
|
if (authComponent.getNTLMMode() == NTLMMode.MD4_PROVIDER)
|
||||||
|
{
|
||||||
|
return authComponent.getMD4HashedPassword(userName);
|
||||||
|
}
|
||||||
|
}
|
||||||
|
throw new AuthenticationException("No MD4 provider available");
|
||||||
|
default:
|
||||||
|
throw new AuthenticationException("No MD4 provider available");
|
||||||
|
}
|
||||||
|
}
|
||||||
|
else
|
||||||
|
{
|
||||||
|
for (AuthenticationComponent authComponent : getUsableAuthenticationComponents())
|
||||||
|
{
|
||||||
|
if (authComponent.getNTLMMode() != NTLMMode.NONE)
|
||||||
|
{
|
||||||
|
if (authComponent.getNTLMMode() == NTLMMode.PASS_THROUGH)
|
||||||
|
{
|
||||||
|
throw new AuthenticationException("The first authentication component to support NTLM supports passthrough");
|
||||||
|
}
|
||||||
|
else
|
||||||
|
{
|
||||||
|
return authComponent.getMD4HashedPassword(userName);
|
||||||
|
}
|
||||||
|
}
|
||||||
|
}
|
||||||
|
throw new AuthenticationException("No MD4 provider available");
|
||||||
|
}
|
||||||
|
|
||||||
|
}
|
||||||
|
|
||||||
|
/**
|
||||||
|
* Get the NTLM mode - this is only what is set if one of the implementations provides support for that mode.
|
||||||
|
*/
|
||||||
|
public NTLMMode getNTLMMode()
|
||||||
|
{
|
||||||
|
if (ntlmMode != null)
|
||||||
|
{
|
||||||
|
switch (ntlmMode)
|
||||||
|
{
|
||||||
|
case NONE:
|
||||||
|
return NTLMMode.NONE;
|
||||||
|
case PASS_THROUGH:
|
||||||
|
for (AuthenticationComponent authComponent : getUsableAuthenticationComponents())
|
||||||
|
{
|
||||||
|
if (authComponent.getNTLMMode() == NTLMMode.PASS_THROUGH)
|
||||||
|
{
|
||||||
|
return NTLMMode.PASS_THROUGH;
|
||||||
|
}
|
||||||
|
}
|
||||||
|
return NTLMMode.NONE;
|
||||||
|
case MD4_PROVIDER:
|
||||||
|
for (AuthenticationComponent authComponent : getUsableAuthenticationComponents())
|
||||||
|
{
|
||||||
|
if (authComponent.getNTLMMode() == NTLMMode.MD4_PROVIDER)
|
||||||
|
{
|
||||||
|
return NTLMMode.MD4_PROVIDER;
|
||||||
|
}
|
||||||
|
}
|
||||||
|
return NTLMMode.NONE;
|
||||||
|
default:
|
||||||
|
return NTLMMode.NONE;
|
||||||
|
}
|
||||||
|
}
|
||||||
|
else
|
||||||
|
{
|
||||||
|
for (AuthenticationComponent authComponent : getUsableAuthenticationComponents())
|
||||||
|
{
|
||||||
|
if (authComponent.getNTLMMode() != NTLMMode.NONE)
|
||||||
|
{
|
||||||
|
return authComponent.getNTLMMode();
|
||||||
|
}
|
||||||
|
}
|
||||||
|
return NTLMMode.NONE;
|
||||||
|
}
|
||||||
|
}
|
||||||
|
|
||||||
|
/**
|
||||||
|
* Get the system user name
|
||||||
|
*/
|
||||||
|
public String getSystemUserName()
|
||||||
|
{
|
||||||
|
return AuthenticationUtil.SYSTEM_USER_NAME;
|
||||||
|
}
|
||||||
|
|
||||||
|
/**
|
||||||
|
* If any implementation supoprts guest then huest is allowed
|
||||||
|
*/
|
||||||
|
public boolean guestUserAuthenticationAllowed()
|
||||||
|
{
|
||||||
|
for (AuthenticationComponent authComponent : getUsableAuthenticationComponents())
|
||||||
|
{
|
||||||
|
if (authComponent.guestUserAuthenticationAllowed())
|
||||||
|
{
|
||||||
|
return true;
|
||||||
|
}
|
||||||
|
}
|
||||||
|
return false;
|
||||||
|
}
|
||||||
|
|
||||||
|
/**
|
||||||
|
* Ste the current authentication
|
||||||
|
*/
|
||||||
|
public Authentication setCurrentAuthentication(Authentication authentication)
|
||||||
|
{
|
||||||
|
return AuthenticationUtil.setCurrentAuthentication(authentication);
|
||||||
|
}
|
||||||
|
|
||||||
|
/**
|
||||||
|
* Set the current user - try all implementations - as some may check the user exists
|
||||||
|
*/
|
||||||
|
public Authentication setCurrentUser(String userName)
|
||||||
|
{
|
||||||
|
for (AuthenticationComponent authComponent : getUsableAuthenticationComponents())
|
||||||
|
{
|
||||||
|
try
|
||||||
|
{
|
||||||
|
return authComponent.setCurrentUser(userName);
|
||||||
|
}
|
||||||
|
catch (AuthenticationException e)
|
||||||
|
{
|
||||||
|
// Ignore and chain
|
||||||
|
}
|
||||||
|
}
|
||||||
|
throw new AuthenticationException("Failed to set current user " + userName);
|
||||||
|
}
|
||||||
|
|
||||||
|
/**
|
||||||
|
* Authenticate as guest - try all in the cahin
|
||||||
|
*/
|
||||||
|
public Authentication setGuestUserAsCurrentUser()
|
||||||
|
{
|
||||||
|
for (AuthenticationComponent authComponent : getUsableAuthenticationComponents())
|
||||||
|
{
|
||||||
|
try
|
||||||
|
{
|
||||||
|
return authComponent.setGuestUserAsCurrentUser();
|
||||||
|
}
|
||||||
|
catch (AuthenticationException e)
|
||||||
|
{
|
||||||
|
// Ignore and chain
|
||||||
|
}
|
||||||
|
}
|
||||||
|
throw new AuthenticationException("Guest authentication is not allowed");
|
||||||
|
}
|
||||||
|
|
||||||
|
/**
|
||||||
|
* Set the system user
|
||||||
|
*/
|
||||||
|
public Authentication setSystemUserAsCurrentUser()
|
||||||
|
{
|
||||||
|
return setCurrentUser(getSystemUserName());
|
||||||
|
}
|
||||||
|
|
||||||
|
/**
|
||||||
|
* Helper to get authentication components
|
||||||
|
*
|
||||||
|
* @return
|
||||||
|
*/
|
||||||
|
private List<AuthenticationComponent> getUsableAuthenticationComponents()
|
||||||
|
{
|
||||||
|
if (mutableAuthenticationComponent == null)
|
||||||
|
{
|
||||||
|
return authenticationComponents;
|
||||||
|
}
|
||||||
|
else
|
||||||
|
{
|
||||||
|
ArrayList<AuthenticationComponent> services = new ArrayList<AuthenticationComponent>(authenticationComponents == null ? 1 : (authenticationComponents.size() + 1));
|
||||||
|
services.add(mutableAuthenticationComponent);
|
||||||
|
if (authenticationComponents != null)
|
||||||
|
{
|
||||||
|
services.addAll(authenticationComponents);
|
||||||
|
}
|
||||||
|
return services;
|
||||||
|
}
|
||||||
|
}
|
||||||
|
|
||||||
|
}
|
@@ -72,7 +72,7 @@ public class SimpleAuthorityServiceTest extends TestCase
|
|||||||
authorityService = (AuthorityService) ctx.getBean("authorityService");
|
authorityService = (AuthorityService) ctx.getBean("authorityService");
|
||||||
pubAuthorityService = (AuthorityService) ctx.getBean("AuthorityService");
|
pubAuthorityService = (AuthorityService) ctx.getBean("AuthorityService");
|
||||||
personService = (PersonService) ctx.getBean("personService");
|
personService = (PersonService) ctx.getBean("personService");
|
||||||
authenticationDAO = (MutableAuthenticationDao) ctx.getBean("alfDaoImpl");
|
authenticationDAO = (MutableAuthenticationDao) ctx.getBean("authenticationDao");
|
||||||
|
|
||||||
this.authenticationComponent.setSystemUserAsCurrentUser();
|
this.authenticationComponent.setSystemUserAsCurrentUser();
|
||||||
|
|
||||||
|
@@ -90,7 +90,7 @@ public class LockOwnerDynamicAuthorityTest extends TestCase
|
|||||||
authenticationComponent = (AuthenticationComponent) ctx.getBean("authenticationComponent");
|
authenticationComponent = (AuthenticationComponent) ctx.getBean("authenticationComponent");
|
||||||
lockService = (LockService) ctx.getBean("lockService");
|
lockService = (LockService) ctx.getBean("lockService");
|
||||||
permissionService = (PermissionService) ctx.getBean("permissionService");
|
permissionService = (PermissionService) ctx.getBean("permissionService");
|
||||||
authenticationDAO = (MutableAuthenticationDao) ctx.getBean("alfDaoImpl");
|
authenticationDAO = (MutableAuthenticationDao) ctx.getBean("authenticationDao");
|
||||||
|
|
||||||
checkOutCheckInService = (CheckOutCheckInService) ctx.getBean("checkOutCheckInService");
|
checkOutCheckInService = (CheckOutCheckInService) ctx.getBean("checkOutCheckInService");
|
||||||
ownableService = (OwnableService) ctx.getBean("ownableService");
|
ownableService = (OwnableService) ctx.getBean("ownableService");
|
||||||
|
@@ -102,7 +102,7 @@ public class AbstractPermissionTest extends BaseSpringTest
|
|||||||
authorityService = (AuthorityService) applicationContext.getBean("authorityService");
|
authorityService = (AuthorityService) applicationContext.getBean("authorityService");
|
||||||
|
|
||||||
authenticationComponent.setCurrentUser(authenticationComponent.getSystemUserName());
|
authenticationComponent.setCurrentUser(authenticationComponent.getSystemUserName());
|
||||||
authenticationDAO = (MutableAuthenticationDao) applicationContext.getBean("alfDaoImpl");
|
authenticationDAO = (MutableAuthenticationDao) applicationContext.getBean("authenticationDao");
|
||||||
|
|
||||||
|
|
||||||
StoreRef storeRef = nodeService.createStore(StoreRef.PROTOCOL_WORKSPACE, "Test_" + System.nanoTime());
|
StoreRef storeRef = nodeService.createStore(StoreRef.PROTOCOL_WORKSPACE, "Test_" + System.nanoTime());
|
||||||
|
@@ -70,8 +70,8 @@ import org.springframework.beans.factory.InitializingBean;
|
|||||||
public class PermissionServiceImpl implements PermissionServiceSPI, InitializingBean
|
public class PermissionServiceImpl implements PermissionServiceSPI, InitializingBean
|
||||||
{
|
{
|
||||||
|
|
||||||
static SimplePermissionReference OLD_ALL_PERMISSIONS_REFERENCE = new SimplePermissionReference(QName.createQName(
|
static SimplePermissionReference OLD_ALL_PERMISSIONS_REFERENCE = new SimplePermissionReference(QName.createQName("", PermissionService.ALL_PERMISSIONS),
|
||||||
"", PermissionService.ALL_PERMISSIONS), PermissionService.ALL_PERMISSIONS);
|
PermissionService.ALL_PERMISSIONS);
|
||||||
|
|
||||||
private static Log log = LogFactory.getLog(PermissionServiceImpl.class);
|
private static Log log = LogFactory.getLog(PermissionServiceImpl.class);
|
||||||
|
|
||||||
@@ -228,8 +228,7 @@ public class PermissionServiceImpl implements PermissionServiceSPI, Initializing
|
|||||||
throw new IllegalArgumentException("Property 'policyComponent' has not been set");
|
throw new IllegalArgumentException("Property 'policyComponent' has not been set");
|
||||||
}
|
}
|
||||||
|
|
||||||
policyComponent.bindClassBehaviour(QName.createQName(NamespaceService.ALFRESCO_URI, "onMoveNode"),
|
policyComponent.bindClassBehaviour(QName.createQName(NamespaceService.ALFRESCO_URI, "onMoveNode"), ContentModel.TYPE_BASE, new JavaBehaviour(this, "onMoveNode"));
|
||||||
ContentModel.TYPE_BASE, new JavaBehaviour(this, "onMoveNode"));
|
|
||||||
|
|
||||||
}
|
}
|
||||||
|
|
||||||
@@ -263,8 +262,7 @@ public class PermissionServiceImpl implements PermissionServiceSPI, Initializing
|
|||||||
NodePermissionEntry nodePremissionEntry = getSetPermissions(nodeRef);
|
NodePermissionEntry nodePremissionEntry = getSetPermissions(nodeRef);
|
||||||
for (PermissionEntry pe : nodePremissionEntry.getPermissionEntries())
|
for (PermissionEntry pe : nodePremissionEntry.getPermissionEntries())
|
||||||
{
|
{
|
||||||
accessPermissions.add(new AccessPermissionImpl(getPermission(pe.getPermissionReference()), pe
|
accessPermissions.add(new AccessPermissionImpl(getPermission(pe.getPermissionReference()), pe.getAccessStatus(), pe.getAuthority()));
|
||||||
.getAccessStatus(), pe.getAuthority()));
|
|
||||||
}
|
}
|
||||||
return accessPermissions;
|
return accessPermissions;
|
||||||
}
|
}
|
||||||
@@ -390,8 +388,7 @@ public class PermissionServiceImpl implements PermissionServiceSPI, Initializing
|
|||||||
if (log.isDebugEnabled())
|
if (log.isDebugEnabled())
|
||||||
{
|
{
|
||||||
log.debug("Permission <"
|
log.debug("Permission <"
|
||||||
+ perm + "> is " + (result ? "allowed" : "denied") + " for "
|
+ perm + "> is " + (result ? "allowed" : "denied") + " for " + authenticationComponent.getCurrentUserName() + " on node " + nodeService.getPath(nodeRef));
|
||||||
+ authenticationComponent.getCurrentUserName() + " on node " + nodeService.getPath(nodeRef));
|
|
||||||
}
|
}
|
||||||
|
|
||||||
status = result ? AccessStatus.ALLOWED : AccessStatus.DENIED;
|
status = result ? AccessStatus.ALLOWED : AccessStatus.DENIED;
|
||||||
@@ -649,21 +646,16 @@ public class PermissionServiceImpl implements PermissionServiceSPI, Initializing
|
|||||||
// Set the required node permissions
|
// Set the required node permissions
|
||||||
if (required.equals(getPermissionReference(ALL_PERMISSIONS)))
|
if (required.equals(getPermissionReference(ALL_PERMISSIONS)))
|
||||||
{
|
{
|
||||||
nodeRequirements = modelDAO.getRequiredPermissions(
|
nodeRequirements = modelDAO.getRequiredPermissions(getPermissionReference(PermissionService.FULL_CONTROL), typeQName, aspectQNames, RequiredPermission.On.NODE);
|
||||||
getPermissionReference(PermissionService.FULL_CONTROL), typeQName, aspectQNames,
|
|
||||||
RequiredPermission.On.NODE);
|
|
||||||
}
|
}
|
||||||
else
|
else
|
||||||
{
|
{
|
||||||
nodeRequirements = modelDAO.getRequiredPermissions(required, typeQName, aspectQNames,
|
nodeRequirements = modelDAO.getRequiredPermissions(required, typeQName, aspectQNames, RequiredPermission.On.NODE);
|
||||||
RequiredPermission.On.NODE);
|
|
||||||
}
|
}
|
||||||
|
|
||||||
parentRequirements = modelDAO.getRequiredPermissions(required, typeQName, aspectQNames,
|
parentRequirements = modelDAO.getRequiredPermissions(required, typeQName, aspectQNames, RequiredPermission.On.PARENT);
|
||||||
RequiredPermission.On.PARENT);
|
|
||||||
|
|
||||||
childrenRequirements = modelDAO.getRequiredPermissions(required, typeQName, aspectQNames,
|
childrenRequirements = modelDAO.getRequiredPermissions(required, typeQName, aspectQNames, RequiredPermission.On.CHILDREN);
|
||||||
RequiredPermission.On.CHILDREN);
|
|
||||||
|
|
||||||
// Find all the permissions that grant the allowed permission
|
// Find all the permissions that grant the allowed permission
|
||||||
// All permissions are treated specially.
|
// All permissions are treated specially.
|
||||||
@@ -695,8 +687,7 @@ public class PermissionServiceImpl implements PermissionServiceSPI, Initializing
|
|||||||
* @param recursiveIn
|
* @param recursiveIn
|
||||||
* @return
|
* @return
|
||||||
*/
|
*/
|
||||||
boolean evaluate(Set<String> authorisations, NodeRef nodeRef, Set<Pair<String, PermissionReference>> denied,
|
boolean evaluate(Set<String> authorisations, NodeRef nodeRef, Set<Pair<String, PermissionReference>> denied, MutableBoolean recursiveIn)
|
||||||
MutableBoolean recursiveIn)
|
|
||||||
{
|
{
|
||||||
// Do we defer our required test to a parent (yes if not null)
|
// Do we defer our required test to a parent (yes if not null)
|
||||||
MutableBoolean recursiveOut = null;
|
MutableBoolean recursiveOut = null;
|
||||||
@@ -771,8 +762,7 @@ public class PermissionServiceImpl implements PermissionServiceSPI, Initializing
|
|||||||
if (pr.equals(required))
|
if (pr.equals(required))
|
||||||
{
|
{
|
||||||
// Recursive permission
|
// Recursive permission
|
||||||
success &= this.evaluate(authorisations, car.getParentRef(), locallyDenied,
|
success &= this.evaluate(authorisations, car.getParentRef(), locallyDenied, recursiveOut);
|
||||||
recursiveOut);
|
|
||||||
if ((recursiveOut != null) && recursiveOut.getValue())
|
if ((recursiveOut != null) && recursiveOut.getValue())
|
||||||
{
|
{
|
||||||
if (recursiveIn != null)
|
if (recursiveIn != null)
|
||||||
@@ -848,8 +838,7 @@ public class PermissionServiceImpl implements PermissionServiceSPI, Initializing
|
|||||||
|
|
||||||
}
|
}
|
||||||
|
|
||||||
public boolean hasSinglePermission(Set<String> authorisations, NodeRef nodeRef,
|
public boolean hasSinglePermission(Set<String> authorisations, NodeRef nodeRef, Set<Pair<String, PermissionReference>> denied)
|
||||||
Set<Pair<String, PermissionReference>> denied)
|
|
||||||
{
|
{
|
||||||
nodeRef = tenantService.getName(nodeRef);
|
nodeRef = tenantService.getName(nodeRef);
|
||||||
|
|
||||||
@@ -974,8 +963,7 @@ public class PermissionServiceImpl implements PermissionServiceSPI, Initializing
|
|||||||
// All the sets that grant this permission must be
|
// All the sets that grant this permission must be
|
||||||
// denied
|
// denied
|
||||||
// Note that granters includes the orginal permission
|
// Note that granters includes the orginal permission
|
||||||
Set<PermissionReference> granters = modelDAO
|
Set<PermissionReference> granters = modelDAO.getGrantingPermissions(pe.getPermissionReference());
|
||||||
.getGrantingPermissions(pe.getPermissionReference());
|
|
||||||
for (PermissionReference granter : granters)
|
for (PermissionReference granter : granters)
|
||||||
{
|
{
|
||||||
deniedSet.add(new Pair<String, PermissionReference>(pe.getAuthority(), granter));
|
deniedSet.add(new Pair<String, PermissionReference>(pe.getAuthority(), granter));
|
||||||
@@ -991,8 +979,7 @@ public class PermissionServiceImpl implements PermissionServiceSPI, Initializing
|
|||||||
|
|
||||||
// All permission excludes all permissions available for
|
// All permission excludes all permissions available for
|
||||||
// the node.
|
// the node.
|
||||||
if (pe.getPermissionReference().equals(getAllPermissionReference())
|
if (pe.getPermissionReference().equals(getAllPermissionReference()) || pe.getPermissionReference().equals(OLD_ALL_PERMISSIONS_REFERENCE))
|
||||||
|| pe.getPermissionReference().equals(OLD_ALL_PERMISSIONS_REFERENCE))
|
|
||||||
{
|
{
|
||||||
for (PermissionReference deny : modelDAO.getAllPermissions(nodeRef))
|
for (PermissionReference deny : modelDAO.getAllPermissions(nodeRef))
|
||||||
{
|
{
|
||||||
@@ -1048,8 +1035,7 @@ public class PermissionServiceImpl implements PermissionServiceSPI, Initializing
|
|||||||
* the set of denied permissions/authority pais
|
* the set of denied permissions/authority pais
|
||||||
* @return
|
* @return
|
||||||
*/
|
*/
|
||||||
private boolean isGranted(PermissionEntry pe, Set<String> authorisations,
|
private boolean isGranted(PermissionEntry pe, Set<String> authorisations, Set<Pair<String, PermissionReference>> denied)
|
||||||
Set<Pair<String, PermissionReference>> denied)
|
|
||||||
{
|
{
|
||||||
// If the permission entry denies then we just deny
|
// If the permission entry denies then we just deny
|
||||||
if (pe.isDenied())
|
if (pe.isDenied())
|
||||||
@@ -1059,16 +1045,41 @@ public class PermissionServiceImpl implements PermissionServiceSPI, Initializing
|
|||||||
|
|
||||||
// The permission is allowed but we deny it as it is in the denied
|
// The permission is allowed but we deny it as it is in the denied
|
||||||
// set
|
// set
|
||||||
|
|
||||||
if (denied != null)
|
if (denied != null)
|
||||||
{
|
{
|
||||||
Pair<String, PermissionReference> specific = new Pair<String, PermissionReference>(pe.getAuthority(),
|
Pair<String, PermissionReference> specific = new Pair<String, PermissionReference>(pe.getAuthority(), required);
|
||||||
required);
|
|
||||||
if (denied.contains(specific))
|
if (denied.contains(specific))
|
||||||
{
|
{
|
||||||
return false;
|
return false;
|
||||||
}
|
}
|
||||||
}
|
}
|
||||||
|
|
||||||
|
// any deny denies
|
||||||
|
|
||||||
|
if (false)
|
||||||
|
{
|
||||||
|
if (denied != null)
|
||||||
|
{
|
||||||
|
for (String auth : authorisations)
|
||||||
|
{
|
||||||
|
Pair<String, PermissionReference> specific = new Pair<String, PermissionReference>(auth, required);
|
||||||
|
if (denied.contains(specific))
|
||||||
|
{
|
||||||
|
return false;
|
||||||
|
}
|
||||||
|
for (PermissionReference perm : granters)
|
||||||
|
{
|
||||||
|
specific = new Pair<String, PermissionReference>(auth, perm);
|
||||||
|
if (denied.contains(specific))
|
||||||
|
{
|
||||||
|
return false;
|
||||||
|
}
|
||||||
|
}
|
||||||
|
}
|
||||||
|
}
|
||||||
|
}
|
||||||
|
|
||||||
// If the permission has a match in both the authorities and
|
// If the permission has a match in both the authorities and
|
||||||
// granters list it is allowed
|
// granters list it is allowed
|
||||||
// It applies to the current user and it is granted
|
// It applies to the current user and it is granted
|
||||||
@@ -1124,8 +1135,7 @@ public class PermissionServiceImpl implements PermissionServiceSPI, Initializing
|
|||||||
return false;
|
return false;
|
||||||
}
|
}
|
||||||
Pair other = (Pair) o;
|
Pair other = (Pair) o;
|
||||||
return EqualsHelper.nullSafeEquals(this.getA(), other.getA())
|
return EqualsHelper.nullSafeEquals(this.getA(), other.getA()) && EqualsHelper.nullSafeEquals(this.getB(), other.getB());
|
||||||
&& EqualsHelper.nullSafeEquals(this.getB(), other.getB());
|
|
||||||
}
|
}
|
||||||
|
|
||||||
@Override
|
@Override
|
||||||
@@ -1167,15 +1177,13 @@ public class PermissionServiceImpl implements PermissionServiceSPI, Initializing
|
|||||||
return permissionsDaoComponent.getAllSetPermissions(authority);
|
return permissionsDaoComponent.getAllSetPermissions(authority);
|
||||||
}
|
}
|
||||||
|
|
||||||
public Set<NodeRef> findNodesByAssignedPermissionForCurrentUser(String permission, boolean allow, boolean includeContainingAuthorities,
|
public Set<NodeRef> findNodesByAssignedPermissionForCurrentUser(String permission, boolean allow, boolean includeContainingAuthorities, boolean exactPermissionMatch)
|
||||||
boolean exactPermissionMatch)
|
|
||||||
{
|
{
|
||||||
String currentUser = authenticationComponent.getCurrentUserName();
|
String currentUser = authenticationComponent.getCurrentUserName();
|
||||||
return findNodesByAssignedPermission(currentUser, permission, allow, includeContainingAuthorities, exactPermissionMatch);
|
return findNodesByAssignedPermission(currentUser, permission, allow, includeContainingAuthorities, exactPermissionMatch);
|
||||||
}
|
}
|
||||||
|
|
||||||
public Set<NodeRef> findNodesByAssignedPermission(String authority, String permission, boolean allow,
|
public Set<NodeRef> findNodesByAssignedPermission(String authority, String permission, boolean allow, boolean includeContainingAuthorities, boolean includeContainingPermissions)
|
||||||
boolean includeContainingAuthorities, boolean includeContainingPermissions)
|
|
||||||
{
|
{
|
||||||
// TODO: owned nodes and add owner rights ??
|
// TODO: owned nodes and add owner rights ??
|
||||||
// Does not include dynamic permissions (they would have to be done by query - e.g. owership and OWNER rights)
|
// Does not include dynamic permissions (they would have to be done by query - e.g. owership and OWNER rights)
|
||||||
|
@@ -149,7 +149,7 @@ public abstract class BaseVersionStoreTest extends BaseSpringTest
|
|||||||
this.authenticationService = (AuthenticationService)applicationContext.getBean("authenticationService");
|
this.authenticationService = (AuthenticationService)applicationContext.getBean("authenticationService");
|
||||||
this.transactionService = (TransactionService)this.applicationContext.getBean("transactionComponent");
|
this.transactionService = (TransactionService)this.applicationContext.getBean("transactionComponent");
|
||||||
this.txnHelper = (RetryingTransactionHelper) applicationContext.getBean("retryingTransactionHelper");
|
this.txnHelper = (RetryingTransactionHelper) applicationContext.getBean("retryingTransactionHelper");
|
||||||
this.authenticationDAO = (MutableAuthenticationDao) applicationContext.getBean("alfDaoImpl");
|
this.authenticationDAO = (MutableAuthenticationDao) applicationContext.getBean("authenticationDao");
|
||||||
this.nodeArchiveService = (NodeArchiveService) applicationContext.getBean("nodeArchiveService");
|
this.nodeArchiveService = (NodeArchiveService) applicationContext.getBean("nodeArchiveService");
|
||||||
this.nodeService = (NodeService)applicationContext.getBean("nodeService");
|
this.nodeService = (NodeService)applicationContext.getBean("nodeService");
|
||||||
|
|
||||||
|
@@ -5,7 +5,11 @@
|
|||||||
|
|
||||||
# Namespaces
|
# Namespaces
|
||||||
namespace.prefix.cm=http://www.alfresco.org/model/content/1.0
|
namespace.prefix.cm=http://www.alfresco.org/model/content/1.0
|
||||||
|
namespace.prefix.test=http://www.alfresco.org/model/test/1.0
|
||||||
|
|
||||||
# Mappings
|
# Mappings
|
||||||
name=cm:title
|
name=cm:title
|
||||||
description=cm:description
|
description=cm:description
|
||||||
|
multi-value-text=test:multi-value-text
|
||||||
|
multi-value-node=test:multi-value-node
|
||||||
|
complex-node=test:complex-node
|
||||||
|
@@ -8,3 +8,6 @@
|
|||||||
# Mappings
|
# Mappings
|
||||||
name=/projectDescription/name/text()
|
name=/projectDescription/name/text()
|
||||||
description=/projectDescription/comment/text()
|
description=/projectDescription/comment/text()
|
||||||
|
multi-value-text=/projectDescription/natures/nature/text()
|
||||||
|
multi-value-node=/projectDescription/natures/nature
|
||||||
|
complex-node=/projectDescription/natures
|
Reference in New Issue
Block a user