123456789101112131415161718192021222324252627282930313233343536373839404142434445464748495051525354555657585960616263646566676869707172737475767778798081828384858687888990919293949596979899100101102103104105106107108109110111112113114115116117118119120121122123124125126127128129(**************************************************************************)(* *)(* Copyright 2018-2023 OCamlPro *)(* *)(* All rights reserved. This file is distributed under the terms of the *)(* GNU Lesser General Public License version 2.1, with the special *)(* exception on linking described in the file LICENSE. *)(* *)(**************************************************************************)moduleTypes=structtypeinfo={idt_iss:string;idt_sub:string;idt_azp:string;idt_aud:string;idt_iat:string;idt_exp:string;}typeprofile={go_addr:string;go_name:string;go_verified:booloption;go_picture:stringoption;go_given_name:stringoption;go_family_name:stringoption;go_locale:stringoption;}typeall={token_info:info;profile_info:profileoption;}endmoduleEncoding=structopenTypesopenJson_encodingletinfo=conv(fun{idt_iss;idt_sub;idt_azp;idt_aud;idt_iat;idt_exp}->(idt_iss,idt_sub,idt_azp,idt_aud,idt_iat,idt_exp))(fun(idt_iss,idt_sub,idt_azp,idt_aud,idt_iat,idt_exp)->{idt_iss;idt_sub;idt_azp;idt_aud;idt_iat;idt_exp})@@obj6(req"iss"string)(req"sub"string)(req"azp"string)(req"aud"string)(req"iat"string)(req"exp"string)letbool_of_string=convstring_of_boolbool_of_stringstringletprofile=conv(fun{go_addr;go_name;go_verified;go_picture;go_given_name;go_family_name;go_locale}->(go_addr,go_name,go_verified,go_picture,go_given_name,go_family_name,go_locale))(fun(go_addr,go_name,go_verified,go_picture,go_given_name,go_family_name,go_locale)->{go_addr;go_name;go_verified;go_picture;go_given_name;go_family_name;go_locale})@@obj7(req"email"string)(req"name"string)(opt"email_verified"bool_of_string)(opt"picture"string)(opt"given_name"string)(opt"family_name"string)(opt"locale"string)letmerge_objs_opte1e2=union[case(merge_objse1e2)(function(x,Somey)->Some(x,y)|_->None)(fun(x,y)->(x,Somey));casee1(function(x,None)->Somex|_->None)(funx->(x,None));]letencoding=EzEncoding.ignore_enc@@conv(fun{token_info;profile_info}->(token_info,profile_info))(fun(token_info,profile_info)->{token_info;profile_info})@@merge_objs_optinfoprofileendmoduleServices=structopenEzAPIletid_token_param=Param.string~descr:"ID token""id_token"letgoogle_auth=BASE"https://www.googleapis.com/"lettoken_info:(Types.all,exn,Security.none)EzAPI.service0=EzAPI.service~register:false~name:"token_info"~params:[id_token_param]~output:Encoding.encodingEzAPI.Path.(root//"oauth2"//"v3"//"tokeninfo")endopenTypesopenServicesopenEzReq_lwtopenLwt.Infixlethandle_errore=Error(handle_error(funexn->Some(Printexc.to_stringexn))e)letcheck_token~client_idid_token=letparams=[id_token_param,EzAPI.Sid_token]inget0~paramsgoogle_authtoken_info>|=function|Errore->handle_errore|Oktoken->iftoken.token_info.idt_aud=client_idthenOktoken.token_info.idt_subelseError(400,Some"this google id_token is not valid for this app")letget_info~client_idid_token=letparams=[id_token_param,EzAPI.Sid_token]inget0~paramsgoogle_authtoken_info>|=function|Errore->handle_errore|Okr->ifr.token_info.idt_aud=client_idthenmatchr.profile_infowith|None->Error(400,Some"email or profile not included in google permission")|Somep->OkpelseError(400,Some"this google id_token is not valid for this app")