-
-
Notifications
You must be signed in to change notification settings - Fork 5.5k
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
Validate query params in BaseService [npm nodeping mozillaobservatory matrix gitlab f-droid endpoint dynamic bitbucket appveyor] #3042
Conversation
… matrix gitlab f-droid endpoint dynamic bitbucket appveyor] Fix #2676
|
static get route() { | ||
return {} | ||
} | ||
|
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.
route
is now required for invoke()
.
@@ -174,7 +175,8 @@ module.exports = class BaseService { | |||
|
|||
let base, format, pattern, queryParams | |||
try { | |||
;({ base, format, pattern, query: queryParams = [] } = this.route) | |||
;({ base, format, pattern } = this.route) | |||
queryParams = getQueryParamNames(this.route) |
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 service definition export was intended to contain a list of valid query parameters for each service. This was broken before: it always returned an empty array. Now fixed, with a test.
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.
👍
@@ -270,12 +272,44 @@ module.exports = class BaseService { | |||
|
|||
const serviceInstance = new this(context, config) | |||
|
|||
let serviceError |
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 where the validation happens.
describe('Required overrides', function() { | ||
it('Should throw if render() is not overridden', function() { | ||
expect(() => BaseService.render()).to.throw( | ||
'render() function not implemented for BaseService' | ||
) | ||
}) | ||
|
||
it('Should throw if handle() is not overridden', async function() { | ||
it('Should throw if route is not overridden', async function() { |
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.
invoke()
now requires a route
.
@@ -67,9 +69,19 @@ function namedParamsForMatch(captureNames = [], match, ServiceClass) { | |||
return result | |||
} | |||
|
|||
function getQueryParamNames({ queryParams = [], queryParamSchema }) { |
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 function translates from a Joi schema to the keys which may be considered. We need the full list of keys including the renames, in order to set the correct cache key in legacy-request-handler.
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.
What sort of circumstances warrant using Joi rename
in the schema for query params? Is it kinda along the same lines of what we used to do in pattern/format
around redirects for routes when we changed param names, (and now do with the redirect-service)?
@@ -19,16 +20,18 @@ const documentation = ` | |||
</p> | |||
` | |||
|
|||
const queryParamSchema = Joi.object({ | |||
compact_message: Joi.equal(''), |
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 kind of odd, though it's how Scoutcamp represents ?compact_message
.
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.
Odd indeed 🤔 I've no idea why that's happening, so feel inclined to ask how common an occurrence this would be? Would this only be necessary on Test related badges that had compact (I believe the Azure DevOps Test and Jenkins Test services have the compact message too) or could it happen with other params?
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.
Ah, as you surmised elsewhere, it's for any of the boolean params.
.get('/NZSmartie/coap-net-iu0to.json', { | ||
qs: { | ||
.get( | ||
`/NZSmartie/coap-net-iu0to.json?${queryString.stringify({ |
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 old version produced ?compact_message=
; the new one produces ?compact_message
which is what we are supposed to support.
@@ -26,6 +26,10 @@ const schema = Joi.object({ | |||
.required(), | |||
}).required() | |||
|
|||
const queryParamSchema = Joi.object({ | |||
publish: Joi.equal(''), |
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.
As above, this is how ?publish
is represented which is what the badge customizer creates for this badge. Have update the documentation to match.
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'm more confused now around why/when this is necessary. Is it when we're expecting query params representing a boolean value?
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.
Also if anyone is using this badge and had explicitly added a query param with false (i suppose ?publish=false
) will the param maintain the false value/get dropped entirely in the validation? Just want to make sure that wouldn't somehow get converted to ?publish
and have the reverse behavior
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'm more confused now around why/when this is necessary.
It's super confusing. camp
, querystring
and basically every other querystring library have different ideas about how to represent these values.
Is it when we're expecting query params representing a boolean value?
I'm actually not sure whether Scoutcamp passes through the string 'false'
or converts it to a boolean. Since the schema here isn't converting anything, I think it would reject ?publish=false
.
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've finished going through all the changes and ready to approve. I'd like run a quick test in my local env on this particular one just to triple check if that's cool with you
You're right. The schema validation is failing if there's a value defined for the query param (regardless of whether it is true
, false
, 1
, 0
, etc.) so there's no unexpected result publish happening
This would technically break anyone currently using the publish=true
(https://img.shields.io/mozilla-observatory/grade-score/observatory.mozilla.org.svg?publish=true
) but as we discussed offline this is a brand new badge so no real issues here
As you put it:
we're more clearly establishing the pattern that we'll follow for boolean params, so there should be less churn 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.
Yea, of course!
down_color: 'lightgrey', | ||
}, | ||
staticPreview: this.render({ | ||
status: true, | ||
upMessage: 'Online', | ||
upMessage: 'online', |
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.
Use our usual caps conventions.
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 need to spend a little more time on base.js
and route.js
and had a couple questions but overall looking good to me!
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 a mid-sized PR that adds query param validation to BaseService and updates most of the services which use query param validation to use it. There are a couple minor tweaks I made along the way.
Fix #2676