Beispiel #1
0
def upload_profile() -> Response:
    try:
        form = request.form.to_dict()
        identifier = form['ID']
        meta = form['meta']
        profile = form['profile']
        identifier = ID.parse(identifier=identifier)
        # save meta
        if meta is None:
            meta = g_facebook.meta(identifier=identifier)
            if meta is None:
                raise LookupError('meta not found: %s' % identifier)
        else:
            meta = Meta.parse(meta=json.loads(meta))
            if not g_facebook.save_meta(meta=meta, identifier=identifier):
                raise ValueError('meta not acceptable: %s' % identifier)
        # save profile
        if profile is None:
            raise ValueError('profile empty: %s' % identifier)
        else:
            profile = Document.parse(document=json.loads(profile))
            if not g_facebook.save_document(document=profile):
                raise ValueError('profile not acceptable: %s' % identifier)
        # OK
        return user(identifier)
    except Exception as error:
        res = {
            'code': 500,
            'name': 'Internal Server Error',
            'message': '%s' % error
        }
        xml = render_template('error.xml', result=res)
    return respond_xml(xml)
Beispiel #2
0
 def do_profile(self, name: str):
     if self.client is None:
         self.info('login first')
         return
     facebook = g_messenger.facebook
     user = facebook.current_user
     profile = None
     if name is None:
         identifier = user.identifier
     elif name.startswith('{') and name.endswith('}'):
         identifier = user.identifier
         profile = json_decode(data=utf8_encode(string=name))
     else:
         identifier = ID.parse(identifier=name)
         if identifier is None:
             self.info('I don\'t understand.')
             return
     if profile:
         private_key = facebook.private_key_for_signature(identifier=identifier)
         assert private_key is not None, 'failed to get private key for client: %s' % self.client
         # create new profile and set all properties
         tai = Document.create(doc_type=Document.VISA, identifier=identifier)
         for key in profile:
             tai.set_property(key, profile.get(key))
         tai.sign(private_key=private_key)
         cmd = DocumentCommand.response(identifier=identifier, document=tai)
     else:
         cmd = DocumentCommand.query(identifier=identifier)
     self.client.send_command(cmd=cmd)
Beispiel #3
0
    def check_document(self, document: Document) -> bool:
        """
        Checking document

        :param document: entity document
        :return: True on accepted
        """
        identifier = document.identifier
        if identifier is None:
            return False
        # NOTICE: if this is a group profile,
        #             verify it with each member's meta.key
        #         else (this is a user profile)
        #             verify it with the user's meta.key
        if identifier.is_group:
            # check by each member
            members = self.members(identifier=identifier)
            if members is not None:
                for item in members:
                    meta = self.meta(identifier=item)
                    if meta is None:
                        # FIXME: meta not found for this member
                        continue
                    if document.verify(public_key=meta.key):
                        return True
            # DISCUSS: what to do about assistants?

            # check by owner
            owner = self.owner(identifier=identifier)
            if owner is None:
                if identifier.type == NetworkType.POLYLOGUE:
                    # NOTICE: if this is a polylogue profile
                    #             verify it with the founder's meta.key
                    #             (which equals to the group's meta.key)
                    meta = self.meta(identifier=identifier)
                else:
                    # FIXME: owner not found for this group
                    return False
            elif owner in members:
                # already checked
                return False
            else:
                meta = self.meta(identifier=owner)
        else:
            meta = self.meta(identifier=identifier)
        if meta is not None:
            return document.verify(public_key=meta.key)
Beispiel #4
0
def register_document_factories():
    Document.register(doc_type='*',
                      factory=GeneralDocumentFactory(doc_type='*'))
    Document.register(doc_type=Document.VISA,
                      factory=GeneralDocumentFactory(doc_type=Document.VISA))
    Document.register(
        doc_type=Document.PROFILE,
        factory=GeneralDocumentFactory(doc_type=Document.PROFILE))
    Document.register(
        doc_type=Document.BULLETIN,
        factory=GeneralDocumentFactory(doc_type=Document.BULLETIN))
Beispiel #5
0
 def save_document(self, document: Document) -> bool:
     if not document.valid:
         identifier = document.identifier
         if identifier is None:
             return False
         meta = self.meta(identifier=identifier)
         if meta is None:
             return False
         if not document.verify(public_key=meta.key):
             return False
     return self.__document_table.save_document(document=document)
Beispiel #6
0
def load_station(identifier: Union[ID, str], facebook: CommonFacebook) -> Station:
    """ Load station info from 'etc' directory

        :param identifier - station ID
        :param facebook - social network data source
        :return station with info from 'dims/etc/{address}/*'
    """
    identifier = ID.parse(identifier=identifier)
    # check meta
    meta = facebook.meta(identifier=identifier)
    if meta is None:
        # load from 'etc' directory
        meta = Meta.parse(meta=load_station_info(identifier=identifier, filename='meta.js'))
        if meta is None:
            raise LookupError('failed to get meta for station: %s' % identifier)
        elif not facebook.save_meta(meta=meta, identifier=identifier):
            raise ValueError('meta error: %s' % meta)
    # check private key
    private_key = facebook.private_key_for_signature(identifier=identifier)
    if private_key is None:
        # load from 'etc' directory
        private_key = PrivateKey.parse(key=load_station_info(identifier=identifier, filename='secret.js'))
        if private_key is None:
            pass
        elif not facebook.save_private_key(key=private_key, identifier=identifier):
            raise AssertionError('failed to save private key for ID: %s, %s' % (identifier, private_key))
    # check profile
    profile = load_station_info(identifier=identifier, filename='profile.js')
    if profile is None:
        raise LookupError('failed to get profile for station: %s' % identifier)
    Log.info('station profile: %s' % profile)
    name = profile.get('name')
    host = profile.get('host')
    port = profile.get('port')
    # create station
    if private_key is None:
        # remote station
        station = Station(identifier=identifier, host=host, port=port)
    else:
        # create profile
        profile = Document.create(doc_type=Document.PROFILE, identifier=identifier)
        profile.set_property('name', name)
        profile.set_property('host', host)
        profile.set_property('port', port)
        profile.sign(private_key=private_key)
        if not facebook.save_document(document=profile):
            raise AssertionError('failed to save profile: %s' % profile)
        # local station
        station = Station(identifier=identifier, host=host, port=port)
    facebook.cache_user(user=station)
    Log.info('station loaded: %s' % station)
    return station
Beispiel #7
0
 def is_expired_document(self,
                         document: Document,
                         reset: bool = True) -> bool:
     # check expired time
     now = time.time()
     expires = document.get(self.EXPIRES_KEY)
     if expires is None:
         # set expired time
         document[self.EXPIRES_KEY] = now + self.EXPIRES
         return False
     if now > expires:
         if reset:
             # update expired time
             document[self.EXPIRES_KEY] = now + self.EXPIRES
         return True
Beispiel #8
0
def load_user(identifier: str, facebook: CommonFacebook) -> User:
    identifier = ID.parse(identifier=identifier)
    # check meta
    try:
        meta = facebook.meta(identifier=identifier)
    except AssertionError:
        meta = None
    if meta is None:
        # load from 'etc' directory
        meta = Meta.parse(meta=load_robot_info(identifier=identifier, filename='meta.js'))
        if meta is None:
            raise LookupError('failed to get meta for robot: %s' % identifier)
        elif not facebook.save_meta(meta=meta, identifier=identifier):
            raise ValueError('meta error: %s' % meta)
    # check private key
    private_key = facebook.private_key_for_signature(identifier=identifier)
    if private_key is None:
        # load from 'etc' directory
        private_key = PrivateKey.parse(key=load_robot_info(identifier=identifier, filename='secret.js'))
        if private_key is None:
            raise AssertionError('private key not found for ID: %s' % identifier)
        elif not facebook.save_private_key(key=private_key, identifier=identifier):
            raise AssertionError('failed to save private key for ID: %s, %s' % (identifier, private_key))
    # check profile
    profile = load_robot_info(identifier=identifier, filename='profile.js')
    if profile is None:
        raise LookupError('failed to get profile for robot: %s' % identifier)
    Log.info('robot profile: %s' % profile)
    name = profile.get('name')
    avatar = profile.get('avatar')
    # create profile
    profile = Document.create(doc_type=Document.VISA, identifier=identifier)
    profile.set_property('name', name)
    profile.set_property('avatar', avatar)
    profile.sign(private_key=private_key)
    if not facebook.save_document(document=profile):
        raise AssertionError('failed to save profile: %s' % profile)
    # create local user
    return facebook.user(identifier=identifier)
Beispiel #9
0
 def __load_profile(self, filename: str) -> Optional[Document]:
     profile = Document.parse(document=load_resource_file(
         filename=filename))
     assert profile is not None, 'failed to load profile: %s' % filename
     # copy 'name'
     name = profile.get('name')
     if name is None:
         names = profile.get('names')
         if names is not None and len(names) > 0:
             profile.set_property('name', names[0])
     else:
         profile.set_property('name', name)
     # copy 'avatar'
     avatar = profile.get('avatar')
     if avatar is None:
         photos = profile.get('photos')
         if photos is not None and len(photos) > 0:
             profile.set_property('avatar', photos[0])
     else:
         profile.set_property('avatar', avatar)
     # sign
     self.__sign_profile(profile=profile)
     return profile
 def document(self, identifier: ID, doc_type: Optional[str]='*') -> Optional[Document]:
     # 1. try from memory cache
     info = self.__caches.get(identifier)
     if info is None:
         # 2. try from local storage
         path = self.__path(identifier=identifier)
         self.info('Loading document from: %s' % path)
         dictionary = self.read_json(path=path)
         if dictionary is not None:
             data = dictionary.get('data')
             if data is None:
                 # compatible with v1.0
                 data = dictionary.get('profile')
             signature = dictionary.get('signature')
             info = Document.create(doc_type=doc_type, identifier=identifier, data=data, signature=signature)
         if info is None:
             # 2.1. place an empty meta for cache
             info = self.__empty
         # 3. store into memory cache
         self.__caches[identifier] = info
     if info is not self.__empty:
         return info
     self.info('document not found: %s' % identifier)
Beispiel #11
0
 def is_empty_document(document: Document) -> bool:
     if document is None:
         return True
     json = document.get('data')
     return json is None or len(json) == 0
Beispiel #12
0
 def __sign_profile(self, profile: Document) -> bytes:
     identifier = profile.identifier
     key = self.private_key_for_signature(identifier)
     if key is not None:
         return profile.sign(private_key=key)