Example #1
0
    def attachments_delete(self, request):
        """Retrieve metainfo for a single attachments for a timeline card"""

        current_user = endpoints.get_current_user()
        if current_user is None:
            raise endpoints.UnauthorizedException("Authentication required.")

        card = ndb.Key("TimelineItem", request.itemId).get()

        if card is None or card.user != current_user:
            raise endpoints.NotFoundException("Attachment not found.")

        if card.attachments is not None:
            for att in card.attachments:
                if att.id == request.attachmentId:
                    # Delete attachment from blobstore
                    blobkey = blobstore.BlobKey(request.attachmentId)
                    blobstore.delete(blobkey)

                    # Remove attachment from timeline card
                    card.attachments.remove(att)
                    card.put()

                    return AttachmentResponse(id=att.id)

        raise endpoints.NotFoundException("Attachment not found.")
Example #2
0
def ValidateUserIsAuthorized():
    """Raises endpoints.UnauthorizedException if the caller is not signed in
    or is not allowed to publish content.
    """
    user = endpoints.get_current_user()
    if user is None or user.email() not in CONTENT_DEVELOPERS:
        raise endpoints.UnauthorizedException()
 def get_task_lists_for_user(self, request):
     """ Returns all the TaskLists for the logged in user. """
     current_user = endpoints.get_current_user()
     if current_user is None:
         raise endpoints.UnauthorizedException('Invalid token.')
     current_users_task_user = TaskUser.get_task_user_by_email(current_user.email().lower())
     users_task_lists = []
     for a_task_list_key in current_users_task_user.task_list_keys:
         a_task_list = a_task_list_key.get()
         all_tasks_in_list = []
         for a_task_key in a_task_list.task_keys:
             a_task = a_task_key.get()
             assigned_to_task_user_msg = None
             if a_task.assigned_to_email:
                 assigned_to_task_user = TaskUser.get_task_user_by_email(a_task.assigned_to_email)
                 assigned_to_task_user_msg = TaskUserResponseMessage(lowercase_email=assigned_to_task_user.lowercase_email, preferred_name=assigned_to_task_user.preferred_name, google_plus_id=assigned_to_task_user.google_plus_id)
             all_tasks_in_list.append(TaskResponseMessage(identifier=a_task.key.id(),
                                                          text=a_task.text,
                                                          details=a_task.details,
                                                          complete=a_task.complete,
                                                          assigned_to=assigned_to_task_user_msg))
         all_task_users_in_list = []
         for a_task_user_email in a_task_list.task_user_emails:
             a_task_user = TaskUser.get_task_user_by_email(a_task_user_email)
             all_task_users_in_list.append(TaskUserResponseMessage(lowercase_email=a_task_user.lowercase_email, preferred_name=a_task_user.preferred_name, google_plus_id=a_task_user.google_plus_id))
         users_task_lists.append(TaskListResponseMessage(identifier=a_task_list.key.id(), title=a_task_list.title, tasks=all_tasks_in_list, task_users=all_task_users_in_list))
     logging.info("Returning a list of TaskList, count = " + str(len(users_task_lists)))
     return TaskListListResponse(items=users_task_lists)
Example #4
0
    def timeline_get(self, card):
        """Get card with ID for the current user"""

        if not card.from_datastore or card.user != endpoints.get_current_user():
            raise endpoints.NotFoundException("Card not found.")

        return card
Example #5
0
    def timeline_list(self, query):
        """List timeline cards for the current user."""

        query = query.order(-TimelineItem.updated)
        query = query.filter(TimelineItem.user == endpoints.get_current_user())
        query = query.filter(TimelineItem.isDeleted == False)
        return query
Example #6
0
    def locations_insert(self, location):
        """Insert a new location for the current user.

        Not part of the actual mirror API but used by the emulator.
        """

        if location.id is not None:
            raise endpoints.BadRequestException("ID is not allowed in request body.")

        location.put()

        # Notify location subscriptions

        data = {}
        data["collection"] = "locations"
        data["itemId"] = "latest"
        operation = Operation.UPDATE
        data["operation"] = operation.name

        header = {"Content-type": "application/json"}

        query = Subscription.query().filter(Subscription.user == endpoints.get_current_user())
        query = query.filter(Subscription.collection == "locations")
        query = query.filter(Subscription.operation == operation)
        for subscription in query.fetch():
            data["userToken"] = subscription.userToken
            data["verifyToken"] = subscription.verifyToken

            req = urllib2.Request(subscription.callbackUrl, json.dumps(data), header)
            try:
                urllib2.urlopen(req)
            except:
                logging.error(sys.exc_info()[0])

        return location
def _get_user_id_from_id_token(jwt):
  """Attempts to get Google+ User ID from ID Token.

  First calls endpoints.get_current_user() to assure there is a valid user.
  If it has already been called, there will be environment variables set
  so this will be a low-cost call (no network overhead).

  After this, we know the JWT is valid and can simply parse a value from it.

  Args:
    jwt: String, containing the JSON web token which acts as the ID Token.

  Returns:
    String containing the Google+ user ID or None if it can't be determined
      from the JWT.
  """
  if endpoints.get_current_user() is None:
    return

  segments = jwt.split('.')
  if len(segments) != 3:
    return

  json_body = users_id_token._urlsafe_b64decode(segments[1])
  try:
    parsed = json.loads(json_body)
    return parsed.get('sub')
  except:
    pass
Example #8
0
    def contacts_get(self, contact):
        """Get contact with ID for the current user"""

        if not contact.from_datastore or contact.user != endpoints.get_current_user():
            raise endpoints.NotFoundException("Contact not found.")

        return contact
def get_google_plus_user_id():
  """Method to get the Google+ User ID from the environment.

  Attempts to get the user ID if the token in the environment is either
  an ID token or a bearer token. If there is no token in the environment
  or there the current token is invalid (no current endpoints user), will not
  attempt either.

  Returns:
    The Google+ User ID of the user whose token is in the environment if it can
      be retrieved, else None.
  """
  # Assumes endpoints.get_current_user has already returned a
  # non-null value, hence the needed environment variables
  # should already be set and this won't make the RPC/urlfetch
  # a second time.
  if endpoints.get_current_user() is None:
    return

  token = users_id_token._get_token(None)
  if token is None:
    return

  user_id = _get_user_id_from_id_token(token)
  if user_id is None:
    user_id = _get_user_id_from_bearer_token(token)
  return user_id
def _get_user_id_from_bearer_token(token):
  """Attempts to get Google+ User ID from Bearer Token.

  First calls endpoints.get_current_user() to assure there is a valid user.
  If it has already been called, there will be environment variables set
  so this will be a low-cost call (no network overhead).

  Since we have already called endpoints.get_current_user, if the token is a
  valid Bearer token, a call to the TOKENINFO url must have been made hence a
  URLFetch response object corresponding to the token should be in
  _SAVED_TOKEN_DICT.

  Args:
    token: String, containing a Bearer Token.

  Returns:
    String containing the Google+ user ID or None if it can't be determined
      from the token.
  """
  if endpoints.get_current_user() is None:
    return

  urlfetch_result = _SAVED_TOKEN_DICT.get(token)
  if urlfetch_result is None:
    return

  if urlfetch_result.status_code == 200:
    try:
      user_info = json.loads(urlfetch_result.content)
      return user_info.get('user_id')
    except:
      pass
  def RequirePicturesqueUser(cls):
    """Makes sure the user from the environment has a Picturesque account.

    Checks first that there is a valid endpoints user, then checks if the
    current token can allow access to the user's Google+ ID and finally
    checks that a corresponding PicturesqueUser for that Google+ ID exists.

    Returns:
      The PicturesqueUser entity corresponding to the token user from the
        environment.

    Raises:
      endpoints.UnauthorizedException: If there is no endpoints current user.
        This results in a 401 response.
      endpoints.ForbiddenException: If either the token can't access the Google+
        ID or no Picturesque account exists for the user. This results in a 403
        response.
    """
    current_user = endpoints.get_current_user()
    if current_user is None:
      raise endpoints.UnauthorizedException(cls.INVALID_TOKEN)

    googleplus_user_id = auth_util.get_google_plus_user_id()
    if googleplus_user_id is None:
      raise endpoints.ForbiddenException(cls.NO_GPLUS_ID)

    existing_picturesque_user = cls.get_by_id(googleplus_user_id)
    if existing_picturesque_user is None:
      raise endpoints.ForbiddenException(cls.NO_ACCOUNT)

    return existing_picturesque_user
Example #12
0
    def contacts_update(self, contact):
        """Update Contact with ID for the current user"""

        if not contact.from_datastore or contact.user != endpoints.get_current_user():
            raise endpoints.NotFoundException("Card not found.")

        contact.put()
        return contact
Example #13
0
    def shareEntities_list(self, query):
        """List all Share entities registered for the current user.

        This isn't part of the actual Mirror API but necessary for the emulator part
        to be able to display relevant Share options.
        """

        return query.filter(ShareEntity.user == endpoints.get_current_user())
Example #14
0
 def start(self, request):
     ValidateUserIsAuthorized()
     change = publish.start_change(
         request.project_prefixes,
         request.upload_paths,
         endpoints.get_current_user())
     response = StartResponse(change_id=change.get_change_id())
     return response
  def ScoresGet(self, score):
    if not score.from_datastore:
      raise endpoints.NotFoundException('Score not found.')

    if score.player != endpoints.get_current_user():
      raise endpoints.ForbiddenException(
          'You do not have access to this score.')

    return score
Example #16
0
    def contacts_delete(self, contact):
        """Remove an existing Contact for the current user."""

        if not contact.from_datastore or contact.user != endpoints.get_current_user():
            raise endpoints.NotFoundException("Contact not found.")

        contact.key.delete()

        return contact
Example #17
0
    def subscription_delete(self, subscription):
        """Remove an existing subscription for the current user."""

        if not subscription.from_datastore or subscription.user != endpoints.get_current_user():
            raise endpoints.NotFoundException("Card not found.")

        subscription.key.delete()

        return subscription
Example #18
0
    def subscription_delete(self, subscription):
        """Remove an existing subscription for the current user."""

        if not subscription.from_datastore or subscription.user != endpoints.get_current_user():
            raise endpoints.NotFoundException("Card not found.")

        subscription.key.delete()

        # TODO: Check if a success HTTP code can be returned with an empty body
        return subscription
Example #19
0
    def contacts_delete(self, contact):
        """Remove an existing Contact for the current user."""

        if not contact.from_datastore or contact.user != endpoints.get_current_user():
            raise endpoints.NotFoundException("Contact not found.")

        contact.key.delete()

        # TODO: Check if a success HTTP code can be returned with an empty body
        return contact
Example #20
0
    def shareEntities_delete(self, shareEntity):
        """Remove an existing ShareEntity for the current user."""

        if not shareEntity.from_datastore or shareEntity.user != endpoints.get_current_user():
            raise endpoints.NotFoundException("shareEntity not found.")

        shareEntity.key.delete()

        # TODO: Check if a success HTTP code can be returned with an empty body
        return shareEntity
Example #21
0
    def locations_get(self, location):
        """Retrieve a single location for the current user.

        ID can be a specific location ID or "latest" to retrieve the
        latest known position of the user.
        """

        if not location.from_datastore or location.user != endpoints.get_current_user():
            raise endpoints.NotFoundException("Location not found.")

        return location
Example #22
0
 def MyModelInsert(self, my_model):
   # Since user_required is True, we know endpoints.get_current_user will
   # return a valid user.
   my_model.owner = endpoints.get_current_user()
   # Also note, since we don't override the default ProtoRPC message schema,
   # API users can send an owner object in the request, but we overwrite the
   # model property with the current user before the entity is inserted into
   # the datastore and this put operation will only occur if a valid token
   # identifying the user was sent in the Authorization header.
   my_model.put()
   return my_model
Example #23
0
    def timeline_list(self, query):
        """List timeline cards for the current user.

        Args:
            query: An ndb Query object for Cards.

        Returns:
            An update ndb Query object for the current user.
        """
        query = query.order(-Card.when)
        return query.filter(Card.user == endpoints.get_current_user())
Example #24
0
    def timeline_update(self, card):
        """Update card with ID for the current user"""

        if not card.from_datastore or card.user != endpoints.get_current_user():
            raise endpoints.NotFoundException("Card not found.")

        card.put()

        channel.send_message(card.user.email(), json.dumps({"id": card.id}))

        return card
 def task_list_insert(self, a_task_list):
     """ Insert a TaskList. """
     #TODO: Check if current user is in this TaskList
     a_task_list.creator = endpoints.get_current_user()
     current_user_email = endpoints.get_current_user().email().lower()
     if not current_user_email in a_task_list.task_user_emails:
         a_task_list.task_user_emails.append(current_user_email)
     # Consider: Check the email list for duplicates and remove them.
     if a_task_list.from_datastore:
         #logging.info("This is an update not a new TaskList")
         if not a_task_list.task_user_emails is None:
             TaskList.flush_task_users(a_task_list.id, a_task_list.task_user_emails)
     else:
         a_task_list.put() # Generate a key because it'll be needed for next steps.
     if not a_task_list.task_user_emails is None:
         for an_email in a_task_list.task_user_emails:
             #logging.info("Adding " + an_email.lower() + " to the TaskList")
             TaskUser.add_task_list(a_task_list.key, an_email)
     a_task_list.put()
     return a_task_list
Example #26
0
    def timeline_get(self, card):
        """Get card with ID for the current user

        Args:
            card: An instance of Card parsed from the API request.

        Returns:
            An instance of Card requested.
        """
        if not card.from_datastore or card.user != endpoints.get_current_user():
            raise endpoints.NotFoundException('Card not found.')
        return card
 def task_insert(self, a_task):
     """ Insert a Task. """
     #TODO: Check if current user is in this TaskList
     a_task.creator = endpoints.get_current_user()
     parent_task_list = TaskList.get_by_id(a_task.task_list_id)
     a_task.anestor = parent_task_list
     if a_task.assigned_to_email and not a_task.assigned_to_email.lower() in parent_task_list.task_user_emails:
         logging.info("Attempt to assign user that is not in the TaskList. " + a_task.assigned_to_email.lower() + " not found.")
         a_task.assigned_to_email = None
     a_task.put()
     if not a_task.key in parent_task_list.task_keys:
         parent_task_list.task_keys.append(a_task.key)
         parent_task_list.put()
     return a_task
Example #28
0
def get_endpoints_current_user(raise_unauthorized=True):
    """Returns a current user and (optionally) causes an HTTP 401 if no user.
    Args:
        raise_unauthorized: Boolean; defaults to True. If True, this method
            raises an exception which causes an HTTP 401 Unauthorized to be
            returned with the request.
    Returns:
        The signed in user if there is one, else None if there is no signed in
        user and raise_unauthorized is False.
    """
    current_user = endpoints.get_current_user()
    if raise_unauthorized and current_user is None:
        raise endpoints.UnauthorizedException('Invalid token.')
    return current_user
 def task_user_insert(self, a_task_user):
     """ Insert a TaskUser. """
     request_email = a_task_user.lowercase_email.lower()
     current_user_email = endpoints.get_current_user().email().lower()
     if current_user_email != request_email:
         logging.info('Current user email = ' + current_user_email + '  TaskUser email = ' + request_email)            
         #Allow odd creations for testing.  Turn off later as you should only edit yourself.
         raise endpoints.ForbiddenException("Only can only edit/create your own TaskUser.")
     the_task_user = TaskUser.get_task_user_by_email(request_email)
     if not a_task_user.preferred_name is None:
         the_task_user.preferred_name = a_task_user.preferred_name
     if not a_task_user.google_plus_id is None:
         the_task_user.google_plus_id = a_task_user.google_plus_id
     the_task_user.put()
     return the_task_user
Example #30
0
  def _set_value(self, entity, value):
    """Internal helper to set value on model entity.

    If the value to be set is null, will try to retrieve the current user and
    will return a 401 if a user can't be found and raise_unauthorized is True.

    Args:
      entity: An instance of some NDB model.
      value: The value of this property to be set on the instance.
    """
    if value is None:
      value = endpoints.get_current_user()
      if self._raise_unauthorized and value is None:
        raise endpoints.UnauthorizedException('Invalid token.')
    super(EndpointsUserProperty, self)._set_value(entity, value)
Example #31
0
    def action_insert(self, action):
        """Perform an action on a timeline card for the current user.

        This isn't part of the actual Mirror API but necessary for the emulator
        to send actions to the subscribed services.

        Returns just a simple success message
        """

        current_user = endpoints.get_current_user()
        if current_user is None:
            raise endpoints.UnauthorizedException("Authentication required.")

        card = ndb.Key("TimelineItem", action.itemId).get()
        if card is None or card.user != current_user:
            raise endpoints.NotFoundException("Card not found.")

        data = None
        operation = None

        if action.action == MenuAction.SHARE:
            operation = Operation.UPDATE
            data = {}
            data["collection"] = "timeline"
            data["itemId"] = action.itemId
            data["operation"] = operation.name
            data["userActions"] = [{"type": MenuAction.SHARE.name}]

        if action.action == MenuAction.REPLY or action.action == MenuAction.REPLY_ALL:
            operation = Operation.INSERT
            data = {}
            data["collection"] = "timeline"
            data["itemId"] = action.itemId
            data["operation"] = operation.name
            data["userActions"] = [{"type": MenuAction.REPLY.name}]

        if action.action == MenuAction.DELETE:
            operation = Operation.DELETE
            data = {}
            data["collection"] = "timeline"
            data["itemId"] = action.itemId
            data["operation"] = operation.name
            data["userActions"] = [{"type": MenuAction.DELETE.name}]

        if action.action == MenuAction.CUSTOM:
            operation = Operation.UPDATE
            data = {}
            data["collection"] = "timeline"
            data["itemId"] = action.itemId
            data["operation"] = operation.name
            data["userActions"] = [{
                "type": MenuAction.CUSTOM.name,
                "payload": action.value
            }]

        if data is not None and operation is not None:
            header = {"Content-type": "application/json"}

            query = Subscription.query().filter(
                Subscription.user == current_user)
            query = query.filter(Subscription.collection == "timeline")
            query = query.filter(Subscription.operation == operation)
            for subscription in query.fetch():
                data["userToken"] = subscription.userToken
                data["verifyToken"] = subscription.verifyToken

                req = urllib2.Request(subscription.callbackUrl,
                                      json.dumps(data), header)
                try:
                    urllib2.urlopen(req)
                except:
                    logging.error(sys.exc_info()[0])

        # Report back to Glass emulator
        channel.send_message(current_user.email(),
                             json.dumps({"id": action.itemId}))

        return ActionResponse(success=True)
Example #32
0
    def timeline_list(self, query):
        """List timeline cards for the current user."""

        query = query.order(-TimelineItem.updated)
        query = query.filter(TimelineItem.user == endpoints.get_current_user())
        return query
def login_required():
    current_user = endpoints.get_current_user()
    if current_user is None:
        raise endpoints.UnauthorizedException('Invalid token.')
    return current_user
Example #34
0
    def timeline_delete(self, card):
        """Remove an existing card for the current user.

        This will set all properties except the ID to None and set isDeleted to true
        """

        if not card.from_datastore or card.user != endpoints.get_current_user():
            raise endpoints.NotFoundException("Contact not found.")

        if card.isDeleted:
            raise endpoints.NotFoundException("Card has been deleted")

        # Delete attachments
        keys = []
        if card.attachments is not None:
            for att in card.attachments:
                keys.append(blobstore.BlobKey(att.id))
        blobstore.delete_async(keys)

        card.attachments = []
        card.bundleId = None
        card.canonicalUrl = None
        card.created = None
        card.creator = None
        card.displayTime = None
        card.html = None
        card.htmlPages = []
        card.inReplyTo = None
        card.isBundleCover = None
        card.isPinned = None
        card.menuItems = []
        card.notification = None
        card.recipients = []
        card.sourceItemId = None
        card.speakableText = None
        card.text = None
        card.title = None
        card.updated = None
        card.isDeleted = True
        card.put()

        # Notify Glass emulator
        channel.send_message(card.user.email(), json.dumps({"id": card.id}))

        # Notify timeline DELETE subscriptions
        data = {}
        data["collection"] = "timeline"
        data["itemId"] = card.id
        operation = Operation.DELETE
        data["operation"] = operation.name

        header = {"Content-type": "application/json"}

        query = Subscription.query().filter(Subscription.user == endpoints.get_current_user())
        query = query.filter(Subscription.collection == "timeline")
        query = query.filter(Subscription.operation == operation)
        for subscription in query.fetch():
            data["userToken"] = subscription.userToken
            data["verifyToken"] = subscription.verifyToken

            req = urllib2.Request(subscription.callbackUrl, json.dumps(data), header)
            try:
                urllib2.urlopen(req)
            except:
                logging.error(sys.exc_info()[0])

        return card
Example #35
0
    def contacts_list(self, query):
        """List all Contacts registered for the current user."""

        return query.filter(Contact.user == endpoints.get_current_user())
Example #36
0
    def subscriptions_list(self, query):
        """List all Subscriptions registered for the current user."""

        return query.filter(Contact.user == endpoints.get_current_user())
Example #37
0
    def locations_list(self, query):
        """List locations for the current user."""

        query = query.order(-Location.timestamp)
        return query.filter(TimelineItem.user == endpoints.get_current_user())