]> git.immae.eu Git - github/Chocobozzz/PeerTube.git/commitdiff
Provide express request to onLogout call
authorChocobozzz <chocobozzz@framasoft.org>
Fri, 20 Nov 2020 14:36:43 +0000 (15:36 +0100)
committerChocobozzz <chocobozzz@framasoft.org>
Fri, 20 Nov 2020 14:36:43 +0000 (15:36 +0100)
+ pluginInfo related changes

client/src/app/core/auth/auth.service.ts
server/lib/auth.ts
server/lib/oauth-model.ts
server/lib/plugins/plugin-manager.ts
server/tests/fixtures/peertube-plugin-test-external-auth-three/main.js [new file with mode: 0644]
server/tests/fixtures/peertube-plugin-test-external-auth-three/package.json [new file with mode: 0644]
server/tests/plugins/external-auth.ts
server/types/plugins/register-server-auth.model.ts

index 3410c5a6fe92af5760c0e8fb6509caab116cd073..fd6062d3fbdb864aecbc0398f12c5803235f65a6 100644 (file)
@@ -167,9 +167,13 @@ Ensure you have correctly configured PeerTube (config/ directory), in particular
     const authHeaderValue = this.getRequestHeaderValue()
     const headers = new HttpHeaders().set('Authorization', authHeaderValue)
 
-    this.http.post<void>(AuthService.BASE_REVOKE_TOKEN_URL, {}, { headers })
+    this.http.post<{ redirectUrl?: string }>(AuthService.BASE_REVOKE_TOKEN_URL, {}, { headers })
     .subscribe(
-      () => { /* nothing to do */ },
+      res => {
+        if (res.redirectUrl) {
+          window.location.href = res.redirectUrl
+        }
+      },
 
       err => console.error(err)
     )
index 3f8e186334bef7d6b01eb79b6a015ab6cad7bfe7..acf0da18a6740e20a0567a1394d32a78e95095cd 100644 (file)
@@ -52,7 +52,7 @@ async function handleTokenRevocation (req: express.Request, res: express.Respons
   const token = res.locals.oauth.token
 
   res.locals.explicitLogout = true
-  await revokeToken(token)
+  const result = await revokeToken(token)
 
   // FIXME: uncomment when https://github.com/oauthjs/node-oauth2-server/pull/289 is released
   // oAuthServer.revoke(req, res, err => {
@@ -68,7 +68,7 @@ async function handleTokenRevocation (req: express.Request, res: express.Respons
   //   }
   // })
 
-  return res.json()
+  return res.json(result)
 }
 
 async function onExternalUserAuthenticated (options: {
index 3273c6c2d485bacc345db5da47afe1f6ea5be024..f7ea98b4174cee8854dd827e55319a8b19daff36 100644 (file)
@@ -141,13 +141,15 @@ async function getUser (usernameOrEmail?: string, password?: string) {
   return user
 }
 
-async function revokeToken (tokenInfo: { refreshToken: string }) {
+async function revokeToken (tokenInfo: { refreshToken: string }): Promise<{ success: boolean, redirectUrl?: string }> {
   const res: express.Response = this.request.res
   const token = await OAuthTokenModel.getByRefreshTokenAndPopulateUser(tokenInfo.refreshToken)
 
   if (token) {
+    let redirectUrl: string
+
     if (res.locals.explicitLogout === true && token.User.pluginAuth && token.authName) {
-      PluginManager.Instance.onLogout(token.User.pluginAuth, token.authName, token.User)
+      redirectUrl = await PluginManager.Instance.onLogout(token.User.pluginAuth, token.authName, token.User, this.request)
     }
 
     clearCacheByToken(token.accessToken)
@@ -155,10 +157,10 @@ async function revokeToken (tokenInfo: { refreshToken: string }) {
     token.destroy()
          .catch(err => logger.error('Cannot destroy token when revoking token.', { err }))
 
-    return true
+    return { success: true, redirectUrl }
   }
 
-  return false
+  return { success: false }
 }
 
 async function saveToken (token: TokenInfo, client: OAuthClientModel, user: UserModel) {
index 94b5ecc4114039b5c1bbe26d4efa20e98166e33b..8e74912570e1ab7c9bd3d682f5c4863507a9510e 100644 (file)
@@ -1,3 +1,4 @@
+import * as express from 'express'
 import { createReadStream, createWriteStream } from 'fs'
 import { outputFile, readJSON } from 'fs-extra'
 import { basename, join } from 'path'
@@ -166,18 +167,25 @@ export class PluginManager implements ServerHook {
 
   // ###################### External events ######################
 
-  onLogout (npmName: string, authName: string, user: MUser) {
+  async onLogout (npmName: string, authName: string, user: MUser, req: express.Request) {
     const auth = this.getAuth(npmName, authName)
 
     if (auth?.onLogout) {
       logger.info('Running onLogout function from auth %s of plugin %s', authName, npmName)
 
       try {
-        auth.onLogout(user)
+        // Force await, in case or onLogout returns a promise
+        const result = await auth.onLogout(user, req)
+
+        return typeof result === 'string'
+          ? result
+          : undefined
       } catch (err) {
         logger.warn('Cannot run onLogout function from auth %s of plugin %s.', authName, npmName, { err })
       }
     }
+
+    return undefined
   }
 
   onSettingsChanged (name: string, settings: any) {
diff --git a/server/tests/fixtures/peertube-plugin-test-external-auth-three/main.js b/server/tests/fixtures/peertube-plugin-test-external-auth-three/main.js
new file mode 100644 (file)
index 0000000..30cedcc
--- /dev/null
@@ -0,0 +1,53 @@
+async function register ({
+  registerExternalAuth,
+  peertubeHelpers
+}) {
+  {
+    const result = registerExternalAuth({
+      authName: 'external-auth-7',
+      authDisplayName: () => 'External Auth 7',
+      onAuthRequest: (req, res) => {
+        result.userAuthenticated({
+          req,
+          res,
+          username: 'cid',
+          email: 'cid@example.com',
+          displayName: 'Cid Marquez'
+        })
+      },
+      onLogout: (user, req) => {
+        return 'https://example.com/redirectUrl'
+      }
+    })
+  }
+
+  {
+    const result = registerExternalAuth({
+      authName: 'external-auth-8',
+      authDisplayName: () => 'External Auth 8',
+      onAuthRequest: (req, res) => {
+        result.userAuthenticated({
+          req,
+          res,
+          username: 'cid',
+          email: 'cid@example.com',
+          displayName: 'Cid Marquez'
+        })
+      },
+      onLogout: (user, req) => {
+        return 'https://example.com/redirectUrl?access_token=' + req.headers['authorization'].split(' ')[1]
+      }
+    })
+  }
+}
+
+async function unregister () {
+
+}
+
+module.exports = {
+  register,
+  unregister
+}
+
+// ###########################################################################
diff --git a/server/tests/fixtures/peertube-plugin-test-external-auth-three/package.json b/server/tests/fixtures/peertube-plugin-test-external-auth-three/package.json
new file mode 100644 (file)
index 0000000..f323d18
--- /dev/null
@@ -0,0 +1,20 @@
+{
+  "name": "peertube-plugin-test-external-auth-three",
+  "version": "0.0.1",
+  "description": "External auth three",
+  "engine": {
+    "peertube": ">=1.3.0"
+  },
+  "keywords": [
+    "peertube",
+    "plugin"
+  ],
+  "homepage": "https://github.com/Chocobozzz/PeerTube",
+  "author": "Chocobozzz",
+  "bugs": "https://github.com/Chocobozzz/PeerTube/issues",
+  "library": "./main.js",
+  "staticDirs": {},
+  "css": [],
+  "clientScripts": [],
+  "translations": {}
+}
index 57361be05a84763b70c71a84b4b03b05b4129fe5..6d907cc515cf92db727726e0759e5f663e0e5662 100644 (file)
@@ -73,7 +73,7 @@ describe('Test external auth plugins', function () {
     server = await flushAndRunServer(1)
     await setAccessTokensToServers([ server ])
 
-    for (const suffix of [ 'one', 'two' ]) {
+    for (const suffix of [ 'one', 'two', 'three' ]) {
       await installPlugin({
         url: server.url,
         accessToken: server.accessToken,
@@ -88,7 +88,7 @@ describe('Test external auth plugins', function () {
     const config: ServerConfig = res.body
 
     const auths = config.plugin.registeredExternalAuths
-    expect(auths).to.have.lengthOf(6)
+    expect(auths).to.have.lengthOf(8)
 
     const auth2 = auths.find((a) => a.authName === 'external-auth-2')
     expect(auth2).to.exist
@@ -301,7 +301,7 @@ describe('Test external auth plugins', function () {
     const config: ServerConfig = res.body
 
     const auths = config.plugin.registeredExternalAuths
-    expect(auths).to.have.lengthOf(5)
+    expect(auths).to.have.lengthOf(7)
 
     const auth1 = auths.find(a => a.authName === 'external-auth-2')
     expect(auth1).to.not.exist
@@ -371,7 +371,7 @@ describe('Test external auth plugins', function () {
     const config: ServerConfig = res.body
 
     const auths = config.plugin.registeredExternalAuths
-    expect(auths).to.have.lengthOf(4)
+    expect(auths).to.have.lengthOf(6)
 
     const auth2 = auths.find((a) => a.authName === 'external-auth-2')
     expect(auth2).to.not.exist
@@ -380,4 +380,30 @@ describe('Test external auth plugins', function () {
   after(async function () {
     await cleanupTests([ server ])
   })
+
+  it('Should forward the redirectUrl if the plugin returns one', async function () {
+    const resLogin = await loginExternal({
+      server,
+      npmName: 'test-external-auth-three',
+      authName: 'external-auth-7',
+      username: 'cid'
+    })
+
+    const resLogout = await logout(server.url, resLogin.access_token)
+
+    expect(resLogout.body.redirectUrl).to.equal('https://example.com/redirectUrl')
+  })
+
+  it('Should call the plugin\'s onLogout method with the request', async function () {
+    const resLogin = await loginExternal({
+      server,
+      npmName: 'test-external-auth-three',
+      authName: 'external-auth-8',
+      username: 'cid'
+    })
+
+    const resLogout = await logout(server.url, resLogin.access_token)
+
+    expect(resLogout.body.redirectUrl).to.equal('https://example.com/redirectUrl?access_token=' + resLogin.access_token)
+  })
 })
index 31c71b0d01d905a6d3c53677ae960ac845f391c5..3e1a5aeba1ba0c736033eaad8357607f608f4dcf 100644 (file)
@@ -21,7 +21,8 @@ interface RegisterServerAuthBase {
   authName: string
 
   // Called by PeerTube when a user from your plugin logged out
-  onLogout?(user: MUser): void
+  // Returns a redirectUrl sent to the client or nothing
+  onLogout?(user: MUser, req: express.Request): Promise<string>
 
   // Your plugin can hook PeerTube access/refresh token validity
   // So you can control for your plugin the user session lifetime