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

fix(cognito): make callbackUrls required when auth flow is set #28236

Closed
wants to merge 2 commits into from

Conversation

markmansur
Copy link
Contributor

make callbackUrls required when auth flow is explicitly set.

See comment for explanation: #28204 (comment)

Closes #28204


By submitting this pull request, I confirm that my contribution is made under the terms of the Apache-2.0 license

@aws-cdk-automation aws-cdk-automation requested a review from a team December 3, 2023 04:10
@github-actions github-actions bot added beginning-contributor [Pilot] contributed between 0-2 PRs to the CDK bug This issue is a bug. effort/small Small work item – less than a day of effort p2 labels Dec 3, 2023
Copy link
Collaborator

@aws-cdk-automation aws-cdk-automation left a comment

Choose a reason for hiding this comment

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

The pull request linter has failed. See the aws-cdk-automation comment below for failure reasons. If you believe this pull request should receive an exemption, please comment and provide a justification.

A comment requesting an exemption should contain the text Exemption Request. Additionally, if clarification is needed add Clarification Request to a comment.

@markmansur markmansur changed the title fix(aws-cognito): make callbackUrls required when auth flow is set fix(cognito): make callbackUrls required when auth flow is set Dec 3, 2023
@aws-cdk-automation aws-cdk-automation dismissed their stale review December 3, 2023 05:08

✅ Updated pull request passes all PRLinter validations. Dismissing previous PRLinter review.

@aws-cdk-automation
Copy link
Collaborator

AWS CodeBuild CI Report

  • CodeBuild project: AutoBuildv2Project1C6BFA3F-wQm2hXv2jqQv
  • Commit ID: e31d617
  • Result: SUCCEEDED
  • Build Logs (available for 30 days)

Powered by github-codebuild-logs, available on the AWS Serverless Application Repository

@aws-cdk-automation aws-cdk-automation added the pr/needs-community-review This PR needs a review from a Trusted Community Member or Core Team Member. label Dec 3, 2023
removalPolicy: RemovalPolicy.DESTROY,
});

userpool.addClient('client');
Copy link
Contributor

Choose a reason for hiding this comment

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

Why don't you define a UserPoolClient? Don't we want to test the callbackUrls

Copy link
Contributor Author

@markmansur markmansur Dec 3, 2023

Choose a reason for hiding this comment

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

The existing integ tests already test with callbackUrls,

See here:

There wasn't a test for a basic client with no props, so I added this test.

I also added the appropriate unit tests for all cases around callbackUrls.

Comment on lines +395 to +399
if (!props.oAuth && callbackUrls === undefined) {
callbackUrls = ['https://example.com'];
} else if (props.oAuth?.flows?.authorizationCodeGrant || props.oAuth?.flows?.implicitCodeGrant) {
if (callbackUrls === undefined || callbackUrls.length === 0) {
throw new Error('callbackUrls must not be empty when codeGrant or implicitGrant OAuth flows are enabled.');
Copy link
Contributor

Choose a reason for hiding this comment

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

This is quite complicated.
What do you think about following?

Suggested change
if (!props.oAuth && callbackUrls === undefined) {
callbackUrls = ['https://example.com'];
} else if (props.oAuth?.flows?.authorizationCodeGrant || props.oAuth?.flows?.implicitCodeGrant) {
if (callbackUrls === undefined || callbackUrls.length === 0) {
throw new Error('callbackUrls must not be empty when codeGrant or implicitGrant OAuth flows are enabled.');
// We set a default when the flow is `clientCredentials`, otherwise we check what is set
let callbackUrls: string[] | undefined = props.oAuth?.flows?.clientCredentials
? ['https://example.com']
: props.oAuth?.callbackUrls;
// Now we do a type guard check
if (callbackUrls === undefined || callbackUrls.length === 0) {
throw new Error('callbackUrl must not be empty when codeGrant or implicitGrant OAuth flows are enabled.');
}

Copy link
Contributor Author

@markmansur markmansur Dec 3, 2023

Choose a reason for hiding this comment

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

I don't think that gives the same result.

let callbackUrls: string[] | undefined = props.oAuth?.flows?.clientCredentials
      ? ['https://example.com']
      : props.oAuth?.callbackUrls;

This will set callbacks to example.com as long as clientCredentials is true. We don't want that. We want to use the callbacks passed in and fallback to example.com if needed.

if only clientCredentials is true, we don't require any callbacks.

Copy link
Contributor

Choose a reason for hiding this comment

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

Ah true, you're right.
So a callback URL always must be set, right?
When looking at the UI, it says this:
5343

It seems like there is no distinction between each oAuth flow.

@scanlonp
Copy link
Contributor

scanlonp commented Dec 4, 2023

@markmansur I have concerns that this may be a breaking change. I see that having example.com as a callback url is likely not desirable, but I believe that the reproduction code from the issue will now fail at synth time, where it would have successfully deployed previously, correct?

From my understanding, we add this dummy value to avoid deployment failures. Are there cases where the callback function is un-important? Such that having the dummy does not have an affect on the application? If so, I think a warning may be the best course. If a valid callback is necessary, then looking at ways to tightly couple the props could be best.

In any case, better docs and possibly a warning could work. Making sure the user knows about this behavior is the crux of the issue, right?

@scanlonp scanlonp self-assigned this Dec 4, 2023
@jolo-dev
Copy link
Contributor

jolo-dev commented Dec 5, 2023

@markmansur I have concerns that this may be a breaking change. I see that having example.com as a callback url is likely not desirable, but I believe that the reproduction code from the issue will now fail at synth time, where it would have successfully deployed previously, correct?

From my understanding, we add this dummy value to avoid deployment failures. Are there cases where the callback function is un-important? Such that having the dummy does not have an affect on the application? If so, I think a warning may be the best course. If a valid callback is necessary, then looking at ways to tightly couple the props could be best.

In any case, better docs and possibly a warning could work. Making sure the user knows about this behavior is the crux of the issue, right?

Well, if we can avoid this in code that would be best. I believe throwing an error would be the best solution.

@kaizencc
Copy link
Contributor

@markmansur @jolo-dev unfortunately when it comes to breaking changes we don't have much leeway. We simply cannot change the default as is, since it could have been successfully deployed before. We could do a feature flag, but I don't think that's necessary.

I agree with @scanlonp that the path forward for this PR to be accepted is to emit a warning instead of an error. That should be enough deterrent.

@jolo-dev
Copy link
Contributor

Hey @kaizencc @scanlonp,
Thanks for the reply.
I don't think, this is a breaking change. It should throw an error if authorizationCodeGrant and implicitCodeGrant are true and at the same time callbackUrls is not set. I agree that, we can set a default for implicitCodeGrant=true.

@kaizencc
Copy link
Contributor

@jolo-dev @markmansur

It really hinges on whether or not you dispute this comment: "I see that having example.com as a callback url is likely not desirable, but I believe that the reproduction code from the issue will now fail at synth time, where it would have successfully deployed previously, correct?"

If you do, please explain why more clearly, and we can discuss.

If you don't, CDK simply cannot turn something that successfully deploys into something that fails at synth time. We will have to find an alternate solution (which is to emit a warning only).

@jolo-dev
Copy link
Contributor

jolo-dev commented Jan 2, 2024

It really hinges on whether or not you dispute this comment: "I see that having example.com as a callback url is likely not desirable, but I believe that the reproduction code from the issue will now fail at synth time, where it would have successfully deployed previously, correct?"

@kaizencc @scanlonp
Callback URLs are interchangeable.
Even though someone has successfully deployed with example.com, it should be replaced then.

If you do, please explain why more clearly, and we can discuss.

When I tried to deploy it, I forgot to set the Callback URL and Cognito was simply not working (because it was redirecting to example.com) and in the AWS Console I saw example.com.
By the way, I tested it with the code provided by user @markmansur. I had a UserPoolClient deployed with the unchanged code and it resulted in example.com. Then I deployed it again with the code here to change the callback URL. The code worked successfully, and I received an error message when attempting to use the authorizationCodeGrant or implicitCodeGrant methods without setting the callback URL.

@scanlonp
Copy link
Contributor

scanlonp commented Jan 2, 2024

@jolo-dev I think we talking about slightly different things here. This discussion of breaking change is somewhat independent of the behavior post-deployment. If the code deploys successfully now (whether or not it functions), and we make a change which then causes that same code to now throw an error, that is a breaking change. And we cannot do that.

I believe we are in agreement that making sure the user understands that example.com will be a poor default value is a good change. However, we cannot do that by erroring out on code that deploys as-is today.

@jolo-dev
Copy link
Contributor

jolo-dev commented Jan 3, 2024

@scanlonp So you mean throwing an error is not the right way here? I don't really get it.

Okay, I give up. If that does not work then feel free to close it.

@scanlonp
Copy link
Contributor

Correct, throwing an error is not an option here.

@scanlonp scanlonp closed this Apr 10, 2024
Sign up for free to join this conversation on GitHub. Already have an account? Sign in to comment
Labels
beginning-contributor [Pilot] contributed between 0-2 PRs to the CDK bug This issue is a bug. effort/small Small work item – less than a day of effort p2 pr/needs-community-review This PR needs a review from a Trusted Community Member or Core Team Member.
Projects
None yet
Development

Successfully merging this pull request may close these issues.

aws-cognito: oAuth.callbackUrls of UserPoolClient should not have http://example.com
5 participants