Skip to content

Commit

Permalink
Finalized the migration flows and added the appropriate curl commands
Browse files Browse the repository at this point in the history
  • Loading branch information
Vladimir Budilov committed Jan 24, 2018
1 parent df0e4fe commit a5af2a0
Show file tree
Hide file tree
Showing 10 changed files with 248 additions and 78 deletions.
69 changes: 44 additions & 25 deletions README.md
Original file line number Diff line number Diff line change
Expand Up @@ -2,8 +2,8 @@
It's a set of [AWS Lambda](https://aws.amazon.com/lambda/) functions that, once deployed using the provided [SAM](https://github.com/awslabs/serverless-application-model) template, act as
an [Amazon Cognito](https://aws.amazon.com/cognito/) proxy.

*Note: In most cases you should consider using the SDKs directly on the client, without using a proxy, especially
if your business usecase allows it*
*Note: In most cases you should consider using the SDKs directly on the client side, without using a proxy, especially
if your business use-case allows it*

### Why was this project created?
* QuickStart for any custom IdP --> Cognito migration service
Expand Down Expand Up @@ -32,38 +32,57 @@ CognitoAutoconfirmUserParameter | Setting this value to 'true' will auto-confirm
# Package it
aws cloudformation package --template-file sam.yaml --s3-bucket code.budilovv --output-template-file /tmp/UpdatedSAMTemplate.yaml
# Deploy it
aws cloudformation deploy --template-file /tmp/UpdatedSAMTemplate.yaml --stack-name auth-stack --parameter-overrides RegionParameter=REGION CognitoUserPoolIdParameter=REGION_PGSbCVZ7S CognitoAppClientIdParameter=hikoo0i7jmt9lplrd2j0n9jqo --capabilities CAPABILITY_IAM
aws cloudformation deploy --template-file /tmp/UpdatedSAMTemplate.yaml --stack-name auth-stack \
--parameter-overrides \
RegionParameter=REGION \
CognitoUserPoolIdParameter=REGION_xxxxxxxxx \
CognitoAppClientIdParameter=xxxxxxxxxxxxxxxxxxxxx \
CognitoAutoconfirmUserParameter=true \
--capabilities CAPABILITY_IAM
```

### Test the Flows

##### Sign Up
```
curl -XPOST 'https://API_GATEWAY_ID.execute-api.REGION.amazonaws.com/Prod/signup' --header "username: [email protected]" --header "password: Cognito&&1"
```
export [email protected]
export SAMPLE_PASSWORD=myPassword**^1
export REGION=us-east-1
export API_GATEWAY_ID=
##### Sign In
```
curl -XPOST 'https://API_GATEWAY_ID.execute-api.REGION.amazonaws.com/Prod/signin' --header "username: [email protected]" --header "password: Cognito&&1"
```
# Signup
curl -XPOST 'https://$API_GATEWAY_ID.execute-api.$REGION.amazonaws.com/Prod/signup' --header "username: $SAMPLE_EMAIL" --header "password: $SAMPLE_PASSWORD"
##### Password Reset
```
curl -XPOST 'https://API_GATEWAY_ID.execute-api.REGION.amazonaws.com/Prod/password/reset' --header "idToken: AAAAAAAAAAAAaa"
```
# Confirm SignUp
curl -XPOST 'https://$API_GATEWAY_ID.execute-api.$REGION.amazonaws.com/Prod/confirmsignup' --header "username: $SAMPLE_EMAIL" --header "confirmationCode: CONFIRMATION_CODE"
##### Refresh
```
curl -XPOST 'https://API_GATEWAY_ID.execute-api.REGION.amazonaws.com/Prod/refresh' --header "refreshToken: BBBBBBBBBBBBBBb"
```
# SignIn
curl -XPOST 'https://$API_GATEWAY_ID.execute-api.$REGION.amazonaws.com/Prod/admin/signin' --header "username: $SAMPLE_EMAIL" --header "password: $SAMPLE_PASSWORD"
##### Check for token validity
```
curl -XPOST 'https://API_GATEWAY_ID.execute-api.REGION.amazonaws.com/Prod/token/valid' --header "idToken: AAAAAAAAAAAAaa"
```
##### Delete User
```
curl -XDELETE 'https://API_GATEWAY_ID.execute-api.REGION.amazonaws.com/Prod/user' --header "idToken: AAAAAAAAAAAAaa"
# Refresh Tokens
curl -XPOST 'https://$API_GATEWAY_ID.execute-api.$REGION.amazonaws.com/Prod/admin/refresh' --header "refreshToken: JWT_REFRESH_TOKEN"
# Check if the token is valid
curl -XGET 'https://$API_GATEWAY_ID.execute-api.$REGION.amazonaws.com/Prod/token/valid' --header "idToken: JWT_ID_TOKEN"
# Reset Password
curl -XPOST 'https://$API_GATEWAY_ID.execute-api.$REGION.amazonaws.com/Prod/password/reset' --header "username: $SAMPLE_EMAIL"
# Create a new password
curl -XPOST 'https://$API_GATEWAY_ID.execute-api.$REGION.amazonaws.com/Prod/password/confirm' --header "username: $SAMPLE_EMAIL" --header "password: $SAMPLE_PASSWORD" --header "confirmationCode: CONFIRMATION_CODE"
# Update User Attribute
curl -XPOST 'https://$API_GATEWAY_ID.execute-api.$REGION.amazonaws.com/Prod/admin/user/attribute' --header "idToken: JWT_ID_TOKEN" --header "attributeName: name" --header "attributeValue: Vladimir Budilov"
# Delete User
curl -XDELETE 'https://$API_GATEWAY_ID.execute-api.$REGION.amazonaws.com/Prod/admin/user' --header "idToken: JWT_ID_TOKEN"
# Resend Confirmation Code (can be used only when verification is turned on)
curl -XPOST 'https://$API_GATEWAY_ID.execute-api.$REGION.amazonaws.com/Prod/resendcode' --header "username: $SAMPLE_EMAIL"
# Confirm SignUp (can be used only when verification is turned on)
curl -XPOST 'https://60ii5ih8b4.execute-api.us-east-1.amazonaws.com/Prod/confirmsignup' --header "username: $SAMPLE_EMAIL" --header "confirmationCode: CONFIRMATION_CODE"
```
64 changes: 60 additions & 4 deletions sam.yaml
Original file line number Diff line number Diff line change
Expand Up @@ -119,7 +119,7 @@ Resources:
GetResource:
Type: Api
Properties:
Path: /refresh
Path: /admin/refresh
Method: post
UserSignin:
Type: AWS::Serverless::Function
Expand All @@ -146,7 +146,7 @@ Resources:
GetResource:
Type: Api
Properties:
Path: /signin
Path: /admin/signin
Method: post
UserDelete:
Type: AWS::Serverless::Function
Expand All @@ -173,7 +173,7 @@ Resources:
GetResource:
Type: Api
Properties:
Path: /user
Path: /admin/user
Method: delete
CheckTokenValidity:
Type: AWS::Serverless::Function
Expand Down Expand Up @@ -205,7 +205,7 @@ Resources:
ResetPassword:
Type: AWS::Serverless::Function
Properties:
Handler: com.budilov.cognito.lambda.CognitoResetPassword::handleRequest
Handler: com.budilov.cognito.lambda.CognitoResetPasswordLambda::handleRequest
FunctionName: CognitoResetPassword
Policies:
- AmazonCognitoPowerUser
Expand All @@ -230,3 +230,59 @@ Resources:
Properties:
Path: /password/reset
Method: post
ConfirmForgotPassword:
Type: AWS::Serverless::Function
Properties:
Handler: com.budilov.cognito.lambda.CognitoConfirmForgotPasswordLambda::handleRequest
FunctionName: ConfirmForgotPassword
Policies:
- AmazonCognitoPowerUser
Runtime: java8
MemorySize: 1024
Timeout: 15
CodeUri: build/libs/cognito-rest-service-1.0-SNAPSHOT.jar
Environment:
Variables:
Variables:
REGION_NAME:
Ref: RegionParameter
COGNITO_USER_POOL_ID:
Ref: CognitoUserPoolIdParameter
COGNITO_APP_CLIENT_ID:
Ref: CognitoAppClientIdParameter
AUTOCONFIRM_USER:
Ref: CognitoAutoconfirmUserParameter
Events:
GetResource:
Type: Api
Properties:
Path: /password/confirm
Method: post
UpdateUserAttribute:
Type: AWS::Serverless::Function
Properties:
Handler: com.budilov.cognito.lambda.CognitoUpdateUserAttributeLambda::handleRequest
FunctionName: UpdateUserAttribute
Policies:
- AmazonCognitoPowerUser
Runtime: java8
MemorySize: 1024
Timeout: 15
CodeUri: build/libs/cognito-rest-service-1.0-SNAPSHOT.jar
Environment:
Variables:
Variables:
REGION_NAME:
Ref: RegionParameter
COGNITO_USER_POOL_ID:
Ref: CognitoUserPoolIdParameter
COGNITO_APP_CLIENT_ID:
Ref: CognitoAppClientIdParameter
AUTOCONFIRM_USER:
Ref: CognitoAutoconfirmUserParameter
Events:
GetResource:
Type: Api
Properties:
Path: /admin/user/attribute
Method: post
Original file line number Diff line number Diff line change
@@ -0,0 +1,34 @@
package com.budilov.cognito.lambda

import com.amazonaws.services.lambda.runtime.Context
import com.amazonaws.services.lambda.runtime.RequestHandler
import com.budilov.cognito.services.CognitoService
import com.google.gson.Gson

/**
* @author Vladimir Budilov
*/
class CognitoConfirmForgotPasswordLambda : RequestHandler<ApiGatewayRequest.Input,
ApiGatewayResponse> {

val cognito = CognitoService()

override fun handleRequest(request: ApiGatewayRequest.Input?,
context: Context?): ApiGatewayResponse {

val username = request?.headers?.get("username")
val password = request?.headers?.get("password")

val confirmationCode = request?.headers?.get("confirmationCode")

var status = 400
var response = ""

if (username != null && password != null && confirmationCode != null) {
response = Gson().toJson(cognito.confirmForgotPassword(username = username, confirmationCode = confirmationCode, password = password))
status = 200
}

return ApiGatewayResponse(statusCode = status, body = response)
}
}
Original file line number Diff line number Diff line change
Expand Up @@ -39,9 +39,9 @@ class CognitoDeleteUserLambda : RequestHandler<ApiGatewayRequest.Input,
}

} else {
return ApiGatewayResponse(statusCode = 400, body = Gson().toJson("A valid id token is required"))
return ApiGatewayResponse(statusCode = 400, body = "A valid id token is required")
}

return ApiGatewayResponse(statusCode = status, body = Gson().toJson(response))
return ApiGatewayResponse(statusCode = status, body = response)
}
}
Original file line number Diff line number Diff line change
Expand Up @@ -17,28 +17,15 @@ class CognitoResetPasswordLambda : RequestHandler<ApiGatewayRequest.Input,
override fun handleRequest(request: ApiGatewayRequest.Input?,
context: Context?): ApiGatewayResponse? {

val logger = context?.logger
val username = request?.headers?.get("username")

val idToken = request?.headers?.get("idToken")

var status = 200
var status = 400
var response = ""

if (idToken != null) {
// Check to see if the token is valid and if the username matches the
// idToken's username
try {
if (cognito.isTokenValid(idToken)) {
val username = cognito.getUsername(idToken)
response = Gson().toJson(cognito.adminResetPassword(username = username))
}
} catch (e: Exception) {
logger?.log("Couldn't figure out if the id token is valid...caught an exception...${e.message}")
status = 400
}

} else {
logger?.log("The id token is required")
if (username != null) {
val result = cognito.forgotPassword(username = username)
status = 200
response = Gson().toJson(result)
}

return ApiGatewayResponse(statusCode = status, body = response)
Expand Down
Original file line number Diff line number Diff line change
Expand Up @@ -25,7 +25,7 @@ class CognitoSigninLambda : RequestHandler<ApiGatewayRequest.Input,
var response = ""

if (username != null && password != null) {
val result = cognito.signInNoSRP(username = username,
val result = cognito.adminInitiateAuth(username = username,
password = password)
status = 200
response = Gson().toJson(result)
Expand Down
Original file line number Diff line number Diff line change
Expand Up @@ -15,12 +15,10 @@ class CognitoSignupLambda : RequestHandler<ApiGatewayRequest.Input,

override fun handleRequest(request: ApiGatewayRequest.Input?,
context: Context?): ApiGatewayResponse {
val logger = context?.logger

val username = request?.headers?.get("username")
val password = request?.headers?.get("password")

logger?.log("${username} & ${password}")
var status = 400
var response = ""

Expand Down
Original file line number Diff line number Diff line change
Expand Up @@ -22,7 +22,7 @@ class CognitoTokenValidLambda : RequestHandler<ApiGatewayRequest.Input,
val idToken = request?.headers?.get("idToken")

var status = 200
var response: String = ""
var response = ""

if (idToken != null) {
val result = try {
Expand Down
Original file line number Diff line number Diff line change
Expand Up @@ -17,21 +17,35 @@ class CognitoUpdateUserAttributeLambda : RequestHandler<ApiGatewayRequest.Input,
context: Context?): ApiGatewayResponse {
val logger = context?.logger

val username = request?.headers?.get("username")
val idToken = request?.headers?.get("idToken")
val attributeName = request?.headers?.get("attributeName")
val attributeValue = request?.headers?.get("attributeValue")


var status = 400
var response = ""

if (username != null && attributeName != null
if (idToken != null && attributeName != null
&& attributeValue != null) {
response = Gson().toJson(cognito.updateUserAttribute(username = username,
attributeName = attributeName, attributeValue = attributeValue))
status = 200
// Check to see if the token is valid and if the username matches the
// idToken's username

try {
if (cognito.isTokenValid(idToken)) {
val username = cognito.getUsername(idToken)
response = Gson().toJson(cognito.updateUserAttribute(username = username,
attributeName = attributeName, attributeValue = attributeValue))
status = 200
}
} catch (e: Exception) {
logger?.log("Couldn't figure out if the id token is valid...caught an exception...${e.stackTrace}")
status = 400
}

} else {
return ApiGatewayResponse(statusCode = 400, body = "A valid id token is required")
}

return ApiGatewayResponse(statusCode = status, body = response)

}
}
Loading

0 comments on commit a5af2a0

Please sign in to comment.