aboutsummaryrefslogtreecommitdiffhomepage
path: root/server/lib/plugins
diff options
context:
space:
mode:
authorChocobozzz <me@florianbigard.com>2020-04-22 16:07:04 +0200
committerChocobozzz <chocobozzz@cpy.re>2020-05-04 16:21:39 +0200
commit7fed637506043e4432cbebe041ada0625171cceb (patch)
tree07f174e17c4b4a0b3d43a0fa6944865c06234338 /server/lib/plugins
parent8d4197637868d5cde49434e937186b57e40f4b2b (diff)
downloadPeerTube-7fed637506043e4432cbebe041ada0625171cceb.tar.gz
PeerTube-7fed637506043e4432cbebe041ada0625171cceb.tar.zst
PeerTube-7fed637506043e4432cbebe041ada0625171cceb.zip
Begin auth plugin support
Diffstat (limited to 'server/lib/plugins')
-rw-r--r--server/lib/plugins/plugin-manager.ts55
-rw-r--r--server/lib/plugins/register-helpers-store.ts43
2 files changed, 80 insertions, 18 deletions
diff --git a/server/lib/plugins/plugin-manager.ts b/server/lib/plugins/plugin-manager.ts
index 37fb07716..f78b989f5 100644
--- a/server/lib/plugins/plugin-manager.ts
+++ b/server/lib/plugins/plugin-manager.ts
@@ -39,6 +39,7 @@ export interface RegisteredPlugin {
39 css: string[] 39 css: string[]
40 40
41 // Only if this is a plugin 41 // Only if this is a plugin
42 registerHelpersStore?: RegisterHelpersStore
42 unregister?: Function 43 unregister?: Function
43} 44}
44 45
@@ -58,11 +59,10 @@ export class PluginManager implements ServerHook {
58 private static instance: PluginManager 59 private static instance: PluginManager
59 60
60 private registeredPlugins: { [name: string]: RegisteredPlugin } = {} 61 private registeredPlugins: { [name: string]: RegisteredPlugin } = {}
62
61 private hooks: { [name: string]: HookInformationValue[] } = {} 63 private hooks: { [name: string]: HookInformationValue[] } = {}
62 private translations: PluginLocalesTranslations = {} 64 private translations: PluginLocalesTranslations = {}
63 65
64 private registerHelpersStore: { [npmName: string]: RegisterHelpersStore } = {}
65
66 private constructor () { 66 private constructor () {
67 } 67 }
68 68
@@ -102,18 +102,30 @@ export class PluginManager implements ServerHook {
102 return this.getRegisteredPluginsOrThemes(PluginType.THEME) 102 return this.getRegisteredPluginsOrThemes(PluginType.THEME)
103 } 103 }
104 104
105 getIdAndPassAuths () {
106 return this.getRegisteredPlugins()
107 .map(p => ({ npmName: p.npmName, idAndPassAuths: p.registerHelpersStore.getIdAndPassAuths() }))
108 .filter(v => v.idAndPassAuths.length !== 0)
109 }
110
111 getExternalAuths () {
112 return this.getRegisteredPlugins()
113 .map(p => ({ npmName: p.npmName, externalAuths: p.registerHelpersStore.getExternalAuths() }))
114 .filter(v => v.externalAuths.length !== 0)
115 }
116
105 getRegisteredSettings (npmName: string) { 117 getRegisteredSettings (npmName: string) {
106 const store = this.registerHelpersStore[npmName] 118 const result = this.getRegisteredPluginOrTheme(npmName)
107 if (store) return store.getSettings() 119 if (!result || result.type !== PluginType.PLUGIN) return []
108 120
109 return [] 121 return result.registerHelpersStore.getSettings()
110 } 122 }
111 123
112 getRouter (npmName: string) { 124 getRouter (npmName: string) {
113 const store = this.registerHelpersStore[npmName] 125 const result = this.getRegisteredPluginOrTheme(npmName)
114 if (!store) return null 126 if (!result || result.type !== PluginType.PLUGIN) return null
115 127
116 return store.getRouter() 128 return result.registerHelpersStore.getRouter()
117 } 129 }
118 130
119 getTranslations (locale: string) { 131 getTranslations (locale: string) {
@@ -185,11 +197,9 @@ export class PluginManager implements ServerHook {
185 this.hooks[key] = this.hooks[key].filter(h => h.npmName !== npmName) 197 this.hooks[key] = this.hooks[key].filter(h => h.npmName !== npmName)
186 } 198 }
187 199
188 const store = this.registerHelpersStore[plugin.npmName] 200 const store = plugin.registerHelpersStore
189 store.reinitVideoConstants(plugin.npmName) 201 store.reinitVideoConstants(plugin.npmName)
190 202
191 delete this.registerHelpersStore[plugin.npmName]
192
193 logger.info('Regenerating registered plugin CSS to global file.') 203 logger.info('Regenerating registered plugin CSS to global file.')
194 await this.regeneratePluginGlobalCSS() 204 await this.regeneratePluginGlobalCSS()
195 } 205 }
@@ -294,8 +304,11 @@ export class PluginManager implements ServerHook {
294 this.sanitizeAndCheckPackageJSONOrThrow(packageJSON, plugin.type) 304 this.sanitizeAndCheckPackageJSONOrThrow(packageJSON, plugin.type)
295 305
296 let library: PluginLibrary 306 let library: PluginLibrary
307 let registerHelpersStore: RegisterHelpersStore
297 if (plugin.type === PluginType.PLUGIN) { 308 if (plugin.type === PluginType.PLUGIN) {
298 library = await this.registerPlugin(plugin, pluginPath, packageJSON) 309 const result = await this.registerPlugin(plugin, pluginPath, packageJSON)
310 library = result.library
311 registerHelpersStore = result.registerStore
299 } 312 }
300 313
301 const clientScripts: { [id: string]: ClientScript } = {} 314 const clientScripts: { [id: string]: ClientScript } = {}
@@ -314,6 +327,7 @@ export class PluginManager implements ServerHook {
314 staticDirs: packageJSON.staticDirs, 327 staticDirs: packageJSON.staticDirs,
315 clientScripts, 328 clientScripts,
316 css: packageJSON.css, 329 css: packageJSON.css,
330 registerHelpersStore: registerHelpersStore || undefined,
317 unregister: library ? library.unregister : undefined 331 unregister: library ? library.unregister : undefined
318 } 332 }
319 333
@@ -332,15 +346,15 @@ export class PluginManager implements ServerHook {
332 throw new Error('Library code is not valid (miss register or unregister function)') 346 throw new Error('Library code is not valid (miss register or unregister function)')
333 } 347 }
334 348
335 const registerHelpers = this.getRegisterHelpers(npmName, plugin) 349 const { registerOptions, registerStore } = this.getRegisterHelpers(npmName, plugin)
336 library.register(registerHelpers) 350 library.register(registerOptions)
337 .catch(err => logger.error('Cannot register plugin %s.', npmName, { err })) 351 .catch(err => logger.error('Cannot register plugin %s.', npmName, { err }))
338 352
339 logger.info('Add plugin %s CSS to global file.', npmName) 353 logger.info('Add plugin %s CSS to global file.', npmName)
340 354
341 await this.addCSSToGlobalFile(pluginPath, packageJSON.css) 355 await this.addCSSToGlobalFile(pluginPath, packageJSON.css)
342 356
343 return library 357 return { library, registerStore }
344 } 358 }
345 359
346 // ###################### Translations ###################### 360 // ###################### Translations ######################
@@ -440,7 +454,10 @@ export class PluginManager implements ServerHook {
440 454
441 // ###################### Generate register helpers ###################### 455 // ###################### Generate register helpers ######################
442 456
443 private getRegisterHelpers (npmName: string, plugin: PluginModel): RegisterServerOptions { 457 private getRegisterHelpers (
458 npmName: string,
459 plugin: PluginModel
460 ): { registerStore: RegisterHelpersStore, registerOptions: RegisterServerOptions } {
444 const onHookAdded = (options: RegisterServerHookOptions) => { 461 const onHookAdded = (options: RegisterServerHookOptions) => {
445 if (!this.hooks[options.target]) this.hooks[options.target] = [] 462 if (!this.hooks[options.target]) this.hooks[options.target] = []
446 463
@@ -453,9 +470,11 @@ export class PluginManager implements ServerHook {
453 } 470 }
454 471
455 const registerHelpersStore = new RegisterHelpersStore(npmName, plugin, onHookAdded.bind(this)) 472 const registerHelpersStore = new RegisterHelpersStore(npmName, plugin, onHookAdded.bind(this))
456 this.registerHelpersStore[npmName] = registerHelpersStore
457 473
458 return registerHelpersStore.buildRegisterHelpers() 474 return {
475 registerStore: registerHelpersStore,
476 registerOptions: registerHelpersStore.buildRegisterHelpers()
477 }
459 } 478 }
460 479
461 private sanitizeAndCheckPackageJSONOrThrow (packageJSON: PluginPackageJson, pluginType: PluginType) { 480 private sanitizeAndCheckPackageJSONOrThrow (packageJSON: PluginPackageJson, pluginType: PluginType) {
diff --git a/server/lib/plugins/register-helpers-store.ts b/server/lib/plugins/register-helpers-store.ts
index 5ca52b151..7e827401f 100644
--- a/server/lib/plugins/register-helpers-store.ts
+++ b/server/lib/plugins/register-helpers-store.ts
@@ -20,6 +20,12 @@ import { RegisterServerSettingOptions } from '@shared/models/plugins/register-se
20import * as express from 'express' 20import * as express from 'express'
21import { PluginVideoPrivacyManager } from '@shared/models/plugins/plugin-video-privacy-manager.model' 21import { PluginVideoPrivacyManager } from '@shared/models/plugins/plugin-video-privacy-manager.model'
22import { PluginPlaylistPrivacyManager } from '@shared/models/plugins/plugin-playlist-privacy-manager.model' 22import { PluginPlaylistPrivacyManager } from '@shared/models/plugins/plugin-playlist-privacy-manager.model'
23import {
24 RegisterServerAuthExternalOptions,
25 RegisterServerAuthExternalResult,
26 RegisterServerAuthPassOptions
27} from '@shared/models/plugins/register-server-auth.model'
28import { onExternalAuthPlugin } from '@server/lib/auth'
23 29
24type AlterableVideoConstant = 'language' | 'licence' | 'category' | 'privacy' | 'playlistPrivacy' 30type AlterableVideoConstant = 'language' | 'licence' | 'category' | 'privacy' | 'playlistPrivacy'
25type VideoConstant = { [key in number | string]: string } 31type VideoConstant = { [key in number | string]: string }
@@ -42,6 +48,9 @@ export class RegisterHelpersStore {
42 48
43 private readonly settings: RegisterServerSettingOptions[] = [] 49 private readonly settings: RegisterServerSettingOptions[] = []
44 50
51 private readonly idAndPassAuths: RegisterServerAuthPassOptions[] = []
52 private readonly externalAuths: RegisterServerAuthExternalOptions[] = []
53
45 private readonly router: express.Router 54 private readonly router: express.Router
46 55
47 constructor ( 56 constructor (
@@ -69,6 +78,9 @@ export class RegisterHelpersStore {
69 const videoPrivacyManager = this.buildVideoPrivacyManager() 78 const videoPrivacyManager = this.buildVideoPrivacyManager()
70 const playlistPrivacyManager = this.buildPlaylistPrivacyManager() 79 const playlistPrivacyManager = this.buildPlaylistPrivacyManager()
71 80
81 const registerIdAndPassAuth = this.buildRegisterIdAndPassAuth()
82 const registerExternalAuth = this.buildRegisterExternalAuth()
83
72 const peertubeHelpers = buildPluginHelpers(this.npmName) 84 const peertubeHelpers = buildPluginHelpers(this.npmName)
73 85
74 return { 86 return {
@@ -87,6 +99,9 @@ export class RegisterHelpersStore {
87 videoPrivacyManager, 99 videoPrivacyManager,
88 playlistPrivacyManager, 100 playlistPrivacyManager,
89 101
102 registerIdAndPassAuth,
103 registerExternalAuth,
104
90 peertubeHelpers 105 peertubeHelpers
91 } 106 }
92 } 107 }
@@ -125,6 +140,14 @@ export class RegisterHelpersStore {
125 return this.router 140 return this.router
126 } 141 }
127 142
143 getIdAndPassAuths () {
144 return this.idAndPassAuths
145 }
146
147 getExternalAuths () {
148 return this.externalAuths
149 }
150
128 private buildGetRouter () { 151 private buildGetRouter () {
129 return () => this.router 152 return () => this.router
130 } 153 }
@@ -146,6 +169,26 @@ export class RegisterHelpersStore {
146 } 169 }
147 } 170 }
148 171
172 private buildRegisterIdAndPassAuth () {
173 return (options: RegisterServerAuthPassOptions) => {
174 this.idAndPassAuths.push(options)
175 }
176 }
177
178 private buildRegisterExternalAuth () {
179 const self = this
180
181 return (options: RegisterServerAuthExternalOptions) => {
182 this.externalAuths.push(options)
183
184 return {
185 onAuth (options: { username: string, email: string }): void {
186 onExternalAuthPlugin(self.npmName, options.username, options.email)
187 }
188 } as RegisterServerAuthExternalResult
189 }
190 }
191
149 private buildSettingsManager (): PluginSettingsManager { 192 private buildSettingsManager (): PluginSettingsManager {
150 return { 193 return {
151 getSetting: (name: string) => PluginModel.getSetting(this.plugin.name, this.plugin.type, name), 194 getSetting: (name: string) => PluginModel.getSetting(this.plugin.name, this.plugin.type, name),