Example #1
0
def set_default_forwards(app_name, operation, apps, schema_editor):
    """Set default value for AleaIdField."""
    model = apps.get_model(app_name, operation.model_name)
    for obj_pk in model.objects.values_list('pk', flat=True):
        model.objects.filter(pk=obj_pk).update(**{
            operation.name: get_meteor_id(model, obj_pk),
        })
Example #2
0
    def user_queries(self, user, *params):
        """Return queries for this publication as seen by `user`."""
        try:
            get_queries = self.get_queries
        except AttributeError:
            # statically defined queries
            if self.queries is None:
                raise NotImplementedError(
                    'Must set either queries or implement get_queries method.',
                )
            if params:
                raise NotImplementedError(
                    'Publication params not implemented on %r publication.' %
                    (self.name, ), )
            return self.queries[:]

        if user is False:
            # no need to play with `this.user_id` or `this.user_ddp_id`.
            return get_queries(*params)

        # stash the old user details
        old_user_id = this.user_id
        old_user_ddp_id = this.user_ddp_id
        # apply the desired user details
        this.user_id = None if user is None else user.pk
        this.user_ddp_id = None if user is None else get_meteor_id(user)
        try:
            return get_queries(*params)
        finally:
            # restore the old user details
            this.user_id = old_user_id
            this.user_ddp_id = old_user_ddp_id
Example #3
0
    def user_queries(self, user, *params):
        """Return queries for this publication as seen by `user`."""
        try:
            get_queries = self.get_queries
        except AttributeError:
            # statically defined queries
            if self.queries is None:
                raise NotImplementedError(
                    'Must set either queries or implement get_queries method.',
                )
            if params:
                raise NotImplementedError(
                    'Publication params not implemented on %r publication.' % (
                        self.name,
                    ),
                )
            return self.queries[:]

        if user is False:
            # no need to play with `this.user_id` or `this.user_ddp_id`.
            return get_queries(*params)

        # stash the old user details
        old_user_id = this.user_id
        old_user_ddp_id = this.user_ddp_id
        # apply the desired user details
        this.user_id = None if user is None else user.pk
        this.user_ddp_id = None if user is None else get_meteor_id(user)
        try:
            return get_queries(*params)
        finally:
            # restore the old user details
            this.user_id = old_user_id
            this.user_ddp_id = old_user_ddp_id
Example #4
0
 def handle_m2m_field(self, obj, field):
     if field.rel.through._meta.auto_created:
         if self.use_natural_foreign_keys and hasattr(field.rel.to, 'natural_key'):
             m2m_value = lambda value: value.natural_key()
         else:
             m2m_value = lambda value: get_meteor_id(value)
         self._current['%s_ids' % field.name] = [m2m_value(related)
                            for related in getattr(obj, field.name).iterator()]
Example #5
0
    def get_dump_object(self, obj):
        data = {
            "model": force_text(obj._meta),
            "fields": self._current,
        }
        if not self.use_natural_primary_keys or not hasattr(obj, 'natural_key'):
            data["pk"] = get_meteor_id(obj)

        return data
Example #6
0
 def reset_password(self, token, new_password):
     """Reset password using a token received in email then logs user in."""
     user, _ = self.validated_user_and_session(
         token, purpose=HashPurpose.PASSWORD_RESET,
     )
     user.set_password(new_password)
     user.save()
     auth.login(this.request, user)
     self.update_subs(user.pk)
     return {"userId": get_meteor_id(this.request.user)};
Example #7
0
 def do_login(self, user):
     """Login a user."""
     this.user_id = user.pk
     this.user_ddp_id = get_meteor_id(user)
     # silent subscription (sans sub/nosub msg) to LoggedInUser pub
     this.user_sub_id = meteor_random_id()
     API.do_sub(this.user_sub_id, 'LoggedInUser', silent=True)
     self.update_subs(user.pk)
     user_logged_in.send(
         sender=user.__class__, request=this.request, user=user,
     )
Example #8
0
def send_notify(model, obj, msg, using):
    """Dispatch PostgreSQL async NOTIFY."""
    col_name = collection_name(model)
    if col_name == 'migrations.migration':
        return  # never send migration models.
    if col_name.startswith('dddp.'):
        return  # don't send DDP internal models.
    sub_ids = set()
    for sub in Subscription.objects.filter(
            collections__name=col_name,
    ):
        pub = _CLS_CACHE[sub.publication_class]()
        pub_queries = {
            collection_name(qs.model): qs
            for qs
            in pub.get_queries(*sub.params)
            if qs.model is model
        }
        for sub_col in sub.collections.filter(
                name=col_name,
        ):
            qs = pub_queries[sub_col.name]
            col = _CLS_CACHE[sub_col.collection_class]()
            # filter qs using user_rel paths on collection
            qs = col.get_queryset(qs)
            if qs.filter(pk=obj.pk).exists():
                sub_ids.add(sub.sub_id)

    if not sub_ids:
        get_meteor_id(obj)  # force creation of meteor ID using randomSeed
        return  # no subscribers for this object, nothing more to do.

    name, payload = obj_change_as_msg(obj, msg)
    payload['_sub_ids'] = sorted(sub_ids)
    cursor = connections[using].cursor()
    cursor.execute(
        'NOTIFY "%s", %%s' % name,
        [
            ejson.dumps(payload),
        ],
    )
Example #9
0
 def handle_fk_field(self, obj, field):
     if self.use_natural_foreign_keys and hasattr(field.rel.to, 'natural_key'):
         related = getattr(obj, field.name)
         if related:
             value = related.natural_key()
         else:
             value = None
     else:
         value = getattr(obj, field.name)
         if value is not None:
             value = get_meteor_id(value)
     self._current[field.column] = value
Example #10
0
def get_user_token(user, purpose, days_valid):
    """Return login token info for given user."""
    token = ''.join(
        dumps([
            user.get_username(),
            get_auth_hash(user, purpose),
        ]).encode('base64').split('\n'))
    return {
        'id': get_meteor_id(user),
        'token': token,
        'tokenExpires': calc_expiry_time(days_valid),
    }
Example #11
0
def get_user_token(user, purpose, minutes_valid):
    """Return login token info for given user."""
    token = ''.join(
        dumps([
            user.get_username(),
            get_auth_hash(user, purpose),
        ]).encode('base64').split('\n')
    )
    return {
        'id': get_meteor_id(user),
        'token': token,
        'tokenExpires': calc_expiry_time(minutes_valid),
    }
Example #12
0
 def get_user_token(cls, user, session_key, expiry_date, purpose):
     """Return login token info for given user."""
     token = ''.join(
         dumps([
             user.get_username(),
             session_key,
             cls.get_auth_hash(user, purpose),
         ]).encode('base64').split('\n')
     )
     return {
         'id': get_meteor_id(user),
         'token': token,
         'tokenExpires': expiry_date,
     }
Example #13
0
def get_user_token(user, purpose, minutes_valid):
    """Return login token info for given user."""
    token_json = dumps([
        user.get_username(),
        get_auth_hash(user, purpose),
    ])
    token_json_enc = token_json.encode()
    token_json_enc_b64_multiline = base64.b64encode(token_json_enc)
    token_json_enc_b64_singleline = "".join(
        token_json_enc_b64_multiline.decode().split("\n")
    )

    return {
        'id': get_meteor_id(user),
        'token': token_json_enc_b64_singleline,
        'tokenExpires': calc_expiry_time(minutes_valid),
    }
Example #14
0
    def serialize(self, obj, meteor_ids):
        """Generate a DDP msg for obj with specified msg type."""
        # check for F expressions
        exps = [
            name for name, val in vars(obj).items()
            if isinstance(val, ExpressionNode)
        ]
        if exps:
            # clone/update obj with values but only for the expression fields
            obj = deepcopy(obj)
            for name, val in self.model.objects.values(*exps).get(
                    pk=obj.pk,
            ).items():
                setattr(obj, name, val)

        # run serialization now all fields are "concrete" (not F expressions)
        data = this.serializer.serialize([obj])[0]
        fields = data['fields']
        del data['pk'], data['model']
        # Django supports model._meta -> pylint: disable=W0212
        meta = self.model._meta
        for field in meta.local_fields:
            rel = getattr(field, 'rel', None)
            if rel:
                # use field value which should set by select_related()
                fields[field.column] = get_meteor_id(
                    getattr(obj, field.name),
                )
                fields.pop(field.name)
            elif isinstance(field, django.contrib.postgres.fields.ArrayField):
                fields[field.name] = field.to_python(fields.pop(field.name))
            elif (
                isinstance(field, AleaIdField)
            ) and (
                not field.null
            ) and (
                field.name == 'aid'
            ):
                # This will be sent as the `id`, don't send it in `fields`.
                fields.pop(field.name)
        for field in meta.local_many_to_many:
            fields['%s_ids' % field.name] = get_meteor_ids(
                field.rel.to, fields.pop(field.name),
            ).values()
        return data
Example #15
0
    def serialize(self, obj, meteor_ids):
        """Generate a DDP msg for obj with specified msg type."""
        # check for F expressions
        exps = [
            name for name, val in vars(obj).items()
            if isinstance(val, ExpressionNode)
        ]
        if exps:
            # clone/update obj with values but only for the expression fields
            obj = deepcopy(obj)
            for name, val in self.model.objects.values(*exps).get(
                    pk=obj.pk,
            ).items():
                setattr(obj, name, val)

        # run serialization now all fields are "concrete" (not F expressions)
        data = this.serializer.serialize([obj])[0]
        fields = data['fields']
        del data['pk'], data['model']
        # Django supports model._meta -> pylint: disable=W0212
        meta = self.model._meta
        for field in meta.local_fields:
            rel = getattr(field, 'rel', None)
            if rel:
                # use field value which should set by select_related()
                fields[field.column] = get_meteor_id(
                    getattr(obj, field.name),
                )
                fields.pop(field.name)
            elif isinstance(field, django.contrib.postgres.fields.ArrayField):
                fields[field.name] = field.to_python(fields.pop(field.name))
            elif (
                isinstance(field, AleaIdField)
            ) and (
                not field.null
            ) and (
                field.name == 'aid'
            ):
                # This will be sent as the `id`, don't send it in `fields`.
                fields.pop(field.name)
        for field in meta.local_many_to_many:
            fields['%s_ids' % field.name] = get_meteor_ids(
                field.rel.to, fields.pop(field.name),
            ).values()
        return data
Example #16
0
    def obj_change_as_msg(self, obj, msg, meteor_ids=None):
        """Return DDP change message of specified type (msg) for obj."""
        if meteor_ids is None:
            meteor_ids = {}
        try:
            meteor_id = meteor_ids[str(obj.pk)]
        except KeyError:
            meteor_id = None
        if meteor_id is None:
            meteor_ids[str(obj.pk)] = meteor_id = get_meteor_id(obj)
        assert meteor_id is not None
        if msg == REMOVED:
            data = {}  # `removed` only needs ID (added below)
        elif msg in (ADDED, CHANGED):
            data = self.serialize(obj, meteor_ids)
        else:
            raise ValueError('Invalid message type: %r' % msg)

        data.update(msg=msg, collection=self.name, id=meteor_id)
        return data
Example #17
0
    def obj_change_as_msg(self, obj, msg, meteor_ids=None):
        """Return DDP change message of specified type (msg) for obj."""
        if meteor_ids is None:
            meteor_ids = {}
        try:
            meteor_id = meteor_ids[str(obj.pk)]
        except KeyError:
            meteor_id = None
        if meteor_id is None:
            meteor_ids[str(obj.pk)] = meteor_id = get_meteor_id(obj)
        assert meteor_id is not None
        if msg == REMOVED:
            data = {}  # `removed` only needs ID (added below)
        elif msg in (ADDED, CHANGED):
            data = self.serialize(obj, meteor_ids)
        else:
            raise ValueError('Invalid message type: %r' % msg)

        data.update(msg=msg, collection=self.name, id=meteor_id)
        return data
Example #18
0
def set_default_reverse(app_name, operation, apps, schema_editor):
    """Unset default value for AleaIdField."""
    model = apps.get_model(app_name, operation.model_name)
    for obj_pk in model.objects.values_list('pk', flat=True):
        get_meteor_id(model, obj_pk)