Exemplo n.º 1
0
 def __put(self, cmd: Command, sender: ID) -> Content:
     # receive encrypted contacts, save it
     if self.database.save_contacts_command(cmd=cmd, sender=sender):
         self.info('contacts command saved for %s' % sender)
         return ReceiptCommand.new(message='Contacts of %s received!' %
                                   sender)
     else:
         self.error('failed to save contacts command: %s' % cmd)
         return TextContent.new(text='Contacts not stored %s!' % cmd)
Exemplo n.º 2
0
 def __put(self, cmd: Command, sender: ID) -> Content:
     # receive block command, save it
     if self.database.save_block_command(cmd=cmd, sender=sender):
         self.info('block command saved for %s' % sender)
         return ReceiptCommand.new(message='Block command of %s received!' %
                                   sender)
     else:
         self.error('failed to save block command: %s' % cmd)
         return TextContent.new(text='Block-list not stored %s!' % cmd)
Exemplo n.º 3
0
 def __get(self, identifier: ID) -> Content:
     # query meta for ID
     meta = self.facebook.meta(identifier=identifier)
     if meta is None:
         # meta not found
         text = 'Sorry, meta for %s not found.' % identifier
         return TextContent(text=text)
     # response
     return MetaCommand.response(identifier=identifier, meta=meta)
Exemplo n.º 4
0
 def __get_contacts(self, sender: ID) -> Content:
     # query encrypted contacts, load it
     stored: Command = self.database.contacts_command(identifier=sender)
     # response
     if stored is not None:
         # response the stored contacts command directly
         return stored
     else:
         return TextContent.new(text='Sorry, contacts of %s not found.' %
                                sender)
Exemplo n.º 5
0
 def execute(self, cmd: Command, msg: ReliableMessage) -> Optional[Content]:
     assert isinstance(cmd, HandshakeCommand), 'command error: %s' % cmd
     message = cmd.message
     if message in ['DIM?', 'DIM!']:
         # S -> C
         return TextContent(text='Handshake command error: %s' % message)
     else:
         # C -> S: Hello world!
         assert 'Hello world!' == message, 'Handshake command error: %s' % cmd
         return self.__offer(session_key=cmd.session, sender=msg.sender)
Exemplo n.º 6
0
 def process(self, content: Content, sender: ID, msg: InstantMessage) -> Content:
     assert isinstance(content, HandshakeCommand), 'command error: %s' % content
     message = content.message
     if message in ['DIM?', 'DIM!']:
         # S -> C
         return TextContent.new(text='Handshake command error: %s' % message)
     else:
         # C -> S: Hello world!
         assert 'Hello world!' == message, 'Handshake command error: %s' % content
         return self.__offer(session_key=content.session, sender=sender)
Exemplo n.º 7
0
 def process(self, content: Content, sender: ID,
             msg: InstantMessage) -> Content:
     assert isinstance(content,
                       StorageCommand), 'command error: %s' % content
     title = content.title
     if title == StorageCommand.CONTACTS:
         return self.__process_contacts(cmd=content, sender=sender)
     # error
     return TextContent.new(
         text='Storage command (title: %s) not support yet!' % title)
Exemplo n.º 8
0
 def broadcast_message(self, msg: ReliableMessage) -> Optional[Content]:
     """ Deliver message to everyone@everywhere, including all neighbours """
     res = self.filter.check_broadcast(msg=msg)
     if res is not None:
         # broadcast is not allowed
         return res
     # TODO: broadcast this message
     text = 'Message broadcast to "%s" is not implemented' % msg.envelope.receiver
     res = TextContent.new(text=text)
     res.group = msg.envelope.group
     return res
Exemplo n.º 9
0
 def execute(self, cmd: Command, msg: ReliableMessage) -> Optional[Content]:
     assert isinstance(cmd, SearchCommand), 'command error: %s' % cmd
     # keywords
     keywords = cmd.get('keywords')
     if keywords is None:
         return TextContent(text='Search command error')
     keywords = keywords.split(' ')
     # search in database
     results = self.database.search(keywords=keywords)
     users = list(results.keys())
     return SearchCommand(users=users, results=results)
Exemplo n.º 10
0
 def process(self, content: Content, sender: ID,
             msg: InstantMessage) -> Optional[Content]:
     assert isinstance(content, Command), 'command error: %s' % content
     # keywords
     keywords = content.get('keywords')
     if keywords is None:
         return TextContent.new(text='Search command error')
     keywords = keywords.split(' ')
     # search in database
     results = self.database.search(keywords=keywords)
     users = list(results.keys())
     return SearchCommand.new(users=users, results=results)
Exemplo n.º 11
0
 def forward_message(self, msg: ReliableMessage) -> Optional[Content]:
     """ Re-pack and deliver (Top-Secret) message to the real receiver """
     res = self.filter.check_forward(msg=msg)
     if res is not None:
         # forward is not allowed
         return res
     forward = ForwardContent.new(message=msg)
     receiver = self.facebook.identifier(string=msg.envelope.receiver)
     if self.send_content(content=forward, receiver=receiver):
         return ReceiptCommand.new(message='Message forwarded', envelope=msg.envelope)
     else:
         return TextContent.new(text='Failed to forward your message')
Exemplo n.º 12
0
 def __get(self, identifier: ID, doc_type: str = '*') -> Content:
     facebook = self.facebook
     # query entity document for ID
     doc = facebook.document(identifier=identifier, doc_type=doc_type)
     if facebook.is_empty_document(document=doc):
         # document not found
         text = 'Sorry, document not found for ID: %s' % identifier
         return TextContent(text=text)
     # response
     meta: Meta = facebook.meta(identifier=identifier)
     return DocumentCommand.response(document=doc,
                                     meta=meta,
                                     identifier=identifier)
Exemplo n.º 13
0
 def process(self, content: Content, sender: ID, msg: InstantMessage) -> Optional[Content]:
     assert isinstance(content, Command), 'command error: %s' % content
     # report title
     title = content.get('title')
     if 'report' == title:
         return self.__process_old_report(cmd=content, sender=sender)
     # get CPU by report title
     cpu = self.cpu(command=title)
     # check and run
     if cpu is None:
         return TextContent.new(text='Report command (title: %s) not support yet!' % title)
     assert cpu is not self, 'Dead cycle! report cmd: %s' % content
     return cpu.process(content=content, sender=sender, msg=msg)
Exemplo n.º 14
0
 def arrival(self, msg: ReliableMessage) -> Optional[ReliableMessage]:
     # check message delegate
     if msg.delegate is None:
         msg.delegate = self
     sid = g_station.identifier
     if self.__traced(msg=msg, station=g_station):
         self.debug(
             'current station %s in traces list, ignore this message: %s' %
             (sid, msg))
         return None
     if not self.__deliver_message(msg=msg, neighbor=sid):
         self.error('failed to send income message: %s' % msg)
         return None
     if g_released:
         # FIXME: how to let the client knows where the message reached
         return None
     # response
     sender = msg.sender
     text = 'Message reached station: %s' % g_station
     self.debug('income: %s, %s | %s | %s' %
                (text, msg['signature'][:8], sender.name, msg.receiver))
     res = TextContent(text=text)
     res.group = msg.group
     return self.__pack_message(content=res, receiver=sender)
Exemplo n.º 15
0
 def departure(self, msg: ReliableMessage) -> Optional[ReliableMessage]:
     receiver = msg.receiver
     if receiver == g_station.identifier:
         self.debug('msg for %s will be stopped here' % receiver)
         return None
     sent_neighbors = msg.get('sent_neighbors')
     if sent_neighbors is None:
         sent_neighbors = []
     else:
         msg.pop('sent_neighbors')
     neighbors = self.__neighbors.copy()
     success = 0
     for sid in neighbors:
         if sid in sent_neighbors:
             self.debug('station %s in sent list, ignore this neighbor' %
                        sid)
             continue
         if self.__deliver_message(msg=msg, neighbor=sid):
             success += 1
     # FIXME: what about the failures
     if g_released:
         # FIXME: how to let the client knows where the message reached
         return None
     # response
     sender = msg.sender
     meta = g_messenger.facebook.meta(identifier=sender)
     if meta is None:
         # waiting for meta
         return None
     text = 'Message broadcast to %d/%d stations' % (success,
                                                     len(neighbors))
     self.debug('outgo: %s, %s | %s | %s' %
                (text, msg['signature'][:8], sender.name, msg.receiver))
     res = TextContent(text=text)
     res.group = msg.group
     return self.__pack_message(content=res, receiver=sender)
Exemplo n.º 16
0
 def __welcome(self, freshmen: list) -> TextContent:
     names = [g_facebook.nickname(item) for item in freshmen]
     count = len(names)
     if count == 1:
         string = names[0]
         msg = 'Welcome new member~ %s.' % string
     elif count > 1:
         string = ', '.join(names)
         msg = 'Welcome new members~ %s.' % string
     else:
         # should not be here
         msg = 'Welcome!'
     text = TextContent.new(text=msg)
     text.group = self.__group.identifier
     return text
Exemplo n.º 17
0
 def forward_message(self, msg: ReliableMessage) -> Optional[Content]:
     """ Re-pack and deliver (Top-Secret) message to the real receiver """
     if self.filter.allow_forward(msg=msg):
         # call dispatcher to deliver this message
         # repack the top-secret message
         sender = self.messenger.current_user.identifier
         receiver = g_facebook.identifier(msg.envelope.receiver)
         content = ForwardContent.new(message=msg)
         i_msg = InstantMessage.new(content=content,
                                    sender=sender,
                                    receiver=receiver)
         # encrypt, sign & deliver it
         r_msg = self.messenger.encrypt_sign(msg=i_msg)
         return self.deliver_message(msg=r_msg)
     else:
         text = 'Message forward to "%s" is not allowed' % msg.envelope.receiver
         return TextContent.new(text=text)
Exemplo n.º 18
0
 def execute(self, cmd: Command, msg: ReliableMessage) -> Optional[Content]:
     assert isinstance(cmd, ReportCommand), 'report command error: %s' % cmd
     # report title
     title = cmd.title
     if title == ReportCommand.REPORT:
         return self.__process_old_report(cmd=cmd, sender=msg.sender)
     # get CPU by report title
     cpu = self.processor_for_name(command=title)
     # check and run
     if cpu is None:
         return TextContent(
             text='Report command (title: %s) not support yet!' % title)
     elif cpu is self:
         raise AssertionError('Dead cycle! report cmd: %s' % cmd)
     assert isinstance(cpu, CommandProcessor), 'CPU error: %s' % cpu
     cpu.messenger = self.messenger
     return cpu.execute(cmd=cmd, msg=msg)
Exemplo n.º 19
0
 def send_report(self, text: str, receiver: ID) -> bool:
     if self.sender is None:
         self.error('sender not set yet')
         return False
     sender = self.facebook.identifier(self.sender)
     receiver = self.facebook.identifier(receiver)
     timestamp = int(time.time())
     content = TextContent.new(text=text)
     i_msg = InstantMessage.new(content=content,
                                sender=sender,
                                receiver=receiver,
                                time=timestamp)
     s_msg = self.messenger.encrypt_message(msg=i_msg)
     r_msg = self.messenger.sign_message(msg=s_msg)
     # try for online user
     sessions = self.session_server.all(identifier=receiver)
     if sessions and len(sessions) > 0:
         self.info('%s is online(%d), try to push report: %s' %
                   (receiver, len(sessions), text))
         success = 0
         for sess in sessions:
             if sess.valid is False or sess.active is False:
                 # self.info('session invalid %s' % sess)
                 continue
             request_handler = self.session_server.get_handler(
                 client_address=sess.client_address)
             if request_handler is None:
                 self.error('handler lost: %s' % sess)
                 continue
             if request_handler.push_message(r_msg):
                 success = success + 1
             else:
                 self.error(
                     'failed to push report via connection (%s, %s)' %
                     sess.client_address)
         if success > 0:
             self.info(
                 'report pushed to activated session(%d) of user: %s' %
                 (success, receiver))
             return True
     # store in local cache file
     self.info('%s is offline, store report: %s' % (receiver, text))
     self.database.store_message(r_msg)
     # push notification
     return self.apns.push(identifier=receiver, message=text)
Exemplo n.º 20
0
 def __check_blocked(self, envelope: Envelope) -> Optional[Content]:
     sender = self.facebook.identifier(envelope.sender)
     receiver = self.facebook.identifier(envelope.receiver)
     group = self.facebook.identifier(envelope.group)
     # check block-list
     if self.database.is_blocked(sender=sender,
                                 receiver=receiver,
                                 group=group):
         nickname = self.__name(identifier=receiver)
         if group is None:
             text = 'Message is blocked by %s' % nickname
         else:
             grp_name = self.__name(identifier=group)
             text = 'Message is blocked by %s in group %s' % (nickname,
                                                              grp_name)
         # response
         res = TextContent.new(text=text)
         res.group = group
         return res
Exemplo n.º 21
0
 def process_message(self, msg: Message) -> Optional[Content]:
     if isinstance(msg, ReliableMessage):
         s_msg = self.verify_message(msg=msg)
         if s_msg is None:
             # waiting for sender's meta if not exists
             return None
         receiver = self.facebook.identifier(string=msg.envelope.receiver)
         if receiver.type.is_group() and receiver.is_broadcast:
             # if it's a grouped broadcast id, then
             #    split and deliver to everyone
             return self.broadcast_message(msg=msg)
         try:
             return self.process_message(msg=s_msg)
         except LookupError as error:
             if str(error).startswith('receiver error'):
                 return self.deliver_message(msg=msg)
             else:
                 return TextContent.new(text='failed to process message: %s' % s_msg)
     else:
         return super().process_message(msg=msg)
Exemplo n.º 22
0
 def process(self, content: Content, sender: ID, msg: InstantMessage) -> Optional[Content]:
     assert isinstance(content, QueryCommand), 'group command error: %s' % content
     facebook: Facebook = self.facebook
     group: ID = facebook.identifier(content.group)
     # 1. check permission
     if not facebook.exists_member(member=sender, group=group):
         if not facebook.exists_assistant(member=sender, group=group):
             raise AssertionError('only member/assistant can query: %s' % msg)
     # 2. get group members
     members = facebook.members(identifier=group)
     if members is None or len(members) == 0:
         text = 'Group members not found: %s' % group
         return TextContent.new(text=text)
     # 3. response group members for sender
     user = facebook.current_user
     assert user is not None, 'current user not set'
     if facebook.is_owner(member=user.identifier, group=group):
         return GroupCommand.reset(group=group, members=members)
     else:
         return GroupCommand.invite(group=group, members=members)
Exemplo n.º 23
0
 def execute(self, cmd: Command, msg: ReliableMessage) -> Optional[Content]:
     assert isinstance(cmd, QueryCommand), 'group command error: %s' % cmd
     facebook = self.facebook
     group: ID = cmd.group
     # 1. check permission
     if not facebook.exists_member(member=msg.sender, group=group):
         if not facebook.exists_assistant(member=msg.sender, group=group):
             raise AssertionError('only member/assistant can query: %s, %s' % (group, msg.sender))
     # 2. get group members
     members = facebook.members(identifier=group)
     if members is None or len(members) == 0:
         text = 'Group members not found: %s' % group
         return TextContent(text=text)
     # 3. response group members for sender
     user = facebook.current_user
     assert user is not None, 'current user not set'
     if facebook.is_owner(member=user.identifier, group=group):
         return GroupCommand.reset(group=group, members=members)
     else:
         return GroupCommand.invite(group=group, members=members)
Exemplo n.º 24
0
 def send_report(self, text: str, receiver: ID) -> bool:
     if self.sender is None:
         self.error('sender not set yet')
         return False
     timestamp = int(time.time())
     content = TextContent(text=text)
     env = Envelope.create(sender=self.sender,
                           receiver=receiver,
                           time=timestamp)
     i_msg = InstantMessage.create(head=env, body=content)
     s_msg = self.messenger.encrypt_message(msg=i_msg)
     assert s_msg is not None, 'failed to report: %s, %s' % (receiver, text)
     r_msg = self.messenger.sign_message(msg=s_msg)
     if r_msg.delegate is None:
         r_msg.delegate = self.messenger
     # try for online user
     sessions = self.session_server.active_sessions(identifier=receiver)
     if len(sessions) > 0:
         self.debug('%s is online(%d), try to push report: %s' %
                    (receiver, len(sessions), text))
         success = 0
         for sess in sessions:
             if sess.push_message(r_msg):
                 success = success + 1
             else:
                 self.error(
                     'failed to push report via connection (%s, %s)' %
                     sess.client_address)
         if success > 0:
             self.debug(
                 'report pushed to activated session(%d) of user: %s' %
                 (success, receiver))
             return True
     # store in local cache file
     self.debug('%s is offline, store report: %s' % (receiver, text))
     self.database.store_message(r_msg)
     # push notification
     dispatcher = self.messenger.dispatcher
     return dispatcher.push(sender=self.sender,
                            receiver=receiver,
                            message=text)
Exemplo n.º 25
0
 def __put_contacts(self, cmd: StorageCommand, sender: ID) -> Content:
     # receive encrypted contacts, save it
     if self.database.save_contacts_command(cmd=cmd, sender=sender):
         return ReceiptCommand(message='Contacts of %s received!' % sender)
     else:
         return TextContent(text='Contacts not stored %s!' % cmd)
Exemplo n.º 26
0
 def __put(self, cmd: BlockCommand, sender: ID) -> Content:
     # receive block command, save it
     if self.database.save_block_command(cmd=cmd, sender=sender):
         return ReceiptCommand.new(message='Block command of %s received!' % sender)
     else:
         return TextContent.new(text='Sorry, block-list not stored: %s!' % cmd)