<?xml version='1.0' encoding='UTF-8'?>
<!DOCTYPE beans PUBLIC '-//SPRING//DTD BEAN//EN' 'http://www.springframework.org/dtd/spring-beans.dtd'>

<!-- ===================================================================  -->
<!-- This file contains the bean definitions that support authentication  -->
<!-- ===================================================================  -->

<!--                                                                        -->
<!-- Acegi is used for authentication and protecting method calls on public -->
<!-- services. To do this requires our authentication mechanism to work     -->
<!-- within the acegi framework.                                            -->
<!--                                                                        -->
<!-- It is important to decide if user names are case sensitive or not.     -->
<!-- This is configured in repository.properties.                           -->
<!--                                                                        -->
<!--                                                                        -->
<!-- TODO:                                                                  -->
<!--                                                                        -->
<!-- The transactional wrappers should be removed from the beans in this    -->
<!-- file. This should be done in the public services definitions.          -->
<!-- This requires some tests to be fixed up.                               -->
<!--                                                                        -->


<beans>
    <!--                                                                    -->
    <!-- The Acegi authentication manager.                                  -->
    <!--                                                                    -->
    <!-- Provders are asked to authenticate in order.                       -->
    <!-- First, is a provider that checks if an acegi authentication object -->
    <!-- is already bound to the executing thread. If it is, and it is set  -->
    <!-- as authenticated then no further authentication is required. If    -->
    <!-- this is absent, Acegi validates the password for every method      -->
    <!-- invocation, which is too CPU expensive. If we set an               -->
    <!-- authentication based on a ticket etc .... or we want to set the    -->
    <!-- the system user as the current user ... we do not have the         -->
    <!-- password. So if we have set an authentication and set it as        -->
    <!-- authenticated that is sufficient to validate the user.             -->
    <!--                                                                    -->
    <!-- If the authentication bound to the current thread is not set as    -->
    <!-- authenticated the standard Acegi DAO Authentication provider       -->
    <!-- is used to authenticate.                                           -->
    <!--                                                                    -->

    <bean id="authenticationManager" class="net.sf.acegisecurity.providers.ProviderManager">
        <property name="providers">
            <list>
                <ref bean="authenticatedAuthenticationPassthroughProvider" />
            </list>
        </property>
    </bean>


    <!-- An authentication Provider that just believes authentications      -->
    <!-- bound to the local thread are valid if they are set as             -->
    <!-- authenticated.                                                     -->

    <bean id="authenticatedAuthenticationPassthroughProvider" class="org.alfresco.repo.security.authentication.AuthenticatedAuthenticationPassthroughProvider" />

    <!-- The authority DAO implements an interface extended from the Acegi  -->
    <!-- DAO that supports CRUD.                                            -->

   <!-- The editable authentication chain -->
   <bean id="Authentication" class="org.alfresco.repo.management.subsystems.DefaultChildApplicationContextManager"
      parent="abstractPropertyBackedBean">
      <property name="defaultChain">
         <value>${authentication.chain}</value>
      </property>
   </bean>

   <!-- Acegi providers now proxy to the first authentication DAO in the chain -->
   <bean id="authenticationDao" class="org.alfresco.repo.management.subsystems.ChainingSubsystemProxyFactory">
      <property name="applicationContextManager">
         <ref bean="Authentication" />
      </property>
      <property name="interfaces">
         <list>
            <value>org.alfresco.repo.security.authentication.MutableAuthenticationDao</value>
         </list>
      </property>
      <!-- A generic fallback implementation, in case the chain doesn't provide one-->
      <property name="defaultTarget">
         <bean class="org.alfresco.repo.security.authentication.DefaultMutableAuthenticationDao">
            <property name="allowSetEnabled" value="true" />
            <property name="allowGetEnabled" value="true" />
            <property name="allowDeleteUser" value="true" />
            <property name="allowCreateUser" value="true" />
         </bean>
      </property>
   </bean>

   <!-- Allow the authentication subsystem to listen for SMB Server session events -->
   <bean id="SmbSessionListener" class="org.alfresco.repo.management.subsystems.ChainingSubsystemProxyFactory">
      <property name="applicationContextManager">
         <ref bean="Authentication" />
      </property>
      <property name="interfaces">
         <list>
            <value>org.alfresco.jlan.server.SessionListener</value>
         </list>
      </property>
      <!-- A benign fallback implementation, in case the chain isn't interested! -->
      <property name="defaultTarget">
         <bean class="org.alfresco.filesys.NullSessionListener" />
      </property>
   </bean>

   <bean id="CifsAuthenticator" class="org.alfresco.repo.management.subsystems.ChainingSubsystemProxyFactory">
      <property name="applicationContextManager">
         <ref bean="Authentication" />
      </property>
      <property name="sourceBeanName">
         <value>cifsAuthenticator</value>
      </property>
      <property name="interfaces">
         <list>
            <value>org.alfresco.jlan.server.auth.ICifsAuthenticator</value>
            <value>org.alfresco.repo.management.subsystems.ActivateableBean</value>
         </list>
      </property>
   </bean>

   <bean id="FtpAuthenticator" class="org.alfresco.repo.management.subsystems.ChainingSubsystemProxyFactory">
      <property name="applicationContextManager">
         <ref bean="Authentication" />
      </property>
      <property name="sourceBeanName">
         <value>ftpAuthenticator</value>
      </property>
      <property name="interfaces">
         <list>
            <value>org.alfresco.jlan.ftp.FTPAuthenticator</value>
            <value>org.alfresco.repo.management.subsystems.ActivateableBean</value>
         </list>
      </property>
      <!-- A generic fallback implementation, in case the chain doesn't provide one-->
      <property name="defaultTarget">
         <bean class="org.alfresco.filesys.auth.ftp.AlfrescoFtpAuthenticator" parent="ftpAuthenticatorBase" />
      </property>
   </bean>
    
    <!-- Passwords are encoded using MD4                                    -->
    <!-- This is not ideal and only done to be compatible with NTLM         -->
    <!-- authentication against the default authentication mechanism.       -->

    <bean id="passwordEncoder" class="org.alfresco.repo.security.authentication.MD4PasswordEncoderImpl"></bean>


    <!-- The Authentication Service implementation.                         -->
    <!--                                                                    -->
    <!-- Each method 'chains' through all AuthenticationService implementations in the authentication chain -->

    <bean id="authenticationService" class="org.alfresco.repo.security.authentication.subsystems.SubsystemChainingAuthenticationService">
        <property name="sysAdminParams">
            <ref bean="sysAdminParams" />
        </property>
        <property name="applicationContextManager">
            <ref bean="Authentication" />
        </property>
        <property name="sourceBeanName">
            <value>localAuthenticationService</value>
        </property>
    </bean>

    <!-- The public authentication component.                                      -->

    <bean id="AuthenticationComponent" class="org.springframework.transaction.interceptor.TransactionProxyFactoryBean">
        <property name="proxyInterfaces">
            <value>org.alfresco.repo.security.authentication.AuthenticationComponent</value>
        </property>
        <property name="transactionManager">
            <ref bean="transactionManager" />
        </property>
        <property name="target">
            <ref bean="authenticationComponent" />
        </property>
        <property name="transactionAttributes">
            <props>
                <prop key="*">${server.transaction.mode.default}</prop>
            </props>
        </property>
    </bean>

    <!-- Parent bean for beans derived from AbstractAuthenticationComponent -->
    <bean id="authenticationComponentBase" abstract="true">
       <property name="authenticationContext">
            <ref bean="authenticationContext"/>
        </property>
       <property name="userRegistrySynchronizer">
            <ref bean="userRegistrySynchronizer"/>
        </property>
    </bean>

    <!-- The chaining authentication component -->
    <bean id="authenticationComponent" class="org.alfresco.repo.security.authentication.subsystems.SubsystemChainingAuthenticationComponent"
        parent="authenticationComponentBase">
        <property name="nodeService">
            <ref bean="nodeService" />
        </property>
        <property name="personService">
            <ref bean="personService" />
        </property>
        <property name="transactionService">
            <ref bean="transactionService" />
        </property>
        <property name="applicationContextManager">
            <ref bean="Authentication" />
        </property>
        <property name="sourceBeanName">
            <value>authenticationComponent</value>
        </property>
    </bean>

   <!-- Import the user registry synchronizer from the synchronization subsystem -->
   <bean id="userRegistrySynchronizer" class="org.alfresco.repo.management.subsystems.SubsystemProxyFactory">
      <property name="sourceApplicationContextFactory">
         <ref bean="Synchronization" />
      </property>
      <property name="interfaces">
         <list>
            <value>org.alfresco.repo.security.sync.UserRegistrySynchronizer</value>
         </list>
      </property>
   </bean>

    <bean id="authenticationContext" class="org.alfresco.repo.security.authentication.AuthenticationContextImpl">
       <property name="tenantService">
            <ref bean="tenantService"/>
        </property>
    </bean>

    <!-- Simple Authentication component that rejects all authentication requests -->
    <!-- Use this defintion for Novell IChain integration.                        -->
    <!-- It should never go to the login screen  so this is not required          -->

    <!--
    <bean id="authenticationComponent"
          class="org.alfresco.repo.security.authentication.SimpleAcceptOrRejectAllAuthenticationComponentImpl"
          parent="authenticationComponentBase">
        <property name="accept">
            <value>true</value>
        </property>
        </property>
        <property name="nodeService">
            <ref bean="nodeService" />
        </property>
        <property name="personService">
            <ref bean="personService" />
        </property>
        <property name="transactionService">
            <ref bean="transactionService" />
        </property>    
    </bean>
    -->

    <!-- support to match user names -->
    
    <bean id="userNameMatcher" class="org.alfresco.repo.security.person.UserNameMatcherImpl">
        <property name="userNamesAreCaseSensitive">
          <value>${user.name.caseSensitive}</value>
        </property>
        <property name="domainNamesAreCaseSensitive">
          <value>${domain.name.caseSensitive}</value>
        </property>
        <property name="domainSeparator">
          <value>${domain.separator}</value>
        </property>  
    </bean>
    
    <!-- The person service.                                                -->

    <bean id="personService" class="org.alfresco.repo.security.person.PersonServiceImpl" init-method="init">
        <property name="transactionService">
            <ref bean="transactionService" />
        </property>
        <property name="nodeService">
            <ref bean="nodeService" />
        </property>
        <property name="tenantService">
            <ref bean="tenantService"/>
        </property>
        <property name="searchService">
            <ref bean="admSearchService" />
        </property>
        <property name="permissionServiceSPI">
            <ref bean="permissionServiceImpl" />
        </property>
        <property name="authorityService">
           <ref bean="authorityService" />
        </property>
        <property name="authenticationService">
           <ref bean="authenticationService" />
        </property>
        <property name="dictionaryService">
           <ref bean="dictionaryService" />
        </property>
        <property name="namespacePrefixResolver">
            <ref bean="namespaceService" />
        </property>
        <property name="policyComponent">
            <ref bean="policyComponent"/>
        </property>
        <property name="personCache">
            <ref bean="personCache" />
        </property>
        <property name="permissionsManager">
            <ref bean="personServicePermissionsManager" />
        </property>
        <property name="aclDao">
            <ref bean="aclDaoComponent" />
        </property>
        <property name="homeFolderManager">
            <ref bean="homeFolderManager" />
        </property>
        <!-- Configurable properties.                                 -->
        <!--                                                          -->
        <!-- TODO:                                                    -->
        <!-- Add support for creating real home spaces adn setting    -->
        <!-- permissions on the hame space and people created.        -->
        <!--                                                          -->
        <!-- The store in which people are persisted.                 -->
        <property name="storeUrl">
           <value>${spaces.store}</value>
        </property>
        <!-- Some authentication mechanisms may need to create people -->
        <!-- in the repository on demand. This enables that feature.  -->
        <!-- If dsiabled an error will be generated for missing       -->
        <!-- people. If enabled then a person will be created and     -->
        <!-- persisted.                                               -->
        <!-- Valid values are                                         -->
        <!--     ${server.transaction.allow-writes}                   -->
        <!--     false                                                -->
        <property name="createMissingPeople">
           <value>${server.transaction.allow-writes}</value>
        </property>
        <property name="userNameMatcher">
           <ref bean="userNameMatcher" />
        </property>
        <!-- New properties after 1.4.0 to deal with duplicate user ids when found -->
        <property name="processDuplicates">
            <value>true</value>
        </property>
        <!-- one of:  LEAVE, SPLIT, DELETE -->
        <property name="duplicateMode">
            <value>SPLIT</value>
        </property>
        <property name="lastIsBest">
            <value>true</value>
        </property>
        <property name="includeAutoCreated">
            <value>false</value>
        </property>
    </bean>

    <bean name="personServicePermissionsManager" class="org.alfresco.repo.security.person.PermissionsManagerImpl" >
        <property name="permissionService">
            <ref bean="permissionServiceImpl" />
        </property>
        <property name="ownableService">
            <ref bean="ownableService" />
        </property>
        <property name="ownerPermissions">
            <set>
                <value>All</value>
            </set>
        </property>
        <property name="userPermissions">
            <set>
                <value>All</value>
            </set>
        </property>
    </bean>
    
    <bean name="homeFolderManager" class="org.alfresco.repo.security.person.HomeFolderManager" init-method="init">
        <property name="nodeService">
            <ref bean="nodeService" />
        </property>
        <property name="policyComponent">
            <ref bean="policyComponent" />
        </property>
        <property name="defaultProvider">
            <ref bean="userHomesHomeFolderProvider" />
        </property>
        <property name="enableHomeFolderCreationAsPeopleAreCreated">
           <!--<value>false</value> -->
            <value>${home.folder.creation.eager}</value>
        </property>
    </bean>

    <bean name="baseHomeFolderProvider" class="org.alfresco.repo.security.person.AbstractHomeFolderProvider" abstract="true">
        <!-- Requests services via ServiceRegistry for auditability -->
        <property name="serviceRegistry">
            <ref bean="ServiceRegistry" />
        </property>
        <property name="homeFolderManager">
            <ref bean="homeFolderManager" />
        </property>
        <property name="tenantService">
            <ref bean="tenantService" />
        </property>
    </bean>

    <bean name="companyHomeFolderProvider" class="org.alfresco.repo.security.person.ExistingPathBasedHomeFolderProvider" parent="baseHomeFolderProvider">
        <property name="path">
           <value>/${spaces.company_home.childname}</value>
        </property>
        <property name="storeUrl">
           <value>${spaces.store}</value>
        </property>
    </bean>

    <bean name="guestHomeFolderProviderPermissionsManager" class="org.alfresco.repo.security.person.PermissionsManagerImpl">
        <property name="permissionService">
            <ref bean="permissionServiceImpl" />
        </property>
        <property name="ownableService">
            <ref bean="ownableService" />
        </property>
         <property name="userPermissions">
            <set>
                <value>Consumer</value>
            </set>
        </property>
    </bean>
         
    
    <bean name="guestHomeFolderProvider" class="org.alfresco.repo.security.person.ExistingPathBasedHomeFolderProvider" parent="baseHomeFolderProvider">
        <!-- Requests services via ServiceRegistry for auditability -->
        <property name="serviceRegistry">
            <ref bean="ServiceRegistry" />
        </property>
        <property name="path">
           <value>/${spaces.company_home.childname}/${spaces.guest_home.childname}</value>
        </property>
        <property name="storeUrl">
           <value>${spaces.store}</value>
        </property>
        <property name="onCreatePermissionsManager">
            <ref bean="guestHomeFolderProviderPermissionsManager" />
        </property>
        <property name="onReferencePermissionsManager">
            <ref bean="guestHomeFolderProviderPermissionsManager" />
        </property>
    </bean>

    <bean name="bootstrapHomeFolderProvider" class="org.alfresco.repo.security.person.BootstrapHomeFolderProvider" parent="baseHomeFolderProvider" />

    <bean name="defaultOnCreatePermissionsManager" class="org.alfresco.repo.security.person.PermissionsManagerImpl" >
        <property name="permissionService">
            <ref bean="permissionServiceImpl" />
        </property>
        <property name="ownableService">
            <ref bean="ownableService" />
        </property>
        <property name="inheritPermissions">
            <value>false</value>
        </property>
        <property name="ownerPermissions">
            <set>
                <value>All</value>
            </set>
        </property>
        <property name="userPermissions">
            <set>
                <value>All</value>
            </set>
        </property>
    </bean>
    
    <bean name="defaultOnReferencePermissionsManager" class="org.alfresco.repo.security.person.PermissionsManagerImpl" >
        <property name="permissionService">
            <ref bean="permissionServiceImpl" />
        </property>
        <property name="ownableService">
            <ref bean="ownableService" />
        </property>
        <property name="userPermissions">
            <set>
                <value>All</value>
            </set>
        </property>
    </bean>
    
    <bean name="personalHomeFolderProvider" class="org.alfresco.repo.security.person.UIDBasedHomeFolderProvider"  parent="baseHomeFolderProvider">
        <!-- Requests services via ServiceRegistry for auditability -->
        <property name="serviceRegistry">
            <ref bean="ServiceRegistry" />
        </property>
        <property name="path">
           <value>/${spaces.company_home.childname}</value>
        </property>
        <property name="storeUrl">
           <value>${spaces.store}</value>
        </property>
        <property name="onCreatePermissionsManager">
            <ref bean="defaultOnCreatePermissionsManager" />
        </property>
        <property name="onReferencePermissionsManager">
            <ref bean="defaultOnReferencePermissionsManager" />
        </property>
    </bean>

    <bean name="userHomesHomeFolderProvider" class="org.alfresco.repo.security.person.UIDBasedHomeFolderProvider" parent="baseHomeFolderProvider">
        <property name="path">
           <value>/${spaces.company_home.childname}/${spaces.user_homes.childname}</value>
        </property>
        <property name="storeUrl">
           <value>${spaces.store}</value>
        </property>
        <property name="onCreatePermissionsManager">
            <ref bean="defaultOnCreatePermissionsManager" />
        </property>
        <property name="onReferencePermissionsManager">
            <ref bean="defaultOnReferencePermissionsManager" />
        </property>
    </bean>


    <!-- The ticket component.                                              -->
    <!-- Used for reauthentication                                          -->
    <bean id="ticketComponent" class="org.alfresco.repo.security.authentication.InMemoryTicketComponentImpl">
        <property name="ticketsCache">
            <ref bean="ticketsCache"/>
        </property>
        <!-- The period for which tickets are valid in XML duration format. -->
        <!-- The default is P1H for one hour.                               -->
        <property name="validDuration">
            <value>PT1H</value>
        </property>
        <!-- Do tickets expire or live for ever?                            -->
        <property name="ticketsExpire">
            <value>false</value>
        </property>
        <!-- Are tickets only valid for a single use?                       -->
        <property name="oneOff">
            <value>false</value>
        </property>
        <!-- If ticketsEpire is true then how they should expire -->
        <!-- AFTER_INACTIVITY, AFTER_FIXED_TIME, DO_NOT_EXPIRE  -->
        <!-- The default is AFTER_FIXED_TIME -->
        <property name="expiryMode">
            <value>AFTER_FIXED_TIME</value>
        </property>
    </bean>
    
    <!--  -->
    <bean id="nameBasedUserNameGenerator" class="org.alfresco.repo.security.authentication.NameBasedUserNameGenerator">
            <!-- name patterns available:
       		%lastName%,  lower case last name
       		%firstName%, lower case first name
       		%emailAddress% email address
           	%i% lower case first name inital
     		-->
        <property name="namePattern">
        	<value>%firstName%_%lastName%</value>
        </property>
        
        <property name="userNameLength">
            <value>10</value>
        </property>
    </bean>
    
    <!-- Used for generating user names                                     -->
    <bean id="userNameGenerator" class="org.alfresco.repo.security.authentication.TenantAwareUserNameGenerator">
        <property name="generator">
            <ref bean="nameBasedUserNameGenerator"/>
        </property>
        <property name="tenantService">
            <ref bean="tenantService"/>
        </property>
    </bean>
    
    <!-- Used for generating passwords -->
    <bean id="passwordGenerator" class="org.alfresco.repo.security.authentication.BasicPasswordGenerator">
        <property name="passwordLength">
            <value>8</value>
        </property>
    </bean>
    
    <!-- Authentication Util initialization -->
    <bean id="authenticationUtil" class="org.alfresco.repo.security.authentication.AuthenticationUtil">
        <property name="defaultAdminUserName"><value>${alfresco_user_store.adminusername}</value></property>
        <property name="defaultGuestUserName"><value>${alfresco_user_store.guestusername}</value></property>
    </bean>
    
</beans>
