Implement operator role for apps

There are two main use cases:
* A consultant/contractor/external developer is given access to just an app.
* A "service" personnel (say upstream app author) is to be given access to single app
for debugging.

Since, this is an "app admin", they are also given access to apps to be consistent with
the idea that Cloudron admin has access to all apps.

part of #791
This commit is contained in:
Girish Ramakrishnan
2021-09-21 10:11:27 -07:00
parent f44fa2cf47
commit bb2ad0e986
7 changed files with 193 additions and 53 deletions
+40 -38
View File
@@ -85,6 +85,7 @@ function initializeExpressSync() {
const token = routes.accesscontrol.tokenAuth;
const authorizeOwner = routes.accesscontrol.authorize(users.ROLE_OWNER);
const authorizeAdmin = routes.accesscontrol.authorize(users.ROLE_ADMIN);
const authorizeOperator = routes.accesscontrol.authorizeOperator;
const authorizeUserManager = routes.accesscontrol.authorize(users.ROLE_USER_MANAGER);
// public routes
@@ -197,44 +198,45 @@ function initializeExpressSync() {
router.get ('/api/v1/appstore/apps/:appstoreId/versions/:versionId', token, authorizeAdmin, routes.appstore.getAppVersion);
// app routes
router.post('/api/v1/apps/install', json, token, authorizeAdmin, routes.apps.install);
router.get ('/api/v1/apps', token, routes.apps.listByUser);
router.get ('/api/v1/apps/:id', token, authorizeAdmin, routes.apps.load, routes.apps.getApp);
router.get ('/api/v1/apps/:id/icon', token, routes.apps.load, routes.apps.getAppIcon);
router.post('/api/v1/apps/:id/uninstall', json, token, authorizeAdmin, routes.apps.load, routes.apps.uninstall);
router.post('/api/v1/apps/:id/configure/access_restriction', json, token, authorizeAdmin, routes.apps.load, routes.apps.setAccessRestriction);
router.post('/api/v1/apps/:id/configure/label', json, token, authorizeAdmin, routes.apps.load, routes.apps.setLabel);
router.post('/api/v1/apps/:id/configure/tags', json, token, authorizeAdmin, routes.apps.load, routes.apps.setTags);
router.post('/api/v1/apps/:id/configure/icon', json, token, authorizeAdmin, routes.apps.load, routes.apps.setIcon);
router.post('/api/v1/apps/:id/configure/memory_limit', json, token, authorizeAdmin, routes.apps.load, routes.apps.setMemoryLimit);
router.post('/api/v1/apps/:id/configure/cpu_shares', json, token, authorizeAdmin, routes.apps.load, routes.apps.setCpuShares);
router.post('/api/v1/apps/:id/configure/automatic_backup', json, token, authorizeAdmin, routes.apps.load, routes.apps.setAutomaticBackup);
router.post('/api/v1/apps/:id/configure/automatic_update', json, token, authorizeAdmin, routes.apps.load, routes.apps.setAutomaticUpdate);
router.post('/api/v1/apps/:id/configure/reverse_proxy', json, token, authorizeAdmin, routes.apps.load, routes.apps.setReverseProxyConfig);
router.post('/api/v1/apps/:id/configure/cert', json, token, authorizeAdmin, routes.apps.load, routes.apps.setCertificate);
router.post('/api/v1/apps/:id/configure/debug_mode', json, token, authorizeAdmin, routes.apps.load, routes.apps.setDebugMode);
router.post('/api/v1/apps/:id/configure/mailbox', json, token, authorizeAdmin, routes.apps.load, routes.apps.setMailbox);
router.post('/api/v1/apps/:id/configure/env', json, token, authorizeAdmin, routes.apps.load, routes.apps.setEnvironment);
router.post('/api/v1/apps/:id/configure/data_dir', json, token, authorizeAdmin, routes.apps.load, routes.apps.setDataDir);
router.post('/api/v1/apps/:id/configure/location', json, token, authorizeAdmin, routes.apps.load, routes.apps.setLocation);
router.post('/api/v1/apps/:id/configure/mounts', json, token, authorizeAdmin, routes.apps.load, routes.apps.setMounts);
router.post('/api/v1/apps/:id/repair', json, token, authorizeAdmin, routes.apps.load, routes.apps.repair);
router.post('/api/v1/apps/:id/update', json, token, authorizeAdmin, routes.apps.load, routes.apps.update);
router.post('/api/v1/apps/:id/restore', json, token, authorizeAdmin, routes.apps.load, routes.apps.restore);
router.post('/api/v1/apps/:id/import', json, token, authorizeAdmin, routes.apps.load, routes.apps.importApp);
router.post('/api/v1/apps/:id/export', json, token, authorizeAdmin, routes.apps.load, routes.apps.exportApp);
router.post('/api/v1/apps/:id/backup', json, token, authorizeAdmin, routes.apps.load, routes.apps.backup);
router.get ('/api/v1/apps/:id/backups', token, authorizeAdmin, routes.apps.load, routes.apps.listBackups);
router.post('/api/v1/apps/:id/start', json, token, authorizeAdmin, routes.apps.load, routes.apps.start);
router.post('/api/v1/apps/:id/stop', json, token, authorizeAdmin, routes.apps.load, routes.apps.stop);
router.post('/api/v1/apps/:id/restart', json, token, authorizeAdmin, routes.apps.load, routes.apps.restart);
router.get ('/api/v1/apps/:id/logstream', token, authorizeAdmin, routes.apps.load, routes.apps.getLogStream);
router.get ('/api/v1/apps/:id/logs', token, authorizeAdmin, routes.apps.load, routes.apps.getLogs);
router.post('/api/v1/apps/:id/clone', json, token, authorizeAdmin, routes.apps.load, routes.apps.clone);
router.get ('/api/v1/apps/:id/download', token, authorizeAdmin, routes.apps.load, routes.apps.downloadFile);
router.post('/api/v1/apps/:id/upload', json, token, authorizeAdmin, multipart, routes.apps.load, routes.apps.uploadFile);
router.use ('/api/v1/apps/:id/files/*', token, authorizeAdmin, routes.filemanager.proxy);
router.get ('/api/v1/apps/:id/exec', token, authorizeAdmin, routes.apps.load, routes.apps.exec);
router.post('/api/v1/apps/install', json, token, authorizeAdmin, routes.apps.install);
router.get ('/api/v1/apps', token, routes.apps.listByUser);
router.get ('/api/v1/apps/:id', token, authorizeAdmin, routes.apps.load, routes.apps.getApp);
router.get ('/api/v1/apps/:id/icon', token, routes.apps.load, routes.apps.getAppIcon);
router.post('/api/v1/apps/:id/uninstall', json, token, authorizeAdmin, routes.apps.load, routes.apps.uninstall);
router.post('/api/v1/apps/:id/configure/access_restriction', json, token, authorizeAdmin, routes.apps.load, routes.apps.setAccessRestriction);
router.post('/api/v1/apps/:id/configure/operators', json, token, authorizeAdmin, routes.apps.load, routes.apps.setOperators);
router.post('/api/v1/apps/:id/configure/label', json, token, routes.apps.load, authorizeOperator, routes.apps.setLabel);
router.post('/api/v1/apps/:id/configure/tags', json, token, routes.apps.load, authorizeOperator, routes.apps.setTags);
router.post('/api/v1/apps/:id/configure/icon', json, token, routes.apps.load, authorizeOperator, routes.apps.setIcon);
router.post('/api/v1/apps/:id/configure/memory_limit', json, token, routes.apps.load, authorizeOperator, routes.apps.setMemoryLimit);
router.post('/api/v1/apps/:id/configure/cpu_shares', json, token, routes.apps.load, authorizeOperator, routes.apps.setCpuShares);
router.post('/api/v1/apps/:id/configure/automatic_backup', json, token, routes.apps.load, authorizeOperator, routes.apps.setAutomaticBackup);
router.post('/api/v1/apps/:id/configure/automatic_update', json, token, routes.apps.load, authorizeOperator, routes.apps.setAutomaticUpdate);
router.post('/api/v1/apps/:id/configure/reverse_proxy', json, token, routes.apps.load, authorizeOperator, routes.apps.setReverseProxyConfig);
router.post('/api/v1/apps/:id/configure/cert', json, token, routes.apps.load, authorizeOperator, routes.apps.setCertificate);
router.post('/api/v1/apps/:id/configure/debug_mode', json, token, routes.apps.load, authorizeOperator, routes.apps.setDebugMode);
router.post('/api/v1/apps/:id/configure/mailbox', json, token, routes.apps.load, authorizeOperator, routes.apps.setMailbox);
router.post('/api/v1/apps/:id/configure/env', json, token, routes.apps.load, authorizeOperator, routes.apps.setEnvironment);
router.post('/api/v1/apps/:id/configure/data_dir', json, token, routes.apps.load, authorizeAdmin, routes.apps.setDataDir);
router.post('/api/v1/apps/:id/configure/location', json, token, routes.apps.load, authorizeAdmin, routes.apps.setLocation);
router.post('/api/v1/apps/:id/configure/mounts', json, token, routes.apps.load, authorizeAdmin, routes.apps.setMounts);
router.post('/api/v1/apps/:id/repair', json, token, routes.apps.load, authorizeOperator, routes.apps.repair);
router.post('/api/v1/apps/:id/update', json, token, routes.apps.load, authorizeOperator, routes.apps.update);
router.post('/api/v1/apps/:id/restore', json, token, routes.apps.load, authorizeOperator, routes.apps.restore);
router.post('/api/v1/apps/:id/import', json, token, routes.apps.load, authorizeOperator, routes.apps.importApp);
router.post('/api/v1/apps/:id/export', json, token, routes.apps.load, authorizeOperator, routes.apps.exportApp);
router.post('/api/v1/apps/:id/backup', json, token, routes.apps.load, authorizeOperator, routes.apps.backup);
router.get ('/api/v1/apps/:id/backups', token, routes.apps.load, authorizeOperator, routes.apps.listBackups);
router.post('/api/v1/apps/:id/start', json, token, routes.apps.load, authorizeOperator, routes.apps.start);
router.post('/api/v1/apps/:id/stop', json, token, routes.apps.load, authorizeOperator, routes.apps.stop);
router.post('/api/v1/apps/:id/restart', json, token, routes.apps.load, authorizeOperator, routes.apps.restart);
router.get ('/api/v1/apps/:id/logstream', token, routes.apps.load, authorizeOperator, routes.apps.getLogStream);
router.get ('/api/v1/apps/:id/logs', token, routes.apps.load, authorizeOperator, routes.apps.getLogs);
router.post('/api/v1/apps/:id/clone', json, token, routes.apps.load, authorizeAdmin, routes.apps.clone);
router.get ('/api/v1/apps/:id/download', token, routes.apps.load, authorizeOperator, routes.apps.downloadFile);
router.post('/api/v1/apps/:id/upload', json, token, multipart, routes.apps.load, authorizeOperator, routes.apps.uploadFile);
router.use ('/api/v1/apps/:id/files/*', token, routes.apps.load, authorizeOperator, routes.filemanager.proxy);
router.get ('/api/v1/apps/:id/exec', token, routes.apps.load, authorizeOperator, routes.apps.exec);
// websocket cannot do bearer authentication
router.get ('/api/v1/apps/:id/execws', routes.accesscontrol.websocketAuth.bind(null, users.ROLE_ADMIN), routes.apps.load, routes.apps.execWebSocket);