diff --git a/src/backend/src/routers/whoami.js b/src/backend/src/routers/whoami.js index a08d796ee..89320312a 100644 --- a/src/backend/src/routers/whoami.js +++ b/src/backend/src/routers/whoami.js @@ -61,7 +61,10 @@ const WHOAMI_GET = eggspress('/whoami', { // Get whoami values from other services const svc_whoami = req.services.get('whoami'); - const provider_details = await svc_whoami.get_details({ user: req.user }); + const provider_details = await svc_whoami.get_details({ + user: req.user, + actor: actor, + }); Object.assign(details, provider_details); if ( ! is_user ) { diff --git a/src/backend/src/services/FeatureFlagService.js b/src/backend/src/services/FeatureFlagService.js index bbce5818b..d310cce6a 100644 --- a/src/backend/src/services/FeatureFlagService.js +++ b/src/backend/src/services/FeatureFlagService.js @@ -8,6 +8,20 @@ const BaseService = require("./BaseService"); * are enabled or disabled for the current user. */ class FeatureFlagService extends BaseService { + _construct () { + this.known_flags = new Map(); + } + register (name, spec) { + this.known_flags.set(name, spec); + } + async _init () { + const svc_detailProvider = this.services.get('whoami'); + svc_detailProvider.register_provider(async (context, out) => { + console.log(`\x1B[36;1mCALLED\x1B[0m`); + if ( ! context.actor ) return; + out.feature_flags = await this.get_summary(context.actor); + }); + } async check (...a) { // allows binding call with multiple options objects; // the last argument is the permission to check @@ -25,6 +39,9 @@ class FeatureFlagService extends BaseService { return { options, value }; })(); + if ( ! this.known_flags.has(permission) ) { + this.known_flags.set(permission, true); + } const actor = options.actor ?? Context.get('actor'); @@ -35,6 +52,22 @@ class FeatureFlagService extends BaseService { if ( l.length === 0 ) return false; return true; } + + async get_summary (actor) { + const summary = {}; + for ( const [key, value] of this.known_flags.entries() ) { + if ( value.$ === 'config-flag' ) { + summary[key] = value.value; + continue; + } + const svc_permission = this.services.get('permission'); + const reading = await svc_permission.scan(actor, `feature:`); + const l = PermissionUtil.reading_to_options(reading); + summary[key] = l.length > 0; + } + + return summary; + } } module.exports = { diff --git a/src/backend/src/services/ShareService.js b/src/backend/src/services/ShareService.js index b64093436..63e7e7760 100644 --- a/src/backend/src/services/ShareService.js +++ b/src/backend/src/services/ShareService.js @@ -37,6 +37,13 @@ class ShareService extends BaseService { async _init () { this.db = await this.services.get('database').get(DB_WRITE, 'share'); + + // registry "share" as a feature flag so gui is informed + // about whether or not a user has access to this feature + const svc_featureFlag = this.services.get('feature-flag'); + svc_featureFlag.register('share', { + $: 'permission-flag' + }); } ['__on_install.routes'] (_, { app }) { diff --git a/src/backend/src/services/auth/ACLService.js b/src/backend/src/services/auth/ACLService.js index a036983e1..9cbc98ab3 100644 --- a/src/backend/src/services/auth/ACLService.js +++ b/src/backend/src/services/auth/ACLService.js @@ -25,6 +25,13 @@ const { AppUnderUserActorType, UserActorType, Actor, SystemActorType, AccessToke const { PermissionUtil } = require("./PermissionService"); class ACLService extends BaseService { + async _init () { + const svc_featureFlag = this.services.get('feature-flag'); + svc_featureFlag.register('public-folders', { + $: 'config-flag', + value: this.global_config.enable_public_folders ?? false, + }); + } async check (actor, resource, mode) { const ld = (Context.get('logdent') ?? 0) + 1; return await Context.get().sub({ logdent: ld }).arun(async () => {