def test_has_user_id_ng(self): with self.assertRaises(ClientError): self.dynamodb.Table = MagicMock() self.dynamodb.Table.return_value.get_item.side_effect = ClientError( {'Error': { 'Code': 'xxxx' }}, 'operation_name') UserUtil.has_user_id(self.dynamodb, 'external_provider_user_id')
def test_has_user_id_ok_with_return_false(self): self.dynamodb.Table = MagicMock() self.dynamodb.Table.return_value.get_item.return_value = {'Item': {}} response = UserUtil.has_user_id( self.dynamodb, 'external_provider_user_id', ) self.assertFalse(response)
def exec_main_proc(self): yahoo = YahooUtil(client_id=os.environ['YAHOO_CLIENT_ID'], secret=os.environ['YAHOO_SECRET'], callback_url=os.environ['YAHOO_OAUTH_CALLBACK_URL']) try: yahoo.verify_state_nonce(dynamodb=self.dynamodb, state=self.params['state']) token = yahoo.get_access_token(code=self.params['code']) yahoo.verify_access_token(dynamodb=self.dynamodb, access_token=token['access_token'], id_token=token['id_token']) user_info = yahoo.get_user_info(access_token=token['access_token']) except YahooOauthError as e: if e.status_code == 401: message = json.loads(e.message) return ResponseBuilder.response( status_code=401, body={'message': message['error_description']}) logging.info(self.event) logging.fatal(e) traceback.print_exc() return ResponseBuilder.response( status_code=500, body={'message': 'Internal server error'}) except (jwt.ExpiredSignatureError, jwt.InvalidTokenError, ClientError, YahooVerifyException) as e: logging.info(self.event) logging.fatal(e) traceback.print_exc() return ResponseBuilder.response( status_code=500, body={'message': 'Internal server error'}) if UserUtil.exists_user(self.dynamodb, user_info['user_id']): try: has_user_id = UserUtil.has_user_id( dynamodb=self.dynamodb, external_provider_user_id=user_info['user_id'], ) if has_user_id is True: user_id = UserUtil.get_user_id( dynamodb=self.dynamodb, external_provider_user_id=user_info['user_id']) else: user_id = user_info['user_id'] # パスワードの取得、デコード処理追加 password = CryptoUtil.get_external_provider_password( dynamodb=self.dynamodb, user_id=user_info['user_id']) response = UserUtil.external_provider_login( cognito=self.cognito, user_pool_id=os.environ['COGNITO_USER_POOL_ID'], user_pool_app_id=os.environ['COGNITO_USER_POOL_APP_ID'], user_id=user_id, password=password, provider=os.environ['EXTERNAL_PROVIDER_LOGIN_MARK']) return ResponseBuilder.response( status_code=200, body={ 'access_token': response['AuthenticationResult']['AccessToken'], 'id_token': response['AuthenticationResult']['IdToken'], 'refresh_token': response['AuthenticationResult']['RefreshToken'], 'last_auth_user': user_id, 'has_user_id': has_user_id, 'status': 'login' }) except ClientError as e: logging.info(self.event) logging.fatal(e) traceback.print_exc() return ResponseBuilder.response( status_code=500, body={'message': 'Internal server error'}) try: backed_password = UserUtil.generate_backend_password() response = UserUtil.create_external_provider_user( cognito=self.cognito, user_pool_id=os.environ['COGNITO_USER_POOL_ID'], user_pool_app_id=os.environ['COGNITO_USER_POOL_APP_ID'], user_id=user_info['user_id'], email=user_info['email'], backed_temp_password=os. environ['EXTERNAL_PROVIDER_LOGIN_COMMON_TEMP_PASSWORD'], backed_password=backed_password, provider=os.environ['EXTERNAL_PROVIDER_LOGIN_MARK']) aes_iv = os.urandom(settings.AES_IV_BYTES) encrypted_password = CryptoUtil.encrypt_password( backed_password, aes_iv) iv = base64.b64encode(aes_iv).decode() UserUtil.add_external_provider_user_info( dynamodb=self.dynamodb, external_provider_user_id=user_info['user_id'], password=encrypted_password, iv=iv, email=user_info['email']) return ResponseBuilder.response( status_code=200, body={ 'access_token': response['AuthenticationResult']['AccessToken'], 'id_token': response['AuthenticationResult']['IdToken'], 'refresh_token': response['AuthenticationResult']['RefreshToken'], 'last_auth_user': user_info['user_id'], 'has_user_id': False, 'status': 'sign_up' }) except ClientError as e: logging.info(self.event) logging.fatal(e) traceback.print_exc() if e.response['Error']['Code'] == 'UsernameExistsException': return ResponseBuilder.response( status_code=400, body={'message': 'EmailExistsException'}) return ResponseBuilder.response( status_code=500, body={'message': 'Internal server error'})
def exec_main_proc(self): body = json.loads(self.event.get('body')) code = body['code'] client_id = os.environ['LINE_CHANNEL_ID'] client_secret = os.environ['LINE_CHANNEL_SECRET'] try: # JWTの取得 got_jwt = self.__get_line_jwt(code, client_id, client_secret, settings.LINE_REQUEST_HEADER) except LineOauthError as e: logging.info(self.event) logging.fatal(e) traceback.print_exc() return ResponseBuilder.response( status_code=e.status_code, body={'message': json.loads(e.message)}) # JWTのデコード decoded_id_token = self.__decode_jwt(got_jwt, client_secret, client_id) user_id = settings.LINE_USERNAME_PREFIX + decoded_id_token['sub'] if UserUtil.exists_user(self.dynamodb, user_id): try: external_provider_users = self.dynamodb.Table( os.environ['EXTERNAL_PROVIDER_USERS_TABLE_NAME']) external_provider_user = external_provider_users.get_item( Key={ 'external_provider_user_id': user_id }).get('Item') hash_data = external_provider_user['password'] byte_hash_data = hash_data.encode() decoded_iv = external_provider_user['iv'] iv = decoded_iv.encode() password = CryptoUtil.decrypt_password(byte_hash_data, iv) has_user_id = UserUtil.has_user_id(self.dynamodb, user_id) if external_provider_user is not None and 'user_id' in external_provider_user: user_id = external_provider_user['user_id'] response = UserUtil.external_provider_login( cognito=self.cognito, user_pool_id=os.environ['COGNITO_USER_POOL_ID'], user_pool_app_id=os.environ['COGNITO_USER_POOL_APP_ID'], user_id=user_id, password=password, provider=os.environ['EXTERNAL_PROVIDER_LOGIN_MARK']) return ResponseBuilder.response( status_code=200, body={ 'access_token': response['AuthenticationResult']['AccessToken'], 'id_token': response['AuthenticationResult']['IdToken'], 'refresh_token': response['AuthenticationResult']['RefreshToken'], 'last_auth_user': user_id, 'has_user_id': has_user_id, 'status': 'login' }) except ClientError as e: logging.info(self.event) logging.fatal(e) traceback.print_exc() return ResponseBuilder.response( status_code=500, body={'message': 'Internal server error'}) else: try: if 'email' not in decoded_id_token: return ResponseBuilder.response( status_code=400, body={'message': 'NotRegistered'}) if not decoded_id_token['email']: email = user_id + '@' + settings.FAKE_USER_EMAIL_DOMAIN else: email = decoded_id_token['email'] backed_temp_password = os.environ[ 'EXTERNAL_PROVIDER_LOGIN_COMMON_TEMP_PASSWORD'] backed_password = UserUtil.generate_password() response = UserUtil.create_external_provider_user( cognito=self.cognito, user_pool_id=os.environ['COGNITO_USER_POOL_ID'], user_pool_app_id=os.environ['COGNITO_USER_POOL_APP_ID'], user_id=user_id, email=email, backed_temp_password=backed_temp_password, backed_password=backed_password, provider=os.environ['EXTERNAL_PROVIDER_LOGIN_MARK']) aes_iv = os.urandom(settings.AES_IV_BYTES) encrypted_password = CryptoUtil.encrypt_password( backed_password, aes_iv) iv = base64.b64encode(aes_iv).decode() UserUtil.add_external_provider_user_info( dynamodb=self.dynamodb, external_provider_user_id=user_id, password=encrypted_password, iv=iv, email=email) return ResponseBuilder.response( status_code=200, body={ 'access_token': response['AuthenticationResult']['AccessToken'], 'id_token': response['AuthenticationResult']['IdToken'], 'refresh_token': response['AuthenticationResult']['RefreshToken'], 'last_auth_user': user_id, 'has_user_id': False, 'status': 'sign_up' }) except ClientError as e: logging.info(self.event) logging.fatal(e) traceback.print_exc() if e.response['Error']['Code'] == 'UsernameExistsException': return ResponseBuilder.response( status_code=400, body={'message': 'EmailExistsException'}) return ResponseBuilder.response( status_code=500, body={'message': 'Internal server error'})
def exec_main_proc(self): params = self.event body = json.loads(params.get('body')) if UserUtil.check_try_to_register_as_line_user(body['user_id']) or \ UserUtil.check_try_to_register_as_twitter_user(body['user_id']) or \ UserUtil.check_try_to_register_as_yahoo_user(body['user_id']) or \ UserUtil.check_try_to_register_as_facebook_user(body['user_id']): raise ValidationError('This username is not allowed') users_table = self.dynamodb.Table(os.environ['USERS_TABLE_NAME']) external_provider_users_table = self.dynamodb.Table( os.environ['EXTERNAL_PROVIDER_USERS_TABLE_NAME']) external_provider_user_id = params['requestContext']['authorizer'][ 'claims']['cognito:username'] exist_check_user = users_table.get_item(Key={ 'user_id': body['user_id'] }).get('Item') external_provider_user = external_provider_users_table.get_item( Key={ 'external_provider_user_id': external_provider_user_id }).get('Item') if (external_provider_user is not None) and ('user_id' in external_provider_user): raise ValidationError('The user id of this user has been added.') elif exist_check_user is None: # EXTERNAL_PROVIDERのidで作成したcognitoのユーザーを除去 if UserUtil.delete_external_provider_id_cognito_user( self.cognito, external_provider_user_id): # user_idでのCognitoユーザーの作成し直し try: email = external_provider_user['email'] hash_data = external_provider_user['password'] byte_hash_data = hash_data.encode() decoded_iv = external_provider_user['iv'] iv = decoded_iv.encode() backed_password = CryptoUtil.decrypt_password( byte_hash_data, iv) backed_temp_password = os.environ[ 'EXTERNAL_PROVIDER_LOGIN_COMMON_TEMP_PASSWORD'] provider = os.environ['EXTERNAL_PROVIDER_LOGIN_MARK'] response = UserUtil.create_external_provider_user( cognito=self.cognito, user_id=body['user_id'], user_pool_id=os.environ['COGNITO_USER_POOL_ID'], user_pool_app_id=os. environ['COGNITO_USER_POOL_APP_ID'], email=email, backed_temp_password=backed_temp_password, backed_password=backed_password, provider=provider) UserUtil.force_non_verified_phone(cognito=self.cognito, user_id=body['user_id']) UserUtil.wallet_initialization( self.cognito, os.environ['COGNITO_USER_POOL_ID'], body['user_id']) # ExternalProviderUsersテーブルにuser_idを追加 UserUtil.add_user_id_to_external_provider_user( body['user_id'], external_provider_users_table, external_provider_user_id) # Usersテーブルにユーザーを作成 UserUtil.add_user_profile( dynamodb=self.dynamodb, user_id=body['user_id'], user_display_name=body['user_id']) has_user_id = UserUtil.has_user_id( self.dynamodb, external_provider_user_id) return { 'statusCode': 200, 'body': json.dumps({ 'access_token': response['AuthenticationResult']['AccessToken'], 'last_auth_user': body['user_id'], 'id_token': response['AuthenticationResult']['IdToken'], 'refresh_token': response['AuthenticationResult']['RefreshToken'], 'status': 'login', 'has_user_id': has_user_id }) } except ClientError as e: logging.fatal(e) return { 'statusCode': 500, 'body': json.dumps({'message': 'Internal server error'}) } return { 'statusCode': 500, 'body': json.dumps({'message': 'Internal server error'}) } else: raise ValidationError('This id is already in use.')