<commit_before>package com.github.kpavlov.restws.server.hmac;

import com.github.kpavlov.restws.commons.HmacSignatureBuilder;
import org.springframework.beans.factory.annotation.Autowired;
import org.springframework.http.HttpHeaders;
import org.springframework.security.web.authentication.preauth.PreAuthenticatedCredentialsNotFoundException;
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 javax.xml.bind.DatatypeConverter;
import java.io.IOException;
import java.util.regex.Matcher;
import java.util.regex.Pattern;

public class HmacFilter extends OncePerRequestFilter {

    private static final Pattern AUTHORIZATION_TOKEN_PATTERN = Pattern.compile("^(\\w+) (\\S+):(\\S+):([\\S]+)$");

    @Autowired
    private CredentialsProvider credentialsProvider;

    @Override
    protected void doFilterInternal(HttpServletRequest request, HttpServletResponse response, FilterChain filterChain) throws ServletException, IOException {
        CachingRequestWrapper requestWrapper = new CachingRequestWrapper(request);

        final String authHeader = request.getHeader(HttpHeaders.AUTHORIZATION);

        final Matcher authHeaderMatcher = AUTHORIZATION_TOKEN_PATTERN.matcher(authHeader);
        if (!authHeaderMatcher.matches()) {
            // invalid authorization token
            logger.error("Bad authorization data");
            response.sendError(HttpServletResponse.SC_NOT_ACCEPTABLE, "Bad authorization data");
            return;
        }

        final String algorithm = authHeaderMatcher.group(1);
        final String apiKey = authHeaderMatcher.group(2);
        final String nonce = authHeaderMatcher.group(3);
        final String receivedDigest = authHeaderMatcher.group(4);

        final byte[] apiSecret = credentialsProvider.getApiSecret(apiKey);
        if (apiSecret == null) {
            throw new PreAuthenticatedCredentialsNotFoundException("Access Denied");
        }

        final byte[] contentAsByteArray = requestWrapper.getContentAsByteArray();

        final HmacSignatureBuilder signatureBuilder = new HmacSignatureBuilder()
                .algorithm(algorithm)
                .scheme(request.getScheme())
                .host(request.getServerName() + ":" + request.getServerPort())
                .method(request.getMethod())
                .resource(request.getRequestURI())
                .contentType(request.getContentType())<commit_msg>handle absence of Authorization header<commit_after>package com.github.kpavlov.restws.server.hmac;

import com.github.kpavlov.restws.commons.HmacSignatureBuilder;
import org.springframework.beans.factory.annotation.Autowired;
import org.springframework.http.HttpHeaders;
import org.springframework.security.web.authentication.preauth.PreAuthenticatedCredentialsNotFoundException;
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 javax.xml.bind.DatatypeConverter;
import java.io.IOException;
import java.util.regex.Matcher;
import java.util.regex.Pattern;

public class HmacFilter extends OncePerRequestFilter {

    private static final Pattern AUTHORIZATION_TOKEN_PATTERN = Pattern.compile("^(\\w+) (\\S+):(\\S+):([\\S]+)$");

    @Autowired
    private CredentialsProvider credentialsProvider;

    @Override
    protected void doFilterInternal(HttpServletRequest request, HttpServletResponse response, FilterChain filterChain) throws ServletException, IOException {
        CachingRequestWrapper requestWrapper = new CachingRequestWrapper(request);

        final String authHeader = request.getHeader(HttpHeaders.AUTHORIZATION);
        if (authHeader == null) {
            // invalid authorization token
            logger.error("Authorization header is missing");
            response.sendError(HttpServletResponse.SC_UNAUTHORIZED);
            return;

        }

        final Matcher authHeaderMatcher = AUTHORIZATION_TOKEN_PATTERN.matcher(authHeader);
        if (!authHeaderMatcher.matches()) {
            // invalid authorization token
            logger.error("Bad authorization data");
            response.sendError(HttpServletResponse.SC_NOT_ACCEPTABLE, "Bad authorization data");
            return;
        }

        final String algorithm = authHeaderMatcher.group(1);
        final String apiKey = authHeaderMatcher.group(2);
        final String nonce = authHeaderMatcher.group(3);
        final String receivedDigest = authHeaderMatcher.group(4);

        final byte[] apiSecret = credentialsProvider.getApiSecret(apiKey);
        if (apiSecret == null) {
            throw new PreAuthenticatedCredentialsNotFoundException("Access Denied");
        }

        final byte[] contentAsByteArray = requestWrapper.getContentAsByteArray();

        final HmacSignatureBuilder signatureBuilder = new HmacSignatureBuilder()
                .algorithm(algorithm)
                .scheme(request.getScheme())
                .host(request.getServerName() + ":" + request.getServerPort())
                .method(request.getMethod())
                .resource(request.getRequestURI())
                .contentType(request.getContentType())
{'fraction_non_alphanumeric': 0.09163125808239424, 'fraction_numerical': 0.0014779235174579716, 'mean_word_length': 3.7037358818418764, 'pattern_counts': {'":': 2, '<': 3, '<?xml version=': 0, '>': 3, 'https://': 0, 'lorem ipsum': 0, 'www.': 0, 'xml': 2}, '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': '4740901', 'n_tokens_mistral': 1354, 'n_tokens_neox': 1326, 'n_words': 263}