@@ -4,6 +4,7 @@ import { TerraformError } from '../interfaces/errors';
44import { Identity } from '../models/interfaces' ;
55import crypto from 'crypto' ;
66import { IdentityModel } from '../models/IdentityModel' ;
7+ import { StateLockRequest } from '../models/interfaces/StateLockRequest' ;
78// import seedrandom from 'seedrandom';
89
910export type IdentityWithToken = Identity & {
@@ -25,7 +26,10 @@ export class GithubService {
2526 this . identityModel = new IdentityModel ( ) ;
2627 }
2728
28- public getIdentity = async ( request : HttpRequest ) : Promise < IdentityWithToken > => {
29+ public getIdentity = async (
30+ request : HttpRequest ,
31+ stateLockRequest ?: StateLockRequest ,
32+ ) : Promise < IdentityWithToken > => {
2933 const { authorization } = request . headers ;
3034 if ( ! authorization ) {
3135 throw new TerraformError ( 401 ) ;
@@ -46,11 +50,6 @@ export class GithubService {
4650
4751 const [ username , password ] = decoded . split ( ':' ) ;
4852
49- // Unauthenticated state storage for localstack
50- if ( username === 'localstack' && password === 'localstack' ) {
51- return this . inferLocalstackIdentity ( ) ;
52- }
53-
5453 let owner : string | undefined ;
5554 let repo : string | undefined ;
5655 let workspace : string | undefined ;
@@ -80,7 +79,7 @@ export class GithubService {
8079 }
8180
8281 try {
83- const identity = await this . inferIdentity ( password , owner , repo , workspace ) ;
82+ const identity = await this . inferIdentity ( password , owner , repo , workspace , stateLockRequest ) ;
8483
8584 console . log (
8685 `Using identity: ${ identity . owner } /${ identity . repo } [${ identity . ownerId } /${ identity . repoId } ]` ,
@@ -101,24 +100,31 @@ export class GithubService {
101100 owner ?: string ,
102101 repo ?: string ,
103102 workspace ?: string ,
103+ stateLockRequest ?: StateLockRequest ,
104104 ) : Promise < Identity > => {
105105 const tokenSha = crypto . createHash ( 'sha256' ) . update ( auth ) . digest ( ) . toString ( 'base64' ) ;
106106
107107 console . log (
108- `Inferring identity (auth: ${ auth } sha: ${ tokenSha } owner: ${ owner } , repo: ${ repo } , workspace: ${ workspace } )` ,
108+ `Inferring identity (auth: ${ auth } sha: ${ tokenSha } owner: ${ owner } , repo: ${ repo } , workspace: ${ workspace } , stateLockRequest; ${ stateLockRequest } )` ,
109109 ) ;
110110
111- // TODO Expire stored identities
112- const storedIdentity = await this . identityModel . model . get (
113- IdentityModel . prefix ( 'pk' , tokenSha ) ,
114- IdentityModel . prefix ( 'sk' ) ,
115- ) ;
111+ let storedIdentity : Identity | undefined ;
112+
113+ if ( stateLockRequest && stateLockRequest . identity ) {
114+ const { pk, sk } = stateLockRequest . identity ;
116115
117- if ( storedIdentity ) {
118- // Terraform planfiles contain backend configurations from plan operations
119- // Return the previously known identy from the plan operation
116+ const identity = await this . identityModel . model . get ( pk , sk ) ;
117+
118+ if ( identity ) {
119+ storedIdentity = identity . attrs ;
120+ }
121+ }
122+
123+ if ( storedIdentity && stateLockRequest && stateLockRequest . Operation === 'OperationTypeApply' ) {
124+ // Terraform planfiles contain credentials from plan operations
125+ // Return the previously known identity from the plan operation
120126 console . log ( `Found previously known identity (sha: ${ tokenSha } )` ) ;
121- return { ...storedIdentity . attrs , workspace : workspace || 'default' } ;
127+ return { ...storedIdentity , workspace : workspace || 'default' } ;
122128 }
123129
124130 const octokit = new Octokit ( { auth } ) ;
@@ -212,33 +218,4 @@ export class GithubService {
212218 `Unable to determine owner and/or repository from token privileges. Ensure \`username\` is in the format of \`{owner}/{repository}\`, and the provided \`password\` (a GitHub token) has access to that repository.` ,
213219 ) ;
214220 } ;
215-
216- // TODO: support 'who' from State Lock Request
217- private inferLocalstackIdentity = ( who = 'unknown@unknown' ) : IdentityWithToken => {
218- const tokenSha = crypto . createHash ( 'sha256' ) . update ( who ) . digest ( ) . toString ( 'base64' ) ;
219-
220- const [ username , host ] = who . split ( '@' ) ;
221- if ( ! username || ! host ) {
222- throw new Error ( `Invalid format for \`Who\` on state lock request` ) ;
223- }
224-
225- // Set IDs as negative so they're clearly out of valid range
226- // const ownerId = seedrandom(host).int32() * -1;
227- // const repoId = seedrandom(username).int32() * -1;
228-
229- return {
230- pk : IdentityModel . prefix ( 'pk' , tokenSha ) ,
231- sk : IdentityModel . prefix ( 'sk' ) ,
232- owner : host ,
233- ownerId : - 1 ,
234- repo : username ,
235- repoId : - 1 ,
236- token : who ,
237- tokenSha : tokenSha ,
238- workspace : 'default' ,
239- meta : {
240- name : 'localstack' ,
241- } ,
242- } ;
243- } ;
244221}
0 commit comments