def test_get_and_put_simple(self): storage = StorageByKeyName(CredentialsModel, 'foo', 'credentials') self.assertEqual(None, storage.get()) self.credentials.set_store(storage) self.credentials._refresh(_http_request) credmodel = CredentialsModel.get_by_key_name('foo') self.assertEqual('bar', credmodel.credentials.access_token)
def test_get_and_put_simple(self): storage = StorageByKeyName( CredentialsModel, 'foo', 'credentials') self.assertEqual(None, storage.get()) self.credentials.set_store(storage) self.credentials._refresh(_http_request) credmodel = CredentialsModel.get_by_key_name('foo') self.assertEqual('bar', credmodel.credentials.access_token)
def test_get_and_put_ndb(self): # Start empty storage = StorageByKeyName(CredentialsNDBModel, 'foo', 'credentials') self.assertEqual(None, storage.get()) # Refresh storage and retrieve without using storage self.credentials.set_store(storage) self.credentials._refresh(_http_request) credmodel = CredentialsNDBModel.get_by_id('foo') self.assertEqual('bar', credmodel.credentials.access_token) self.assertEqual(credmodel.credentials.to_json(), self.credentials.to_json())
def test_get_and_put_ndb(self): # Start empty storage = StorageByKeyName( CredentialsNDBModel, 'foo', 'credentials') self.assertEqual(None, storage.get()) # Refresh storage and retrieve without using storage self.credentials.set_store(storage) self.credentials._refresh(_http_request) credmodel = CredentialsNDBModel.get_by_id('foo') self.assertEqual('bar', credmodel.credentials.access_token) self.assertEqual(credmodel.credentials.to_json(), self.credentials.to_json())
def get_token(self): secrets_filepath = os.path.join(os.path.dirname(__file__), 'secrets/urltoken.json') with open(secrets_filepath, 'r') as fp: secrets = json.load(fp) token = hashlib.sha256(self.user_id.encode() + secrets.get('hash_seed').encode()).hexdigest() if (self.credentials.refresh_token): storage = StorageByKeyName(TokenizedCredentialsModel, token, 'credentials') storage.put(self.credentials) return token
def test_get_and_put_mixed_db_storage_ndb_get(self): # Start empty storage = StorageByKeyName(CredentialsModel, 'foo', 'credentials') self.assertEqual(None, storage.get()) # Set DB store and refresh to add to storage self.credentials.set_store(storage) self.credentials._refresh(_http_request) # Retrieve same key from NDB model to confirm mixing works credmodel = CredentialsNDBModel.get_by_id('foo') self.assertEqual('bar', credmodel.credentials.access_token) self.assertEqual(self.credentials.to_json(), credmodel.credentials.to_json())
def test_get_and_put_mixed_db_storage_ndb_get(self): # Start empty storage = StorageByKeyName( CredentialsModel, 'foo', 'credentials') self.assertEqual(None, storage.get()) # Set DB store and refresh to add to storage self.credentials.set_store(storage) self.credentials._refresh(_http_request) # Retrieve same key from NDB model to confirm mixing works credmodel = CredentialsNDBModel.get_by_id('foo') self.assertEqual('bar', credmodel.credentials.access_token) self.assertEqual(self.credentials.to_json(), credmodel.credentials.to_json())
def test__is_ndb(self): storage = StorageByKeyName( object(), 'foo', 'credentials') with self.assertRaises(TypeError): storage._is_ndb() storage._model = type(object) with self.assertRaises(TypeError): storage._is_ndb() storage._model = CredentialsModel self.assertFalse(storage._is_ndb()) storage._model = CredentialsNDBModel self.assertTrue(storage._is_ndb())
def test_get_and_put_cached(self): storage = StorageByKeyName(CredentialsModel, 'foo', 'credentials', cache=memcache) self.assertEqual(None, storage.get()) self.credentials.set_store(storage) self.credentials._refresh(_http_request) credmodel = CredentialsModel.get_by_key_name('foo') self.assertEqual('bar', credmodel.credentials.access_token) # Now remove the item from the cache. memcache.delete('foo') # Check that getting refreshes the cache. credentials = storage.get() self.assertEqual('bar', credentials.access_token) self.assertNotEqual(None, memcache.get('foo')) # Deleting should clear the cache. storage.delete() credentials = storage.get() self.assertEqual(None, credentials) self.assertEqual(None, memcache.get('foo'))
def __init__(self, user): """ Constructor de la clase. :param user: Usuario cuyas credenciales se usarán para conectar con Gmail API. :type user: str. """ from core.logger import Logger Logger.info("Initializing gmail client...") # Obtenemos las credenciales para el usuario dado. credentials = StorageByKeyName(CredentialsModel, user, "credentials").get() # Securizamos el cliente HTTP con ellas. http = credentials.authorize(httplib2.Http()) # Construimos el acceso a los recursos de Gmail API. self.resource = build("gmail", "v1", http=http) Logger.info("Gmail client initialized")
def get(self): """Handler for GET requests to the app.""" http = OAUTH_DECORATOR.http() if not self.request.get('videoId'): self.response.write( """Please supply the video ID of a YouTube live stream as a query parameter, i.e. ?videoId=xxx.""") return youtube = build('youtube', 'v3', http=http) channel = youtube.channels().list(mine=True, part='id').execute() channel_id = channel['items'][0]['id'] storage = StorageByKeyName(CredentialsModel, channel_id, 'credentials') storage.put(OAUTH_DECORATOR.credentials) video_id = self.request.get('videoId') videos = youtube.videos().list(id=video_id, part="liveStreamingDetails").execute() video = videos['items'][0] live_chat_id = video['liveStreamingDetails']['activeLiveChatId'] # See if the bot's already in the channel. in_chat = memcache.get("{}:in_chat".format(live_chat_id)) if in_chat: self.response.write( """The bot's already in that chat! Try saying .hi to it, or asking it to .leave! If the bot isn't in chat, wait 4 minutes then try adding it again""") else: taskqueue.add(url='/spawnbot', target='worker', params={ 'channel_id': channel_id, 'live_chat_id': live_chat_id }) self.response.write( "Created the bot task for live chat " + live_chat_id + " on channel " + channel_id + "! The bot should join the channel soon and say hello :)")
def test_delete_ndb(self): # Start empty storage = StorageByKeyName(CredentialsNDBModel, 'foo', 'credentials') self.assertEqual(None, storage.get()) # Add credentials to model with storage, and check equivalent # w/o storage storage.put(self.credentials) credmodel = CredentialsNDBModel.get_by_id('foo') self.assertEqual(credmodel.credentials.to_json(), self.credentials.to_json()) # Delete and make sure empty storage.delete() self.assertEqual(None, storage.get())
def test__is_ndb(self): storage = StorageByKeyName(object(), 'foo', 'credentials') self.assertRaises(TypeError, storage._is_ndb) storage._model = type(object) self.assertRaises(TypeError, storage._is_ndb) storage._model = CredentialsModel self.assertFalse(storage._is_ndb()) storage._model = CredentialsNDBModel self.assertTrue(storage._is_ndb())
def test_delete_ndb(self): # Start empty storage = StorageByKeyName( CredentialsNDBModel, 'foo', 'credentials') self.assertEqual(None, storage.get()) # Add credentials to model with storage, and check equivalent # w/o storage storage.put(self.credentials) credmodel = CredentialsNDBModel.get_by_id('foo') self.assertEqual(credmodel.credentials.to_json(), self.credentials.to_json()) # Delete and make sure empty storage.delete() self.assertEqual(None, storage.get())
def test_get_and_put_set_store_on_cache_retrieval(self): storage = StorageByKeyName(CredentialsModel, 'foo', 'credentials', cache=memcache) self.assertEqual(None, storage.get()) self.credentials.set_store(storage) storage.put(self.credentials) # Pre-bug 292 old_creds wouldn't have storage, and the _refresh # wouldn't be able to store the updated cred back into the storage. old_creds = storage.get() self.assertEqual(old_creds.access_token, 'foo') old_creds.invalid = True old_creds._refresh(_http_request) new_creds = storage.get() self.assertEqual(new_creds.access_token, 'bar')
def test_get_and_put_set_store_on_cache_retrieval(self): storage = StorageByKeyName( CredentialsModel, 'foo', 'credentials', cache=memcache) self.assertEqual(None, storage.get()) self.credentials.set_store(storage) storage.put(self.credentials) # Pre-bug 292 old_creds wouldn't have storage, and the _refresh # wouldn't be able to store the updated cred back into the storage. old_creds = storage.get() self.assertEqual(old_creds.access_token, 'foo') old_creds.invalid = True old_creds._refresh(_http_request) new_creds = storage.get() self.assertEqual(new_creds.access_token, 'bar')
def build_service_account_credentials(scope, user=None): """ Builds service account credentials using the configuration stored in :mod:`~ferris3.settings` and masquerading as the provided user. """ config = _get_config() try: from oauth2client.service_account import ServiceAccountCredentials except ImportError: ServiceAccountCredentials = None if ServiceAccountCredentials is not None and hasattr( ServiceAccountCredentials, "from_json_keyfile_dict"): # running oauth2client version 2.0 creds = ServiceAccountCredentials.from_json_keyfile_dict(config, scope) if user is not None: creds = creds.create_delegated(user) else: try: from oauth2client.client import SignedJwtAssertionCredentials except ImportError: raise EnvironmentError( "Service account can not be used because PyCrypto is not available. Please install PyCrypto." ) if not isinstance(scope, (list, tuple)): scope = [scope] creds = SignedJwtAssertionCredentials( service_account_name=config['client_email'], private_key=config['private_key'], scope=scope, prn=user) key = _generate_storage_key(config['client_email'], scope, user) storage = StorageByKeyName(ServiceAccountStorage, key, 'credentials') creds.set_store(storage) return creds
def test_get_and_put_cached(self): storage = StorageByKeyName( CredentialsModel, 'foo', 'credentials', cache=memcache) self.assertEqual(None, storage.get()) self.credentials.set_store(storage) self.credentials._refresh(_http_request) credmodel = CredentialsModel.get_by_key_name('foo') self.assertEqual('bar', credmodel.credentials.access_token) # Now remove the item from the cache. memcache.delete('foo') # Check that getting refreshes the cache. credentials = storage.get() self.assertEqual('bar', credentials.access_token) self.assertNotEqual(None, memcache.get('foo')) # Deleting should clear the cache. storage.delete() credentials = storage.get() self.assertEqual(None, credentials) self.assertEqual(None, memcache.get('foo'))
def get_storage(): if APPENGINE: return StorageByKeyName(CredentialsModel, self.name, 'credentials') else: return get_file_storage()
def test_delete_db_ndb_mixed(self): # Start empty storage_ndb = StorageByKeyName(CredentialsNDBModel, 'foo', 'credentials') storage = StorageByKeyName(CredentialsModel, 'foo', 'credentials') # First DB, then NDB self.assertEqual(None, storage.get()) storage.put(self.credentials) self.assertNotEqual(None, storage.get()) storage_ndb.delete() self.assertEqual(None, storage.get()) # First NDB, then DB self.assertEqual(None, storage_ndb.get()) storage_ndb.put(self.credentials) storage.delete() self.assertNotEqual(None, storage_ndb.get()) # NDB uses memcache and an instance cache (Context) ndb.get_context().clear_cache() memcache.flush_all() self.assertEqual(None, storage_ndb.get())
def post(self): """Entry point for the worker.""" # channel_id refers to the channel that the bot is using # video_id refers to the live stream we want to chat in channel_id = self.request.get("channel_id") live_chat_id = self.request.get("live_chat_id") storage = StorageByKeyName(CredentialsModel, channel_id, 'credentials') credential = storage.get() http = credential.authorize(httplib2.Http()) youtube = build('youtube', 'v3', http=http) in_chat = memcache.get("{}:in_chat".format(live_chat_id)) if in_chat is None: say("Hello, I've joined the chat!", live_chat_id, youtube) next_page = memcache.get("{}:nextpage".format(live_chat_id)) # This is our loop control. If we want the bot to gracefully exit, # we can just set this to false. remain_in_channel = True try: while remain_in_channel: memcache.set("{}:in_chat".format(live_chat_id), True, MEMCACHE_CHAT_PING_EXPIRY_TIME) messages = youtube.liveChatMessages().list(liveChatId=live_chat_id, part="id,snippet,authorDetails", pageToken=next_page).execute() if messages is None: break for message in messages['items']: message_id = message['id'] message_type = message['snippet']['type'] # Keep track of every message we process, so we # don't accidentally do it more than once. already_processed = memcache.get("{}:processed".format(message_id)) if already_processed: continue else: memcache.set("{}:processed".format(message_id), True) # Here, we're doing the real work of the bot. # Check the message type and respond appropriately. # Message types are documented here: # https://developers.google.com/youtube/v3/live/docs/liveChatMessages#snippet.type # Before we proceed, let's pull out the author details, so we can # personalize our response and do some basic permission checking. author_channel_name = message['authorDetails']['displayName'] author_is_moderator = message['authorDetails']['isChatModerator'] author_is_owner = message['authorDetails']['isChatOwner'] if message_type == "textMessageEvent": message_text = message['snippet']['textMessageDetails']['messageText'] if message_text == ".hi": say("Well hello there, {}!".format(author_channel_name), live_chat_id, youtube) elif message_text == ".leave": # We only want moderators or the channel owner to be able to # tell the bot to leave. Let's ensure that's the case. if author_is_moderator or author_is_owner: say("Okay {}, I'm leaving the channel!".format(author_channel_name), live_chat_id, youtube) remain_in_channel = False elif type == "chatEndedEvent": remain_in_channel = False break next_page = messages['nextPageToken'] memcache.set("{}:nextpage".format(live_chat_id), next_page) time.sleep(messages['pollingIntervalMillis']/1000) except DeadlineExceededError: # App Engine is terminating our task, so we need to re-queue it. # Tasks in Task Queues have deadlines. To learn more: # https://cloud.google.com/appengine/docs/standard/python/taskqueue/push/creating-handlers if remain_in_channel: taskqueue.add(url='/spawnbot', target='worker', params= {'channel_id':channel_id, 'live_chat_id':live_chat_id}) else: # TODO: Don't duplicate the cleanup code. memcache.delete("{}:nextpage".format(live_chat_id)) memcache.delete("{}:in_chat".format(live_chat_id)) return memcache.delete("{}:nextpage".format(live_chat_id)) memcache.delete("{}:in_chat".format(live_chat_id))
def get_credentials(self): storage = StorageByKeyName(TokenizedCredentialsModel, self.token, 'credentials') return storage.get()
def test_bad_ctor(self): with self.assertRaises(ValueError): StorageByKeyName(CredentialsModel, None, None)
def _CreateStorage(key_name): return StorageByKeyName( model=CredentialsModel, key_name=key_name, # Use user_id. property_name='credentials')
def test_delete_db_ndb_mixed(self): # Start empty storage_ndb = StorageByKeyName( CredentialsNDBModel, 'foo', 'credentials') storage = StorageByKeyName( CredentialsModel, 'foo', 'credentials') # First DB, then NDB self.assertEqual(None, storage.get()) storage.put(self.credentials) self.assertNotEqual(None, storage.get()) storage_ndb.delete() self.assertEqual(None, storage.get()) # First NDB, then DB self.assertEqual(None, storage_ndb.get()) storage_ndb.put(self.credentials) storage.delete() self.assertNotEqual(None, storage_ndb.get()) # NDB uses memcache and an instance cache (Context) ndb.get_context().clear_cache() memcache.flush_all() self.assertEqual(None, storage_ndb.get())
from google.appengine.api import users from oauth2client.contrib.appengine import StorageByKeyName user = users.get_current_user() storage = StorageByKeyName(CredentialsModel, user.user_id(), 'credentials') credentials = storage.get() # hi dewdadssddsaad