Cognito passwordless flow with username and email as aliasAttribute - amazon-cognito

I'm made a cognito passwordless flow and i create userPool with this SAM template:
UserPool:
Type: "AWS::Cognito::UserPool"
Properties:
UserPoolName: !Ref UserPoolName
Schema:
- Name: phone_number
AttributeDataType: String
Mutable: true
- Name: email
AttributeDataType: String
Mutable: true
Policies:
PasswordPolicy:
MinimumLength: 6
RequireLowercase: false
RequireNumbers: false
RequireSymbols: false
RequireUppercase: false
AliasAttributes:
- email
- phone_number
MfaConfiguration: "OFF"
UserPoolClient:
Type: "AWS::Cognito::UserPoolClient"
Properties:
ClientName: sms-auth-client
GenerateSecret: false
UserPoolId: !Ref UserPool
ExplicitAuthFlows:
- CUSTOM_AUTH_FLOW_ONLY
Here, the User can use a email or phone_number to sign in, both of them are aliases.
But, Is there a way to identify which alias the User uses on sign in inside create-auth-lambda trigger?
Anyone can help?

Related

POST in openapi

I'm new in the world of API. I want to do an API using swagger in yaml. My teacher given us a snippet of code that should simulate a login API, but Bearer style. I want to map the generated identifier with the correlated name
paths:
/session:
post:
tags: ["login"]
summary: Logs in the user
description: |-
If the user does not exist, it will be created,
and an identifier is returned.
If the user exists, the user identifier is returned.
operationId: doLogin
requestBody:
description: User details
content:
application/json:
schema:
type: object
properties:
name:
type: string
example: Jason
pattern: 'ˆ.*?$'
minLength: 3
maxLength: 16
required: true
responses:
'201':
description: User log-in action successfully
content:
application/json:
schema:
type: object
properties:
identifier:
# change here if you decide to use an integer
# or any other type of identifier
type: string
example: "abcdef012345"
/session/{identifier}:
get:
summary: Get username
description: Get username from identifier
operationId: getUsername
parameters:
- name: identifier
in: path
description: User ID
required: true
schema:
$ref: "#/components/schemas/User/properties/identifier"
responses:
'200':
description: 'User exists'
content:
application/json:
schema:
$ref: "#/components/schemas/User"
components:
schemas:
User:
type: object
properties:
identifier:
type: string
example: "abcdef012345"
name:
type: string
example: "Jason"
I tried adding the "/session/{identifier}" path, but the get never retrieve the correct information. How can I do it?
Thank you in advance

Authenticate AppSync queries console with Cognito User Pools

I am trying to authenticate Queries playground in AWS AppSync console. I have created User Pool and linked it to the AppSync API, I have also created an App Client in Cognito User Pool (deployed using CloudFormation). It appears under Select the authorization provider to use for running queries on this page: in the console.
When I run test query I get:
{
"errors": [
{
"errorType": "UnauthorizedException",
"message": "Unable to parse JWT token."
}
]
}
This is what I would expect. There is an option to Login with User Pools. The issue is I can't select any Client ID and when I choose to insert Client ID manually, anything I enter I get Invalid UserPoolId format. I am trying to copy Pool ID from User Pool General settings (format eu-west-2_xxxxxxxxx) but no joy. Btw, I am not using Amplify and I have not configured any Identity Pools.
EDIT:
Here is the CloudFormation GraphQLApi definition:
MyApi:
Type: AWS::AppSync::GraphQLApi
Properties:
Name: !Sub "${AWS::StackName}-api"
AuthenticationType: AMAZON_COGNITO_USER_POOLS
UserPoolConfig:
UserPoolId: !Ref UserPoolClient
AwsRegion: !Sub ${AWS::Region}
DefaultAction: ALLOW
To set up the stack using CloudFormation I have followed these 2 examples:
https://adrianhall.github.io/cloud/2018/04/17/deploy-an-aws-appsync-graphql-api-with-cloudformation/
https://gist.github.com/adrianhall/f330a10451f05a529680f32978dddb64
Turns out they both (same author) have an issue in them in the section where ApiGraphQL is defined. This:
MyApi:
Type: AWS::AppSync::GraphQLApi
Properties:
Name: !Sub "${AWS::StackName}-api"
AuthenticationType: AMAZON_COGNITO_USER_POOLS
UserPoolConfig:
UserPoolId: !Ref UserPoolClient
AwsRegion: !Sub ${AWS::Region}
DefaultAction: ALLOW
Should be:
MyApi:
Type: AWS::AppSync::GraphQLApi
Properties:
Name: !Sub "${AWS::StackName}-api"
AuthenticationType: AMAZON_COGNITO_USER_POOLS
UserPoolConfig:
UserPoolId: !Ref UserPool
AwsRegion: !Sub ${AWS::Region}
DefaultAction: ALLOW
Thank you #Myz for pointing me back to review the whole CF yaml file

Does a POST method create a new entity, and return the id of that entity, in openapi 3.0.2?

I understand that a POST method in openapi 3.0.2 is supposed to create a new entity, and return the id of that entity. When I add an additional route to GET or DELETE that entity by ID, I get a 404 error. I don't quite know why that might be.
Here are my post and get methods:
/api/globalorderdays:
post:
tags:
- Setup Global Order Days
summary: Allows user to add order days and holidays to multiple
sessions.
requestBody:
required: true
description: put text here
content:
application/json:
schema:
$ref: '#/components/schemas/GlobalOrderSetupInfo'
responses:
201:
description: Created
400:
description: Bad request
401:
description: Unauthorized
/api/globalorderdays/{Id}:
get:
tags:
- Setup Global Order Days
summary: put text here
parameters:
- in: path
name: Id
required: true
description: put text here
schema:
type: integer
example:
responses:
200:
description: Success
content:
application/json:
schema:
$ref: '#/components/schemas/GlobalOrderSetupInfo'
400:
description: Bad request
401:
description: Unauthorized
/api/globalorderdays/{Id}:
delete:
tags:
- Setup Global Order Days
summary: Allows user to delete added order days
parameters:
- in: path
name: Id
required: true
description: put text here
schema:
type: integer
example:
responses:
204:
description: Deleted
400:
description: Bad request
401:
description: Unauthorized
Here are the components:
GlobalOrderSetupInfo:
description: 'Put Text Here'
type: object
properties:
Id:
type: integer
nullable: true
AvailableHolidayList:
type: string
nullable: true
SelectedOrderHolidays:
type: string
nullable: true
SelectedHolidays:
type: string
nullable: true
OrderDays:
type: string
nullable: true
NoOrderDays:
type: string
nullable: true
AllSessionList:
uniqueItems: false
type: array
items:
$ref: '#/components/schemas/SessionInfoList'
SessionIdString:
type: string
nullable: true
SessionInfoList:
description: 'Put Text Here'
type: object
properties:
Id:
type: integer
nullable: true
SessionID:
type: integer
nullable: true
Name:
type: string
nullable: true
Type:
type: string
GroupName:
type: string
IsChecked:
type: boolean
default: false
SetupID:
type: string
nullable: true
I expect to be able to retrieve/delete the entity by Id, but I return 404 errors
There are several issues with your spec.
The /api/globalorderdays/{Id} path is repeated several times. This is not valid.
# Incorrect
/api/globalorderdays/{Id}:
get:
...
/api/globalorderdays/{Id}:
delete:
...
Instead, specify the path once and list all of its HTTP methods below it, like so:
/api/globalorderdays/{Id}:
get:
...
delete:
...
Parameter examples are missing the value:
schema:
type: integer
example: # <-----
A missing value in YAML is an equivalent of null, but null is not a valid example for an integer schema. Either add a proper integer example, such as example: 1, or remove the example keyword from those schemas.
Once these issues are fixed, the mocks for GET and DELETE will work properly.

Swagger POST with non-json body

I'm defining a resource that you POST to with a non-JSON body. It's just a string like form parameters. Something like what happens with OAuth:
grant_type=&code=&redirect_uri=
How can I document that on Swagger? Do I have to use formParam format instead of body? Everything I put into body it converts to JSON examples.
TokenRequest:
properties:
grant_type:
type: string
description: OAuth Grant Type
enum:
- authorization_code
- refresh
code:
type: string
description: Authorization Code obtained from /authorize required if grant_type = au
redirect_uri:
type: string
description: Defined Redirect URI Example - https://example.com/callback
refresh_token:
type: string
description: Required if grant_type = refresh
Here is an example on how to document the form data:
post:
tags:
- pet
summary: Updates a pet in the store with form data
description: ''
operationId: updatePetWithForm
consumes:
- application/x-www-form-urlencoded
produces:
- application/xml
- application/json
parameters:
- name: petId
in: path
description: ID of pet that needs to be updated
required: true
type: integer
format: int64
- name: name
in: formData
description: Updated name of the pet
required: false
type: string
- name: status
in: formData
description: Updated status of the pet
required: false
type: string
responses:
'405':
description: Invalid input
security:
- petstore_auth:
- 'write:pets'
- 'read:pets'
But in your case, it seems you want to define OAuth setting so please refer to Swagger Spec 2.0 for more information. Here is an example for PetStore:
securityDefinitions:
petstore_auth:
type: oauth2
authorizationUrl: 'http://petstore.swagger.io/api/oauth/dialog'
flow: implicit
scopes:
'write:pets': modify pets in your account
'read:pets': read your pets
api_key:
type: apiKey
name: api_key
in: header

Authenticate multiple symfony2 firewalls

I'm trying to authenticate users from in_memory provider for one section on the site and sso provider for all the other pages, so I tried the following:
role_hierarchy:
ROLE_ADMIN: ROLE_USER
ROLE_SUPER_ADMIN: [ROLE_ADMIN, ROLE_ALLOWED_TO_SWITCH]
providers:
sso:
id: sso.security.user.provider
fos_twitter:
id: fos_twitter.auth
in_memory:
users:
ryan: { password: ryanpass, roles: 'ROLE_CANVAS_ADMIN' }
admin: { password: kitten, roles: 'ROLE_CANVAS_ADMIN' }
firewalls:
main:
pattern: ^/canvas
provider: in_memory
secured_area:
pattern: ^/
form_login:
login_path: /signin
check_path: /login_check
anonymous: true
sso: true
fos_twitter: false
access_control:
- { path: ^/canvas, roles: [ROLE_CANVAS_ADMIN] }
This is not working, because it always enter to the /signin login path and this working using the sso provider.
I already tried the following implementations:
Authenticate multiple symfony2 firewalls with one login form,
http://symfony.com/doc/2.0/cookbook/security/custom_authentication_provider.html
and this: http://symfony.com/doc/current/book/security.html#using-multiple-user-providers
None of them work for me.
Can someone help with that?
Thanks..