<commit_before><?xml version="1.0" encoding="UTF-8"?>
<beans xmlns="http://www.springframework.org/schema/beans" xmlns:xsi="http://www.w3.org/2001/XMLSchema-instance"
  xmlns:sec="http://www.springframework.org/schema/security" xmlns:oauth="http://www.springframework.org/schema/security/oauth2"
  xsi:schemaLocation="http://www.springframework.org/schema/beans http://www.springframework.org/schema/beans/spring-beans-4.3.xsd
    http://www.springframework.org/schema/security http://www.springframework.org/schema/security/spring-security-4.2.xsd
    http://www.springframework.org/schema/security/oauth2 http://www.springframework.org/schema/security/spring-security-oauth2.xsd">

  <!-- OAuth2 -->

  <bean id="oauthAuthenticationEntryPoint"
    class="org.springframework.security.oauth2.provider.error.OAuth2AuthenticationEntryPoint">
    <property name="realmName" value="dhis2/oauth2" />
  </bean>

  <bean id="oauthAccessDeniedHandler" class="org.springframework.security.oauth2.provider.error.OAuth2AccessDeniedHandler" />

  <oauth:resource-server id="resourceServerFilter" token-services-ref="tokenServices" entry-point-ref="oauthAuthenticationEntryPoint"
    authentication-manager-ref="oAuth2AuthenticationManager" stateless="false" />

  <sec:http pattern="/uaa/oauth/token/**" create-session="stateless" authentication-manager-ref="authenticationManager" disable-url-rewriting="true"
    use-expressions="false" access-decision-manager-ref="accessDecisionManager">
    <sec:intercept-url pattern="/uaa/oauth/token/**" access="IS_AUTHENTICATED_FULLY" method="POST" />
    <sec:anonymous enabled="false" />
    <sec:http-basic entry-point-ref="oauthAuthenticationEntryPoint" />
    <sec:access-denied-handler ref="oauthAccessDeniedHandler" />
    <sec:csrf disabled="true" />
  </sec:http>

  <sec:http pattern="/uaa/oauth/authorize/**" authentication-manager-ref="authenticationManager" disable-url-rewriting="true" use-expressions="false"
    create-session="ifRequired" access-decision-manager-ref="accessDecisionManager">
    <sec:intercept-url pattern="/uaa/oauth/authorize/**" access="IS_AUTHENTICATED_FULLY" />
    <sec:http-basic />
    <sec:anonymous />

    <sec:form-login authentication-failure-url="/dhis-web-commons/security/login.action?failed=true"
      username-parameter="j_username" password-parameter="<PASSWORD>"
      login-page="/dhis-web-commons/security/login.action"
      login-processing-url="/dhis-web-commons-security/login.action" />
    <sec:csrf disabled="true" />
  </sec:http>

  <bean id="mappedRedirectStrategy" class="org.hisp.dhis.security.MappedRedirectStrategy">
    <property name="redirectMap">
      <map>
        <entry key="/dhis-web-commons-stream/ping.action" value="/" />
      </map>
    </property>
    <property name="deviceResolver" ref="org.springframework.mobile.device.DeviceResolver" />
  </bean>

  <bean id="defaultAuthenticationSuccessHandler" class="org.hisp.dhis.security.DefaultAuthenticationSuccessHandler">
    <property name="redirectStrategy" ref="mappedRedirectStrategy" />
    <property name="sessionTimeout" ref="sessionTimeout" />
  </bean>

  <bean id="customAuthenticationFilter" class="org.hisp.dhis.security.filter.CustomAuthenticationFilter" />

  <bean id="corsFilter" class="org.hisp.dhis.security.filter.CorsFilter" />

  <bean id="appCacheFilter" class="org.hisp.dhis.servlet.filter.AppCacheFilter" />

  <sec:http access-decision-manager-ref="accessDecisionManager"
    authentication-manager-ref="authenticationManager" pattern="/dhis-web-commons/javascripts/**" security="none" />
  <sec:http access-decision-manager-ref="accessDecisionManager"
    authentication-manager-ref="authenticationManager" pattern="/dhis-web-commons/css/**" security="none" />
  <sec:http access-decision-manager-ref="accessDecisionManager"
    authentication-manager-ref="authenticationManager" pattern="/dhis-web-commons/flags/**" security="none" />
  <sec:http access-decision-manager-ref="accessDecisionManager"
    authentication-manager-ref="authenticationManager" pattern="/dhis-web-commons/fonts/**" security="none" />
  <sec:http access-decision-manager-ref="accessDecisionManager"
    authentication-manager-ref="authenticationManager" pattern="/api/files/style/external" security="none" />
  <sec:http access-decision-manager-ref="accessDecisionManager"
    authentication-manager-ref="authenticationManager" pattern="/external-static/**" security="none" />
  <sec:http access-decision-manager-ref="accessDecisionManager"
    authentication-manager-ref="authenticationManager" pattern="/favicon.ico" security="none" />

  <!-- Disabled for now, we need to properly handle "Basic Auth" dialog box popping up on browsers
  <sec:http access-decision-manager-ref="accessDecisionManager" use-expressions="true" realm="DHIS2" pattern="/api/**">
    <sec:http-basic />

    <sec:headers>
      <sec:content-type-options />
      <sec:frame-options />
      <sec:xss-protection />
    </sec:headers>

    <sec:custom-filter ref="automaticAccessFilter" before="LOGOUT_FILTER" />
    <sec:custom-filter ref="corsFilter" before="BASIC_AUTH_FILTER" />
    <sec:intercept-url pattern="/api/account/username" access="permitAll()" />
    <sec:intercept-url pattern="/api/account/recovery" access="permitAll()" />
    <sec:intercept-url pattern="/api/account/restore" access="permitAll()" />
    <sec:intercept-url pattern="/api/account/password" access="permitAll()" />
    <sec:intercept-url pattern="/api/account" access="permitAll()" />
    <sec:intercept-url pattern="/api/**" access="isAuthenticated()" />
  </sec:http>
  -->

  <bean id="http401LoginUrlAuthenticationEntryPoint" class="org.hisp.dhis.security.Http401LoginUrlAuthenticationEntryPoint">
    <constructor-arg name="loginFormUrl" value="/dhis-web-commons/security/login.action" />
  </bean>

  <sec:http access-decision-manager-ref="accessDecisionManager" realm="DHIS2" disable-url-rewriting="true" use-expressions="true"
    authentication-manager-ref="authenticationManager" entry-point-ref="http401LoginUrlAuthenticationEntryPoint">
    <sec:openid-login user-service-ref="userDetailsService" default-target-url="/" always-use-default-target="false"
      authentication-failure-handler-ref="securityExceptionTranslationHandler"
      login-processing-url="/dhis-web-commons-security/openid.action"
      authentication-success-handler-ref="defaultAuthenticationSuccessHandler" />

    <sec:form-login default-target-url="/" always-use-default-target="false"
      username-parameter="j_username" password-parameter="<PASSWORD>"
      authentication-failure-handler-ref="securityExceptionTranslationHandler"
      login-processing-url="/dhis-web-commons-security/login.action"
      login-page="/dhis-web-commons/security/login.action"
      authentication-details-source-ref="twoFactorWebAuthenticationDetailsSource"
      authentication-success-handler-ref="defaultAuthenticationSuccessHandler" />

    <sec:headers>
      <sec:content-type-options />
      <sec:frame-options policy="SAMEORIGIN" />
      <sec:xss-protection />
      <sec:cache-control disabled="true" />
    </sec:headers>

    <sec:csrf disabled="true" />

    <sec:http-basic entry-point-ref="http401LoginUrlAuthenticationEntryPoint" authentication-details-source-ref="twoFactorWebAuthenticationDetailsSource" />
    <sec:logout logout-url="/dhis-web-commons-security/logout.action" logout-success-url="/" />
    <sec:intercept-url pattern="/dhis-web-commons/i18nJavaScript.action" access="permitAll()" />
    <sec:intercept-url pattern="/dhis-web-commons/security/**" access="permitAll()" />

    <!-- Account recovery -->

    <sec:intercept-url pattern="/api/account/username" access="permitAll()" />
    <sec:intercept-url pattern="/api/account/recovery" access="permitAll()" />
    <sec:intercept-url pattern="/api/account/restore" access="permitAll()" />
    <sec:intercept-url pattern="/api/account/password" access="permitAll()" />
    <sec:intercept-url pattern="/api/account" access="permitAll()" />
    <sec:intercept-url pattern="/api/staticContent/*" method="GET" access="permitAll()" />
    <sec:intercept-url pattern="/api/externalFileResources/*" method="GET" access="permitAll()" />
    <sec:intercept-url request-matcher-ref="analyticPluginResources"
      access="hasAnyRole('ALL,M_dhis-web-pivot,M_dhis-web-visualizer,M_dhis-web-maps' +
      'M_dhis-web-event-reports,M_dhis-web-event-visualizer,M_dhis-web-dashboard,M_dhis-web-mapping')" />

    <!-- Apps -->

    <sec:intercept-url pattern="/dhis-web-pivot/**" access="hasAnyRole('ALL,M_dhis-web-pivot')" />
    <sec:intercept-url pattern="/dhis-web-visualizer/**" access="hasAnyRole('ALL,M_dhis-web-visualizer')" />
    <sec:intercept-url pattern="/dhis-web-mapping/**" access="hasAnyRole('ALL,M_dhis-web-mapping')" />
    <sec:intercept-url pattern="/dhis-web-maps/**" access="hasAnyRole('ALL,M_dhis-web-maps')" />
    <sec:intercept-url pattern="/dhis-web-event-reports/**" access="hasAnyRole('ALL,M_dhis-web-event-reports')" />
    <sec:intercept-url pattern="/dhis-web-event-visualizer/**" access="hasAnyRole('ALL,M_dhis-web-event-visualizer')" />
    <sec:intercept-url pattern="/dhis-web-settings/**" access="hasAnyRole('ALL,M_dhis-web-settings')" />
    <sec:intercept-url pattern="/dhis-web-maintenance/**" access="hasAnyRole('ALL,M_dhis-web-maintenance')" />
    <sec:intercept-url pattern="/dhis-web-app-management/**" access="hasAnyRole('ALL,M_dhis-web-app-management')" />
    <sec:intercept-url pattern="/dhis-web-usage-analytics/**" access="hasAnyRole('ALL,M_dhis-web-usage-analytics')" />
    <sec:intercept-url pattern="/dhis-web-event-capture/**" access="hasAnyRole('ALL,M_dhis-web-event-capture')" />
    <sec:intercept-url pattern="/dhis-web-tracker-capture/**" access="hasAnyRole('ALL,M_dhis-web-tracker-capture')" />
    <sec:intercept-url pattern="/dhis-web-cache-cleaner/**" access="hasAnyRole('ALL,M_dhis-web-cache-cleaner')" />
    <sec:intercept-url pattern="/dhis-web-data-administration/**" access="hasAnyRole('ALL,M_dhis-web-data-administration')" />

    <sec:intercept-url pattern="/**" access="isAuthenticated()" />
    <sec:custom-filter ref="resourceServerFilter" before="PRE_AUTH_FILTER" />
    <sec:custom-filter ref="automaticAccessFilter" before="LOGOUT_FILTER" />
    <sec:custom-filter ref="corsFilter" before="BASIC_AUTH_FILTER" />
    <sec:custom-filter ref="customAuthenticationFilter" before="FORM_LOGIN_FILTER" />
  </sec:http>

  <bean id="analyticPluginResources" class="org.springframework.security.web.util.matcher.RegexRequestMatcher">
        <constructor-arg name="pattern" value=".*(dhis-web-mapping\/map.js|dhis-web-visualizer\/chart.js|dhis-web-maps\/map.js|dhis-web-event-reports\/eventreport.js|dhis-web-event-visualizer\/eventchart.js|dhis-web-pivot\/reporttable.js)"/>
        <constructor-arg name="httpMethod" value="GET"/>
  </bean>

  <bean id="securityExceptionTranslationHandler"
    class="org.hisp.dhis.security.CustomExceptionMappingAuthenticationFailureHandler">
    <property name="exceptionMappings">
      <props>
        <prop key="org.springframework.security.authentication.CredentialsExpiredException">/dhis-web-commons/security/expired.action</prop>
      </props>
    </property>
    <property name="defaultFailureUrl" value="/dhis-web-commons/security/login.action?failed=true" />
  </bean>

  <!-- Security : Action -->

  <bean id="restrictOrganisationUnitsAction" class="org.hisp.dhis.security.action.RestrictOrganisationUnitsAction"
    scope="prototype">
    <property name="currentUserService" ref="org.hisp.dhis.user.CurrentUserService" />
    <property name="selectionManager" ref="org.hisp.dhis.ouwt.manager.OrganisationUnitSelectionManager" />
    <property name="selectionTreeManager" ref="org.hisp.dhis.oust.manager.SelectionTreeManager" />
  </bean>

  <bean id="automaticAccessFilter" class="org.hisp.dhis.security.filter.AutomaticAccessFilter">
    <property name="accessProviders">
      <map>
        <entry key="databaseAdmin" value-ref="databaseAutomaticAccessProvider" />
        <entry key="ghostAdmin" value-ref="ghostAutomaticAccessProvider" />
      </map>
    </property>
  </bean>

  <!-- Security : Listener -->

  <bean id="loggerListener" class="org.springframework.security.authentication.event.LoggerListener" />

  <!-- Security : AccessProvider -->

  <bean id="databaseAutomaticAccessProvider" class="org.hisp.dhis.security.DatabaseAutomaticAccessProvider">
    <property name="userService" ref="org.hisp.dhis.user.UserService" />
    <property name="systemAuthoritiesProvider" ref="simpleSystemAuthoritiesProvider" />
  </bean>

  <bean id="ghostAutomaticAccessProvider" class="org.hisp.dhis.security.GhostAutomaticAccessProvider">
    <property name="userService" ref="org.hisp.dhis.user.UserService" />
    <property name="systemAuthoritiesProvider" ref="simpleSystemAuthoritiesProvider" />
  </bean>

  <!-- Security : AccessDecision/Voter -->

  <bean id="accessDecisionManager" class="org.hisp.dhis.security.vote.LogicalOrAccessDecisionManager">
    <property name="accessDecisionManagers">
      <list>
        <ref bean="adminAccessDecisionVoting" />
        <ref bean="regularAccessDecisionVoting" />
        <ref bean="webAccessDecisionVoting" />
        <ref bean="externalAccessDecisionVoting" />
        <ref bean="authenticatedVoting" />
        <ref bean="regularAccessDecisionVoting" />
      </list>
    </property>
  </bean>

  <bean id="authenticatedVoter" class="org.springframework.security.access.vote.AuthenticatedVoter" />

  <bean id="authenticatedVoting" class="org.springframework.security.access.vote.UnanimousBased">
    <constructor-arg name="decisionVoters">
      <list>
        <ref bean="authenticatedVoter" />
      </list>
    </constructor-arg>
  </bean>

  <bean id="methodSecurityExpressionHandler" class="org.springframework.security.access.expression.method.DefaultMethodSecurityExpressionHandler">
    <property name="defaultRolePrefix" value="" />
  </bean>

  <bean id="webSecurityExpressionHandler" class="org.springframework.security.web.access.expression.DefaultWebSecurityExpressionHandler">
    <property name="defaultRolePrefix" value="" />
  </bean>

  <bean id="webExpressionVoter" class="org.springframework.security.web.access.expression.WebExpressionVoter">
    <property name="expressionHandler" ref="webSecurityExpressionHandler" />
  </bean>

  <bean id="externalAccessVoter" class="org.hisp.dhis.security.vote.ExternalAccessVoter" />

  <bean id="regularAccessDecisionVoting" class="org.springframework.security.access.vote.UnanimousBased">
    <constructor-arg name="decisionVoters">
      <list>
        <ref bean="actionAccessVoter" />
        <ref bean="moduleAccessVoter" />
      </list>
    </constructor-arg>
  </bean>

  <bean id="adminAccessDecisionVoting" class="org.springframework.security.access.vote.UnanimousBased">
    <constructor-arg name="decisionVoters">
      <list>
        <ref bean="adminAccessVoter" />
      </list>
    </constructor-arg>
  </bean>

  <bean id="adminAccessVoter" class="org.hisp.dhis.security.vote.SimpleAccessVoter">
    <property name="requiredAuthority" value="ALL" />
  </bean>

  <bean id="webAccessDecisionVoting" class="org.springframework.security.access.vote.UnanimousBased">
    <constructor-arg name="decisionVoters">
      <list>
        <ref bean="webExpressionVoter" />
      </list>
    </constructor-arg>
  </bean>

  <bean id="externalAccessDecisionVoting" class="org.springframework.security.access.vote.UnanimousBased">
    <constructor-arg name="decisionVoters">
      <list>
        <ref bean="externalAccessVoter" />
      </list>
    </constructor-arg>
  </bean>

  <bean id="actionAccessVoter" class="org.hisp.dhis.security.vote.ActionAccessVoter">
    <property name="attributePrefix" value="F_" />
    <property name="requiredAuthoritiesKey" value="requiredAuthorities" />
    <property name="anyAuthoritiesKey" value="anyAuthorities" />
  </bean>

  <bean id="moduleAccessVoter" class="org.hisp.dhis.security.vote.ModuleAccessVoter">
    <property name="attributePrefix" value="M_" />
    <property name="alwaysAccessible">
      <set>
        <value>dhis-web-commons-menu</value>
        <value>dhis-web-commons-oust</value>
        <value>dhis-web-commons-ouwt</value>
        <value>dhis-web-commons-security</value>
        <value>dhis-web-commons-i18n</value>
        <value>dhis-web-commons-ajax</value>
        <value>dhis-web-commons-ajax-json</value>
        <value>dhis-web-commons-ajax-html</value>
        <value>dhis-web-commons-stream</value>
        <value>dhis-web-commons-help</value>
        <value>dhis-web-commons-about</value>
        <value>dhis-web-menu-management</value>
        <value>dhis-web-apps</value>
        <value>dhis-web-api-mobile</value>
        <value>dhis-web-portal</value>
        <value>dhis-web-uaa</value>
      </set>
    </property>
  </bean>

  <bean id="org.hisp.dhis.security.ActionAccessResolver"
    class="org.hisp.dhis.security.SpringSecurityActionAccessResolver">
    <property name="requiredAuthoritiesProvider" ref="org.hisp.dhis.security.authority.RequiredAuthoritiesProvider" />
    <property name="accessDecisionManager" ref="accessDecisionManager" />
  </bean>

  <!-- Security : Interceptor -->

  <bean id="org.hisp.dhis.security.intercept.LoginInterceptor" class="org.hisp.dhis.security.intercept.LoginInterceptor">
    <property name="actions">
      <list>
        <ref bean="restrictOrganisationUnitsAction" />
      </list>
    </property>
  </bean>

  <bean id="org.hisp.dhis.security.intercept.XWorkSecurityInterceptor"
    class="org.hisp.dhis.security.intercept.XWorkSecurityInterceptor">
    <property name="accessDecisionManager" ref="accessDecisionManager" />
    <property name="authenticationManager" ref="authenticationManager" />
    <property name="validateConfigAttributes" value="false" />
    <property name="requiredAuthoritiesProvider" ref="org.hisp.dhis.security.authority.RequiredAuthoritiesProvider" />
    <property name="actionAccessResolver" ref="org.hisp.dhis.security.ActionAccessResolver" />
    <property name="securityService" ref="org.hisp.dhis.security.SecurityService" />
  </bean>

  <!-- Security : AuthorityProvider -->

  <bean id="org.hisp.dhis.security.authority.RequiredAuthoritiesProvider"
    class="org.hisp.dhis.security.authority.DefaultRequiredAuthoritiesProvider">
    <property name="requiredAuthoritiesKey" value="requiredAuthorities" />
    <property name="anyAuthoritiesKey" value="anyAuthorities" />
    <property name="globalAttributes">
      <set>
        <value>M_MODULE_ACCESS_VOTER_ENABLED</value>
      </set>
    </property>
  </bean>

  <bean id="org.hisp.dhis.security.authority.SystemAuthoritiesProvider"
    class="org.hisp.dhis.security.authority.CompositeSystemAuthoritiesProvider">
    <property name="sources">
      <set>
        <bean class="org.hisp.dhis.security.authority.CachingSystemAuthoritiesProvider">
          <property name="source" ref="detectingSystemAuthoritiesProvider" />
        </bean>
        <bean class="org.hisp.dhis.security.authority.CachingSystemAuthoritiesProvider">
          <property name="source" ref="moduleSystemAuthoritiesProvider" />
        </bean>
        <bean class="org.hisp.dhis.security.authority.CachingSystemAuthoritiesProvider">
          <property name="source" ref="simpleSystemAuthoritiesProvider" />
        </bean>
        <ref bean="appsSystemAuthoritiesProvider" />
        <ref bean="schemaAuthoritiesProvider" />
      </set>
    </property>
  </bean>

  <bean id="detectingSystemAuthoritiesProvider"
    class="org.hisp.dhis.security.authority.DetectingSystemAuthoritiesProvider">
    <property name="requiredAuthoritiesProvider" ref="org.hisp.dhis.security.authority.RequiredAuthoritiesProvider" />
  </bean>

  <bean id="moduleSystemAuthoritiesProvider" class="org.hisp.dhis.security.authority.ModuleSystemAuthoritiesProvider">
    <property name="authorityPrefix" value="M_" />
    <property name="moduleManager" ref="org.hisp.dhis.webportal.module.ModuleManager" />
    <property name="excludes">
      <set>
        <value>dhis-web-commons-menu</value>
        <value>dhis-web-commons-menu-management</value>
        <value>dhis-web-commons-oust</value>
        <value>dhis-web-commons-ouwt</value>
        <value>dhis-web-commons-security</value>
        <value>dhis-web-commons-i18n</value>
        <value>dhis-web-commons-ajax</value>
        <value>dhis-web-commons-ajax-json</value>
        <value>dhis-web-commons-ajax-html</value>
        <value>dhis-web-commons-stream</value>
        <value>dhis-web-commons-help</value>
        <value>dhis-web-commons-about</value>
        <value>dhis-web-apps</value>
        <value>dhis-web-api-mobile</value>
        <value>dhis-web-portal</value>
      </set>
    </property>
  </bean>

  <bean id="schemaAuthoritiesProvider" class="org.hisp.dhis.security.authority.SchemaAuthoritiesProvider" />

  <bean id="simpleSystemAuthoritiesProvider" class="org.hisp.dhis.security.authority.SimpleSystemAuthoritiesProvider">
    <property name="authorities">
      <set>
        <value>ALL</value>
        <value>F_VIEW_EVENT_ANALYTICS</value>
        <value>F_METADATA_EXPORT</value>
        <value>F_METADATA_IMPORT</value>
        <value>F_APPROVE_DATA</value>
        <value>F_APPROVE_DATA_LOWER_LEVELS</value>
        <value>F_ACCEPT_DATA_LOWER_LEVELS</value>
        <value>F_INSERT_CUSTOM_JS_CSS</value>
        <value>F_VIEW_UNAPPROVED_DATA</value>
        <value>F_REPLICATE_USER</value>
        <value>F_USERGROUP_MANAGING_RELATIONSHIPS_ADD</value>
        <value>F_USERGROUP_MANAGING_RELATIONSHIPS_VIEW</value>
        <value>F_USER_GROUPS_READ_ONLY_ADD_MEMBERS</value>
        <value>F_PROGRAM_DASHBOARD_CONFIG_ADMIN</value>
        <value>F_TRACKED_ENTITY_DATAVALUE_ADD</value>
        <value>F_TRACKED_ENTITY_DATAVALUE_DELETE</value>
        <value>F_TRACKED_ENTITY_DATAVALUE_READ</value>
        <value>F_TRACKED_ENTITY_INSTANCE_SEARCH</value>
        <value>F_TRACKED_ENTITY_INSTANCE_SEARCH_IN_ALL_ORGUNITS</value>
        <value>F_TRACKED_ENTITY_INSTANCE_ADD</value>
        <value>F_TRACKED_ENTITY_INSTANCE_DELETE</value>
        <value>F_UNCOMPLETE_EVENT</value>
        <value>F_PROGRAM_ENROLLMENT</value>
        <value>F_PROGRAM_UNENROLLMENT</value>
        <value>F_PROGRAM_ENROLLMENT_READ</value>
        <value>F_ORGANISATIONUNIT_MOVE</value>
        <value>F_PREDICTOR_RUN</value>
        <value>F_SEND_EMAIL</value>
        <value>F_TEI_CASCADE_DELETE</value>
        <value>F_ENROLLMENT_CASCADE_DELETE</value>
      </set>
    </property>
  </bean>

  <bean id="appsSystemAuthoritiesProvider" class="org.hisp.dhis.security.authority.AppsSystemAuthoritiesProvider" />

  <bean id="authenticationListener" class="org.hisp.dhis.security.AuthenticationListener"/>
</beans>
<commit_msg>[DHIS2-3519] Fix 302 response for basic auth request. (#1892)<commit_after><?xml version="1.0" encoding="UTF-8"?>
<beans xmlns="http://www.springframework.org/schema/beans" xmlns:xsi="http://www.w3.org/2001/XMLSchema-instance"
  xmlns:sec="http://www.springframework.org/schema/security" xmlns:oauth="http://www.springframework.org/schema/security/oauth2"
  xsi:schemaLocation="http://www.springframework.org/schema/beans http://www.springframework.org/schema/beans/spring-beans-4.3.xsd
    http://www.springframework.org/schema/security http://www.springframework.org/schema/security/spring-security-4.2.xsd
    http://www.springframework.org/schema/security/oauth2 http://www.springframework.org/schema/security/spring-security-oauth2.xsd">

  <!-- OAuth2 -->

  <bean id="oauthAuthenticationEntryPoint"
    class="org.springframework.security.oauth2.provider.error.OAuth2AuthenticationEntryPoint">
    <property name="realmName" value="dhis2/oauth2" />
  </bean>

  <bean id="oauthAccessDeniedHandler" class="org.springframework.security.oauth2.provider.error.OAuth2AccessDeniedHandler" />

  <oauth:resource-server id="resourceServerFilter" token-services-ref="tokenServices" entry-point-ref="oauthAuthenticationEntryPoint"
    authentication-manager-ref="oAuth2AuthenticationManager" stateless="false" />

  <sec:http pattern="/uaa/oauth/token/**" create-session="stateless" authentication-manager-ref="authenticationManager" disable-url-rewriting="true"
    use-expressions="false" access-decision-manager-ref="accessDecisionManager">
    <sec:intercept-url pattern="/uaa/oauth/token/**" access="IS_AUTHENTICATED_FULLY" method="POST" />
    <sec:anonymous enabled="false" />
    <sec:http-basic entry-point-ref="oauthAuthenticationEntryPoint" />
    <sec:access-denied-handler ref="oauthAccessDeniedHandler" />
    <sec:csrf disabled="true" />
  </sec:http>

  <sec:http pattern="/uaa/oauth/authorize/**" authentication-manager-ref="authenticationManager" disable-url-rewriting="true" use-expressions="false"
    create-session="ifRequired" access-decision-manager-ref="accessDecisionManager">
    <sec:intercept-url pattern="/uaa/oauth/authorize/**" access="IS_AUTHENTICATED_FULLY" />
    <sec:http-basic />
    <sec:anonymous />

    <sec:form-login authentication-failure-url="/dhis-web-commons/security/login.action?failed=true"
      username-parameter="j_username" password-parameter="<PASSWORD>"
      login-page="/dhis-web-commons/security/login.action"
      login-processing-url="/dhis-web-commons-security/login.action" />
    <sec:csrf disabled="true" />
  </sec:http>

  <bean id="mappedRedirectStrategy" class="org.hisp.dhis.security.MappedRedirectStrategy">
    <property name="redirectMap">
      <map>
        <entry key="/dhis-web-commons-stream/ping.action" value="/" />
      </map>
    </property>
    <property name="deviceResolver" ref="org.springframework.mobile.device.DeviceResolver" />
  </bean>

  <bean id="defaultAuthenticationSuccessHandler" class="org.hisp.dhis.security.DefaultAuthenticationSuccessHandler">
    <property name="redirectStrategy" ref="mappedRedirectStrategy" />
    <property name="sessionTimeout" ref="sessionTimeout" />
  </bean>

  <bean id="customAuthenticationFilter" class="org.hisp.dhis.security.filter.CustomAuthenticationFilter" />

  <bean id="corsFilter" class="org.hisp.dhis.security.filter.CorsFilter" />

  <bean id="appCacheFilter" class="org.hisp.dhis.servlet.filter.AppCacheFilter" />

  <sec:http access-decision-manager-ref="accessDecisionManager"
    authentication-manager-ref="authenticationManager" pattern="/dhis-web-commons/javascripts/**" security="none" />
  <sec:http access-decision-manager-ref="accessDecisionManager"
    authentication-manager-ref="authenticationManager" pattern="/dhis-web-commons/css/**" security="none" />
  <sec:http access-decision-manager-ref="accessDecisionManager"
    authentication-manager-ref="authenticationManager" pattern="/dhis-web-commons/flags/**" security="none" />
  <sec:http access-decision-manager-ref="accessDecisionManager"
    authentication-manager-ref="authenticationManager" pattern="/dhis-web-commons/fonts/**" security="none" />
  <sec:http access-decision-manager-ref="accessDecisionManager"
    authentication-manager-ref="authenticationManager" pattern="/api/files/style/external" security="none" />
  <sec:http access-decision-manager-ref="accessDecisionManager"
    authentication-manager-ref="authenticationManager" pattern="/external-static/**" security="none" />
  <sec:http access-decision-manager-ref="accessDecisionManager"
    authentication-manager-ref="authenticationManager" pattern="/favicon.ico" security="none" />

  <!-- Disabled for now, we need to properly handle "Basic Auth" dialog box popping up on browsers
  <sec:http access-decision-manager-ref="accessDecisionManager" use-expressions="true" realm="DHIS2" pattern="/api/**">
    <sec:http-basic />

    <sec:headers>
      <sec:content-type-options />
      <sec:frame-options />
      <sec:xss-protection />
    </sec:headers>

    <sec:custom-filter ref="automaticAccessFilter" before="LOGOUT_FILTER" />
    <sec:custom-filter ref="corsFilter" before="BASIC_AUTH_FILTER" />
    <sec:intercept-url pattern="/api/account/username" access="permitAll()" />
    <sec:intercept-url pattern="/api/account/recovery" access="permitAll()" />
    <sec:intercept-url pattern="/api/account/restore" access="permitAll()" />
    <sec:intercept-url pattern="/api/account/password" access="permitAll()" />
    <sec:intercept-url pattern="/api/account" access="permitAll()" />
    <sec:intercept-url pattern="/api/**" access="isAuthenticated()" />
  </sec:http>
  -->

  <bean id="http401LoginUrlAuthenticationEntryPoint" class="org.hisp.dhis.security.Http401LoginUrlAuthenticationEntryPoint">
    <constructor-arg name="loginFormUrl" value="/dhis-web-commons/security/login.action" />
  </bean>

  <sec:http access-decision-manager-ref="accessDecisionManager" realm="DHIS2" disable-url-rewriting="true" use-expressions="true"
    authentication-manager-ref="authenticationManager" entry-point-ref="http401LoginUrlAuthenticationEntryPoint">
    <sec:openid-login user-service-ref="userDetailsService" default-target-url="/" always-use-default-target="false"
      authentication-failure-handler-ref="securityExceptionTranslationHandler"
      login-processing-url="/dhis-web-commons-security/openid.action"
      authentication-success-handler-ref="defaultAuthenticationSuccessHandler" />

    <sec:form-login default-target-url="/" always-use-default-target="false"
      username-parameter="j_username" password-parameter="<PASSWORD>"
      authentication-failure-handler-ref="securityExceptionTranslationHandler"
      login-processing-url="/dhis-web-commons-security/login.action"
      login-page="/dhis-web-commons/security/login.action"
      authentication-details-source-ref="twoFactorWebAuthenticationDetailsSource"
      authentication-success-handler-ref="defaultAuthenticationSuccessHandler" />

    <sec:headers>
      <sec:content-type-options />
      <sec:frame-options policy="SAMEORIGIN" />
      <sec:xss-protection />
      <sec:cache-control disabled="true" />
    </sec:headers>

    <sec:csrf disabled="true" />

    <sec:http-basic authentication-details-source-ref="twoFactorWebAuthenticationDetailsSource"/>
    <sec:logout logout-url="/dhis-web-commons-security/logout.action" logout-success-url="/" />
    <sec:intercept-url pattern="/dhis-web-commons/i18nJavaScript.action" access="permitAll()" />
    <sec:intercept-url pattern="/dhis-web-commons/security/**" access="permitAll()" />

    <!-- Account recovery -->

    <sec:intercept-url pattern="/api/account/username" access="permitAll()" />
    <sec:intercept-url pattern="/api/account/recovery" access="permitAll()" />
    <sec:intercept-url pattern="/api/account/restore" access="permitAll()" />
    <sec:intercept-url pattern="/api/account/password" access="permitAll()" />
    <sec:intercept-url pattern="/api/account" access="permitAll()" />
    <sec:intercept-url pattern="/api/staticContent/*" method="GET" access="permitAll()" />
    <sec:intercept-url pattern="/api/externalFileResources/*" method="GET" access="permitAll()" />
    <sec:intercept-url request-matcher-ref="analyticPluginResources"
      access="hasAnyRole('ALL,M_dhis-web-pivot,M_dhis-web-visualizer,M_dhis-web-maps' +
      'M_dhis-web-event-reports,M_dhis-web-event-visualizer,M_dhis-web-dashboard,M_dhis-web-mapping')" />

    <!-- Apps -->

    <sec:intercept-url pattern="/dhis-web-pivot/**" access="hasAnyRole('ALL,M_dhis-web-pivot')" />
    <sec:intercept-url pattern="/dhis-web-visualizer/**" access="hasAnyRole('ALL,M_dhis-web-visualizer')" />
    <sec:intercept-url pattern="/dhis-web-mapping/**" access="hasAnyRole('ALL,M_dhis-web-mapping')" />
    <sec:intercept-url pattern="/dhis-web-maps/**" access="hasAnyRole('ALL,M_dhis-web-maps')" />
    <sec:intercept-url pattern="/dhis-web-event-reports/**" access="hasAnyRole('ALL,M_dhis-web-event-reports')" />
    <sec:intercept-url pattern="/dhis-web-event-visualizer/**" access="hasAnyRole('ALL,M_dhis-web-event-visualizer')" />
    <sec:intercept-url pattern="/dhis-web-settings/**" access="hasAnyRole('ALL,M_dhis-web-settings')" />
    <sec:intercept-url pattern="/dhis-web-maintenance/**" access="hasAnyRole('ALL,M_dhis-web-maintenance')" />
    <sec:intercept-url pattern="/dhis-web-app-management/**" access="hasAnyRole('ALL,M_dhis-web-app-management')" />
    <sec:intercept-url pattern="/dhis-web-usage-analytics/**" access="hasAnyRole('ALL,M_dhis-web-usage-analytics')" />
    <sec:intercept-url pattern="/dhis-web-event-capture/**" access="hasAnyRole('ALL,M_dhis-web-event-capture')" />
    <sec:intercept-url pattern="/dhis-web-tracker-capture/**" access="hasAnyRole('ALL,M_dhis-web-tracker-capture')" />
    <sec:intercept-url pattern="/dhis-web-cache-cleaner/**" access="hasAnyRole('ALL,M_dhis-web-cache-cleaner')" />
    <sec:intercept-url pattern="/dhis-web-data-administration/**" access="hasAnyRole('ALL,M_dhis-web-data-administration')" />

    <sec:intercept-url pattern="/**" access="isAuthenticated()" />
    <sec:custom-filter ref="resourceServerFilter" before="PRE_AUTH_FILTER" />
    <sec:custom-filter ref="automaticAccessFilter" before="LOGOUT_FILTER" />
    <sec:custom-filter ref="corsFilter" before="BASIC_AUTH_FILTER" />
    <sec:custom-filter ref="customAuthenticationFilter" before="FORM_LOGIN_FILTER" />
  </sec:http>

  <bean id="analyticPluginResources" class="org.springframework.security.web.util.matcher.RegexRequestMatcher">
        <constructor-arg name="pattern" value=".*(dhis-web-mapping\/map.js|dhis-web-visualizer\/chart.js|dhis-web-maps\/map.js|dhis-web-event-reports\/eventreport.js|dhis-web-event-visualizer\/eventchart.js|dhis-web-pivot\/reporttable.js)"/>
        <constructor-arg name="httpMethod" value="GET"/>
  </bean>

  <bean id="securityExceptionTranslationHandler"
    class="org.hisp.dhis.security.CustomExceptionMappingAuthenticationFailureHandler">
    <property name="exceptionMappings">
      <props>
        <prop key="org.springframework.security.authentication.CredentialsExpiredException">/dhis-web-commons/security/expired.action</prop>
      </props>
    </property>
    <property name="defaultFailureUrl" value="/dhis-web-commons/security/login.action?failed=true" />
  </bean>

  <!-- Security : Action -->

  <bean id="restrictOrganisationUnitsAction" class="org.hisp.dhis.security.action.RestrictOrganisationUnitsAction"
    scope="prototype">
    <property name="currentUserService" ref="org.hisp.dhis.user.CurrentUserService" />
    <property name="selectionManager" ref="org.hisp.dhis.ouwt.manager.OrganisationUnitSelectionManager" />
    <property name="selectionTreeManager" ref="org.hisp.dhis.oust.manager.SelectionTreeManager" />
  </bean>

  <bean id="automaticAccessFilter" class="org.hisp.dhis.security.filter.AutomaticAccessFilter">
    <property name="accessProviders">
      <map>
        <entry key="databaseAdmin" value-ref="databaseAutomaticAccessProvider" />
        <entry key="ghostAdmin" value-ref="ghostAutomaticAccessProvider" />
      </map>
    </property>
  </bean>

  <!-- Security : Listener -->

  <bean id="loggerListener" class="org.springframework.security.authentication.event.LoggerListener" />

  <!-- Security : AccessProvider -->

  <bean id="databaseAutomaticAccessProvider" class="org.hisp.dhis.security.DatabaseAutomaticAccessProvider">
    <property name="userService" ref="org.hisp.dhis.user.UserService" />
    <property name="systemAuthoritiesProvider" ref="simpleSystemAuthoritiesProvider" />
  </bean>

  <bean id="ghostAutomaticAccessProvider" class="org.hisp.dhis.security.GhostAutomaticAccessProvider">
    <property name="userService" ref="org.hisp.dhis.user.UserService" />
    <property name="systemAuthoritiesProvider" ref="simpleSystemAuthoritiesProvider" />
  </bean>

  <!-- Security : AccessDecision/Voter -->

  <bean id="accessDecisionManager" class="org.hisp.dhis.security.vote.LogicalOrAccessDecisionManager">
    <property name="accessDecisionManagers">
      <list>
        <ref bean="adminAccessDecisionVoting" />
        <ref bean="regularAccessDecisionVoting" />
        <ref bean="webAccessDecisionVoting" />
        <ref bean="externalAccessDecisionVoting" />
        <ref bean="authenticatedVoting" />
        <ref bean="regularAccessDecisionVoting" />
      </list>
    </property>
  </bean>

  <bean id="authenticatedVoter" class="org.springframework.security.access.vote.AuthenticatedVoter" />

  <bean id="authenticatedVoting" class="org.springframework.security.access.vote.UnanimousBased">
    <constructor-arg name="decisionVoters">
      <list>
        <ref bean="authenticatedVoter" />
      </list>
    </constructor-arg>
  </bean>

  <bean id="methodSecurityExpressionHandler" class="org.springframework.security.access.expression.method.DefaultMethodSecurityExpressionHandler">
    <property name="defaultRolePrefix" value="" />
  </bean>

  <bean id="webSecurityExpressionHandler" class="org.springframework.security.web.access.expression.DefaultWebSecurityExpressionHandler">
    <property name="defaultRolePrefix" value="" />
  </bean>

  <bean id="webExpressionVoter" class="org.springframework.security.web.access.expression.WebExpressionVoter">
    <property name="expressionHandler" ref="webSecurityExpressionHandler" />
  </bean>

  <bean id="externalAccessVoter" class="org.hisp.dhis.security.vote.ExternalAccessVoter" />

  <bean id="regularAccessDecisionVoting" class="org.springframework.security.access.vote.UnanimousBased">
    <constructor-arg name="decisionVoters">
      <list>
        <ref bean="actionAccessVoter" />
        <ref bean="moduleAccessVoter" />
      </list>
    </constructor-arg>
  </bean>

  <bean id="adminAccessDecisionVoting" class="org.springframework.security.access.vote.UnanimousBased">
    <constructor-arg name="decisionVoters">
      <list>
        <ref bean="adminAccessVoter" />
      </list>
    </constructor-arg>
  </bean>

  <bean id="adminAccessVoter" class="org.hisp.dhis.security.vote.SimpleAccessVoter">
    <property name="requiredAuthority" value="ALL" />
  </bean>

  <bean id="webAccessDecisionVoting" class="org.springframework.security.access.vote.UnanimousBased">
    <constructor-arg name="decisionVoters">
      <list>
        <ref bean="webExpressionVoter" />
      </list>
    </constructor-arg>
  </bean>

  <bean id="externalAccessDecisionVoting" class="org.springframework.security.access.vote.UnanimousBased">
    <constructor-arg name="decisionVoters">
      <list>
        <ref bean="externalAccessVoter" />
      </list>
    </constructor-arg>
  </bean>

  <bean id="actionAccessVoter" class="org.hisp.dhis.security.vote.ActionAccessVoter">
    <property name="attributePrefix" value="F_" />
    <property name="requiredAuthoritiesKey" value="requiredAuthorities" />
    <property name="anyAuthoritiesKey" value="anyAuthorities" />
  </bean>

  <bean id="moduleAccessVoter" class="org.hisp.dhis.security.vote.ModuleAccessVoter">
    <property name="attributePrefix" value="M_" />
    <property name="alwaysAccessible">
      <set>
        <value>dhis-web-commons-menu</value>
        <value>dhis-web-commons-oust</value>
        <value>dhis-web-commons-ouwt</value>
        <value>dhis-web-commons-security</value>
        <value>dhis-web-commons-i18n</value>
        <value>dhis-web-commons-ajax</value>
        <value>dhis-web-commons-ajax-json</value>
        <value>dhis-web-commons-ajax-html</value>
        <value>dhis-web-commons-stream</value>
        <value>dhis-web-commons-help</value>
        <value>dhis-web-commons-about</value>
        <value>dhis-web-menu-management</value>
        <value>dhis-web-apps</value>
        <value>dhis-web-api-mobile</value>
        <value>dhis-web-portal</value>
        <value>dhis-web-uaa</value>
      </set>
    </property>
  </bean>

  <bean id="org.hisp.dhis.security.ActionAccessResolver"
    class="org.hisp.dhis.security.SpringSecurityActionAccessResolver">
    <property name="requiredAuthoritiesProvider" ref="org.hisp.dhis.security.authority.RequiredAuthoritiesProvider" />
    <property name="accessDecisionManager" ref="accessDecisionManager" />
  </bean>

  <!-- Security : Interceptor -->

  <bean id="org.hisp.dhis.security.intercept.LoginInterceptor" class="org.hisp.dhis.security.intercept.LoginInterceptor">
    <property name="actions">
      <list>
        <ref bean="restrictOrganisationUnitsAction" />
      </list>
    </property>
  </bean>

  <bean id="org.hisp.dhis.security.intercept.XWorkSecurityInterceptor"
    class="org.hisp.dhis.security.intercept.XWorkSecurityInterceptor">
    <property name="accessDecisionManager" ref="accessDecisionManager" />
    <property name="authenticationManager" ref="authenticationManager" />
    <property name="validateConfigAttributes" value="false" />
    <property name="requiredAuthoritiesProvider" ref="org.hisp.dhis.security.authority.RequiredAuthoritiesProvider" />
    <property name="actionAccessResolver" ref="org.hisp.dhis.security.ActionAccessResolver" />
    <property name="securityService" ref="org.hisp.dhis.security.SecurityService" />
  </bean>

  <!-- Security : AuthorityProvider -->

  <bean id="org.hisp.dhis.security.authority.RequiredAuthoritiesProvider"
    class="org.hisp.dhis.security.authority.DefaultRequiredAuthoritiesProvider">
    <property name="requiredAuthoritiesKey" value="requiredAuthorities" />
    <property name="anyAuthoritiesKey" value="anyAuthorities" />
    <property name="globalAttributes">
      <set>
        <value>M_MODULE_ACCESS_VOTER_ENABLED</value>
      </set>
    </property>
  </bean>

  <bean id="org.hisp.dhis.security.authority.SystemAuthoritiesProvider"
    class="org.hisp.dhis.security.authority.CompositeSystemAuthoritiesProvider">
    <property name="sources">
      <set>
        <bean class="org.hisp.dhis.security.authority.CachingSystemAuthoritiesProvider">
          <property name="source" ref="detectingSystemAuthoritiesProvider" />
        </bean>
        <bean class="org.hisp.dhis.security.authority.CachingSystemAuthoritiesProvider">
          <property name="source" ref="moduleSystemAuthoritiesProvider" />
        </bean>
        <bean class="org.hisp.dhis.security.authority.CachingSystemAuthoritiesProvider">
          <property name="source" ref="simpleSystemAuthoritiesProvider" />
        </bean>
        <ref bean="appsSystemAuthoritiesProvider" />
        <ref bean="schemaAuthoritiesProvider" />
      </set>
    </property>
  </bean>

  <bean id="detectingSystemAuthoritiesProvider"
    class="org.hisp.dhis.security.authority.DetectingSystemAuthoritiesProvider">
    <property name="requiredAuthoritiesProvider" ref="org.hisp.dhis.security.authority.RequiredAuthoritiesProvider" />
  </bean>

  <bean id="moduleSystemAuthoritiesProvider" class="org.hisp.dhis.security.authority.ModuleSystemAuthoritiesProvider">
    <property name="authorityPrefix" value="M_" />
    <property name="moduleManager" ref="org.hisp.dhis.webportal.module.ModuleManager" />
    <property name="excludes">
      <set>
        <value>dhis-web-commons-menu</value>
        <value>dhis-web-commons-menu-management</value>
        <value>dhis-web-commons-oust</value>
        <value>dhis-web-commons-ouwt</value>
        <value>dhis-web-commons-security</value>
        <value>dhis-web-commons-i18n</value>
        <value>dhis-web-commons-ajax</value>
        <value>dhis-web-commons-ajax-json</value>
        <value>dhis-web-commons-ajax-html</value>
        <value>dhis-web-commons-stream</value>
        <value>dhis-web-commons-help</value>
        <value>dhis-web-commons-about</value>
        <value>dhis-web-apps</value>
        <value>dhis-web-api-mobile</value>
        <value>dhis-web-portal</value>
      </set>
    </property>
  </bean>

  <bean id="schemaAuthoritiesProvider" class="org.hisp.dhis.security.authority.SchemaAuthoritiesProvider" />

  <bean id="simpleSystemAuthoritiesProvider" class="org.hisp.dhis.security.authority.SimpleSystemAuthoritiesProvider">
    <property name="authorities">
      <set>
        <value>ALL</value>
        <value>F_VIEW_EVENT_ANALYTICS</value>
        <value>F_METADATA_EXPORT</value>
        <value>F_METADATA_IMPORT</value>
        <value>F_APPROVE_DATA</value>
        <value>F_APPROVE_DATA_LOWER_LEVELS</value>
        <value>F_ACCEPT_DATA_LOWER_LEVELS</value>
        <value>F_INSERT_CUSTOM_JS_CSS</value>
        <value>F_VIEW_UNAPPROVED_DATA</value>
        <value>F_REPLICATE_USER</value>
        <value>F_USERGROUP_MANAGING_RELATIONSHIPS_ADD</value>
        <value>F_USERGROUP_MANAGING_RELATIONSHIPS_VIEW</value>
        <value>F_USER_GROUPS_READ_ONLY_ADD_MEMBERS</value>
        <value>F_PROGRAM_DASHBOARD_CONFIG_ADMIN</value>
        <value>F_TRACKED_ENTITY_DATAVALUE_ADD</value>
        <value>F_TRACKED_ENTITY_DATAVALUE_DELETE</value>
        <value>F_TRACKED_ENTITY_DATAVALUE_READ</value>
        <value>F_TRACKED_ENTITY_INSTANCE_SEARCH</value>
        <value>F_TRACKED_ENTITY_INSTANCE_SEARCH_IN_ALL_ORGUNITS</value>
        <value>F_TRACKED_ENTITY_INSTANCE_ADD</value>
        <value>F_TRACKED_ENTITY_INSTANCE_DELETE</value>
        <value>F_UNCOMPLETE_EVENT</value>
        <value>F_PROGRAM_ENROLLMENT</value>
        <value>F_PROGRAM_UNENROLLMENT</value>
        <value>F_PROGRAM_ENROLLMENT_READ</value>
        <value>F_ORGANISATIONUNIT_MOVE</value>
        <value>F_PREDICTOR_RUN</value>
        <value>F_SEND_EMAIL</value>
        <value>F_TEI_CASCADE_DELETE</value>
        <value>F_ENROLLMENT_CASCADE_DELETE</value>
      </set>
    </property>
  </bean>

  <bean id="appsSystemAuthoritiesProvider" class="org.hisp.dhis.security.authority.AppsSystemAuthoritiesProvider" />

  <bean id="authenticationListener" class="org.hisp.dhis.security.AuthenticationListener"/>
</beans>

{'fraction_non_alphanumeric': 0.151827634258763, 'fraction_numerical': 0.002036659877800407, 'mean_word_length': 4.140055096418733, 'pattern_counts': {'":': 0, '<': 831, '<?xml version=': 2, '>': 831, 'https://': 0, 'lorem ipsum': 0, 'www.': 20, 'xml': 10}, 'pii_count': 0, 'substrings_counts': 0, 'word_list_counts': {'cursed_substrings.json': 0, 'profanity_word_list.json': 0, 'sexual_word_list.json': 0, 'zh_pornsignals.json': 0}}
{'dir': 'git-commits-cleaned', 'id': '5714037', 'n_tokens_mistral': 14948, 'n_tokens_neox': 14253, 'n_words': 1509}