-
Notifications
You must be signed in to change notification settings - Fork 1
New issue
Have a question about this project? Sign up for a free GitHub account to open an issue and contact its maintainers and the community.
By clicking “Sign up for GitHub”, you agree to our terms of service and privacy statement. We’ll occasionally send you account related emails.
Already on GitHub? Sign in to your account
account-service: added graph key endpoints #488
Conversation
apps/account-worker/src/transaction_notifier/notifier.service.ts
Outdated
Show resolved
Hide resolved
There was a problem hiding this comment.
Choose a reason for hiding this comment
The reason will be displayed to describe this comment to others. Learn more.
- Read through changes, looks good!
- Do we want to add tests for these endpoints?
🚢 it!
@Get('addKey/:msaId') | ||
@HttpCode(HttpStatus.OK) | ||
@ApiQuery({ | ||
name: 'newKey', | ||
description: 'New public key to be added in hex format', | ||
type: 'string', | ||
required: true, | ||
}) | ||
@ApiOperation({ summary: 'Get a properly encoded StatefulStorageItemizedSignaturePayloadV2 that can be signed.' }) | ||
@ApiOkResponse({ description: 'Returned an encoded StatefulStorageItemizedSignaturePayloadV2 for signing' }) | ||
/** | ||
* Using the provided query parameters, creates a new payload that can be signed to add new graph keys. | ||
* @param queryParams - The query parameters for adding a new key | ||
* @returns Payload is included for convenience. Encoded payload to be used when signing the transaction. | ||
* @throws An error if the key already exists or the payload creation fails. | ||
*/ | ||
async getAddKeyPayload( | ||
@Param('msaId') msaId: string, | ||
@Query('newKey') newKey: HexString, | ||
): Promise<AddNewGraphKeyPayloadRequest> { | ||
// this is temporary until we find a better way to enforce data validation. the validation decorator didn't work | ||
if (!isHexString(newKey)) { | ||
throw new BadRequestException('Not a valid Hex value!'); | ||
} | ||
return this.graphsService.getAddingNewKeyPayload(msaId, newKey); | ||
} |
There was a problem hiding this comment.
Choose a reason for hiding this comment
The reason will be displayed to describe this comment to others. Learn more.
While I agree that this should be a GET
operation, we need to be careful because the hex-encoded public key may be too long, depending on the web server configuration. We should either:
- confirm that the max hex-encoded key length will not break under any valid web server configuration, or
- change to a
POST
request and put the key in the request body (at least until there is more widespread support for the newHTTP QUERY
method) (this is a common workaround for essentially "GET
with a body" (see Refactor GET endpoints that use POST method to use new HTTP QUERY #219 )
There was a problem hiding this comment.
Choose a reason for hiding this comment
The reason will be displayed to describe this comment to others. Learn more.
The public key is limited to 32 byes currently. We have new issues to enforce better verifications for apis and we have another issue to limit the request size so I think that would solve the server overload.
Query is nice but I don't think a lot of clients/proxies and ... support it out of the box right now.
apps/account-worker/src/transaction_publisher/publisher.service.ts
Outdated
Show resolved
Hide resolved
openapi-specs/account.openapi.json
Outdated
There was a problem hiding this comment.
Choose a reason for hiding this comment
The reason will be displayed to describe this comment to others. Learn more.
I think this also should be in .pretttierignore
There was a problem hiding this comment.
Choose a reason for hiding this comment
The reason will be displayed to describe this comment to others. Learn more.
It already is but I think this is dependent on the code generator.
There was a problem hiding this comment.
Choose a reason for hiding this comment
The reason will be displayed to describe this comment to others. Learn more.
.prettierignore
There was a problem hiding this comment.
Choose a reason for hiding this comment
The reason will be displayed to describe this comment to others. Learn more.
It already is but I think this is dependent on the code generator.
openapi-specs/graph.openapi.json
Outdated
There was a problem hiding this comment.
Choose a reason for hiding this comment
The reason will be displayed to describe this comment to others. Learn more.
.prettierignore
There was a problem hiding this comment.
Choose a reason for hiding this comment
The reason will be displayed to describe this comment to others. Learn more.
same
Overall, looks pretty good. Left some comments inline. My biggest comment is for naming REST API endpoints. I've been trying to follow this approach. Going by that, perhaps the following endpoint names would be better, or something similar:
|
@@ -1,14 +1,16 @@ | |||
/* eslint-disable */ | |||
export default async () => { | |||
const t = { |
There was a problem hiding this comment.
Choose a reason for hiding this comment
The reason will be displayed to describe this comment to others. Learn more.
make sure to run format. this looks unformatted.
There was a problem hiding this comment.
Choose a reason for hiding this comment
The reason will be displayed to describe this comment to others. Learn more.
This is generated every time we change anything in the api and I'm not sure if we need formatting on generated code. Open to know why that might be useful.
public handlePublishGraphKeyTxResult(event: Event): ItemizedPageUpdated { | ||
const graphKeyValues: Partial<ItemizedPageUpdated> = {}; | ||
|
||
// Grab the event data | ||
if (event && this.api.events.statefulStorage.ItemizedPageUpdated.is(event)) { | ||
graphKeyValues.msaId = event.data.msaId.toString(); | ||
graphKeyValues.schemaId = event.data.schemaId.toString(); | ||
graphKeyValues.prevContentHash = event.data.prevContentHash.toString(); | ||
graphKeyValues.currContentHash = event.data.currContentHash.toString(); | ||
graphKeyValues.debugMsg = `New Graph Public Key Added for msaId: ${graphKeyValues.msaId} and schemaId: ${graphKeyValues.schemaId}`; | ||
} | ||
|
||
return graphKeyValues as ItemizedPageUpdated; | ||
} |
There was a problem hiding this comment.
Choose a reason for hiding this comment
The reason will be displayed to describe this comment to others. Learn more.
public handlePublishGraphKeyTxResult(event: Event): ItemizedPageUpdated { | |
const graphKeyValues: Partial<ItemizedPageUpdated> = {}; | |
// Grab the event data | |
if (event && this.api.events.statefulStorage.ItemizedPageUpdated.is(event)) { | |
graphKeyValues.msaId = event.data.msaId.toString(); | |
graphKeyValues.schemaId = event.data.schemaId.toString(); | |
graphKeyValues.prevContentHash = event.data.prevContentHash.toString(); | |
graphKeyValues.currContentHash = event.data.currContentHash.toString(); | |
graphKeyValues.debugMsg = `New Graph Public Key Added for msaId: ${graphKeyValues.msaId} and schemaId: ${graphKeyValues.schemaId}`; | |
} | |
return graphKeyValues as ItemizedPageUpdated; | |
} | |
public handlePublishGraphKeyTxResult(event: Event): ItemizedPageUpdated { | |
// Grab the event data | |
if (event && this.api.events.statefulStorage.ItemizedPageUpdated.is(event)) { | |
return { | |
msaId: event.data.msaId.toString(), | |
schemaId: event.data.schemaId.toString(), | |
prevContentHash: event.data.prevContentHash.toString(), | |
currContentHash: event.data.currContentHash.toString(), | |
debugMsg: `New Graph Public Key Added for msaId: ${event.data.msaId} and schemaId: ${event.data.schemaId}`, | |
}; | |
} | |
throw new Error('Graph Key Tx Result Event invalid.'); | |
} |
There was a problem hiding this comment.
Choose a reason for hiding this comment
The reason will be displayed to describe this comment to others. Learn more.
I don't think we are handling the errors correctly for these events in general. Unfortunately throwing an error alone here will not solve that issue. I opened a new issue for this #500
@@ -0,0 +1,25 @@ | |||
import { registerDecorator, ValidationArguments, ValidationOptions } from 'class-validator'; | |||
|
|||
export function IsHexPublicKey(validationOptions?: ValidationOptions) { |
There was a problem hiding this comment.
Choose a reason for hiding this comment
The reason will be displayed to describe this comment to others. Learn more.
might be nice to add some validationOptions
in here, such as:
prefixRequired: boolean
minByteLen: number
maxByteLen: number
Would make it easy to support different key algorithms in the future.
There was a problem hiding this comment.
Choose a reason for hiding this comment
The reason will be displayed to describe this comment to others. Learn more.
I'll add this in the validation specific ticket.
As an unrelated note I think going forward we have to be more careful about adding new features and functionality in general. We have a lot of existing features that needs to be hardened and adding more would only make our life harder.
One question I usually like to think about is that how hard would it be for a future developer to change this to support that extra feature or data. If it is easy enough and the probability of this being changed in the near future is low enough. Usually keeping it simple and dumb might be preferable.
The best code is no code at all!
probably from somebody wise.
Problem
To be able to easily add graph keys we need endpoints which facilitates this operation.
Solution
implemented two new endpoints which
closes
applyItemActions
(for graph encryption key management) #414Screenshots (optional):
new endpoints
endpoint that prepared the payload to add a new graph key
endpoint that submits the graph key creation
worker logs
blockchain submission