From 7fed637506043e4432cbebe041ada0625171cceb Mon Sep 17 00:00:00 2001 From: Chocobozzz Date: Wed, 22 Apr 2020 16:07:04 +0200 Subject: Begin auth plugin support --- server/lib/plugins/plugin-manager.ts | 55 +++++++++++++++++++--------- server/lib/plugins/register-helpers-store.ts | 43 ++++++++++++++++++++++ 2 files changed, 80 insertions(+), 18 deletions(-) (limited to 'server/lib/plugins') 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 { css: string[] // Only if this is a plugin + registerHelpersStore?: RegisterHelpersStore unregister?: Function } @@ -58,11 +59,10 @@ export class PluginManager implements ServerHook { private static instance: PluginManager private registeredPlugins: { [name: string]: RegisteredPlugin } = {} + private hooks: { [name: string]: HookInformationValue[] } = {} private translations: PluginLocalesTranslations = {} - private registerHelpersStore: { [npmName: string]: RegisterHelpersStore } = {} - private constructor () { } @@ -102,18 +102,30 @@ export class PluginManager implements ServerHook { return this.getRegisteredPluginsOrThemes(PluginType.THEME) } + getIdAndPassAuths () { + return this.getRegisteredPlugins() + .map(p => ({ npmName: p.npmName, idAndPassAuths: p.registerHelpersStore.getIdAndPassAuths() })) + .filter(v => v.idAndPassAuths.length !== 0) + } + + getExternalAuths () { + return this.getRegisteredPlugins() + .map(p => ({ npmName: p.npmName, externalAuths: p.registerHelpersStore.getExternalAuths() })) + .filter(v => v.externalAuths.length !== 0) + } + getRegisteredSettings (npmName: string) { - const store = this.registerHelpersStore[npmName] - if (store) return store.getSettings() + const result = this.getRegisteredPluginOrTheme(npmName) + if (!result || result.type !== PluginType.PLUGIN) return [] - return [] + return result.registerHelpersStore.getSettings() } getRouter (npmName: string) { - const store = this.registerHelpersStore[npmName] - if (!store) return null + const result = this.getRegisteredPluginOrTheme(npmName) + if (!result || result.type !== PluginType.PLUGIN) return null - return store.getRouter() + return result.registerHelpersStore.getRouter() } getTranslations (locale: string) { @@ -185,11 +197,9 @@ export class PluginManager implements ServerHook { this.hooks[key] = this.hooks[key].filter(h => h.npmName !== npmName) } - const store = this.registerHelpersStore[plugin.npmName] + const store = plugin.registerHelpersStore store.reinitVideoConstants(plugin.npmName) - delete this.registerHelpersStore[plugin.npmName] - logger.info('Regenerating registered plugin CSS to global file.') await this.regeneratePluginGlobalCSS() } @@ -294,8 +304,11 @@ export class PluginManager implements ServerHook { this.sanitizeAndCheckPackageJSONOrThrow(packageJSON, plugin.type) let library: PluginLibrary + let registerHelpersStore: RegisterHelpersStore if (plugin.type === PluginType.PLUGIN) { - library = await this.registerPlugin(plugin, pluginPath, packageJSON) + const result = await this.registerPlugin(plugin, pluginPath, packageJSON) + library = result.library + registerHelpersStore = result.registerStore } const clientScripts: { [id: string]: ClientScript } = {} @@ -314,6 +327,7 @@ export class PluginManager implements ServerHook { staticDirs: packageJSON.staticDirs, clientScripts, css: packageJSON.css, + registerHelpersStore: registerHelpersStore || undefined, unregister: library ? library.unregister : undefined } @@ -332,15 +346,15 @@ export class PluginManager implements ServerHook { throw new Error('Library code is not valid (miss register or unregister function)') } - const registerHelpers = this.getRegisterHelpers(npmName, plugin) - library.register(registerHelpers) + const { registerOptions, registerStore } = this.getRegisterHelpers(npmName, plugin) + library.register(registerOptions) .catch(err => logger.error('Cannot register plugin %s.', npmName, { err })) logger.info('Add plugin %s CSS to global file.', npmName) await this.addCSSToGlobalFile(pluginPath, packageJSON.css) - return library + return { library, registerStore } } // ###################### Translations ###################### @@ -440,7 +454,10 @@ export class PluginManager implements ServerHook { // ###################### Generate register helpers ###################### - private getRegisterHelpers (npmName: string, plugin: PluginModel): RegisterServerOptions { + private getRegisterHelpers ( + npmName: string, + plugin: PluginModel + ): { registerStore: RegisterHelpersStore, registerOptions: RegisterServerOptions } { const onHookAdded = (options: RegisterServerHookOptions) => { if (!this.hooks[options.target]) this.hooks[options.target] = [] @@ -453,9 +470,11 @@ export class PluginManager implements ServerHook { } const registerHelpersStore = new RegisterHelpersStore(npmName, plugin, onHookAdded.bind(this)) - this.registerHelpersStore[npmName] = registerHelpersStore - return registerHelpersStore.buildRegisterHelpers() + return { + registerStore: registerHelpersStore, + registerOptions: registerHelpersStore.buildRegisterHelpers() + } } 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 import * as express from 'express' import { PluginVideoPrivacyManager } from '@shared/models/plugins/plugin-video-privacy-manager.model' import { PluginPlaylistPrivacyManager } from '@shared/models/plugins/plugin-playlist-privacy-manager.model' +import { + RegisterServerAuthExternalOptions, + RegisterServerAuthExternalResult, + RegisterServerAuthPassOptions +} from '@shared/models/plugins/register-server-auth.model' +import { onExternalAuthPlugin } from '@server/lib/auth' type AlterableVideoConstant = 'language' | 'licence' | 'category' | 'privacy' | 'playlistPrivacy' type VideoConstant = { [key in number | string]: string } @@ -42,6 +48,9 @@ export class RegisterHelpersStore { private readonly settings: RegisterServerSettingOptions[] = [] + private readonly idAndPassAuths: RegisterServerAuthPassOptions[] = [] + private readonly externalAuths: RegisterServerAuthExternalOptions[] = [] + private readonly router: express.Router constructor ( @@ -69,6 +78,9 @@ export class RegisterHelpersStore { const videoPrivacyManager = this.buildVideoPrivacyManager() const playlistPrivacyManager = this.buildPlaylistPrivacyManager() + const registerIdAndPassAuth = this.buildRegisterIdAndPassAuth() + const registerExternalAuth = this.buildRegisterExternalAuth() + const peertubeHelpers = buildPluginHelpers(this.npmName) return { @@ -87,6 +99,9 @@ export class RegisterHelpersStore { videoPrivacyManager, playlistPrivacyManager, + registerIdAndPassAuth, + registerExternalAuth, + peertubeHelpers } } @@ -125,6 +140,14 @@ export class RegisterHelpersStore { return this.router } + getIdAndPassAuths () { + return this.idAndPassAuths + } + + getExternalAuths () { + return this.externalAuths + } + private buildGetRouter () { return () => this.router } @@ -146,6 +169,26 @@ export class RegisterHelpersStore { } } + private buildRegisterIdAndPassAuth () { + return (options: RegisterServerAuthPassOptions) => { + this.idAndPassAuths.push(options) + } + } + + private buildRegisterExternalAuth () { + const self = this + + return (options: RegisterServerAuthExternalOptions) => { + this.externalAuths.push(options) + + return { + onAuth (options: { username: string, email: string }): void { + onExternalAuthPlugin(self.npmName, options.username, options.email) + } + } as RegisterServerAuthExternalResult + } + } + private buildSettingsManager (): PluginSettingsManager { return { getSetting: (name: string) => PluginModel.getSetting(this.plugin.name, this.plugin.type, name), -- cgit v1.2.3