Skip to content

Commit

Permalink
Fix UnauthorizedError on GitHub Enterprise publish (#740)
Browse files Browse the repository at this point in the history
* Fix UnauthorizedError on GitHub Enterprise publish

* Add unit-tests

* Fix issue when hostingUrl is still github.com

* Added the slash at the end of the baseURL.

* Adjust baseUrl override logic

* Fix unit tests

---------

Co-authored-by: Tomas Merendon <tomas.merendon@gmail.com>
  • Loading branch information
necosta and TomyMeren authored Feb 24, 2023
1 parent 995eabe commit 02e9681
Show file tree
Hide file tree
Showing 4 changed files with 126 additions and 3 deletions.
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/",
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

0 comments on commit 02e9681

Please sign in to comment.