openvibers/openvibe.services Commits

Services: Space sites, deploys and domains can be deleted from the console (contracts 0.170) (#59)

OP OpenVibers committed 30 days ago · c5c8f6b63b · 4 files, +12 −8

Plan T13 step 10 (contracts 0.170.0, Space PR, Network#188): Space takes control requests too.

- The console offers **Delete…** on Space sites, deploys and domains. Deleted sites and deploys offer nothing.
- Any admin of the project may ask. Space decides by its own roles (maintainer or owner) and refuses the deploy being served and a default domain with its own reason.
- Contracts are pinned to v0.170.0. `control.test.js` expects five authorities that take control.

Changes

ddiff --git a/package-lock.json b/package-lock.json
iindex 328ce48..3b165e5 100644
---- a/package-lock.json
++++ b/package-lock.json
@@@ -16,7 +16,7 @@
"express-rate-limit": "^7.5.0",
"helmet": "^8.1.0",
"iovalkey": "^0.4.0",
-- "openvibe-contracts": "https://codeload.github.com/OpenVibers/OpenVibe.Contracts/tar.gz/refs/tags/v0.169.0",
++ "openvibe-contracts": "https://codeload.github.com/OpenVibers/OpenVibe.Contracts/tar.gz/refs/tags/v0.170.0",
"openvibe-sdk": "https://codeload.github.com/OpenVibers/OpenVibe.SDK/tar.gz/refs/tags/v0.44.0",
"openvibe-shared": "https://codeload.github.com/OpenVibers/OpenVibe.Shared/tar.gz/refs/tags/v4.1.3",
"pg": "^8.23.0"
@@@ -890,9 +890,9 @@
}
},
"node_modules/openvibe-contracts": {
-- "version": "0.169.0",
-- "resolved": "https://codeload.github.com/OpenVibers/OpenVibe.Contracts/tar.gz/refs/tags/v0.169.0",
-- "integrity": "sha512-Py2z8UaKGvLzG3atuIAnJKnRe74Te9cJRTaxqFq6m4fov6gaMXeS6rn7lH0tSIo0qBGD5trrT618ARXnklkp+A==",
++ "version": "0.170.0",
++ "resolved": "https://codeload.github.com/OpenVibers/OpenVibe.Contracts/tar.gz/refs/tags/v0.170.0",
++ "integrity": "sha512-EpOUiqFSYBZ1p7aQTek1IYyHcbD9QT0pdr492+teWvZf425xXSMu7+DQsnzgMP8JdTmdS2VMxoirrBwMUGxjrw==",
"license": "AGPL-3.0-only",
"dependencies": {
"ajv": "^8.17.1",
ddiff --git a/package.json b/package.json
iindex 9feedd8..4aa3426 100644
---- a/package.json
++++ b/package.json
@@@ -27,7 +27,7 @@
"express-rate-limit": "^7.5.0",
"helmet": "^8.1.0",
"iovalkey": "^0.4.0",
-- "openvibe-contracts": "https://codeload.github.com/OpenVibers/OpenVibe.Contracts/tar.gz/refs/tags/v0.169.0",
++ "openvibe-contracts": "https://codeload.github.com/OpenVibers/OpenVibe.Contracts/tar.gz/refs/tags/v0.170.0",
"openvibe-sdk": "https://codeload.github.com/OpenVibers/OpenVibe.SDK/tar.gz/refs/tags/v0.44.0",
"openvibe-shared": "https://codeload.github.com/OpenVibers/OpenVibe.Shared/tar.gz/refs/tags/v4.1.3",
"pg": "^8.23.0"
ddiff --git a/server/http/portal.js b/server/http/portal.js
iindex b10ce48..1527137 100644
---- a/server/http/portal.js
++++ b/server/http/portal.js
@@@ -40,13 +40,17 @@ const { ServiceError } = require('../util');
// What the console offers on a resource (ADR-048 control), by kind. The owning service decides; a button it does not
// take would only be refused. `admins`: the service lets a project's admins act on what its apps made, not only the
--// resource's own person (Actor and Media, contracts 0.169.0).
++// resource's own person (Actor and Media, contracts 0.169.0; Space, 0.170.0).
const OPEN_TASK = new Set(['queued', 'running', 'verifying']);
const KIND_ACTIONS = {
'watch.watch': { actions: (x) => [x.state === 'paused' ? ['resume', 'Resume'] : ['suspend', 'Suspend'], ['delete', 'Delete…']] },
'events.subscription': { actions: (x) => [x.state === 'disabled' ? ['resume', 'Resume'] : ['suspend', 'Suspend']] },
'actor.task': { admins: true, actions: (x) => (OPEN_TASK.has(x.state) ? [['stop', 'Stop']] : []) },
'media.object': { admins: true, actions: (x) => (x.state === 'deleted' ? [] : [['delete', 'Delete…']]) },
++ // Space decides by its own project roles (maintainer or owner), so any admin here may ask (contracts 0.170.0).
++ 'space.site': { admins: true, actions: (x) => (x.state === 'deleted' ? [] : [['delete', 'Delete…']]) },
++ 'space.deploy': { admins: true, actions: (x) => (x.state === 'deleted' ? [] : [['delete', 'Delete…']]) },
++ 'space.domain': { admins: true, actions: () => [['delete', 'Delete…']] },
default: { actions: (x) => [x.state === 'paused' ? ['resume', 'Resume'] : ['suspend', 'Suspend'], ['delete', 'Delete…']] },
};
ddiff --git a/test/control.test.js b/test/control.test.js
iindex 425d414..9931a10 100644
---- a/test/control.test.js
++++ b/test/control.test.js
@@@ -88,10 +88,10 @@ function registryOf(list) {
const prj = ids.newId('project');
const object = resources.format({ service: 'media', project_id: prj, type: 'object', id: ids.newId('media') });
-- await check('only an authority with an active <id>.resource.control takes control requests (Watch 0.165, Events 0.168, Actor and Media 0.169)', async () => {
++ await check('only an authority with an active <id>.resource.control takes control requests (Watch 0.165, Events 0.168, Actor and Media 0.169, Space 0.170)', async () => {
const real = createAuthorities(t.config, { log: { warn() {} } });
assert.ok(real.size() > 0);
-- const TAKES = { watch: 'watch.resource.control', events: 'events.resource.control', actor: 'actor.resource.control', media: 'media.resource.control' };
++ const TAKES = { watch: 'watch.resource.control', events: 'events.resource.control', actor: 'actor.resource.control', media: 'media.resource.control', space: 'space.resource.control' };
for (const a of real.list()) assert.strictEqual(a.control, TAKES[a.id] || null, `${a.id}: the control capability in the pinned contracts`);
});