awslabs / aws-api-gateway-developer-portal

A Serverless Developer Portal for easily publishing and cataloging APIs
Apache License 2.0
927 stars 399 forks source link

My Dashboard link and 'Try me' not being shown for registered user. #409

Open steve-be-old opened 4 years ago

steve-be-old commented 4 years ago

I have the AWS dev portal running locally and deployed to a non-prod AWS account. If I log in as an admin, I get the My Dashboard which shows the API key, and can perform the Try me functionality. If I log in as a non-admin, I don't get either. I can see API's but no My Dashboard with a key and no try me. Here is what I have found: For the non-admin user, in Cognito, their role is: “dev-entarch-api-gateway-dev-portal-aCognitoRegisteredRole”

In the REACT code of the dev portal, the check to display the tab, and ultimately set 'isRegistered' to true is in dev-portal/src/services/self.js as follows:

    const role = getPreferredRole()
      return (
        role.includes('-CognitoAdminRole-') ||
        role.includes('-CognitoRegisteredRole-')
      )

So I can see my role would never match the '-CognitoRegisteredRole-'. I tested by removing the two dashes from that check, and then it worked.

I am trying to determine what I have done that cause it. The roles are set in the cloudformation/template.yaml. I have needed to alter that as I need Permissionboundries on most roles. Here is what my current template.yaml looks like for this new role:

CognitoRegisteredRole:
    Type: AWS::IAM::Role
    Properties:
    # MY-CUSTOM-CODE  BEGIN
      PermissionsBoundary: !Sub arn:aws:iam::${AWS::AccountId}:policy/ggg/boundaries/apps/GggAppPermissionsBoundaryWithIAM
      Path: "/ggg/apps/devportal/"
      RoleName: !Join
        - ''
        - - !Ref AWS::StackName
          - 'CognitoRegisteredRole'
    # MY-CUSTOM-CODE  END

      AssumeRolePolicyDocument:
        Version: '2012-10-17'
        Statement:
        - Effect: Allow
          Principal:
            Federated: cognito-identity.amazonaws.com
          Action: sts:AssumeRoleWithWebIdentity
          Condition:
            StringEquals:
              'cognito-identity.amazonaws.com:aud': !Ref CognitoIdentityPool
            'ForAnyValue:StringLike':
              'cognito-identity.amazonaws.com:amr': authenticated
      Policies:
      - PolicyName: CognitoRegisteredRole
        PolicyDocument:
          Version: '2012-10-17'
          Statement:
          - Effect: Allow
            Action:
            - execute-api:Invoke
            Resource: !Join
              - ''
              - - 'arn:aws:execute-api:'
                - !Ref 'AWS::Region'
                - ':'
                - !Ref 'AWS::AccountId'
                - ':'
                - !Ref ApiGatewayApi
                - /prod/*/*
          - Effect: Deny
            Action:
            - execute-api:Invoke
            Resource: !Join
              - ''
              - - 'arn:aws:execute-api:'
                - !Ref 'AWS::Region'
                - ':'
                - !Ref 'AWS::AccountId'
                - ':'
                - !Ref ApiGatewayApi
                - /prod/*/admin/*
                # MY-CUSTOM-CODE  BEGIN
                # Removed Path: '/'
                # MY-CUSTOM-CODE  END

  CognitoRegisteredGroup:
    Type: AWS::Cognito::UserPoolGroup
    Properties:
      Description: 'Registered users in the developer portal'
      GroupName: !Sub '${AWS::StackName}-RegisteredGroup'
      Precedence: 1
      RoleArn: !GetAtt CognitoRegisteredRole.Arn
      UserPoolId: !Ref CognitoUserPool

If I had not added the permissions boundary, I still don't see how this could work. Any help appreciated, Thanks

ghost commented 4 years ago

I'm getting a Cognito role ARN returned from getPreferredRole(), something like arn:aws:iam::$ACCOUNT_ID:role/$PREFIX-dev-portal-CognitoAdminRole-$ROLE_ID, not a role name. Could you be a little more specific on what you're getting returned from that function? Also, does that part work without either of your modifications?

steve-be-old commented 4 years ago

Hi, I get what you get when I log in as an admin. When I log in as a non-Admin, consol.log(role) has this: arn:aws:iam::$ACCOUNT_ID:role/ggg/apps/devportal/dev-entarch-api-gateway-dev-portal-aCognitoRegisteredRole

I am seeing if I can get it deployed somewhere with out the permissions boundary change. It was working prior to us pulling the new version from GitHub a month or so ago, I think the registered user concept must be new.

ghost commented 4 years ago

It's new, but it mainly accounts for this:

Suppose a random person Mallory registers with your email. They then, instead of confirming the email as theirs using the given token (as they can't, anyways), proceed to log in regardless of this. We don't want that login to be successful, and we don't want to give them the ability to read any APIs, and that registered group is how we enforce that.

Edit: removed a redundant word

steve-be-old commented 4 years ago

I changed the permissions boundary for this one so that it will format the Registered role as the code in self.js is expecting:

  RoleName: !Join
    - '-'
    - - !Ref AWS::StackName
      - 'CognitoRegisteredRole'
      - 'Role'

then it matched the check and seemed to work.