Add basic implement for cognito-idp create_resource_server (#3153)

* Add basic implement for cognito-idp create_resource_server

* lint
This commit is contained in:
cm-iwata 2020-07-20 20:31:30 +09:00 committed by GitHub
parent ba99c61477
commit fdeee07762
No known key found for this signature in database
GPG Key ID: 4AEE18F83AFDEB23
5 changed files with 97 additions and 2 deletions

View File

@ -1664,7 +1664,7 @@
## cognito-idp ## cognito-idp
<details> <details>
<summary>37% implemented</summary> <summary>38% implemented</summary>
- [ ] add_custom_attributes - [ ] add_custom_attributes
- [X] admin_add_user_to_group - [X] admin_add_user_to_group
@ -1700,7 +1700,7 @@
- [ ] confirm_sign_up - [ ] confirm_sign_up
- [X] create_group - [X] create_group
- [X] create_identity_provider - [X] create_identity_provider
- [ ] create_resource_server - [X] create_resource_server
- [ ] create_user_import_job - [ ] create_user_import_job
- [X] create_user_pool - [X] create_user_pool
- [X] create_user_pool_client - [X] create_user_pool_client

View File

@ -2,6 +2,7 @@ from __future__ import unicode_literals
import json import json
from werkzeug.exceptions import BadRequest from werkzeug.exceptions import BadRequest
from moto.core.exceptions import JsonRESTError
class ResourceNotFoundError(BadRequest): class ResourceNotFoundError(BadRequest):
@ -42,3 +43,11 @@ class NotAuthorizedError(BadRequest):
self.description = json.dumps( self.description = json.dumps(
{"message": message, "__type": "NotAuthorizedException"} {"message": message, "__type": "NotAuthorizedException"}
) )
class InvalidParameterException(JsonRESTError):
def __init__(self, msg=None):
self.code = 400
super(InvalidParameterException, self).__init__(
"InvalidParameterException", msg or "A parameter is specified incorrectly."
)

View File

@ -21,6 +21,7 @@ from .exceptions import (
ResourceNotFoundError, ResourceNotFoundError,
UserNotFoundError, UserNotFoundError,
UsernameExistsException, UsernameExistsException,
InvalidParameterException,
) )
UserStatus = { UserStatus = {
@ -83,6 +84,7 @@ class CognitoIdpUserPool(BaseModel):
self.identity_providers = OrderedDict() self.identity_providers = OrderedDict()
self.groups = OrderedDict() self.groups = OrderedDict()
self.users = OrderedDict() self.users = OrderedDict()
self.resource_servers = OrderedDict()
self.refresh_tokens = {} self.refresh_tokens = {}
self.access_tokens = {} self.access_tokens = {}
self.id_tokens = {} self.id_tokens = {}
@ -337,6 +339,27 @@ class CognitoIdpUser(BaseModel):
self.attributes = expand_attrs(flat_attributes) self.attributes = expand_attrs(flat_attributes)
class CognitoResourceServer(BaseModel):
def __init__(self, user_pool_id, identifier, name, scopes):
self.user_pool_id = user_pool_id
self.identifier = identifier
self.name = name
self.scopes = scopes
def to_json(self):
res = {
"UserPoolId": self.user_pool_id,
"Identifier": self.identifier,
"Name": self.name,
}
if len(self.scopes) != 0:
res.update({"Scopes": self.scopes})
return res
class CognitoIdpBackend(BaseBackend): class CognitoIdpBackend(BaseBackend):
def __init__(self, region): def __init__(self, region):
super(CognitoIdpBackend, self).__init__() super(CognitoIdpBackend, self).__init__()
@ -768,6 +791,20 @@ class CognitoIdpBackend(BaseBackend):
user = user_pool.users[username] user = user_pool.users[username]
user.update_attributes(attributes) user.update_attributes(attributes)
def create_resource_server(self, user_pool_id, identifier, name, scopes):
user_pool = self.user_pools.get(user_pool_id)
if not user_pool:
raise ResourceNotFoundError(user_pool_id)
if identifier in user_pool.resource_servers:
raise InvalidParameterException(
"%s already exists in user pool %s." % (identifier, user_pool_id)
)
resource_server = CognitoResourceServer(user_pool_id, identifier, name, scopes)
user_pool.resource_servers[identifier] = resource_server
return resource_server
cognitoidp_backends = {} cognitoidp_backends = {}
for region in Session().get_available_regions("cognito-idp"): for region in Session().get_available_regions("cognito-idp"):

View File

@ -379,6 +379,17 @@ class CognitoIdpResponse(BaseResponse):
) )
return "" return ""
# Resource Server
def create_resource_server(self):
user_pool_id = self._get_param("UserPoolId")
identifier = self._get_param("Identifier")
name = self._get_param("Name")
scopes = self._get_param("Scopes")
resource_server = cognitoidp_backends[self.region].create_resource_server(
user_pool_id, identifier, name, scopes
)
return json.dumps({"ResourceServer": resource_server.to_json()})
class CognitoIdpJsonWebKeyResponse(BaseResponse): class CognitoIdpJsonWebKeyResponse(BaseResponse):
def __init__(self): def __init__(self):

View File

@ -1398,6 +1398,44 @@ def test_admin_update_user_attributes():
val.should.equal("Jane") val.should.equal("Jane")
@mock_cognitoidp
def test_resource_server():
client = boto3.client("cognito-idp", "us-west-2")
name = str(uuid.uuid4())
value = str(uuid.uuid4())
res = client.create_user_pool(PoolName=name)
user_pool_id = res["UserPool"]["Id"]
identifier = "http://localhost.localdomain"
name = "local server"
scopes = [
{"ScopeName": "app:write", "ScopeDescription": "write scope"},
{"ScopeName": "app:read", "ScopeDescription": "read scope"},
]
res = client.create_resource_server(
UserPoolId=user_pool_id, Identifier=identifier, Name=name, Scopes=scopes
)
res["ResourceServer"]["UserPoolId"].should.equal(user_pool_id)
res["ResourceServer"]["Identifier"].should.equal(identifier)
res["ResourceServer"]["Name"].should.equal(name)
res["ResourceServer"]["Scopes"].should.equal(scopes)
with assert_raises(ClientError) as ex:
client.create_resource_server(
UserPoolId=user_pool_id, Identifier=identifier, Name=name, Scopes=scopes
)
ex.exception.operation_name.should.equal("CreateResourceServer")
ex.exception.response["Error"]["Code"].should.equal("InvalidParameterException")
ex.exception.response["Error"]["Message"].should.equal(
"%s already exists in user pool %s." % (identifier, user_pool_id)
)
ex.exception.response["ResponseMetadata"]["HTTPStatusCode"].should.equal(400)
# Test will retrieve public key from cognito.amazonaws.com/.well-known/jwks.json, # Test will retrieve public key from cognito.amazonaws.com/.well-known/jwks.json,
# which isnt mocked in ServerMode # which isnt mocked in ServerMode
if not settings.TEST_SERVER_MODE: if not settings.TEST_SERVER_MODE: