示例#1
0
文件: db.py 项目: lucays/ProxyPool
async def crawl_proxies(app):
    proxies_count = await app['redis_client'].get_count()
    logger.info(f"now there are {proxies_count} proxies.")
    while True:
        await asyncio.sleep(3)
        with cd("../"):
            logger.info(f'now in {os.getcwd()}')
            """
            # 这两行代码在Python3.6尚未实现,需要Python3.7才能运行
            process = await asyncio.create_subprocess_exec('scrapy list', stdout=asyncio.subprocess.PIPE, stderr=asyncio.subprocess.PIPE)
            stdout, stderr = await process.communicate()
            """
            p = subprocess.run(['scrapy', 'list'],
                               stdout=subprocess.PIPE,
                               encoding='utf8')
            spiders = p.stdout.split()

            for spider in spiders:
                logger.info(spider)
                try:
                    subprocess.run(['scrapy', 'crawl', spider],
                                   timeout=60 * 10)
                except subprocess.TimeoutExpired as e:
                    logger.error(f'{spider} crawl TIMEOUT!')
                await asyncio.sleep(3)
        proxies_count = await app['redis_client'].get_count()
        await asyncio.sleep(3600 * 0.5)
示例#2
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
        })
    }
示例#3
0
    def get_domain(self):
        if self._domain_id is not None:
            return

        response = self.post_json(
            "/Domain.List", dict(login_token=self._login_token, format="json"))
        assert response['status'] == 200
        if "domains" not in response['json']:
            logger.error(u"[DNSPOD]登陆异常:" +
                         response['json']['status']['message'])
            return

        domains = response['json']['domains']
        if len(domains) < 1:
            logger.error("[DNSPOD]没有域名配置,请先在dnspod配置域名")
            return

        for domain_dict in response['json']['domains']:
            if self._config.get("config", "domain") == domain_dict['punycode']:
                self._domain_id = domain_dict['id']
示例#4
0
    def get_domain(self):
        if self._domain_id is not None:
            return

        response = self.post_json("/Domain.List", dict(
            login_token=self._login_token,
            format="json"
        ))
        assert response['status'] == 200
        if "domains" not in response['json']:
            logger.error(u"[DNSPOD]登陆异常:" + response['json']['status']['message'])
            return

        domains = response['json']['domains']
        if len(domains) < 1:
            logger.error("[DNSPOD]没有域名配置,请先在dnspod配置域名")
            return

        for domain_dict in response['json']['domains']:
            if self._config.get("config", "domain") == domain_dict['punycode']:
                self._domain_id = domain_dict['id']
示例#5
0
    def start(self):
        while self._is_alive:
            try:
                if self._domain_id is None:
                    self.get_domain()
                if len(self._record_dict) == 0:
                    self.get_record()

                ip = self.get_ip()
                logger.info("LOCAL IP ADDR:" + ip)
                if self._current_ip != ip:
                    for sub_domain, record in self._record_dict.items():
                        if ip == record['value']:
                            continue
                        if self.ddns(ip, record['id'], sub_domain):
                            self._current_ip = ip
                            logger.info("[DNSPOD]CHANGE %s DDNS IP [%s --> %s]" % (sub_domain, current_ip, ip))
                        else:
                            logger.info("[DNSPOD]REFRESH DDNS FAIL")
            except Exception as e:
                logger.error(e)
            time.sleep(30)
示例#6
0
    def start(self):
        while self._is_alive:
            try:
                if self._domain_id is None:
                    self.get_domain()
                if len(self._record_dict) == 0:
                    self.get_record()

                ip = self.get_ip()
                logger.info("LOCAL IP ADDR:" + ip)
                if self._current_ip != ip:
                    for sub_domain, record in self._record_dict.items():
                        if ip == record['value']:
                            continue
                        if self.ddns(ip, record['id'], sub_domain):
                            self._current_ip = ip
                            logger.info(
                                "[DNSPOD]CHANGE %s DDNS IP [%s --> %s]" %
                                (sub_domain, current_ip, ip))
                        else:
                            logger.info("[DNSPOD]REFRESH DDNS FAIL")
            except Exception as e:
                logger.error(e)
            time.sleep(30)
示例#7
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'})
        }
示例#8
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'
            })
        }
示例#9
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"]:
        logger.error("email is missing in JSON")
        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:
        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']

    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:
        logger.error(
            "Failure: POST %AUTH0_DOMAIN%/dbconnections/change_password")
        logger.error(body['message'])
        return {
            'statusCode': body.get('statusCode', 400),
            'body': json.dumps({'error': body['message']})
        }
    else:
        logger.error(
            "Failure: POST %AUTH0_DOMAIN%/dbconnections/change_password")
        logger.error("No error message returned from Auth0")
        return {
            'statusCode': 500,
            'body': json.dumps({'error': 'Unknown Error happened'})
        }
示例#10
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'})
        }
示例#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'})
        }