Skip to content

Commit

Permalink
feat: Add data:application/json;base64 support to AuthenticationOauth2 (
Browse files Browse the repository at this point in the history
#263)

* feat: Add data:application/json;base64 support to AuthenticationOauth2

* Refactoring

* Fix build

---------

Co-authored-by: Vladimir Shchur <odindafna2006@rambler.ru>
  • Loading branch information
chriscameron-vertexinc and Lanayx authored May 15, 2024
1 parent 9eda4b2 commit ad89cbb
Show file tree
Hide file tree
Showing 2 changed files with 27 additions and 8 deletions.
2 changes: 1 addition & 1 deletion global.json
Original file line number Diff line number Diff line change
@@ -1,5 +1,5 @@
{
"sdk": {
"version": "8.0.202"
"version": "8.0.300"
}
}
33 changes: 26 additions & 7 deletions src/Pulsar.Client/Auth/Oauth2/AuthenticationOauth2.fs
Original file line number Diff line number Diff line change
Expand Up @@ -6,7 +6,7 @@ open System.IO
open System.Text.Json
open System.Net.Http
open System.Text.Json.Serialization
open Microsoft.Extensions.DependencyInjection
open System.Threading.Tasks
open Pulsar.Client.Api
open Pulsar.Client.Common
open FSharp.UMX
Expand Down Expand Up @@ -50,7 +50,7 @@ type Credentials =
IssuerUrl : string
}

type internal AuthenticationOauth2(issuerUrl: Uri, audience: string, privateKey: Uri, scope: string) =
type internal AuthenticationOauth2(issuerUrl: Uri, audience: string, credentialsUrl: Uri, scope: string) =
inherit Authentication()

let mutable token : Option<TokenResult * TimeStamp> = None
Expand All @@ -74,13 +74,32 @@ type internal AuthenticationOauth2(issuerUrl: Uri, audience: string, privateKey:
return TokenClient(Uri(metadata.TokenEndpoint), httpClient)
}

let openAndDeserializeCreds uri =
let getCredsFromFile (credentialsUrl: Uri) =
backgroundTask {
use fs = new FileStream(uri, FileMode.Open, FileAccess.Read)
let! temp = JsonSerializer.DeserializeAsync<Credentials>(fs)
return temp
use fs = new FileStream(credentialsUrl.LocalPath, FileMode.Open, FileAccess.Read)
return! JsonSerializer.DeserializeAsync<Credentials>(fs)
}

let getCredsFromDataEncodedUri (credentialsUrl: Uri) =
match credentialsUrl.LocalPath.Split(',', 2) with
| [| contentType; data |] when contentType = "application/json;base64" ->
data
|> Convert.FromBase64String
|> JsonSerializer.Deserialize<Credentials>
| [| contentType; _ |] ->
raise <| NotSupportedException $"Content type '{contentType}' is not supported."
| _ ->
raise <| FormatException "The credentials are not in the expected format."

let deserializeCreds (credentialsUrl: Uri) =
match credentialsUrl.Scheme with
| "file" ->
getCredsFromFile credentialsUrl
| "data" ->
getCredsFromDataEncodedUri credentialsUrl |> Task.FromResult
| _ ->
raise <| NotSupportedException($"Scheme '{credentialsUrl.Scheme}' is not supported.")

//https://datatracker.ietf.org/doc/html/rfc6749#section-4.2.2
let tryGetToken() =
token
Expand All @@ -101,7 +120,7 @@ type internal AuthenticationOauth2(issuerUrl: Uri, audience: string, privateKey:
| None ->
let newToken =
(backgroundTask {
let! credentials = openAndDeserializeCreds(privateKey.LocalPath)
let! credentials = deserializeCreds credentialsUrl
let! tokenClient = getTokenClient()
return!
tokenClient.ExchangeClientCredentials(
Expand Down

0 comments on commit ad89cbb

Please sign in to comment.