Add ability to unregister plugin auths
authorChocobozzz <me@florianbigard.com>
Thu, 30 Apr 2020 08:03:09 +0000 (10:03 +0200)
committerChocobozzz <chocobozzz@cpy.re>
Mon, 4 May 2020 14:21:39 +0000 (16:21 +0200)
client/src/app/core/auth/auth.service.ts
server/lib/plugins/register-helpers-store.ts
server/tests/fixtures/peertube-plugin-test-external-auth-one/main.js
server/tests/fixtures/peertube-plugin-test-id-pass-auth-one/main.js
server/tests/plugins/external-auth.ts
server/tests/plugins/id-and-pass-auth.ts
server/typings/plugins/register-server-option.model.ts

index e624c6a202695aed265437f37caed232ed0e1732..de8c509d1d6a3d7345792fafe50aa7c35ac06f96 100644 (file)
@@ -181,7 +181,6 @@ export class AuthService {
       err => console.error(err)
     )
 
-
     this.user = null
 
     AuthUser.flush()
index 6317ac2cf0f149665c19a8aea77b031a566e1da7..a3ec7ef6a0eb521964df925aa439d0f41d4ebb4b 100644 (file)
@@ -49,8 +49,8 @@ export class RegisterHelpersStore {
 
   private readonly settings: RegisterServerSettingOptions[] = []
 
-  private readonly idAndPassAuths: RegisterServerAuthPassOptions[] = []
-  private readonly externalAuths: RegisterServerAuthExternalOptions[] = []
+  private idAndPassAuths: RegisterServerAuthPassOptions[] = []
+  private externalAuths: RegisterServerAuthExternalOptions[] = []
 
   private readonly onSettingsChangeCallbacks: ((settings: any) => void)[] = []
 
@@ -83,6 +83,8 @@ export class RegisterHelpersStore {
 
     const registerIdAndPassAuth = this.buildRegisterIdAndPassAuth()
     const registerExternalAuth = this.buildRegisterExternalAuth()
+    const unregisterIdAndPassAuth = this.buildUnregisterIdAndPassAuth()
+    const unregisterExternalAuth = this.buildUnregisterExternalAuth()
 
     const peertubeHelpers = buildPluginHelpers(this.npmName)
 
@@ -104,6 +106,8 @@ export class RegisterHelpersStore {
 
       registerIdAndPassAuth,
       registerExternalAuth,
+      unregisterIdAndPassAuth,
+      unregisterExternalAuth,
 
       peertubeHelpers
     }
@@ -179,7 +183,7 @@ export class RegisterHelpersStore {
   private buildRegisterIdAndPassAuth () {
     return (options: RegisterServerAuthPassOptions) => {
       if (!options.authName || typeof options.getWeight !== 'function' || typeof options.login !== 'function') {
-        logger.error('Cannot register auth plugin %s: authName of getWeight or login are not valid.', this.npmName)
+        logger.error('Cannot register auth plugin %s: authName, getWeight or login are not valid.', this.npmName, { options })
         return
       }
 
@@ -192,7 +196,7 @@ export class RegisterHelpersStore {
 
     return (options: RegisterServerAuthExternalOptions) => {
       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)
+        logger.error('Cannot register auth plugin %s: authName, authDisplayName or onAuthRequest are not valid.', this.npmName, { options })
         return
       }
 
@@ -212,6 +216,18 @@ export class RegisterHelpersStore {
     }
   }
 
+  private buildUnregisterExternalAuth () {
+    return (authName: string) => {
+      this.externalAuths = this.externalAuths.filter(a => a.authName !== authName)
+    }
+  }
+
+  private buildUnregisterIdAndPassAuth () {
+    return (authName: string) => {
+      this.idAndPassAuths = this.idAndPassAuths.filter(a => a.authName !== authName)
+    }
+  }
+
   private buildSettingsManager (): PluginSettingsManager {
     return {
       getSetting: (name: string) => PluginModel.getSetting(this.plugin.name, this.plugin.type, name),
index 91c67e55046868b69be7a150ec6144e26abdf49b..c65b8d3a8f618af61d92712a947fc348549966ec 100644 (file)
@@ -1,6 +1,8 @@
 async function register ({
   registerExternalAuth,
-  peertubeHelpers
+  peertubeHelpers,
+  settingsManager,
+  unregisterExternalAuth
 }) {
   {
     const result = registerExternalAuth({
@@ -53,6 +55,12 @@ async function register ({
       }
     })
   }
+
+  settingsManager.onSettingsChange(settings => {
+    if (settings.disableKefka) {
+      unregisterExternalAuth('external-auth-2')
+    }
+  })
 }
 
 async function unregister () {
index 9fc12a3e33c59bc7305ee7d720378738cf1a598f..f58faa8471472ba3eec93dd138fcd46d66604f83 100644 (file)
@@ -1,6 +1,8 @@
 async function register ({
   registerIdAndPassAuth,
-  peertubeHelpers
+  peertubeHelpers,
+  settingsManager,
+  unregisterIdAndPassAuth
 }) {
   registerIdAndPassAuth({
     authName: 'spyro-auth',
@@ -47,6 +49,12 @@ async function register ({
       return null
     }
   })
+
+  settingsManager.onSettingsChange(settings => {
+    if (settings.disableSpyro) {
+      unregisterIdAndPassAuth('spyro-auth')
+    }
+  })
 }
 
 async function unregister () {
index a72b2829b5e535d167c268c9af116234842747f9..3125615388f099e68a8d5d0940d774d3198775f8 100644 (file)
@@ -16,7 +16,9 @@ import {
   setAccessTokensToServers,
   uninstallPlugin,
   updateMyUser,
-  wait
+  wait,
+  userLogin,
+  updatePluginSettings
 } from '../../../shared/extra-utils'
 import { cleanupTests, flushAndRunServer, ServerInfo, waitUntilLog } from '../../../shared/extra-utils/server/servers'
 
@@ -258,6 +260,40 @@ describe('Test external auth plugins', function () {
     await getMyUserInformation(server.url, kefkaAccessToken, 401)
   })
 
+  it('Should unregister external-auth-2 and do not login existing Kefka', async function () {
+    await updatePluginSettings({
+      url: server.url,
+      accessToken: server.accessToken,
+      npmName: 'peertube-plugin-test-external-auth-one',
+      settings: { disableKefka: true }
+    })
+
+    await userLogin(server, { username: 'kefka', password: 'fake' }, 400)
+
+    await loginExternal({
+      server,
+      npmName: 'test-external-auth-one',
+      authName: 'external-auth-2',
+      query: {
+        username: 'kefka'
+      },
+      username: 'kefka',
+      statusCodeExpected: 404
+    })
+  })
+
+  it('Should have disabled this auth', async function () {
+    const res = await getConfig(server.url)
+
+    const config: ServerConfig = res.body
+
+    const auths = config.plugin.registeredExternalAuths
+    expect(auths).to.have.lengthOf(2)
+
+    const auth1 = auths.find(a => a.authName === 'external-auth-2')
+    expect(auth1).to.not.exist
+  })
+
   it('Should uninstall the plugin one and do not login Cyan', async function () {
     await uninstallPlugin({
       url: server.url,
index 6c10730aafc8f1a628f20704422492be3ac45a4d..97df4c1fd50c2d25536f3b761b89a7e9a10ae2bf 100644 (file)
@@ -12,7 +12,7 @@ import {
   updateMyUser,
   userLogin,
   wait,
-  login, refreshToken, getConfig
+  login, refreshToken, getConfig, updatePluginSettings
 } from '../../../shared/extra-utils'
 import { User, UserRole, ServerConfig } from '@shared/models'
 import { expect } from 'chai'
@@ -179,6 +179,30 @@ describe('Test id and pass auth plugins', function () {
     await waitUntilLog(server, 'valid email')
   })
 
+  it('Should unregister spyro-auth and do not login existing Spyro', async function () {
+    await updatePluginSettings({
+      url: server.url,
+      accessToken: server.accessToken,
+      npmName: 'peertube-plugin-test-id-pass-auth-one',
+      settings: { disableSpyro: true }
+    })
+
+    await userLogin(server, { username: 'spyro', password: 'spyro password' }, 400)
+    await userLogin(server, { username: 'spyro', password: 'fake' }, 400)
+  })
+
+  it('Should have disabled this auth', async function () {
+    const res = await getConfig(server.url)
+
+    const config: ServerConfig = res.body
+
+    const auths = config.plugin.registeredIdAndPassAuths
+    expect(auths).to.have.lengthOf(7)
+
+    const spyroAuth = auths.find(a => a.authName === 'spyro-auth')
+    expect(spyroAuth).to.not.exist
+  })
+
   it('Should uninstall the plugin one and do not login existing Crash', async function () {
     await uninstallPlugin({
       url: server.url,
index c1e63316d3000e27aeca6c6bd8b4ec15a2fe86bb..7f933b43aa4f602eeabf21239d13a41936785029 100644 (file)
@@ -49,6 +49,8 @@ export type RegisterServerOptions = {
 
   registerIdAndPassAuth: (options: RegisterServerAuthPassOptions) => void
   registerExternalAuth: (options: RegisterServerAuthExternalOptions) => RegisterServerAuthExternalResult
+  unregisterIdAndPassAuth: (authName: string) => void
+  unregisterExternalAuth: (authName: string) => void
 
   // Get plugin router to create custom routes
   // Base routes of this router are