<commit_before>package org.innovateuk.ifs.security;

import java.io.IOException;

import javax.servlet.FilterChain;
import javax.servlet.ServletException;
import javax.servlet.http.HttpServletRequest;
import javax.servlet.http.HttpServletResponse;

import org.innovateuk.ifs.commons.security.UserAuthenticationService;
import org.innovateuk.ifs.user.resource.UserResource;
import org.innovateuk.ifs.user.resource.UserStatus;
import org.springframework.beans.factory.annotation.Autowired;
import org.springframework.beans.factory.annotation.Configurable;
import org.springframework.beans.factory.annotation.Value;
import org.springframework.security.core.Authentication;
import org.springframework.security.core.context.SecurityContextHolder;
import org.springframework.stereotype.Service;
import org.springframework.web.filter.OncePerRequestFilter;

@Service
@Configurable
public class StatelessAuthenticationFilter extends OncePerRequestFilter {

    @Autowired
    private UserAuthenticationService userAuthenticationService;

    @Value("management.contextPath")
    private String monitoringEndpoint;

    @Value("${logout.url}")
    private String logoutUrl;

    @Override
    public void doFilterInternal(HttpServletRequest request, HttpServletResponse response, FilterChain filterChain)
            throws IOException, ServletException {

        if(shouldBeAuthenticated(request)) {
            Authentication authentication = userAuthenticationService.getAuthentication(request, true);

            if (authentication != null) {
                UserResource ur = userAuthenticationService.getAuthenticatedUser(request);
                if (ur == null) {
                    response.sendRedirect(logoutUrl);
                } else if (ur.getStatus().equals(UserStatus.INACTIVE)) {
                    response.sendRedirect(logoutUrl);
                } else {
                    SecurityContextHolder.getContext().setAuthentication(authentication);
                }
            }
        }
        filterChain.doFilter(request, response);
    }

    private boolean shouldBeAuthenticated(final HttpServletRequest httpRequest) {
        String uri = httpRequest.getRequestURI();
        return !(
            uri.startsWith(monitoringEndpoint) ||
            uri.startsWith("/js/") ||
            uri.startsWith("/css/") ||
            uri.startsWith("/images/") ||
            uri.equals("/favicon.ico") ||
            uri.startsWith("/prototypes") ||
            uri.startsWith("/error")
        );
    }
}
<commit_msg>IFS-3093 Redirect to the new site terms and conditions page if there is an update.<commit_after>package org.innovateuk.ifs.security;

import org.innovateuk.ifs.commons.security.UserAuthenticationService;
import org.innovateuk.ifs.competition.resource.SiteTermsAndConditionsResource;
import org.innovateuk.ifs.competition.service.TermsAndConditionsRestService;
import org.innovateuk.ifs.user.resource.Role;
import org.innovateuk.ifs.user.resource.UserResource;
import org.springframework.beans.factory.annotation.Autowired;
import org.springframework.beans.factory.annotation.Configurable;
import org.springframework.beans.factory.annotation.Value;
import org.springframework.security.core.Authentication;
import org.springframework.security.core.context.SecurityContextHolder;
import org.springframework.stereotype.Service;
import org.springframework.web.filter.OncePerRequestFilter;

import javax.servlet.FilterChain;
import javax.servlet.ServletException;
import javax.servlet.http.HttpServletRequest;
import javax.servlet.http.HttpServletResponse;
import java.io.IOException;
import java.util.EnumSet;
import java.util.Set;

import static org.innovateuk.ifs.user.resource.Role.*;
import static org.innovateuk.ifs.user.resource.UserStatus.INACTIVE;

@Service
@Configurable
public class StatelessAuthenticationFilter extends OncePerRequestFilter {

    @Autowired
    private UserAuthenticationService userAuthenticationService;

    @Autowired
    private TermsAndConditionsRestService termsAndConditionsRestService;

    @Value("management.contextPath")
    private String monitoringEndpoint;

    @Value("${logout.url}")
    private String logoutUrl;

    @Override
    public void doFilterInternal(HttpServletRequest request, HttpServletResponse response, FilterChain filterChain)
            throws IOException, ServletException {

        boolean redirected = false;
        if (shouldBeAuthenticated(request)) {
            Authentication authentication = userAuthenticationService.getAuthentication(request, true);

            if (authentication != null) {
                UserResource userResource = userAuthenticationService.getAuthenticatedUser(request);
                if (nullOrInactiveUser(userResource)) {
                    response.sendRedirect(logoutUrl);
                } else {
                    SecurityContextHolder.getContext().setAuthentication(authentication);
                    if (shouldRedirectToNewSiteTerms(request, userResource)) {
                        response.sendRedirect("/info/new-terms-and-conditions");
                        redirected = true;
                    }
                }
            }
        }

        if (!redirected) {
            filterChain.doFilter(request, response);
        }
    }

    private boolean shouldBeAuthenticated(HttpServletRequest request) {
        String uri = request.getRequestURI();
        return !(
                uri.startsWith(monitoringEndpoint) ||
                        uri.startsWith("/js/") ||
                        uri.startsWith("/css/") ||
                        uri.startsWith("/images/") ||
                        uri.equals("/favicon.ico") ||
                        uri.startsWith("/prototypes") ||
                        uri.startsWith("/error")
        );
    }

    private boolean nullOrInactiveUser(UserResource userResource) {
        return userResource == null || INACTIVE == userResource.getStatus();
    }

    private boolean shouldRedirectToNewSiteTerms(HttpServletRequest request,
                                                 UserResource userResource) {
        return siteTermsCheckNeeded(request, userResource) && !userHasAcceptedLatestSiteTerms(userResource);
    }

    private boolean siteTermsCheckNeeded(HttpServletRequest request,
                                         UserResource userResource) {
        return !isSiteInfoRequest(request) && userHasApplicantRole(userResource);
    }

    private boolean isSiteInfoRequest(HttpServletRequest request) {
        // requests include the site terms and conditions, cookie and contact pages and the new site terms form page.
        return request.getRequestURI().startsWith("/info/");
    }

    private boolean userHasApplicantRole(UserResource userResource) {
        Set<Role> applicationRoles = EnumSet.of(APPLICANT, LEADAPPLICANT, COLLABORATOR);
        applicationRoles.retainAll(userResource.getRoles());
        return !applicationRoles.isEmpty();
    }

    private boolean userHasAcceptedLatestSiteTerms(UserResource userResource) {
        SiteTermsAndConditionsResource latestSiteTermsAndConditions = termsAndConditionsRestService
                .getLatestSiteTermsAndConditions().getSuccess();
        return userResource.getTermsAndConditionsIds().contains(latestSiteTermsAndConditions.getId());
    }
}

{'fraction_non_alphanumeric': 0.08686181075561607, 'fraction_numerical': 0.0005445881552076242, 'mean_word_length': 3.1200224340998317, 'pattern_counts': {'":': 0, '<': 4, '<?xml version=': 0, '>': 4, 'https://': 0, 'lorem ipsum': 0, 'www.': 0, 'xml': 0}, 'pii_count': 0, 'substrings_counts': 0, 'word_list_counts': {'cursed_substrings.json': 4, 'profanity_word_list.json': 0, 'sexual_word_list.json': 0, 'zh_pornsignals.json': 0}}
{'dir': 'git-commits-cleaned', 'id': '1700610', 'n_tokens_mistral': 1799, 'n_tokens_neox': 1786, 'n_words': 316}