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), })
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
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
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()]
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
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)};
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, )
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), ], )
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
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), }
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), }
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, }
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), }
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
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
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)