Skip to content
New issue

Have a question about this project? Sign up for a free GitHub account to open an issue and contact its maintainers and the community.

By clicking “Sign up for GitHub”, you agree to our terms of service and privacy statement. We’ll occasionally send you account related emails.

Already on GitHub? Sign in to your account

Fix UnauthorizedError on GitHub Enterprise publish #740

Merged
merged 7 commits into from
Feb 24, 2023
Merged
Show file tree
Hide file tree
Changes from all commits
Commits
File filter

Filter by extension

Filter by extension

Conversations
Failed to load comments.
Loading
Jump to
Jump to file
Failed to load files.
Loading
Diff view
Diff view
25 changes: 25 additions & 0 deletions src/main/scala/microsites/MicrositeKeys.scala
Original file line number Diff line number Diff line change
Expand Up @@ -19,8 +19,10 @@ package microsites
import java.nio.file.*
import cats.effect.IO
import cats.effect.unsafe.implicits.global
import cats.syntax.either.*
import com.github.sbt.sbtghpages.GhpagesPlugin.autoImport.*
import com.typesafe.sbt.site.SitePlugin.autoImport.makeSite
import github4s.GithubConfig
import io.circe.*
import io.circe.generic.semiauto.*
import io.circe.syntax.*
Expand All @@ -36,6 +38,7 @@ import sbt.*
import sbt.complete.DefaultParsers.OptNotSpace
import sbt.io.IO as FIO

import java.net.MalformedURLException
import scala.language.implicitConversions
import scala.sys.process.*

Expand Down Expand Up @@ -491,6 +494,9 @@ trait MicrositeAutoImportSettings extends MicrositeKeys {

BlazeClientBuilder[IO].resource
.use { client =>

implicit val config: GithubConfig =
buildGithubConfig(micrositeGitHostingUrl.value)(log)
val ghOps: GitHubOps[IO] =
new GitHubOps[IO](client, githubOwner, githubRepo, githubToken)

Expand Down Expand Up @@ -551,6 +557,25 @@ trait MicrositeAutoImportSettings extends MicrositeKeys {
extracted.runTask(publishMultiversionMicrosite, st)._1
}

protected[this] def buildGithubConfig(hostingUrl: String)(implicit log: Logger): GithubConfig =
Either.catchOnly[MalformedURLException](new URL(hostingUrl)) match {
case Right(url) if url.getHost == "github.com" => GithubConfig.default
case Right(url) if url.getProtocol.startsWith("https") =>
val replaceHost: String => String = s => s.replace("github.com", url.getHost)
GithubConfig.default
.copy(
baseUrl = s"${url.getProtocol}://${url.getHost}/api/v3/",
necosta marked this conversation as resolved.
Show resolved Hide resolved
authorizeUrl = replaceHost(GithubConfig.default.authorizeUrl),
accessTokenUrl = replaceHost(GithubConfig.default.accessTokenUrl)
)
case Right(url) =>
log.warn(s"Invalid protocol: ${url.getProtocol}")
GithubConfig.default
case Left(ex) =>
log.error(ex.getMessage)
GithubConfig.default
}

private[this] def validFile(extension: String)(file: File): Boolean =
file.getName.endsWith(s".$extension")
}
2 changes: 1 addition & 1 deletion src/main/scala/microsites/github/GitHubOps.scala
Original file line number Diff line number Diff line change
Expand Up @@ -39,7 +39,7 @@ class GitHubOps[F[_]: Async: Temporal](
repo: String,
accessToken: Option[String],
fileReader: FileReader = FileReader
) {
)(implicit val config: GithubConfig) {

private val gh: Github[F] = Github[F](client, accessToken)
private val headers: Map[String, String] = Map("user-agent" -> "sbt-microsites")
Expand Down
86 changes: 86 additions & 0 deletions src/test/scala/microsites/MicrositeAutoImportSettingsTest.scala
Original file line number Diff line number Diff line change
@@ -0,0 +1,86 @@
/*
* Copyright 2016-2023 47 Degrees Open Source <https://www.47deg.com>
*
* Licensed under the Apache License, Version 2.0 (the "License");
* you may not use this file except in compliance with the License.
* You may obtain a copy of the License at
*
* http://www.apache.org/licenses/LICENSE-2.0
*
* Unless required by applicable law or agreed to in writing, software
* distributed under the License is distributed on an "AS IS" BASIS,
* WITHOUT WARRANTIES OR CONDITIONS OF ANY KIND, either express or implied.
* See the License for the specific language governing permissions and
* limitations under the License.
*/

package microsites

import github4s.GithubConfig
import microsites.util.Arbitraries
import org.scalacheck.Prop.*
import org.scalatest.funsuite.AnyFunSuite
import org.scalatest.matchers.should.Matchers
import org.scalatestplus.scalacheck.Checkers
import sbt.Logger

import java.net.URL

class MicrositeAutoImportSettingsTest
extends AnyFunSuite
with Checkers
with Matchers
with Arbitraries
with MicrositeAutoImportSettings {

test("buildGithubConfig should return default GitHub config when invalid Git hosting URL") {
val property = forAll(
settingsArbitrary.arbitrary suchThat (!_.gitSettings.gitHostingUrl.startsWith("https://"))
) {
settings: MicrositeSettings ⇒
implicit val log: Logger = Logger.Null
val githubConfig = buildGithubConfig(settings.gitSettings.gitHostingUrl)

githubConfig shouldBe GithubConfig.default
githubConfig.baseUrl.nonEmpty
}

check(property)
}

test("buildGithubConfig should override GitHub config when valid Git hosting URL") {
val property = forAll(
settingsArbitrary.arbitrary suchThat (_.gitSettings.gitHostingUrl.startsWith("https://"))
) {
settings: MicrositeSettings ⇒
implicit val log: Logger = Logger.Null
val gitSiteUrl = new URL(settings.gitSettings.gitHostingUrl)
val githubConfig = buildGithubConfig(gitSiteUrl.toString)

val actualGitBaseUrl = new URL(githubConfig.baseUrl)
actualGitBaseUrl.getProtocol shouldBe "https"
actualGitBaseUrl.getHost shouldBe gitSiteUrl.getHost
actualGitBaseUrl.getPath shouldBe "/api/v3/"

val actualGitAuthorizeUrl = new URL(githubConfig.authorizeUrl)
actualGitAuthorizeUrl.getProtocol shouldBe "https"
actualGitAuthorizeUrl.getHost shouldBe gitSiteUrl.getHost
actualGitAuthorizeUrl.getPath shouldBe new URL(GithubConfig.default.authorizeUrl).getPath
actualGitAuthorizeUrl.getQuery shouldBe new URL(GithubConfig.default.authorizeUrl).getQuery

val actualGitAccessTokenUrl = new URL(githubConfig.accessTokenUrl)
actualGitAccessTokenUrl.getProtocol shouldBe "https"
actualGitAccessTokenUrl.getHost shouldBe gitSiteUrl.getHost
actualGitAccessTokenUrl.getPath shouldBe new URL(
GithubConfig.default.accessTokenUrl
).getPath
actualGitAccessTokenUrl.getQuery shouldBe new URL(
GithubConfig.default.accessTokenUrl
).getQuery

githubConfig.baseUrl.nonEmpty
}

check(property)
}
}
16 changes: 14 additions & 2 deletions src/test/scala/microsites/util/Arbitraries.scala
Original file line number Diff line number Diff line change
Expand Up @@ -24,6 +24,8 @@ import org.scalacheck.Arbitrary
import org.scalacheck.Gen
import org.scalacheck.Gen.*

import java.net.URL

trait Arbitraries {

implicit def fileArbitrary: Arbitrary[File] =
Expand Down Expand Up @@ -99,6 +101,16 @@ trait Arbitraries {
} yield Some(MicrositeEditButton(text, basePath))
}

implicit val urlArbitrary: Arbitrary[URL] =
Arbitrary {
for {
protocol <- Gen.oneOf("http", "https", "ftp", "file")
domain <- Gen.alphaNumStr
tld <- Gen.oneOf("com", "io", "net")
path <- Gen.alphaNumStr
} yield new URL(s"$protocol://$domain.$tld/$path")
}

implicit def settingsArbitrary: Arbitrary[MicrositeSettings] =
Arbitrary {
for {
Expand Down Expand Up @@ -135,7 +147,7 @@ trait Arbitraries {
githubOwner <- Arbitrary.arbitrary[String]
githubRepo <- Arbitrary.arbitrary[String]
gitHostingService <- Arbitrary.arbitrary[GitHostingService]
gitHostingUrl <- Arbitrary.arbitrary[String]
gitHostingUrl <- Arbitrary.arbitrary[URL]
githubLinks <- Arbitrary.arbitrary[Boolean]
gitSidecarChat <- Arbitrary.arbitrary[Boolean]
gitSidecarChatUrl <- Arbitrary.arbitrary[String]
Expand Down Expand Up @@ -194,7 +206,7 @@ trait Arbitraries {
githubRepo,
githubLinks,
gitHostingService,
gitHostingUrl,
gitHostingUrl.toString, // ToDo: Change to URL type on codebase
gitSidecarChat,
gitSidecarChatUrl
),
Expand Down