diff options
-rw-r--r-- | client/src/app/+admin/plugins/plugin-show-installed/plugin-show-installed.component.ts | 2 | ||||
-rw-r--r-- | client/src/app/+admin/plugins/shared/plugin-api.service.ts | 4 | ||||
-rw-r--r-- | client/src/app/core/plugins/plugin.service.ts | 7 | ||||
-rw-r--r-- | server/controllers/api/plugins.ts | 32 | ||||
-rw-r--r-- | server/models/server/plugin.ts | 15 | ||||
-rw-r--r-- | server/tests/api/check-params/plugins.ts | 10 | ||||
-rw-r--r-- | server/tests/api/server/plugins.ts | 19 | ||||
-rw-r--r-- | shared/extra-utils/server/plugins.ts | 18 | ||||
-rw-r--r-- | shared/models/plugins/public-server.setting.ts | 3 | ||||
-rw-r--r-- | shared/models/plugins/register-server-setting.model.ts | 8 |
10 files changed, 92 insertions, 26 deletions
diff --git a/client/src/app/+admin/plugins/plugin-show-installed/plugin-show-installed.component.ts b/client/src/app/+admin/plugins/plugin-show-installed/plugin-show-installed.component.ts index 569d98482..13d12b145 100644 --- a/client/src/app/+admin/plugins/plugin-show-installed/plugin-show-installed.component.ts +++ b/client/src/app/+admin/plugins/plugin-show-installed/plugin-show-installed.component.ts | |||
@@ -66,7 +66,7 @@ export class PluginShowInstalledComponent extends FormReactive implements OnInit | |||
66 | this.pluginService.getPlugin(npmName) | 66 | this.pluginService.getPlugin(npmName) |
67 | .pipe(switchMap(plugin => { | 67 | .pipe(switchMap(plugin => { |
68 | return this.pluginService.getPluginRegisteredSettings(plugin.name, plugin.type) | 68 | return this.pluginService.getPluginRegisteredSettings(plugin.name, plugin.type) |
69 | .pipe(map(data => ({ plugin, registeredSettings: data.settings }))) | 69 | .pipe(map(data => ({ plugin, registeredSettings: data.registeredSettings }))) |
70 | })) | 70 | })) |
71 | .subscribe( | 71 | .subscribe( |
72 | ({ plugin, registeredSettings }) => { | 72 | ({ plugin, registeredSettings }) => { |
diff --git a/client/src/app/+admin/plugins/shared/plugin-api.service.ts b/client/src/app/+admin/plugins/shared/plugin-api.service.ts index 343eb57b2..c360fc1b3 100644 --- a/client/src/app/+admin/plugins/shared/plugin-api.service.ts +++ b/client/src/app/+admin/plugins/shared/plugin-api.service.ts | |||
@@ -11,7 +11,7 @@ import { PeerTubePlugin } from '@shared/models/plugins/peertube-plugin.model' | |||
11 | import { ManagePlugin } from '@shared/models/plugins/manage-plugin.model' | 11 | import { ManagePlugin } from '@shared/models/plugins/manage-plugin.model' |
12 | import { InstallOrUpdatePlugin } from '@shared/models/plugins/install-plugin.model' | 12 | import { InstallOrUpdatePlugin } from '@shared/models/plugins/install-plugin.model' |
13 | import { PeerTubePluginIndex } from '@shared/models/plugins/peertube-plugin-index.model' | 13 | import { PeerTubePluginIndex } from '@shared/models/plugins/peertube-plugin-index.model' |
14 | import { RegisterServerSettingOptions } from '@shared/models/plugins/register-server-setting.model' | 14 | import { RegisteredServerSettings, RegisterServerSettingOptions } from '@shared/models/plugins/register-server-setting.model' |
15 | import { PluginService } from '@app/core/plugins/plugin.service' | 15 | import { PluginService } from '@app/core/plugins/plugin.service' |
16 | 16 | ||
17 | @Injectable() | 17 | @Injectable() |
@@ -91,7 +91,7 @@ export class PluginApiService { | |||
91 | const npmName = this.pluginService.nameToNpmName(pluginName, pluginType) | 91 | const npmName = this.pluginService.nameToNpmName(pluginName, pluginType) |
92 | const path = PluginApiService.BASE_PLUGIN_URL + '/' + npmName + '/registered-settings' | 92 | const path = PluginApiService.BASE_PLUGIN_URL + '/' + npmName + '/registered-settings' |
93 | 93 | ||
94 | return this.authHttp.get<{ settings: RegisterServerSettingOptions[] }>(path) | 94 | return this.authHttp.get<RegisteredServerSettings>(path) |
95 | .pipe(catchError(res => this.restExtractor.handleError(res))) | 95 | .pipe(catchError(res => this.restExtractor.handleError(res))) |
96 | } | 96 | } |
97 | 97 | ||
diff --git a/client/src/app/core/plugins/plugin.service.ts b/client/src/app/core/plugins/plugin.service.ts index 45d8088a4..714abd82d 100644 --- a/client/src/app/core/plugins/plugin.service.ts +++ b/client/src/app/core/plugins/plugin.service.ts | |||
@@ -15,6 +15,7 @@ import { PeerTubePlugin } from '@shared/models/plugins/peertube-plugin.model' | |||
15 | import { HttpClient } from '@angular/common/http' | 15 | import { HttpClient } from '@angular/common/http' |
16 | import { RestExtractor } from '@app/shared/rest' | 16 | import { RestExtractor } from '@app/shared/rest' |
17 | import { PluginType } from '@shared/models/plugins/plugin.type' | 17 | import { PluginType } from '@shared/models/plugins/plugin.type' |
18 | import { PublicServerSetting } from '@shared/models/plugins/public-server.setting' | ||
18 | 19 | ||
19 | interface HookStructValue extends RegisterClientHookOptions { | 20 | interface HookStructValue extends RegisterClientHookOptions { |
20 | plugin: ServerConfigPlugin | 21 | plugin: ServerConfigPlugin |
@@ -241,11 +242,11 @@ export class PluginService implements ClientHook { | |||
241 | 242 | ||
242 | getSettings: () => { | 243 | getSettings: () => { |
243 | const npmName = this.nameToNpmName(pluginInfo.plugin.name, pluginInfo.pluginType) | 244 | const npmName = this.nameToNpmName(pluginInfo.plugin.name, pluginInfo.pluginType) |
244 | const path = PluginService.BASE_PLUGIN_URL + '/' + npmName | 245 | const path = PluginService.BASE_PLUGIN_URL + '/' + npmName + '/public-settings' |
245 | 246 | ||
246 | return this.authHttp.get<PeerTubePlugin>(path) | 247 | return this.authHttp.get<PublicServerSetting>(path) |
247 | .pipe( | 248 | .pipe( |
248 | map(p => p.settings), | 249 | map(p => p.publicSettings), |
249 | catchError(res => this.restExtractor.handleError(res)) | 250 | catchError(res => this.restExtractor.handleError(res)) |
250 | ) | 251 | ) |
251 | .toPromise() | 252 | .toPromise() |
diff --git a/server/controllers/api/plugins.ts b/server/controllers/api/plugins.ts index 86384ee27..6b7562fd3 100644 --- a/server/controllers/api/plugins.ts +++ b/server/controllers/api/plugins.ts | |||
@@ -26,6 +26,7 @@ import { logger } from '../../helpers/logger' | |||
26 | import { listAvailablePluginsFromIndex } from '../../lib/plugins/plugin-index' | 26 | import { listAvailablePluginsFromIndex } from '../../lib/plugins/plugin-index' |
27 | import { PeertubePluginIndexList } from '../../../shared/models/plugins/peertube-plugin-index-list.model' | 27 | import { PeertubePluginIndexList } from '../../../shared/models/plugins/peertube-plugin-index-list.model' |
28 | import { RegisteredServerSettings } from '../../../shared/models/plugins/register-server-setting.model' | 28 | import { RegisteredServerSettings } from '../../../shared/models/plugins/register-server-setting.model' |
29 | import { PublicServerSetting } from '../../../shared/models/plugins/public-server.setting' | ||
29 | 30 | ||
30 | const pluginRouter = express.Router() | 31 | const pluginRouter = express.Router() |
31 | 32 | ||
@@ -51,18 +52,16 @@ pluginRouter.get('/', | |||
51 | asyncMiddleware(listPlugins) | 52 | asyncMiddleware(listPlugins) |
52 | ) | 53 | ) |
53 | 54 | ||
54 | pluginRouter.get('/:npmName', | 55 | pluginRouter.get('/:npmName/registered-settings', |
55 | authenticate, | 56 | authenticate, |
56 | ensureUserHasRight(UserRight.MANAGE_PLUGINS), | 57 | ensureUserHasRight(UserRight.MANAGE_PLUGINS), |
57 | asyncMiddleware(existingPluginValidator), | 58 | asyncMiddleware(existingPluginValidator), |
58 | getPlugin | 59 | getPluginRegisteredSettings |
59 | ) | 60 | ) |
60 | 61 | ||
61 | pluginRouter.get('/:npmName/registered-settings', | 62 | pluginRouter.get('/:npmName/public-settings', |
62 | authenticate, | ||
63 | ensureUserHasRight(UserRight.MANAGE_PLUGINS), | ||
64 | asyncMiddleware(existingPluginValidator), | 63 | asyncMiddleware(existingPluginValidator), |
65 | getPluginRegisteredSettings | 64 | getPublicPluginSettings |
66 | ) | 65 | ) |
67 | 66 | ||
68 | pluginRouter.put('/:npmName/settings', | 67 | pluginRouter.put('/:npmName/settings', |
@@ -73,6 +72,13 @@ pluginRouter.put('/:npmName/settings', | |||
73 | asyncMiddleware(updatePluginSettings) | 72 | asyncMiddleware(updatePluginSettings) |
74 | ) | 73 | ) |
75 | 74 | ||
75 | pluginRouter.get('/:npmName', | ||
76 | authenticate, | ||
77 | ensureUserHasRight(UserRight.MANAGE_PLUGINS), | ||
78 | asyncMiddleware(existingPluginValidator), | ||
79 | getPlugin | ||
80 | ) | ||
81 | |||
76 | pluginRouter.post('/install', | 82 | pluginRouter.post('/install', |
77 | authenticate, | 83 | authenticate, |
78 | ensureUserHasRight(UserRight.MANAGE_PLUGINS), | 84 | ensureUserHasRight(UserRight.MANAGE_PLUGINS), |
@@ -161,10 +167,20 @@ async function uninstallPlugin (req: express.Request, res: express.Response) { | |||
161 | return res.sendStatus(204) | 167 | return res.sendStatus(204) |
162 | } | 168 | } |
163 | 169 | ||
170 | function getPublicPluginSettings (req: express.Request, res: express.Response) { | ||
171 | const plugin = res.locals.plugin | ||
172 | const registeredSettings = PluginManager.Instance.getRegisteredSettings(req.params.npmName) | ||
173 | const publicSettings = plugin.getPublicSettings(registeredSettings) | ||
174 | |||
175 | const json: PublicServerSetting = { publicSettings } | ||
176 | |||
177 | return res.json(json) | ||
178 | } | ||
179 | |||
164 | function getPluginRegisteredSettings (req: express.Request, res: express.Response) { | 180 | function getPluginRegisteredSettings (req: express.Request, res: express.Response) { |
165 | const settings = PluginManager.Instance.getRegisteredSettings(req.params.npmName) | 181 | const registeredSettings = PluginManager.Instance.getRegisteredSettings(req.params.npmName) |
166 | 182 | ||
167 | const json: RegisteredServerSettings = { settings } | 183 | const json: RegisteredServerSettings = { registeredSettings } |
168 | 184 | ||
169 | return res.json(json) | 185 | return res.json(json) |
170 | } | 186 | } |
diff --git a/server/models/server/plugin.ts b/server/models/server/plugin.ts index f39b97ef0..a15f9a7e2 100644 --- a/server/models/server/plugin.ts +++ b/server/models/server/plugin.ts | |||
@@ -10,7 +10,7 @@ import { | |||
10 | import { PluginType } from '../../../shared/models/plugins/plugin.type' | 10 | import { PluginType } from '../../../shared/models/plugins/plugin.type' |
11 | import { PeerTubePlugin } from '../../../shared/models/plugins/peertube-plugin.model' | 11 | import { PeerTubePlugin } from '../../../shared/models/plugins/peertube-plugin.model' |
12 | import { FindAndCountOptions, json } from 'sequelize' | 12 | import { FindAndCountOptions, json } from 'sequelize' |
13 | import { PeerTubePluginIndex } from '../../../shared/models/plugins/peertube-plugin-index.model' | 13 | import { RegisterServerSettingOptions } from '../../../shared/models/plugins/register-server-setting.model' |
14 | 14 | ||
15 | @DefaultScope(() => ({ | 15 | @DefaultScope(() => ({ |
16 | attributes: { | 16 | attributes: { |
@@ -238,6 +238,19 @@ export class PluginModel extends Model<PluginModel> { | |||
238 | return 'peertube-plugin-' + name | 238 | return 'peertube-plugin-' + name |
239 | } | 239 | } |
240 | 240 | ||
241 | getPublicSettings (registeredSettings: RegisterServerSettingOptions[]) { | ||
242 | const result: { [ name: string ]: string } = {} | ||
243 | const settings = this.settings || {} | ||
244 | |||
245 | for (const r of registeredSettings) { | ||
246 | if (r.private !== false) continue | ||
247 | |||
248 | result[r.name] = settings[r.name] || r.default || null | ||
249 | } | ||
250 | |||
251 | return result | ||
252 | } | ||
253 | |||
241 | toFormattedJSON (): PeerTubePlugin { | 254 | toFormattedJSON (): PeerTubePlugin { |
242 | return { | 255 | return { |
243 | name: this.name, | 256 | name: this.name, |
diff --git a/server/tests/api/check-params/plugins.ts b/server/tests/api/check-params/plugins.ts index 83ce6f451..9553bce17 100644 --- a/server/tests/api/check-params/plugins.ts +++ b/server/tests/api/check-params/plugins.ts | |||
@@ -281,7 +281,7 @@ describe('Test server plugins API validators', function () { | |||
281 | }) | 281 | }) |
282 | }) | 282 | }) |
283 | 283 | ||
284 | describe('When getting a plugin or the registered settings', function () { | 284 | describe('When getting a plugin or the registered settings or public settings', function () { |
285 | const path = '/api/v1/plugins/' | 285 | const path = '/api/v1/plugins/' |
286 | 286 | ||
287 | it('Should fail with an invalid token', async function () { | 287 | it('Should fail with an invalid token', async function () { |
@@ -307,7 +307,7 @@ describe('Test server plugins API validators', function () { | |||
307 | }) | 307 | }) |
308 | 308 | ||
309 | it('Should fail with an invalid npm name', async function () { | 309 | it('Should fail with an invalid npm name', async function () { |
310 | for (const suffix of [ 'toto', 'toto/registered-settings' ]) { | 310 | for (const suffix of [ 'toto', 'toto/registered-settings', 'toto/public-settings' ]) { |
311 | await makeGetRequest({ | 311 | await makeGetRequest({ |
312 | url: server.url, | 312 | url: server.url, |
313 | path: path + suffix, | 313 | path: path + suffix, |
@@ -316,7 +316,7 @@ describe('Test server plugins API validators', function () { | |||
316 | }) | 316 | }) |
317 | } | 317 | } |
318 | 318 | ||
319 | for (const suffix of [ 'peertube-plugin-TOTO', 'peertube-plugin-TOTO/registered-settings' ]) { | 319 | for (const suffix of [ 'peertube-plugin-TOTO', 'peertube-plugin-TOTO/registered-settings', 'peertube-plugin-TOTO/public-settings' ]) { |
320 | await makeGetRequest({ | 320 | await makeGetRequest({ |
321 | url: server.url, | 321 | url: server.url, |
322 | path: path + suffix, | 322 | path: path + suffix, |
@@ -327,7 +327,7 @@ describe('Test server plugins API validators', function () { | |||
327 | }) | 327 | }) |
328 | 328 | ||
329 | it('Should fail with an unknown plugin', async function () { | 329 | it('Should fail with an unknown plugin', async function () { |
330 | for (const suffix of [ 'peertube-plugin-toto', 'peertube-plugin-toto/registered-settings' ]) { | 330 | for (const suffix of [ 'peertube-plugin-toto', 'peertube-plugin-toto/registered-settings', 'peertube-plugin-toto/public-settings' ]) { |
331 | await makeGetRequest({ | 331 | await makeGetRequest({ |
332 | url: server.url, | 332 | url: server.url, |
333 | path: path + suffix, | 333 | path: path + suffix, |
@@ -338,7 +338,7 @@ describe('Test server plugins API validators', function () { | |||
338 | }) | 338 | }) |
339 | 339 | ||
340 | it('Should succeed with the correct parameters', async function () { | 340 | it('Should succeed with the correct parameters', async function () { |
341 | for (const suffix of [ npmPlugin, `${npmPlugin}/registered-settings` ]) { | 341 | for (const suffix of [ npmPlugin, `${npmPlugin}/registered-settings`, `${npmPlugin}/public-settings` ]) { |
342 | await makeGetRequest({ | 342 | await makeGetRequest({ |
343 | url: server.url, | 343 | url: server.url, |
344 | path: path + suffix, | 344 | path: path + suffix, |
diff --git a/server/tests/api/server/plugins.ts b/server/tests/api/server/plugins.ts index f8b2d78c9..b8a8a2fee 100644 --- a/server/tests/api/server/plugins.ts +++ b/server/tests/api/server/plugins.ts | |||
@@ -18,7 +18,7 @@ import { | |||
18 | setPluginVersion, uninstallPlugin, | 18 | setPluginVersion, uninstallPlugin, |
19 | updateCustomSubConfig, updateMyUser, updatePluginPackageJSON, updatePlugin, | 19 | updateCustomSubConfig, updateMyUser, updatePluginPackageJSON, updatePlugin, |
20 | updatePluginSettings, | 20 | updatePluginSettings, |
21 | wait | 21 | wait, getPublicSettings |
22 | } from '../../../../shared/extra-utils' | 22 | } from '../../../../shared/extra-utils' |
23 | import { PluginType } from '../../../../shared/models/plugins/plugin.type' | 23 | import { PluginType } from '../../../../shared/models/plugins/plugin.type' |
24 | import { PeerTubePluginIndex } from '../../../../shared/models/plugins/peertube-plugin-index.model' | 24 | import { PeerTubePluginIndex } from '../../../../shared/models/plugins/peertube-plugin-index.model' |
@@ -27,6 +27,7 @@ import { PeerTubePlugin } from '../../../../shared/models/plugins/peertube-plugi | |||
27 | import { User } from '../../../../shared/models/users' | 27 | import { User } from '../../../../shared/models/users' |
28 | import { PluginPackageJson } from '../../../../shared/models/plugins/plugin-package-json.model' | 28 | import { PluginPackageJson } from '../../../../shared/models/plugins/plugin-package-json.model' |
29 | import { RegisteredServerSettings } from '../../../../shared/models/plugins/register-server-setting.model' | 29 | import { RegisteredServerSettings } from '../../../../shared/models/plugins/register-server-setting.model' |
30 | import { PublicServerSetting } from '../../../../shared/models/plugins/public-server.setting' | ||
30 | 31 | ||
31 | const expect = chai.expect | 32 | const expect = chai.expect |
32 | 33 | ||
@@ -217,14 +218,24 @@ describe('Test plugins', function () { | |||
217 | npmName: 'peertube-plugin-hello-world' | 218 | npmName: 'peertube-plugin-hello-world' |
218 | }) | 219 | }) |
219 | 220 | ||
220 | const settings = (res.body as RegisteredServerSettings).settings | 221 | const registeredSettings = (res.body as RegisteredServerSettings).registeredSettings |
221 | 222 | ||
222 | expect(settings).to.have.length.at.least(1) | 223 | expect(registeredSettings).to.have.length.at.least(1) |
223 | 224 | ||
224 | const adminNameSettings = settings.find(s => s.name === 'admin-name') | 225 | const adminNameSettings = registeredSettings.find(s => s.name === 'admin-name') |
225 | expect(adminNameSettings).to.not.be.undefined | 226 | expect(adminNameSettings).to.not.be.undefined |
226 | }) | 227 | }) |
227 | 228 | ||
229 | it('Should get public settings', async function () { | ||
230 | const res = await getPublicSettings({ url: server.url, npmName: 'peertube-plugin-hello-world' }) | ||
231 | |||
232 | const publicSettings = (res.body as PublicServerSetting).publicSettings | ||
233 | |||
234 | expect(Object.keys(publicSettings)).to.have.lengthOf(1) | ||
235 | expect(Object.keys(publicSettings)).to.deep.equal([ 'user-name' ]) | ||
236 | expect(publicSettings['user-name']).to.be.null | ||
237 | }) | ||
238 | |||
228 | it('Should update the settings', async function () { | 239 | it('Should update the settings', async function () { |
229 | const settings = { | 240 | const settings = { |
230 | 'admin-name': 'Cid' | 241 | 'admin-name': 'Cid' |
diff --git a/shared/extra-utils/server/plugins.ts b/shared/extra-utils/server/plugins.ts index 2302208a8..65d37d69f 100644 --- a/shared/extra-utils/server/plugins.ts +++ b/shared/extra-utils/server/plugins.ts | |||
@@ -119,6 +119,21 @@ function getPluginRegisteredSettings (parameters: { | |||
119 | }) | 119 | }) |
120 | } | 120 | } |
121 | 121 | ||
122 | function getPublicSettings (parameters: { | ||
123 | url: string, | ||
124 | npmName: string, | ||
125 | expectedStatus?: number | ||
126 | }) { | ||
127 | const { url, npmName, expectedStatus = 200 } = parameters | ||
128 | const path = '/api/v1/plugins/' + npmName + '/public-settings' | ||
129 | |||
130 | return makeGetRequest({ | ||
131 | url, | ||
132 | path, | ||
133 | statusCodeExpected: expectedStatus | ||
134 | }) | ||
135 | } | ||
136 | |||
122 | function installPlugin (parameters: { | 137 | function installPlugin (parameters: { |
123 | url: string, | 138 | url: string, |
124 | accessToken: string, | 139 | accessToken: string, |
@@ -218,5 +233,6 @@ export { | |||
218 | getPackageJSONPath, | 233 | getPackageJSONPath, |
219 | updatePluginPackageJSON, | 234 | updatePluginPackageJSON, |
220 | getPluginPackageJSON, | 235 | getPluginPackageJSON, |
221 | getPluginTestPath | 236 | getPluginTestPath, |
237 | getPublicSettings | ||
222 | } | 238 | } |
diff --git a/shared/models/plugins/public-server.setting.ts b/shared/models/plugins/public-server.setting.ts new file mode 100644 index 000000000..9802c4d7d --- /dev/null +++ b/shared/models/plugins/public-server.setting.ts | |||
@@ -0,0 +1,3 @@ | |||
1 | export interface PublicServerSetting { | ||
2 | publicSettings: { [ name: string ]: string } | ||
3 | } | ||
diff --git a/shared/models/plugins/register-server-setting.model.ts b/shared/models/plugins/register-server-setting.model.ts index 5dea93c39..78c5abd1b 100644 --- a/shared/models/plugins/register-server-setting.model.ts +++ b/shared/models/plugins/register-server-setting.model.ts | |||
@@ -2,9 +2,15 @@ export interface RegisterServerSettingOptions { | |||
2 | name: string | 2 | name: string |
3 | label: string | 3 | label: string |
4 | type: 'input' | 4 | type: 'input' |
5 | |||
6 | // If the setting is not private, anyone can view its value | ||
7 | // Mainly used by the PeerTube client to get admin config | ||
8 | private: boolean | ||
9 | |||
10 | // Default setting value | ||
5 | default?: string | 11 | default?: string |
6 | } | 12 | } |
7 | 13 | ||
8 | export interface RegisteredServerSettings { | 14 | export interface RegisteredServerSettings { |
9 | settings: RegisterServerSettingOptions[] | 15 | registeredSettings: RegisterServerSettingOptions[] |
10 | } | 16 | } |