From a5896799f169d3313b63165fe6a79d4149fa6df1 Mon Sep 17 00:00:00 2001 From: Chocobozzz Date: Thu, 30 Apr 2020 09:28:39 +0200 Subject: [PATCH] Add plugin settings change watcher --- server/controllers/api/config.ts | 2 +- server/controllers/api/plugins.ts | 2 + server/lib/plugins/plugin-manager.ts | 45 +++++++++++++------ server/lib/plugins/register-helpers-store.ts | 12 ++++- server/tests/api/server/plugins.ts | 11 ++++- .../main.js | 4 +- .../main.js | 2 +- .../plugins/plugin-settings-manager.model.ts | 2 + .../plugins/register-server-auth.model.ts | 2 +- 9 files changed, 59 insertions(+), 23 deletions(-) diff --git a/server/controllers/api/config.ts b/server/controllers/api/config.ts index 85f3ad3d9..edcb0b99e 100644 --- a/server/controllers/api/config.ts +++ b/server/controllers/api/config.ts @@ -299,7 +299,7 @@ function getExternalAuthsPlugins () { name: p.name, version: p.version, authName: auth.authName, - authDisplayName: auth.authDisplayName + authDisplayName: auth.authDisplayName() }) } } diff --git a/server/controllers/api/plugins.ts b/server/controllers/api/plugins.ts index 6b7562fd3..f8a0d19ca 100644 --- a/server/controllers/api/plugins.ts +++ b/server/controllers/api/plugins.ts @@ -191,6 +191,8 @@ async function updatePluginSettings (req: express.Request, res: express.Response plugin.settings = req.body.settings await plugin.save() + await PluginManager.Instance.onSettingsChanged(plugin.name, plugin.settings) + return res.sendStatus(204) } diff --git a/server/lib/plugins/plugin-manager.ts b/server/lib/plugins/plugin-manager.ts index f7b84b1ff..950acf7ad 100644 --- a/server/lib/plugins/plugin-manager.ts +++ b/server/lib/plugins/plugin-manager.ts @@ -144,20 +144,6 @@ export class PluginManager implements ServerHook { return this.translations[locale] || {} } - onLogout (npmName: string, authName: string, user: MUser) { - const auth = this.getAuth(npmName, authName) - - if (auth?.onLogout) { - logger.info('Running onLogout function from auth %s of plugin %s', authName, npmName) - - try { - auth.onLogout(user) - } catch (err) { - logger.warn('Cannot run onLogout function from auth %s of plugin %s.', authName, npmName, { err }) - } - } - } - async isTokenValid (token: MOAuthTokenUser, type: 'access' | 'refresh') { const auth = this.getAuth(token.User.pluginAuth, token.authName) if (!auth) return true @@ -180,6 +166,37 @@ export class PluginManager implements ServerHook { return true } + // ###################### External events ###################### + + onLogout (npmName: string, authName: string, user: MUser) { + const auth = this.getAuth(npmName, authName) + + if (auth?.onLogout) { + logger.info('Running onLogout function from auth %s of plugin %s', authName, npmName) + + try { + auth.onLogout(user) + } catch (err) { + logger.warn('Cannot run onLogout function from auth %s of plugin %s.', authName, npmName, { err }) + } + } + } + + onSettingsChanged (name: string, settings: any) { + const registered = this.getRegisteredPluginByShortName(name) + if (!registered) { + logger.error('Cannot find plugin %s to call on settings changed.', name) + } + + for (const cb of registered.registerHelpersStore.getOnSettingsChangedCallbacks()) { + try { + cb(settings) + } catch (err) { + logger.error('Cannot run on settings changed callback for %s.', registered.npmName, { err }) + } + } + } + // ###################### Hooks ###################### async runHook (hookName: ServerHookName, result?: T, params?: any): Promise { diff --git a/server/lib/plugins/register-helpers-store.ts b/server/lib/plugins/register-helpers-store.ts index 151196bf1..6317ac2cf 100644 --- a/server/lib/plugins/register-helpers-store.ts +++ b/server/lib/plugins/register-helpers-store.ts @@ -52,6 +52,8 @@ export class RegisterHelpersStore { private readonly idAndPassAuths: RegisterServerAuthPassOptions[] = [] private readonly externalAuths: RegisterServerAuthExternalOptions[] = [] + private readonly onSettingsChangeCallbacks: ((settings: any) => void)[] = [] + private readonly router: express.Router constructor ( @@ -149,6 +151,10 @@ export class RegisterHelpersStore { return this.externalAuths } + getOnSettingsChangedCallbacks () { + return this.onSettingsChangeCallbacks + } + private buildGetRouter () { return () => this.router } @@ -185,7 +191,7 @@ export class RegisterHelpersStore { const self = this return (options: RegisterServerAuthExternalOptions) => { - if (!options.authName || !options.onAuthRequest || typeof options.onAuthRequest !== 'function') { + if (!options.authName || typeof options.authDisplayName !== 'function' || typeof options.onAuthRequest !== 'function') { logger.error('Cannot register auth plugin %s: authName of getWeight or login are not valid.', this.npmName) return } @@ -212,7 +218,9 @@ export class RegisterHelpersStore { getSettings: (names: string[]) => PluginModel.getSettings(this.plugin.name, this.plugin.type, names), - setSetting: (name: string, value: string) => PluginModel.setSetting(this.plugin.name, this.plugin.type, name, value) + setSetting: (name: string, value: string) => PluginModel.setSetting(this.plugin.name, this.plugin.type, name, value), + + onSettingsChange: (cb: (settings: any) => void) => this.onSettingsChangeCallbacks.push(cb) } } diff --git a/server/tests/api/server/plugins.ts b/server/tests/api/server/plugins.ts index 452d05012..9885be4e8 100644 --- a/server/tests/api/server/plugins.ts +++ b/server/tests/api/server/plugins.ts @@ -27,7 +27,8 @@ import { updatePlugin, updatePluginPackageJSON, updatePluginSettings, - wait + wait, + waitUntilLog } from '../../../../shared/extra-utils' import { PluginType } from '../../../../shared/models/plugins/plugin.type' import { PeerTubePluginIndex } from '../../../../shared/models/plugins/peertube-plugin-index.model' @@ -142,7 +143,7 @@ describe('Test plugins', function () { it('Should have the correct global css', async function () { const res = await getPluginsCSS(server.url) - expect(res.text).to.contain('--mainBackgroundColor') + expect(res.text).to.contain('background-color: red') }) it('Should have the plugin loaded in the configuration', async function () { @@ -258,6 +259,12 @@ describe('Test plugins', function () { }) }) + it('Should have watched settings changes', async function () { + this.timeout(10000) + + await waitUntilLog(server, 'Settings changed!') + }) + it('Should get a plugin and a theme', async function () { { const res = await getPlugin({ diff --git a/server/tests/fixtures/peertube-plugin-test-external-auth-one/main.js b/server/tests/fixtures/peertube-plugin-test-external-auth-one/main.js index f29fd1f30..91c67e550 100644 --- a/server/tests/fixtures/peertube-plugin-test-external-auth-one/main.js +++ b/server/tests/fixtures/peertube-plugin-test-external-auth-one/main.js @@ -5,7 +5,7 @@ async function register ({ { const result = registerExternalAuth({ authName: 'external-auth-1', - authDisplayName: 'External Auth 1', + authDisplayName: () => 'External Auth 1', onLogout: user => peertubeHelpers.logger.info('On logout %s', user.username), onAuthRequest: (req, res) => { const username = req.query.username @@ -23,7 +23,7 @@ async function register ({ { const result = registerExternalAuth({ authName: 'external-auth-2', - authDisplayName: 'External Auth 2', + authDisplayName: () => 'External Auth 2', onAuthRequest: (req, res) => { result.userAuthenticated({ req, diff --git a/server/tests/fixtures/peertube-plugin-test-external-auth-two/main.js b/server/tests/fixtures/peertube-plugin-test-external-auth-two/main.js index 34fec1bb3..126905ffc 100644 --- a/server/tests/fixtures/peertube-plugin-test-external-auth-two/main.js +++ b/server/tests/fixtures/peertube-plugin-test-external-auth-two/main.js @@ -5,7 +5,7 @@ async function register ({ { const result = registerExternalAuth({ authName: 'external-auth-3', - authDisplayName: 'External Auth 3', + authDisplayName: () => 'External Auth 3', onAuthRequest: (req, res) => { result.userAuthenticated({ req, diff --git a/shared/models/plugins/plugin-settings-manager.model.ts b/shared/models/plugins/plugin-settings-manager.model.ts index f83f53b8f..db88ae6e7 100644 --- a/shared/models/plugins/plugin-settings-manager.model.ts +++ b/shared/models/plugins/plugin-settings-manager.model.ts @@ -6,4 +6,6 @@ export interface PluginSettingsManager { getSettings: (names: string[]) => Bluebird<{ [settingName: string]: string | boolean }> setSetting: (name: string, value: string) => Bluebird + + onSettingsChange: (cb: (names: string[]) => void) => void } diff --git a/shared/models/plugins/register-server-auth.model.ts b/shared/models/plugins/register-server-auth.model.ts index 6539dc888..4ffce9456 100644 --- a/shared/models/plugins/register-server-auth.model.ts +++ b/shared/models/plugins/register-server-auth.model.ts @@ -42,7 +42,7 @@ export interface RegisterServerAuthPassOptions extends RegisterServerAuthBase { export interface RegisterServerAuthExternalOptions extends RegisterServerAuthBase { // Will be displayed in a block next to the login form - authDisplayName: string + authDisplayName: () => string onAuthRequest: (req: express.Request, res: express.Response) => void }