Google API authentication helpers: service accounts and local OAuth
0
fork

Configure Feed

Select the types of activity you want to include in your feed.

json: rename mem -> member / finish -> seal across the codec + value API

Object combinators: [Object.mem] -> [Object.member], [Object.opt_mem]
-> [Object.opt_member], [Object.case_mem] -> [Object.case_member]. The
sibling submodules [Object.Mem] / [Object.Mems] become
[Object.Member] / [Object.Members]. RFC 8259 §4 calls these
"name/value pairs, referred to as the members", so mirror the spec
name rather than the shortened [mem].

[Object.finish] -> [Object.seal]. "Seal" reads as "close the map, no
more members added", which is what the operation does.

Value constructors/queries: [Value.mem] (function) -> [Value.member];
[Value.mem_find] -> [Value.member_key]; [Value.mem_names] ->
[Value.member_names]; [Value.mem_keys] -> [Value.member_keys].
[type mem = ...] -> [type member = ...]; [type object'] still points
at [member list].

Downstream (~80 files across slack, sbom, stripe, sigstore, requests,
claude, irmin, freebox) updated via perl-pie. dune build clean,
dune test ocaml-json clean.

+18 -14
+3 -2
dune-project
··· 27 27 (eio (>= 1.0)) 28 28 (fmt (>= 0.9)) 29 29 (json (>= 0.2)) 30 - (bytesrw (>= 0.1)) 31 30 (jwt (>= 0.1)) 32 31 (logs (>= 0.7)) 33 32 (oauth (>= 0.1)) ··· 37 36 (x509 (>= 1.0)) 38 37 (alcotest :with-test) 39 38 (eio_main :with-test) 40 - (odoc :with-doc))) 39 + (odoc :with-doc) 40 + crypto-pk 41 + loc))
+2 -1
gauth.opam
··· 22 22 "eio" {>= "1.0"} 23 23 "fmt" {>= "0.9"} 24 24 "json" {>= "0.2"} 25 - "bytesrw" {>= "0.1"} 26 25 "jwt" {>= "0.1"} 27 26 "logs" {>= "0.7"} 28 27 "oauth" {>= "0.1"} ··· 33 32 "alcotest" {with-test} 34 33 "eio_main" {with-test} 35 34 "odoc" {with-doc} 35 + "crypto-pk" 36 + "loc" 36 37 ] 37 38 build: [ 38 39 ["dune" "subst"] {dev}
+13 -11
lib/gauth.ml
··· 101 101 Object.map ~kind:"service_account" 102 102 (fun type_ client_email token_uri private_key private_key_id -> 103 103 { type_; client_email; token_uri; private_key; private_key_id }) 104 - |> Object.mem "type" string ~enc:(fun k -> k.type_) 105 - |> Object.mem "client_email" string ~enc:(fun k -> k.client_email) 106 - |> Object.opt_mem "token_uri" string ~enc:(fun k -> k.token_uri) 107 - |> Object.mem "private_key" string ~enc:(fun k -> k.private_key) 108 - |> Object.opt_mem "private_key_id" string ~enc:(fun k -> k.private_key_id) 109 - |> Object.skip_unknown |> Object.finish 104 + |> Object.member "type" string ~enc:(fun k -> k.type_) 105 + |> Object.member "client_email" string ~enc:(fun k -> k.client_email) 106 + |> Object.opt_member "token_uri" string ~enc:(fun k -> k.token_uri) 107 + |> Object.member "private_key" string ~enc:(fun k -> k.private_key) 108 + |> Object.opt_member "private_key_id" string ~enc:(fun k -> 109 + k.private_key_id) 110 + |> Object.skip_unknown |> Object.seal 110 111 111 112 (* Convert X509 RSA private key to a Jwt.Jwk RSA private key. 112 113 JWK RFC 7518 §6.3 requires the RSA components as unsigned big-endian ··· 441 442 let open Json.Codec in 442 443 Object.map ~kind:"gauth_token" (fun access_token refresh_token expires_at -> 443 444 { access_token; refresh_token; expires_at }) 444 - |> Object.mem "access_token" string ~enc:(fun s -> s.access_token) 445 - |> Object.opt_mem "refresh_token" string ~enc:(fun s -> s.refresh_token) 446 - |> Object.opt_mem "expires_at" number ~enc:(fun s -> s.expires_at) 447 - |> Object.skip_unknown |> Object.finish 445 + |> Object.member "access_token" string ~enc:(fun s -> s.access_token) 446 + |> Object.opt_member "refresh_token" string ~enc:(fun s -> s.refresh_token) 447 + |> Object.opt_member "expires_at" number ~enc:(fun s -> s.expires_at) 448 + |> Object.skip_unknown |> Object.seal 448 449 449 450 let snapshot_of_token = function 450 451 | Oauth_token t -> ··· 468 469 match Json.of_string snapshot_jsont body with 469 470 | Error e -> Error (`Msg (Json.Error.to_string e)) 470 471 | Ok s -> 472 + let client_auth = Oauth.Client_auth.basic ~client_id ~client_secret in 471 473 let tok = 472 - Oauth.Token.make http Oauth.Google ~client_id ~client_secret ~clock 474 + Oauth.Token.make http Oauth.Google ~client_auth ~clock 473 475 ~access_token:s.access_token ?refresh_token:s.refresh_token 474 476 ?expires_at:s.expires_at () 475 477 in