Skip to content

Commit

Permalink
rip out records subscribe
Browse files Browse the repository at this point in the history
  • Loading branch information
LiranCohen committed Jan 10, 2024
1 parent f49e516 commit 00d436d
Show file tree
Hide file tree
Showing 26 changed files with 16 additions and 2,099 deletions.
2 changes: 0 additions & 2 deletions build/compile-validators.js
Original file line number Diff line number Diff line change
Expand Up @@ -45,7 +45,6 @@ import RecordsDelete from '../json-schemas/interface-methods/records-delete.json
import RecordsFilter from '../json-schemas/interface-methods/records-filter.json' assert { type: 'json' };
import RecordsQuery from '../json-schemas/interface-methods/records-query.json' assert { type: 'json' };
import RecordsRead from '../json-schemas/interface-methods/records-read.json' assert { type: 'json' };
import RecordsSubscribe from '../json-schemas/interface-methods/records-subscribe.json' assert { type: 'json' };
import RecordsWrite from '../json-schemas/interface-methods/records-write.json' assert { type: 'json' };
import RecordsWriteSignaturePayload from '../json-schemas/signature-payloads/records-write-signature-payload.json' assert { type: 'json' };
import RecordsWriteUnidentified from '../json-schemas/interface-methods/records-write-unidentified.json' assert { type: 'json' };
Expand All @@ -56,7 +55,6 @@ const schemas = {
AuthorizationOwner,
RecordsDelete,
RecordsQuery,
RecordsSubscribe,
RecordsWrite,
RecordsWriteUnidentified,
EventsFilter,
Expand Down
1 change: 0 additions & 1 deletion json-schemas/interface-methods/protocol-rule-set.json
Original file line number Diff line number Diff line change
Expand Up @@ -66,7 +66,6 @@
"enum": [
"delete",
"query",
"subscribe",
"read",
"update",
"write"
Expand Down
44 changes: 0 additions & 44 deletions json-schemas/interface-methods/records-subscribe.json

This file was deleted.

3 changes: 0 additions & 3 deletions json-schemas/permissions/permissions-definitions.json
Original file line number Diff line number Diff line change
Expand Up @@ -28,9 +28,6 @@
},
{
"$ref": "https://identity.foundation/dwn/json-schemas/permissions/scopes.json#/definitions/records-query-scope"
},
{
"$ref": "https://identity.foundation/dwn/json-schemas/permissions/scopes.json#/definitions/records-subscribe-scope"
}
]
},
Expand Down
18 changes: 0 additions & 18 deletions json-schemas/permissions/scopes.json
Original file line number Diff line number Diff line change
Expand Up @@ -106,24 +106,6 @@
"type": "string"
}
}
},
"records-subscribe-scope": {
"type": "object",
"required": [
"interface",
"method"
],
"properties": {
"interface": {
"const": "Records"
},
"method": {
"const": "Subscribe"
},
"protocol": {
"type": "string"
}
}
}
}
}
3 changes: 0 additions & 3 deletions src/core/dwn-error.ts
Original file line number Diff line number Diff line change
Expand Up @@ -101,9 +101,6 @@ export enum DwnErrorCode {
RecordsQueryFilterMissingRequiredProperties = 'RecordsQueryFilterMissingRequiredProperties',
RecordsReadReturnedMultiple = 'RecordsReadReturnedMultiple',
RecordsReadAuthorizationFailed = 'RecordsReadAuthorizationFailed',
RecordsSubscribeFilterMissingRequiredProperties = 'RecordsSubscribeFilterMissingRequiredProperties',
RecordsSubscribeUnauthorized = 'RecordsSubscribeUnauthorized',
RecordsSubscribeUnknownError = 'RecordsSubscribeUnknownError',
RecordsSchemasDerivationSchemeMissingSchema = 'RecordsSchemasDerivationSchemeMissingSchema',
RecordsValidateIntegrityDelegatedGrantAndIdExistenceMismatch = 'RecordsValidateIntegrityDelegatedGrantAndIdExistenceMismatch',
RecordsValidateIntegrityGrantedToAndSignerMismatch = 'RecordsValidateIntegrityGrantedToAndSignerMismatch',
Expand Down
51 changes: 3 additions & 48 deletions src/core/protocol-authorization.ts
Original file line number Diff line number Diff line change
Expand Up @@ -3,7 +3,6 @@ import type { MessageStore } from '../types/message-store.js';
import type { RecordsDelete } from '../interfaces/records-delete.js';
import type { RecordsQuery } from '../interfaces/records-query.js';
import type { RecordsRead } from '../interfaces/records-read.js';
import type { RecordsSubscribe } from '../interfaces/records-subscribe.js';
import type { RecordsWriteMessage } from '../types/records-types.js';
import type { ProtocolActionRule, ProtocolDefinition, ProtocolRuleSet, ProtocolsConfigureMessage, ProtocolType, ProtocolTypes } from '../types/protocols-types.js';

Expand Down Expand Up @@ -153,47 +152,6 @@ export class ProtocolAuthorization {
);
}

public static async authorizeSubscription(
tenant: string,
incomingMessage: RecordsSubscribe,
messageStore: MessageStore,
): Promise<void> {
// validate that required properties exist in subscription filter
const { protocol, protocolPath, contextId } = incomingMessage.message.descriptor.filter;

// fetch the protocol definition
const protocolDefinition = await ProtocolAuthorization.fetchProtocolDefinition(
tenant,
protocol!, // `authorizeSubscription` is only called if `protocol` is present
messageStore,
);

// get the rule set for the inbound message
const inboundMessageRuleSet = ProtocolAuthorization.getRuleSet(
protocolPath!, // presence of `protocolPath` is verified in `parse()`
protocolDefinition,
);

// If the incoming message has `protocolRole` in the descriptor, validate the invoked role
await ProtocolAuthorization.verifyInvokedRole(
tenant,
incomingMessage,
protocol!,
contextId,
protocolDefinition,
messageStore,
);

// verify method invoked against the allowed actions
await ProtocolAuthorization.verifyAllowedActions(
tenant,
incomingMessage,
inboundMessageRuleSet,
[], // ancestor chain is not relevant to subscriptions
messageStore,
);
}

/**
* Performs protocol-based authorization against the incoming RecordsQuery message.
* @throws {Error} if authorization fails.
Expand Down Expand Up @@ -465,7 +423,7 @@ export class ProtocolAuthorization {
*/
private static async verifyInvokedRole(
tenant: string,
incomingMessage: RecordsDelete | RecordsQuery | RecordsRead | RecordsSubscribe | RecordsWrite,
incomingMessage: RecordsDelete | RecordsQuery | RecordsRead | RecordsWrite,
protocolUri: string,
contextId: string | undefined,
protocolDefinition: ProtocolDefinition,
Expand Down Expand Up @@ -523,7 +481,7 @@ export class ProtocolAuthorization {
*/
private static async getActionsSeekingARuleMatch(
tenant: string,
incomingMessage: RecordsDelete | RecordsQuery | RecordsRead | RecordsSubscribe | RecordsWrite,
incomingMessage: RecordsDelete | RecordsQuery | RecordsRead | RecordsWrite,
messageStore: MessageStore,
): Promise<ProtocolAction[]> {

Expand All @@ -537,9 +495,6 @@ export class ProtocolAuthorization {
case DwnMethodName.Read:
return [ProtocolAction.Read];

case DwnMethodName.Subscribe:
return [ProtocolAction.Subscribe];

case DwnMethodName.Write:
const incomingRecordsWrite = incomingMessage as RecordsWrite;
if (await incomingRecordsWrite.isInitialWrite()) {
Expand All @@ -564,7 +519,7 @@ export class ProtocolAuthorization {
*/
private static async verifyAllowedActions(
tenant: string,
incomingMessage: RecordsDelete | RecordsQuery | RecordsRead | RecordsSubscribe | RecordsWrite,
incomingMessage: RecordsDelete | RecordsQuery | RecordsRead | RecordsWrite,
inboundMessageRuleSet: ProtocolRuleSet,
ancestorMessageChain: RecordsWriteMessage[],
messageStore: MessageStore,
Expand Down
36 changes: 1 addition & 35 deletions src/core/records-grant-authorization.ts
Original file line number Diff line number Diff line change
@@ -1,7 +1,7 @@
import type { MessageStore } from '../types/message-store.js';
import type { RecordsPermissionScope } from '../types/permissions-grant-descriptor.js';
import type { PermissionsGrantMessage, RecordsPermissionsGrantMessage } from '../types/permissions-types.js';
import type { RecordsDeleteMessage, RecordsQueryMessage, RecordsReadMessage, RecordsSubscribeMessage, RecordsWriteMessage } from '../types/records-types.js';
import type { RecordsDeleteMessage, RecordsQueryMessage, RecordsReadMessage, RecordsWriteMessage } from '../types/records-types.js';

import { GrantAuthorization } from './grant-authorization.js';
import { PermissionsConditionPublication } from '../types/permissions-grant-descriptor.js';
Expand Down Expand Up @@ -96,40 +96,6 @@ export class RecordsGrantAuthorization {
}
}

/**
* Authorizes the scope of a PermissionsGrant for RecordsSubscribe.
* @param messageStore Used to check if the grant has been revoked.
*/
public static async authorizeSubscribe(input: {
recordsSubscribeMessage: RecordsSubscribeMessage,
expectedGrantedToInGrant: string,
expectedGrantedForInGrant: string,
permissionsGrantMessage: PermissionsGrantMessage,
messageStore: MessageStore,
}): Promise<void> {
const {
recordsSubscribeMessage, expectedGrantedToInGrant, expectedGrantedForInGrant, permissionsGrantMessage, messageStore
} = input;

await GrantAuthorization.performBaseValidation({
incomingMessage: recordsSubscribeMessage,
expectedGrantedToInGrant,
expectedGrantedForInGrant,
permissionsGrantMessage,
messageStore
});

// If the grant specifies a protocol, the query must specify the same protocol.
const protocolInGrant = (permissionsGrantMessage.descriptor.scope as RecordsPermissionScope).protocol;
const protocolInSubscribe = recordsSubscribeMessage.descriptor.filter.protocol;
if (protocolInGrant !== undefined && protocolInSubscribe !== protocolInGrant) {
throw new DwnError(
DwnErrorCode.RecordsGrantAuthorizationSubscribeProtocolScopeMismatch,
`Grant protocol scope ${protocolInGrant} does not match protocol in subscribe ${protocolInSubscribe}`
);
}
}

/**
* Authorizes the scope of a PermissionsGrant for RecordsDelete.
* @param messageStore Used to check if the grant has been revoked.
Expand Down
9 changes: 1 addition & 8 deletions src/dwn.ts
Original file line number Diff line number Diff line change
Expand Up @@ -11,7 +11,7 @@ import type { GenericMessage, GenericMessageReply } from './types/message-types.
import type { MessagesGetMessage, MessagesGetReply } from './types/messages-types.js';
import type { PermissionsGrantMessage, PermissionsRequestMessage, PermissionsRevokeMessage } from './types/permissions-types.js';
import type { ProtocolsConfigureMessage, ProtocolsQueryMessage, ProtocolsQueryReply } from './types/protocols-types.js';
import type { RecordsDeleteMessage, RecordsQueryMessage, RecordsQueryReply, RecordsReadMessage, RecordsReadReply, RecordsSubscribeMessage, RecordsSubscribeReply, RecordsWriteMessage } from './types/records-types.js';
import type { RecordsDeleteMessage, RecordsQueryMessage, RecordsQueryReply, RecordsReadMessage, RecordsReadReply, RecordsWriteMessage } from './types/records-types.js';

import { AllowAllTenantGate } from './core/tenant-gate.js';
import { DidResolver } from './did/did-resolver.js';
Expand All @@ -30,7 +30,6 @@ import { ProtocolsQueryHandler } from './handlers/protocols-query.js';
import { RecordsDeleteHandler } from './handlers/records-delete.js';
import { RecordsQueryHandler } from './handlers/records-query.js';
import { RecordsReadHandler } from './handlers/records-read.js';
import { RecordsSubscribeHandler } from './handlers/records-subscribe.js';
import { RecordsWriteHandler } from './handlers/records-write.js';
import { DwnInterfaceName, DwnMethodName } from './enums/dwn-interface-method.js';

Expand Down Expand Up @@ -116,11 +115,6 @@ export class Dwn {
this.messageStore,
this.dataStore
),
[DwnInterfaceName.Records + DwnMethodName.Subscribe]: new RecordsSubscribeHandler(
this.didResolver,
this.messageStore,
this.eventStream
),
[DwnInterfaceName.Records + DwnMethodName.Write]: new RecordsWriteHandler(
this.didResolver,
this.messageStore,
Expand Down Expand Up @@ -174,7 +168,6 @@ export class Dwn {
public async processMessage(tenant: string, rawMessage: PermissionsRevokeMessage): Promise<GenericMessageReply>;
public async processMessage(tenant: string, rawMessage: RecordsDeleteMessage): Promise<GenericMessageReply>;
public async processMessage(tenant: string, rawMessage: RecordsQueryMessage): Promise<RecordsQueryReply>;
public async processMessage(tenant: string, rawMessage: RecordsSubscribeMessage): Promise<RecordsSubscribeReply>;
public async processMessage(tenant: string, rawMessage: RecordsReadMessage): Promise<RecordsReadReply>;
public async processMessage(tenant: string, rawMessage: RecordsWriteMessage, dataStream?: Readable): Promise<GenericMessageReply>;
public async processMessage(tenant: string, rawMessage: unknown, dataStream?: Readable): Promise<UnionMessageReply>;
Expand Down
16 changes: 1 addition & 15 deletions src/event-log/event-stream.ts
Original file line number Diff line number Diff line change
Expand Up @@ -3,14 +3,11 @@ import type { EventsSubscribeMessage, EventsSubscription } from '../types/events
import type { EventStream, SubscriptionHandler } from '../types/subscriptions.js';
import type { Filter, KeyValues } from '../types/query-types.js';
import type { GenericMessage, GenericMessageSubscription } from '../types/message-types.js';
import type { RecordsSubscribeMessage, RecordsSubscription } from '../types/records-types.js';

import { EventEmitter } from 'events';
import { EventsSubscribe } from '../interfaces/events-subscribe.js';
import { EventsSubscriptionHandler } from '../handlers/events-subscribe.js';
import { Message } from '../core/message.js';
import { RecordsSubscribe } from '../interfaces/records-subscribe.js';
import { RecordsSubscriptionHandler } from '../handlers/records-subscribe.js';
import { DwnError, DwnErrorCode } from '../core/dwn-error.js';

const eventChannel = 'events';
Expand Down Expand Up @@ -45,25 +42,14 @@ export class EventStreamEmitter implements EventStream {
};

async subscribe(tenant: string, message: EventsSubscribeMessage, filters: Filter[], messageStore: MessageStore): Promise<EventsSubscription>;
async subscribe(tenant: string, message: RecordsSubscribeMessage, filters: Filter[], messageStore: MessageStore): Promise<RecordsSubscription>;
async subscribe(tenant: string, message: GenericMessage, filters: Filter[], messageStore: MessageStore): Promise<GenericMessageSubscription> {
const messageCid = await Message.getCid(message);
let subscription = this.subscriptions.get(messageCid);
if (subscription !== undefined) {
return subscription;
}

if (RecordsSubscribe.isRecordsSubscribeMessage(message)) {
subscription = await RecordsSubscriptionHandler.create({
tenant,
message,
filters,
messageStore,
unsubscribe : () => this.unsubscribe(messageCid),
eventEmitter : this.eventEmitter,
reauthorizationTTL : this.reauthorizationTTL,
});
} else if (EventsSubscribe.isEventsSubscribeMessage(message)) {
if (EventsSubscribe.isEventsSubscribeMessage(message)) {
subscription = await EventsSubscriptionHandler.create({
tenant,
message,
Expand Down
2 changes: 0 additions & 2 deletions src/event-log/subscription.ts
Original file line number Diff line number Diff line change
Expand Up @@ -9,8 +9,6 @@ import { FilterUtility } from '../utils/filter.js';

/**
* Base class to extend default subscription behavior.
*
* ie. `RecordsSubscriptionHandler` has different rules for authorization and only matches specific message types.
*/
export class SubscriptionHandlerBase implements SubscriptionHandler {
protected eventEmitter: EventEmitter;
Expand Down
Loading

0 comments on commit 00d436d

Please sign in to comment.