diff options
author | Chocobozzz <me@florianbigard.com> | 2020-04-30 09:28:39 +0200 |
---|---|---|
committer | Chocobozzz <chocobozzz@cpy.re> | 2020-05-04 16:21:39 +0200 |
commit | a5896799f169d3313b63165fe6a79d4149fa6df1 (patch) | |
tree | 0151902e829dce13bbb22ff0fe6967ce6bee4058 | |
parent | dadc90bca257f2d785713a37949c3a1bf6a5243d (diff) | |
download | PeerTube-a5896799f169d3313b63165fe6a79d4149fa6df1.tar.gz PeerTube-a5896799f169d3313b63165fe6a79d4149fa6df1.tar.zst PeerTube-a5896799f169d3313b63165fe6a79d4149fa6df1.zip |
Add plugin settings change watcher
-rw-r--r-- | server/controllers/api/config.ts | 2 | ||||
-rw-r--r-- | server/controllers/api/plugins.ts | 2 | ||||
-rw-r--r-- | server/lib/plugins/plugin-manager.ts | 45 | ||||
-rw-r--r-- | server/lib/plugins/register-helpers-store.ts | 12 | ||||
-rw-r--r-- | server/tests/api/server/plugins.ts | 11 | ||||
-rw-r--r-- | server/tests/fixtures/peertube-plugin-test-external-auth-one/main.js | 4 | ||||
-rw-r--r-- | server/tests/fixtures/peertube-plugin-test-external-auth-two/main.js | 2 | ||||
-rw-r--r-- | shared/models/plugins/plugin-settings-manager.model.ts | 2 | ||||
-rw-r--r-- | shared/models/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 () { | |||
299 | name: p.name, | 299 | name: p.name, |
300 | version: p.version, | 300 | version: p.version, |
301 | authName: auth.authName, | 301 | authName: auth.authName, |
302 | authDisplayName: auth.authDisplayName | 302 | authDisplayName: auth.authDisplayName() |
303 | }) | 303 | }) |
304 | } | 304 | } |
305 | } | 305 | } |
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 | |||
191 | plugin.settings = req.body.settings | 191 | plugin.settings = req.body.settings |
192 | await plugin.save() | 192 | await plugin.save() |
193 | 193 | ||
194 | await PluginManager.Instance.onSettingsChanged(plugin.name, plugin.settings) | ||
195 | |||
194 | return res.sendStatus(204) | 196 | return res.sendStatus(204) |
195 | } | 197 | } |
196 | 198 | ||
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 { | |||
144 | return this.translations[locale] || {} | 144 | return this.translations[locale] || {} |
145 | } | 145 | } |
146 | 146 | ||
147 | onLogout (npmName: string, authName: string, user: MUser) { | ||
148 | const auth = this.getAuth(npmName, authName) | ||
149 | |||
150 | if (auth?.onLogout) { | ||
151 | logger.info('Running onLogout function from auth %s of plugin %s', authName, npmName) | ||
152 | |||
153 | try { | ||
154 | auth.onLogout(user) | ||
155 | } catch (err) { | ||
156 | logger.warn('Cannot run onLogout function from auth %s of plugin %s.', authName, npmName, { err }) | ||
157 | } | ||
158 | } | ||
159 | } | ||
160 | |||
161 | async isTokenValid (token: MOAuthTokenUser, type: 'access' | 'refresh') { | 147 | async isTokenValid (token: MOAuthTokenUser, type: 'access' | 'refresh') { |
162 | const auth = this.getAuth(token.User.pluginAuth, token.authName) | 148 | const auth = this.getAuth(token.User.pluginAuth, token.authName) |
163 | if (!auth) return true | 149 | if (!auth) return true |
@@ -180,6 +166,37 @@ export class PluginManager implements ServerHook { | |||
180 | return true | 166 | return true |
181 | } | 167 | } |
182 | 168 | ||
169 | // ###################### External events ###################### | ||
170 | |||
171 | onLogout (npmName: string, authName: string, user: MUser) { | ||
172 | const auth = this.getAuth(npmName, authName) | ||
173 | |||
174 | if (auth?.onLogout) { | ||
175 | logger.info('Running onLogout function from auth %s of plugin %s', authName, npmName) | ||
176 | |||
177 | try { | ||
178 | auth.onLogout(user) | ||
179 | } catch (err) { | ||
180 | logger.warn('Cannot run onLogout function from auth %s of plugin %s.', authName, npmName, { err }) | ||
181 | } | ||
182 | } | ||
183 | } | ||
184 | |||
185 | onSettingsChanged (name: string, settings: any) { | ||
186 | const registered = this.getRegisteredPluginByShortName(name) | ||
187 | if (!registered) { | ||
188 | logger.error('Cannot find plugin %s to call on settings changed.', name) | ||
189 | } | ||
190 | |||
191 | for (const cb of registered.registerHelpersStore.getOnSettingsChangedCallbacks()) { | ||
192 | try { | ||
193 | cb(settings) | ||
194 | } catch (err) { | ||
195 | logger.error('Cannot run on settings changed callback for %s.', registered.npmName, { err }) | ||
196 | } | ||
197 | } | ||
198 | } | ||
199 | |||
183 | // ###################### Hooks ###################### | 200 | // ###################### Hooks ###################### |
184 | 201 | ||
185 | async runHook<T> (hookName: ServerHookName, result?: T, params?: any): Promise<T> { | 202 | async runHook<T> (hookName: ServerHookName, result?: T, params?: any): Promise<T> { |
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 { | |||
52 | private readonly idAndPassAuths: RegisterServerAuthPassOptions[] = [] | 52 | private readonly idAndPassAuths: RegisterServerAuthPassOptions[] = [] |
53 | private readonly externalAuths: RegisterServerAuthExternalOptions[] = [] | 53 | private readonly externalAuths: RegisterServerAuthExternalOptions[] = [] |
54 | 54 | ||
55 | private readonly onSettingsChangeCallbacks: ((settings: any) => void)[] = [] | ||
56 | |||
55 | private readonly router: express.Router | 57 | private readonly router: express.Router |
56 | 58 | ||
57 | constructor ( | 59 | constructor ( |
@@ -149,6 +151,10 @@ export class RegisterHelpersStore { | |||
149 | return this.externalAuths | 151 | return this.externalAuths |
150 | } | 152 | } |
151 | 153 | ||
154 | getOnSettingsChangedCallbacks () { | ||
155 | return this.onSettingsChangeCallbacks | ||
156 | } | ||
157 | |||
152 | private buildGetRouter () { | 158 | private buildGetRouter () { |
153 | return () => this.router | 159 | return () => this.router |
154 | } | 160 | } |
@@ -185,7 +191,7 @@ export class RegisterHelpersStore { | |||
185 | const self = this | 191 | const self = this |
186 | 192 | ||
187 | return (options: RegisterServerAuthExternalOptions) => { | 193 | return (options: RegisterServerAuthExternalOptions) => { |
188 | if (!options.authName || !options.onAuthRequest || typeof options.onAuthRequest !== 'function') { | 194 | if (!options.authName || typeof options.authDisplayName !== 'function' || typeof options.onAuthRequest !== 'function') { |
189 | logger.error('Cannot register auth plugin %s: authName of getWeight or login are not valid.', this.npmName) | 195 | logger.error('Cannot register auth plugin %s: authName of getWeight or login are not valid.', this.npmName) |
190 | return | 196 | return |
191 | } | 197 | } |
@@ -212,7 +218,9 @@ export class RegisterHelpersStore { | |||
212 | 218 | ||
213 | getSettings: (names: string[]) => PluginModel.getSettings(this.plugin.name, this.plugin.type, names), | 219 | getSettings: (names: string[]) => PluginModel.getSettings(this.plugin.name, this.plugin.type, names), |
214 | 220 | ||
215 | setSetting: (name: string, value: string) => PluginModel.setSetting(this.plugin.name, this.plugin.type, name, value) | 221 | setSetting: (name: string, value: string) => PluginModel.setSetting(this.plugin.name, this.plugin.type, name, value), |
222 | |||
223 | onSettingsChange: (cb: (settings: any) => void) => this.onSettingsChangeCallbacks.push(cb) | ||
216 | } | 224 | } |
217 | } | 225 | } |
218 | 226 | ||
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 { | |||
27 | updatePlugin, | 27 | updatePlugin, |
28 | updatePluginPackageJSON, | 28 | updatePluginPackageJSON, |
29 | updatePluginSettings, | 29 | updatePluginSettings, |
30 | wait | 30 | wait, |
31 | waitUntilLog | ||
31 | } from '../../../../shared/extra-utils' | 32 | } from '../../../../shared/extra-utils' |
32 | import { PluginType } from '../../../../shared/models/plugins/plugin.type' | 33 | import { PluginType } from '../../../../shared/models/plugins/plugin.type' |
33 | import { PeerTubePluginIndex } from '../../../../shared/models/plugins/peertube-plugin-index.model' | 34 | import { PeerTubePluginIndex } from '../../../../shared/models/plugins/peertube-plugin-index.model' |
@@ -142,7 +143,7 @@ describe('Test plugins', function () { | |||
142 | it('Should have the correct global css', async function () { | 143 | it('Should have the correct global css', async function () { |
143 | const res = await getPluginsCSS(server.url) | 144 | const res = await getPluginsCSS(server.url) |
144 | 145 | ||
145 | expect(res.text).to.contain('--mainBackgroundColor') | 146 | expect(res.text).to.contain('background-color: red') |
146 | }) | 147 | }) |
147 | 148 | ||
148 | it('Should have the plugin loaded in the configuration', async function () { | 149 | it('Should have the plugin loaded in the configuration', async function () { |
@@ -258,6 +259,12 @@ describe('Test plugins', function () { | |||
258 | }) | 259 | }) |
259 | }) | 260 | }) |
260 | 261 | ||
262 | it('Should have watched settings changes', async function () { | ||
263 | this.timeout(10000) | ||
264 | |||
265 | await waitUntilLog(server, 'Settings changed!') | ||
266 | }) | ||
267 | |||
261 | it('Should get a plugin and a theme', async function () { | 268 | it('Should get a plugin and a theme', async function () { |
262 | { | 269 | { |
263 | const res = await getPlugin({ | 270 | 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 ({ | |||
5 | { | 5 | { |
6 | const result = registerExternalAuth({ | 6 | const result = registerExternalAuth({ |
7 | authName: 'external-auth-1', | 7 | authName: 'external-auth-1', |
8 | authDisplayName: 'External Auth 1', | 8 | authDisplayName: () => 'External Auth 1', |
9 | onLogout: user => peertubeHelpers.logger.info('On logout %s', user.username), | 9 | onLogout: user => peertubeHelpers.logger.info('On logout %s', user.username), |
10 | onAuthRequest: (req, res) => { | 10 | onAuthRequest: (req, res) => { |
11 | const username = req.query.username | 11 | const username = req.query.username |
@@ -23,7 +23,7 @@ async function register ({ | |||
23 | { | 23 | { |
24 | const result = registerExternalAuth({ | 24 | const result = registerExternalAuth({ |
25 | authName: 'external-auth-2', | 25 | authName: 'external-auth-2', |
26 | authDisplayName: 'External Auth 2', | 26 | authDisplayName: () => 'External Auth 2', |
27 | onAuthRequest: (req, res) => { | 27 | onAuthRequest: (req, res) => { |
28 | result.userAuthenticated({ | 28 | result.userAuthenticated({ |
29 | req, | 29 | 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 ({ | |||
5 | { | 5 | { |
6 | const result = registerExternalAuth({ | 6 | const result = registerExternalAuth({ |
7 | authName: 'external-auth-3', | 7 | authName: 'external-auth-3', |
8 | authDisplayName: 'External Auth 3', | 8 | authDisplayName: () => 'External Auth 3', |
9 | onAuthRequest: (req, res) => { | 9 | onAuthRequest: (req, res) => { |
10 | result.userAuthenticated({ | 10 | result.userAuthenticated({ |
11 | req, | 11 | 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 { | |||
6 | getSettings: (names: string[]) => Bluebird<{ [settingName: string]: string | boolean }> | 6 | getSettings: (names: string[]) => Bluebird<{ [settingName: string]: string | boolean }> |
7 | 7 | ||
8 | setSetting: (name: string, value: string) => Bluebird<any> | 8 | setSetting: (name: string, value: string) => Bluebird<any> |
9 | |||
10 | onSettingsChange: (cb: (names: string[]) => void) => void | ||
9 | } | 11 | } |
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 { | |||
42 | 42 | ||
43 | export interface RegisterServerAuthExternalOptions extends RegisterServerAuthBase { | 43 | export interface RegisterServerAuthExternalOptions extends RegisterServerAuthBase { |
44 | // Will be displayed in a block next to the login form | 44 | // Will be displayed in a block next to the login form |
45 | authDisplayName: string | 45 | authDisplayName: () => string |
46 | 46 | ||
47 | onAuthRequest: (req: express.Request, res: express.Response) => void | 47 | onAuthRequest: (req: express.Request, res: express.Response) => void |
48 | } | 48 | } |