amplify-category-api icon indicating copy to clipboard operation
amplify-category-api copied to clipboard

api gql-compile produces wrong auth VTL for Mutation

Open nilyin opened this issue 10 months ago • 22 comments

How did you install the Amplify CLI?

npm

If applicable, what version of Node.js are you using?

v21.7.1

Amplify CLI Version

12.10.3

What operating system are you using?

Mac, Win10

Did you make any manual changes to the cloud resources managed by Amplify? Please describe the changes made.

No

Describe the bug

after amplify api gql-compile the vtl file for deleteComponent mutation has no code to process "User Pool Authorization", which results to authorization error in graphql Mutation deleteComponet. My generated Mutation.deleteComponent.auth.1.res.vtl file content (bad file):

## [Start] Authorization Steps. 
$util.qr($ctx.stash.put("hasAuth", true))
#set( $isAuthorized = false )
#if( $util.authType() == "API Key Authorization" )
$util.unauthorized()
#end
#if( $util.authType() == "IAM Authorization" )
  #foreach( $adminRole in $ctx.stash.adminRoles )
    #if( $ctx.identity.userArn.contains($adminRole) && $ctx.identity.userArn != $ctx.stash.authRole && $ctx.identity.userArn != $ctx.stash.unauthRole )
      #return($util.toJson({}))
    #end
  #end
$util.unauthorized()
#end
#if( $util.authType() == "User Pool Authorization" )

#end
#if( !$isAuthorized )
$util.unauthorized()
#end
$util.toJson({"version":"2018-05-29","payload":{}})
## [End] Authorization Steps.

when i've tried to use new machine and installed all codebase and deps i initially received correct (good) file content for "User Pool Authorization":

## [Start] Authorization Steps. 
$util.qr($ctx.stash.put("hasAuth", true))
#set( $isAuthorized = false )
#if( $util.authType() == "API Key Authorization" )
$util.unauthorized()
#end
#if( $util.authType() == "User Pool Authorization" )
  #if( !$isAuthorized )
    #set( $ownerEntity0 = $util.defaultIfNull($ctx.result.userCreated, null) )
    #set( $ownerClaim0 = $util.defaultIfNull($ctx.identity.claims.get("sub"), null) )
    #if( !$util.isNull($ownerClaim0) )

      #set( $ownerClaimsList0 = [] )
      #if( $ownerEntity0 == $ownerClaim0 || $ownerClaimsList0.contains($ownerEntity0) )
        #set( $isAuthorized = true )
      #end
    #end
  #end
  #if( !$isAuthorized )
    #set( $ownerEntity1 = $util.defaultIfNull($ctx.result.owners, null) )
    #set( $ownerClaim1 = $util.defaultIfNull($ctx.identity.claims.get("sub"), null) )
    #if( !$util.isNull($ownerClaim1) )

      #set( $ownerClaimsList1 = [] )
      #foreach( $allowedOwner in $ownerEntity1 )
        #if( $allowedOwner == $ownerClaim1 || $ownerClaimsList1.contains($allowedOwner) )
          #set( $isAuthorized = true )
        #end
      #end
    #end
  #end
#end
#if( !$isAuthorized )
$util.unauthorized()
#end
$util.toJson({"version":"2018-05-29","payload":{}})
## [End] Authorization Steps.

when I have initialized my backend env and did amplify pull my good vtl file above was rewritten to bad one from the cloud backend. But when weird things happened: my following amplify api gql-compile commands stopped generating the correct file (only bad file above was genereted every time). BTW my deleting of build/resolvers/* files didn't help at all.

What could happen? Why vtl engine stopped working correctly if my original schema.graphql file wasn't changed?

Expected behavior

correct (good) vtl / reolver file is to be generated

Reproduction steps

  1. amplify pull from my backend
  2. run amplify api gql-compile

Project Identifier

0682ade323272668435183796fe4bc9e

Log output

# Put your logs below this line


Additional information

No response

Before submitting, please confirm:

  • [X] I have done my best to include a minimal, self-contained set of instructions for consistently reproducing the issue.
  • [X] I have removed any sensitive information from my code snippets and submission.

nilyin avatar Apr 12 '24 15:04 nilyin

Hey,👋 thanks for raising this! I'm going to transfer this over to our API repository for better assistance 🙂

ykethan avatar Apr 12 '24 15:04 ykethan

I notice you have IAM Authorization in the bad code which is missing in the correct code. Do you have any admin roles defined in the file custom-roles.json which is mentioned here? I also cannot find it in the uploaded project folder, which could be related to the difference of the resolvers.

AaronZyLee avatar Apr 18 '24 18:04 AaronZyLee

Hi, I don't know why correct vtl code has missing IAM Authorization section, as my schema.graphql contains: { allow: public, operations: [read], provider: iam } in @auth for Component model. I can provide Component model definition or whole schema file, if needed. I have no admin roles defined as well as custom-roles.json file in my project. I am using multi auth: Cognito UserPool for authorized users and IAM for Unauthorized ones.

nilyin avatar Apr 18 '24 19:04 nilyin

I maybe had some similar problems. Try to reorder the rules array, than it should be work. If yes, maybe there is a bug than.

biller-aivy avatar Apr 18 '24 21:04 biller-aivy

I tried to reorder @auth rules but it hasn't solved the problem. My current rules set is given below:

type Component @model @auth (
        rules: [
          { allow: public, operations: [read], provider: iam },
          { allow: public, operations: [read] },
          { allow: owner, ownerField: "userCreated", identityClaim: "sub"},
          { allow: owner, ownerField: "owners", identityClaim: "sub"},
          { allow: owner, ownerField: "organizationID", identityClaim: "website", operations: [create, read] },
          { allow: private, operations: [read] }
      ]
  )

I have also just upgraded amplify-cli to 12.11.1 but had no change.

nilyin avatar Apr 18 '24 22:04 nilyin

@nilyin an other tip, don't use sub as the claim. When you ever have to restore your users to a new instance of cognito Pool, the sub will be not the same because this is unique in the whole cognito service. Username is the "for me" better solution and in my setup, the same value like sub.

Second info: I had to play around some pushes, I couldn't create items with a create rule. After I played with the rules, at some point it just works. (Maybe this was an other problem like cache or something)

biller-aivy avatar Apr 19 '24 06:04 biller-aivy

@biller-aivy thanks for your advice on token's username as a claim. BTW, I was thinking on using sub value for id field of my User model, but stick with generating different id (to be independent from potentially numerous IDPs). My User's owner field keeps actual 'sub' value. Do you use the same approach? if not, why?

About current issue: in my case only resolver for deleteComponent Mutation is broken. My experiments show that it happened after amplify pull command. As this pulling shouldn't touch / change my local amplify/backend/api/{myprojectname}/schema.graphql file the problem IMHO is not with schema file but in some other file / setting that has been modified by pulling from cloud backend. I was trying to look through all the changes made, but haven't detected anything suspicious. Still waiting for a help from Amplify team.

nilyin avatar Apr 20 '24 14:04 nilyin

@biller-aivy thanks for your advice on token's username as a claim. BTW, I was thinking on using sub value for id field of my User model, but stick with generating different id (to be independent from potentially numerous IDPs). My User's owner field keeps actual 'sub' value. Do you use the same approach? if not, why?

About current issue: in my case only resolver for deleteComponent Mutation is broken. My experiments show that it happened after amplify pull command. As this pulling shouldn't touch / change my local amplify/backend/api/{myprojectname}/schema.graphql file the problem IMHO is not with schema file but in some other file / setting that has been modified by pulling from cloud backend. I was trying to look through all the changes made, but haven't detected anything suspicious. Still waiting for a help from Amplify team.

{
        allow: owner
        identityClaim: "username" #  explicit use of username
      }

with this, you can use username as clam in the Schema. In my Case, sub and username is the same value. The Problem is, when you create a new UserPool, than the sub is different from username and different from current sub.

Or did I misunderstand your question?

biller-aivy avatar Apr 20 '24 17:04 biller-aivy

@biller-aivy I was asking about id field for your user record. Is it different from sub value generated by Cognito and is sub value only kept in owner attribute?

nilyin avatar Apr 23 '24 05:04 nilyin

to Amplify team: is there any way (such as command line option) to turn on debug or verbose mode for amplify api gql-compile command?

nilyin avatar Apr 23 '24 05:04 nilyin

@biller-aivy I was asking about id field for your user record. Is it different from sub value generated by Cognito and is sub value only kept in owner attribute?

At the moment it is the same id like the sub/username but it is not necessary for my logic. I replaced all sub to username in my code. And the user I call by owner with an secondary index. The risk is to high if we need a recovery system with a new userpool.

biller-aivy avatar Apr 23 '24 06:04 biller-aivy

@AnilMaktala hi, did you find any clue to my problem with corrupted deleteComponent Mutation's VTL generation? Or at least pls. give me an idea how can i debug amplify api gql-compile command by myself.

nilyin avatar May 15 '24 14:05 nilyin

Hi @nilyin, can you check if you have a file override for that resolver defined under api/<apiName>/resolvers directory? This is not under the build directory.

phani-srikar avatar May 24 '24 20:05 phani-srikar

Hi @phani-srikar : my api/<apiName>/resolvers folder has no overrides. Pls. let me know if you need any other information.

nilyin avatar May 25 '24 15:05 nilyin

Hey @nilyin, Can you please try adding below sample model in your local machine and run amplify gql-compile and provide us the generated resolvers?

type Component @model @auth (
        rules: [
          { allow: public, operations: [read], provider: iam },
          { allow: public, operations: [read] },
          { allow: owner, ownerField: "userCreated", identityClaim: "sub"},
          { allow: owner, ownerField: "owners", identityClaim: "sub"},
          { allow: owner, ownerField: "organizationID", identityClaim: "website", operations: [create, read] },
          { allow: private, operations: [read] }
      ]
  )

AnilMaktala avatar Aug 12 '24 18:08 AnilMaktala

hi @AnilMaktala , thank you for getting back to me. So, what I've done:

  1. i have replaced schema.graphql file in my existing project with file, which only has your sample empty model
  2. I have cleaned all current resolvers in <myproject>/build/resolvers folder
  3. i've run command amplify api gql-compile

after that I have got this output in terminal:

` ⚠️ WARNING: Schema is using an @auth directive with deprecated provider 'iam'. Replace 'iam' provider with 'identityPool' provider. 🛑 Removing a model from the GraphQL schema will also remove the underlying DynamoDB table. This update will remove table(s) [ArchitectureTable, ComponentSubscriptionTable, OrganizationTable, OsTable, RoleTable, TeamTable, UserTable] ALL EXISTING DATA IN THESE TABLES WILL BE LOST! If this is intended, rerun the command with '--allow-destructive-graphql-schema-updates'.

The generated resolvers and schema.graphql are attached: build_folder_resolvers.zip

nilyin avatar Aug 12 '24 21:08 nilyin

Hi @AnilMaktala are there any news? It looks like single model (Component) schema.graphql generates not empty User Pool Authorization section.

What should I do next?

Is it possible that things mentioned in this amplify api gql-compile command message affect the deleteComponent resolver generation:

Be careful when using @auth directives on a field in a root type. @auth directives on field definitions use the source object to perform authorization logic and the source will be an empty object for fields on root types. Static group authorization should perform as expected. ✅ GraphQL schema compiled successfully.

nilyin avatar Aug 16 '24 09:08 nilyin

Hi @nilyin, The issue you are facing appears to be specific to your particular scenario. Would you be available for a call where we can screen share, allowing me to better understand and assist you with resolving the problem?

AnilMaktala avatar Sep 06 '24 19:09 AnilMaktala

Anil, hi. Yes, I'll be available for a call Mon -Thursday upcoming week. Please send me a link for a meeting at your convenience.

Thank you, N.

пт, 6 сент. 2024 в 23:00 Anil @.***> написал(-а):

Hi @nilyin, The issue you are facing appears to be specific to your particular scenario. Would you be available for a call where we can screen share, allowing me to better understand and assist you with resolving the problem?

— Reply to this email directly, view it on GitHub, or unsubscribe. You are receiving this because you were mentioned.Message ID: @.***>

nilyin avatar Sep 08 '24 12:09 nilyin

@AnilMaktala hi, can you please offer possible time-slots for today or dates at the end of next week? You may send it to directly to my email.

nilyin avatar Sep 18 '24 07:09 nilyin

Hi @nilyin, Are you on Discord? If so, could you please share your Discord username with me?

AnilMaktala avatar Sep 19 '24 22:09 AnilMaktala

Anil, hi: I don't have discord. I use zoom, telegram, google meet, whatsapp.

Can we use these ones or Discord is the only option for you and i need to create account there? Thanks., N.

пт, 20 сент. 2024 в 1:07 Anil @.***> написал(-а):

Hi @nilyin, Are you on Discord? If so, could you please share your Discord username with me?

— Reply to this email directly, view it on GitHub, or unsubscribe. You are receiving this because you were mentioned.Message ID: @.***>

nilyin avatar Sep 20 '24 17:09 nilyin

Hi @nilyin, Discord is the preferred platform for communication. Would you mind creating an account there?

AnilMaktala avatar Sep 26 '24 00:09 AnilMaktala

Anil, hi. I signed up with Discord. Please send me an invite link (my id: nicktech5481) or you may join my group at link: Join the peerf-amplify Discord Server!

| | | | Join the peerf-amplify Discord Server!

Check out the peerf-amplify community on Discord - hang out with 1 other members and enjoy free voice and text c... |

|

|

Can we talk on Monday? A  time is up to you. Thanks, N.

четверг, 26 сентября 2024 г. в 03:58:00 GMT+3, Anil Maktala ***@***.***> написал(-а):  

Hi @nilyin, Discord is the preferred platform for communication. Would you mind creating an account there?

— Reply to this email directly, view it on GitHub, or unsubscribe. You are receiving this because you were mentioned.Message ID: @.***>

nilyin avatar Sep 28 '24 18:09 nilyin

Hey @nilyin,I sent you a direct message on Discord yesterday. Could you please take a moment to respond?

AnilMaktala avatar Oct 02 '24 20:10 AnilMaktala

Hey @nilyin, Thank you for your time on the call. I was able to replicate the issue using the provided schema and will now mark it as a bug for the team to investigate further.

image

AnilMaktala avatar Oct 04 '24 18:10 AnilMaktala