예제 #1
0
def modify_purchase_order(event, context):
    """
    Modify purchase order
    """
    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'})
        }

    try:
        item = context.repo.save_purchase_order(body)

        return {'statusCode': 200, 'body': json.dumps(item)}
    except BadParameters:
        return {
            'statusCode': 400,
            'body':
            json.dumps({'error': 'Bad request. The request was Malformed'})
        }
    except MissingRequiredKey as ex:
        return {
            'statusCode':
            400,
            'body':
            json.dumps({
                'error':
                'Bad request. Missing required key-val pair {KEY}'.format(
                    KEY=str(ex))
            })
        }
예제 #2
0
def add_adjustment(event, context):
    """
    Add adjustment inventory record
    """
    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'})
        }

    body["supplier_id"] = context.supplier_id

    try:
        body = context.repo.save_adjustment(body)
        return {'statusCode': 200, 'body': json.dumps(body)}
    except BadParameters as ex:
        key = str(ex)
        if key:
            return {
                'statusCode':
                400,
                'body':
                json.dumps({
                    'error':
                    'Bad request. The request was Malformed. Wrong type for key-val pair {KEY}'
                    .format(KEY=key)
                })
            }
        else:
            return {
                'statusCode':
                400,
                'body':
                json.dumps({'error': 'Bad request. The request was Malformed'})
            }
    except NoSuchEntity as ex:
        return {
            'statusCode':
            404,
            'body':
            json.dumps({
                'error':
                '{RESOURCE} Resource not found'.format(RESOURCE=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))
            })
        }
예제 #3
0
def add_count(event, context):
    """
    Add count inventory record
    """
    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'})
        }

    body["supplier_id"] = context.supplier_id

    try:
        body = context.repo.save_count(body)
        return {'statusCode': 200, 'body': json.dumps(body)}
    except BadParameters:
        return {
            'statusCode': 400,
            'body':
            json.dumps({'error': 'Bad request. The request was Malformed'})
        }
    except NoSuchEntity as ex:
        return {
            'statusCode':
            404,
            'body':
            json.dumps({
                'error':
                '{RESOURCE} Resource not found'.format(RESOURCE=str(ex))
            })
        }
예제 #4
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)}
예제 #5
0
def get_inventory_csv(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'})
        }

    try:
        inventory_csv_string = inventory_csv.generate(body)

        return {
            'statusCode': 200,
            'body': inventory_csv_string,
            'isBase64Encoded': True
        }
    except AuroraSqlExecuteFailed:
        return {
            'statusCode': 500,
            'body':
            json.dumps({'error': 'Internal Error. SQL Execution failed'})
        }
예제 #6
0
def modify_retail_package(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

    try:
        item = context.repo.save_retail_package(body)

        return {'statusCode': 200, 'body': json.dumps(item)}
    except BadParameters as ex:
        key = str(ex)
        if key:
            return {
                'statusCode':
                400,
                'body':
                json.dumps({
                    'error':
                    'Bad request. The request was Malformed. Wrong type for key-val pair {KEY}'
                    .format(KEY=key)
                })
            }
        else:
            return {
                'statusCode':
                400,
                'body':
                json.dumps({'error': 'Bad request. The request was Malformed'})
            }
    except MissingRequiredKey as ex:
        return {
            'statusCode':
            400,
            'body':
            json.dumps({
                'error':
                'Bad request. Missing required key-val pair {KEY}'.format(
                    KEY=str(ex))
            })
        }
예제 #7
0
def modify_brand(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

    try:
        item = context.repo.save_brand(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 UnsupportedMediaType:
        return {
            'statusCode': 415,
            'body': json.dumps({
                'error': 'Unsupported media type. Error with logo PNG. Unable to decode base64-PNG'
            })
        }
    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 brand with the same name already exists'
            })
        }
예제 #8
0
def social_auth(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 'connection' not in body or not body['connection'] or 'redirect_uri' not in body or not body['redirect_uri']:
        return {
            'statusCode': 400,
            'body': json.dumps({
                'error': 'Missing required key-value pair(s) in request body'
            })
        }

    connection = body['connection']
    redirect_uri = body['redirect_uri']

    # token access right limited openid, profile, email
    query = (('client_id', os.environ['AUTH0_CLIENT_ID']),
             ('response_type', 'code'),
             ('connection', connection),
             ('scope', 'openid profile email'),
             ('redirect_uri', redirect_uri),
             ('state', 'xyzABC123'))

    return_url = os.environ['AUTH0_DOMAIN'] + '/authorize?' + urlencode(query).replace('+', '%20')
    return {
        'statusCode': 200,
        'body': json.dumps({
            'return_url': return_url
        })
    }
예제 #9
0
def add_user_to_supplier(event, context):
    """
    Add a new/existing user to 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'})
        }
    except:
        logger.log_uncaught_exception()

    try:
        body = context.repo.upsert_user_in_supplier(context.supplier_id, body)
        return {'statusCode': 204, 'body': json.dumps(body)}
    except BadParameters:
        return {
            'statusCode': 400,
            'body':
            json.dumps({'error': 'Bad request. The request was Malformed'})
        }
    except Auth0AccessDenied:
        return {
            'statusCode':
            500,
            'body':
            json.dumps({
                'error':
                "Unable to update Auth0. App doesn't have right scopes"
            })
        }
    except Auth0UnknownError as ex:
        return {
            'statusCode':
            500,
            'body':
            json.dumps({'error': "Auth0 Error: {ERROR}".format(ERROR=str(ex))})
        }
    except Auth0UnableToAccess:
        return {
            'statusCode': 500,
            'body': json.dumps({'error': "Couldn't access Auth0"})
        }
    except NotAnAdminUser:
        return {
            'statusCode': 403,
            'body': json.dumps({'error': "Forbidden. Admins only"})
        }
    except:
        logger.log_uncaught_exception()
예제 #10
0
def add_merchandise(event, context):
    """
    Add a new merchandise
    """
    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'})
        }
    except:
        logger.log_uncaught_exception()

    body["supplier_id"] = context.supplier_id

    try:
        body = context.repo.save_merchandise(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 merchandise with the same name already exists'})
        }
    except:
        logger.log_uncaught_exception()
예제 #11
0
def add_production(event, context):
    """
    Add a new product
    """
    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'})
        }

    body["supplier_id"] = context.supplier_id

    try:
        body = context.repo.save_production(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':
                'The request could not be completed due to a conflict with the current state of the resource. '
                'This error could be because, a supplier with the same name already exists'
            })
        }
예제 #12
0
def modify_count(event, context):
    """
    Modify count record
    """
    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

    try:
        item = context.repo.save_count(body)

        return {'statusCode': 200, 'body': json.dumps(item)}
    except BadParameters:
        return {
            'statusCode': 400,
            'body':
            json.dumps({'error': 'Bad request. The request was Malformed'})
        }
    except NoSuchEntity as ex:
        return {
            'statusCode':
            404,
            'body':
            json.dumps({
                'error':
                '{RESOURCE} Resource not found'.format(RESOURCE=str(ex))
            })
        }
예제 #13
0
def add_supplier_distributor(event, context):
    """
    Add a new supplier_distributor
    """
    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'
            })
        }

    body["supplier_id"] = context.supplier_id
    body['allow_ordering'] = False
    body['access_code'] = 'access-disabled'

    try:
        body = context.repo.save_supplier_distributor(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 supplier_distributor with the same name already exists'
            })
        }
예제 #14
0
def update_profile(event, context):
    """
    Update user profile
    """
    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'})
        }
    except:
        logger.log_uncaught_exception()

    body['user_id'] = context.user_id

    try:
        item = context.repo.update_profile(body)
        return {'statusCode': 200, 'body': json.dumps(item)}
    except NoSuchEntity:
        return {
            'statusCode': 404,
            'body': json.dumps({'error': 'User not found'})
        }
    except BadParameters as ex:
        msg = str(ex)
        if msg:
            return {'statusCode': 400, 'body': json.dumps({'error': msg})}
        return {
            'statusCode':
            400,
            'body':
            json.dumps({'error': 'Bad request. '
                        'The request was Malformed'})
        }
    except CannotModifyEntityStates:
        return {
            'statusCode': 409,
            'body': json.dumps({'error': 'Update of the entity failed'})
        }
    except:
        logger.log_uncaught_exception()
예제 #15
0
def password_reset(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 "email" not in body or not body["email"]:
        return {
            'statusCode':
            400,
            'body':
            json.dumps({
                'error':
                'Missing required key-value pair(s) in request body'
            })
        }

    email = body["email"]

    # 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':
                             'update: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']

    resp = requests.post(os.environ['AUTH0_DOMAIN'] +
                         "/dbconnections/change_password",
                         json={
                             'email':
                             email,
                             'client_id':
                             os.environ['AUTH0_MANAGEMENT_API_CLIENT_ID'],
                             'connection':
                             os.environ['AUTH0_CONNECTION'],
                         },
                         headers={
                             'Authorization':
                             'Bearer {TOKEN}'.format(TOKEN=access_token),
                             'content-type':
                             "application/json"
                         })

    if resp.status_code == 200:
        return {'statusCode': 204}
    elif resp.status_code != 200 and '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'})
        }
예제 #16
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'})
        }
예제 #17
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'})
        }
예제 #18
0
def modify_supplier(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 "entity_id" in body and body["entity_id"] != context.supplier_id:
        return {
            'statusCode':
            400,
            'body':
            json.dumps({
                'error':
                'Bad parameter(s) in request. entity_id in body must match x-supplier-id'
            })
        }

    body["entity_id"] = context.supplier_id

    try:
        item = context.repo.save_supplier(body)

        return {'statusCode': 200, 'body': json.dumps(item)}
    except BadParameters as ex:
        key = str(ex)
        if key:
            return {
                'statusCode':
                400,
                'body':
                json.dumps({
                    'error':
                    'Bad request. The request was Malformed. Wrong type for key-val pair {KEY}'
                    .format(KEY=key)
                })
            }
        else:
            return {
                'statusCode':
                400,
                'body':
                json.dumps({'error': 'Bad request. The request was Malformed'})
            }
    except MissingRequiredKey as ex:
        return {
            'statusCode':
            400,
            'body':
            json.dumps({
                'error':
                'Bad request. Missing required key-val pair {KEY}'.format(
                    KEY=str(ex))
            })
        }
    except CannotUpdateUsers:
        return {
            'statusCode':
            400,
            'body':
            json.dumps({
                'error':
                'users property cannot be updated through this endpoint'
            })
        }
    except UnknownMainContact:
        return {
            'statusCode': 403,
            'body': json.dumps({'error': 'Forbidden. Unknown Main Contact'})
        }
    except NoSuchEntity:
        return {
            'statusCode': 404,
            'body': json.dumps({'error': 'Resource not found'})
        }
    except UnsupportedMediaType:
        return {
            'statusCode':
            415,
            'body':
            json.dumps({
                'error':
                'Unsupported media type. Error with logo PNG. Unable to decode base64-PNG'
            })
        }
    except NotAnAdminUser:
        return {
            'statusCode': 403,
            'body': json.dumps({'error': "Forbidden. Admins only"})
        }
예제 #19
0
def add_supplier(event, context):
    """
    Add a new supplier for user
    """
    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'})
        }

    try:
        body = context.repo.save_supplier(body)
        return {'statusCode': 200, 'body': json.dumps(body)}
    except BadParameters as ex:
        key = str(ex)
        if key:
            return {
                'statusCode':
                400,
                'body':
                json.dumps({
                    'error':
                    'Bad request. Wrong type of data for {KEY}'.format(KEY=key)
                })
            }
        else:
            return {
                'statusCode':
                400,
                'body':
                json.dumps({'error': 'Bad request. The request was Malformed'})
            }
    except CannotUpdateUsers:
        return {
            'statusCode':
            400,
            'body':
            json.dumps({
                'error':
                'users property cannot be updated through this endpoint'
            })
        }
    except UnsupportedMediaType:
        return {
            'statusCode':
            415,
            'body':
            json.dumps({
                'error':
                'Unsupported media type. Error with logo PNG. Unable to decode base64-PNG'
            })
        }
    except MissingRequiredKey as ex:
        return {
            'statusCode':
            400,
            'body':
            json.dumps({
                'error':
                'Bad request. Missing required key-val pair {KEY}'.format(
                    KEY=str(ex))
            })
        }
    except Auth0AccessDenied:
        return {
            'statusCode':
            500,
            'body':
            json.dumps({
                'error':
                "Unable to update Auth0. App doesn't have right scopes"
            })
        }
    except Auth0UnableToAccess:
        return {
            'statusCode': 500,
            'body': json.dumps({'error': "Couldn't access Auth0"})
        }
    except CannotModifyEntityStates:
        return {
            'statusCode':
            409,
            'body':
            json.dumps({
                'error':
                'The request could not be completed due to a conflict with the current state of the resource. '
            })
        }
예제 #20
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'
            })
        }
예제 #21
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'
            })
        }
예제 #22
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'})
        }
예제 #23
0
def modify_distributor_supplier(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'})
        }
    except:
        logger.log_uncaught_exception()

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

    body["distributor_id"] = context.distributor_id

    try:
        item = context.repo.save_distributor_supplier(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 distributor_supplier with the same name already exists'
            })
        }
    except:
        logger.log_uncaught_exception()
예제 #24
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'
            })
        }
예제 #25
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'})
        }
    except:
        logger.log_uncaught_exception()

    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:
        supplier_distributor_obj = context.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'})
        }
    except:
        logger.log_uncaught_exception()

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

    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'
            })
        }
    except:
        logger.log_uncaught_exception()
예제 #26
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'})
        }