Browse Source

Ensure user is owned by plugin before updating it

Chocobozzz 5 months ago
parent
commit
4fd8d34175

+ 23 - 0
packages/tests/src/plugins/id-and-pass-auth.ts

@@ -242,6 +242,29 @@ describe('Test id and pass auth plugins', function () {
     expect(laguna.pluginAuth).to.equal('peertube-plugin-test-id-pass-auth-two')
   })
 
+  it('Should not update a user if not owned by the plugin auth', async function () {
+    {
+      await server.users.update({ userId: lagunaId, videoQuota: 43000, password: 'coucou', pluginAuth: null })
+
+      const body = await server.users.get({ userId: lagunaId })
+      expect(body.videoQuota).to.equal(43000)
+      expect(body.pluginAuth).to.be.null
+    }
+
+    {
+      await server.login.login({
+        user: { username: 'laguna', password: 'laguna password' },
+        expectedStatus: HttpStatusCode.BAD_REQUEST_400
+      })
+    }
+
+    {
+      const body = await server.users.get({ userId: lagunaId })
+      expect(body.videoQuota).to.equal(43000)
+      expect(body.pluginAuth).to.be.null
+    }
+  })
+
   after(async function () {
     await cleanupTests([ server ])
   })

+ 5 - 2
server/core/lib/auth/oauth-model.ts

@@ -89,8 +89,11 @@ async function getUser (usernameOrEmail?: string, password?: string, bypassLogin
 
     let user = await UserModel.loadByEmail(bypassLogin.user.email)
 
-    if (!user) user = await createUserFromExternal(bypassLogin.pluginName, bypassLogin.user)
-    else user = await updateUserFromExternal(user, bypassLogin.user, bypassLogin.userUpdater)
+    if (!user) {
+      user = await createUserFromExternal(bypassLogin.pluginName, bypassLogin.user)
+    } else if (user.pluginAuth === bypassLogin.pluginName) {
+      user = await updateUserFromExternal(user, bypassLogin.user, bypassLogin.userUpdater)
+    }
 
     // Cannot create a user
     if (!user) throw new AccessDeniedError('Cannot create such user: an actor with that name already exists.')

+ 2 - 0
server/core/models/user/user.ts

@@ -873,6 +873,8 @@ export class UserModel extends Model<Partial<AttributesOnly<UserModel>>> {
   }
 
   isPasswordMatch (password: string) {
+    if (!password || !this.password) return false
+
     return comparePassword(password, this.password)
   }