Skip to content
Open
Show file tree
Hide file tree
Changes from all commits
Commits
File filter

Filter by extension

Filter by extension

Conversations
Failed to load comments.
Loading
Jump to
Jump to file
Failed to load files.
Loading
Diff view
Diff view
48 changes: 47 additions & 1 deletion docs/API.md
Original file line number Diff line number Diff line change
Expand Up @@ -203,7 +203,15 @@ returns amount of tokens to transfer to the provider account

returns encrypted blob

#### Request
#### Query Parameters

| name | type | required | description |
| --------------- | ------ | -------- | ------------------------------------------------------- |
| nonce | string | v | is required to verify a request paired with a signature |
| consumerAddress | string | v | consumer address |
| signature | string | v | signed message based on ` nonce` |

#### Request body

```
string
Expand All @@ -217,6 +225,44 @@ string

---

## EncryptFile

### `HTTP` POST /api/services/encryptFile

#### Description

returns encrypted file

#### Query Parameters

| name | type | required | description |
| --------------- | ------ | -------- | ------------------------------------------------------- |
| nonce | string | v | is required to verify a request paired with a signature |
| consumerAddress | string | v | consumer address |
| signature | string | v | signed message based on ` nonce` |

#### Request body

if Content-Type = 'application/json'

```
BaseFileObject
```

if Content-Type = 'application/octet-stream' || 'multipart/form-data'

```
FileContent(bytes)
```

#### Response

```
0x123
```

---

## Decrypt DDO

### `HTTP` POST /api/services/decrypt
Expand Down
12 changes: 12 additions & 0 deletions docs/PolicyServer.md
Original file line number Diff line number Diff line change
Expand Up @@ -95,6 +95,18 @@ Called whenever a new encrypt command is received by Ocean Node
}
```

### encryptFile

Called whenever a new encryptFile command is received by Ocean Node

```json
{
"action": "encrypt",
"policyServer": {},
"file"?: object
}
```

### decrypt

Called whenever a new decrypt command is received by Ocean Node
Expand Down
9 changes: 8 additions & 1 deletion src/@types/commands.ts
Original file line number Diff line number Diff line change
Expand Up @@ -120,16 +120,23 @@ export interface DecryptDDOCommand extends Command {
}

export interface EncryptCommand extends Command {
nonce: string
consumerAddress: string
signature: string
blob: string
encoding?: string
encryptionType?: EncryptMethod.AES | EncryptMethod.ECIES
policyServer?: any // object to pass to policy server
}

export interface EncryptFileCommand extends Command {
nonce: string
consumerAddress: string
signature: string
encryptionType?: EncryptMethod.AES | EncryptMethod.ECIES
files?: BaseFileObject
rawData?: Buffer
// UrlFileObject | ArweaveFileObject | IpfsFileObject
policyServer?: any // object to pass to policy server
}

export interface NonceCommand extends Command {
Expand Down
68 changes: 67 additions & 1 deletion src/components/core/handler/encryptHandler.ts
Original file line number Diff line number Diff line change
Expand Up @@ -4,7 +4,8 @@ import { EncryptCommand, EncryptFileCommand } from '../../../@types/commands.js'
import * as base58 from 'base58-js'
import { Readable } from 'stream'
import { Storage } from '../../storage/index.js'
import { getConfiguration } from '../../../utils/index.js'
import { getConfiguration, isPolicyServerConfigured } from '../../../utils/index.js'
import { PolicyServer } from '../../policyServer/index.js'
import { EncryptMethod } from '../../../@types/fileObject.js'
import {
ValidateParams,
Expand Down Expand Up @@ -49,9 +50,41 @@ export class EncryptHandler extends CommandHandler {

async handle(task: EncryptCommand): Promise<P2PCommandResponse> {
const validationResponse = await this.verifyParamsAndRateLimits(task)

if (this.shouldDenyTaskHandling(validationResponse)) {
return validationResponse
}
const isAuthRequestValid = await this.validateTokenOrSignature(
task.authorization,
task.consumerAddress,
task.nonce,
task.signature,
String(task.nonce)
)
if (isAuthRequestValid.status.httpStatus !== 200) {
return isAuthRequestValid
}

if (isPolicyServerConfigured()) {
const policyServer = new PolicyServer()
const response = await policyServer.checkEncrypt(
task.consumerAddress,
task.policyServer
)
if (!response) {
CORE_LOGGER.logMessage(
`Error: Encrypt for ${task.consumerAddress} was denied`,
true
)
return {
stream: null,
status: {
httpStatus: 403,
error: `Error: Encrypt for ${task.consumerAddress} was denied`
}
}
}
}
try {
const oceanNode = this.getOceanNode()
// prepare an empty array in case if
Expand Down Expand Up @@ -112,6 +145,39 @@ export class EncryptFileHandler extends CommandHandler {
if (this.shouldDenyTaskHandling(validationResponse)) {
return validationResponse
}
const isAuthRequestValid = await this.validateTokenOrSignature(
task.authorization,
task.consumerAddress,
task.nonce,
task.signature,
String(task.nonce)
)
if (isAuthRequestValid.status.httpStatus !== 200) {
return isAuthRequestValid
}

if (isPolicyServerConfigured()) {
const policyServer = new PolicyServer()
const response = await policyServer.checkEncryptFile(
task.consumerAddress,
task.policyServer,
task.files
)
if (!response) {
CORE_LOGGER.logMessage(
`Error: EncryptFile for ${task.consumerAddress} was denied`,
true
)
return {
stream: null,
status: {
httpStatus: 403,
error: `Error: EncryptFile for ${task.consumerAddress} was denied`
}
}
}
}

try {
const oceanNode = this.getOceanNode()
const config = await getConfiguration()
Expand Down
24 changes: 13 additions & 11 deletions src/components/core/handler/handler.ts
Original file line number Diff line number Diff line change
Expand Up @@ -182,17 +182,19 @@ export abstract class CommandHandler
): Promise<P2PCommandResponse> {
const oceanNode = this.getOceanNode()
const auth = oceanNode.getAuth()
const isAuthRequestValid = await auth.validateAuthenticationOrToken({
token: authToken,
address,
nonce,
signature,
message
})
if (!isAuthRequestValid.valid) {
return {
stream: null,
status: { httpStatus: 401, error: isAuthRequestValid.error }
if (auth) {
Copy link
Member

Choose a reason for hiding this comment

The reason will be displayed to describe this comment to others. Learn more.

shouldn't we return 401 if there is no auth?

const isAuthRequestValid = await auth.validateAuthenticationOrToken({
token: authToken,
address,
nonce,
signature,
message
})
if (!isAuthRequestValid.valid) {
return {
stream: null,
status: { httpStatus: 401, error: isAuthRequestValid.error }
}
}
}

Expand Down
15 changes: 12 additions & 3 deletions src/components/httpRoutes/provider.ts
Original file line number Diff line number Diff line change
Expand Up @@ -48,7 +48,10 @@ providerRoutes.post(`${SERVICES_API_BASE_PATH}/encrypt`, async (req, res) => {
encoding: 'string',
encryptionType: EncryptMethod.ECIES,
command: PROTOCOL_COMMANDS.ENCRYPT,
caller: req.caller
caller: req.caller,
nonce: req.query.nonce as string,
consumerAddress: req.query.consumerAddress as string,
signature: req.query.signature as string
})
if (result.stream) {
const encryptedData = await streamToString(result.stream as Readable)
Expand Down Expand Up @@ -100,7 +103,10 @@ providerRoutes.post(`${SERVICES_API_BASE_PATH}/encryptFile`, async (req, res) =>
rawData: input,
encryptionType: encryptMethod,
command: PROTOCOL_COMMANDS.ENCRYPT_FILE,
caller: req.caller
caller: req.caller,
nonce: req.query.nonce as string,
consumerAddress: req.query.consumerAddress as string,
signature: req.query.signature as string
})
return result
}
Expand All @@ -116,7 +122,10 @@ providerRoutes.post(`${SERVICES_API_BASE_PATH}/encryptFile`, async (req, res) =>
files: req.body as BaseFileObject,
encryptionType: encryptMethod,
command: PROTOCOL_COMMANDS.ENCRYPT_FILE,
caller: req.caller
caller: req.caller,
nonce: req.query.nonce as string,
consumerAddress: req.query.consumerAddress as string,
signature: req.query.signature as string
})
return await writeResponse(result, encryptMethod)
// raw data on body
Expand Down
27 changes: 27 additions & 0 deletions src/components/policyServer/index.ts
Original file line number Diff line number Diff line change
@@ -1,6 +1,7 @@
import { DDO } from '@oceanprotocol/ddo-js'
import { PolicyServerResult } from '../../@types/policyServer.js'
import { isDefined } from '../../utils/util.js'
import { BaseFileObject } from '../../@types/fileObject.js'

export class PolicyServer {
serverUrl: string
Expand Down Expand Up @@ -69,6 +70,32 @@ export class PolicyServer {
return await this.askServer(command)
}

async checkEncrypt(
consumerAddress: string,
policyServer: any
): Promise<PolicyServerResult> {
const command = {
action: 'encrypt',
consumerAddress,
policyServer
}
return await this.askServer(command)
}

async checkEncryptFile(
consumerAddress: string,
policyServer: any,
files?: BaseFileObject
): Promise<PolicyServerResult> {
const command = {
action: 'encryptFile',
consumerAddress,
policyServer,
files
}
return await this.askServer(command)
}

async checkDownload(
documentId: string,
ddo: DDO,
Expand Down
Loading
Loading