Skip to content

Support disabling literal stripping when extracting operations.#1703

Merged
abernix merged 6 commits intoapollographql:masterfrom
damondoucet:optionally-strip-literals
Jan 30, 2020
Merged

Support disabling literal stripping when extracting operations.#1703
abernix merged 6 commits intoapollographql:masterfrom
damondoucet:optionally-strip-literals

Conversation

@damondoucet
Copy link
Copy Markdown

@damondoucet damondoucet commented Dec 6, 2019

Fixes #1099

Adds a flag --[no]-preserveStringAndNumericLiterals to client:extract
that controls whether literals are preserved in extracted queries. Prior to
this flag, object and list literals were already preserved; that's unaffected
by this change.

As noted in the linked issue, there are a few reasons to do this, but generally
they boil down to relying on the extracted queries for some functionality, and
literals in the queries controlling important behavior (e.g. generating mock data
for queries might rely on literal args).

A flag is preferred to changing the behavior outright since older clients likely
rely on the current behavior.

TODO:

  • Update CHANGELOG.md* with your change (include reference to issue & this PR)
  • Make sure all of the significant new logic is covered by tests
  • Rebase your changes on master so that they can be merged easily
  • Make sure all tests and linter rules pass

*Make sure changelog entries note which project(s) has been affected. See older entries for examples on what this looks like.

@apollo-cla
Copy link
Copy Markdown

@damondoucet: Thank you for submitting a pull request! Before we can merge it, you'll need to sign the Apollo Contributor License Agreement here: https://contribute.apollographql.com/

@damondoucet
Copy link
Copy Markdown
Author

I left the push command alone, since the issue only references the extract
command, but I'd be happy to adjust that command as well if it's valuable!

@damondoucet damondoucet changed the title Fixes #1099: Support optionally stripping literals when extracting queries Fixes #1099: Support disabling literal stripping when extracting queries Dec 6, 2019
@damondoucet
Copy link
Copy Markdown
Author

I also wasn't sure about the casing of the no prefix - it looks a little funny
to me, but I figured I'd default to OCLIF's behavior unless encouraged otherwise. :)

@jhampton jhampton requested a review from JakeDawkins December 6, 2019 05:24
@jhampton
Copy link
Copy Markdown

jhampton commented Dec 6, 2019

Thanks @damondoucet ! I'd like input from @jbaxleyiii and the team as to whether we should include the push command, but this looks clean to me.

Cheers!

@jhampton jhampton added 🔨 cli related to the CLI itself 🎉 feature New addition or enhancement to existing solutions labels Dec 6, 2019
@jhampton jhampton self-assigned this Dec 6, 2019
@jhampton
Copy link
Copy Markdown

jhampton commented Dec 6, 2019

👍 LGTM

@jhampton jhampton requested a review from glasser December 17, 2019 06:21
Copy link
Copy Markdown
Member

@abernix abernix left a comment

Choose a reason for hiding this comment

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

Thanks for opening this PR! I support this change and my suggestions below revolve purely around clarity of the flag name.

As some back-story, it's worth noting two things:

  • The literal-stripping was originally introduced to ensure that no personally identifiable information which might be encapsulated within such literals was inadvertently shipped to the Apollo Graph Manager operation registry (e.g. API keys or passwords in string literals).
  • The client:extract command was originally intended to be a more observable/debuggable version of the client:push command.

With that second bullet-point in mind, my initial reaction to this PR was to welcome it but suggest that we maintain parity between the client:push and client:extract commands (i.e. also extend this flag to client:push). Upon further consideration, I realized that would create confusion/problems since the operation registry safe-listing plugin itself reads from the manifest published with client:push. This means that the plugin would also need to have the same preserveLiterals option introduced to it and passed along to its own invocation of defaultOperationRegistrySignature on the receiving side (read: Apollo Server). Therefore, we should keep client:push as-is and not allow it to use this flag.

Tangentially (writing this here purely for posterity, not as something you as the PR author needs to act on), in a future version of this command (and the operation registry), I'm hopeful that we can make preserving all literals the default behavior. However, I think that would be best coupled with reminders to users to (perhaps a per-operation blessing of sorts? idk, a directive?) to not use string and numeric literals, but rather use variables whenever possible for their many benefits.

Anyhow, my suggestion is that we use a more clear flag name. But note that I didn't make all necessary suggestions for renaming it. Thoughts? (On any of this, but particularly the name. 😸 )

static flags = {
...ClientCommand.flags
...ClientCommand.flags,
stripLiterals: flags.boolean({
Copy link
Copy Markdown
Member

Choose a reason for hiding this comment

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

Since "literals" also applies to object and list literals (which are not stripped), perhaps we should be a bit more clear with this option name. Even if it's a bit wordy, the intent is more clear, I think? (And its less necessary for someone to understand the notion of negated flags and perhaps more intrinsic understanding of the default behavior?). This change would require changing the default to false below and flipping other conditionals too, of course.)

Suggested change
stripLiterals: flags.boolean({
preserveStringAndNumericLiterals: flags.boolean({

stripLiterals: flags.boolean({
description:
"Whether to strip literals from extracted queries. DEFAULT: true",
default: true,
Copy link
Copy Markdown
Member

Choose a reason for hiding this comment

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

If heeding my suggestion above, this default would become false.

...ClientCommand.flags,
stripLiterals: flags.boolean({
description:
"Whether to strip literals from extracted queries. DEFAULT: true",
Copy link
Copy Markdown
Member

Choose a reason for hiding this comment

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

Suggested change
"Whether to strip literals from extracted queries. DEFAULT: true",
"Disable redaction of string and numerical literals. Without this flag, these values will be replaced with empty strings (`''`) and zeroes (`0`) respectively. This redaction is intended to avoid inadvertently outputting potentially personally identifiable information (e.g. embedded passwords or API keys) into operation manifests.",

description:
"Whether to strip literals from extracted queries. DEFAULT: true",
default: true,
allowNo: true
Copy link
Copy Markdown
Member

Choose a reason for hiding this comment

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

I believe we could get rid of this if the default was false.

Suggested change
allowNo: true

task: async ctx => {
ctx.operations = getOperationManifestFromProject(this.project);
ctx.operations = getOperationManifestFromProject(this.project, {
stripLiterals: flags.stripLiterals
Copy link
Copy Markdown
Member

Choose a reason for hiding this comment

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

I would also suggest renaming this to more accurately describe its scope:

Suggested change
stripLiterals: flags.stripLiterals
preserveStringAndNumericLiterals: flags.preserveStringAndNumericLiterals

export function getOperationManifestFromProject(
project: GraphQLClientProject
project: GraphQLClientProject,
options: { stripLiterals: boolean } = { stripLiterals: true }
Copy link
Copy Markdown
Member

Choose a reason for hiding this comment

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

Suggested change
options: { stripLiterals: boolean } = { stripLiterals: true }
options: {
preserveStringAndNumericLiterals: boolean,
} = {
preserveStringAndNumericLiterals: true,
}

Copy link
Copy Markdown
Author

Choose a reason for hiding this comment

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

Presumably, the default should also flip to false? :)

operationAST,
operationName
operationName,
{ stripLiterals: options.stripLiterals }
Copy link
Copy Markdown
Member

Choose a reason for hiding this comment

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

Suggested change
{ stripLiterals: options.stripLiterals }
{
preserveStringAndNumericLiterals:
options.preserveStringAndNumericLiterals
}

@damondoucet
Copy link
Copy Markdown
Author

Hey Jesse, thanks for getting back to me! So as not to leave this hanging - I had a chance to skim your feedback and it generally makes sense, but I won't be able to update this PR until the new year. It'll be a high priority for us then (1/7 or so). Happy holidays!

@damondoucet damondoucet requested a review from abernix January 9, 2020 20:01
@damondoucet
Copy link
Copy Markdown
Author

Thanks for the feedback @abernix. I read through and it all makes sense to me, so I've updated the PR with the corresponding changes. Let me know what you think!

@damondoucet
Copy link
Copy Markdown
Author

bump @abernix - would be great to get this merged as soon as we can since it's blocking a high priority feature for us. thanks!

@damondoucet
Copy link
Copy Markdown
Author

@abernix friendly bump - any updates on the timeline for getting this merged?

Copy link
Copy Markdown
Member

@abernix abernix left a comment

Choose a reason for hiding this comment

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

Thanks for the adjustments, and apologies for the delays in getting back to you.

I have one remaining thought and I think this is good to ship from my perspective.

(I sincerely apologize for not asking for this in my previous review. I think I got caught up with the flag name and also the holidays! If you're unable to make the change, I can make it this week and get it shipped.)

Comment thread packages/apollo-graphql/src/operationId.ts
@abernix abernix assigned abernix and jhampton and unassigned jhampton Jan 28, 2020
@damondoucet damondoucet requested a review from abernix January 28, 2020 19:49
Comment thread packages/apollo-graphql/src/operationId.ts
Copy link
Copy Markdown
Member

@abernix abernix left a comment

Choose a reason for hiding this comment

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

Yes, defaultOperationRegistrySignature is the public API and other packages are depending on it (internally and otherwise). We'll consider what changing those other packages to use the operationRegistrySignature method in the future looks like, but I think this is great for now.

We'll get this cut into a release as soon as possible. LGTM. Thanks so much! 😄

@abernix abernix changed the title Fixes #1099: Support disabling literal stripping when extracting queries Support disabling literal stripping when extracting operations. Jan 30, 2020
@abernix abernix merged commit bad312d into apollographql:master Jan 30, 2020
@damondoucet
Copy link
Copy Markdown
Author

Woo, thanks!!

@abernix
Copy link
Copy Markdown
Member

abernix commented Jan 30, 2020

@damondoucet Can you try and see if this is working for you in the latest version of the just-published apollo (apollo@2.22.0)?

@damondoucet
Copy link
Copy Markdown
Author

it works, thanks @abernix!

Sign up for free to join this conversation on GitHub. Already have an account? Sign in to comment

Labels

🔨 cli related to the CLI itself 🎉 feature New addition or enhancement to existing solutions

Projects

None yet

Development

Successfully merging this pull request may close these issues.

Extraction strips quoted operation parameters

4 participants