Check auth plugin result
authorChocobozzz <me@florianbigard.com>
Mon, 27 Apr 2020 09:42:01 +0000 (11:42 +0200)
committerChocobozzz <chocobozzz@cpy.re>
Mon, 4 May 2020 14:21:39 +0000 (16:21 +0200)
server/lib/auth.ts
server/tests/fixtures/peertube-plugin-test-id-pass-auth-three/main.js
server/tests/plugins/id-and-pass-auth.ts

index c47ec62d08499140a95cfc50f72fa2e9db35d81b..5a6dd9dec2d3b72fcaea6ed8010a9f8205d6b72d 100644 (file)
@@ -7,6 +7,7 @@ import { logger } from '@server/helpers/logger'
 import { UserRole } from '@shared/models'
 import { revokeToken } from '@server/lib/oauth-model'
 import { OAuthTokenModel } from '@server/models/oauth/oauth-token'
+import { isUserUsernameValid, isUserRoleValid, isUserDisplayNameValid } from '@server/helpers/custom-validators/users'
 
 const oAuthServer = new OAuthServer({
   useErrorHandler: true,
@@ -120,10 +121,12 @@ async function proxifyPasswordGrant (req: express.Request, res: express.Response
 
   for (const pluginAuth of pluginAuths) {
     const authOptions = pluginAuth.registerAuthOptions
+    const authName = authOptions.authName
+    const npmName = pluginAuth.npmName
 
     logger.debug(
       'Using auth method %s of plugin %s to login %s with weight %d.',
-      authOptions.authName, pluginAuth.npmName, loginOptions.id, authOptions.getWeight()
+      authName, npmName, loginOptions.id, authOptions.getWeight()
     )
 
     try {
@@ -131,9 +134,31 @@ async function proxifyPasswordGrant (req: express.Request, res: express.Response
       if (loginResult) {
         logger.info(
           'Login success with auth method %s of plugin %s for %s.',
-          authOptions.authName, pluginAuth.npmName, loginOptions.id
+          authName, npmName, loginOptions.id
         )
 
+        if (!isUserUsernameValid(loginResult.username)) {
+          logger.error('Auth method %s of plugin %s did not provide a valid username.', authName, npmName, { loginResult })
+          continue
+        }
+
+        if (!loginResult.email) {
+          logger.error('Auth method %s of plugin %s did not provide a valid email.', authName, npmName, { loginResult })
+          continue
+        }
+
+        // role is optional
+        if (loginResult.role && !isUserRoleValid(loginResult.role)) {
+          logger.error('Auth method %s of plugin %s did not provide a valid role.', authName, npmName, { loginResult })
+          continue
+        }
+
+        // display name is optional
+        if (loginResult.displayName && !isUserDisplayNameValid(loginResult.displayName)) {
+          logger.error('Auth method %s of plugin %s did not provide a valid display name.', authName, npmName, { loginResult })
+          continue
+        }
+
         res.locals.bypassLogin = {
           bypass: true,
           pluginName: pluginAuth.npmName,
index 372f3fa0c1c0f11aa06baa2edd077df824a46065..caa6a7ccdc4ff471df24f975f145f4fc04ff2ef5 100644 (file)
@@ -23,6 +23,75 @@ async function register ({
       return null
     }
   })
+
+  registerIdAndPassAuth({
+    authName: 'ward-auth',
+
+    getWeight: () => 5,
+
+    login (body) {
+      if (body.id === 'ward') {
+        return Promise.resolve({
+          username: 'ward-42',
+          email: 'ward@example.com'
+        })
+      }
+
+      return null
+    }
+  })
+
+  registerIdAndPassAuth({
+    authName: 'kiros-auth',
+
+    getWeight: () => 5,
+
+    login (body) {
+      if (body.id === 'kiros') {
+        return Promise.resolve({
+          username: 'kiros',
+          email: 'kiros@example.com',
+          displayName: 'a'.repeat(5000)
+        })
+      }
+
+      return null
+    }
+  })
+
+  registerIdAndPassAuth({
+    authName: 'raine-auth',
+
+    getWeight: () => 5,
+
+    login (body) {
+      if (body.id === 'raine') {
+        return Promise.resolve({
+          username: 'raine',
+          email: 'raine@example.com',
+          role: 42
+        })
+      }
+
+      return null
+    }
+  })
+
+  registerIdAndPassAuth({
+    authName: 'ellone-auth',
+
+    getWeight: () => 5,
+
+    login (body) {
+      if (body.id === 'ellone') {
+        return Promise.resolve({
+          username: 'ellone'
+        })
+      }
+
+      return null
+    }
+  })
 }
 
 async function unregister () {
index caf65b55f971b1008f724d1de439fbb7eff2a435..c6382435decb087e495d809ef80ebba0676f92a6 100644 (file)
@@ -151,6 +151,20 @@ describe('Test id and pass auth plugins', function () {
     await getMyUserInformation(server.url, lagunaAccessToken, 401)
   })
 
+  it('Should reject an invalid username, email, role or display name', async function () {
+    await userLogin(server, { username: 'ward', password: 'ward password' }, 400)
+    await waitUntilLog(server, 'valid username')
+
+    await userLogin(server, { username: 'kiros', password: 'kiros password' }, 400)
+    await waitUntilLog(server, 'valid display name')
+
+    await userLogin(server, { username: 'raine', password: 'raine password' }, 400)
+    await waitUntilLog(server, 'valid role')
+
+    await userLogin(server, { username: 'ellone', password: 'elonne password' }, 400)
+    await waitUntilLog(server, 'valid email')
+  })
+
   it('Should uninstall the plugin one and do not login existing Crash', async function () {
     await uninstallPlugin({
       url: server.url,