/* Ċ Ġ* ĠCopyright Ġ 2 0 0 0 - 2 0 2 0 ĠJetBrains Ġs . r . o . Ċ Ġ* Ċ Ġ* ĠLicensed Ġunder Ġthe ĠApache ĠLicense , ĠVersion Ġ 2 . 0 Ġ( the Ġ" License "); Ċ Ġ* Ġyou Ġmay Ġnot Ġuse Ġthis Ġfile Ġexcept Ġin Ġcompliance Ġwith Ġthe ĠLicense . Ċ Ġ* ĠYou Ġmay Ġobtain Ġa Ġcopy Ġof Ġthe ĠLicense Ġat Ċ Ġ* Ċ Ġ* Ġhttp :// www . apache . org / licenses / LICENSE - 2 . 0 Ċ Ġ* Ċ Ġ* ĠUnless Ġrequired Ġby Ġapplicable Ġlaw Ġor Ġagreed Ġto Ġin Ġwriting , Ġsoftware Ċ Ġ* Ġdistributed Ġunder Ġthe ĠLicense Ġis Ġdistributed Ġon Ġan Ġ" AS ĠIS " ĠBASIS , Ċ Ġ* ĠWITHOUT ĠWARRANTIES ĠOR ĠCONDITIONS ĠOF ĠANY ĠKIND , Ġeither Ġexpress Ġor Ġimplied . Ċ Ġ* ĠSee Ġthe ĠLicense Ġfor Ġthe Ġspecific Ġlanguage Ġgoverning Ġpermissions Ġand Ċ Ġ* Ġlimitations Ġunder Ġthe ĠLicense . Ċ Ġ*/ Ċ package Ġorg . jetbrains . team city . vault . server Ċ Ċ import Ġcom . fasterxml . jackson . databind . node . Object Node Ċ import Ġcom . google . common . util . concurrent . Strip ed Ċ import Ġcom . intellij . openapi . diagnostic . Logger Ċ import Ġcom . intellij . util . containers . Concurrent HashSet Ċ import Ġjet brains . build Server . log . Log gers Ċ import Ġjet brains . build Server . server Side . Build Server Adapter Ċ import Ġjet brains . build Server . server Side . Build Server Listener Ċ import Ġjet brains . build Server . server Side . S Build Ċ import Ġjet brains . build Server . server Side . S Running Build Ċ import Ġjet brains . build Server . util . EventDispatcher Ċ import Ġjet brains . build Server . util . ssl . SSL Trust Store Provider Ċ import Ġorg . jetbrains . team city . vault .* Ċ import Ġorg . jetbrains . team city . vault . support . Vault Responses Ċ import Ġorg . jetbrains . team city . vault . support . Vault Template Ċ import Ġorg . springframework . http . HttpStatus Ċ import Ġorg . springframework . vault . Vault Exception Ċ import Ġorg . springframework . vault . authentication . App Role Authentication Options Ċ import Ġorg . springframework . vault . client . Vault Endpoint Ċ import Ġorg . springframework . vault . support . Vault Response Ċ import Ġorg . springframework . web . client . Default Response ErrorHandler Ċ import Ġorg . springframework . web . client . HttpStatusCode Exception Ċ import Ġorg . springframework . web . client . Rest Template Ċ import Ġjava . net . URI Ċ import Ġjava . util . concurrent . Concurrent HashMap Ċ import Ġjava . util . concurrent . TimeUnit Ċ import Ġkotlin . concurrent . with Lock Ċ Ċ class ĠVault Connector ( dispatcher : ĠEvent Dispatcher < Build Server Listener >, Ġprivate Ġval Ġtrust Store Provider : ĠSSL Trust Store Provider ) Ġ{ ĊĠĠĠ Ġinit Ġ{ ĊĠĠĠĠĠĠĠ Ġdispatcher . addListener ( object Ġ: ĠBuild Server Adapter () Ġ{ ĊĠĠĠĠĠĠĠĠĠĠĠ Ġoverride Ġfun Ġbuild Finished ( build : ĠS Running Build ) Ġ{ ĊĠĠĠĠĠĠĠĠĠĠĠĠĠĠĠ Ġval Ġinfos Ġ= Ġmy Build s Tokens . remove ( build . build Id ) Ġ?: Ġreturn ĊĠĠĠĠĠĠĠĠĠĠĠĠĠĠĠ Ġinfos . values . forEach Ġ{ Ġinfo Ġ-> ĊĠĠĠĠĠĠĠĠĠĠĠĠĠĠĠĠĠĠĠ Ġif Ġ( info Ġ== ĠLe ased Wrapped Token Info . FAILED _ TO _ FETCH ) Ġreturn ĊĠĠĠĠĠĠĠĠĠĠĠĠĠĠĠĠĠĠĠ Ġmy Pending Removal . add ( info ) ĊĠĠĠĠĠĠĠĠĠĠĠĠĠĠĠĠĠĠĠ Ġif Ġ( revoke ( info , Ġtrust Store Provider )) Ġ{ ĊĠĠĠĠĠĠĠĠĠĠĠĠĠĠĠĠĠĠĠĠĠĠĠ Ġmy Pending Removal . remove ( info ) ĊĠĠĠĠĠĠĠĠĠĠĠĠĠĠĠĠĠĠĠ Ġ} ĊĠĠĠĠĠĠĠĠĠĠĠĠĠĠĠ Ġ} ĊĠĠĠĠĠĠĠĠĠĠĠ Ġ} ĊĠĠĠĠĠĠĠ Ġ}) ĊĠĠĠ Ġ} ĊĊĠĠĠ Ġcompanion Ġobject Ġ{ ĊĠĠĠĠĠĠĠ Ġval ĠLOG Ġ= ĠLogger . getInstance ( Log gers . SERVER _ CATEGORY Ġ+ Ġ"." Ġ+ ĠVault Connector :: class . java . name ) !! ĊĊĠĠĠĠĠĠĠ Ġ/** ĊĠĠĠĠĠĠĠĠ Ġ* Ġ@ return Ġtrue Ġif Ġoperation Ġsucceed ĊĠĠĠĠĠĠĠĠ Ġ*/ ĊĠĠĠĠĠĠĠ Ġ@ Jvm Static ĊĠĠĠĠĠĠĠ Ġfun Ġre voke ( info : ĠLe ased Wrapped Token Info , Ġtrust Store Provider : ĠSSL Trust Store Provider , Ġcatch : ĠBoolean Ġ= Ġtrue ): ĠBoolean Ġ{ ĊĠĠĠĠĠĠĠĠĠĠĠ Ġval Ġsettings Ġ= Ġinfo . connection ĊĠĠĠĠĠĠĠĠĠĠĠ Ġtry Ġ{ ĊĠĠĠĠĠĠĠĠĠĠĠĠĠĠĠ Ġval Ġtemplate Ġ= Ġcreate Rest Template ( settings , Ġtrust Store Provider ) ĊĠĠĠĠĠĠĠĠĠĠĠĠĠĠĠ Ġ// ĠLogin Ġand Ġretrieve Ġserver Ġtoken ĊĠĠĠĠĠĠĠĠĠĠĠĠĠĠĠ Ġval Ġ( token , Ġ_) Ġ= Ġget Real Token ( template , Ġsettings ) ĊĊĠĠĠĠĠĠĠĠĠĠĠĠĠĠĠ Ġtemplate . with Vault Token ( token ) ĊĠĠĠĠĠĠĠĠĠĠĠĠĠĠĠ Ġtry Ġ{ ĊĠĠĠĠĠĠĠĠĠĠĠĠĠĠĠĠĠĠĠ Ġ// ĠRe voke Ġagent Ġtoken ĊĠĠĠĠĠĠĠĠĠĠĠĠĠĠĠĠĠĠĠ Ġre voke Accessor ( template , Ġinfo . accessor , Ġinfo . connection . role Id ) ĊĠĠĠĠĠĠĠĠĠĠĠĠĠĠĠ Ġ} Ġfinally Ġ{ ĊĠĠĠĠĠĠĠĠĠĠĠĠĠĠĠĠĠĠĠ Ġ// ĠRe voke Ġserver Ġtoken Ġwe Ġjust Ġobtained ĊĠĠĠĠĠĠĠĠĠĠĠĠĠĠĠĠĠĠĠ Ġre voke Self ( template ) ĊĠĠĠĠĠĠĠĠĠĠĠĠĠĠĠ Ġ} ĊĠĠĠĠĠĠĠĠĠĠĠĠĠĠĠ Ġreturn Ġtrue ĊĠĠĠĠĠĠĠĠĠĠĠ Ġ} Ġcatch ( e : ĠException ) Ġ{ ĊĠĠĠĠĠĠĠĠĠĠĠĠĠĠĠ ĠLOG . warn And Debug Details (" Failed Ġto Ġre voke Ġtoken ", Ġe ) ĊĠĠĠĠĠĠĠĠĠĠĠĠĠĠĠ Ġif Ġ(! catch ) Ġthrow Ġe ĊĠĠĠĠĠĠĠĠĠĠĠ Ġ} ĊĠĠĠĠĠĠĠĠĠĠĠ Ġreturn Ġfalse ĊĠĠĠĠĠĠĠ Ġ} ĊĊĠĠĠĠĠĠĠ Ġ/** ĊĠĠĠĠĠĠĠĠ Ġ* Ġ@ return Ġtrue Ġif Ġoperation Ġsucceed ĊĠĠĠĠĠĠĠĠ Ġ*/ ĊĠĠĠĠĠĠĠ Ġ@ Jvm Static ĊĠĠĠĠĠĠĠ Ġfun Ġre voke ( info : ĠLe ased Token Info , Ġtrust Store Provider : ĠSSL Trust Store Provider ): ĠBoolean Ġ{ ĊĠĠĠĠĠĠĠĠĠĠĠ Ġval Ġsettings Ġ= Ġinfo . connection ĊĠĠĠĠĠĠĠĠĠĠĠ Ġtry Ġ{ ĊĠĠĠĠĠĠĠĠĠĠĠĠĠĠĠ Ġval Ġtemplate Ġ= Ġcreate Rest Template ( settings , Ġtrust Store Provider ) ĊĠĠĠĠĠĠĠĠĠĠĠĠĠĠĠ Ġtemplate . with Vault Token ( info . token ) ĊĠĠĠĠĠĠĠĠĠĠĠĠĠĠĠ Ġ// ĠRe voke Ġtoken ĊĠĠĠĠĠĠĠĠĠĠĠĠĠĠĠ Ġreturn Ġre voke Self ( template ) ĊĠĠĠĠĠĠĠĠĠĠĠ Ġ} Ġcatch Ġ( e : ĠException ) Ġ{ ĊĠĠĠĠĠĠĠĠĠĠĠĠĠĠĠ ĠLOG . warn And Debug Details (" Failed Ġto Ġre voke Ġtoken ", Ġe ) ĊĠĠĠĠĠĠĠĠĠĠĠ Ġ} ĊĠĠĠĠĠĠĠĠĠĠĠ Ġreturn Ġfalse ĊĠĠĠĠĠĠĠ Ġ} ĊĊĠĠĠĠĠĠĠ Ġprivate Ġfun Ġget Real Token ( template : ĠRest Template , Ġsettings : ĠVault Feature Settings ): ĠPair < String , ĠString > Ġ{ ĊĠĠĠĠĠĠĠĠĠĠĠ Ġval Ġoptions Ġ= ĠApp Role Authentication Options . builder () ĊĠĠĠĠĠĠĠĠĠĠĠĠĠĠĠĠĠĠĠ Ġ. path ( settings . get Normalized Endpoint ()) ĊĠĠĠĠĠĠĠĠĠĠĠĠĠĠĠĠĠĠĠ Ġ. role Id ( settings . role Id ) ĊĠĠĠĠĠĠĠĠĠĠĠĠĠĠĠĠĠĠĠ Ġ. secret Id ( settings . secret Id ) ĊĠĠĠĠĠĠĠĠĠĠĠĠĠĠĠĠĠĠĠ Ġ. build () ĊĊĠĠĠĠĠĠĠĠĠĠĠ Ġval Ġlogin Ġ= Ġget App Role Login ( settings ) ĊĠĠĠĠĠĠĠĠĠĠĠ Ġtry Ġ{ ĊĠĠĠĠĠĠĠĠĠĠĠĠĠĠĠ Ġval Ġuri Ġ= Ġtemplate . uri Template Handler . expand (" auth /{ mount }/ login ", Ġoptions . path ) ĊĠĠĠĠĠĠĠĠĠĠĠĠĠĠĠ Ġval Ġresponse Ġ= Ġtemplate . post For Object ( uri , Ġlogin , ĠVault Response :: class . java ) ĊĠĠĠĠĠĠĠĠĠĠĠĠĠĠĠĠĠĠĠĠĠĠĠ Ġ?: Ġthrow ĠVault Exception (" Hash i Cor p ĠVault Ġhasn 't Ġreturned Ġanything Ġfor Ġ'$ uri '") ĊĠĠĠĠĠĠĠĠĠĠĠĠĠĠĠ Ġval Ġauth Ġ= Ġresponse . auth ĊĠĠĠĠĠĠĠĠĠĠĠĠĠĠĠ Ġval Ġtoken Ġ= Ġauth [" client _ token "] Ġas ? ĠString Ġ?: Ġthrow ĠVault Exception (" Hash i Cor p ĠVault Ġhasn 't Ġreturned Ġtoken ") ĊĠĠĠĠĠĠĠĠĠĠĠĠĠĠĠ Ġval Ġaccessor Ġ= Ġauth [" accessor "] Ġas ? ĠString Ġ?: Ġthrow ĠVault Exception (" Hash i Cor p ĠVault Ġhasn 't Ġreturned Ġtoken Ġaccessor ") ĊĠĠĠĠĠĠĠĠĠĠĠĠĠĠĠ Ġreturn Ġtoken Ġto Ġaccessor ĊĠĠĠĠĠĠĠĠĠĠĠ Ġ} Ġcatch Ġ( e : ĠHttpStatusCode Exception ) Ġ{ ĊĠĠĠĠĠĠĠĠĠĠĠĠĠĠĠ Ġthrow Ġget Readable Exception ( e , Ġsettings ) ĊĠĠĠĠĠĠĠĠĠĠĠ Ġ} ĊĠĠĠĠĠĠĠ Ġ} ĊĊĠĠĠĠĠĠĠ Ġ/** ĊĠĠĠĠĠĠĠĠ Ġ* Ġ@ return Ġtrue Ġif Ġoperation Ġsucceed Ġor Ġit Ġdoesn 't Ġmakes Ġsense Ġto Ġtry Ġagain Ġlater ĊĠĠĠĠĠĠĠĠ Ġ*/ ĊĠĠĠĠĠĠĠ Ġprivate Ġfun Ġre voke Accessor ( template : ĠRest Template , Ġaccessor : ĠString , Ġappro le : ĠString ): ĠBoolean Ġ{ ĊĠĠĠĠĠĠĠĠĠĠĠ Ġtemplate . error Handler Ġ= Ġobject Ġ: ĠDefault Response ErrorHandler () Ġ{ ĊĠĠĠĠĠĠĠĠĠĠĠĠĠĠĠ Ġoverride Ġfun ĠhasError ( statusCode : ĠHttpStatus ?): ĠBoolean Ġ{ ĊĠĠĠĠĠĠĠĠĠĠĠĠĠĠĠĠĠĠĠ Ġif Ġ( statusCode Ġ== ĠHttpStatus . FOR BID DEN Ġ|| ĠstatusCode Ġ== ĠHttpStatus . BAD _ REQUEST ) Ġreturn Ġfalse ĊĠĠĠĠĠĠĠĠĠĠĠĠĠĠĠĠĠĠĠ Ġreturn Ġsuper . has Error ( statusCode ) ĊĠĠĠĠĠĠĠĠĠĠĠĠĠĠĠ Ġ} ĊĠĠĠĠĠĠĠĠĠĠĠ Ġ} ĊĠĠĠĠĠĠĠĠĠĠĠ Ġval Ġentity Ġ= Ġtemplate . post For Entity ("/ auth / token / revoke - accessor ", Ġmap Of (" accessor " Ġto Ġaccessor ), ĠObject Node :: class . java ) ĊĠĠĠĠĠĠĠĠĠĠĠ Ġif Ġ( entity . statusCode Ġ== ĠHttpStatus . NO _ CONTENT ) Ġ{ ĊĠĠĠĠĠĠĠĠĠĠĠĠĠĠĠ Ġ// ĠOK ĊĠĠĠĠĠĠĠĠĠĠĠĠĠĠĠ Ġreturn Ġtrue ĊĠĠĠĠĠĠĠĠĠĠĠ Ġ} ĊĠĠĠĠĠĠĠĠĠĠĠ Ġval Ġerror Ġ= ĠVault Responses . getError ( entity . body ) ĊĠĠĠĠĠĠĠĠĠĠĠ Ġval Ġsuffix Ġ= Ġerror ?. replace ('\ n ', Ġ' Ġ') ?. let Ġ{ Ġ". ĠError Ġmessage : Ġ$ it " Ġ} Ġ?: Ġ"" ĊĠĠĠĠĠĠĠĠĠĠĠ Ġif Ġ( entity . statusCode Ġ== ĠHttpStatus . FOR BID DEN ) Ġ{ ĊĠĠĠĠĠĠĠĠĠĠĠĠĠĠĠ ĠLOG . warn (" Failed Ġto Ġre voke Ġtoken Ġvia Ġaccessor Ġ'$ accessor ': Ġaccess Ġdenied , Ġgive Ġappro le Ġ'$ appro le ' Ġ' update ' Ġaccess Ġto Ġ'/ auth / token / revoke - accessor '$ suffix ") ĊĠĠĠĠĠĠĠĠĠĠĠĠĠĠĠ Ġreturn Ġtrue ĊĠĠĠĠĠĠĠĠĠĠĠ Ġ} ĊĠĠĠĠĠĠĠĠĠĠĠ Ġif Ġ( entity . statusCode Ġ== ĠHttpStatus . BAD _ REQUEST ) Ġ{ ĊĠĠĠĠĠĠĠĠĠĠĠĠĠĠĠ Ġval Ġmessage Ġ= Ġ" Failed Ġto Ġre voke Ġtoken Ġvia Ġaccessor Ġ'$ accessor ': Ġserver Ġreturned Ġ 4 0 0 , Ġmost Ġprobably Ġtoken Ġwas Ġalready Ġrev oked $ suffix " ĊĠĠĠĠĠĠĠĠĠĠĠĠĠĠĠ Ġif Ġ( error ?. contains (" invalid Ġaccessor ") Ġ== Ġtrue ) Ġ{ ĊĠĠĠĠĠĠĠĠĠĠĠĠĠĠĠĠĠĠĠ ĠLOG . info ( message ) ĊĠĠĠĠĠĠĠĠĠĠĠĠĠĠĠ Ġ} Ġelse Ġ{ ĊĠĠĠĠĠĠĠĠĠĠĠĠĠĠĠĠĠĠĠ ĠLOG . warn ( message ) ĊĠĠĠĠĠĠĠĠĠĠĠĠĠĠĠ Ġ} ĊĠĠĠĠĠĠĠĠĠĠĠĠĠĠĠ Ġreturn Ġtrue ĊĠĠĠĠĠĠĠĠĠĠĠ Ġ} ĊĠĠĠĠĠĠĠĠĠĠĠ ĠLOG . warn (" Unexpected Ġresponse Ġfrom ĠHash icorp ĠVault Ġduring Ġtoken Ġaccessor Ġrev ocation : Ġ${ entity . statusCode Value }") ĊĠĠĠĠĠĠĠĠĠĠĠ Ġreturn Ġfalse ĊĠĠĠĠĠĠĠ Ġ} ĊĊĠĠĠĠĠĠĠ Ġ/** ĊĠĠĠĠĠĠĠĠ Ġ* Ġ@ return Ġtrue Ġif Ġoperation Ġsucceed ĊĠĠĠĠĠĠĠĠ Ġ*/ ĊĠĠĠĠĠĠĠ Ġprivate Ġfun Ġre voke Self ( template : ĠRest Template ): ĠBoolean Ġ{ ĊĠĠĠĠĠĠĠĠĠĠĠ Ġval Ġback offs Ġ= Ġint ArrayOf ( 1 , Ġ 3 , Ġ 6 , Ġ 0 ) Ġ// Ġlast Ġis Ġnot Ġused ĊĠĠĠĠĠĠĠĠĠĠĠ Ġvar Ġe : ĠException ? Ġ= Ġnull ĊĠĠĠĠĠĠĠĠĠĠĠ Ġfor Ġ( backoff Ġin Ġback offs ) Ġ{ ĊĠĠĠĠĠĠĠĠĠĠĠĠĠĠĠ Ġtry Ġ{ ĊĠĠĠĠĠĠĠĠĠĠĠĠĠĠĠĠĠĠĠ Ġtemplate . post For Object (" auth / token / revoke - self ", Ġnull , ĠObject Node :: class . java ) ĊĠĠĠĠĠĠĠĠĠĠĠĠĠĠĠĠĠĠĠ Ġreturn Ġtrue ĊĠĠĠĠĠĠĠĠĠĠĠĠĠĠĠ Ġ} Ġcatch Ġ( re : ĠRuntimeException ) Ġ{ ĊĠĠĠĠĠĠĠĠĠĠĠĠĠĠĠĠĠĠĠ Ġe Ġ= Ġre ĊĠĠĠĠĠĠĠĠĠĠĠĠĠĠĠĠĠĠĠ Ġtry Ġ{ ĊĠĠĠĠĠĠĠĠĠĠĠĠĠĠĠĠĠĠĠĠĠĠĠ ĠTimeUnit . SECONDS . sleep ( backoff . to Long ()) ĊĠĠĠĠĠĠĠĠĠĠĠĠĠĠĠĠĠĠĠ Ġ} Ġcatch Ġ( ignored : ĠInterruptedException ) Ġ{ ĊĠĠĠĠĠĠĠĠĠĠĠĠĠĠĠĠĠĠĠ Ġ} ĊĠĠĠĠĠĠĠĠĠĠĠĠĠĠĠ Ġ} ĊĠĠĠĠĠĠĠĠĠĠĠ Ġ} ĊĠĠĠĠĠĠĠĠĠĠĠ Ġvar Ġmessage : ĠString ? Ġ= Ġ" Cannot Ġre voke ĠHash i Cor p ĠVault Ġtoken : Ġ" ĊĠĠĠĠĠĠĠĠĠĠĠ Ġif Ġ( e Ġis ĠHttpStatusCode Exception ) Ġ{ ĊĠĠĠĠĠĠĠĠĠĠĠĠĠĠĠ Ġmessage Ġ+= ĠVault Responses . getError (( e Ġas ĠHttpStatusCode Exception ?) !! ) ĊĠĠĠĠĠĠĠĠĠĠĠ Ġ} Ġelse Ġ{ ĊĠĠĠĠĠĠĠĠĠĠĠĠĠĠĠ Ġmessage Ġ+= Ġe ?. message ĊĠĠĠĠĠĠĠĠĠĠĠ Ġ} ĊĠĠĠĠĠĠĠĠĠĠĠ ĠLOG . warn ( message , Ġe ) ĊĠĠĠĠĠĠĠĠĠĠĠ Ġreturn Ġfalse ĊĠĠĠĠĠĠĠ Ġ} ĊĊĠĠĠĠĠĠĠ Ġprivate Ġfun Ġget App Role Login ( settings : ĠVault Feature Settings ): ĠMap < String , ĠString > Ġ{ ĊĠĠĠĠĠĠĠĠĠĠĠ Ġval Ġlogin Ġ= ĠHashMap < String , ĠString >( 2 ) ĊĠĠĠĠĠĠĠĠĠĠĠ Ġlogin [" role _ id "] Ġ= Ġsettings . role Id ĊĠĠĠĠĠĠĠĠĠĠĠ Ġsettings . secret Id . null If Empty ()?. let Ġ{ ĊĠĠĠĠĠĠĠĠĠĠĠĠĠĠĠ Ġlogin [" secret _ id "] Ġ= Ġit ĊĠĠĠĠĠĠĠĠĠĠĠ Ġ} ĊĠĠĠĠĠĠĠĠĠĠĠ Ġreturn Ġlogin ĊĠĠĠĠĠĠĠ Ġ} ĊĊĠĠĠĠĠĠĠ Ġprivate Ġfun Ġget Readable Exception ( cause : ĠHttpStatusCode Exception , Ġsettings : ĠVault Feature Settings ): ĠConnection Exception Ġ{ ĊĠĠĠĠĠĠĠĠĠĠĠ Ġval Ġerr Ġ= ĠVault Responses . getError ( cause ) ĊĠĠĠĠĠĠĠĠĠĠĠ Ġval Ġprefix Ġ= Ġ" Cannot Ġlog Ġin Ġto ĠHash i Cor p ĠVault Ġusing ĠApp Role Ġcredentials " ĊĠĠĠĠĠĠĠĠĠĠĠ Ġval Ġmessage : ĠString ĊĠĠĠĠĠĠĠĠĠĠĠ Ġmessage Ġ= Ġset Of (" failed Ġto Ġvalidate Ġcredentials : Ġ", Ġ" failed Ġto Ġvalidate ĠSecret ID : Ġ") ĊĠĠĠĠĠĠĠĠĠĠĠĠĠĠĠĠĠĠĠ Ġ. find Ġ{ Ġerr . startsWith ( it ) Ġ} ĊĠĠĠĠĠĠĠĠĠĠĠĠĠĠĠĠĠĠĠ Ġ? . let Ġ{ ĊĠĠĠĠĠĠĠĠĠĠĠĠĠĠĠĠĠĠĠĠĠĠĠ Ġval Ġsub error Ġ= Ġerr . remove Prefix ( it ) ĊĠĠĠĠĠĠĠĠĠĠĠĠĠĠĠĠĠĠĠĠĠĠĠ Ġif Ġ( sub error . contains (" invalid Ġsecret _ id ")) Ġ{ ĊĠĠĠĠĠĠĠĠĠĠĠĠĠĠĠĠĠĠĠĠĠĠĠĠĠĠĠ Ġreturn @ let Ġ"$ prefix , ĠSecret ID Ġis Ġincorrect Ġor Ġexpired " ĊĠĠĠĠĠĠĠĠĠĠĠĠĠĠĠĠĠĠĠĠĠĠĠ Ġ} Ġelse Ġif Ġ( sub error . contains (" failed Ġto Ġfind Ġsecondary Ġindex Ġfor Ġrole _ id ")) Ġ{ ĊĠĠĠĠĠĠĠĠĠĠĠĠĠĠĠĠĠĠĠĠĠĠĠĠĠĠĠ Ġreturn @ let Ġ"$ prefix , ĠRole ID Ġis Ġincorrect Ġor Ġthere 's Ġno Ġsuch Ġrole " ĊĠĠĠĠĠĠĠĠĠĠĠĠĠĠĠĠĠĠĠĠĠĠĠ Ġ} ĊĠĠĠĠĠĠĠĠĠĠĠĠĠĠĠĠĠĠĠĠĠĠĠ Ġreturn @ let Ġnull ĊĠĠĠĠĠĠĠĠĠĠĠĠĠĠĠĠĠĠĠ Ġ} Ġ?: Ġ"$ prefix : Ġ$ err " ĊĠĠĠĠĠĠĠĠĠĠĠ Ġreturn ĠConnection Exception ( message . replace ( settings . secret Id , Ġ" ******* "), Ġcause ) ĊĠĠĠĠĠĠĠ Ġ} ĊĊĠĠĠĠĠĠĠ Ġ@ Jvm Static Ġfun Ġdo Request Wrapped Token ( settings : ĠVault Feature Settings , Ġtrust Store Provider : ĠSSL Trust Store Provider ): ĠPair < String , ĠString > Ġ{ ĊĠĠĠĠĠĠĠĠĠĠĠ Ġval Ġoptions Ġ= ĠApp Role Authentication Options . builder () ĊĠĠĠĠĠĠĠĠĠĠĠĠĠĠĠĠĠĠĠ Ġ. path ( settings . get Normalized Endpoint ()) ĊĠĠĠĠĠĠĠĠĠĠĠĠĠĠĠĠĠĠĠ Ġ. role Id ( settings . role Id ) ĊĠĠĠĠĠĠĠĠĠĠĠĠĠĠĠĠĠĠĠ Ġ. secret Id ( settings . secret Id ) ĊĠĠĠĠĠĠĠĠĠĠĠĠĠĠĠĠĠĠĠ Ġ. build () ĊĠĠĠĠĠĠĠĠĠĠĠ Ġval Ġendpoint Ġ= ĠVault Endpoint . from ( URI . create ( settings . url )) !! ĊĠĠĠĠĠĠĠĠĠĠĠ Ġval Ġfactory Ġ= Ġcreate Client HttpRequest Factory ( trust Store Provider ) ĊĊĠĠĠĠĠĠĠĠĠĠĠ Ġval Ġtemplate Ġ= ĠVault Template ( endpoint , Ġsettings . vault Namespace , Ġfactory , ĠDummy Session Manager ()). with Wrapped Responses (" 1 0 m ") ĊĊĠĠĠĠĠĠĠĠĠĠĠ Ġval Ġlogin Ġ= Ġget App Role Login ( settings ) ĊĊĠĠĠĠĠĠĠĠĠĠĠ Ġtry Ġ{ ĊĠĠĠĠĠĠĠĠĠĠĠĠĠĠĠ Ġval Ġpath Ġ= Ġ" auth /${ options . path }/ login " ĊĠĠĠĠĠĠĠĠĠĠĠĠĠĠĠ Ġval Ġvault Response Ġ= Ġtemplate . write ( path , Ġlogin ) ĊĠĠĠĠĠĠĠĠĠĠĠĠĠĠĠĠĠĠĠĠĠĠĠ Ġ?: Ġthrow ĠVault Exception (" Hash i Cor p ĠVault Ġhasn 't Ġreturned Ġanything Ġfrom ĠPOST Ġto Ġ'$ path '") ĊĊĠĠĠĠĠĠĠĠĠĠĠĠĠĠĠ Ġval Ġwrap Ġ= Ġvault Response . wrap Info Ġ?: Ġthrow ĠVault Exception (" Hash i Cor p ĠVault Ġhasn 't Ġreturned Ġ' wrap _ info ' Ġfor ĠPOST Ġto Ġ'$ path '") ĊĊĠĠĠĠĠĠĠĠĠĠĠĠĠĠĠ Ġval Ġtoken Ġ= Ġwrap [" token "] Ġ?: Ġthrow ĠVault Exception (" Hash i Cor p ĠVault Ġhasn 't Ġreturned Ġwrapped Ġtoken ") ĊĠĠĠĠĠĠĠĠĠĠĠĠĠĠĠ Ġval Ġaccessor Ġ= Ġwrap [" wrapped _ accessor "] Ġ?: Ġthrow ĠVault Exception (" Hash i Cor p ĠVault Ġhasn 't Ġreturned Ġwrapped Ġtoken Ġaccessor ") ĊĊĠĠĠĠĠĠĠĠĠĠĠĠĠĠĠ Ġreturn Ġtoken Ġto Ġaccessor ĊĠĠĠĠĠĠĠĠĠĠĠ Ġ} Ġcatch Ġ( e : ĠVault Exception ) Ġ{ ĊĠĠĠĠĠĠĠĠĠĠĠĠĠĠĠ Ġval Ġcause Ġ= Ġe . cause ĊĠĠĠĠĠĠĠĠĠĠĠĠĠĠĠ Ġif Ġ( cause Ġis ĠHttpStatusCode Exception ) Ġ{ ĊĠĠĠĠĠĠĠĠĠĠĠĠĠĠĠĠĠĠĠ Ġthrow Ġget Readable Exception ( cause , Ġsettings ) ĊĠĠĠĠĠĠĠĠĠĠĠĠĠĠĠ Ġ} ĊĠĠĠĠĠĠĠĠĠĠĠĠĠĠĠ Ġthrow Ġe ĊĠĠĠĠĠĠĠĠĠĠĠ Ġ} ĊĠĠĠĠĠĠĠ Ġ} ĊĊĠĠĠĠĠĠĠ Ġ@ Jvm Static ĊĠĠĠĠĠĠĠ Ġfun Ġdo Request Token ( settings : ĠVault Feature Settings , Ġtrust Store Provider : ĠSSL Trust Store Provider ): ĠPair < String , ĠString > Ġ{ ĊĠĠĠĠĠĠĠĠĠĠĠ Ġval Ġoptions Ġ= ĠApp Role Authentication Options . builder () ĊĠĠĠĠĠĠĠĠĠĠĠĠĠĠĠĠĠĠĠ Ġ. path ( settings . get Normalized Endpoint ()) ĊĠĠĠĠĠĠĠĠĠĠĠĠĠĠĠĠĠĠĠ Ġ. role Id ( settings . role Id ) ĊĠĠĠĠĠĠĠĠĠĠĠĠĠĠĠĠĠĠĠ Ġ. secret Id ( settings . secret Id ) ĊĠĠĠĠĠĠĠĠĠĠĠĠĠĠĠĠĠĠĠ Ġ. build () ĊĠĠĠĠĠĠĠĠĠĠĠ Ġval Ġendpoint Ġ= ĠVault Endpoint . from ( URI . create ( settings . url )) !! ĊĠĠĠĠĠĠĠĠĠĠĠ Ġval Ġfactory Ġ= Ġcreate Client HttpRequest Factory ( trust Store Provider ) ĊĊĠĠĠĠĠĠĠĠĠĠĠ Ġval Ġtemplate Ġ= ĠVault Template ( endpoint , Ġsettings . vault Namespace , Ġfactory , ĠDummy Session Manager ()) ĊĊĠĠĠĠĠĠĠĠĠĠĠ Ġval Ġlogin Ġ= Ġget App Role Login ( settings ) ĊĊĠĠĠĠĠĠĠĠĠĠĠ Ġtry Ġ{ ĊĠĠĠĠĠĠĠĠĠĠĠĠĠĠĠ Ġval Ġvault Response Ġ= Ġtemplate . write (" auth /${ options . path }/ login ", Ġlogin ) ĊĠĠĠĠĠĠĠĠĠĠĠĠĠĠĠ Ġval Ġauth Ġ= Ġvault Response . auth ĊĊĠĠĠĠĠĠĠĠĠĠĠĠĠĠĠ Ġval Ġtoken Ġ= Ġauth [" client _ token "] Ġas ? ĠString Ġ?: Ġthrow ĠVault Exception (" Hash i Cor p ĠVault Ġhasn 't Ġreturned Ġtoken ") ĊĠĠĠĠĠĠĠĠĠĠĠĠĠĠĠ Ġval Ġaccessor Ġ= Ġauth [" accessor "] Ġas ? ĠString Ġ?: Ġthrow ĠVault Exception (" Hash i Cor p ĠVault Ġhasn 't Ġreturned Ġtoken Ġaccessor ") ĊĠĠĠĠĠĠĠĠĠĠĠĠĠĠĠ Ġreturn Ġtoken Ġto Ġaccessor ĊĠĠĠĠĠĠĠĠĠĠĠ Ġ} Ġcatch Ġ( e : ĠVault Exception ) Ġ{ ĊĠĠĠĠĠĠĠĠĠĠĠĠĠĠĠ Ġval Ġcause Ġ= Ġe . cause ĊĠĠĠĠĠĠĠĠĠĠĠĠĠĠĠ Ġif Ġ( cause Ġis ĠHttpStatusCode Exception ) Ġ{ ĊĠĠĠĠĠĠĠĠĠĠĠĠĠĠĠĠĠĠĠ Ġthrow Ġget Readable Exception ( cause , Ġsettings ) ĊĠĠĠĠĠĠĠĠĠĠĠĠĠĠĠ Ġ} ĊĠĠĠĠĠĠĠĠĠĠĠĠĠĠĠ Ġthrow Ġe ĊĠĠĠĠĠĠĠĠĠĠĠ Ġ} ĊĠĠĠĠĠĠĠ Ġ} ĊĠĠĠ Ġ} ĊĊĠĠĠ Ġ// ĠTODO : ĠSupport Ġserver Ġrestart ĊĠĠĠ Ġprivate Ġval Ġmy Build s Tokens : ĠMutable Map < Long , ĠMutable Map < String , Le ased Wrapped Token Info >> Ġ= ĠConcurrent HashMap () ĊĠĠĠ Ġprivate Ġval Ġmy Pending Removal : ĠMutable Set < Le ased Wrapped Token Info > Ġ= ĠConcurrent HashSet () ĊĠĠĠ Ġprivate Ġval Ġmy Locks Ġ= ĠStrip ed . lazy Weak Lock ( 6 4 ) ĊĊĠĠĠ Ġfun Ġrequest Wrapped Token ( build : ĠS Build , Ġsettings : ĠVault Feature Settings ): ĠString Ġ{ ĊĠĠĠĠĠĠĠ Ġval Ġinfos Ġ= Ġmy Build s Tokens . get OrDefault ( build . build Id , Concurrent HashMap ()) ĊĠĠĠĠĠĠĠ Ġval Ġinfo Ġ= Ġinfos [ settings . namespace ] ĊĠĠĠĠĠĠĠ Ġif ( info Ġ!= Ġnull ) Ġreturn Ġinfo . wrapped ĊĊĠĠĠĠĠĠĠ Ġmy Locks . get ( build . build Id ). with Lock Ġ{ ĊĠĠĠĠĠĠĠĠĠĠĠ Ġ@ Suppress (" NAME _ SH ADO WING ") ĊĠĠĠĠĠĠĠĠĠĠĠ Ġval Ġinfos Ġ= Ġmy Build s Tokens . get OrDefault ( build . build Id , Concurrent HashMap ()) ĊĠĠĠĠĠĠĠĠĠĠĠ Ġ@ Suppress (" NAME _ SH ADO WING ") ĊĠĠĠĠĠĠĠĠĠĠĠ Ġval Ġinfo Ġ= Ġinfos [ settings . namespace ] ĊĠĠĠĠĠĠĠĠĠĠĠ Ġif ( info Ġ!= Ġnull ) Ġreturn Ġinfo . wrapped ĊĠĠĠĠĠĠĠĠĠĠĠ Ġtry Ġ{ ĊĠĠĠĠĠĠĠĠĠĠĠĠĠĠĠ Ġval Ġ( token , Ġaccessor ) Ġ= Ġdo Request Wrapped Token ( settings , Ġtrust Store Provider ) ĊĠĠĠĠĠĠĠĠĠĠĠĠĠĠĠ Ġinfos [ settings . namespace ] Ġ= ĠLe ased Wrapped Token Info ( token , Ġaccessor , Ġsettings ); ĊĠĠĠĠĠĠĠĠĠĠĠĠĠĠĠ Ġmy Build s Tokens [ build . build Id ] Ġ= Ġinfos ; ĊĠĠĠĠĠĠĠĠĠĠĠĠĠĠĠ Ġreturn Ġtoken ĊĠĠĠĠĠĠĠĠĠĠĠ Ġ} Ġcatch Ġ( e : ĠException ) Ġ{ ĊĠĠĠĠĠĠĠĠĠĠĠĠĠĠĠ Ġinfos [ settings . namespace ] Ġ= ĠLe ased Wrapped Token Info . FAILED _ TO _ FETCH ĊĠĠĠĠĠĠĠĠĠĠĠĠĠĠĠ Ġmy Build s Tokens [ build . build Id ] Ġ= Ġinfos ; ĊĠĠĠĠĠĠĠĠĠĠĠĠĠĠĠ Ġthrow Ġe ĊĠĠĠĠĠĠĠĠĠĠĠ Ġ} ĊĠĠĠĠĠĠĠ Ġ} ĊĠĠĠ Ġ} ĊĊĠĠĠ Ġfun Ġtry Request Token ( settings : ĠVault Feature Settings ): ĠLe ased Token Info Ġ{ ĊĠĠĠĠĠĠĠ Ġval Ġ( token , Ġaccessor ) Ġ= Ġdo Request Token ( settings , Ġtrust Store Provider ) ĊĠĠĠĠĠĠĠ Ġreturn ĠLe ased Token Info ( token , Ġaccessor , Ġsettings ) ĊĠĠĠ Ġ} ĊĊĠĠĠ Ġclass ĠConnection Exception ( message : ĠString , Ġcause : ĠThrowable ) Ġ: ĠException ( message , Ġcause ) Ċ } Ċ Ċ data Ġclass ĠLe ased Wrapped Token Info ( val Ġwrapped : ĠString , Ġval Ġaccessor : ĠString , Ġval Ġconnection : ĠVault Feature Settings ) Ġ{ ĊĠĠĠ Ġcompanion Ġobject Ġ{ ĊĠĠĠĠĠĠĠ Ġval ĠFAILED _ TO _ FETCH Ġ= ĠLe ased Wrapped Token Info ( Vault Constants . SPECIAL _ FAILED _ TO _ FETCH , Ġ"", ĠVault Feature Settings ( map Of ())) ĊĠĠĠ Ġ} Ċ } Ċ Ċ data Ġclass ĠLe ased Token Info ( val Ġtoken : ĠString , Ġval Ġaccessor : ĠString , Ġval Ġconnection : ĠVault Feature Settings ) Ċ