Skip to content

Commit 2b405de

Browse files
committed
wip: publications
1 parent 082090a commit 2b405de

File tree

24 files changed

+374
-561
lines changed

24 files changed

+374
-561
lines changed

meteor/server/api/blueprints/__tests__/api.test.ts

Lines changed: 0 additions & 1 deletion
Original file line numberDiff line numberDiff line change
@@ -31,7 +31,6 @@ const DEFAULT_CONTEXT: MethodContext = {
3131
userId: null,
3232
isSimulation: false,
3333
connection: DEFAULT_CONNECTION,
34-
setUserId: () => undefined,
3534
unblock: () => undefined,
3635
}
3736

meteor/server/api/ingest/lib.ts

Lines changed: 2 additions & 1 deletion
Original file line numberDiff line numberDiff line change
@@ -20,6 +20,7 @@ import {
2020
import { PeripheralDevices } from '../../collections'
2121
import { getStudioIdFromDevice } from '../studio/lib'
2222
import { assertConnectionHasOneOfPermissions } from '../../security/auth'
23+
import { SubscriptionContext } from '../../publications/lib'
2324

2425
/**
2526
* Run an ingest operation via the worker.
@@ -67,7 +68,7 @@ export async function runIngestOperation<T extends keyof IngestJobFunc>(
6768
export async function checkAccessAndGetPeripheralDevice(
6869
deviceId: PeripheralDeviceId,
6970
token: string | undefined,
70-
context: MethodContext
71+
context: MethodContext | SubscriptionContext
7172
): Promise<PeripheralDevice> {
7273
const span = profiler.startSpan('lib.checkAccessAndGetPeripheralDevice')
7374

meteor/server/api/methodContext.ts

Lines changed: 1 addition & 1 deletion
Original file line numberDiff line numberDiff line change
@@ -1,7 +1,7 @@
11
import { Meteor } from 'meteor/meteor'
22
import { UserId } from '@sofie-automation/corelib/dist/dataModel/Ids'
33

4-
export interface MethodContext extends Omit<Meteor.MethodThisType, 'userId'> {
4+
export interface MethodContext extends Omit<Meteor.MethodThisType, 'userId' | 'setUserId'> {
55
userId: UserId | null
66
}
77

meteor/server/publications/blueprintUpgradeStatus/publication.ts

Lines changed: 3 additions & 9 deletions
Original file line numberDiff line numberDiff line change
@@ -9,9 +9,6 @@ import {
99
setUpCollectionOptimizedObserver,
1010
TriggerUpdate,
1111
} from '../../lib/customPublication'
12-
import { logger } from '../../logging'
13-
import { resolveCredentials } from '../../security/lib/credentials'
14-
import { NoSecurityReadAccess } from '../../security/noSecurity'
1512
import { LiveQueryHandle } from '../../lib/lib'
1613
import { ContentCache, createReactiveContentCache, ShowStyleBaseFields, StudioFields } from './reactiveContentCache'
1714
import { UpgradesContentObserver } from './upgradesContentObserver'
@@ -23,6 +20,7 @@ import {
2320
UIBlueprintUpgradeStatus,
2421
UIBlueprintUpgradeStatusId,
2522
} from '@sofie-automation/meteor-lib/dist/api/upgradeStatus'
23+
import { assertConnectionHasOneOfPermissions } from '../../security/auth'
2624

2725
type BlueprintUpgradeStatusArgs = Record<string, never>
2826

@@ -238,12 +236,8 @@ meteorCustomPublish(
238236
MeteorPubSub.uiBlueprintUpgradeStatuses,
239237
CustomCollectionName.UIBlueprintUpgradeStatuses,
240238
async function (pub) {
241-
const cred = await resolveCredentials({ userId: this.userId, token: undefined })
239+
assertConnectionHasOneOfPermissions(this.connection, 'configure', 'service')
242240

243-
if (!cred || NoSecurityReadAccess.any()) {
244-
await createBlueprintUpgradeStatusSubscriptionHandle(pub)
245-
} else {
246-
logger.warn(`Pub.${CustomCollectionName.UIBlueprintUpgradeStatuses}: Not allowed`)
247-
}
241+
await createBlueprintUpgradeStatusSubscriptionHandle(pub)
248242
}
249243
)

meteor/server/publications/deviceTriggersPreview.ts

Lines changed: 4 additions & 6 deletions
Original file line numberDiff line numberDiff line change
@@ -9,8 +9,8 @@ import { DeviceTriggerArguments, UIDeviceTriggerPreview } from '@sofie-automatio
99
import { getCurrentTime } from '../lib/lib'
1010
import { setUpOptimizedObserverArray, TriggerUpdate } from '../lib/customPublication'
1111
import { CustomPublish, meteorCustomPublish } from '../lib/customPublication/publish'
12-
import { StudioReadAccess } from '../security/studio'
1312
import { PeripheralDevices } from '../collections'
13+
import { triggerWriteAccessBecauseNoCheckNecessary } from '../security/lib/securityVerify'
1414

1515
/** IDEA: This could potentially be a Capped Collection, thus enabling scaling Core horizontally:
1616
* https://www.mongodb.com/docs/manual/core/capped-collections/ */
@@ -19,14 +19,12 @@ const lastTriggers: Record<string, { triggers: UIDeviceTriggerPreview[]; updated
1919
meteorCustomPublish(
2020
MeteorPubSub.deviceTriggersPreview,
2121
CustomCollectionName.UIDeviceTriggerPreviews,
22-
async function (pub, studioId: StudioId, token: string | undefined) {
22+
async function (pub, studioId: StudioId, _token: string | undefined) {
2323
check(studioId, String)
2424

25-
if (!studioId) throw new Meteor.Error(400, 'One of studioId must be provided')
25+
triggerWriteAccessBecauseNoCheckNecessary()
2626

27-
if (await StudioReadAccess.studioContent(studioId, { userId: this.userId, token })) {
28-
await createObserverForDeviceTriggersPreviewsPublication(pub, MeteorPubSub.deviceTriggersPreview, studioId)
29-
}
27+
await createObserverForDeviceTriggersPreviewsPublication(pub, MeteorPubSub.deviceTriggersPreview, studioId)
3028
}
3129
)
3230

meteor/server/publications/mountedTriggers.ts

Lines changed: 24 additions & 37 deletions
Original file line numberDiff line numberDiff line change
@@ -1,19 +1,18 @@
11
import { Meteor } from 'meteor/meteor'
22
import { CustomPublish, meteorCustomPublish } from '../lib/customPublication'
33
import { PeripheralDeviceId } from '@sofie-automation/corelib/dist/dataModel/Ids'
4-
import { PeripheralDeviceReadAccess } from '../security/peripheralDevice'
54
import { logger } from '../logging'
65
import { DeviceTriggerMountedActionAdlibsPreview, DeviceTriggerMountedActions } from '../api/deviceTriggers/observer'
76
import { Mongo } from 'meteor/mongo'
87
import { ProtectedString } from '@sofie-automation/corelib/dist/protectedString'
98
import _ from 'underscore'
10-
import { PeripheralDevices } from '../collections'
119
import { check } from 'meteor/check'
1210
import {
1311
PeripheralDevicePubSub,
1412
PeripheralDevicePubSubCollectionsNames,
1513
} from '@sofie-automation/shared-lib/dist/pubsub/peripheralDevice'
1614
import { stringifyError } from '@sofie-automation/shared-lib/dist/lib/stringifyError'
15+
import { checkAccessAndGetPeripheralDevice } from '../api/ingest/lib'
1716

1817
const PUBLICATION_DEBOUNCE = 20
1918

@@ -24,26 +23,20 @@ meteorCustomPublish(
2423
check(deviceId, String)
2524
check(deviceIds, [String])
2625

27-
if (await PeripheralDeviceReadAccess.peripheralDeviceContent(deviceId, { userId: this.userId, token })) {
28-
const peripheralDevice = await PeripheralDevices.findOneAsync(deviceId)
29-
30-
if (!peripheralDevice) throw new Meteor.Error(404, `PeripheralDevice "${deviceId}" not found`)
31-
32-
const studioId = peripheralDevice.studioId
33-
if (!studioId) throw new Meteor.Error(400, `Peripheral Device "${deviceId}" not attached to a studio`)
34-
35-
cursorCustomPublish(
36-
pub,
37-
DeviceTriggerMountedActions.find({
38-
studioId,
39-
deviceId: {
40-
$in: deviceIds,
41-
},
42-
})
43-
)
44-
} else {
45-
logger.warn(`Pub.mountedTriggersForDevice: Not allowed: "${deviceId}"`)
46-
}
26+
const peripheralDevice = await checkAccessAndGetPeripheralDevice(deviceId, token, this)
27+
28+
const studioId = peripheralDevice.studioId
29+
if (!studioId) throw new Meteor.Error(400, `Peripheral Device "${deviceId}" not attached to a studio`)
30+
31+
cursorCustomPublish(
32+
pub,
33+
DeviceTriggerMountedActions.find({
34+
studioId,
35+
deviceId: {
36+
$in: deviceIds,
37+
},
38+
})
39+
)
4740
}
4841
)
4942

@@ -53,23 +46,17 @@ meteorCustomPublish(
5346
async function (pub, deviceId: PeripheralDeviceId, token: string | undefined) {
5447
check(deviceId, String)
5548

56-
if (await PeripheralDeviceReadAccess.peripheralDeviceContent(deviceId, { userId: this.userId, token })) {
57-
const peripheralDevice = await PeripheralDevices.findOneAsync(deviceId)
49+
const peripheralDevice = await checkAccessAndGetPeripheralDevice(deviceId, token, this)
5850

59-
if (!peripheralDevice) throw new Meteor.Error(404, `PeripheralDevice "${deviceId}" not found`)
51+
const studioId = peripheralDevice.studioId
52+
if (!studioId) throw new Meteor.Error(400, `Peripheral Device "${deviceId}" not attached to a studio`)
6053

61-
const studioId = peripheralDevice.studioId
62-
if (!studioId) throw new Meteor.Error(400, `Peripheral Device "${deviceId}" not attached to a studio`)
63-
64-
cursorCustomPublish(
65-
pub,
66-
DeviceTriggerMountedActionAdlibsPreview.find({
67-
studioId,
68-
})
69-
)
70-
} else {
71-
logger.warn(`Pub.mountedTriggersForDevicePreview: Not allowed: "${deviceId}"`)
72-
}
54+
cursorCustomPublish(
55+
pub,
56+
DeviceTriggerMountedActionAdlibsPreview.find({
57+
studioId,
58+
})
59+
)
7360
}
7461
)
7562

meteor/server/publications/packageManager/expectedPackages/publication.ts

Lines changed: 25 additions & 27 deletions
Original file line numberDiff line numberDiff line change
@@ -1,5 +1,4 @@
11
import { Meteor } from 'meteor/meteor'
2-
import { PeripheralDeviceReadAccess } from '../../../security/peripheralDevice'
32
import { DBStudio, StudioPackageContainer } from '@sofie-automation/corelib/dist/dataModel/Studio'
43
import {
54
TriggerUpdate,
@@ -29,6 +28,7 @@ import {
2928
PeripheralDevicePubSub,
3029
PeripheralDevicePubSubCollectionsNames,
3130
} from '@sofie-automation/shared-lib/dist/pubsub/peripheralDevice'
31+
import { triggerWriteAccessBecauseNoCheckNecessary } from '../../../security/lib/securityVerify'
3232

3333
interface ExpectedPackagesPublicationArgs {
3434
readonly studioId: StudioId
@@ -200,39 +200,37 @@ meteorCustomPublish(
200200
pub,
201201
deviceId: PeripheralDeviceId,
202202
filterPlayoutDeviceIds: PeripheralDeviceId[] | undefined,
203-
token: string | undefined
203+
_token: string | undefined
204204
) {
205205
check(deviceId, String)
206206
check(filterPlayoutDeviceIds, Match.Maybe([String]))
207207

208-
if (await PeripheralDeviceReadAccess.peripheralDeviceContent(deviceId, { userId: this.userId, token })) {
209-
const peripheralDevice = await PeripheralDevices.findOneAsync(deviceId)
208+
triggerWriteAccessBecauseNoCheckNecessary()
210209

211-
if (!peripheralDevice) throw new Meteor.Error('PeripheralDevice "' + deviceId + '" not found')
210+
const peripheralDevice = await PeripheralDevices.findOneAsync(deviceId)
212211

213-
const studioId = peripheralDevice.studioId
214-
if (!studioId) {
215-
logger.warn(`Pub.packageManagerExpectedPackages: device "${peripheralDevice._id}" has no studioId`)
216-
return this.ready()
217-
}
212+
if (!peripheralDevice) throw new Meteor.Error('PeripheralDevice "' + deviceId + '" not found')
218213

219-
await setUpCollectionOptimizedObserver<
220-
PackageManagerExpectedPackage,
221-
ExpectedPackagesPublicationArgs,
222-
ExpectedPackagesPublicationState,
223-
ExpectedPackagesPublicationUpdateProps
224-
>(
225-
`${PeripheralDevicePubSub.packageManagerExpectedPackages}_${studioId}_${deviceId}_${JSON.stringify(
226-
(filterPlayoutDeviceIds || []).sort()
227-
)}`,
228-
{ studioId, deviceId, filterPlayoutDeviceIds },
229-
setupExpectedPackagesPublicationObservers,
230-
manipulateExpectedPackagesPublicationData,
231-
pub,
232-
500 // ms, wait this time before sending an update
233-
)
234-
} else {
235-
logger.warn(`Pub.packageManagerExpectedPackages: Not allowed: "${deviceId}"`)
214+
const studioId = peripheralDevice.studioId
215+
if (!studioId) {
216+
logger.warn(`Pub.packageManagerExpectedPackages: device "${peripheralDevice._id}" has no studioId`)
217+
return this.ready()
236218
}
219+
220+
await setUpCollectionOptimizedObserver<
221+
PackageManagerExpectedPackage,
222+
ExpectedPackagesPublicationArgs,
223+
ExpectedPackagesPublicationState,
224+
ExpectedPackagesPublicationUpdateProps
225+
>(
226+
`${PeripheralDevicePubSub.packageManagerExpectedPackages}_${studioId}_${deviceId}_${JSON.stringify(
227+
(filterPlayoutDeviceIds || []).sort()
228+
)}`,
229+
{ studioId, deviceId, filterPlayoutDeviceIds },
230+
setupExpectedPackagesPublicationObservers,
231+
manipulateExpectedPackagesPublicationData,
232+
pub,
233+
500 // ms, wait this time before sending an update
234+
)
237235
}
238236
)

meteor/server/publications/packageManager/packageContainers.ts

Lines changed: 23 additions & 25 deletions
Original file line numberDiff line numberDiff line change
@@ -10,12 +10,12 @@ import { ReadonlyDeep } from 'type-fest'
1010
import { PeripheralDevices, Studios } from '../../collections'
1111
import { meteorCustomPublish, setUpOptimizedObserverArray, TriggerUpdate } from '../../lib/customPublication'
1212
import { logger } from '../../logging'
13-
import { PeripheralDeviceReadAccess } from '../../security/peripheralDevice'
1413
import {
1514
PeripheralDevicePubSub,
1615
PeripheralDevicePubSubCollectionsNames,
1716
} from '@sofie-automation/shared-lib/dist/pubsub/peripheralDevice'
1817
import { applyAndValidateOverrides } from '@sofie-automation/corelib/dist/settings/objectWithOverrides'
18+
import { triggerWriteAccessBecauseNoCheckNecessary } from '../../security/lib/securityVerify'
1919

2020
type StudioFields = '_id' | 'packageContainersWithOverrides'
2121
const studioFieldSpecifier = literal<MongoFieldSpecifierOnesStrict<Pick<DBStudio, StudioFields>>>({
@@ -88,35 +88,33 @@ async function manipulateExpectedPackagesPublicationData(
8888
meteorCustomPublish(
8989
PeripheralDevicePubSub.packageManagerPackageContainers,
9090
PeripheralDevicePubSubCollectionsNames.packageManagerPackageContainers,
91-
async function (pub, deviceId: PeripheralDeviceId, token: string | undefined) {
91+
async function (pub, deviceId: PeripheralDeviceId, _token: string | undefined) {
9292
check(deviceId, String)
9393

94-
if (await PeripheralDeviceReadAccess.peripheralDeviceContent(deviceId, { userId: this.userId, token })) {
95-
const peripheralDevice = await PeripheralDevices.findOneAsync(deviceId)
94+
triggerWriteAccessBecauseNoCheckNecessary()
9695

97-
if (!peripheralDevice) throw new Meteor.Error('PeripheralDevice "' + deviceId + '" not found')
96+
const peripheralDevice = await PeripheralDevices.findOneAsync(deviceId)
9897

99-
const studioId = peripheralDevice.studioId
100-
if (!studioId) {
101-
logger.warn(`Pub.packageManagerPackageContainers: device "${peripheralDevice._id}" has no studioId`)
102-
return this.ready()
103-
}
98+
if (!peripheralDevice) throw new Meteor.Error('PeripheralDevice "' + deviceId + '" not found')
10499

105-
await setUpOptimizedObserverArray<
106-
PackageManagerPackageContainers,
107-
PackageManagerPackageContainersArgs,
108-
PackageManagerPackageContainersState,
109-
PackageManagerPackageContainersUpdateProps
110-
>(
111-
`${PeripheralDevicePubSub.packageManagerPackageContainers}_${studioId}_${deviceId}`,
112-
{ studioId, deviceId },
113-
setupExpectedPackagesPublicationObservers,
114-
manipulateExpectedPackagesPublicationData,
115-
pub,
116-
500 // ms, wait this time before sending an update
117-
)
118-
} else {
119-
logger.warn(`Pub.packageManagerPackageContainers: Not allowed: "${deviceId}"`)
100+
const studioId = peripheralDevice.studioId
101+
if (!studioId) {
102+
logger.warn(`Pub.packageManagerPackageContainers: device "${peripheralDevice._id}" has no studioId`)
103+
return this.ready()
120104
}
105+
106+
await setUpOptimizedObserverArray<
107+
PackageManagerPackageContainers,
108+
PackageManagerPackageContainersArgs,
109+
PackageManagerPackageContainersState,
110+
PackageManagerPackageContainersUpdateProps
111+
>(
112+
`${PeripheralDevicePubSub.packageManagerPackageContainers}_${studioId}_${deviceId}`,
113+
{ studioId, deviceId },
114+
setupExpectedPackagesPublicationObservers,
115+
manipulateExpectedPackagesPublicationData,
116+
pub,
117+
500 // ms, wait this time before sending an update
118+
)
121119
}
122120
)

0 commit comments

Comments
 (0)