Triple-T / gradle-play-publisher

GPP is Android's unofficial release automation Gradle Plugin. It can do anything from building, uploading, and then promoting your App Bundle or APK to publishing app listings and other metadata.
MIT License
4.12k stars 340 forks source link

Add proxy authentication #826

Closed wintermute766 closed 4 years ago

wintermute766 commented 4 years ago

Problem description

It would be very useful to publish artifacts for those who are behind a corporate proxy that requires authentication. Because now all attempts result with 407 HTTP error. So I built plugin with this feature locally and it worked fine for me. Apparently it will be useful to add this feature to the main repo. I provided the example code and the full patch in the potential solutions section.

Potential [solutions/workarounds]

private fun buildTransport(): HttpTransport {
    val trustStore: String? = System.getProperty("javax.net.ssl.trustStore", null)
    val trustStorePassword: String? =
            System.getProperty("javax.net.ssl.trustStorePassword", null)

    return if (trustStore == null) {
        createHttpTransport()
    } else {
        val ks = KeyStore.getInstance(KeyStore.getDefaultType())
        FileInputStream(trustStore).use { fis ->
            ks.load(fis, trustStorePassword?.toCharArray())
        }
        NetHttpTransport.Builder().trustCertificates(ks).build()
    }
}

private fun createHttpTransport() : HttpTransport {
    val protocols = arrayOf("http", "https")
    for (protocol in protocols) {
        val proxyHost = System.getProperty("$protocol.proxyHost")
        val proxyUser = System.getProperty("$protocol.proxyUser")
        val proxyPassword = System.getProperty("$protocol.proxyPassword");
        if (proxyHost == null || proxyUser == null || proxyPassword == null) {
            return GoogleNetHttpTransport.newTrustedTransport()
        }
        val defaultProxyPort = if (protocol == "http") "80" else "443"
        val proxyPort = Integer.parseInt(System.getProperty("$protocol.proxyPort", defaultProxyPort))
        val credentials = BasicCredentialsProvider()
        credentials.setCredentials(
                AuthScope(proxyHost, proxyPort),
                UsernamePasswordCredentials(proxyUser, proxyPassword)
        )
        val httpClient = ApacheHttpTransport.newDefaultHttpClientBuilder()
                .setProxyAuthenticationStrategy(ProxyAuthenticationStrategy.INSTANCE)
                .setDefaultCredentialsProvider(credentials)
                .build()
        return ApacheHttpTransport(httpClient)
    }
    return GoogleNetHttpTransport.newTrustedTransport()
}

Full Patch:

Add_proxy_authentication.txt

Additional context

SUPERCILEX commented 4 years ago

Pretty sure we support proxies: https://github.com/Triple-T/gradle-play-publisher/blob/304b0fecba33e4457ad17e0703c4d9d638203793/play/android-publisher/src/main/kotlin/com/github/triplet/gradle/androidpublisher/internal/AndroidPublisher.kt#L32

SUPERCILEX commented 4 years ago

https://github.com/Triple-T/gradle-play-publisher#using-https-proxies

wintermute766 commented 4 years ago

I meant something like this https://github.com/GoogleContainerTools/jib/pull/1337 Because as I said before the problem I struggled with was the 407 HTTP error, not SSLHandshakeException https://developer.mozilla.org/en-US/docs/Web/HTTP/Status/407

SUPERCILEX commented 4 years ago

In the interest of transparency, I'll tell you that I don't know much of anything about proxies. If you want to submit a PR so that this plugin works with your use case, please do so! That said, I won't be working on this since I don't know enough about proxies.

stale[bot] commented 4 years ago

This issue has been automatically marked as stale because it has not had recent activity. It will be closed if no further activity occurs. Thank you for your contributions.

wintermute766 commented 4 years ago

Yeah, sorry that was my first intention, but I tried to push to the original project, not the forked one. So I couldn't do it because of insufficient permissions. And I decided that the default option to communicate with the developer is to create an issue.