Skip to content
New issue

Have a question about this project? Sign up for a free GitHub account to open an issue and contact its maintainers and the community.

By clicking “Sign up for GitHub”, you agree to our terms of service and privacy statement. We’ll occasionally send you account related emails.

Already on GitHub? Sign in to your account

[OGUI-1581] Split action for taking/releasing all locks in API router #2672

9 changes: 9 additions & 0 deletions Control/lib/api.js
Original file line number Diff line number Diff line change
Expand Up @@ -19,6 +19,8 @@ const config = require('./config/configProvider.js');

// middleware
const {minimumRoleMiddleware} = require('./middleware/minimumRole.middleware.js');
const {addDetectorIdMiddleware} = require('./middleware/addDetectorId.middleware.js');
const {DetectorId} = require('./common/detectorId.enum.js');
const {lockOwnershipMiddleware} = require('./middleware/lockOwnership.middleware.js');

// controllers
Expand Down Expand Up @@ -189,6 +191,13 @@ module.exports.setup = (http, ws) => {

// Lock Service
http.get('/locks', lockController.getLocksStateHandler.bind(lockController));

http.put(`/locks/:action/${DetectorId.ALL}`,
minimumRoleMiddleware(Role.GLOBAL),
addDetectorIdMiddleware(DetectorId.ALL),
lockController.actionLockHandler.bind(lockController)
);

http.put('/locks/:action/:detectorId',
minimumRoleMiddleware(Role.DETECTOR),
lockController.actionLockHandler.bind(lockController)
Expand Down
22 changes: 22 additions & 0 deletions Control/lib/common/detectorId.enum.js
Original file line number Diff line number Diff line change
@@ -0,0 +1,22 @@
/**
* @license
* Copyright 2019-2024 CERN and copyright holders of ALICE O2.
* See http://alice-o2.web.cern.ch/copyright for details of the copyright holders.
* All rights not expressly granted are reserved.
*
* This software is distributed under the terms of the GNU General Public
* License v3 (GPL Version 3), copied verbatim in the file "COPYING".
*
* In applying this license CERN does not waive the privileges and immunities
* granted to it by virtue of its status as an Intergovernmental Organization
* or submit itself to any jurisdiction.
*/

/**
* Enum for detector IDs.
*/
const DetectorId = Object.freeze({
ALL: 'ALL',
});

exports.DetectorId = DetectorId;
29 changes: 29 additions & 0 deletions Control/lib/middleware/addDetectorId.middleware.js
Original file line number Diff line number Diff line change
@@ -0,0 +1,29 @@
/**
* @license
* Copyright 2019-2024 CERN and copyright holders of ALICE O2.
* See http://alice-o2.web.cern.ch/copyright for details of the copyright holders.
* All rights not expressly granted are reserved.
*
* This software is distributed under the terms of the GNU General Public
* License v3 (GPL Version 3), copied verbatim in the file "COPYING".
*
* In applying this license CERN does not waive the privileges and immunities
* granted to it by virtue of its status as an Intergovernmental Organization
* or submit itself to any jurisdiction.
*/

/**
* Middleware function to add detectorID to the request object
* @param {Request} req - HTTP Request object
* @param {Next} next - HTTP Next object to use if checks pass
* @param {Response} res - HTTP Response object
* @return {void}
*/
const addDetectorIdMiddleware = (detectorId) => {
return async (req, res, next) => {
pepijndik marked this conversation as resolved.
Show resolved Hide resolved
req.params.detectorId = detectorId;
next();
};
}

exports.addDetectorIdMiddleware = addDetectorIdMiddleware
32 changes: 31 additions & 1 deletion Control/test/api/lock/api-put-locks.test.js
Original file line number Diff line number Diff line change
Expand Up @@ -154,7 +154,7 @@ describe(`'API - PUT - /locks/:action/:detectorId' test suite`, () => {
MID: { name: 'MID', state: 'FREE' },
DCS: { name: 'DCS', state: 'TAKEN', owner: { username: 'global', fullName: 'Global User', personid: 1 } },
ODC: { name: 'ODC', state: 'TAKEN', owner: { username: 'admin', fullName: 'Admin User', personid: 0 } },
});
});

await request(`${TEST_URL}/api/locks`)
.put(`/force/${DetectorLockAction.RELEASE}/ALL?token=${GLOBAL_TEST_TOKEN}`)
Expand All @@ -164,4 +164,34 @@ describe(`'API - PUT - /locks/:action/:detectorId' test suite`, () => {
ODC: { name: 'ODC', state: 'FREE' },
});
});

it('should successfully Take ALL locks when >=global ', async () => {
await request(`${TEST_URL}/api/locks`)
.put(`/${DetectorLockAction.TAKE}/ALL?token=${GLOBAL_TEST_TOKEN}`)
.expect(200, {
DCS: { name: 'DCS', state: 'TAKEN', owner: { username: 'global', fullName: 'Global User', personid: 1 } },
MID: { name: 'MID', state: 'TAKEN', owner: { username: 'global', fullName: 'Global User', personid: 1 } },
ODC: { name: 'ODC', state: 'TAKEN', owner: { username: 'global', fullName: 'Global User', personid: 1 } },
});

await request(`${TEST_URL}/api/locks`)
.put(`/${DetectorLockAction.RELEASE}/ALL?token=${GLOBAL_TEST_TOKEN}`)
.expect(200, {
MID: { name: 'MID', state: 'FREE' },
DCS: { name: 'DCS', state: 'FREE' },
ODC: { name: 'ODC', state: 'FREE' },
});
});

it('should fail taking ALL locks when <=global ', async () => {

await request(`${TEST_URL}/api/locks`)
.put(`/${DetectorLockAction.TAKE}/ALL?token=${GUEST_TEST_TOKEN}`)
.expect(403);

await request(`${TEST_URL}/api/locks`)
.put(`/${DetectorLockAction.RELEASE}/ALL?token=${GUEST_TEST_TOKEN}`)
.expect(403);
});
});

Original file line number Diff line number Diff line change
@@ -0,0 +1,35 @@
const assert = require('assert');
const sinon = require('sinon');

// Import the middleware
const { addDetectorIdMiddleware } = require('../../../lib/middleware/addDetectorId.middleware');

describe('`addDetectorIdMiddleware` test suite', () => {
it('should add the specified detectorId to req.params and call next()', () => {
const detectorId = '1234';
const req = { params: {} }; // Mock req object
const res = {}; // Mock res object
const next = sinon.stub(); // Mock next function

addDetectorIdMiddleware(detectorId)(req, res, next);

// Validate the detectorId is added
assert.strictEqual(req.params.detectorId, detectorId);
// Ensure next() is called
assert.ok(next.calledOnce);
});

it('should overwrite existing detectorId in req.params', () => {
const detectorId = '5678';
const req = { params: { detectorId: 'original' } };
const res = {};
const next = sinon.stub();

addDetectorIdMiddleware(detectorId)(req, res, next);

// Validate the detectorId is overwritten
assert.strictEqual(req.params.detectorId, detectorId);
assert.ok(next.calledOnce);
});

});
Loading