<commit_before>package butterflynet;

import com.google.api.client.auth.oauth2.AuthorizationCodeFlow;
import com.google.api.client.auth.oauth2.BearerToken;
import com.google.api.client.auth.oauth2.Credential;
import com.google.api.client.auth.oauth2.TokenResponse;
import com.google.api.client.http.BasicAuthentication;
import com.google.api.client.http.GenericUrl;
import com.google.api.client.http.HttpResponse;
import com.google.api.client.http.javanet.NetHttpTransport;
import com.google.api.client.json.JsonFactory;
import com.google.api.client.json.gson.GsonFactory;

import java.io.IOException;
import java.io.UncheckedIOException;
import java.security.MessageDigest;
import java.security.NoSuchAlgorithmException;
import java.util.Base64;

import static java.nio.charset.StandardCharsets.UTF_8;

final class OAuth {
    final NetHttpTransport http = new NetHttpTransport();
    final JsonFactory json = new GsonFactory();
    final AuthorizationCodeFlow authFlow;

    final String serverUrl;
    final String clientId;
    final String clientSecret;

    OAuth(String serverUrl, String clientId, String clientSecret) {
        this.serverUrl = serverUrl;
        this.clientId = clientId;
        this.clientSecret = clientSecret;

        authFlow = new AuthorizationCodeFlow.Builder(BearerToken.authorizationHeaderAccessMethod(),
                http, json,
                new GenericUrl(serverUrl + "/token"),
                new BasicAuthentication(clientId, clientSecret),
                clientId,
                serverUrl + "/authorize").build();
    }

    /**
     * Generates the OIDC server URL to redirect to for the login page.
     */
    String authUrl(String csrfToken) {
        return authFlow.newAuthorizationUrl()
                .setState(sha256(csrfToken))
                .build();
    }

    /**
     * Called when the OIDC server redirects back to us after the user is logged in.
     * We ask the OIDC server for their details (username, email address etc) and
     * return it to store in our user session.
     */
    UserInfo authCallback(String csrfToken, String authCode, String state) {
        if (!state.equals(sha256(csrfToken))) {
            throw new IllegalArgumentException("Incorrect OAuth state, possible CSRF attack");
        }
        try {
            TokenResponse tokenResponse = authFlow.newTokenRequest(authCode).execute();
            Credential credential = new Credential(BearerToken.authorizationHeaderAccessMethod())
                    .setAccessToken(tokenResponse.getAccessToken());
            GenericUrl url = new GenericUrl(serverUrl + "/userinfo");
            HttpResponse response = http.createRequestFactory(credential)
                    .buildGetRequest(url)
                    .setParser(json.createJsonObjectParser())
                    .execute();
            UserInfo user = response.parseAs(UserInfo.class);
            user.issuer = serverUrl;
            return user;
        } catch (IOException e) {
            throw new UncheckedIOException(e);
        }
    }
    
    /**
     * Calculate a SHA-256 digest of a string.
     */
    private String sha256(String data) {
        try {
            MessageDigest digest = MessageDigest.getInstance("SHA-256");
            digest.update(data.getBytes(UTF_8));
            return Base64.getUrlEncoder().encodeToString(digest.digest());
        } catch (NoSuchAlgorithmException e) {
            throw new RuntimeException(e);
        }
    }
}
<commit_msg>Hex encode instead of base64 because = can't appear in url<commit_after>package butterflynet;

import com.google.api.client.auth.oauth2.AuthorizationCodeFlow;
import com.google.api.client.auth.oauth2.BearerToken;
import com.google.api.client.auth.oauth2.Credential;
import com.google.api.client.auth.oauth2.TokenResponse;
import com.google.api.client.http.BasicAuthentication;
import com.google.api.client.http.GenericUrl;
import com.google.api.client.http.HttpResponse;
import com.google.api.client.http.javanet.NetHttpTransport;
import com.google.api.client.json.JsonFactory;
import com.google.api.client.json.gson.GsonFactory;

import javax.xml.bind.DatatypeConverter;
import java.io.IOException;
import java.io.UncheckedIOException;
import java.security.MessageDigest;
import java.security.NoSuchAlgorithmException;
import java.util.Base64;

import static java.nio.charset.StandardCharsets.UTF_8;

final class OAuth {
    final NetHttpTransport http = new NetHttpTransport();
    final JsonFactory json = new GsonFactory();
    final AuthorizationCodeFlow authFlow;

    final String serverUrl;
    final String clientId;
    final String clientSecret;

    OAuth(String serverUrl, String clientId, String clientSecret) {
        this.serverUrl = serverUrl;
        this.clientId = clientId;
        this.clientSecret = clientSecret;

        authFlow = new AuthorizationCodeFlow.Builder(BearerToken.authorizationHeaderAccessMethod(),
                http, json,
                new GenericUrl(serverUrl + "/token"),
                new BasicAuthentication(clientId, clientSecret),
                clientId,
                serverUrl + "/authorize").build();
    }

    /**
     * Generates the OIDC server URL to redirect to for the login page.
     */
    String authUrl(String csrfToken) {
        return authFlow.newAuthorizationUrl()
                .setState(sha256(csrfToken))
                .build();
    }

    /**
     * Called when the OIDC server redirects back to us after the user is logged in.
     * We ask the OIDC server for their details (username, email address etc) and
     * return it to store in our user session.
     */
    UserInfo authCallback(String csrfToken, String authCode, String state) {
        if (!state.equals(sha256(csrfToken))) {
            throw new IllegalArgumentException("Incorrect OAuth state, possible CSRF attack");
        }
        try {
            TokenResponse tokenResponse = authFlow.newTokenRequest(authCode).execute();
            Credential credential = new Credential(BearerToken.authorizationHeaderAccessMethod())
                    .setAccessToken(tokenResponse.getAccessToken());
            GenericUrl url = new GenericUrl(serverUrl + "/userinfo");
            HttpResponse response = http.createRequestFactory(credential)
                    .buildGetRequest(url)
                    .setParser(json.createJsonObjectParser())
                    .execute();
            UserInfo user = response.parseAs(UserInfo.class);
            user.issuer = serverUrl;
            return user;
        } catch (IOException e) {
            throw new UncheckedIOException(e);
        }
    }
    
    /**
     * Calculate a SHA-256 digest of a string.
     */
    private String sha256(String data) {
        try {
            MessageDigest digest = MessageDigest.getInstance("SHA-256");
            digest.update(data.getBytes(UTF_8));
            return DatatypeConverter.printHexBinary(digest.digest());
        } catch (NoSuchAlgorithmException e) {
            throw new RuntimeException(e);
        }
    }
}

{'fraction_non_alphanumeric': 0.0904202631951323, 'fraction_numerical': 0.007075137965190321, 'mean_word_length': 2.6908616187989556, 'pattern_counts': {'":': 0, '<': 3, '<?xml version=': 0, '>': 3, 'https://': 0, 'lorem ipsum': 0, 'www.': 0, 'xml': 1}, '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': '5802833', 'n_tokens_mistral': 1930, 'n_tokens_neox': 1860, 'n_words': 441}