diff --git a/api.py b/api.py index be83784..16a4880 100644 --- a/api.py +++ b/api.py @@ -27,7 +27,7 @@ from cosmopolite.lib import utils import config -def CreateChannel(google_user, client, instance_id, args): +def CreateChannel(google_user, client, client_address, instance_id, args): models.Instance.FindOrCreate(instance_id) token = channel.create_channel( @@ -52,7 +52,7 @@ def CreateChannel(google_user, client, instance_id, args): } -def Pin(google_user, client, instance_id, args): +def Pin(google_user, client, client_address, instance_id, args): instance = models.Instance.FromID(instance_id) if not instance or not instance.active: # Probably a race with the channel opening @@ -69,6 +69,7 @@ def Pin(google_user, client, instance_id, args): message, models.Client.profile.get_value_for_datastore(client), sender_message_id, + client_address, instance) except models.DuplicateMessage: logging.warning('Duplicate pin: %s', sender_message_id) @@ -86,7 +87,7 @@ def Pin(google_user, client, instance_id, args): } -def SendMessage(google_user, client, instance_id, args): +def SendMessage(google_user, client, client_address, instance_id, args): subject = args['subject'] message = args['message'] sender_message_id = args['sender_message_id'] @@ -95,7 +96,8 @@ def SendMessage(google_user, client, instance_id, args): models.Subject.FindOrCreate(subject).SendMessage( message, models.Client.profile.get_value_for_datastore(client), - sender_message_id) + sender_message_id, + client_address) except models.DuplicateMessage: logging.warning('Duplicate message: %s', sender_message_id) return { @@ -112,7 +114,7 @@ def SendMessage(google_user, client, instance_id, args): } -def Subscribe(google_user, client, instance_id, args): +def Subscribe(google_user, client, client_address, instance_id, args): instance = models.Instance.FromID(instance_id) subject = models.Subject.FindOrCreate(args['subject']) messages = args.get('messages', 0) @@ -141,7 +143,7 @@ def Subscribe(google_user, client, instance_id, args): } -def Unpin(google_user, client, instance_id, args): +def Unpin(google_user, client, client_address, instance_id, args): instance = models.Instance.FromID(instance_id) subject = args['subject'] sender_message_id = args['sender_message_id'] @@ -162,7 +164,7 @@ def Unpin(google_user, client, instance_id, args): } -def Unsubscribe(google_user, client, instance_id, args): +def Unsubscribe(google_user, client, client_address, instance_id, args): instance = models.Instance.FromID(instance_id) subject = models.Subject.FindOrCreate(args['subject']) models.Subscription.Remove(subject, instance) @@ -199,6 +201,7 @@ class APIWrapper(webapp2.RequestHandler): result = callback( self.verified_google_user, self.client, + self.request.remote_addr, self.request_json['instance_id'], command.get('arguments', {})) # Magic: if result contains "events", haul them up a level so the diff --git a/lib/models.py b/lib/models.py index fb2388a..856f0ae 100644 --- a/lib/models.py +++ b/lib/models.py @@ -175,7 +175,7 @@ class Subject(db.Model): return list(query) @db.transactional() - def PutMessage(self, message, sender, sender_message_id): + def PutMessage(self, message, sender, sender_message_id, sender_address): """Internal helper for SendMessage(). Unless/until channel.send_message becomes transactional, we have to finish @@ -205,6 +205,7 @@ class Subject(db.Model): message=message, sender=sender, sender_message_id=sender_message_id, + sender_address=sender_address, id_=message_id) obj.put() @@ -222,15 +223,17 @@ class Subject(db.Model): readable_only_by != reader): raise AccessDenied - def SendMessage(self, message, sender, sender_message_id): + def SendMessage(self, message, sender, sender_message_id, sender_address): self.VerifyWritable(sender) - obj, subscriptions = self.PutMessage(message, sender, sender_message_id) + obj, subscriptions = self.PutMessage( + message, sender, sender_message_id, sender_address) event = obj.ToEvent() for subscription in subscriptions: subscription.SendMessage(event) @db.transactional() - def PutPin(self, message, sender, sender_message_id, instance): + def PutPin(self, message, sender, sender_message_id, + instance, sender_address): """Internal helper for Pin().""" # sender_message_id should be universal across all subjects, but we check # it within just this subject to allow in-transaction verification. @@ -248,15 +251,16 @@ class Subject(db.Model): message=message, sender=sender, sender_message_id=sender_message_id, + sender_address=sender_address, instance=instance) obj.put() return (obj, list(Subscription.all().ancestor(self))) - def Pin(self, message, sender, sender_message_id, instance): + def Pin(self, message, sender, sender_message_id, sender_address, instance): self.VerifyWritable(sender) obj, subscriptions = self.PutPin( - message, sender, sender_message_id, instance) + message, sender, sender_message_id, instance, sender_address) event = obj.ToEvent() for subscription in subscriptions: subscription.SendMessage(event) @@ -347,6 +351,7 @@ class Message(db.Model): message = db.TextProperty(required=True) sender = db.ReferenceProperty(required=True, reference_class=Profile) sender_message_id = db.StringProperty(required=True) + sender_address = db.StringProperty(required=True) # id is reserved id_ = db.IntegerProperty(required=True) @@ -367,9 +372,10 @@ class Pin(db.Model): created = db.DateTimeProperty(required=True, auto_now_add=True) instance = db.ReferenceProperty(required=True, reference_class=Instance) - sender = db.ReferenceProperty(required=True, reference_class=Profile) message = db.TextProperty(required=True) + sender = db.ReferenceProperty(required=True, reference_class=Profile) sender_message_id = db.StringProperty(required=True) + sender_address = db.StringProperty(required=True) def ToEvent(self, event_type='pin'): return {