diff options
author | Chocobozzz <me@florianbigard.com> | 2022-12-30 10:12:20 +0100 |
---|---|---|
committer | Chocobozzz <me@florianbigard.com> | 2023-01-04 11:41:29 +0100 |
commit | 60b880acdfa85eab5c9ec09ba1283f82ae58ec85 (patch) | |
tree | 3c89db53ea9a00e61121d76672bd931eb6d1a84a /server/lib/auth/oauth-model.ts | |
parent | 7e0c26066a5c59af742ae56bddaff9635debe034 (diff) | |
download | PeerTube-60b880acdfa85eab5c9ec09ba1283f82ae58ec85.tar.gz PeerTube-60b880acdfa85eab5c9ec09ba1283f82ae58ec85.tar.zst PeerTube-60b880acdfa85eab5c9ec09ba1283f82ae58ec85.zip |
External auth can update user on login
Diffstat (limited to 'server/lib/auth/oauth-model.ts')
-rw-r--r-- | server/lib/auth/oauth-model.ts | 53 |
1 files changed, 52 insertions, 1 deletions
diff --git a/server/lib/auth/oauth-model.ts b/server/lib/auth/oauth-model.ts index 603cc0f5f..43909284f 100644 --- a/server/lib/auth/oauth-model.ts +++ b/server/lib/auth/oauth-model.ts | |||
@@ -1,10 +1,13 @@ | |||
1 | import express from 'express' | 1 | import express from 'express' |
2 | import { AccessDeniedError } from '@node-oauth/oauth2-server' | 2 | import { AccessDeniedError } from '@node-oauth/oauth2-server' |
3 | import { PluginManager } from '@server/lib/plugins/plugin-manager' | 3 | import { PluginManager } from '@server/lib/plugins/plugin-manager' |
4 | import { AccountModel } from '@server/models/account/account' | ||
5 | import { AuthenticatedResultUpdaterFieldName, RegisterServerAuthenticatedResult } from '@server/types' | ||
4 | import { MOAuthClient } from '@server/types/models' | 6 | import { MOAuthClient } from '@server/types/models' |
5 | import { MOAuthTokenUser } from '@server/types/models/oauth/oauth-token' | 7 | import { MOAuthTokenUser } from '@server/types/models/oauth/oauth-token' |
6 | import { MUser } from '@server/types/models/user/user' | 8 | import { MUser, MUserDefault } from '@server/types/models/user/user' |
7 | import { pick } from '@shared/core-utils' | 9 | import { pick } from '@shared/core-utils' |
10 | import { AttributesOnly } from '@shared/typescript-utils' | ||
8 | import { logger } from '../../helpers/logger' | 11 | import { logger } from '../../helpers/logger' |
9 | import { CONFIG } from '../../initializers/config' | 12 | import { CONFIG } from '../../initializers/config' |
10 | import { OAuthClientModel } from '../../models/oauth/oauth-client' | 13 | import { OAuthClientModel } from '../../models/oauth/oauth-client' |
@@ -27,6 +30,7 @@ export type BypassLogin = { | |||
27 | pluginName: string | 30 | pluginName: string |
28 | authName?: string | 31 | authName?: string |
29 | user: ExternalUser | 32 | user: ExternalUser |
33 | userUpdater: RegisterServerAuthenticatedResult['userUpdater'] | ||
30 | } | 34 | } |
31 | 35 | ||
32 | async function getAccessToken (bearerToken: string) { | 36 | async function getAccessToken (bearerToken: string) { |
@@ -84,7 +88,9 @@ async function getUser (usernameOrEmail?: string, password?: string, bypassLogin | |||
84 | logger.info('Bypassing oauth login by plugin %s.', bypassLogin.pluginName) | 88 | logger.info('Bypassing oauth login by plugin %s.', bypassLogin.pluginName) |
85 | 89 | ||
86 | let user = await UserModel.loadByEmail(bypassLogin.user.email) | 90 | let user = await UserModel.loadByEmail(bypassLogin.user.email) |
91 | |||
87 | if (!user) user = await createUserFromExternal(bypassLogin.pluginName, bypassLogin.user) | 92 | if (!user) user = await createUserFromExternal(bypassLogin.pluginName, bypassLogin.user) |
93 | else user = await updateUserFromExternal(user, bypassLogin.user, bypassLogin.userUpdater) | ||
88 | 94 | ||
89 | // Cannot create a user | 95 | // Cannot create a user |
90 | if (!user) throw new AccessDeniedError('Cannot create such user: an actor with that name already exists.') | 96 | if (!user) throw new AccessDeniedError('Cannot create such user: an actor with that name already exists.') |
@@ -234,6 +240,51 @@ async function createUserFromExternal (pluginAuth: string, userOptions: External | |||
234 | return user | 240 | return user |
235 | } | 241 | } |
236 | 242 | ||
243 | async function updateUserFromExternal ( | ||
244 | user: MUserDefault, | ||
245 | userOptions: ExternalUser, | ||
246 | userUpdater: RegisterServerAuthenticatedResult['userUpdater'] | ||
247 | ) { | ||
248 | if (!userUpdater) return user | ||
249 | |||
250 | { | ||
251 | type UserAttributeKeys = keyof AttributesOnly<UserModel> | ||
252 | const mappingKeys: { [ id in UserAttributeKeys ]?: AuthenticatedResultUpdaterFieldName } = { | ||
253 | role: 'role', | ||
254 | adminFlags: 'adminFlags', | ||
255 | videoQuota: 'videoQuota', | ||
256 | videoQuotaDaily: 'videoQuotaDaily' | ||
257 | } | ||
258 | |||
259 | for (const modelKey of Object.keys(mappingKeys)) { | ||
260 | const pluginOptionKey = mappingKeys[modelKey] | ||
261 | |||
262 | const newValue = userUpdater({ fieldName: pluginOptionKey, currentValue: user[modelKey], newValue: userOptions[pluginOptionKey] }) | ||
263 | user.set(modelKey, newValue) | ||
264 | } | ||
265 | } | ||
266 | |||
267 | { | ||
268 | type AccountAttributeKeys = keyof Partial<AttributesOnly<AccountModel>> | ||
269 | const mappingKeys: { [ id in AccountAttributeKeys ]?: AuthenticatedResultUpdaterFieldName } = { | ||
270 | name: 'displayName' | ||
271 | } | ||
272 | |||
273 | for (const modelKey of Object.keys(mappingKeys)) { | ||
274 | const optionKey = mappingKeys[modelKey] | ||
275 | |||
276 | const newValue = userUpdater({ fieldName: optionKey, currentValue: user.Account[modelKey], newValue: userOptions[optionKey] }) | ||
277 | user.Account.set(modelKey, newValue) | ||
278 | } | ||
279 | } | ||
280 | |||
281 | logger.debug('Updated user %s with plugin userUpdated function.', user.email, { user, userOptions }) | ||
282 | |||
283 | user.Account = await user.Account.save() | ||
284 | |||
285 | return user.save() | ||
286 | } | ||
287 | |||
237 | function checkUserValidityOrThrow (user: MUser) { | 288 | function checkUserValidityOrThrow (user: MUser) { |
238 | if (user.blocked) throw new AccessDeniedError('User is blocked.') | 289 | if (user.blocked) throw new AccessDeniedError('User is blocked.') |
239 | } | 290 | } |