Skip to content

Commit 4499ad0

Browse files
committed
optional LockRequest on DELETE lock
1 parent a986660 commit 4499ad0

File tree

3 files changed

+28
-38
lines changed

3 files changed

+28
-38
lines changed

src/controllers/ControllerV1.ts

Lines changed: 9 additions & 5 deletions
Original file line numberDiff line numberDiff line change
@@ -94,14 +94,18 @@ export class ControllerV1 extends Controller {
9494
@Delete('lock')
9595
public async unlockState(
9696
@Request() request: HttpRequest,
97-
@Body() lockRequest: StateLockRequest,
9897
@Res() res: TsoaResponse<200 | 401 | 403 | 404 | 409, boolean>,
99-
@Query('force') force = false,
98+
@Body() lockRequest?: StateLockRequest,
10099
): Promise<boolean> {
101100
try {
102-
const stateLockRequest = await this.stateService.getRequest(lockRequest.ID);
103-
const identity = await this.githubService.getIdentity(request, stateLockRequest);
104-
await this.stateService.unlockState(identity, stateLockRequest, force);
101+
if (lockRequest && lockRequest.ID) {
102+
const stateLockRequest = await this.stateService.getRequest(lockRequest.ID);
103+
const identity = await this.githubService.getIdentity(request, stateLockRequest);
104+
await this.stateService.unlockState(identity, stateLockRequest);
105+
} else {
106+
const identity = await this.githubService.getIdentity(request);
107+
await this.stateService.unlockState(identity);
108+
}
105109
const response = res(200, true);
106110
return response;
107111
} catch (e) {

src/models/schemas/StateLockRequest.ts

Lines changed: 6 additions & 6 deletions
Original file line numberDiff line numberDiff line change
@@ -7,13 +7,13 @@ export const stateLockRequest = {
77
sk: Joi.string()
88
.regex(/statelock/) // statelock
99
.optional(),
10-
ID: Joi.string().required(),
11-
Operation: Joi.string().required(),
10+
ID: Joi.string().optional(),
11+
Operation: Joi.string().optional(),
1212
Info: Joi.string().allow('').optional(),
13-
Who: Joi.string().required(),
14-
Version: Joi.string().required(),
15-
Created: Joi.string().required(),
16-
Path: Joi.string().allow('').required(),
13+
Who: Joi.string().optional(),
14+
Version: Joi.string().optional(),
15+
Created: Joi.string().optional(),
16+
Path: Joi.string().allow('').optional(),
1717
stateLock: Joi.object({
1818
pk: Joi.string().required(),
1919
sk: Joi.string().required(),

src/services/StateService.ts

Lines changed: 13 additions & 27 deletions
Original file line numberDiff line numberDiff line change
@@ -132,6 +132,11 @@ export class StateService {
132132
throw new TerraformError(409, stateLockRequest);
133133
}
134134

135+
if (!stateLockRequest.ID) {
136+
console.warn(`Missing ID on stateLockRequest`);
137+
throw new TerraformError(400);
138+
}
139+
135140
try {
136141
stateLock = await this.stateLockModel.model.create(
137142
{
@@ -171,43 +176,24 @@ export class StateService {
171176

172177
public unlockState = async (
173178
identity: IdentityWithToken,
174-
stateLockRequest: StateLockRequest,
175-
force: boolean,
179+
stateLockRequest?: StateLockRequest,
176180
): Promise<void> => {
177-
const lockedBy = crypto.createHash('sha256').update(identity.token, 'utf8').digest('base64');
178-
181+
const path = stateLockRequest ? stateLockRequest.Path : '';
179182
const pk = StateLockModel.prefix('pk', identity.ownerId);
180-
const sk = StateLockModel.prefix('sk', `${identity.repoId}_${identity.workspace}`);
181-
const id = stateLockRequest.ID;
183+
const sk = StateLockModel.prefix('sk', `${identity.repoId}_${identity.workspace}_${path}`);
182184

183-
console.log('Releasing state lock');
185+
console.log(`Releasing state lock (pk: ${pk} sk: ${sk})`);
184186

185-
const [stateLocks] = await this.stateLockModel.model
186-
.query(pk)
187-
.where('sk')
188-
.beginsWith(sk)
189-
.filter('id')
190-
.eq(id)
191-
.exec()
192-
.promise();
187+
const stateLock = await this.stateLockModel.model.get(pk, sk);
193188

194-
if (!stateLocks || !stateLocks.Count) {
189+
if (!stateLock) {
195190
console.log(
196-
`No state locks for ${identity.ownerId}/${identity.repoId} on workspace ${identity.workspace} with id ${stateLockRequest.ID}`,
191+
`No state locks for ${identity.ownerId}/${identity.repoId} on workspace ${identity.workspace} with path ${path}`,
197192
);
198193
return;
199194
}
200195

201-
const [stateLock] = stateLocks.Items;
202-
203-
if (stateLock.attrs.lockedBy !== lockedBy && !force) {
204-
console.warn(
205-
`State is locked by ${identity.meta.name} for ${identity.owner}/${identity.repo} on workspace ${identity.workspace}.`,
206-
);
207-
throw new TerraformError(409, stateLockRequest);
208-
}
209-
210-
await this.stateLockModel.model.destroy(stateLock.attrs.pk, stateLock.attrs.sk);
196+
this.stateLockModel.model.destroy(stateLock.attrs.pk, stateLock.attrs.sk);
211197
};
212198

213199
public saveRequest = async (stateLockRequest: StateLockRequest): Promise<StateLockRequest> => {

0 commit comments

Comments
 (0)