mirror of
https://github.com/HeyPuter/puter.git
synced 2025-01-23 22:40:20 +08:00
feat: add feature flag for /share
This commit is contained in:
parent
d4319ea072
commit
461ea3eae6
@ -314,6 +314,9 @@ const install = async ({ services, app, useapi }) => {
|
|||||||
|
|
||||||
const { BootScriptService } = require('./services/BootScriptService');
|
const { BootScriptService } = require('./services/BootScriptService');
|
||||||
services.registerService('boot-script', BootScriptService);
|
services.registerService('boot-script', BootScriptService);
|
||||||
|
|
||||||
|
const { FeatureFlagService } = require('./services/FeatureFlagService');
|
||||||
|
services.registerService('feature-flag', FeatureFlagService);
|
||||||
}
|
}
|
||||||
|
|
||||||
const install_legacy = async ({ services }) => {
|
const install_legacy = async ({ services }) => {
|
||||||
|
@ -74,6 +74,7 @@ const hardcoded_user_group_permissions = {
|
|||||||
system: {
|
system: {
|
||||||
'ca342a5e-b13d-4dee-9048-58b11a57cc55': {
|
'ca342a5e-b13d-4dee-9048-58b11a57cc55': {
|
||||||
'service': {},
|
'service': {},
|
||||||
|
'feature': {},
|
||||||
},
|
},
|
||||||
'b7220104-7905-4985-b996-649fdcdb3c8f': {
|
'b7220104-7905-4985-b996-649fdcdb3c8f': {
|
||||||
'service:hello-world:ii:hello-world': policy_perm('temp.es'),
|
'service:hello-world:ii:hello-world': policy_perm('temp.es'),
|
||||||
|
22
src/backend/src/middleware/featureflag.js
Normal file
22
src/backend/src/middleware/featureflag.js
Normal file
@ -0,0 +1,22 @@
|
|||||||
|
const APIError = require("../api/APIError");
|
||||||
|
const { Context } = require("../util/context");
|
||||||
|
|
||||||
|
const featureflag = options => async (req, res, next) => {
|
||||||
|
const { feature } = options;
|
||||||
|
|
||||||
|
const context = Context.get();
|
||||||
|
const services = context.get('services');
|
||||||
|
const svc_featureFlag = services.get('feature-flag');
|
||||||
|
|
||||||
|
if ( ! await svc_featureFlag.check({
|
||||||
|
actor: req.actor,
|
||||||
|
}, feature) ) {
|
||||||
|
const e = APIError.create('forbidden');
|
||||||
|
e.write(res);
|
||||||
|
return;
|
||||||
|
}
|
||||||
|
|
||||||
|
next();
|
||||||
|
};
|
||||||
|
|
||||||
|
module.exports = featureflag;
|
42
src/backend/src/services/FeatureFlagService.js
Normal file
42
src/backend/src/services/FeatureFlagService.js
Normal file
@ -0,0 +1,42 @@
|
|||||||
|
const { Context } = require("../util/context");
|
||||||
|
const { whatis } = require("../util/langutil");
|
||||||
|
const { PermissionUtil } = require("./auth/PermissionService");
|
||||||
|
const BaseService = require("./BaseService");
|
||||||
|
|
||||||
|
/**
|
||||||
|
* FeatureFlagService is a way to let the client (frontend) know what features
|
||||||
|
* are enabled or disabled for the current user.
|
||||||
|
*/
|
||||||
|
class FeatureFlagService extends BaseService {
|
||||||
|
async check (...a) {
|
||||||
|
// allows binding call with multiple options objects;
|
||||||
|
// the last argument is the permission to check
|
||||||
|
const { options, value: permission } = (() => {
|
||||||
|
let value;
|
||||||
|
const options = {};
|
||||||
|
for ( const arg of a ) {
|
||||||
|
if ( whatis(arg) === 'object' ) {
|
||||||
|
Object.assign(options, arg);
|
||||||
|
continue;
|
||||||
|
}
|
||||||
|
value = arg;
|
||||||
|
break;
|
||||||
|
}
|
||||||
|
return { options, value };
|
||||||
|
})();
|
||||||
|
|
||||||
|
|
||||||
|
|
||||||
|
const actor = options.actor ?? Context.get('actor');
|
||||||
|
|
||||||
|
const svc_permission = this.services.get('permission');
|
||||||
|
const reading = await svc_permission.scan(actor, `feature:${permission}`);
|
||||||
|
const l = PermissionUtil.reading_to_options(reading);
|
||||||
|
if ( l.length === 0 ) return false;
|
||||||
|
return true;
|
||||||
|
}
|
||||||
|
}
|
||||||
|
|
||||||
|
module.exports = {
|
||||||
|
FeatureFlagService
|
||||||
|
};
|
@ -19,6 +19,7 @@
|
|||||||
const APIError = require("../api/APIError");
|
const APIError = require("../api/APIError");
|
||||||
const { get_user } = require("../helpers");
|
const { get_user } = require("../helpers");
|
||||||
const configurable_auth = require("../middleware/configurable_auth");
|
const configurable_auth = require("../middleware/configurable_auth");
|
||||||
|
const featureflag = require("../middleware/featureflag.js");
|
||||||
const { Context } = require("../util/context");
|
const { Context } = require("../util/context");
|
||||||
const { Endpoint } = require("../util/expressutil");
|
const { Endpoint } = require("../util/expressutil");
|
||||||
const { whatis } = require("../util/langutil");
|
const { whatis } = require("../util/langutil");
|
||||||
@ -246,7 +247,10 @@ class ShareService extends BaseService {
|
|||||||
Endpoint({
|
Endpoint({
|
||||||
route: '/',
|
route: '/',
|
||||||
methods: ['POST'],
|
methods: ['POST'],
|
||||||
mw: [configurable_auth()],
|
mw: [
|
||||||
|
configurable_auth(),
|
||||||
|
featureflag({ feature: 'share' }),
|
||||||
|
],
|
||||||
handler: async (req, res) => {
|
handler: async (req, res) => {
|
||||||
const actor = Actor.adapt(req.user);
|
const actor = Actor.adapt(req.user);
|
||||||
return await share_sequence.call(this, {
|
return await share_sequence.call(this, {
|
||||||
|
Loading…
Reference in New Issue
Block a user