Fixhancement: check more permissions for status consumer messages (#9804)

This commit is contained in:
shamoon
2025-04-26 23:31:04 -07:00
committed by GitHub
parent 0cefdc8475
commit a3b85c64ca
6 changed files with 125 additions and 12 deletions

View File

@@ -7,4 +7,6 @@ export interface WebsocketProgressMessage {
message?: string
document_id: number
owner_id?: number
users_can_view?: number[]
groups_can_view?: number[]
}

View File

@@ -355,6 +355,50 @@ describe('ConsumerStatusService', () => {
)
})
it('should notify user if user can view or is in group', () => {
settingsService.currentUser = {
id: 1,
username: 'testuser',
is_superuser: false,
groups: [1],
}
websocketStatusService.connect()
server.send({
type: WebsocketStatusType.STATUS_UPDATE,
data: {
task_id: '1234',
filename: 'file1.pdf',
current_progress: 50,
max_progress: 100,
docuement_id: 12,
owner_id: 2,
status: 'WORKING',
users_can_view: [1],
groups_can_view: [],
},
})
expect(websocketStatusService.getConsumerStatusNotCompleted()).toHaveLength(
1
)
server.send({
type: WebsocketStatusType.STATUS_UPDATE,
data: {
task_id: '5678',
filename: 'file2.pdf',
current_progress: 50,
max_progress: 100,
docuement_id: 13,
owner_id: 2,
status: 'WORKING',
users_can_view: [],
groups_can_view: [1],
},
})
expect(websocketStatusService.getConsumerStatusNotCompleted()).toHaveLength(
2
)
})
it('should trigger deleted subject on document deleted', () => {
let deleted = false
websocketStatusService.onDocumentDeleted().subscribe(() => {

View File

@@ -1,6 +1,7 @@
import { Injectable } from '@angular/core'
import { Subject } from 'rxjs'
import { environment } from 'src/environments/environment'
import { User } from '../data/user'
import { WebsocketDocumentsDeletedMessage } from '../data/websocket-documents-deleted-message'
import { WebsocketProgressMessage } from '../data/websocket-progress-message'
import { SettingsService } from './settings.service'
@@ -173,13 +174,25 @@ export class WebsocketStatusService {
}
}
private canViewMessage(messageData: WebsocketProgressMessage): boolean {
// see paperless.consumers.StatusConsumer._can_view
const user: User = this.settingsService.currentUser
return (
!messageData.owner_id ||
user.is_superuser ||
(messageData.owner_id && messageData.owner_id === user.id) ||
(messageData.users_can_view &&
messageData.users_can_view.includes(user.id)) ||
(messageData.groups_can_view &&
messageData.groups_can_view.some((groupId) =>
user.groups?.includes(groupId)
))
)
}
handleProgressUpdate(messageData: WebsocketProgressMessage) {
// fallback if backend didn't restrict message
if (
messageData.owner_id &&
messageData.owner_id !== this.settingsService.currentUser?.id &&
!this.settingsService.currentUser?.is_superuser
) {
if (!this.canViewMessage(messageData)) {
return
}