Skip to content

Commit 8144a05

Browse files
committed
Merge branch 'test-GithubAuthAlg'
2 parents f3741d4 + c16c8c2 commit 8144a05

File tree

4 files changed

+107
-20
lines changed

4 files changed

+107
-20
lines changed

modules/core/src/main/scala/org/scalasteward/core/forge/github/GitHubAuthAlg.scala

Lines changed: 27 additions & 19 deletions
Original file line numberDiff line numberDiff line change
@@ -18,13 +18,15 @@ package org.scalasteward.core.forge.github
1818

1919
import better.files.File
2020
import cats.effect.Sync
21+
import cats.implicits._
2122
import io.jsonwebtoken.{Jwts, SignatureAlgorithm}
23+
import org.bouncycastle.jce.provider.BouncyCastleProvider
24+
import org.bouncycastle.util.io.pem.PemReader
25+
2226
import java.io.FileReader
2327
import java.security.spec.PKCS8EncodedKeySpec
2428
import java.security.{KeyFactory, PrivateKey, Security}
2529
import java.util.Date
26-
import org.bouncycastle.jce.provider.BouncyCastleProvider
27-
import org.bouncycastle.util.io.pem.PemReader
2830
import scala.concurrent.duration.FiniteDuration
2931
import scala.util.Using
3032

@@ -33,6 +35,9 @@ trait GitHubAuthAlg[F[_]] {
3335
/** [[https://docs.github.com/en/free-pro-team@latest/developers/apps/authenticating-with-github-apps#authenticating-as-a-github-app]]
3436
*/
3537
def createJWT(app: GitHubApp, ttl: FiniteDuration): F[String]
38+
39+
def createJWT(app: GitHubApp, ttl: FiniteDuration, nowMillis: Long): F[String]
40+
3641
}
3742

3843
object GitHubAuthAlg {
@@ -56,23 +61,26 @@ object GitHubAuthAlg {
5661

5762
/** [[https://docs.github.com/en/free-pro-team@latest/developers/apps/authenticating-with-github-apps#authenticating-as-a-github-app]]
5863
*/
59-
def createJWT(app: GitHubApp, ttl: FiniteDuration): F[String] = F.delay {
60-
Security.addProvider(new BouncyCastleProvider())
61-
val ttlMillis = ttl.toMillis
62-
val nowMillis = System.currentTimeMillis()
63-
val now = new Date(nowMillis)
64-
val signingKey = readPrivateKey(app.keyFile)
65-
val builder = Jwts
66-
.builder()
67-
.setIssuedAt(now)
68-
.setIssuer(app.id.toString)
69-
.signWith(signingKey, SignatureAlgorithm.RS256)
70-
if (ttlMillis > 0) {
71-
val expMillis = nowMillis + ttlMillis
72-
val exp = new Date(expMillis)
73-
builder.setExpiration(exp)
64+
def createJWT(app: GitHubApp, ttl: FiniteDuration): F[String] =
65+
F.delay(System.currentTimeMillis()).flatMap(createJWT(app, ttl, _))
66+
67+
def createJWT(app: GitHubApp, ttl: FiniteDuration, nowMillis: Long): F[String] =
68+
F.delay {
69+
Security.addProvider(new BouncyCastleProvider())
70+
val ttlMillis = ttl.toMillis
71+
val now = new Date(nowMillis)
72+
val signingKey = readPrivateKey(app.keyFile)
73+
val builder = Jwts
74+
.builder()
75+
.setIssuedAt(now)
76+
.setIssuer(app.id.toString)
77+
.signWith(signingKey, SignatureAlgorithm.RS256)
78+
if (ttlMillis > 0) {
79+
val expMillis = nowMillis + ttlMillis
80+
val exp = new Date(expMillis)
81+
builder.setExpiration(exp)
82+
}
83+
builder.compact()
7484
}
75-
builder.compact()
76-
}
7785
}
7886
}
Lines changed: 51 additions & 0 deletions
Original file line numberDiff line numberDiff line change
@@ -0,0 +1,51 @@
1+
-----BEGIN RSA PRIVATE KEY-----
2+
MIIJJwIBAAKCAgEAqETmgWBi5rCmb7euJplA/9xs65+bncc9Yvs5zjyycXSW82Jf
3+
RuyguGm0OvA2wog24dR4N2kT/87DcGtp5JqJWADVFNr+2V2r6i57/OMLruRpn3p2
4+
r95dmo0COE+BxPFl7XEBT8JbH57ZtpgcB3/xkS14nLOWFf96hrXPlXJC+VMVKVZm
5+
A8k2LRh42vT5wUf4U0Doy/p7yFNSFFa6Q8wwe4TBy/z/f+rhFD1w8rxlYjallee/
6+
ocm7bjZCwbJGMm7orLViqWfsFX3O35PeoJ5h/7uJ7iRwvTFERkTdwWP/0BeKBeIt
7+
BR3YFc2mut+V9W+WKRkMSL6Crc+oVSx3p8aB7j9SZFzQiRtes4BYETpX1xl2mgIq
8+
5hvsFbLw7ESrlIodiwUMTrSIid2DQ6q80kv1zXPr4+Id6L0sJLxPCaXnTmNtasSw
9+
yedJJYxLjwhHJwtzFAeaq18H3O791YKhjAJ6YxK3zJ59jTE6Pkvqjq183f2PGHVR
10+
vgSN7aCmI6MBUUB5wDP2K8zX2sh40/uPDVSd6ei1vl3DpPk+h8iExx6AzbohfqZ+
11+
5RUUNx127L3MaQvOVC5TxV+R99gwKW++wzcVuO3m2KqVUj+K1uYBy3KBCUMBbckp
12+
EWGbN++jcdV5oJX6fsC66nOmKlntYwCL/pRww+oLsbzF8J3dxeDbKNF9JDsCAwEA
13+
AQKCAgBJF8TZJjlP5CQoGy227pNhkSpvH6HFY6qyuFZf09XfmrmHd4/Tiy41bRUx
14+
FO90iR7t8hFWYHqjf/k9eCtDdi164MGukYJqgVoQG6kYLLgCfI21DMlJk9otLFtu
15+
gnroRcP05EWhk9dpYONJgcGLMHSKj6n4x7nGTHe41HkbfcrB6ukiT7l4o4q5BAxb
16+
cFadMtoXr/ZvxJrIZgkddJ7snGHjBcP5DCkgM7MZy6aoilWv1/UNrOF9MdgNA9zz
17+
rrD3b136x7/XvqC6pS+bxuvJ8YK4R4qeu42NYT07GOcK/pk8lz0JWTodIt2eevqV
18+
6lGFj7c2mv7PCpJRVgbVGL/RTVVap/+jbcRVLdnYKsII/dANG7iXnfwRgkLWet5D
19+
OOsPuvIuyiSaJIwcdRE3SSO+tZhKLt+gh/oLxBPw5Ex0FwsVTtYn3Q/X3EAx+Wph
20+
eFcRr3TVkDg0MfdWWkgk16DvYB5cWc29coTaH1g+2juadNHbtVAigwJorKc6sxH3
21+
QGsW0WQJ8ZRZgJkSUuu3nr7QD3ZrgHptONQAh1RWGnIWi6OlMfaPdMo+SDnnL5SG
22+
mpOPjWadDc1XvMFnKQYMYB5GWU/ZNmnZmDLyg1Pc0Y+qRUc0s83nZFHN60KnUrSz
23+
0MZDspSFtr0fMx0b2/EB4EbuXd3QjQURF6P6HtWBu6oFnzu1AQKCAQEA2R9BKJgJ
24+
vNP+DUu8NBzwmi0cKlAiaxt+w90i5DWq1XWPKgi+RVLkaQSJqHoYQVNgEwL/cWxp
25+
s2r3GCMNIdOrGdcm8dX/6UYFpRaFcViTycVEA7cwZOMppgqr2Q+ZYX42K7HObUVL
26+
JGvdEWWWfSsynUGsrG87DC1gl94ANxCdqkZdbW5d3X0w5v7M/1tlrmAeskZSZpeT
27+
8BwwM6REb0U/B4/i8TLtLi/PGmMTOIxW41uKS/S6kq/gwyv+jNNO0ljhPt25iSbV
28+
K5ZHS4YuPKLl0tZMaOkPco9s6t4ES/Y317zQoTzUkAAkkFO4QPzRZL0ESqVBNR0h
29+
Ao7FLmFZzFHpoQKCAQEAxmZBn0UrJLXkD7bw66y4RwzjQYmxLlkEl3uvjrvVSuL1
30+
mAHDW58aGIpFFZ8QSTtNewIBQYNifp/cdFHAagqtl/iMGEegaOpJAKu/ykrkfZUp
31+
7mYDNng4ZWpypeKaGMAQoNzZiUpF+BDnqbeb/kgYu6sNlh9gRHR79rgAuZQxZ/1B
32+
tE8WcUFi4CnTq2QLqX4LwMuZHWXAJQoMoW3K5av+J544lIM6GdMJuIONtBBkKVQD
33+
ErrJ0bqYeykrFS6pKl/NBCZLGo5xFFRiYEdZ1GlA3uW3EGKppz6PS7194+x5UVts
34+
xZPUfkgdFjWCczkl4JDoWfaNn5sgXtiVbGh1n3gYWwKCAQB7vHEg1kyuXU4qe5/d
35+
PyTraIvlnVeQHNJIgy0QS3l5Pw8A0IzG6y+anehpqHNMP1zAWPQEytkOVAZPriIc
36+
xgl7p37dUa0PX0V2SPhxmR5YXeCeEXc197PTmb9H67jos8nhauqOoW/qaMJK2M9D
37+
tCubLUNf3eAT14R16CHNP93qnUE/TSeXQ3JsIofne0neb47u4F6zcuzvaNEbjSEn
38+
HJqID7sw5GoA6WQo0I+yqWAXICMXmHf/gtYfxGHEFeSUwexULH5BKG1R8sncw7J0
39+
Ag3h8xkGrNON4SkcTLy8Iay/eS6YxRcKndo4mk2mU65tr77TX4xi3Z/jWkQLY5WO
40+
eJwhAoIBABO17wkSxyGDjJ/fDfpsE3bDmgRV2KuBHoqqOBvXH26sM7ghXLZKjT4o
41+
5ooqXmTYJm91GIjYs71exnkr8hDW9L4nbEuxOgeSVyRg69H+NMshOaQ8sE8GDJxO
42+
wgsnAyY4Vq6UomwYW/E0RL/AxRezM/nZGaVzgo3qgLJXP4MwbOQm7hMq1FD2LQuW
43+
PDhH3Ty+kA5ca97W0Asd/3k+Pi0pNDvdZUOj8e7E369cKoTcKAdPGGsQ8aILhsCd
44+
q3EUTKwwDl8+KrH9utBJPejQzeTjfBVo/xH6q145QeVFcy9ku/zQN3M9p5vQMEuX
45+
j1lBMTkpTFw7uYBE2idyHw5BJoZsWQcCggEADfZTChqnOncItSflzGoaAACrr4/x
46+
KyT/4A+cPMCs11JN9J+EWsCezya2o1l/NF7YPcBR4qjCmFMEiq5GxH5fGLQp0aa7
47+
V13mHA8XBQ25OW2K7BGJhMHdbuvTnl6jsOfC4+t7P2bUAYxoP6/ncxTzZ5OlBN5k
48+
aMv9firWl1kSKK75ww9DWn6j0rQ4dBetwX45EMcs+iKIdydg0fmJxR2EJ+uQsCFy
49+
xcWBEDqV7qLUi6UrAPL3v/DXUv9wKcKOTbKw/aNE8+YTWMUO330GCJ5cVU1eTL5t
50+
UrcNKOJkFIj7jJUCzv6vcy++hMJEbNXnnTVRnky6e9C2vwzMl33njntapg==
51+
-----END RSA PRIVATE KEY-----

modules/core/src/test/scala/org/scalasteward/core/BuiltinConfigFilesTest.scala

Lines changed: 1 addition & 1 deletion
Original file line numberDiff line numberDiff line change
@@ -1,6 +1,6 @@
11
package org.scalasteward.core
22

3-
import better.files._
3+
import better.files.File
44
import cats.effect.unsafe.implicits.global
55
import munit.FunSuite
66
import org.scalasteward.core.application.Config.{ArtifactCfg, RepoConfigCfg, ScalafixCfg}
Lines changed: 28 additions & 0 deletions
Original file line numberDiff line numberDiff line change
@@ -0,0 +1,28 @@
1+
package org.scalasteward.core.forge.github
2+
3+
import better.files.File
4+
import cats.effect.IO
5+
import munit.CatsEffectSuite
6+
7+
import scala.concurrent.duration._
8+
9+
class GitHubAuthAlgTest extends CatsEffectSuite {
10+
11+
private val gitHubAuthAlg = GitHubAuthAlg.create[IO]
12+
private val pemFile = File(getClass.getResource("/rsa-4096-private.pem"))
13+
private val nowMillis = 1673743729714L
14+
15+
test("createJWT with ttl") {
16+
val obtained = gitHubAuthAlg.createJWT(GitHubApp(42, pemFile), 2.minutes, nowMillis)
17+
val expected =
18+
"eyJhbGciOiJSUzI1NiJ9.eyJpYXQiOjE2NzM3NDM3MjksImlzcyI6IjQyIiwiZXhwIjoxNjczNzQzODQ5fQ.SDW4TqjokzYAwHD6joDdgqCtQyPrq-4QThanWB12vNUkjNtP4gw9iiG_baWBNXi4nlA6_HtO0H_WNKO6God6vkHz_ERBbIUb7I2vhp17NEb8vRECUksqARnrAzPU8HPUZPD5V7uehEDxEa-Tv-eI3L8iH8JVWx-m60vAZdBi76IQ094mIXf_d1TC75HKpap1wPMV7i_973IVAuL6zu2Sy6bkhHAS0WAQKStSAolFvwih7uq2f6N1b-1ogopFtkL6w19lQ4iRSvaoXPvkyBuvw6DqowVcAWon8-OB9cdzUIsjQs5GkR4IwCQQOBp-9_NYKBRDyVTwa-vqBBlYcOc_Zzd-_tpK3zRLpsh-h8_p0W8YAQrYAVyJRWn128Mm72jc2q9DkWhsiIGGWr44p3z6DENypgx3HiFDZbcvgMhPJKeNY3CwYh2QK56XtPNcbYSmUzog1IkX5lrM3WOO9j1bfj8tTP5h46dYXApvTq2-q5zlLP66Rm40RQnc_TE_6ntVq1kKn6IQ0yqEuPN0GVwoX71PElnajufz_Bzn08-YtYMK2Ca-t-wKWapDaH9zDjWUoXe_Pbcb5T_AZkbqPy8MHkzRzkMFSACwrXjHDuq_PphdlHZJeIb4xJ0PSp4f6urz_TRdxFmrTlG-e7DaKcoOLMbp8VK419TD3VinXq3MGDs"
19+
assertIO(obtained, expected)
20+
}
21+
22+
test("createJWT without ttl") {
23+
val obtained = gitHubAuthAlg.createJWT(GitHubApp(42, pemFile), 0.minutes, nowMillis)
24+
val expected =
25+
"eyJhbGciOiJSUzI1NiJ9.eyJpYXQiOjE2NzM3NDM3MjksImlzcyI6IjQyIn0.GcJ2RzzwgN-decPz0BNhNwrMFh6Wjj2xtbH0bOWEBGolnclEymJDT0QrjojvVw7iDabq5FezOGgPYP6JXlykMQlXFjX7TFeBAsydpZt1wyU1N8PQwxpoUtumksBGgTqNuIWg6_Y8CQg-UTbM4B63axcNREz6iT43a0cKxNe0ABy6jwcWSXw2Ck5Ob2uS_ZMCAt3VapIovT7Vci0goI7z6eXF8l6FpJauSgiVRXYsOAoZwXnDeNU1LkWFkGtWh9vK4iyaI_IDc85f3ODU5KfiPHOWuy2h7j6WPKEMXQTLXiiGQr_HqP4ROR-HXW7hlpyBFsrL44EqNe3oQcnTWNdOAj2s2K0aLzMm1XmeenPKgMeJcDvp8q_lRFKC54En4bHKZZEccOVnfItEb7D7fkBuWUYM5-k6cb4CPZyPrOvO5zBsQyboW2_Zcrpr_mGelm9rdSQ29azIvu2G2gBWY_QsT54E1_D3uN4HbsUsTxwjJPXlw2ScFgn_4wGu3XuU9QfIzipw4-PJtXo9deoHMinji0VuXzAZslJMyCoKqvCOV7voVNQOuQJroVeahVY1cU-dWLWOfrOcJ0LZRxZ2gIoRztc1wawfmNix8mFGNXei_qY0M5LZtOgWfdgIsmrUF17s1mX2Lwp2mlvjvCCP6qcXQnrn6GWit_ihcOb2IFR9yIw"
26+
assertIO(obtained, expected)
27+
}
28+
}

0 commit comments

Comments
 (0)