Skip to content

Commit

Permalink
[OGUI-1581] Split action for taking/releasing all locks in API router (
Browse files Browse the repository at this point in the history
…#2672)

* Adds a pre-route which should be match for lock action `ALL` detector
* Ensures for `ALL` the user has a minimum of Role.GLOBAL
  • Loading branch information
pepijndik authored Dec 3, 2024
1 parent 6de5a60 commit 3438073
Show file tree
Hide file tree
Showing 5 changed files with 126 additions and 1 deletion.
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) => {
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);
});
});

35 changes: 35 additions & 0 deletions Control/test/lib/middleware/mocha-addDetectorId.middleware.test.js
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);
});

});

0 comments on commit 3438073

Please sign in to comment.