AppInstallationAuthorizationProvider.java
package org.kohsuke.github.authorization;
import org.kohsuke.github.BetaApi;
import org.kohsuke.github.GHApp;
import org.kohsuke.github.GHAppInstallation;
import org.kohsuke.github.GHAppInstallationToken;
import org.kohsuke.github.GitHub;
import java.io.IOException;
import java.time.Duration;
import java.time.Instant;
import java.util.Objects;
import javax.annotation.Nonnull;
/**
* An AuthorizationProvider that performs automatic token refresh for an organization's AppInstallation.
*/
public class AppInstallationAuthorizationProvider extends GitHub.DependentAuthorizationProvider {
private final AppInstallationProvider appInstallationProvider;
private String authorization;
@Nonnull
private Instant validUntil = Instant.MIN;
/**
* Provides an AuthorizationProvider that performs automatic token refresh, based on an previously authenticated
* github client.
*
* @param appInstallationProvider
* An AppInstallationProvider that the authorization provider will use to retrieve the App.
* @param authorizationProvider
* A authorization provider that returns a JWT token that can be used to refresh the App Installation
* token from GitHub.
*/
@BetaApi
public AppInstallationAuthorizationProvider(AppInstallationProvider appInstallationProvider,
AuthorizationProvider authorizationProvider) {
super(authorizationProvider);
this.appInstallationProvider = appInstallationProvider;
}
@Override
public String getEncodedAuthorization() throws IOException {
synchronized (this) {
if (authorization == null || Instant.now().isAfter(this.validUntil)) {
String token = refreshToken();
authorization = String.format("token %s", token);
}
return authorization;
}
}
private String refreshToken() throws IOException {
GitHub gitHub = this.gitHub();
GHAppInstallation installationByOrganization = appInstallationProvider.getAppInstallation(gitHub.getApp());
GHAppInstallationToken ghAppInstallationToken = installationByOrganization.createToken().create();
this.validUntil = ghAppInstallationToken.getExpiresAt().toInstant().minus(Duration.ofMinutes(5));
return Objects.requireNonNull(ghAppInstallationToken.getToken());
}
/**
* Provides an interface that returns an app to be used by an AppInstallationAuthorizationProvider
*/
@FunctionalInterface
public interface AppInstallationProvider {
/**
* Provides a GHAppInstallation for the given GHApp
*
* @param app
* The GHApp to use
* @return The GHAppInstallation
* @throws IOException
* on error
*/
GHAppInstallation getAppInstallation(GHApp app) throws IOException;
}
}