From f23288d9b92d8519239a2beeeb0dc27b97676f17 Mon Sep 17 00:00:00 2001 From: Ferruvich Date: Tue, 7 Aug 2018 13:55:13 +0200 Subject: [PATCH 01/11] Changed the 'create_access_token' function in order to add the extra data into 'create_jwt' function --- moto/cognitoidp/models.py | 24 +++++++++++++++++++++++- 1 file changed, 23 insertions(+), 1 deletion(-) diff --git a/moto/cognitoidp/models.py b/moto/cognitoidp/models.py index 52a73f89f..1119edcbe 100644 --- a/moto/cognitoidp/models.py +++ b/moto/cognitoidp/models.py @@ -84,7 +84,11 @@ class CognitoIdpUserPool(BaseModel): return refresh_token def create_access_token(self, client_id, username): - access_token, expires_in = self.create_jwt(client_id, username) + extra_data = self.get_user_extra_data_by_client_id( + client_id, username + ) + access_token, expires_in = self.create_jwt(client_id, username, + extra_data=extra_data) self.access_tokens[access_token] = (client_id, username) return access_token, expires_in @@ -97,6 +101,21 @@ class CognitoIdpUserPool(BaseModel): id_token, _ = self.create_id_token(client_id, username) return access_token, id_token, expires_in + def get_user_extra_data_by_client_id(self, client_id, username): + extra_data = {} + current_client = self.clients.get(client_id, None) + if current_client: + for readable_field in current_client.get_readable_fields(): + attribute = list(filter( + lambda f: f['Name'] == readable_field, + self.users.get(username).attributes + )) + if len(attribute) > 0: + extra_data.update({ + attribute[0]['Name']: attribute[0]['Value'] + }) + return extra_data + class CognitoIdpUserPoolDomain(BaseModel): @@ -138,6 +157,9 @@ class CognitoIdpUserPoolClient(BaseModel): return user_pool_client_json + def get_readable_fields(self): + return self.extended_config.get('ReadAttributes', []) + class CognitoIdpIdentityProvider(BaseModel): From 4776228b6824e31a43060082ef4ef15b490de3af Mon Sep 17 00:00:00 2001 From: Ferruvich Date: Tue, 7 Aug 2018 13:55:32 +0200 Subject: [PATCH 02/11] Testing new feature --- tests/test_cognitoidp/test_cognitoidp.py | 13 +++++++++++++ 1 file changed, 13 insertions(+) diff --git a/tests/test_cognitoidp/test_cognitoidp.py b/tests/test_cognitoidp/test_cognitoidp.py index b2bd469ce..fda24146d 100644 --- a/tests/test_cognitoidp/test_cognitoidp.py +++ b/tests/test_cognitoidp/test_cognitoidp.py @@ -325,6 +325,7 @@ def test_delete_identity_providers(): def test_admin_create_user(): conn = boto3.client("cognito-idp", "us-west-2") + username = str(uuid.uuid4()) username = str(uuid.uuid4()) value = str(uuid.uuid4()) user_pool_id = conn.create_user_pool(PoolName=str(uuid.uuid4()))["UserPool"]["Id"] @@ -399,15 +400,22 @@ def authentication_flow(conn): username = str(uuid.uuid4()) temporary_password = str(uuid.uuid4()) user_pool_id = conn.create_user_pool(PoolName=str(uuid.uuid4()))["UserPool"]["Id"] + user_attribute_name = str(uuid.uuid4()) + user_attribute_value = str(uuid.uuid4()) client_id = conn.create_user_pool_client( UserPoolId=user_pool_id, ClientName=str(uuid.uuid4()), + ReadAttributes=[user_attribute_name] )["UserPoolClient"]["ClientId"] conn.admin_create_user( UserPoolId=user_pool_id, Username=username, TemporaryPassword=temporary_password, + UserAttributes=[{ + 'Name': user_attribute_name, + 'Value': user_attribute_value + }] ) result = conn.admin_initiate_auth( @@ -446,6 +454,9 @@ def authentication_flow(conn): "access_token": result["AuthenticationResult"]["AccessToken"], "username": username, "password": new_password, + "additional_fields": { + user_attribute_name: user_attribute_value + } } @@ -475,6 +486,8 @@ def test_token_legitimacy(): access_claims = json.loads(jws.verify(access_token, json_web_key, "RS256")) access_claims["iss"].should.equal(issuer) access_claims["aud"].should.equal(client_id) + for k, v in outputs["additional_fields"].items(): + access_claims[k].should.equal(v) @mock_cognitoidp From df28ec03d2cc8c44387fa0ac41f57a3431dd6a45 Mon Sep 17 00:00:00 2001 From: Ferruvich Date: Fri, 10 Aug 2018 16:07:27 +0200 Subject: [PATCH 03/11] Added extra test --- tests/test_cognitoidp/test_cognitoidp.py | 5 +++++ 1 file changed, 5 insertions(+) diff --git a/tests/test_cognitoidp/test_cognitoidp.py b/tests/test_cognitoidp/test_cognitoidp.py index fda24146d..d1d57f307 100644 --- a/tests/test_cognitoidp/test_cognitoidp.py +++ b/tests/test_cognitoidp/test_cognitoidp.py @@ -4,8 +4,10 @@ import boto3 import json import os import uuid +import jwt from jose import jws + from moto import mock_cognitoidp import sure # noqa @@ -446,6 +448,9 @@ def authentication_flow(conn): result["AuthenticationResult"]["IdToken"].should_not.be.none result["AuthenticationResult"]["AccessToken"].should_not.be.none + jwt.decode( + result["AuthenticationResult"]["AccessToken"], verify=False + ).get(user_attribute_name, '').should.be.equal(user_attribute_value) return { "user_pool_id": user_pool_id, From aae3ab6b900b879841e75474a9fcc716f238009f Mon Sep 17 00:00:00 2001 From: Ferruvich Date: Fri, 10 Aug 2018 16:26:09 +0200 Subject: [PATCH 04/11] Added package dependency --- requirements-dev.txt | 1 + 1 file changed, 1 insertion(+) diff --git a/requirements-dev.txt b/requirements-dev.txt index 655be0616..11f59e069 100644 --- a/requirements-dev.txt +++ b/requirements-dev.txt @@ -15,3 +15,4 @@ click==6.7 inflection==0.3.1 lxml==4.0.0 beautifulsoup4==4.6.0 +PyJWT==1.6.4 From f9762a5ecb98599109172d0af5295b6f13d1c57f Mon Sep 17 00:00:00 2001 From: Ferruvich Date: Fri, 10 Aug 2018 16:52:48 +0200 Subject: [PATCH 05/11] Removing failing test in order to check coverage and Travis test --- requirements-dev.txt | 1 - tests/test_cognitoidp/test_cognitoidp.py | 4 ---- 2 files changed, 5 deletions(-) diff --git a/requirements-dev.txt b/requirements-dev.txt index 11f59e069..655be0616 100644 --- a/requirements-dev.txt +++ b/requirements-dev.txt @@ -15,4 +15,3 @@ click==6.7 inflection==0.3.1 lxml==4.0.0 beautifulsoup4==4.6.0 -PyJWT==1.6.4 diff --git a/tests/test_cognitoidp/test_cognitoidp.py b/tests/test_cognitoidp/test_cognitoidp.py index d1d57f307..98153feef 100644 --- a/tests/test_cognitoidp/test_cognitoidp.py +++ b/tests/test_cognitoidp/test_cognitoidp.py @@ -4,7 +4,6 @@ import boto3 import json import os import uuid -import jwt from jose import jws @@ -448,9 +447,6 @@ def authentication_flow(conn): result["AuthenticationResult"]["IdToken"].should_not.be.none result["AuthenticationResult"]["AccessToken"].should_not.be.none - jwt.decode( - result["AuthenticationResult"]["AccessToken"], verify=False - ).get(user_attribute_name, '').should.be.equal(user_attribute_value) return { "user_pool_id": user_pool_id, From 2253bbf36123cf542f95f33b0037984686d199d6 Mon Sep 17 00:00:00 2001 From: Ferruvich Date: Tue, 7 Aug 2018 13:55:13 +0200 Subject: [PATCH 06/11] Changed the 'create_access_token' function in order to add the extra data into 'create_jwt' function --- moto/cognitoidp/models.py | 24 +++++++++++++++++++++++- 1 file changed, 23 insertions(+), 1 deletion(-) diff --git a/moto/cognitoidp/models.py b/moto/cognitoidp/models.py index 52a73f89f..1119edcbe 100644 --- a/moto/cognitoidp/models.py +++ b/moto/cognitoidp/models.py @@ -84,7 +84,11 @@ class CognitoIdpUserPool(BaseModel): return refresh_token def create_access_token(self, client_id, username): - access_token, expires_in = self.create_jwt(client_id, username) + extra_data = self.get_user_extra_data_by_client_id( + client_id, username + ) + access_token, expires_in = self.create_jwt(client_id, username, + extra_data=extra_data) self.access_tokens[access_token] = (client_id, username) return access_token, expires_in @@ -97,6 +101,21 @@ class CognitoIdpUserPool(BaseModel): id_token, _ = self.create_id_token(client_id, username) return access_token, id_token, expires_in + def get_user_extra_data_by_client_id(self, client_id, username): + extra_data = {} + current_client = self.clients.get(client_id, None) + if current_client: + for readable_field in current_client.get_readable_fields(): + attribute = list(filter( + lambda f: f['Name'] == readable_field, + self.users.get(username).attributes + )) + if len(attribute) > 0: + extra_data.update({ + attribute[0]['Name']: attribute[0]['Value'] + }) + return extra_data + class CognitoIdpUserPoolDomain(BaseModel): @@ -138,6 +157,9 @@ class CognitoIdpUserPoolClient(BaseModel): return user_pool_client_json + def get_readable_fields(self): + return self.extended_config.get('ReadAttributes', []) + class CognitoIdpIdentityProvider(BaseModel): From ab8f4dd159fd66ba8f9dedb9e8445a3ca33fb308 Mon Sep 17 00:00:00 2001 From: Ferruvich Date: Tue, 7 Aug 2018 13:55:32 +0200 Subject: [PATCH 07/11] Testing new feature --- tests/test_cognitoidp/test_cognitoidp.py | 13 +++++++++++++ 1 file changed, 13 insertions(+) diff --git a/tests/test_cognitoidp/test_cognitoidp.py b/tests/test_cognitoidp/test_cognitoidp.py index b2bd469ce..fda24146d 100644 --- a/tests/test_cognitoidp/test_cognitoidp.py +++ b/tests/test_cognitoidp/test_cognitoidp.py @@ -325,6 +325,7 @@ def test_delete_identity_providers(): def test_admin_create_user(): conn = boto3.client("cognito-idp", "us-west-2") + username = str(uuid.uuid4()) username = str(uuid.uuid4()) value = str(uuid.uuid4()) user_pool_id = conn.create_user_pool(PoolName=str(uuid.uuid4()))["UserPool"]["Id"] @@ -399,15 +400,22 @@ def authentication_flow(conn): username = str(uuid.uuid4()) temporary_password = str(uuid.uuid4()) user_pool_id = conn.create_user_pool(PoolName=str(uuid.uuid4()))["UserPool"]["Id"] + user_attribute_name = str(uuid.uuid4()) + user_attribute_value = str(uuid.uuid4()) client_id = conn.create_user_pool_client( UserPoolId=user_pool_id, ClientName=str(uuid.uuid4()), + ReadAttributes=[user_attribute_name] )["UserPoolClient"]["ClientId"] conn.admin_create_user( UserPoolId=user_pool_id, Username=username, TemporaryPassword=temporary_password, + UserAttributes=[{ + 'Name': user_attribute_name, + 'Value': user_attribute_value + }] ) result = conn.admin_initiate_auth( @@ -446,6 +454,9 @@ def authentication_flow(conn): "access_token": result["AuthenticationResult"]["AccessToken"], "username": username, "password": new_password, + "additional_fields": { + user_attribute_name: user_attribute_value + } } @@ -475,6 +486,8 @@ def test_token_legitimacy(): access_claims = json.loads(jws.verify(access_token, json_web_key, "RS256")) access_claims["iss"].should.equal(issuer) access_claims["aud"].should.equal(client_id) + for k, v in outputs["additional_fields"].items(): + access_claims[k].should.equal(v) @mock_cognitoidp From 9adb7c818df7bbaf842c49b82cba8579fb7bd8a9 Mon Sep 17 00:00:00 2001 From: Ferruvich Date: Fri, 10 Aug 2018 16:07:27 +0200 Subject: [PATCH 08/11] Added extra test --- tests/test_cognitoidp/test_cognitoidp.py | 5 +++++ 1 file changed, 5 insertions(+) diff --git a/tests/test_cognitoidp/test_cognitoidp.py b/tests/test_cognitoidp/test_cognitoidp.py index fda24146d..d1d57f307 100644 --- a/tests/test_cognitoidp/test_cognitoidp.py +++ b/tests/test_cognitoidp/test_cognitoidp.py @@ -4,8 +4,10 @@ import boto3 import json import os import uuid +import jwt from jose import jws + from moto import mock_cognitoidp import sure # noqa @@ -446,6 +448,9 @@ def authentication_flow(conn): result["AuthenticationResult"]["IdToken"].should_not.be.none result["AuthenticationResult"]["AccessToken"].should_not.be.none + jwt.decode( + result["AuthenticationResult"]["AccessToken"], verify=False + ).get(user_attribute_name, '').should.be.equal(user_attribute_value) return { "user_pool_id": user_pool_id, From c2b8a7bbb0d1b53b20e7b019a1c8b65b9359abab Mon Sep 17 00:00:00 2001 From: Ferruvich Date: Fri, 10 Aug 2018 16:26:09 +0200 Subject: [PATCH 09/11] Added package dependency --- requirements-dev.txt | 1 + 1 file changed, 1 insertion(+) diff --git a/requirements-dev.txt b/requirements-dev.txt index 111cd5f3f..54802ad89 100644 --- a/requirements-dev.txt +++ b/requirements-dev.txt @@ -15,3 +15,4 @@ click==6.7 inflection==0.3.1 lxml==4.2.3 beautifulsoup4==4.6.0 +PyJWT==1.6.4 From e69d2834e8905f42eb02ae0a451acfe891e64a50 Mon Sep 17 00:00:00 2001 From: Ferruvich Date: Fri, 10 Aug 2018 16:52:48 +0200 Subject: [PATCH 10/11] Removing failing test in order to check coverage and Travis test --- requirements-dev.txt | 1 - tests/test_cognitoidp/test_cognitoidp.py | 4 ---- 2 files changed, 5 deletions(-) diff --git a/requirements-dev.txt b/requirements-dev.txt index 54802ad89..111cd5f3f 100644 --- a/requirements-dev.txt +++ b/requirements-dev.txt @@ -15,4 +15,3 @@ click==6.7 inflection==0.3.1 lxml==4.2.3 beautifulsoup4==4.6.0 -PyJWT==1.6.4 diff --git a/tests/test_cognitoidp/test_cognitoidp.py b/tests/test_cognitoidp/test_cognitoidp.py index d1d57f307..98153feef 100644 --- a/tests/test_cognitoidp/test_cognitoidp.py +++ b/tests/test_cognitoidp/test_cognitoidp.py @@ -4,7 +4,6 @@ import boto3 import json import os import uuid -import jwt from jose import jws @@ -448,9 +447,6 @@ def authentication_flow(conn): result["AuthenticationResult"]["IdToken"].should_not.be.none result["AuthenticationResult"]["AccessToken"].should_not.be.none - jwt.decode( - result["AuthenticationResult"]["AccessToken"], verify=False - ).get(user_attribute_name, '').should.be.equal(user_attribute_value) return { "user_pool_id": user_pool_id, From da76ea633bfc6fef1ac1619dd311c379b253b833 Mon Sep 17 00:00:00 2001 From: Ferruvich Date: Fri, 28 Sep 2018 16:31:57 +0200 Subject: [PATCH 11/11] Removed redundand line --- tests/test_cognitoidp/test_cognitoidp.py | 1 - 1 file changed, 1 deletion(-) diff --git a/tests/test_cognitoidp/test_cognitoidp.py b/tests/test_cognitoidp/test_cognitoidp.py index 98153feef..b879cc42a 100644 --- a/tests/test_cognitoidp/test_cognitoidp.py +++ b/tests/test_cognitoidp/test_cognitoidp.py @@ -326,7 +326,6 @@ def test_delete_identity_providers(): def test_admin_create_user(): conn = boto3.client("cognito-idp", "us-west-2") - username = str(uuid.uuid4()) username = str(uuid.uuid4()) value = str(uuid.uuid4()) user_pool_id = conn.create_user_pool(PoolName=str(uuid.uuid4()))["UserPool"]["Id"]