Skip to content
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

Merged
merged 6 commits into from
Sep 10, 2024
Merged

account-service: added graph key endpoints #488

merged 6 commits into from
Sep 10, 2024

Conversation

aramikm
Copy link
Contributor

@aramikm aramikm commented Sep 6, 2024

Problem

To be able to easily add graph keys we need endpoints which facilitates this operation.

Solution

implemented two new endpoints which

Screenshots (optional):

  • new endpoints
    Screenshot 2024-09-09 at 2 06 05 PM

  • endpoint that prepared the payload to add a new graph key
    Screenshot 2024-09-09 at 2 07 00 PM

  • endpoint that submits the graph key creation

Screenshot 2024-09-09 at 2 07 16 PM

  • worker logs
    Screenshot 2024-09-06 at 2 12 01 PM

  • blockchain submission
    Screenshot 2024-09-06 at 2 12 27 PM

Screenshot 2024-09-06 at 2 13 47 PM

@aramikm aramikm marked this pull request as ready for review September 6, 2024 21:19
Copy link
Contributor

@mattheworris mattheworris left a 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!

Comment on lines 38 to 63
@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);
}
Copy link
Contributor

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 new HTTP 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 )

Copy link
Contributor Author

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.

jest.config.json Outdated Show resolved Hide resolved
Copy link
Contributor

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

Copy link
Contributor Author

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.

Copy link
Contributor

Choose a reason for hiding this comment

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

.prettierignore

Copy link
Contributor Author

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.

Copy link
Contributor

Choose a reason for hiding this comment

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

.prettierignore

Copy link
Contributor Author

Choose a reason for hiding this comment

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

same

@JoeCap08055
Copy link
Contributor

JoeCap08055 commented Sep 9, 2024

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:

GET <path>/graphKeys/addKeyPayload/{key} // see my inline comment about this one; it may need to be a POST
// or
POST <path>/graphKeys/getAddKeyPayload
// (aware that getAddKeyPayload breaks the naming convention referenced, but it's a necessary evil because we have to use a POST operation to perform a GET in this scenario)

POST <path>/graphKeys // no need for any other specifier; the HTTP method & resource name tell us what the endpoint does

GET <path>/graphKeys/{msaId} // return list of all graph keys for MSA
GET <path>/graphKeys/{msaId}/{index} // get specific graph key from MSA's list of graph keys

@@ -1,14 +1,16 @@
/* eslint-disable */
export default async () => {
const t = {
Copy link
Contributor

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.

Copy link
Contributor Author

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.

Comment on lines 487 to 500
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;
}
Copy link
Contributor

Choose a reason for hiding this comment

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

Suggested change
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.');
}

Copy link
Contributor Author

@aramikm aramikm Sep 9, 2024

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

@aramikm aramikm merged commit 5afd947 into main Sep 10, 2024
11 checks passed
@aramikm aramikm deleted the add_graph_key branch September 10, 2024 17:56
@@ -0,0 +1,25 @@
import { registerDecorator, ValidationArguments, ValidationOptions } from 'class-validator';

export function IsHexPublicKey(validationOptions?: ValidationOptions) {
Copy link
Contributor

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.

Copy link
Contributor Author

@aramikm aramikm Sep 10, 2024

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.

Sign up for free to join this conversation on GitHub. Already have an account? Sign in to comment
Labels
None yet
Projects
None yet
Development

Successfully merging this pull request may close these issues.

applyItemActions (for graph encryption key management)
4 participants