Stream example
First we need to import everthing that we need.
import java.time.Instant
import cats.effect._
import io.github.jkobejs.google.oauth4s.ServerToServer
import io.github.jkobejs.google.oauth4s.ServiceAccountKeyReader
import scala.concurrent.ExecutionContext.Implicits.global
import fs2.Stream
We will use cats.effect.IO
effect wrapper to make our computation pure. To be able to use it we need to create context shift and timer which are need for shifting execution and scheduling of tasks.
implicit val ctx = IO.contextShift(global)
// ctx: ContextShift[IO] = cats.effect.internals.IOContextShift@43571e39
implicit val timer = IO.timer(global)
// timer: Timer[IO] = cats.effect.internals.IOTimer@12982287
To communicate with google auth api we need to create claims and settings. We can do it in two ways, create them manually (private key should we read in a safe way) or read service account key data from google service account key file and use it to create settings.
Let’s first do it manually.
{
val privateKey = "sample-private-key" // read it in a safe way
val clientEmail = "sample@email.iam.gserviceaccount.com"
val url = "https://www.googleapis.com/oauth2/v4/token"
val scope = "https://www.googleapis.com/auth/devstorage.read_write"
val claims = ServerToServer.GoogleClaims(
issuer = clientEmail,
scope = scope,
audience = url,
expiration = Instant.now().plusSeconds(3600),
issuedAt = Instant.now()
)
val settings = ServerToServer.Settings(
uri = "https://www.googleapis.com/oauth2/v4/token",
privateKey = privateKey,
grantType = "urn:ietf:params:oauth:grant-type:jwt-bearer",
claims = claims
)
ServerToServer.stream[IO](settings, global)
}
// res0: Stream[IO, ServerToServer.AuthResponse] = Stream(..)
Now lets see how to use ServiceAccountKey
.
for {
serviceAccountKey <- Stream.eval(ServiceAccountKeyReader.readServiceAccountKey[IO]("src/test/resources/service-account.json", global))
scope = "https://www.googleapis.com/auth/devstorage.read_write"
claims = ServerToServer.GoogleClaims(
issuer = serviceAccountKey.client_email,
scope = scope,
audience = serviceAccountKey.token_uri,
expiration = Instant.now().plusSeconds(3600),
issuedAt = Instant.now()
)
settings = ServerToServer.Settings(
uri = serviceAccountKey.token_uri,
privateKey = serviceAccountKey.private_key,
grantType = "urn:ietf:params:oauth:grant-type:jwt-bearer",
claims = claims
)
stream <- ServerToServer.stream[IO](settings, global)
} yield stream
// res1: Stream[IO[x], ServerToServer.AuthResponse] = Stream(..)