Ejemplo n.º 1
0
    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)
Ejemplo n.º 2
0
    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)
Ejemplo n.º 3
0
    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())
Ejemplo n.º 4
0
    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())
Ejemplo n.º 5
0
    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
Ejemplo n.º 6
0
    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())
Ejemplo n.º 7
0
    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())
Ejemplo n.º 9
0
    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'))
Ejemplo n.º 10
0
    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")
Ejemplo n.º 11
0
    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 :)")
Ejemplo n.º 12
0
    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())
Ejemplo n.º 13
0
    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())
Ejemplo n.º 14
0
    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())
Ejemplo n.º 15
0
    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')
Ejemplo n.º 16
0
    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')
Ejemplo n.º 17
0
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
Ejemplo n.º 18
0
    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'))
Ejemplo n.º 19
0
 def get_storage():
     if APPENGINE:
         return StorageByKeyName(CredentialsModel, self.name,
                                 'credentials')
     else:
         return get_file_storage()
Ejemplo n.º 20
0
    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())
Ejemplo n.º 21
0
    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))
Ejemplo n.º 22
0
 def get_credentials(self):
     storage = StorageByKeyName(TokenizedCredentialsModel, self.token,
                                'credentials')
     return storage.get()
Ejemplo n.º 23
0
 def test_bad_ctor(self):
     with self.assertRaises(ValueError):
         StorageByKeyName(CredentialsModel, None, None)
Ejemplo n.º 24
0
def _CreateStorage(key_name):
    return StorageByKeyName(
        model=CredentialsModel,
        key_name=key_name,  # Use user_id.
        property_name='credentials')
Ejemplo n.º 25
0
    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())
Ejemplo n.º 26
0
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