Record IP addresses for messages and pins to support later banning.

This commit is contained in:
Ian Gulliver
2014-06-08 22:04:53 -07:00
parent 322eb14a5d
commit 44ede2abbf
2 changed files with 23 additions and 14 deletions

17
api.py
View File

@@ -27,7 +27,7 @@ from cosmopolite.lib import utils
import config 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) models.Instance.FindOrCreate(instance_id)
token = channel.create_channel( 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) instance = models.Instance.FromID(instance_id)
if not instance or not instance.active: if not instance or not instance.active:
# Probably a race with the channel opening # Probably a race with the channel opening
@@ -69,6 +69,7 @@ def Pin(google_user, client, instance_id, args):
message, message,
models.Client.profile.get_value_for_datastore(client), models.Client.profile.get_value_for_datastore(client),
sender_message_id, sender_message_id,
client_address,
instance) instance)
except models.DuplicateMessage: except models.DuplicateMessage:
logging.warning('Duplicate pin: %s', sender_message_id) 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'] subject = args['subject']
message = args['message'] message = args['message']
sender_message_id = args['sender_message_id'] sender_message_id = args['sender_message_id']
@@ -95,7 +96,8 @@ def SendMessage(google_user, client, instance_id, args):
models.Subject.FindOrCreate(subject).SendMessage( models.Subject.FindOrCreate(subject).SendMessage(
message, message,
models.Client.profile.get_value_for_datastore(client), models.Client.profile.get_value_for_datastore(client),
sender_message_id) sender_message_id,
client_address)
except models.DuplicateMessage: except models.DuplicateMessage:
logging.warning('Duplicate message: %s', sender_message_id) logging.warning('Duplicate message: %s', sender_message_id)
return { 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) instance = models.Instance.FromID(instance_id)
subject = models.Subject.FindOrCreate(args['subject']) subject = models.Subject.FindOrCreate(args['subject'])
messages = args.get('messages', 0) 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) instance = models.Instance.FromID(instance_id)
subject = args['subject'] subject = args['subject']
sender_message_id = args['sender_message_id'] 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) instance = models.Instance.FromID(instance_id)
subject = models.Subject.FindOrCreate(args['subject']) subject = models.Subject.FindOrCreate(args['subject'])
models.Subscription.Remove(subject, instance) models.Subscription.Remove(subject, instance)
@@ -199,6 +201,7 @@ class APIWrapper(webapp2.RequestHandler):
result = callback( result = callback(
self.verified_google_user, self.verified_google_user,
self.client, self.client,
self.request.remote_addr,
self.request_json['instance_id'], self.request_json['instance_id'],
command.get('arguments', {})) command.get('arguments', {}))
# Magic: if result contains "events", haul them up a level so the # Magic: if result contains "events", haul them up a level so the

View File

@@ -175,7 +175,7 @@ class Subject(db.Model):
return list(query) return list(query)
@db.transactional() @db.transactional()
def PutMessage(self, message, sender, sender_message_id): def PutMessage(self, message, sender, sender_message_id, sender_address):
"""Internal helper for SendMessage(). """Internal helper for SendMessage().
Unless/until channel.send_message becomes transactional, we have to finish Unless/until channel.send_message becomes transactional, we have to finish
@@ -205,6 +205,7 @@ class Subject(db.Model):
message=message, message=message,
sender=sender, sender=sender,
sender_message_id=sender_message_id, sender_message_id=sender_message_id,
sender_address=sender_address,
id_=message_id) id_=message_id)
obj.put() obj.put()
@@ -222,15 +223,17 @@ class Subject(db.Model):
readable_only_by != reader): readable_only_by != reader):
raise AccessDenied raise AccessDenied
def SendMessage(self, message, sender, sender_message_id): def SendMessage(self, message, sender, sender_message_id, sender_address):
self.VerifyWritable(sender) 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() event = obj.ToEvent()
for subscription in subscriptions: for subscription in subscriptions:
subscription.SendMessage(event) subscription.SendMessage(event)
@db.transactional() @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().""" """Internal helper for Pin()."""
# sender_message_id should be universal across all subjects, but we check # sender_message_id should be universal across all subjects, but we check
# it within just this subject to allow in-transaction verification. # it within just this subject to allow in-transaction verification.
@@ -248,15 +251,16 @@ class Subject(db.Model):
message=message, message=message,
sender=sender, sender=sender,
sender_message_id=sender_message_id, sender_message_id=sender_message_id,
sender_address=sender_address,
instance=instance) instance=instance)
obj.put() obj.put()
return (obj, list(Subscription.all().ancestor(self))) 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) self.VerifyWritable(sender)
obj, subscriptions = self.PutPin( obj, subscriptions = self.PutPin(
message, sender, sender_message_id, instance) message, sender, sender_message_id, instance, sender_address)
event = obj.ToEvent() event = obj.ToEvent()
for subscription in subscriptions: for subscription in subscriptions:
subscription.SendMessage(event) subscription.SendMessage(event)
@@ -347,6 +351,7 @@ class Message(db.Model):
message = db.TextProperty(required=True) message = db.TextProperty(required=True)
sender = db.ReferenceProperty(required=True, reference_class=Profile) sender = db.ReferenceProperty(required=True, reference_class=Profile)
sender_message_id = db.StringProperty(required=True) sender_message_id = db.StringProperty(required=True)
sender_address = db.StringProperty(required=True)
# id is reserved # id is reserved
id_ = db.IntegerProperty(required=True) id_ = db.IntegerProperty(required=True)
@@ -367,9 +372,10 @@ class Pin(db.Model):
created = db.DateTimeProperty(required=True, auto_now_add=True) created = db.DateTimeProperty(required=True, auto_now_add=True)
instance = db.ReferenceProperty(required=True, reference_class=Instance) instance = db.ReferenceProperty(required=True, reference_class=Instance)
sender = db.ReferenceProperty(required=True, reference_class=Profile)
message = db.TextProperty(required=True) message = db.TextProperty(required=True)
sender = db.ReferenceProperty(required=True, reference_class=Profile)
sender_message_id = db.StringProperty(required=True) sender_message_id = db.StringProperty(required=True)
sender_address = db.StringProperty(required=True)
def ToEvent(self, event_type='pin'): def ToEvent(self, event_type='pin'):
return { return {