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

Validate query params in BaseService [npm nodeping mozillaobservatory matrix gitlab f-droid endpoint dynamic bitbucket appveyor] #3042

Merged
merged 5 commits into from
Feb 21, 2019

Conversation

paulmelnikow
Copy link
Member

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

… matrix gitlab f-droid endpoint dynamic bitbucket appveyor]

Fix #2676
@paulmelnikow paulmelnikow added service-badge New or updated service badge core Server, BaseService, GitHub auth, Shared helpers blocker PRs and epics which block other work labels Feb 19, 2019
@shields-ci
Copy link

shields-ci commented Feb 19, 2019

Warnings
⚠️ This PR modified service code for bitbucket but not its test code.
That's okay so long as it's refactoring existing code.
⚠️ This PR modified service code for dynamic but not its test code.
That's okay so long as it's refactoring existing code.
⚠️ This PR modified service code for endpoint but not its test code.
That's okay so long as it's refactoring existing code.
⚠️ This PR modified service code for f-droid but not its test code.
That's okay so long as it's refactoring existing code.
⚠️ This PR modified service code for gitlab but not its test code.
That's okay so long as it's refactoring existing code.
⚠️ This PR modified service code for matrix but not its test code.
That's okay so long as it's refactoring existing code.
⚠️ This PR modified service code for nodeping but not its test code.
That's okay so long as it's refactoring existing code.
⚠️

📚 Remember to ensure any changes to serverSecrets in services/npm/npm-base.js are reflected in the server secrets documentation

⚠️

📚 Remember to ensure any changes to serverSecrets in services/bitbucket/bitbucket-pull-request.service.js are reflected in the server secrets documentation

⚠️

Found 'assert' statement added in core/base-service/base.js.
Please ensure tests are written using Chai expect syntax

Messages
📖 ✨ Thanks for your contribution to Shields, @paulmelnikow!

Generated by 🚫 dangerJS against f3ae300

static get route() {
return {}
}

Copy link
Member Author

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)
Copy link
Member Author

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.

Copy link
Member

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
Copy link
Member Author

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() {
Copy link
Member Author

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 }) {
Copy link
Member Author

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.

Copy link
Member

@calebcartwright calebcartwright Feb 21, 2019

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(''),
Copy link
Member Author

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.

Copy link
Member

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?

Copy link
Member Author

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({
Copy link
Member Author

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(''),
Copy link
Member Author

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.

Copy link
Member

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?

Copy link
Member

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

Copy link
Member Author

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.

Copy link
Member

@calebcartwright calebcartwright Feb 21, 2019

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

👍

Copy link
Member Author

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',
Copy link
Member Author

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.

@paulmelnikow paulmelnikow temporarily deployed to shields-staging-pr-3042 February 19, 2019 04:05 Inactive
Copy link
Member

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

@paulmelnikow paulmelnikow temporarily deployed to shields-staging-pr-3042 February 20, 2019 04:19 Inactive
Copy link
Member

@calebcartwright calebcartwright left a comment

Choose a reason for hiding this comment

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

👍

@shields-deployment
Copy link

This pull request was merged to master branch. This change is now waiting for deployment, which will usually happen within a few days. Stay tuned by joining our #ops channel on Discord!

After deployment, changes are copied to gh-pages branch:

Sign up for free to join this conversation on GitHub. Already have an account? Sign in to comment
Labels
blocker PRs and epics which block other work core Server, BaseService, GitHub auth, Shared helpers service-badge New or updated service badge
Projects
None yet
Development

Successfully merging this pull request may close these issues.

3 participants