Skip to content

Commit

Permalink
#1042 Allow Authentication via Http Header
Browse files Browse the repository at this point in the history
  • Loading branch information
liefke authored and eirslett committed Sep 5, 2024
1 parent 60bbf02 commit 122cd9b
Show file tree
Hide file tree
Showing 13 changed files with 159 additions and 47 deletions.
Original file line number Diff line number Diff line change
@@ -1,6 +1,8 @@
package com.github.eirslett.maven.plugins.frontend.mojo;

import java.io.File;
import java.util.Collections;
import java.util.HashMap;
import java.util.Map;

import org.apache.maven.plugin.AbstractMojo;
Expand All @@ -9,6 +11,8 @@
import org.apache.maven.plugins.annotations.Component;
import org.apache.maven.plugins.annotations.Parameter;
import org.apache.maven.project.MavenProject;
import org.apache.maven.settings.Server;
import org.apache.maven.shared.utils.xml.Xpp3Dom;
import org.eclipse.aether.RepositorySystemSession;

import com.github.eirslett.maven.plugins.frontend.lib.FrontendException;
Expand Down Expand Up @@ -106,5 +110,33 @@ public void execute() throws MojoFailureException {
getLog().info("Skipping execution.");
}
}

/**
* Provides the HTTP-Headers from the server section of settings.xml.
*
* @param server
* the <server> entry from the settings.xml
*/
protected Map<String, String> getHttpHeaders(Server server) {
if (server == null || !(server.getConfiguration() instanceof Xpp3Dom)) {
return Collections.emptyMap();
}

Xpp3Dom configuration = (Xpp3Dom) server.getConfiguration();

Map<String, String> result = new HashMap<>();

Xpp3Dom httpHeaders = configuration.getChild("httpHeaders");
if (httpHeaders != null) {
for (Xpp3Dom property : httpHeaders.getChildren("property")) {
Xpp3Dom name = property.getChild("name");
Xpp3Dom value = property.getChild("value");
if (name != null && value != null) {
result.put(name.getValue(), value.getValue());
}
}
}
return result;
}

}
Original file line number Diff line number Diff line change
Expand Up @@ -50,7 +50,7 @@ public void execute(FrontendPluginFactory factory) throws InstallationException
Server server = MojoUtils.decryptServer(this.serverId, this.session, this.decrypter);
if (null != server) {
factory.getBunInstaller(proxyConfig).setBunVersion(this.bunVersion).setUserName(server.getUsername())
.setPassword(server.getPassword()).install();
.setPassword(server.getPassword()).setHttpHeaders(getHttpHeaders(server)).install();
} else {
factory.getBunInstaller(proxyConfig).setBunVersion(this.bunVersion).install();
}
Expand Down
Original file line number Diff line number Diff line change
Expand Up @@ -5,6 +5,9 @@
import com.github.eirslett.maven.plugins.frontend.lib.InstallationException;
import com.github.eirslett.maven.plugins.frontend.lib.NodeInstaller;
import com.github.eirslett.maven.plugins.frontend.lib.ProxyConfig;

import java.util.Map;

import org.apache.maven.execution.MavenSession;
import org.apache.maven.plugins.annotations.Component;
import org.apache.maven.plugins.annotations.LifecyclePhase;
Expand Down Expand Up @@ -88,8 +91,15 @@ public void execute(FrontendPluginFactory factory) throws InstallationException
// If pplicable, configure authentication details
Server server = MojoUtils.decryptServer(serverId, session, decrypter);
if (null != server) {
nodeInstaller.setUserName(server.getUsername()).setPassword(server.getPassword());
corepackInstaller.setUserName(server.getUsername()).setPassword(server.getPassword());
Map<String, String> httpHeaders = getHttpHeaders(server);
nodeInstaller
.setUserName(server.getUsername())
.setPassword(server.getPassword())
.setHttpHeaders(httpHeaders);
corepackInstaller
.setUserName(server.getUsername())
.setPassword(server.getPassword())
.setHttpHeaders(httpHeaders);
}

// Perform the installation
Expand Down
Original file line number Diff line number Diff line change
Expand Up @@ -4,6 +4,9 @@
import com.github.eirslett.maven.plugins.frontend.lib.InstallationException;
import com.github.eirslett.maven.plugins.frontend.lib.NPMInstaller;
import com.github.eirslett.maven.plugins.frontend.lib.ProxyConfig;

import java.util.Map;

import org.apache.maven.execution.MavenSession;
import org.apache.maven.plugins.annotations.Component;
import org.apache.maven.plugins.annotations.LifecyclePhase;
Expand Down Expand Up @@ -78,19 +81,22 @@ public void execute(FrontendPluginFactory factory) throws InstallationException
String npmDownloadRoot = getNpmDownloadRoot();
Server server = MojoUtils.decryptServer(serverId, session, decrypter);
if (null != server) {
factory.getNodeInstaller(proxyConfig)
Map<String, String> httpHeaders = getHttpHeaders(server);
factory.getNodeInstaller(proxyConfig)
.setNodeVersion(nodeVersion)
.setNodeDownloadRoot(nodeDownloadRoot)
.setNpmVersion(npmVersion)
.setUserName(server.getUsername())
.setPassword(server.getPassword())
.setHttpHeaders(httpHeaders)
.install();
factory.getNPMInstaller(proxyConfig)
.setNodeVersion(nodeVersion)
.setNpmVersion(npmVersion)
.setNpmDownloadRoot(npmDownloadRoot)
.setUserName(server.getUsername())
.setPassword(server.getPassword())
.setHttpHeaders(httpHeaders)
.install();
} else {
factory.getNodeInstaller(proxyConfig)
Expand Down
Original file line number Diff line number Diff line change
Expand Up @@ -4,6 +4,9 @@
import com.github.eirslett.maven.plugins.frontend.lib.InstallationException;
import com.github.eirslett.maven.plugins.frontend.lib.PnpmInstaller;
import com.github.eirslett.maven.plugins.frontend.lib.ProxyConfig;

import java.util.Map;

import org.apache.maven.execution.MavenSession;
import org.apache.maven.plugins.annotations.Component;
import org.apache.maven.plugins.annotations.LifecyclePhase;
Expand Down Expand Up @@ -84,17 +87,20 @@ public void execute(FrontendPluginFactory factory) throws InstallationException
String resolvedPnpmDownloadRoot = getPnpmDownloadRoot();
Server server = MojoUtils.decryptServer(serverId, session, decrypter);
if (null != server) {
Map<String, String> httpHeaders = getHttpHeaders(server);
factory.getNodeInstaller(proxyConfig)
.setNodeVersion(nodeVersion)
.setNodeDownloadRoot(resolvedNodeDownloadRoot)
.setUserName(server.getUsername())
.setPassword(server.getPassword())
.setHttpHeaders(httpHeaders)
.install();
factory.getPnpmInstaller(proxyConfig)
.setPnpmVersion(pnpmVersion)
.setPnpmDownloadRoot(resolvedPnpmDownloadRoot)
.setUserName(server.getUsername())
.setPassword(server.getPassword())
.setHttpHeaders(httpHeaders)
.install();
} else {
factory.getNodeInstaller(proxyConfig)
Expand Down
Original file line number Diff line number Diff line change
Expand Up @@ -2,8 +2,7 @@

import static com.github.eirslett.maven.plugins.frontend.mojo.YarnUtils.isYarnrcYamlFilePresent;

import java.io.File;
import java.util.stream.Stream;
import java.util.Map;
import org.apache.maven.execution.MavenSession;
import org.apache.maven.plugins.annotations.Component;
import org.apache.maven.plugins.annotations.LifecyclePhase;
Expand Down Expand Up @@ -79,12 +78,14 @@ public void execute(FrontendPluginFactory factory) throws InstallationException
boolean isYarnYamlFilePresent = isYarnrcYamlFilePresent(this.session, this.workingDirectory);

if (null != server) {
Map<String, String> httpHeaders = getHttpHeaders(server);
factory.getNodeInstaller(proxyConfig).setNodeDownloadRoot(this.nodeDownloadRoot)
.setNodeVersion(this.nodeVersion).setPassword(server.getPassword())
.setUserName(server.getUsername()).install();
.setNodeVersion(this.nodeVersion).setUserName(server.getUsername())
.setPassword(server.getPassword()).setHttpHeaders(httpHeaders).install();
factory.getYarnInstaller(proxyConfig).setYarnDownloadRoot(this.yarnDownloadRoot)
.setYarnVersion(this.yarnVersion).setUserName(server.getUsername())
.setPassword(server.getPassword()).setIsYarnBerry(isYarnYamlFilePresent).install();
.setPassword(server.getPassword()).setHttpHeaders(httpHeaders)
.setIsYarnBerry(isYarnYamlFilePresent).install();
} else {
factory.getNodeInstaller(proxyConfig).setNodeDownloadRoot(this.nodeDownloadRoot)
.setNodeVersion(this.nodeVersion).install();
Expand Down
Original file line number Diff line number Diff line change
Expand Up @@ -11,6 +11,7 @@
import java.nio.file.Files;
import java.nio.file.StandardCopyOption;
import java.util.Arrays;
import java.util.Map;

public class BunInstaller {

Expand All @@ -22,6 +23,8 @@ public class BunInstaller {

private String bunVersion, userName, password;

private Map<String, String> httpHeaders;

private final Logger logger;

private final InstallConfig config;
Expand Down Expand Up @@ -52,6 +55,11 @@ public BunInstaller setPassword(String password) {
return this;
}

public BunInstaller setHttpHeaders(Map<String, String> httpHeaders) {
this.httpHeaders = httpHeaders;
return this;
}

public void install() throws InstallationException {
// use static lock object for a synchronized block
synchronized (LOCK) {
Expand Down Expand Up @@ -105,7 +113,7 @@ private void installBunDefault() throws InstallationException {

File archive = this.config.getCacheResolver().resolve(cacheDescriptor);

downloadFileIfMissing(downloadUrl, archive, this.userName, this.password);
downloadFileIfMissing(downloadUrl, archive, this.userName, this.password, this.httpHeaders);

File installDirectory = getInstallDirectory();

Expand Down Expand Up @@ -201,16 +209,16 @@ private void extractFile(File archive, File destinationDirectory) throws Archive
this.archiveExtractor.extract(archive.getPath(), destinationDirectory.getPath());
}

private void downloadFileIfMissing(String downloadUrl, File destination, String userName, String password)
private void downloadFileIfMissing(String downloadUrl, File destination, String userName, String password, Map<String, String> httpHeaders)
throws DownloadException {
if (!destination.exists()) {
downloadFile(downloadUrl, destination, userName, password);
downloadFile(downloadUrl, destination, userName, password, httpHeaders);
}
}

private void downloadFile(String downloadUrl, File destination, String userName, String password)
private void downloadFile(String downloadUrl, File destination, String userName, String password, Map<String, String> httpHeaders)
throws DownloadException {
this.logger.info("Downloading {} to {}", downloadUrl, destination);
this.fileDownloader.download(downloadUrl, destination.getPath(), userName, password);
this.fileDownloader.download(downloadUrl, destination.getPath(), userName, password, httpHeaders);
}
}
Original file line number Diff line number Diff line change
Expand Up @@ -9,6 +9,7 @@
import java.nio.file.Files;
import java.nio.file.Path;
import java.util.HashMap;
import java.util.Map;

public class CorepackInstaller {

Expand All @@ -20,6 +21,8 @@ public class CorepackInstaller {

private String corepackVersion, corepackDownloadRoot, userName, password;

private Map<String, String> httpHeaders;

private final Logger logger;

private final InstallConfig config;
Expand Down Expand Up @@ -59,6 +62,11 @@ public CorepackInstaller setPassword(String password) {
return this;
}

public CorepackInstaller setHttpHeaders(Map<String, String> httpHeaders) {
this.httpHeaders = httpHeaders;
return this;
}

public void install() throws InstallationException {
// use static lock object for a synchronized block
synchronized (LOCK) {
Expand Down Expand Up @@ -120,7 +128,7 @@ private void installCorepack() throws InstallationException {

File archive = this.config.getCacheResolver().resolve(cacheDescriptor);

downloadFileIfMissing(downloadUrl, archive, this.userName, this.password);
downloadFileIfMissing(downloadUrl, archive, this.userName, this.password, this.httpHeaders);

File installDirectory = getNodeInstallDirectory();
File nodeModulesDirectory = new File(installDirectory, "node_modules");
Expand Down Expand Up @@ -261,16 +269,16 @@ private void extractFile(File archive, File destinationDirectory) throws Archive
this.archiveExtractor.extract(archive.getPath(), destinationDirectory.getPath());
}

private void downloadFileIfMissing(String downloadUrl, File destination, String userName, String password)
private void downloadFileIfMissing(String downloadUrl, File destination, String userName, String password, Map<String, String> httpHeaders)
throws DownloadException {
if (!destination.exists()) {
downloadFile(downloadUrl, destination, userName, password);
downloadFile(downloadUrl, destination, userName, password, httpHeaders);
}
}

private void downloadFile(String downloadUrl, File destination, String userName, String password)
private void downloadFile(String downloadUrl, File destination, String userName, String password, Map<String, String> httpHeaders)
throws DownloadException {
this.logger.info("Downloading {} to {}", downloadUrl, destination);
this.fileDownloader.download(downloadUrl, destination.getPath(), userName, password);
this.fileDownloader.download(downloadUrl, destination.getPath(), userName, password, httpHeaders);
}
}
Original file line number Diff line number Diff line change
Expand Up @@ -5,6 +5,7 @@
import java.net.URI;
import java.net.URISyntaxException;
import java.net.URL;
import java.util.Map;

import org.apache.commons.io.IOUtils;
import org.apache.commons.io.FileUtils;
Expand Down Expand Up @@ -39,7 +40,7 @@ public DownloadException(String message){
}

interface FileDownloader {
void download(String downloadUrl, String destination, String userName, String password) throws DownloadException;
void download(String downloadUrl, String destination, String userName, String password, Map<String, String> header) throws DownloadException;
}

final class DefaultFileDownloader implements FileDownloader {
Expand All @@ -52,7 +53,7 @@ public DefaultFileDownloader(ProxyConfig proxyConfig){
}

@Override
public void download(String downloadUrl, String destination, String userName, String password) throws DownloadException {
public void download(String downloadUrl, String destination, String userName, String password, Map<String, String> httpHeaders) throws DownloadException {
// force tls to 1.2 since github removed weak cryptographic standards
// https://blog.github.com/2018-02-02-weak-cryptographic-standards-removal-notice/
System.setProperty("https.protocols", "TLSv1.2");
Expand All @@ -64,7 +65,7 @@ public void download(String downloadUrl, String destination, String userName, St
FileUtils.copyFile(new File(downloadURI), new File(destination));
}
else {
CloseableHttpResponse response = execute(fixedDownloadUrl, userName, password);
CloseableHttpResponse response = execute(fixedDownloadUrl, userName, password, httpHeaders);
int statusCode = response.getStatusLine().getStatusCode();
if(statusCode != 200){
throw new DownloadException("Got error code "+ statusCode +" from the server.");
Expand All @@ -79,7 +80,7 @@ public void download(String downloadUrl, String destination, String userName, St
}
}

private CloseableHttpResponse execute(String requestUrl, String userName, String password) throws IOException {
private CloseableHttpResponse execute(String requestUrl, String userName, String password, Map<String, String> httpHeaders) throws IOException {
final HttpGet request = new HttpGet(requestUrl);
final CredentialsProvider credentialsProvider = new BasicCredentialsProvider();

Expand All @@ -100,6 +101,13 @@ private CloseableHttpResponse execute(String requestUrl, String userName, String
} else {
LOGGER.info("No proxy was configured, downloading directly");
}

if (httpHeaders != null) {
for (Map.Entry<String, String> header : httpHeaders.entrySet()) {
LOGGER.info("Using HTTP-Header (" + header.getKey() + ") from settings.xml");
request.addHeader(header.getKey(), header.getValue());
}
}

if (StringUtils.isNotEmpty(userName) && StringUtils.isNotEmpty(password)) {
LOGGER.info("Using credentials (" + userName + ") from settings.xml");
Expand Down
Loading

0 comments on commit 122cd9b

Please sign in to comment.