allow proxy login on the socket

This commit is contained in:
Igor Serebryany 2023-10-06 16:33:48 -07:00
parent 63f1df4015
commit 74e3560153
No known key found for this signature in database
GPG key ID: 0AF607692FD9EB24
2 changed files with 43 additions and 30 deletions

View file

@ -47,6 +47,7 @@ class Auth {
async authMiddleware(req, res, next) {
var token = null
var proxyAccount = this.getProxyAccount(req.headers)
// If using a get request, the token can be passed as a query string
if (req.method === 'GET' && req.query && req.query.token) {
@ -56,13 +57,7 @@ class Auth {
token = authHeader && authHeader.split(' ')[1]
}
let proxyUsername = null
if (Database.serverSettings.proxyAuthEnabled) {
const uHeader = Database.serverSettings.proxyAuthUsernameHeader.toLowerCase()
proxyUsername = uHeader ? req.headers[uHeader] : null
}
if (token == null && proxyUsername == null) {
if (token == null && !(proxyAccount && proxyAccount['username'])) {
Logger.error('Api called without a token and no proxy auth provided', req.path)
return res.sendStatus(401)
}
@ -76,11 +71,8 @@ class Auth {
}
user.isFromProxy = false
} else if (proxyUsername) {
const eHeader = Database.serverSettings.proxyAuthEmailHeader.toLowerCase()
const proxyEmail = eHeader ? req.headers[eHeader] : null
user = await this.getProxyUser(proxyUsername, proxyEmail)
} else if (proxyAccount) {
user = await this.getProxyUser(proxyAccount)
if (!user) {
Logger.error('Cannot get user from proxy headers', proxyUsername)
return res.sendStatus(401)
@ -121,8 +113,20 @@ class Auth {
return jwt.sign(payload, Database.serverSettings.tokenSecret)
}
authenticateUser(token) {
return this.verifyToken(token)
async authenticateUser(token, headers) {
const tokenUser = token ? await this.verifyToken(token) : null
if (tokenUser) return tokenUser
const proxyAccount = this.getProxyAccount(headers)
if (proxyAccount && proxyAccount.username) {
const proxyUser = await this.getProxyUser(proxyAccount)
if (proxyUser) {
proxyUser.isFromProxy = true;
return proxyUser;
}
}
return null
}
verifyToken(token) {
@ -143,19 +147,28 @@ class Auth {
})
}
async getProxyUser(username, email) {
const user = await Database.userModel.getUserByUsername(username)
if (user) {
return user
getProxyAccount(headers) {
if (!Database.serverSettings.proxyAuthEnabled) return null
const uHeader = Database.serverSettings.proxyAuthUsernameHeader.toLowerCase()
const eHeader = Database.serverSettings.proxyAuthEmailHeader.toLowerCase()
return {
username: uHeader ? headers[uHeader] : null,
email: eHeader ? headers[eHeader] : null,
}
}
if (!email) {
return null
}
async getProxyUser(account) {
const user = await Database.userModel.getUserByUsername(account.username)
if (user) return user;
const account = {
username,
email,
// we need an email to create accounts
if (!account.email) return null;
// add some fields for proxy users
account = {
...account,
type: 'user',
isActive: true,
}

View file

@ -147,7 +147,7 @@ class SocketAuthority {
// When setting up a socket connection the user needs to be associated with a socket id
// for this the client will send a 'auth' event that includes the users API token
async authenticateSocket(socket, token) {
const user = await this.Server.auth.authenticateUser(token)
const user = await this.Server.auth.authenticateUser(token, socket.handshake.headers)
if (!user) {
Logger.error('Cannot validate socket - invalid token')
return socket.emit('invalid_token')
@ -169,7 +169,7 @@ class SocketAuthority {
return
}
Logger.debug(`[SocketAuthority] User Online ${client.user.username}`)
Logger.debug(`[SocketAuthority] User Online ${client.user.username} (FromProxy: ${user.isFromProxy})`)
this.adminEmitter('user_online', client.user.toJSONForPublic(this.Server.playbackSessionManager.sessions))