External auth can set more user fields
videoQuota, videoQuotaDaily, adminFlags
This commit is contained in:
parent
b65f5367ba
commit
7e0c26066a
|
@ -1,26 +1,33 @@
|
|||
|
||||
import { isUserDisplayNameValid, isUserRoleValid, isUserUsernameValid } from '@server/helpers/custom-validators/users'
|
||||
import {
|
||||
isUserAdminFlagsValid,
|
||||
isUserDisplayNameValid,
|
||||
isUserRoleValid,
|
||||
isUserUsernameValid,
|
||||
isUserVideoQuotaDailyValid,
|
||||
isUserVideoQuotaValid
|
||||
} from '@server/helpers/custom-validators/users'
|
||||
import { logger } from '@server/helpers/logger'
|
||||
import { generateRandomString } from '@server/helpers/utils'
|
||||
import { PLUGIN_EXTERNAL_AUTH_TOKEN_LIFETIME } from '@server/initializers/constants'
|
||||
import { PluginManager } from '@server/lib/plugins/plugin-manager'
|
||||
import { OAuthTokenModel } from '@server/models/oauth/oauth-token'
|
||||
import { MUser } from '@server/types/models'
|
||||
import {
|
||||
RegisterServerAuthenticatedResult,
|
||||
RegisterServerAuthPassOptions,
|
||||
RegisterServerExternalAuthenticatedResult
|
||||
} from '@server/types/plugins/register-server-auth.model'
|
||||
import { UserRole } from '@shared/models'
|
||||
import { UserAdminFlag, UserRole } from '@shared/models'
|
||||
|
||||
export type ExternalUser =
|
||||
Pick<MUser, 'username' | 'email' | 'role' | 'adminFlags' | 'videoQuotaDaily' | 'videoQuota'> &
|
||||
{ displayName: string }
|
||||
|
||||
// Token is the key, expiration date is the value
|
||||
const authBypassTokens = new Map<string, {
|
||||
expires: Date
|
||||
user: {
|
||||
username: string
|
||||
email: string
|
||||
displayName: string
|
||||
role: UserRole
|
||||
}
|
||||
user: ExternalUser
|
||||
authName: string
|
||||
npmName: string
|
||||
}>()
|
||||
|
@ -172,30 +179,20 @@ function getBypassFromExternalAuth (username: string, externalAuthToken: string)
|
|||
}
|
||||
|
||||
function isAuthResultValid (npmName: string, authName: string, result: RegisterServerAuthenticatedResult) {
|
||||
if (!isUserUsernameValid(result.username)) {
|
||||
logger.error('Auth method %s of plugin %s did not provide a valid username.', authName, npmName, { username: result.username })
|
||||
const returnError = (field: string) => {
|
||||
logger.error('Auth method %s of plugin %s did not provide a valid %s.', authName, npmName, field, { [field]: result[field] })
|
||||
return false
|
||||
}
|
||||
|
||||
if (!result.email) {
|
||||
logger.error('Auth method %s of plugin %s did not provide a valid email.', authName, npmName, { email: result.email })
|
||||
return false
|
||||
}
|
||||
if (!isUserUsernameValid(result.username)) return returnError('username')
|
||||
if (!result.email) return returnError('email')
|
||||
|
||||
// role is optional
|
||||
if (result.role && !isUserRoleValid(result.role)) {
|
||||
logger.error('Auth method %s of plugin %s did not provide a valid role.', authName, npmName, { role: result.role })
|
||||
return false
|
||||
}
|
||||
|
||||
// display name is optional
|
||||
if (result.displayName && !isUserDisplayNameValid(result.displayName)) {
|
||||
logger.error(
|
||||
'Auth method %s of plugin %s did not provide a valid display name.',
|
||||
authName, npmName, { displayName: result.displayName }
|
||||
)
|
||||
return false
|
||||
}
|
||||
// Following fields are optional
|
||||
if (result.role && !isUserRoleValid(result.role)) return returnError('role')
|
||||
if (result.displayName && !isUserDisplayNameValid(result.displayName)) return returnError('displayName')
|
||||
if (result.adminFlags && !isUserAdminFlagsValid(result.adminFlags)) return returnError('adminFlags')
|
||||
if (result.videoQuota && !isUserVideoQuotaValid(result.videoQuota + '')) return returnError('videoQuota')
|
||||
if (result.videoQuotaDaily && !isUserVideoQuotaDailyValid(result.videoQuotaDaily + '')) return returnError('videoQuotaDaily')
|
||||
|
||||
return true
|
||||
}
|
||||
|
@ -205,7 +202,12 @@ function buildUserResult (pluginResult: RegisterServerAuthenticatedResult) {
|
|||
username: pluginResult.username,
|
||||
email: pluginResult.email,
|
||||
role: pluginResult.role ?? UserRole.USER,
|
||||
displayName: pluginResult.displayName || pluginResult.username
|
||||
displayName: pluginResult.displayName || pluginResult.username,
|
||||
|
||||
adminFlags: pluginResult.adminFlags ?? UserAdminFlag.NONE,
|
||||
|
||||
videoQuota: pluginResult.videoQuota,
|
||||
videoQuotaDaily: pluginResult.videoQuotaDaily
|
||||
}
|
||||
}
|
||||
|
||||
|
|
|
@ -5,7 +5,6 @@ import { MOAuthClient } from '@server/types/models'
|
|||
import { MOAuthTokenUser } from '@server/types/models/oauth/oauth-token'
|
||||
import { MUser } from '@server/types/models/user/user'
|
||||
import { pick } from '@shared/core-utils'
|
||||
import { UserRole } from '@shared/models/users/user-role'
|
||||
import { logger } from '../../helpers/logger'
|
||||
import { CONFIG } from '../../initializers/config'
|
||||
import { OAuthClientModel } from '../../models/oauth/oauth-client'
|
||||
|
@ -13,6 +12,7 @@ import { OAuthTokenModel } from '../../models/oauth/oauth-token'
|
|||
import { UserModel } from '../../models/user/user'
|
||||
import { findAvailableLocalActorName } from '../local-actor'
|
||||
import { buildUser, createUserAccountAndChannelAndPlaylist } from '../user'
|
||||
import { ExternalUser } from './external-auth'
|
||||
import { TokensCache } from './tokens-cache'
|
||||
|
||||
type TokenInfo = {
|
||||
|
@ -26,12 +26,7 @@ export type BypassLogin = {
|
|||
bypass: boolean
|
||||
pluginName: string
|
||||
authName?: string
|
||||
user: {
|
||||
username: string
|
||||
email: string
|
||||
displayName: string
|
||||
role: UserRole
|
||||
}
|
||||
user: ExternalUser
|
||||
}
|
||||
|
||||
async function getAccessToken (bearerToken: string) {
|
||||
|
@ -219,16 +214,11 @@ export {
|
|||
|
||||
// ---------------------------------------------------------------------------
|
||||
|
||||
async function createUserFromExternal (pluginAuth: string, options: {
|
||||
username: string
|
||||
email: string
|
||||
role: UserRole
|
||||
displayName: string
|
||||
}) {
|
||||
const username = await findAvailableLocalActorName(options.username)
|
||||
async function createUserFromExternal (pluginAuth: string, userOptions: ExternalUser) {
|
||||
const username = await findAvailableLocalActorName(userOptions.username)
|
||||
|
||||
const userToCreate = buildUser({
|
||||
...pick(options, [ 'email', 'role' ]),
|
||||
...pick(userOptions, [ 'email', 'role', 'adminFlags', 'videoQuota', 'videoQuotaDaily' ]),
|
||||
|
||||
username,
|
||||
emailVerified: null,
|
||||
|
@ -238,7 +228,7 @@ async function createUserFromExternal (pluginAuth: string, options: {
|
|||
|
||||
const { user } = await createUserAccountAndChannelAndPlaylist({
|
||||
userToCreate,
|
||||
userDisplayName: options.displayName
|
||||
userDisplayName: userOptions.displayName
|
||||
})
|
||||
|
||||
return user
|
||||
|
|
|
@ -33,7 +33,10 @@ async function register ({
|
|||
username: 'kefka',
|
||||
email: 'kefka@example.com',
|
||||
role: 0,
|
||||
displayName: 'Kefka Palazzo'
|
||||
displayName: 'Kefka Palazzo',
|
||||
adminFlags: 1,
|
||||
videoQuota: 42000,
|
||||
videoQuotaDaily: 42100
|
||||
})
|
||||
},
|
||||
hookTokenValidity: (options) => {
|
||||
|
|
|
@ -2,7 +2,7 @@
|
|||
|
||||
import { expect } from 'chai'
|
||||
import { wait } from '@shared/core-utils'
|
||||
import { HttpStatusCode, UserRole } from '@shared/models'
|
||||
import { HttpStatusCode, UserAdminFlag, UserRole } from '@shared/models'
|
||||
import {
|
||||
cleanupTests,
|
||||
createSingleServer,
|
||||
|
@ -156,6 +156,9 @@ describe('Test external auth plugins', function () {
|
|||
expect(body.account.displayName).to.equal('cyan')
|
||||
expect(body.email).to.equal('cyan@example.com')
|
||||
expect(body.role.id).to.equal(UserRole.USER)
|
||||
expect(body.adminFlags).to.equal(UserAdminFlag.NONE)
|
||||
expect(body.videoQuota).to.equal(5242880)
|
||||
expect(body.videoQuotaDaily).to.equal(-1)
|
||||
}
|
||||
})
|
||||
|
||||
|
@ -178,6 +181,9 @@ describe('Test external auth plugins', function () {
|
|||
expect(body.account.displayName).to.equal('Kefka Palazzo')
|
||||
expect(body.email).to.equal('kefka@example.com')
|
||||
expect(body.role.id).to.equal(UserRole.ADMINISTRATOR)
|
||||
expect(body.adminFlags).to.equal(UserAdminFlag.BYPASS_VIDEO_AUTO_BLACKLIST)
|
||||
expect(body.videoQuota).to.equal(42000)
|
||||
expect(body.videoQuotaDaily).to.equal(42100)
|
||||
}
|
||||
})
|
||||
|
||||
|
|
|
@ -1,5 +1,5 @@
|
|||
import express from 'express'
|
||||
import { UserRole } from '@shared/models'
|
||||
import { UserAdminFlag, UserRole } from '@shared/models'
|
||||
import { MOAuthToken, MUser } from '../models'
|
||||
|
||||
export type RegisterServerAuthOptions = RegisterServerAuthPassOptions | RegisterServerAuthExternalOptions
|
||||
|
@ -9,6 +9,11 @@ export interface RegisterServerAuthenticatedResult {
|
|||
email: string
|
||||
role?: UserRole
|
||||
displayName?: string
|
||||
|
||||
adminFlags?: UserAdminFlag
|
||||
|
||||
videoQuota?: number
|
||||
videoQuotaDaily?: number
|
||||
}
|
||||
|
||||
export interface RegisterServerExternalAuthenticatedResult extends RegisterServerAuthenticatedResult {
|
||||
|
|
Loading…
Reference in New Issue