Пример #1
0
def get_repo(record):
    """This is not a decorator"""
    sys.path.append('data_dynamodb')
    sys.path.append('data_common')
    from data_common.exceptions import UserIdNotInObject
    from data_dynamodb.dynamodb_repository import DynamoRepository
    import json

    try:
        body = record['body']
        user_id = json.loads(body)['user_id']
    except KeyError:
        raise UserIdNotInObject

    # While developing, dynamodb local is used. So if `DYANMODB_LOCAL_ENDPOINT` is present in env vars
    # dynamodb boto client is patched to use local db
    try:
        repo = DynamoRepository(
            region_name=os.environ['REGION'],
            table='sp-{STAGE}'.format(STAGE=os.environ['STAGE']),
            user_id=user_id,
            dynamodb_local_endpoint=os.environ['DYNAMO_ENDPOINT'])

    except KeyError:
        repo = DynamoRepository(
            region_name=os.environ['REGION'],
            table='sp-{STAGE}'.format(STAGE=os.environ['STAGE']),
            user_id=user_id,
        )

    return repo
Пример #2
0
def get_purchase_orders_by_ship_date(event, context):
    """
    Get list of purchase orders by ship_date range
    """
    logger.debug('event: {}'.format(event))

    params = get_path_parameters(event)

    min_ship_date = params['min_ship_date']
    max_ship_date = params.get('max_ship_date', None)

    if hasattr(context, 'supplier_id'):
        supplier_id = context.supplier_id
        distributors = []
    else:
        supplier_id = None
        distributor_id = context.distributor_id
        try:
            repo = DynamoRepository(
                region_name=os.environ['REGION'],
                dynamodb_local_endpoint=os.environ['DYNAMO_ENDPOINT'])

        except KeyError:
            repo = DynamoRepository(region_name=os.environ['REGION'], )
        supplier_distributors = repo.get_all_distributor_suppliers(
            distributor_id)
        distributors = [
            item['supplier_distributor_id'] for item in supplier_distributors
        ]

    items = context.repo.get_purchase_orders_by_ship_date_range(
        min_ship_date, max_ship_date, supplier_id, distributors)

    return {'statusCode': 200, 'body': json.dumps(items)}
Пример #3
0
def charge_by_stripe(event, context):
    logger.debug('event: {}'.format(event))

    try:
        body = get_body(event)
    except json.JSONDecodeError:
        return {
            'statusCode': 400,
            'body': json.dumps({'error': 'Bad parameter(s) in request'})
        }

    email = body["email"]

    user_id = '00000000-0000-0000-0000-000000000000'

    try:
        repo = DynamoRepository(
            region_name=os.environ['REGION'],
            user_id=user_id,
            email=email,
            dynamodb_local_endpoint=os.environ['DYNAMO_ENDPOINT'])
    except KeyError:
        repo = DynamoRepository(region_name=os.environ['REGION'],
                                user_id=user_id,
                                email=email)

    resp = repo.charge_by_stripe(body)

    if 'status' in resp and resp['status'] == 'succeeded':
        return {'statusCode': 200, 'body': json.dumps(resp)}
    else:
        return {'statusCode': 500, 'body': json.dumps(resp)}
Пример #4
0
def get_every_brand(event, context):
    """
    Get all brands
    """
    logger.debug('event: {}'.format(event))

    if hasattr(context, 'supplier_id'):
        supplier = context.supplier_id
    else:
        distributor_id = context.distributor_id
        try:
            repo = DynamoRepository(
                region_name=os.environ['REGION'],
                dynamodb_local_endpoint=os.environ['DYNAMO_ENDPOINT']
            )

        except KeyError:
            repo = DynamoRepository(
                region_name=os.environ['REGION'],
            )
        supplier_distributors = repo.get_all_distributor_suppliers(distributor_id)
        supplier = [item['supplier_id'] for item in supplier_distributors]

    items = context.repo.get_all_brands(supplier)

    return {
        'statusCode': 200,
        'body': json.dumps(items)
    }
Пример #5
0
def get_repo(user_id):
    if "DYNAMO_ENDPOINT" in os.environ:
        return DynamoRepository(
            region_name=os.environ['REGION'],
            user_id=user_id,
            dynamodb_local_endpoint=os.environ['DYNAMO_ENDPOINT'])

    return DynamoRepository(region_name=os.environ['REGION'], user_id=user_id)
Пример #6
0
def get_repo(user_id):
    if "DYNAMO_ENDPOINT" in os.environ:
        return DynamoRepository(
            region_name=os.environ['REGION'],
            table='brewoptix-{STAGE}'.format(STAGE=os.environ['STAGE']),
            user_id=user_id,
            dynamodb_local_endpoint=os.environ['DYNAMO_ENDPOINT']
        )

    return DynamoRepository(
        region_name=os.environ['REGION'],
        table='brewoptix-{STAGE}'.format(STAGE=os.environ['STAGE']),
        user_id=user_id
    )
Пример #7
0
def get_by_id(event, context):
    """
    Get an count record by its id
    """
    logger.debug('event: {}'.format(event))

    params = get_path_parameters(event)

    if hasattr(context, 'supplier_id'):
        supplier_id = context.supplier_id
        distributors = []
    else:
        supplier_id = None
        distributor_id = context.distributor_id
        try:
            repo = DynamoRepository(
                region_name=os.environ['REGION'],
                dynamodb_local_endpoint=os.environ['DYNAMO_ENDPOINT'])

        except KeyError:
            repo = DynamoRepository(region_name=os.environ['REGION'], )
        supplier_distributors = repo.get_all_distributor_suppliers(
            distributor_id)
        distributors = [
            item['supplier_distributor_id'] for item in supplier_distributors
        ]

    try:
        entity_id = params['entity_id']

        item = context.repo.get_purchase_order_by_id(entity_id, supplier_id,
                                                     distributors)

        return {'statusCode': 200, 'body': json.dumps(item)}
    except NoSuchEntity as ex:
        return {
            'statusCode':
            404,
            'body':
            json.dumps({
                'error':
                '{RESOURCE} Resource not found'.format(RESOURCE=str(ex))
            })
        }
Пример #8
0
def get_repo(record):
    """This is not a decorator"""
    sys.path.append('data_dynamodb')
    sys.path.append('data_common')
    from data_common.exceptions import UserIdNotInObject
    from data_dynamodb.dynamodb_repository import DynamoRepository
    import json

    try:
        body = record['body']
        user_id = json.loads(body)['user_id']
    except KeyError:
        raise UserIdNotInObject

    # While developing, dynamodb local is used. So if `DYANMODB_LOCAL_ENDPOINT` is present in env vars
    # dynamodb boto client is patched to use local db
    try:
        repo = DynamoRepository(
            region_name=os.environ['REGION'],
            user_id=user_id,
            aurora_db_arn=os.environ['AURORA_DB_ARN'],
            aurora_db_secret_arn=os.environ['AURORA_DB_SECRET_ARN'],
            aurora_db_name=os.environ['AURORA_DB_NAME'],
            dynamodb_local_endpoint=os.environ['DYNAMO_ENDPOINT'])

    except KeyError:
        repo = DynamoRepository(
            region_name=os.environ['REGION'],
            user_id=user_id,
            aurora_db_arn=os.environ['AURORA_DB_ARN'],
            aurora_db_secret_arn=os.environ['AURORA_DB_SECRET_ARN'],
            aurora_db_name=os.environ['AURORA_DB_NAME'])

    # pull and insert app_metadata
    suppliers = {}
    if user_id:
        app_metadata = repo.get_user_app_metadata()

        if "suppliers" in app_metadata:
            suppliers = app_metadata["suppliers"]

    return repo, suppliers
Пример #9
0
    def wrapper(event, context):
        sys.path.append('data_dynamodb')
        sys.path.append('data_common')
        from data_dynamodb.dynamodb_repository import DynamoRepository

        # While developing, dynamodb local is used. So if `DYANMODB_LOCAL_ENDPOINT` is present in env vars
        # dynamodb boto client is patched to use local db
        try:
            context.repo = DynamoRepository(
                region_name=os.environ['REGION'],
                user_id=context.user_id,
                email=context.email,
                aurora_db_arn=os.environ['AURORA_DB_ARN'],
                aurora_db_secret_arn=os.environ['AURORA_DB_SECRET_ARN'],
                aurora_db_name=os.environ['AURORA_DB_NAME'],
                dynamodb_local_endpoint=os.environ['DYNAMO_ENDPOINT'])

        except KeyError:
            context.repo = DynamoRepository(
                region_name=os.environ['REGION'],
                user_id=context.user_id,
                email=context.email,
                aurora_db_arn=os.environ['AURORA_DB_ARN'],
                aurora_db_secret_arn=os.environ['AURORA_DB_SECRET_ARN'],
                aurora_db_name=os.environ['AURORA_DB_NAME'])

        # pull and insert app_metadata
        app_metadata = context.repo.get_user_app_metadata()

        if "suppliers" in app_metadata:
            context.suppliers = app_metadata["suppliers"]
        else:
            context.suppliers = {}

        if "distributors" in app_metadata:
            context.distributors = app_metadata["distributors"]
        else:
            context.distributors = {}

        return handler(event, context)
Пример #10
0
    def wrapper(event, context):
        sys.path.append('data_dynamodb')
        sys.path.append('data_common')
        from data_dynamodb.dynamodb_repository import DynamoRepository

        # While developing, dynamodb local is used. So if `DYANMODB_LOCAL_ENDPOINT` is present in env vars
        # dynamodb boto client is patched to use local db
        context.repo = DynamoRepository(
            region_name=os.environ['REGION'],
            table='sp-{STAGE}'.format(STAGE=os.environ['STAGE']),
            user_id=context.user_id,
            email=context.email,
            dynamodb_local_endpoint=os.environ['DYNAMO_ENDPOINT']
            if 'DYNAMO_ENDPOINT' in os.environ else None)

        return handler(event, context)
Пример #11
0
def signup(event, context):
    event_log = deepcopy(event)
    try:
        event_log["body"].pop("password")
    except KeyError:
        pass
    logger.debug('event: {}'.format(event_log))

    if os.environ[
            'SIGNUP_ORIGIN_URL'] is not "*":  # "*" means accept any origin
        # Check if the request is originating from a valid URI
        origin = event['headers']['origin']
        valid_origin_uri = urlparse(os.environ['SIGNUP_ORIGIN_URL'])
        request_uri = urlparse(origin)

        if request_uri.netloc not in valid_origin_uri.netloc:
            logger.error("Request origin domain: {REQ_DOM}, "
                         "Valid origin domain: {VALID_DOM}".format(
                             REQ_DOM=request_uri.netloc,
                             VALID_DOM=valid_origin_uri.netloc))
            return {
                'statusCode':
                401,
                'body':
                json.dumps({
                    'error':
                    'Unauthorized. Request originating from invalid domain'
                })
            }

    try:
        body = get_body(event)
    except json.JSONDecodeError:
        logger.error("bad JSON payload")
        return {
            'statusCode': 400,
            'body': json.dumps({'error': 'Bad parameter(s) in request'})
        }
    except:
        logger.log_uncaught_exception()

    if 'email' not in body or not body[
            'email'] or 'password' not in body or not body['password']:
        logger.error("username, and/or password is missing in JSON")
        return {
            'statusCode':
            400,
            'body':
            json.dumps({
                'error':
                'Missing required key-value pair(s) in request body'
            })
        }

    email = body['email']
    password = body['password']
    name = body.get('name', '')

    # get Machine-to-machine access token
    resp = requests.post(os.environ['AUTH0_DOMAIN'] + '/oauth/token',
                         json={
                             'grant_type':
                             'client_credentials',
                             'client_id':
                             os.environ['AUTH0_MANAGEMENT_API_CLIENT_ID'],
                             'client_secret':
                             os.environ['AUTH0_MANAGEMENT_API_CLIENT_SECRET'],
                             'audience':
                             os.environ['AUTH0_AUDIENCE'],
                             'scope':
                             'create:users'
                         },
                         headers={'content-type': "application/json"})

    body = resp.json()

    if all(k in body
           for k in ['access_token', 'scope', 'expires_in', 'token_type']):
        pass  # to the next section of code
    elif 'error_description' in body:
        logger.error(
            "POST /oauth/token did not return all of 'access_token, id_token, scope, expires_in, token_type'"
        )
        logger.error(body['error_description'])
        return {
            'statusCode': 400,
            'body': json.dumps({'error': body['error_description']})
        }
    else:
        logger.error(
            "POST /oauth/token did not return all of 'access_token, id_token, scope, expires_in, token_type'"
        )
        logger.error("No error message returned from Auth0")
        return {
            'statusCode': 500,
            'body': json.dumps({'error': 'Unknown Error happened'})
        }

    access_token = body['access_token']

    payload = {
        'email': email,
        'password': password,
        'email_verified': True,
        'blocked': False,
        'connection': os.environ['AUTH0_CONNECTION'],
    }

    if name:
        payload['name'] = name

    resp = requests.post(os.environ['AUTH0_DOMAIN'] + "/api/v2/users",
                         json=payload,
                         headers={
                             'Authorization':
                             'Bearer {TOKEN}'.format(TOKEN=access_token),
                             'content-type':
                             "application/json"
                         })

    body = resp.json()

    if all(k in body for k in ['user_id', 'email']):
        user_id = body['user_id'][6:]
        email = body['email']

        # Make a repo object
        sys.path.append('data_dynamodb')
        sys.path.append('data_common')
        from data_dynamodb.dynamodb_repository import DynamoRepository

        # While developing, dynamodb local is used. So if `DYANMODB_LOCAL_ENDPOINT` is present in env vars
        # dynamodb boto client is patched to use local db
        try:
            repo = DynamoRepository(
                region_name=os.environ['REGION'],
                table='sp-{STAGE}'.format(STAGE=os.environ['STAGE']),
                user_id=user_id,
                email=email,
                dynamodb_local_endpoint=os.environ['DYNAMO_ENDPOINT'])

        except KeyError:
            repo = DynamoRepository(
                region_name=os.environ['REGION'],
                table='sp-{STAGE}'.format(STAGE=os.environ['STAGE']),
                user_id=user_id,
                email=email)
        # create new user in `'sp-' + os.environ['STAGE'] + 'user'` table
        user_obj = repo.get_or_create_profile()

        if 'name' in body:
            user_obj['name'] = body['name']
        if 'picture' in body:
            user_obj['avatar_url'] = body['picture']
        if 'nickname' in body:
            user_obj['nickname'] = body['nickname']
        if 'email_verified' in body:
            user_obj['email_verified'] = body['email_verified']
        if 'blocked' in body:
            user_obj['blocked'] = body['blocked']

        user_obj = repo.update_profile(user_obj)

        return {'statusCode': 200, 'body': json.dumps(user_obj)}
    elif 'message' in body:
        logger.error(
            "Failed: POST %AUTH0_DOMAIN%/api/v2/users for AUTH0_DOMAIN={AUTH0_DOMAIN}"
            .format(AUTH0_DOMAIN=os.environ['AUTH0_DOMAIN']))
        logger.error(body['message'])
        return {
            'statusCode': body.get('statusCode', 400),
            'body': json.dumps({'error': body['message']})
        }
    else:
        logger.error(
            "Failed: POST %AUTH0_DOMAIN%/api/v2/users for AUTH0_DOMAIN={AUTH0_DOMAIN}"
            .format(AUTH0_DOMAIN=os.environ['AUTH0_DOMAIN']))
        return {
            'statusCode': 500,
            'body': json.dumps({'error': 'Unknown Error happened'})
        }
Пример #12
0
def signup(event, context):
    event_log = deepcopy(event)
    try:
        event_log["body"].pop("password")
    except KeyError:
        pass
    logger.debug('event: {}'.format(event_log))

    if os.environ[
            'SIGNUP_ORIGIN_URL'] is not "*":  # "*" means accept any origin
        # Check if the request is originating from a valid URI
        origin = event['headers']['origin']
        valid_origin_uri = urlparse(os.environ['SIGNUP_ORIGIN_URL'])
        request_uri = urlparse(origin)

        if request_uri.netloc not in valid_origin_uri.netloc:
            logger.error("Request origin domain: {REQ_DOM}, "
                         "Valid origin domain: {VALID_DOM}".format(
                             REQ_DOM=request_uri.netloc,
                             VALID_DOM=valid_origin_uri.netloc))
            return {
                'statusCode':
                401,
                'body':
                json.dumps({
                    'error':
                    'Unauthorized. Request originating from invalid domain'
                })
            }

    try:
        body = get_body(event)
    except json.JSONDecodeError:
        return {
            'statusCode': 400,
            'body': json.dumps({'error': 'Bad parameter(s) in request'})
        }

    if 'email' not in body or not body[
            'email'] or 'password' not in body or not body['password']:
        return {
            'statusCode':
            400,
            'body':
            json.dumps({
                'error':
                'Missing required key-value pair(s) in request body'
            })
        }

    email = body['email']
    password = body['password']
    name = body.get('name', '')
    company_name = body.get('company_name', '')
    is_distributor = body.get('is_distributor', False)
    website = body.get('website', '')

    # get Machine-to-machine access token
    resp = requests.post(os.environ['AUTH0_DOMAIN'] + '/oauth/token',
                         json={
                             'grant_type':
                             'client_credentials',
                             'client_id':
                             os.environ['AUTH0_MANAGEMENT_API_CLIENT_ID'],
                             'client_secret':
                             os.environ['AUTH0_MANAGEMENT_API_CLIENT_SECRET'],
                             'audience':
                             os.environ['AUTH0_AUDIENCE'],
                             'scope':
                             'create:users'
                         },
                         headers={'content-type': "application/json"})

    body = resp.json()

    if all(k in body
           for k in ['access_token', 'scope', 'expires_in', 'token_type']):
        pass  # to the next section of code
    elif 'error_description' in body:
        return {
            'statusCode': 400,
            'body': json.dumps({'error': body['error_description']})
        }
    else:
        return {
            'statusCode': 500,
            'body': json.dumps({'error': 'Unknown Error happened'})
        }

    access_token = body['access_token']

    payload = {
        'email': email,
        'password': password,
        'email_verified': True,
        'blocked': False,
        'connection': os.environ['AUTH0_CONNECTION'],
    }

    if name:
        payload['name'] = name

    resp = requests.post(os.environ['AUTH0_DOMAIN'] + "/api/v2/users",
                         json=payload,
                         headers={
                             'Authorization':
                             'Bearer {TOKEN}'.format(TOKEN=access_token),
                             'content-type':
                             "application/json"
                         })

    body = resp.json()
    print(body)

    if all(k in body for k in ['user_id', 'email']):
        user_id = body['user_id'][6:]
        email = body['email']

        # Make a repo object
        sys.path.append('data_dynamodb')
        sys.path.append('data_common')
        from data_dynamodb.dynamodb_repository import DynamoRepository

        # While developing, dynamodb local is used. So if `DYANMODB_LOCAL_ENDPOINT` is present in env vars
        # dynamodb boto client is patched to use local db
        try:
            repo = DynamoRepository(
                region_name=os.environ['REGION'],
                user_id=user_id,
                email=email,
                dynamodb_local_endpoint=os.environ['DYNAMO_ENDPOINT'])

        except KeyError:
            repo = DynamoRepository(region_name=os.environ['REGION'],
                                    user_id=user_id,
                                    email=email)
        # create new user in `brewoptix-users` table
        user_obj = repo.get_or_create_profile()

        if 'name' in body:
            user_obj['name'] = body['name']
        if 'picture' in body:
            user_obj['picture'] = body['picture']
        if 'nickname' in body:
            user_obj['nickname'] = body['nickname']
        if 'email_verified' in body:
            user_obj['email_verified'] = body['email_verified']
        if 'blocked' in body:
            user_obj['blocked'] = body['blocked']

        user_obj = repo.update_profile(user_obj)

        # check if "company_name" in request body and create supplier
        if company_name:
            if not is_distributor:
                supplier = {"name": company_name, "website": website}

                supplier_obj = repo.save_supplier(supplier)

                # add user to distributors's users list
                supplier_id = supplier_obj["entity_id"]
                user_info = {
                    "email": email,
                    "role": "admin",
                    "name": user_obj.get("name", "")
                }
                try:
                    repo.upsert_user_in_supplier(supplier_id, user_info)
                except Auth0UnknownError as ex:
                    return {
                        'statusCode':
                        400,
                        'body':
                        json.dumps({
                            'error':
                            "User created. Auth0 error: {ERROR}".format(
                                ERROR=str(ex))
                        })
                    }
                except Auth0UnableToAccess:
                    return {
                        'statusCode':
                        400,
                        'body':
                        json.dumps({
                            'error':
                            "User created. But app_metadata update failed, Unable to access Auth0"
                        })
                    }
            else:
                distributor = {"name": company_name, "website": website}

                distributor_obj = repo.save_distributor(distributor)

                # add user to distributors's users list
                distributor_id = distributor_obj["entity_id"]
                user_info = {
                    "email": email,
                    "role": "admin",
                    "name": user_obj.get("name", "")
                }
                try:
                    repo.upsert_user_in_distributor(distributor_id, user_info)
                except Auth0UnknownError as ex:
                    return {
                        'statusCode':
                        400,
                        'body':
                        json.dumps({
                            'error':
                            "User created. Auth0 error: {ERROR}".format(
                                ERROR=str(ex))
                        })
                    }
                except Auth0UnableToAccess:
                    return {
                        'statusCode':
                        400,
                        'body':
                        json.dumps({
                            'error':
                            "User created. But app_metadata update failed, Unable to access Auth0"
                        })
                    }

        email_data = {
            'email': email,
            'name': name,
            'website': website,
            'company_name': company_name
        }
        if is_distributor:
            email_data['brewery_distributor'] = "Distributor"
        else:
            email_data['brewery_distributor'] = "Brewery"

        to_list = NEW_USER_NOTIFICATION_LIST.split(',')
        to_email_list = []
        for item in to_list:
            to_email_list.append(item.strip())

        # Send the SQS message
        sqs = boto3.resource('sqs')
        queue = sqs.get_queue_by_name(QueueName=SQS_EMAIL_TRANSMITTER)
        try:
            message_body = {
                "template": USER_REGISTER_EMAIL_TEMPLATE,
                "to": to_email_list,
                "data": email_data
            }
            print(message_body)
            response = queue.send_message(MessageBody=json.dumps(message_body))
            logger.debug('response: {}'.format(response))
        except ClientError as e:
            logger.debug('error: {}'.format(e))

        return {'statusCode': 200, 'body': json.dumps(user_obj)}
    elif 'message' in body:
        return {
            'statusCode': body.get('statusCode', 400),
            'body': json.dumps({'error': body['message']})
        }
    else:
        return {
            'statusCode': 500,
            'body': json.dumps({'error': 'Unknown Error happened'})
        }
Пример #13
0
def login(event, context):
    event_log = deepcopy(event)
    try:
        event_log["body"].pop("password")
    except KeyError:
        pass
    logger.debug('event: {}'.format(event_log))

    try:
        body = get_body(event)
    except json.JSONDecodeError:
        return {
            'statusCode': 400,
            'body': json.dumps({'error': 'Bad parameter(s) in request'})
        }

    if not all([k in body for k in ['username', 'password']]) or \
            not all([body[k] for k in ['username', 'password']]):
        return {
            'statusCode':
            400,
            'body':
            json.dumps({'error': 'Both username and password are required.'})
        }

    # Authenticate and get tokens
    req = requests.post(os.environ['AUTH0_DOMAIN'] + '/oauth/token',
                        json={
                            'grant_type': 'password',
                            'username': body['username'],
                            'password': body['password'],
                            'audience': os.environ['AUTH0_AUDIENCE'],
                            'client_id': os.environ['AUTH0_CLIENT_ID'],
                            'client_secret': os.environ['AUTH0_CLIENT_SECRET'],
                            'scope': 'openid'
                        })

    body = req.json()

    # extract payload for jwt token
    if 'id_token' in body:
        _id_token = body['id_token']
        payload = jwt_decode(_id_token, AUTH0_CLIENT_PUBLIC_KEY)
    else:
        if 'error_description' in body:
            return {
                'statusCode': 400,
                'body': json.dumps({'error': body['error_description']})
            }
        else:
            return {
                'statusCode': 500,
                'body': json.dumps({'error': 'Unknown Error happened'})
            }

    # get Auth0 user profile object (in order to get app_metadata)
    resp = requests.post(os.environ['AUTH0_DOMAIN'] + '/oauth/token',
                         json={
                             'grant_type':
                             'client_credentials',
                             'client_id':
                             os.environ['AUTH0_MANAGEMENT_API_CLIENT_ID'],
                             'client_secret':
                             os.environ['AUTH0_MANAGEMENT_API_CLIENT_SECRET'],
                             'audience':
                             os.environ['AUTH0_AUDIENCE'],
                             'scope':
                             'read:users'
                         },
                         headers={'content-type': "application/json"})

    users_token_body = resp.json()

    if 'access_token' in users_token_body:
        _access_token = users_token_body['access_token']
        _auth0_user_id = payload['sub']
        resp = requests.get(
            os.environ['AUTH0_DOMAIN'] +
            '/api/v2/users/{ID}'.format(ID=_auth0_user_id),
            headers={
                'content-type':
                "application/json",
                'Authorization':
                'Bearer {ACCESS_TOKEN}'.format(ACCESS_TOKEN=_access_token)
            })

        users_body = resp.json()
        if "app_metadata" not in users_body:
            app_metadata = {}
        else:
            app_metadata = users_body["app_metadata"]

        # update app_metadata in users object
        # While developing, dynamodb local is used. So if `DYANMODB_LOCAL_ENDPOINT` is present in env vars
        # dynamodb boto client is patched to use local db
        email = payload['email']
        user_id = payload['sub'][6:]
        try:
            repo = DynamoRepository(
                region_name=os.environ['REGION'],
                user_id=user_id,
                email=email,
                dynamodb_local_endpoint=os.environ['DYNAMO_ENDPOINT'])

        except KeyError:
            repo = DynamoRepository(region_name=os.environ['REGION'],
                                    user_id=user_id,
                                    email=email)

        try:
            repo.update_user_app_metadata(app_metadata)
        except NoSuchEntity:
            return {
                'statusCode': 404,
                'body': json.dumps({'error': 'User not found'})
            }
    else:
        if 'error_description' in users_token_body:
            return {
                'statusCode': 400,
                'body': json.dumps({'error': body['error_description']})
            }
        else:
            return {
                'statusCode': 500,
                'body': json.dumps({'error': 'Unknown Error happened'})
            }

    if all(k in body for k in
           ['access_token', 'id_token', 'scope', 'expires_in', 'token_type']):
        return {'statusCode': 200, 'body': json.dumps(body)}
    elif 'error_description' in body:
        return {
            'statusCode': 400,
            'body': json.dumps({'error': body['error_description']})
        }
    else:
        return {
            'statusCode': 500,
            'body': json.dumps({'error': 'Unknown Error happened'})
        }
Пример #14
0
def social_signup(event, context):
    logger.debug('event: {}'.format(event))

    if os.environ['SIGNUP_ORIGIN_URL'] is not "*":    # "*" means accept any origin
        # Check if the request is originating from a valid URI
        origin = event['headers']['origin']
        valid_origin_uri = urlparse(os.environ['SIGNUP_ORIGIN_URL'])
        request_uri = urlparse(origin)

        if request_uri.netloc not in valid_origin_uri.netloc:
            logger.error("Request origin domain: {REQ_DOM}, "
                         "Valid origin domain: {VALID_DOM}".format(REQ_DOM=request_uri.netloc,
                                                                   VALID_DOM=valid_origin_uri.netloc))
            return {
                'statusCode': 401,
                'body': json.dumps({
                    'error': 'Unauthorized. Request originating from invalid domain'
                })
            }

    try:
        body = get_body(event)
    except json.JSONDecodeError:
        return {
            'statusCode': 400,
            'body': json.dumps({
                'error': 'Bad parameter(s) in request'
            })
        }

    if 'authorization_code' not in body or not body['authorization_code']:
        return {
            'statusCode': 400,
            'body': json.dumps({
                'error': 'Missing authorization_code in request body'
            })
        }

    authorization_code = body['authorization_code']

    # get access token
    resp = requests.post(
        url=os.environ['AUTH0_DOMAIN'] + '/oauth/token',
        data={
            'grant_type': 'authorization_code',
            'client_id': os.environ['AUTH0_CLIENT_ID'],
            'client_secret': os.environ['AUTH0_CLIENT_SECRET'],
            'code': authorization_code,
            'redirect_uri': 'https://localhost:8080/callback'
        },
        headers={
            'content-type': "application/x-www-form-urlencoded"
        }
    )

    body = resp.json()

    if all(k in body for k in [
        'access_token',
        'id_token',
        'expires_in',
        'token_type'
    ]):
        pass    # to the next section of code
    elif 'error_description' in body:
        return {
            'statusCode': 400,
            'body': json.dumps({
                'error': body['error_description']
            })
        }
    else:
        return {
            'statusCode': 500,
            'body': json.dumps({
                'error': 'Unknown Error happened'
            })
        }

    # extract payload for jwt token
    if 'id_token' in body:
        _id_token = body['id_token']
        payload = jwt_decode(_id_token, AUTH0_CLIENT_PUBLIC_KEY)
    else:
        if 'error_description' in body:
            return {
                'statusCode': 400,
                'body': json.dumps({
                    'error': body['error_description']
                })
            }
        else:
            return {
                'statusCode': 500,
                'body': json.dumps({
                    'error': 'Unknown Error happened'
                })
            }

    if all(k in payload for k in [
        'email',
        'sub'
    ]):
        # extract user id, social user id format: social-type|user_id
        user_id = payload['sub']
        email = payload['email']

        # Make a repo object
        sys.path.append('data_dynamodb')
        sys.path.append('data_common')
        from data_dynamodb.dynamodb_repository import DynamoRepository

        # While developing, dynamodb local is used. So if `DYANMODB_LOCAL_ENDPOINT` is present in env vars
        # dynamodb boto client is patched to use local db
        try:
            repo = DynamoRepository(
                region_name=os.environ['REGION'],
                user_id=user_id,
                email=email,
                dynamodb_local_endpoint=os.environ['DYNAMO_ENDPOINT']
            )

        except KeyError:
            repo = DynamoRepository(
                region_name=os.environ['REGION'],
                user_id=user_id,
                email=email
            )
        # create new user in `brewoptix-users` table
        user_obj = repo.get_or_create_profile()

        if 'name' in payload:
            user_obj['name'] = payload['name']
        if 'picture' in payload:
            user_obj['picture'] = payload['picture']
        if 'nickname' in payload:
            user_obj['nickname'] = payload['nickname']
        if 'email_verified' in payload:
            user_obj['email_verified'] = payload['email_verified']
        if 'blocked' in payload:
            user_obj['blocked'] = payload['blocked']

        user_obj = repo.update_profile(user_obj)
        return {
            'statusCode': 200,
            'body': json.dumps(body)
        }
    elif 'message' in body:
        return {
            'statusCode': body.get('statusCode', 400),
            'body': json.dumps({
                'error': body['message']
            })
        }
    else:
        return {
            'statusCode': 500,
            'body': json.dumps({
                'error': 'Unknown Error happened'
            })
        }
Пример #15
0
def social_signin(event, context):
    event_log = deepcopy(event)

    try:
        body = get_body(event)
    except json.JSONDecodeError:
        return {
            'statusCode': 400,
            'body': json.dumps({
                'error': 'Bad parameter(s) in request'
            })
        }

    if 'authorization_code' not in body or not body['authorization_code']:
        return {
            'statusCode': 400,
            'body': json.dumps({
                'error': 'Missing authorization_code in request body'
            })
        }

    authorization_code = body['authorization_code']

    # get access token
    resp = requests.post(
        url=os.environ['AUTH0_DOMAIN'] + '/oauth/token',
        data={
            'grant_type': 'authorization_code',
            'client_id': os.environ['AUTH0_CLIENT_ID'],
            'client_secret': os.environ['AUTH0_CLIENT_SECRET'],
            'code': authorization_code,
            'redirect_uri': 'https://localhost:8080/callback'
        },
        headers={
            'content-type': "application/x-www-form-urlencoded"
        }
    )

    body = resp.json()

    # extract payload for jwt token
    if 'id_token' in body:
        _id_token = body['id_token']
        payload = jwt_decode(_id_token, AUTH0_CLIENT_PUBLIC_KEY)
    else:
        if 'error_description' in body:
            return {
                'statusCode': 400,
                'body': json.dumps({
                    'error': body['error_description']
                })
            }
        else:
            return {
                'statusCode': 500,
                'body': json.dumps({
                    'error': 'Unknown Error happened'
                })
            }

    if 'access_token' in body:
        _access_token = body['access_token']

        # While developing, dynamodb local is used. So if `DYANMODB_LOCAL_ENDPOINT` is present in env vars
        # dynamodb boto client is patched to use local db
        email = payload['email']
        user_id = payload['sub']
        try:
            repo = DynamoRepository(
                region_name=os.environ['REGION'],
                user_id=user_id,
                email=email,
                dynamodb_local_endpoint=os.environ['DYNAMO_ENDPOINT']
            )

        except KeyError:
            repo = DynamoRepository(
                region_name=os.environ['REGION'],
                user_id=user_id,
                email=email
            )
    else:
        if 'error_description' in body:
            return {
                'statusCode': 400,
                'body': json.dumps({
                    'error': body['error_description']
                })
            }
        else:
            return {
                'statusCode': 500,
                'body': json.dumps({
                    'error': 'Unknown Error happened'
                })
            }

    if all(k in body for k in [
        'access_token',
        'id_token',
        'expires_in',
        'token_type'
    ]):
        body['scope'] = 'openid profile email'
        return {
            'statusCode': 200,
            'body': json.dumps(body)
        }
    elif 'error_description' in body:
        return {
            'statusCode': 400,
            'body': json.dumps({
                'error': body['error_description']
            })
        }
    else:
        return {
            'statusCode': 500,
            'body': json.dumps({
                'error': 'Unknown Error happened'
            })
        }
Пример #16
0
def modify_supplier_distributor(event, context):
    logger.debug('event: {}'.format(event))

    try:
        body = get_body(event)
    except json.JSONDecodeError:
        return {
            'statusCode': 400,
            'body': json.dumps({
                'error': 'Bad parameter(s) in request'
            })
        }

    if "supplier_id" in body and body["supplier_id"] != context.supplier_id:
        return {
            'statusCode': 400,
            'body': json.dumps({
                'error': 'Bad parameter(s) in request. supplier_id in body must match x-supplier-id'
            })
        }

    body["supplier_id"] = context.supplier_id

    if 'allow_ordering' not in body or 'allow_order_updated' not in body:
        return {
            'statusCode': 400,
            'body': json.dumps({
                'error': 'Missing required key-value pair(s) in request body'
            })
        }

    try:
        repo = DynamoRepository(
            region_name=os.environ['REGION'],
            dynamodb_local_endpoint=os.environ['DYNAMO_ENDPOINT']
        )

    except KeyError:
        repo = DynamoRepository(
            region_name=os.environ['REGION']
        )

    if body['allow_order_updated']:
        if body['allow_ordering']:
            try:
                supplier_id = body["supplier_id"]
                access_code = body['access_code']
                repo.delete_distributor_supplier_by_access_code(supplier_id, access_code)
            except NoSuchEntity:
                pass
            body['access_code'] = 'access-disabled'
            body['allow_ordering'] = False
        else:
            body['access_code'] = generate_access_code()
            body['allow_ordering'] = True

    try:
        item = context.repo.save_supplier_distributor(body)
        return {
            'statusCode': 200,
            'body': json.dumps(item)
        }
    except BadParameters as ex:
        return {
            'statusCode': 400,
            'body': json.dumps({
                'error': 'Bad request. The request was Malformed. Wrong type for key-val pair {KEY}'.format(KEY=str(ex))
            })
        }
    except MissingRequiredKey as ex:
        return {
            'statusCode': 400,
            'body': json.dumps({
                'error': 'Bad request. Missing required key-val pair {KEY}'.format(KEY=str(ex))
            })
        }
    except CannotModifyEntityStates:
        return {
            'statusCode': 409,
            'body': json.dumps({
                'error': 'a supplier_distributor with the same name already exists'
            })
        }
Пример #17
0
def add_distributor_supplier(event, context):
    """
    Add a new distributor_supplier
    """
    logger.debug('event: {}'.format(event))

    try:
        body = get_body(event)
    except json.JSONDecodeError:
        return {
            'statusCode': 400,
            'body': json.dumps({'error': 'Bad parameter(s) in request'})
        }

    if 'access_code' not in body or not body['access_code']:
        return {
            'statusCode':
            400,
            'body':
            json.dumps({
                'error':
                'Missing required key-value pair(s) in request body'
            })
        }

    body["distributor_id"] = context.distributor_id

    try:
        repo = DynamoRepository(
            region_name=os.environ['REGION'],
            dynamodb_local_endpoint=os.environ['DYNAMO_ENDPOINT'])

    except KeyError:
        repo = DynamoRepository(region_name=os.environ['REGION'])

    try:
        supplier_distributor_obj = repo.get_supplier_distributor_by_access_code(
            body['access_code'])
        if supplier_distributor_obj['allow_ordering']:
            body["supplier_distributor_id"] = supplier_distributor_obj[
                'entity_id']
            body["supplier_id"] = supplier_distributor_obj['supplier_id']
        else:
            return {
                'statusCode': 403,
                'body': json.dumps({'error': 'Access denied'})
            }
    except NoSuchEntity:
        return {
            'statusCode': 404,
            'body': json.dumps({'error': 'Resource not found'})
        }

    try:
        supplier_id = body['supplier_id']
        supplier_obj = repo.get_supplier_by_id(supplier_id)
        body["nickname"] = supplier_obj['name']
    except NoSuchEntity:
        return {
            'statusCode': 404,
            'body': json.dumps({'error': 'Supplier not found'})
        }

    try:
        body = context.repo.save_distributor_supplier(body)
        return {'statusCode': 200, 'body': json.dumps(body)}
    except BadParameters as ex:
        return {
            'statusCode':
            400,
            'body':
            json.dumps({
                'error':
                'Bad request. The request was Malformed. Wrong type for key-val pair {KEY}'
                .format(KEY=str(ex))
            })
        }
    except MissingRequiredKey as ex:
        return {
            'statusCode':
            400,
            'body':
            json.dumps({
                'error':
                'Bad request. Missing required key-val pair {KEY}'.format(
                    KEY=str(ex))
            })
        }
    except CannotModifyEntityStates:
        return {
            'statusCode':
            409,
            'body':
            json.dumps({
                'error':
                'a distributor_supplier with the same name already exists'
            })
        }
Пример #18
0
def login(event, context):
    event_log = deepcopy(event)
    try:
        event_log["body"].pop("password")
    except KeyError:
        pass
    logger.debug('event: {}'.format(event_log))

    try:
        body = get_body(event)
    except json.JSONDecodeError:
        logger.error("bad JSON payload")
        return {
            'statusCode': 400,
            'body': json.dumps({'error': 'Bad parameter(s) in request'})
        }
    except:
        logger.log_uncaught_exception()

    if not all([k in body for k in ['username', 'password']]) or \
            not all([body[k] for k in ['username', 'password']]):
        logger.error("username, and/or password is missing in JSON")
        return {
            'statusCode':
            400,
            'body':
            json.dumps({'error': 'Both username and password are required.'})
        }

    # Authenticate and get tokens
    req = requests.post(os.environ['AUTH0_DOMAIN'] + '/oauth/token',
                        json={
                            'grant_type': 'password',
                            'username': body['username'],
                            'password': body['password'],
                            'audience': os.environ['AUTH0_AUDIENCE'],
                            'client_id': os.environ['AUTH0_CLIENT_ID'],
                            'client_secret': os.environ['AUTH0_CLIENT_SECRET'],
                            'scope': 'openid'
                        })

    body = req.json()

    # extract payload for jwt token
    if 'id_token' in body:
        _id_token = body['id_token']
        payload = jwt_decode(_id_token, AUTH0_CLIENT_PUBLIC_KEY)
    else:
        logger.error(
            "oAuth token is not returned by Auth0 for POST {AUTH0_DOMAIN}/oauth/token. "
            "Please check if AUTH0_DOMAIN, AUTH0_AUDIENCE, AUTH0_CLIENT_ID, AUTH0_CLIENT_SECRET and "
            "AUTH0_CLIENT_PUBLIC_KEY are set correctly")
        if 'error_description' in body:
            logger.error(body['error_description'])
            return {
                'statusCode': 400,
                'body': json.dumps({'error': body['error_description']})
            }
        else:
            logger.error("No error message returned from Auth0")
            return {
                'statusCode': 500,
                'body': json.dumps({'error': 'Unknown Error happened'})
            }

    # get Auth0 user profile object (in order to get app_metadata)
    resp = requests.post(os.environ['AUTH0_DOMAIN'] + '/oauth/token',
                         json={
                             'grant_type':
                             'client_credentials',
                             'client_id':
                             os.environ['AUTH0_MANAGEMENT_API_CLIENT_ID'],
                             'client_secret':
                             os.environ['AUTH0_MANAGEMENT_API_CLIENT_SECRET'],
                             'audience':
                             os.environ['AUTH0_AUDIENCE'],
                             'scope':
                             'read:users'
                         },
                         headers={'content-type': "application/json"})

    users_token_body = resp.json()

    if 'access_token' in users_token_body:
        _access_token = users_token_body['access_token']
        _auth0_user_id = payload['sub']
        resp = requests.get(
            os.environ['AUTH0_DOMAIN'] +
            '/api/v2/users/{ID}'.format(ID=_auth0_user_id),
            headers={
                'content-type':
                "application/json",
                'Authorization':
                'Bearer {ACCESS_TOKEN}'.format(ACCESS_TOKEN=_access_token)
            })

        users_body = resp.json()
        if "app_metadata" not in users_body:
            app_metadata = {}
        else:
            app_metadata = users_body["app_metadata"]

        if 'error_description' in users_body:
            logger.error(
                "Failed: GET %AUTH0_DOMAIN%/api/v2/users/%ID% for AUTH0_DOMAIN={AUTH0_DOMAIN}, ID={ID}"
                .format(AUTH0_DOMAIN=os.environ['AUTH0_DOMAIN'],
                        ID=_auth0_user_id))
            logger.error(body['error_description'])

        # update app_metadata in users object
        # While developing, dynamodb local is used. So if `DYANMODB_LOCAL_ENDPOINT` is present in env vars
        # dynamodb boto client is patched to use local db
        email = payload['email']
        user_id = payload['sub'][6:]
        try:
            repo = DynamoRepository(
                region_name=os.environ['REGION'],
                table='sp-{STAGE}'.format(STAGE=os.environ['STAGE']),
                user_id=user_id,
                email=email,
                dynamodb_local_endpoint=os.environ['DYNAMO_ENDPOINT'])

        except KeyError:
            repo = DynamoRepository(
                region_name=os.environ['REGION'],
                table='sp-{STAGE}'.format(STAGE=os.environ['STAGE']),
                user_id=user_id,
                email=email)
        except:
            logger.log_uncaught_exception()

        try:
            repo.update_user_app_metadata(app_metadata)
        except NoSuchEntity:
            return {
                'statusCode': 404,
                'body': json.dumps({'error': 'User not found'})
            }
        except:
            logger.log_uncaught_exception()
    else:
        logger.error(
            "oAuth access_token is not returned by Auth0 for POST {AUTH0_DOMAIN}/oauth/token. "
            "Please check if AUTH0_DOMAIN, AUTH0_AUDIENCE, AUTH0_MANAGEMENT_API_CLIENT_ID, and "
            "AUTH0_MANAGEMENT_API_CLIENT_SECRET are set correctly. "
            "Please also check if scope 'read:users' is set in the management app"
        )
        if 'error_description' in users_token_body:
            logger.error(users_token_body['error_description'])
            return {
                'statusCode':
                400,
                'body':
                json.dumps({'error': users_token_body['error_description']})
            }
        else:
            logger.error("No error message returned from Auth0")
            return {
                'statusCode': 500,
                'body': json.dumps({'error': 'Unknown Error happened'})
            }

    if all(k in body for k in
           ['access_token', 'id_token', 'scope', 'expires_in', 'token_type']):
        return {'statusCode': 200, 'body': json.dumps(body)}
    elif 'error_description' in body:
        logger.error(
            "POST /oauth/token did not return all of 'access_token, id_token, scope, expires_in, token_type'"
        )
        logger.error(body['error_description'])
        return {
            'statusCode': 400,
            'body': json.dumps({'error': body['error_description']})
        }
    else:
        logger.error(
            "POST /oauth/token did not return all of 'access_token, id_token, scope, expires_in, token_type'"
        )
        logger.error("No error message returned from Auth0")
        return {
            'statusCode': 500,
            'body': json.dumps({'error': 'Unknown Error happened'})
        }