Beispiel #1
0
    def _validate_webpush(self, d, result):
        db = self.context["db"]  # type: DatabaseManager
        log = self.context["log"]  # type: Logger
        channel_id = normalize_id(d["chid"])
        uaid = result["uaid"]
        if 'current_month' not in result:
            log.info(format="Dropping User",
                     code=102,
                     uaid_hash=hasher(uaid),
                     uaid_record=dump_uaid(result))
            db.router.drop_user(uaid)
            raise InvalidRequest("No such subscription",
                                 status_code=410,
                                 errno=106)

        month_table = result["current_month"]
        if month_table not in db.message_tables:
            log.info(format="Dropping User",
                     code=103,
                     uaid_hash=hasher(uaid),
                     uaid_record=dump_uaid(result))
            db.router.drop_user(uaid)
            raise InvalidRequest("No such subscription",
                                 status_code=410,
                                 errno=106)
        exists, chans = db.message_tables[month_table].all_channels(uaid=uaid)

        if (not exists or channel_id.lower() not in map(
                lambda x: normalize_id(x), chans)):
            log.info("Unknown subscription: {channel_id}",
                     channel_id=channel_id)
            raise InvalidRequest("No such subscription",
                                 status_code=410,
                                 errno=106)
Beispiel #2
0
    def unregister_channel(self, uaid, channel_id, **kwargs):
        # type: (str, str, **str) -> bool
        """Remove a channel registration for a given uaid"""
        chid = normalize_id(channel_id)

        response = self.table.update_item(
            Key={
                'uaid': hasher(uaid),
                'chidmessageid': ' ',
            },
            UpdateExpression="DELETE chids :channel_id SET expiry = :expiry",
            ExpressionAttributeValues={
                ":channel_id": set([chid]),
                ":expiry": _expiry(self._max_ttl)
            },
            ReturnValues="UPDATED_OLD",
        )
        chids = response.get('Attributes', {}).get('chids', {})
        if chids:
            try:
                return chid in chids
            except (TypeError, AttributeError):  # pragma: nocover
                pass
        # if, for some reason, there are no chids defined, return False.
        return False
Beispiel #3
0
    def save_notification(self, uaid, chid, version):
        # type: (str, str, Optional[int]) -> bool
        """Save a notification for the UAID

        :raises:
            :exc:`ProvisionedThroughputExceededException` if dynamodb table
            exceeds throughput.

        """
        conn = self.table.connection
        try:
            cond = "attribute_not_exists(version) or version < :ver"
            conn.put_item(
                self.table.table_name,
                item=self.encode(
                    dict(uaid=hasher(uaid),
                         chid=normalize_id(chid),
                         version=version)),
                condition_expression=cond,
                expression_attribute_values={":ver": {
                    'N': str(version)
                }})
            return True
        except ConditionalCheckFailedException:
            return False
Beispiel #4
0
    def delete_notification(self, uaid, chid, version=None):
        # type: (str, str, Optional[int]) -> bool
        """Delete a notification for a UAID

        :returns: Whether or not the notification was able to be deleted.

        """
        try:
            if version:
                self.table.delete_item(uaid=hasher(uaid),
                                       chid=normalize_id(chid),
                                       expected={"version__eq": version})
            else:
                self.table.delete_item(uaid=hasher(uaid),
                                       chid=normalize_id(chid))
            return True
        except ProvisionedThroughputExceededException:
            return False
Beispiel #5
0
    def _validate_webpush(self, d, result):
        db = self.context["db"]  # type: DatabaseManager
        log = self.context["log"]  # type: Logger
        metrics = self.context["metrics"]  # type: IMetrics
        channel_id = normalize_id(d["chid"])
        uaid = result["uaid"]
        if 'current_month' not in result:
            log.debug(format="Dropping User",
                      code=102,
                      uaid_hash=hasher(uaid),
                      uaid_record=repr(result))
            metrics.increment("updates.drop_user", tags=make_tags(errno=102))
            db.router.drop_user(uaid)
            raise InvalidRequest("No such subscription",
                                 status_code=410,
                                 errno=106)

        month_table = result["current_month"]
        if month_table not in db.message_tables:
            log.debug(format="Dropping User",
                      code=103,
                      uaid_hash=hasher(uaid),
                      uaid_record=repr(result))
            metrics.increment("updates.drop_user", tags=make_tags(errno=103))
            db.router.drop_user(uaid)
            raise InvalidRequest("No such subscription",
                                 status_code=410,
                                 errno=106)
        msg = db.message_table(month_table)
        exists, chans = msg.all_channels(uaid=uaid)

        if (not exists or channel_id.lower() not in map(
                lambda x: normalize_id(x), chans)):
            log.debug("Unknown subscription: {channel_id}",
                      channel_id=channel_id)
            raise InvalidRequest("No such subscription",
                                 status_code=410,
                                 errno=106)
Beispiel #6
0
 def register_channel(self, uaid, channel_id):
     # type: (str, str) -> bool
     """Register a channel for a given uaid"""
     conn = self.table.connection
     db_key = self.encode({"uaid": hasher(uaid), "chidmessageid": " "})
     # Generate our update expression
     expr = "ADD chids :channel_id"
     expr_values = self.encode(
         {":channel_id": set([normalize_id(channel_id)])})
     conn.update_item(
         self.table.table_name,
         db_key,
         update_expression=expr,
         expression_attribute_values=expr_values,
     )
     return True
Beispiel #7
0
 def register_channel(self, uaid, channel_id, ttl=None):
     # type: (str, str, int) -> bool
     """Register a channel for a given uaid"""
     # Generate our update expression
     if ttl is None:
         ttl = self._max_ttl
     expr_values = {
         ":channel_id": set([normalize_id(channel_id)]),
         ":expiry": _expiry(ttl)
     }
     self.table.update_item(
         Key={
             'uaid': hasher(uaid),
             'chidmessageid': ' ',
         },
         UpdateExpression='ADD chids :channel_id, expiry :expiry',
         ExpressionAttributeValues=expr_values,
     )
     return True
Beispiel #8
0
    def unregister_channel(self, uaid, channel_id, **kwargs):
        # type: (str, str, **str) -> bool
        """Remove a channel registration for a given uaid"""
        conn = self.table.connection
        db_key = self.encode({"uaid": hasher(uaid), "chidmessageid": " "})
        expr = "DELETE chids :channel_id"
        expr_values = self.encode(
            {":channel_id": set([normalize_id(channel_id)])})

        result = conn.update_item(
            self.table.table_name,
            db_key,
            update_expression=expr,
            expression_attribute_values=expr_values,
            return_values="UPDATED_OLD",
        )
        chids = result.get('Attributes', {}).get('chids', {})
        if chids:
            try:
                return channel_id in self.table._dynamizer.decode(chids)
            except (TypeError, AttributeError):  # pragma: nocover
                pass
        # if, for some reason, there are no chids defined, return False.
        return False