Skip to content

Commit 5e8b77e

Browse files
committed
Added credentials check for free start compute. Use download endpoint from policy server.
1 parent fba187a commit 5e8b77e

4 files changed

Lines changed: 135 additions & 7 deletions

File tree

src/@types/commands.ts

Lines changed: 1 addition & 1 deletion
Original file line numberDiff line numberDiff line change
@@ -196,10 +196,10 @@ export interface FreeComputeStartCommand extends Command {
196196
output?: ComputeOutput
197197
resources?: ComputeResourceRequest[]
198198
maxJobDuration?: number
199+
policyServer?: any // object to pass to policy server
199200
}
200201
export interface PaidComputeStartCommand extends FreeComputeStartCommand {
201202
payment: ComputePayment
202-
policyServer?: any // object to pass to policy server
203203
}
204204

205205
export interface ComputeStopCommand extends Command {

src/components/core/compute/startCompute.ts

Lines changed: 99 additions & 0 deletions
Original file line numberDiff line numberDiff line change
@@ -596,6 +596,105 @@ export class FreeComputeStartHandler extends CommandHandler {
596596
}
597597
}
598598
}
599+
for (const elem of [...[task.algorithm], ...task.datasets]) {
600+
const ddo = await new FindDdoHandler(this.getOceanNode()).findAndFormatDdo(
601+
elem.documentId
602+
)
603+
if (!ddo) {
604+
const error = `DDO ${elem.documentId} not found`
605+
return {
606+
stream: null,
607+
status: {
608+
httpStatus: 500,
609+
error
610+
}
611+
}
612+
}
613+
// check credentials (DDO level)
614+
let accessGrantedDDOLevel: boolean
615+
if (ddo.credentials) {
616+
// if POLICY_SERVER_URL exists, then ocean-node will NOT perform any checks.
617+
// It will just use the existing code and let PolicyServer decide.
618+
if (isPolicyServerConfigured() && task.policyServer) {
619+
accessGrantedDDOLevel = await (
620+
await new PolicyServer().checkStartCompute(
621+
ddo.id,
622+
ddo,
623+
elem.serviceId,
624+
0,
625+
elem.transferTxId,
626+
task.consumerAddress,
627+
task.policyServer
628+
)
629+
).success
630+
} else {
631+
accessGrantedDDOLevel = areKnownCredentialTypes(ddo.credentials)
632+
? checkCredentials(ddo.credentials, task.consumerAddress)
633+
: true
634+
}
635+
if (!accessGrantedDDOLevel) {
636+
CORE_LOGGER.logMessage(`Error: Access to asset ${ddo.id} was denied`, true)
637+
return {
638+
stream: null,
639+
status: {
640+
httpStatus: 403,
641+
error: `Error: Access to asset ${ddo.id} was denied`
642+
}
643+
}
644+
}
645+
}
646+
const service = AssetUtils.getServiceById(ddo, elem.serviceId)
647+
if (!service) {
648+
const error = `Cannot find service ${elem.serviceId} in DDO ${elem.documentId}`
649+
return {
650+
stream: null,
651+
status: {
652+
httpStatus: 500,
653+
error
654+
}
655+
}
656+
}
657+
// check credentials on service level
658+
// if using a policy server and we are here it means that access was granted (they are merged/assessed together)
659+
if (service.credentials) {
660+
let accessGrantedServiceLevel: boolean
661+
if (isPolicyServerConfigured() && task.policyServer) {
662+
// we use the previous check or we do it again
663+
// (in case there is no DDO level credentials and we only have Service level ones)
664+
accessGrantedServiceLevel =
665+
accessGrantedDDOLevel ||
666+
(await (
667+
await new PolicyServer().checkStartCompute(
668+
ddo.id,
669+
ddo,
670+
elem.serviceId,
671+
0,
672+
elem.transferTxId,
673+
task.consumerAddress,
674+
task.policyServer
675+
)
676+
).success)
677+
} else {
678+
accessGrantedServiceLevel = areKnownCredentialTypes(service.credentials)
679+
? checkCredentials(service.credentials, task.consumerAddress)
680+
: true
681+
}
682+
683+
if (!accessGrantedServiceLevel) {
684+
CORE_LOGGER.logMessage(
685+
`Error: Access to service with id ${service.id} was denied`,
686+
true
687+
)
688+
return {
689+
stream: null,
690+
status: {
691+
httpStatus: 403,
692+
error: `Error: Access to service with id ${service.id} was denied`
693+
}
694+
}
695+
}
696+
}
697+
}
599698
try {
600699
const env = await engine.getComputeEnvironment(null, task.environment)
601700
if (!env) {

src/components/core/compute/utils.ts

Lines changed: 15 additions & 0 deletions
Original file line numberDiff line numberDiff line change
@@ -76,6 +76,7 @@ export async function validateAlgoForDataset(
7676
const datasetService = services.find(
7777
(service: any) => service.id === datasetServiceId
7878
)
79+
CORE_LOGGER.logMessage(`datasetService: ${JSON.stringify(datasetService)}`)
7980
if (!datasetService) {
8081
throw new Error('Dataset service not found')
8182
}
@@ -85,13 +86,27 @@ export async function validateAlgoForDataset(
8586
}
8687

8788
if (algoDID) {
89+
CORE_LOGGER.logMessage(`has algoDid: ${algoDID}`)
90+
CORE_LOGGER.logMessage(
91+
`is array1: ${Array.isArray(compute.publisherTrustedAlgorithms)}`
92+
)
93+
CORE_LOGGER.logMessage(
94+
`is array2: ${Array.isArray(compute.publisherTrustedAlgorithmPublishers)}`
95+
)
96+
CORE_LOGGER.logMessage(
97+
`check length 1: ${compute.publisherTrustedAlgorithms.length}`
98+
)
99+
CORE_LOGGER.logMessage(
100+
`check length 2: ${compute.publisherTrustedAlgorithmPublishers.length}`
101+
)
88102
if (
89103
// if not set allow them all
90104
(!Array.isArray(compute.publisherTrustedAlgorithms) ||
91105
compute.publisherTrustedAlgorithms.length === 0) &&
92106
(!Array.isArray(compute.publisherTrustedAlgorithmPublishers) ||
93107
compute.publisherTrustedAlgorithmPublishers.length === 0)
94108
) {
109+
CORE_LOGGER.logMessage(`has algoDid: ${algoDID}`)
95110
return true
96111
}
97112
// if is set only allow if match

src/components/policyServer/index.ts

Lines changed: 20 additions & 6 deletions
Original file line numberDiff line numberDiff line change
@@ -109,9 +109,8 @@ export class PolicyServer {
109109
return await this.askServer(command)
110110
}
111111

112-
// TODO: when commands for initializeCompute and startCompute will be
113-
// implemented in policy server, we'll update these functions
114-
// eslint-disable-next-line require-await
112+
// use checkDownload functionality for initializeCompute and startCompute,
113+
// it will do the same credentials checks
115114
async checkInitializeCompute(
116115
documentId: string,
117116
ddo: DDO,
@@ -121,10 +120,17 @@ export class PolicyServer {
121120
consumerAddress: string,
122121
policyServer: any
123122
): Promise<PolicyServerResult> {
124-
throw new Error('Not implemented yet in policy server')
123+
return await this.checkDownload(
124+
documentId,
125+
ddo,
126+
serviceId,
127+
fileIndex,
128+
transferTxId,
129+
consumerAddress,
130+
policyServer
131+
)
125132
}
126133

127-
// eslint-disable-next-line require-await
128134
async checkStartCompute(
129135
documentId: string,
130136
ddo: DDO,
@@ -134,7 +140,15 @@ export class PolicyServer {
134140
consumerAddress: string,
135141
policyServer: any
136142
): Promise<PolicyServerResult> {
137-
throw new Error('Not implemented yet in policy server')
143+
return await this.checkDownload(
144+
documentId,
145+
ddo,
146+
serviceId,
147+
fileIndex,
148+
transferTxId,
149+
consumerAddress,
150+
policyServer
151+
)
138152
}
139153

140154
async passThrough(request: any): Promise<PolicyServerResult> {

0 commit comments

Comments
 (0)