Exemplo n.º 1
0
class ProfileResource(Resource):
    def __init__(self):
        self.logger = Logger(__name__)

    def get(self, username):
        try:
            # get token from header
            token = self._get_token_from_header()

            # identify with token
            callee_user = Token.identify(token)

            # get profile info from user username
            profile = User.get_profile(username, callee_user)

            # generate response
            self.logger.info('User profile found for: {}'.format(username))
            output = profile

            # return response
            return ResponseBuilder.build_response(output)

        except UserNotFoundException as e:
            err_msg = "No user found with that name"
            self.logger.info(err_msg)
            return ResponseBuilder.build_error_response(err_msg, e.error_code)
        except (ExpiredTokenException, MissingFieldException,
                InvalidTokenException) as e:
            return ResponseBuilder.build_error_response(
                e.message, e.error_code)

    def _get_token_from_header(self):
        return RequestBuilder.get_field_from_header('token')
Exemplo n.º 2
0
    def get_feed_for_username(username):
        Logger(__name__).info('Getting feed for user {}.'.format(username))

        # get all stories by iterating over usernames, use username to filter private, non-friend ones
        stories_feed_data = User.get_feed_data(username)

        Logger(__name__).info(
            'Prioritizing {} stories for user {}\'s feed.'.format(
                len(stories_feed_data), username))

        # calculate priorities
        for story_feed_data in stories_feed_data:
            set_score(story_feed_data, INITIAL_SCORE)

            run_all(rule_list=rules,
                    stop_on_first_trigger=False,
                    defined_actions=StoryActions(story_feed_data),
                    defined_variables=StoryVariables(story_feed_data))

        prioritized_stories = [
            story_feed_data['story_id']
            for story_feed_data in sorted(stories_feed_data,
                                          key=lambda sfd: get_score(sfd),
                                          reverse=True)
        ]

        Logger(__name__).info('Serving feed for user {}.'.format(username))
        # get stories in according order, add feed-specific fields of user's name and profile pic
        return [
            FeedBuilder._format_feed_story(story_id)
            for story_id in prioritized_stories
        ]
Exemplo n.º 3
0
class PingResource(Resource):

    def __init__(self):
        self.logger = Logger(__name__)

    def get(self):
        self.logger.debug('Pinged.')
        return ResponseBuilder.build_response({}, status_code=200)
Exemplo n.º 4
0
 def sanitize_story_reaction(input_data):
     input_data = input_data.lower()
     if input_data in ALLOWED_STORY_REACTIONS:
         Logger(__name__).info(
             'Input {} successfully recognized as a story reaction.'.format(
                 str(input_data)))
         return input_data
     Logger(__name__).info(
         'Input {} not recognized as a story reaction.'.format(
             str(input_data)))
     raise InvalidFormatException(input_data, "story reaction")
Exemplo n.º 5
0
class LoginResource(Resource):
    def __init__(self):
        self.logger = Logger(__name__)
        self.shared_server_service = SharedServerService()

    def post(self):
        try:
            # get data from request
            user_data = {}
            user_data['username'] = self._get_username_from_request()
            user_data['password'] = self._get_password_from_request()
            self.logger.info('User data generated. ({})'.format(user_data))

            # validate data

            # ask shared server for authentication service
            output_dict = self.shared_server_service.get_new_token(user_data)

            # save token in application server for future use
            Token.save_new(username=user_data['username'],
                           token=output_dict['token'],
                           expiration_epochs=output_dict['expiresAt'])

            assert (Token.identify(
                output_dict['token']) == user_data['username']
                    )  # confirm it's all good

            # generate response
            response = {
                'username': user_data['username'],
                'token': output_dict
            }
            self.logger.info(
                'Token received from service. ({})'.format(response))

            # return response
            return ResponseBuilder.build_response(response)

        except MissingFieldException as mfe:
            return ResponseBuilder.build_error_response(str(mfe), 400)
        except InvalidDataException as ide:
            return ResponseBuilder.build_error_response(str(ide), 400)
        except NoServerException as nse:
            return ResponseBuilder.build_error_response(str(nse), 500)
        except UnexpectedErrorException as uee:
            return ResponseBuilder.build_error_response(str(uee), 500)
        except ConnectionFailException as cfe:
            return ResponseBuilder.build_error_response(str(cfe), 500)

    def _get_username_from_request(self):
        return RequestBuilder.get_field_from_request('username')

    def _get_password_from_request(self):
        return RequestBuilder.get_field_from_request('password')
Exemplo n.º 6
0
 def __init__(self):
     self.success_codes = [200, 201, 204]
     self.logger = Logger(__name__)
     my_file = Path('config.cfg')
     if my_file.is_file():
         parser = ConfigParser()
         file = open('config.cfg')
         parser.read_file(file)
         file.close()
         self.host = parser.get('shared_server', 'host')
     else:
         self.host = 'https://picappss.herokuapp.com'
Exemplo n.º 7
0
 def sanitize_integer(input_data):
     try:
         sanitized_data = int(input_data)
         Logger(__name__).info(
             'Input {} successfully recognized as an integer.'.format(
                 str(input_data)))
         return sanitized_data
     except ValueError:
         Logger(__name__).info(
             'Input {} not recognized as an integer.'.format(
                 str(input_data)))
         raise InvalidFormatException(input_data, "integer")
Exemplo n.º 8
0
    def _delete_friendship_in(origin_username, destiny_username):
        Logger(__name__).info('Deleting Friendship state in {}: {}.'.format(
            origin_username, destiny_username))

        entry = "friends." + destiny_username
        new_origin = User._delete_field_by_username(origin_username,
                                                    {entry: ""})

        Logger(__name__).info(
            'Friendship state in {}: {} is now deleted.'.format(
                origin_username, destiny_username))
        return new_origin
Exemplo n.º 9
0
 def sanitize_boolean(input_data):
     if input_data in ['true', 'True', True]:
         Logger(__name__).info(
             'Input {} recognized as boolean True.'.format(str(input_data)))
         return True
     if input_data in ['false', 'False', False]:
         Logger(__name__).info(
             'Input {} recognized as boolean False.'.format(
                 str(input_data)))
         return False
     Logger(__name__).info('Input {} not recognized as a boolean.'.format(
         str(input_data)))
     raise InvalidFormatException(input_data, "boolean")
Exemplo n.º 10
0
    def _change_friendship_in_to(origin_username, destiny_username,
                                 new_friendship_state):
        Logger(__name__).info(
            'Changing Friendship state in {}: {} to state {}.'.format(
                origin_username, destiny_username, str(new_friendship_state)))

        entry = "friends." + destiny_username
        new_origin = User._update_user_by_username(
            origin_username, {entry: new_friendship_state})

        Logger(__name__).info(
            'Friendship state in {}: {} is now at state {}.'.format(
                origin_username, destiny_username, str(new_friendship_state)))
        return new_origin
Exemplo n.º 11
0
 def identify(token):
     """Receives a token and looks for it in the database, returning the username of the owner or
     raising an exception if it was not found or had expired"""
     Logger(__name__).info('Looking for token {}'.format(token))
     tk = Token._find_token(int(token))
     if tk is None:
         Logger(__name__).info("Token {} not found".format(token))
         raise InvalidTokenException
     if Token._get_current_epochs() > tk['expiresAt']:
         Logger(__name__).info(
             "Token {} was found but it had expired".format(token))
         raise ExpiredTokenException
     Logger(__name__).info("Token {} found".format(token))
     return tk['username']
Exemplo n.º 12
0
 def save_new(token, expiration_epochs, username):
     """Saves to DB a newly created Token with expiration date (in epochs) associated
     with a user"""
     tk = Token._get_tokens_db().find_one({'username': username})
     new_token_id = Token._create_token(token, expiration_epochs, username)
     Logger(__name__).info('Token {} stored for user {}, with id {}'.format(
         token, username, new_token_id))
     # enforce only one active session
     if tk is not None:
         Logger(__name__).info(
             'Old token ({}) removed for user ({}).'.format(
                 token, username))
         Token._get_tokens_db().remove({'_id': tk['_id']})
     return new_token_id
Exemplo n.º 13
0
 def _delete_field_by_username(username, deleted_param_dict):
     Logger(__name__).info(
         'Deleting fields of user {} with value {}'.format(
             username, deleted_param_dict))
     return Persistence.unset_on_one(User._get_coll(),
                                     {'username': username},
                                     deleted_param_dict)
Exemplo n.º 14
0
    def wants_to_not_be_friends_with(origin_username, destiny_username):
        """Declares an intention from origin to not be friends with destiny, being that a rejection
        of a previously received friendship request or the deletion of an existing friendship.
        Returns a FriendshipState which can be request_received or friends depending on the previous
        state."""
        Logger(__name__).info(
            'Username {} wants to NOT be friends with {}.'.format(
                origin_username, destiny_username))
        # retrieve the DB user representations
        origin_user = User._get_one({'username': origin_username})
        destiny_user = User._get_one({'username': destiny_username})

        # if one of them was not found raise exception
        if origin_user is None or destiny_user is None:
            raise UserNotFoundException

        # if origin doesnt know destiny or origin was the one requesting raise exception
        if destiny_username not in origin_user['friends'] or \
                origin_user['friends'][destiny_username] == FRIENDSHIP_STATE_SENT:
            raise NotFriendsException

        # if here they were already friends or destiny had sent request to origin, so delete
        assert Friendship._are_friends(origin_username, destiny_username) or \
            Friendship._had_sent_request(destiny_username, origin_username)

        return Friendship._reject_friendship(origin_username, destiny_username)
Exemplo n.º 15
0
    def wants_to_be_friends_with(origin_username, destiny_username):
        """Declares an intention from origin to be friends with destiny, sending a request to
        destiny or confirming the relation if the inverse had been previously stated.
        Returns a FriendshipState which can be request_sent or friends depending on the previous."""
        Logger(__name__).info(
            'Username {} wants to be friends with {}.'.format(
                origin_username, destiny_username))
        # retrieve the DB user representations
        origin_user = User._get_one({'username': origin_username})
        destiny_user = User._get_one({'username': destiny_username})

        # if one of them was not found raise exception
        if origin_user is None or destiny_user is None:
            raise UserNotFoundException

        # if destiny had NOT already wanted to be friends with origin
        if origin_username not in destiny_user['friends']:
            return Friendship._send_request_from_to(origin_username,
                                                    destiny_username)

        # if destiny is already friends with origin
        if Friendship._are_friends(origin_username, destiny_username):
            raise AlreadyFriendsException

        # only other cases are: invitation already sent or needed confirmation
        # and this first case should not be possible
        assert _user(destiny_username
                     )['friends'][origin_username] == FRIENDSHIP_STATE_SENT
        assert _user(origin_username)['friends'][
            destiny_username] == FRIENDSHIP_STATE_RECEIVED

        # so now it should be confirmed
        return Friendship._confirm_friends(origin_username, destiny_username)
Exemplo n.º 16
0
 def delete_comment(comment_id):
     """Delete the comment identified by comment_id."""
     Logger(__name__).info("Deleting comment id {}".format(comment_id))
     deleted_comment = StoryComment._delete_one(comment_id)
     if deleted_comment is None:
         raise StoryCommentNotFoundException
     return deleted_comment['_id']
Exemplo n.º 17
0
    def update_one(target_collection, query, updated_param_dict):
        Logger(__name__).debug('Updating one element in collection {} matching query {} with value {}'.format(
            target_collection.name, query, updated_param_dict))

        return target_collection.find_one_and_update(filter=query,
                                                     update={"$set": updated_param_dict},
                                                     return_document=ReturnDocument.AFTER)
Exemplo n.º 18
0
    def get_flash_feed_for_username(username):
        Logger(__name__).info('Getting flash-feed for user {}.'.format(username))

        # retrieve up to 10 flashes per friend
        feed_flashes = User.get_feed_flashes(username, FEED_FLASHES_PER_USER)

        Logger(__name__).info('Serving {} flashes for user {}\'s flash-feed.'.format(
            len(feed_flashes), username))

        # sort by timestamp in descending order and format (add name and profile_pic)
        prioritized_flashes = [FlashFeedBuilder._format_feed_flash(srz_flash) for srz_flash in
                               sorted(feed_flashes, key=lambda ffd: ffd['timestamp'], reverse=True)]

        Logger(__name__).info('Serving flash-feed for user {}.'.format(username))

        return prioritized_flashes
Exemplo n.º 19
0
    def add_item_to_one(target_collection, query, pushed_param_dict):
        Logger(__name__).debug('Pushing to one element of collection {} matching query {} with value {}'.format(
            target_collection.name, query, pushed_param_dict))

        return target_collection.find_one_and_update(filter=query,
                                                     update={"$push": pushed_param_dict},
                                                     return_document=ReturnDocument.AFTER)
Exemplo n.º 20
0
 def get_field_from_request_or_default(key, default_value):
     try:
         return RequestBuilder.get_field_from_request(key)
     except MissingFieldException:
         Logger(__name__).error("Default value returned: {}".format(
             str(default_value)))
         return default_value
Exemplo n.º 21
0
 def _are_friends(username1, username2):
     Logger(__name__).info(
         'Evaluating whether users {} and {} are friends.'.format(
             username1, username2))
     if username2 in _user(username1)['friends'] and \
             _user(username1)['friends'][username2] == FRIENDSHIP_STATE_FRIENDS:
         return True
     return False
Exemplo n.º 22
0
 def get_story(story_id):
     """Get story represented by story_id formatted to be JSON serializable, or raise
      StoryNotFound exception if no story was found"""
     Logger(__name__).info('Looking for story {}.'.format(story_id))
     story = Story._get_one_by_id(story_id)
     if story is None:
         raise StoryNotFoundException
     return Story._serialize_story(story)
Exemplo n.º 23
0
 def get_comment(comment_id):
     """Get comment identified by comment_id or raise StoryCommentNotFoundException if none
     was found."""
     Logger(__name__).info("Retrieving comment id {}".format(comment_id))
     comment_obj = StoryComment._get_one_by_id(comment_id)
     if comment_obj is None:
         raise StoryCommentNotFoundException
     return StoryComment._serialize_comment(comment_obj)
Exemplo n.º 24
0
 def get_flash(flash_id):
     """Get flash represented by flash_id formatted to be JSON serializable, or raise
      FlashNotFoundException exception if no flash was found"""
     Logger(__name__).info('Looking for flash {}.'.format(flash_id))
     flash = Flash._get_one_by_id(flash_id)
     if flash is None:
         raise FlashNotFoundException
     return Flash._serialize_flash(flash)
Exemplo n.º 25
0
 def _had_sent_request(origin_username, destiny_username):
     Logger(__name__).info(
         'Evaluating whether user {} wanted to be friends with {} '
         'beforehand.'.format(origin_username, destiny_username))
     if _user(destiny_username
              )['friends'][origin_username] == FRIENDSHIP_STATE_RECEIVED:
         return True
     return False
Exemplo n.º 26
0
 def react_to_story(story_id, username, sanitized_reaction):
     """React to story represented by story_id as username, with reaction 'reaction'"""
     if Story._get_one_by_id(story_id) is None:
         raise StoryNotFoundException
     updated_story = Story._update_story(
         story_id, {"reactions." + username: sanitized_reaction})
     Logger(__name__).info("User {} has reacted {} to Story_id {}.".format(
         username, sanitized_reaction, story_id))
     return updated_story["reactions"][username]
Exemplo n.º 27
0
 def delete_user(username):
     """Deletes user from the Application Server or raises a UserNotFoundException"""
     user = User._get_one({'username': username})
     if user is None:
         raise UserNotFoundException
     deleted_name = User._safe_delete_user(user)
     Logger(__name__).info(
         "Account for user {} was deleted at User".format(deleted_name))
     return deleted_name
Exemplo n.º 28
0
 def get_friends(username):
     """Returns a list of username friends as profile previews, or raises UserNotFoundException
     if none was found."""
     Logger(__name__).info(
         'Retrieving friends for user {}.'.format(username))
     friend_ids = Friendship._get_friends_of(username)
     return [
         User.get_profile_preview(friend_id) for friend_id in friend_ids
     ]
Exemplo n.º 29
0
    def delete_flash(flash_id):
        """Safely delete flash"""
        Logger(__name__).info("Deleting flash_id {}.".format(flash_id))
        # try to delete it
        deleted_flash = Flash._delete_one(flash_id)
        if deleted_flash is None:
            raise FlashNotFoundException

        return str(deleted_flash['_id'])
Exemplo n.º 30
0
 def change_account_info(username, new_data):
     Logger(__name__).info(
         'Changing account info for user {}.'.format(username))
     User._update_user_by_username(username, new_data)
     new_user_data = {}
     updated_user = _user(username)
     for field in new_data.keys():
         new_user_data[field] = updated_user[field]
     return new_user_data