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

[api] Update endpoint for getting project cost surface min and max values [MRXN23-320] #1526

Merged

Conversation

yulia-bel
Copy link
Contributor

@yulia-bel yulia-bel commented Sep 27, 2023

Endpoint for getting project cost surface min and max values

Overview

The endpoint has already been part of ProjectCostSurfaceController and was using ScenariosService to get min and max values from cost_surface_pu_data. This PR implements Cost Surface service to retrieve min and max data from (api)cost_surfaces table and adds test.

Designs

Link to the related design prototypes (if applicable)

Testing instructions

Please explain how to test the PR: ID of a dataset, steps to reach the feature, etc.

Feature relevant tickets

Link to the related task manager tickets


Checklist before submitting

  • Meaningful commits and code rebased on develop.
  • If this PR adds feature that should be tested for regressions when
    deploying to staging/production, please add brief testing instructions
    to the deploy checklist (docs/deployment-checklist.md)
  • Update CHANGELOG file

@vercel
Copy link

vercel bot commented Sep 27, 2023

The latest updates on your projects. Learn more about Vercel for Git ↗︎

Name Status Preview Comments Updated (UTC)
marxan ✅ Ready (Inspect) Visit Preview 💬 Add feedback Oct 3, 2023 3:03pm

@yulia-bel yulia-bel changed the title Update endpoint for getting project cost surface min and max values [api] Update endpoint for getting project cost surface min and max values [MRXN23-320] Sep 28, 2023
@yulia-bel yulia-bel requested a review from hotzevzl September 28, 2023 09:14
Copy link
Member

@hotzevzl hotzevzl left a comment

Choose a reason for hiding this comment

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

thanks @yulia-bel!

overall all works as expected, but see my note about the ACL check you chose - I think it will prevent users with only project viewer role from getting the range.

plus a bonus rant about not trusting user input, even if your code ends up dealing with this correctly 😄

>
> {
if (
!(await this.projectAclService.canEditCostSurfaceInProject(
Copy link
Member

Choose a reason for hiding this comment

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

why canEditCostSurfaceInProject()? this would prevent project viewers from getting cost surface range.

I'd go easy with something like this:

Suggested change
!(await this.projectAclService.canEditCostSurfaceInProject(
!(await this.projectAclService.canViewProjectt(

Or, if we want to be more specific (but I don't see much value in this specifically: users who can "view" projects should be able to view every aspect of the project, at least in terms of functionality implemented so far in MaPP), create a method such as canViewCostSurfacesInProject().

Copy link
Member

Choose a reason for hiding this comment

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

well, actually.

The trouble with the kind of logic we have here for ACLs (I've been yelling at clouds about this, just not with you... yet 😅) is that in practice, all we need to get in the endpoint URL is a scenarioId, but we include a projectId for reasons (URL design blah blah), but then, I'm not really thrilled about the way we use these.

If a malicious user somehow knows the UUID of a cost surface (or any other thing, such as a feature, the overall logic is the same) in a project they don't have access to, and request a cost surface (range, in this case) or tile, or feature, or whatever, supplying the UUID of the thing they want to see, and the projectId of any project they have access to... in your implementation here they won't have any luck because the findOne() below looks for a specific cost surface in a specific project, so they will receive a 404. But my point is, this is slightly brittle. If someone comes in months from now and makes some changes without full context, for example decide to simplify the where for whatever reason and only search for the costSurfaceId because hey, that's unique anyway, then the malicious user above will win (tm).

So I'm happy to keep this as is, because it works and it's a low-risk scenario in any case, but in practice my recommendation for these kinds of checks would be to outright ignore the projectId supplied by the user, and instead look up the projectId from the supplied scenarioId, and then check if the user can view the project.

I would not even extract the projectId from the request, nor pass it on from the controller handler to CostSurfaceService.getCostSurfaceRange() - just scenarioId and userId. Just keep the projectId in the URL to make it look kind of logical-looking but then ignore it. I'd even go as far as removing the /projects/:projectId part of the URL, but we do have this kind of parent/child URL design in several places, so I'd just leave this as is.

projectId,
))
) {
return left(projectNotEditable);
Copy link
Member

Choose a reason for hiding this comment

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

likewise, this should be a different kind of left, such as projectNotVisible from projects.service.ts

@@ -131,23 +131,35 @@ export class ProjectCostSurfaceController {

@ImplementsAcl()
@UseGuards(JwtAuthGuard)
@ApiParam({
name: 'costSurfaceId',
description: 'The id of the Cost Surface to be updated',
Copy link
Member

Choose a reason for hiding this comment

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

Suggested change
description: 'The id of the Cost Surface to be updated',
description: 'The id of the Cost Surface for which to retrieve [min,max] cost range',

@yulia-bel yulia-bel force-pushed the feature/api/MRXN23-320-cost-surface-min-max-endpoint branch from d5193fe to d3e205c Compare October 3, 2023 15:01
Copy link
Member

@hotzevzl hotzevzl left a comment

Choose a reason for hiding this comment

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

@yulia-bel let's merge! 🚀

@hotzevzl hotzevzl merged commit 2e0df9d into develop Oct 4, 2023
@hotzevzl hotzevzl deleted the feature/api/MRXN23-320-cost-surface-min-max-endpoint branch October 4, 2023 08:40
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.

2 participants