Skip to content

Commit

Permalink
Merge pull request #1 from spulec/master
Browse files Browse the repository at this point in the history
pull latest
  • Loading branch information
corrjo authored Dec 20, 2018
2 parents dfa7935 + ed861ec commit dd0f047
Show file tree
Hide file tree
Showing 52 changed files with 2,370 additions and 145 deletions.
4 changes: 2 additions & 2 deletions .travis.yml
Original file line number Diff line number Diff line change
Expand Up @@ -23,6 +23,8 @@ matrix:
sudo: true
before_install:
- export BOTO_CONFIG=/dev/null
- export AWS_SECRET_ACCESS_KEY=foobar_secret
- export AWS_ACCESS_KEY_ID=foobar_key
install:
# We build moto first so the docker container doesn't try to compile it as well, also note we don't use
# -d for docker run so the logs show up in travis
Expand All @@ -32,8 +34,6 @@ install:
if [ "$TEST_SERVER_MODE" = "true" ]; then
docker run --rm -t --name motoserver -e TEST_SERVER_MODE=true -e AWS_SECRET_ACCESS_KEY=server_secret -e AWS_ACCESS_KEY_ID=server_key -v `pwd`:/moto -p 5000:5000 -v /var/run/docker.sock:/var/run/docker.sock python:${TRAVIS_PYTHON_VERSION}-stretch /moto/travis_moto_server.sh &
export AWS_SECRET_ACCESS_KEY=foobar_secret
export AWS_ACCESS_KEY_ID=foobar_key
fi
travis_retry pip install boto==2.45.0
travis_retry pip install boto3
Expand Down
5 changes: 5 additions & 0 deletions CHANGELOG.md
Original file line number Diff line number Diff line change
@@ -1,6 +1,11 @@
Moto Changelog
===================

1.3.7
-----

* Switch from mocking requests to using before-send for AWS calls

1.3.6
-----

Expand Down
32 changes: 16 additions & 16 deletions IMPLEMENTATION_COVERAGE.md
Original file line number Diff line number Diff line change
Expand Up @@ -835,8 +835,8 @@
- [ ] admin_delete_user
- [ ] admin_delete_user_attributes
- [ ] admin_disable_provider_for_user
- [ ] admin_disable_user
- [ ] admin_enable_user
- [X] admin_disable_user
- [X] admin_enable_user
- [ ] admin_forget_device
- [ ] admin_get_device
- [ ] admin_get_user
Expand Down Expand Up @@ -3092,23 +3092,23 @@
- [ ] update_server
- [ ] update_server_engine_attributes

## organizations - 0% implemented
## organizations - 30% implemented
- [ ] accept_handshake
- [ ] attach_policy
- [ ] cancel_handshake
- [ ] create_account
- [ ] create_organization
- [ ] create_organizational_unit
- [X] create_account
- [X] create_organization
- [X] create_organizational_unit
- [ ] create_policy
- [ ] decline_handshake
- [ ] delete_organization
- [ ] delete_organizational_unit
- [ ] delete_policy
- [ ] describe_account
- [X] describe_account
- [ ] describe_create_account_status
- [ ] describe_handshake
- [ ] describe_organization
- [ ] describe_organizational_unit
- [X] describe_organization
- [X] describe_organizational_unit
- [ ] describe_policy
- [ ] detach_policy
- [ ] disable_aws_service_access
Expand All @@ -3118,20 +3118,20 @@
- [ ] enable_policy_type
- [ ] invite_account_to_organization
- [ ] leave_organization
- [ ] list_accounts
- [ ] list_accounts_for_parent
- [X] list_accounts
- [X] list_accounts_for_parent
- [ ] list_aws_service_access_for_organization
- [ ] list_children
- [X] list_children
- [ ] list_create_account_status
- [ ] list_handshakes_for_account
- [ ] list_handshakes_for_organization
- [ ] list_organizational_units_for_parent
- [ ] list_parents
- [X] list_organizational_units_for_parent
- [X] list_parents
- [ ] list_policies
- [ ] list_policies_for_target
- [ ] list_roots
- [X] list_roots
- [ ] list_targets_for_policy
- [ ] move_account
- [X] move_account
- [ ] remove_account_from_organization
- [ ] update_organizational_unit
- [ ] update_policy
Expand Down
2 changes: 2 additions & 0 deletions README.md
Original file line number Diff line number Diff line change
Expand Up @@ -112,6 +112,8 @@ It gets even better! Moto isn't just for Python code and it isn't just for S3. L
|------------------------------------------------------------------------------|
| KMS | @mock_kms | basic endpoints done |
|------------------------------------------------------------------------------|
| Organizations | @mock_organizations | some core endpoints done |
|------------------------------------------------------------------------------|
| Polly | @mock_polly | all endpoints done |
|------------------------------------------------------------------------------|
| RDS | @mock_rds | core endpoints done |
Expand Down
10 changes: 5 additions & 5 deletions docs/index.rst
Original file line number Diff line number Diff line change
Expand Up @@ -34,11 +34,11 @@ Currently implemented Services:
| - DynamoDB2 | - @mock_dynamodb2 | - core endpoints + partial indexes|
+-----------------------+---------------------+-----------------------------------+
| EC2 | @mock_ec2 | core endpoints done |
| - AMI | | core endpoints done |
| - EBS | | core endpoints done |
| - Instances | | all endpoints done |
| - Security Groups | | core endpoints done |
| - Tags | | all endpoints done |
| - AMI | | - core endpoints done |
| - EBS | | - core endpoints done |
| - Instances | | - all endpoints done |
| - Security Groups | | - core endpoints done |
| - Tags | | - all endpoints done |
+-----------------------+---------------------+-----------------------------------+
| ECS | @mock_ecs | basic endpoints done |
+-----------------------+---------------------+-----------------------------------+
Expand Down
3 changes: 2 additions & 1 deletion moto/__init__.py
Original file line number Diff line number Diff line change
Expand Up @@ -3,7 +3,7 @@
# logging.getLogger('boto').setLevel(logging.CRITICAL)

__title__ = 'moto'
__version__ = '1.3.6'
__version__ = '1.3.7'

from .acm import mock_acm # flake8: noqa
from .apigateway import mock_apigateway, mock_apigateway_deprecated # flake8: noqa
Expand All @@ -28,6 +28,7 @@
from .iam import mock_iam, mock_iam_deprecated # flake8: noqa
from .kinesis import mock_kinesis, mock_kinesis_deprecated # flake8: noqa
from .kms import mock_kms, mock_kms_deprecated # flake8: noqa
from .organizations import mock_organizations # flake8: noqa
from .opsworks import mock_opsworks, mock_opsworks_deprecated # flake8: noqa
from .polly import mock_polly # flake8: noqa
from .rds import mock_rds, mock_rds_deprecated # flake8: noqa
Expand Down
15 changes: 12 additions & 3 deletions moto/apigateway/models.py
Original file line number Diff line number Diff line change
Expand Up @@ -10,6 +10,7 @@
import responses
from moto.core import BaseBackend, BaseModel
from .utils import create_id
from moto.core.utils import path_url
from .exceptions import StageNotFoundException, ApiKeyNotFoundException

STAGE_URL = "https://{api_id}.execute-api.{region_name}.amazonaws.com/{stage_name}"
Expand Down Expand Up @@ -372,7 +373,8 @@ def get_resource_for_path(self, path_after_stage_name):
# TODO deal with no matching resource

def resource_callback(self, request):
path_after_stage_name = '/'.join(request.path_url.split("/")[2:])
path = path_url(request.url)
path_after_stage_name = '/'.join(path.split("/")[2:])
if not path_after_stage_name:
path_after_stage_name = '/'

Expand Down Expand Up @@ -606,8 +608,15 @@ def create_usage_plan(self, payload):
self.usage_plans[plan['id']] = plan
return plan

def get_usage_plans(self):
return list(self.usage_plans.values())
def get_usage_plans(self, api_key_id=None):
plans = list(self.usage_plans.values())
if api_key_id is not None:
plans = [
plan
for plan in plans
if self.usage_plan_keys.get(plan['id'], {}).get(api_key_id, False)
]
return plans

def get_usage_plan(self, usage_plan_id):
return self.usage_plans[usage_plan_id]
Expand Down
3 changes: 2 additions & 1 deletion moto/apigateway/responses.py
Original file line number Diff line number Diff line change
Expand Up @@ -255,7 +255,8 @@ def usage_plans(self, request, full_url, headers):
if self.method == 'POST':
usage_plan_response = self.backend.create_usage_plan(json.loads(self.body))
elif self.method == 'GET':
usage_plans_response = self.backend.get_usage_plans()
api_key_id = self.querystring.get("keyId", [None])[0]
usage_plans_response = self.backend.get_usage_plans(api_key_id=api_key_id)
return 200, {}, json.dumps({"item": usage_plans_response})
return 200, {}, json.dumps(usage_plan_response)

Expand Down
6 changes: 3 additions & 3 deletions moto/awslambda/responses.py
Original file line number Diff line number Diff line change
Expand Up @@ -7,7 +7,7 @@
except ImportError:
from urllib.parse import unquote

from moto.core.utils import amz_crc32, amzn_request_id
from moto.core.utils import amz_crc32, amzn_request_id, path_url
from moto.core.responses import BaseResponse
from .models import lambda_backends

Expand Down Expand Up @@ -94,7 +94,7 @@ def policy(self, request, full_url, headers):
return self._add_policy(request, full_url, headers)

def _add_policy(self, request, full_url, headers):
path = request.path if hasattr(request, 'path') else request.path_url
path = request.path if hasattr(request, 'path') else path_url(request.url)
function_name = path.split('/')[-2]
if self.lambda_backend.get_function(function_name):
policy = request.body.decode('utf8')
Expand All @@ -104,7 +104,7 @@ def _add_policy(self, request, full_url, headers):
return 404, {}, "{}"

def _get_policy(self, request, full_url, headers):
path = request.path if hasattr(request, 'path') else request.path_url
path = request.path if hasattr(request, 'path') else path_url(request.url)
function_name = path.split('/')[-2]
if self.lambda_backend.get_function(function_name):
lambda_function = self.lambda_backend.get_function(function_name)
Expand Down
2 changes: 2 additions & 0 deletions moto/backends.py
Original file line number Diff line number Diff line change
Expand Up @@ -27,6 +27,7 @@
from moto.kms import kms_backends
from moto.logs import logs_backends
from moto.opsworks import opsworks_backends
from moto.organizations import organizations_backends
from moto.polly import polly_backends
from moto.rds2 import rds2_backends
from moto.redshift import redshift_backends
Expand Down Expand Up @@ -74,6 +75,7 @@
'kinesis': kinesis_backends,
'kms': kms_backends,
'opsworks': opsworks_backends,
'organizations': organizations_backends,
'polly': polly_backends,
'redshift': redshift_backends,
'rds': rds2_backends,
Expand Down
5 changes: 4 additions & 1 deletion moto/cognitoidentity/responses.py
Original file line number Diff line number Diff line change
Expand Up @@ -3,6 +3,7 @@
from moto.core.responses import BaseResponse

from .models import cognitoidentity_backends
from .utils import get_random_identity_id


class CognitoIdentityResponse(BaseResponse):
Expand Down Expand Up @@ -31,4 +32,6 @@ def get_credentials_for_identity(self):
return cognitoidentity_backends[self.region].get_credentials_for_identity(self._get_param('IdentityId'))

def get_open_id_token_for_developer_identity(self):
return cognitoidentity_backends[self.region].get_open_id_token_for_developer_identity(self._get_param('IdentityId'))
return cognitoidentity_backends[self.region].get_open_id_token_for_developer_identity(
self._get_param('IdentityId') or get_random_identity_id(self.region)
)
2 changes: 1 addition & 1 deletion moto/cognitoidentity/utils.py
Original file line number Diff line number Diff line change
Expand Up @@ -2,4 +2,4 @@


def get_random_identity_id(region):
return "{0}:{0}".format(region, get_random_hex(length=19))
return "{0}:{1}".format(region, get_random_hex(length=19))
38 changes: 34 additions & 4 deletions moto/cognitoidp/models.py
Original file line number Diff line number Diff line change
Expand Up @@ -24,7 +24,7 @@ class CognitoIdpUserPool(BaseModel):

def __init__(self, region, name, extended_config):
self.region = region
self.id = str(uuid.uuid4())
self.id = "{}_{}".format(self.region, str(uuid.uuid4().hex))
self.name = name
self.status = None
self.extended_config = extended_config or {}
Expand Down Expand Up @@ -84,7 +84,11 @@ def create_refresh_token(self, client_id, username):
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

Expand All @@ -97,6 +101,21 @@ def create_tokens_from_refresh_token(self, refresh_token):
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):

Expand Down Expand Up @@ -138,6 +157,9 @@ def to_json(self, extended=False):

return user_pool_client_json

def get_readable_fields(self):
return self.extended_config.get('ReadAttributes', [])


class CognitoIdpIdentityProvider(BaseModel):

Expand Down Expand Up @@ -361,7 +383,7 @@ def admin_get_user(self, user_pool_id, username):
raise ResourceNotFoundError(user_pool_id)

if username not in user_pool.users:
raise ResourceNotFoundError(username)
raise UserNotFoundError(username)

return user_pool.users[username]

Expand All @@ -372,13 +394,21 @@ def list_users(self, user_pool_id):

return user_pool.users.values()

def admin_disable_user(self, user_pool_id, username):
user = self.admin_get_user(user_pool_id, username)
user.enabled = False

def admin_enable_user(self, user_pool_id, username):
user = self.admin_get_user(user_pool_id, username)
user.enabled = True

def admin_delete_user(self, user_pool_id, username):
user_pool = self.user_pools.get(user_pool_id)
if not user_pool:
raise ResourceNotFoundError(user_pool_id)

if username not in user_pool.users:
raise ResourceNotFoundError(username)
raise UserNotFoundError(username)

del user_pool.users[username]

Expand Down
12 changes: 12 additions & 0 deletions moto/cognitoidp/responses.py
Original file line number Diff line number Diff line change
Expand Up @@ -160,6 +160,18 @@ def list_users(self):
"Users": [user.to_json(extended=True) for user in users]
})

def admin_disable_user(self):
user_pool_id = self._get_param("UserPoolId")
username = self._get_param("Username")
cognitoidp_backends[self.region].admin_disable_user(user_pool_id, username)
return ""

def admin_enable_user(self):
user_pool_id = self._get_param("UserPoolId")
username = self._get_param("Username")
cognitoidp_backends[self.region].admin_enable_user(user_pool_id, username)
return ""

def admin_delete_user(self):
user_pool_id = self._get_param("UserPoolId")
username = self._get_param("Username")
Expand Down
Loading

0 comments on commit dd0f047

Please sign in to comment.