示例#1
0
    def test_generate_change_token_ok(self) -> None:
        """ Test the function that generates a change token, with a success case for DELETION. """

        # The expected result
        expected_expiration_date = datetime.datetime.today().replace(
            microsecond=0) + datetime.timedelta(days=5)

        expected_type = 'DELETION'

        # Prepare the mocks
        configuration.DELETION_TOKEN_VALIDITY_DAYS = 5

        # Call the function
        actual_result = authentication.generate_change_token(
            123, authentication.TokenType.DELETION,
            {'extra_key': 'extra_value'})

        # Verify the result
        self.assertIsNotNone(actual_result)
        db_calls_mock.register_token.assert_not_called()

        # Verify the date
        actual_expiration_date = datetime.datetime.fromtimestamp(
            authentication.get_token_field(actual_result, 'exp'))
        self.assertEqual(expected_expiration_date, actual_expiration_date)

        # Verify the other fields exist
        self.assertEqual(expected_type,
                         authentication.get_token_field(actual_result, 'type'))
        self.assertEqual(123,
                         authentication.get_token_field(actual_result, 'user'))
        self.assertEqual(
            'extra_value',
            authentication.get_token_field(actual_result, 'extra_key'))
示例#2
0
    def test_generate_token_ok_01(self) -> None:
        """ Test the function that generates a token, with a success case for REFRESH. """

        # The expected result
        expected_expiration_date = datetime.datetime.today().replace(
            microsecond=0) + datetime.timedelta(days=5)

        expected_type = 'REFRESH'

        # Prepare the mocks
        token_payload = {'key': 'value'}
        token = jwt.encode(token_payload, 'secret key', algorithm='HS256')

        configuration.REFRESH_TOKEN_VALIDITY_DAYS = 5
        db_calls_mock.register_token.return_value = models.Token(
            token, expected_expiration_date.date())

        # Call the function
        actual_result = authentication.generate_token(
            1, authentication.TokenType.REFRESH, unittest.mock.MagicMock())

        # Verify the result
        self.assertIsNotNone(actual_result)
        db_calls_mock.register_token.assert_called()

        # Verify the date
        actual_expiration_date = datetime.datetime.fromtimestamp(
            authentication.get_token_field(actual_result, 'exp'))
        self.assertEqual(expected_expiration_date, actual_expiration_date)

        # Verify the other fields exist
        self.assertEqual(expected_type,
                         authentication.get_token_field(actual_result, 'type'))
        self.assertEqual(1,
                         authentication.get_token_field(actual_result, 'user'))
示例#3
0
    def post(self, args):
        """Send settings email."""

        with session_scope() as session:
            token = flask.request.headers.environ['HTTP_AUTHORIZATION'][7:]
            email_type = args['type']

            # Get the user id from the token
            user_id = authentication.get_token_field(token.encode(), 'user')

            # If it is a user's deletion email request
            if email_type == SendEmailEP.EmailType.DELETION.name:
                if processing.send_deletion_email(session, user_id):
                    return flask.make_response('', 200)
                else:
                    return flask.make_response('', 400)

            # If it is an email change email request
            elif email_type == SendEmailEP.EmailType.CHANGE_OLD.name:
                if processing.send_change_email_old(session, user_id):
                    return flask.make_response('', 200)
                else:
                    return flask.make_response('', 400)

            # If something else is sent
            else:
                return flask.make_response('', 400)
示例#4
0
    def put(self, args):
        """Update a reminder."""

        reminder_id = args['reminder_id']
        anticipation_minutes = args['anticipation_minutes']

        with session_scope() as session:
            # Get the user id from the token
            token = flask.request.headers.environ['HTTP_AUTHORIZATION'][7:]
            user_id = authentication.get_token_field(token.encode(), 'user')

            success, msg = reminders.update_reminder(session, reminder_id,
                                                     anticipation_minutes,
                                                     user_id)

            if success:
                return flask.make_response(
                    flask.jsonify({
                        'reminder_list':
                        auxiliary.list_to_json(
                            reminders.get_reminders(session, user_id))
                    }), 201)
            else:
                if msg == 'Not found':
                    return flask.make_response('', 404)
                else:
                    return flask.make_response(msg, 400)
示例#5
0
    def test_get_token_field_error_01(self) -> None:
        """ Test the function that returns a field in the payload of a token, with an error due to invalid token. """

        # The expected result
        expected_result = None

        # Call the function
        token = 'secret string'.encode()
        actual_result = authentication.get_token_field(token, 'key')

        # Verify the result
        self.assertEqual(expected_result, actual_result)
示例#6
0
    def post(self, args):
        """Register an alarm."""

        show_name = args['show_name']
        is_movie = args['is_movie']
        alarm_type = args['type']
        trakt_id = None
        show_season = None
        show_episode = None

        for k, v in args.items():
            if v is None:
                continue

            if k == 'show_season':
                show_season = v
            elif k == 'show_episode':
                show_episode = v
            elif k == 'trakt_id':
                trakt_id = v

        with session_scope() as session:
            try:
                alarm_type = AlarmType[alarm_type]
            except KeyError:
                return flask.make_response('Invalid Alarm Type', 400)

            # Alarms for Listings are no longer valid
            if alarm_type == AlarmType.LISTINGS:
                return flask.make_response('Invalid Alarm Type', 400)

            if alarm_type == AlarmType.DB and trakt_id is None:
                return flask.make_response('Missing Trakt Id', 400)

            if not is_movie and (show_season is None or show_episode is None):
                return flask.make_response('Missing Season Episode', 400)

            # Get the user id from the token
            token = flask.request.headers.environ['HTTP_AUTHORIZATION'][7:]
            user_id = authentication.get_token_field(token.encode(), 'user')

            if db_calls.register_alarm(session, show_name, trakt_id, is_movie,
                                       alarm_type, show_season, show_episode,
                                       user_id) is not None:
                return flask.make_response(
                    flask.jsonify({
                        'alarm_list':
                        auxiliary.list_to_json(
                            processing.get_alarms(session, user_id))
                    }), 201)
            else:
                return flask.make_response('Alarm Already Exists', 400)
示例#7
0
    def get(self):
        """Get the list of alarms of the user."""

        with session_scope() as session:
            # Get the user id from the token
            token = flask.request.headers.environ['HTTP_AUTHORIZATION'][7:]
            user_id = authentication.get_token_field(token.encode(), 'user')

            alarms = processing.get_alarms(session, user_id)

            return flask.make_response(
                flask.jsonify({'alarm_list': auxiliary.list_to_json(alarms)}),
                200)
示例#8
0
    def put(self, args):
        """Change user's settings, that don't require anything."""

        include_adult_channels = None
        language = None
        excluded_channel_list = None

        for k, v in args.items():
            if v is None:
                continue

            if k == 'include_adult_channels':
                include_adult_channels = v
            elif k == 'language':
                language = v
            elif k == 'excluded_channel_list':
                excluded_channel_list = v

        with session_scope() as session:
            # Get the user id from the token
            token = flask.request.headers.environ['HTTP_AUTHORIZATION'][7:]
            user_id = authentication.get_token_field(token.encode(), 'user')

            changes = {}

            # Update include_adult_channels
            if include_adult_channels is not None:
                changes[ChangeType.INCLUDE_ADULT_CHANNELS.
                        value] = include_adult_channels

            # Update language
            if language is not None and language in configuration.AVAILABLE_LANGUAGES:
                changes[ChangeType.LANGUAGE.value] = language

            # Update excluded channel list
            if excluded_channel_list is not None:
                changes[
                    ChangeType.EXCLUDED_CHANNELS.value] = excluded_channel_list

            # If there are changes to be made
            if changes != {}:
                if processing.change_user_settings(session, changes, user_id):
                    return flask.make_response(
                        flask.jsonify(processing.get_settings(
                            session, user_id)), 200)
                else:
                    return flask.make_response('', 400)

            # If there are no changes to be made
            else:
                return flask.make_response('Invalid Parameters', 400)
示例#9
0
    def get(self):
        """Get the user's settings, that don't require anything."""

        with session_scope() as session:
            # Get the user id from the token
            token = flask.request.headers.environ['HTTP_AUTHORIZATION'][7:]
            user_id = authentication.get_token_field(token.encode(), 'user')

            settings = processing.get_settings(session, user_id)

            if settings != {}:
                return flask.make_response(flask.jsonify(settings), 200)
            else:
                return flask.make_response('', 404)
示例#10
0
    def test_get_token_field_error_02(self) -> None:
        """ Test the function that returns a field in the payload of a token, with an error due to invalid field. """

        # The expected result
        expected_result = None

        # Call the function
        token_payload = {'key': 'value'}

        token = jwt.encode(token_payload, 'secret key', algorithm='HS256')

        actual_result = authentication.get_token_field(token, 'invalid key')

        # Verify the result
        self.assertEqual(expected_result, actual_result)
示例#11
0
    def test_generate_access_token_ok(self) -> None:
        """ Test the function that generates an access token, with a success case. """

        # The expected result
        expected_expiration_date = datetime.datetime.today().replace(
            microsecond=0) + datetime.timedelta(hours=10)

        expected_type = 'ACCESS'

        # Prepare the mocks
        configuration.REFRESH_TOKEN_VALIDITY_DAYS = 5
        configuration.ACCESS_TOKEN_VALIDITY_HOURS = 10

        refresh_token = authentication.generate_token(
            123, authentication.TokenType.REFRESH, unittest.mock.MagicMock())
        db_calls_mock.register_token.return_value = models.Token(
            refresh_token, expected_expiration_date.date())

        # Call the function
        actual_result, actual_token = authentication.generate_access_token(
            unittest.mock.MagicMock(), refresh_token)

        # Verify the result
        self.assertTrue(actual_result)
        self.assertIsNotNone(actual_token)

        # Verify the date
        actual_expiration_date = datetime.datetime.fromtimestamp(
            authentication.get_token_field(actual_token, 'exp'))
        self.assertEqual(expected_expiration_date, actual_expiration_date)

        # Verify the other fields exist
        self.assertEqual(expected_type,
                         authentication.get_token_field(actual_token, 'type'))
        self.assertEqual(123,
                         authentication.get_token_field(actual_token, 'user'))
示例#12
0
    def get(self, args):
        """Get search results for the search_text, using the Trakt API."""

        search_text = args['search_text']
        language = args['language']
        is_movie = None

        for k, v in args.items():
            if v is None:
                continue

            if k == 'is_movie':
                is_movie = v

        if len(search_text) < 2:
            return flask.make_response('Search Text Too Small', 400)

        with session_scope() as session:
            search_adult = False

            # Get the user settings of whether it should look in channels with adult content or not
            if 'HTTP_AUTHORIZATION' in flask.request.headers.environ:
                token = flask.request.headers.environ['HTTP_AUTHORIZATION'][7:]
                user_id = authentication.get_token_field(
                    token.encode(), 'user')

                user = db_calls.get_user_id(session, user_id)
                search_adult = user.show_adult if user is not None else False

            if search_text[0] == '"' and search_text[-1] == '"':
                search_text = search_text[1:-1]
                exact_name = True
            else:
                exact_name = False

            more_results, shows = processing.search_show_information(
                session, search_text, is_movie, language, search_adult,
                exact_name)

            response_dict = {'show_list': shows}

            # Add a remark when there are more results than those on the response
            if more_results and not exact_name:
                response_dict['remark'] = 'Incomplete List'

            return flask.make_response(flask.jsonify(response_dict), 200)
示例#13
0
    def delete(self, args):
        """Delete a alarm."""

        alarm_id = args['alarm_id']

        with session_scope() as session:
            # Get the user id from the token
            token = flask.request.headers.environ['HTTP_AUTHORIZATION'][7:]
            user_id = authentication.get_token_field(token.encode(), 'user')

            processing.remove_alarm(session, alarm_id, user_id)

            return flask.make_response(
                flask.jsonify({
                    'alarm_list':
                    auxiliary.list_to_json(
                        processing.get_alarms(session, user_id))
                }), 200)
示例#14
0
def send_change_email_new(session, change_token_old: str,
                          new_email: str) -> (bool, bool):
    """
    Send a 'Change Email' email to the new email address.

    :param session: the db session.
    :param change_token_old: the change token from the old email address.
    :param new_email: the new email.
    :return: a pair of booleans: the first is the success of the operation and the second is if the motif of the failure
    is that the new email is already at use.
    """

    # Validate the change token from the old email address
    valid, user_id = authentication.validate_token(
        change_token_old.encode(), authentication.TokenType.CHANGE_EMAIL_OLD)

    if not valid:
        return False, False

    # Get the user id from the token
    user_id = authentication.get_token_field(change_token_old.encode(), 'user')

    # Get user
    user = session.query(models.User).filter(models.User.id == user_id).first()

    if user is None:
        return False, False

    # Check if the new email is valid
    new_email_user = session.query(
        models.User).filter(models.User.email == new_email).first()

    if new_email_user is not None:
        return False, True

    changes = {ChangeType.NEW_EMAIL.value: new_email}
    change_email_new_token = authentication.generate_change_token(
        user.id, authentication.TokenType.CHANGE_EMAIL_NEW, changes).decode()

    process_emails.set_language(user.language)
    return process_emails.send_change_email_new(new_email,
                                                change_email_new_token,
                                                user.email), True
示例#15
0
    def put(self, args):
        """Change user's settings, that require the password to be sent."""

        password = args['password']

        new_password = None

        for k, v in args.items():
            if v is None:
                continue

            if k == 'new_password':
                new_password = v

        with session_scope() as session:
            # Get the user id from the token
            token = flask.request.headers.environ['HTTP_AUTHORIZATION'][7:]
            user_id = authentication.get_token_field(token.encode(), 'user')

            user = db_calls.get_user_id(session, user_id)

            # Check if the password is valid
            valid = verify_login_credentials(user.email, password)

            if not valid:
                return flask.make_response('Unauthorized Access',
                                           403)  # Should be 503

            # Update new_password
            if new_password is not None:
                if password == new_password:
                    return flask.make_response('Same Password', 400)

                if processing.change_user_settings(
                        session, {ChangeType.NEW_PASSWORD.value: new_password},
                        user_id):
                    return flask.make_response('', 200)
                else:
                    return flask.make_response('', 400)

            # No parameters
            else:
                return flask.make_response('Missing Parameter', 400)
示例#16
0
    def delete(self, args):
        """Delete a reminder."""

        reminder_id = args['reminder_id']

        with session_scope() as session:
            # Get the user id from the token
            token = flask.request.headers.environ['HTTP_AUTHORIZATION'][7:]
            user_id = authentication.get_token_field(token.encode(), 'user')

            if db_calls.delete_reminder(session, reminder_id, user_id):
                return flask.make_response(
                    flask.jsonify({
                        'reminder_list':
                        auxiliary.list_to_json(
                            reminders.get_reminders(session, user_id))
                    }), 200)
            else:
                return flask.make_response('', 404)
示例#17
0
    def put(self, args):
        """Update an alarm."""

        alarm_id = args['alarm_id']
        show_season = args['show_season']
        show_episode = args['show_episode']

        with session_scope() as session:
            # Get the user id from the token
            token = flask.request.headers.environ['HTTP_AUTHORIZATION'][7:]
            user_id = authentication.get_token_field(token.encode(), 'user')

            if processing.update_alarm(session, alarm_id, show_season,
                                       show_episode, user_id):
                return flask.make_response(
                    flask.jsonify({
                        'alarm_list':
                        auxiliary.list_to_json(
                            processing.get_alarms(session, user_id))
                    }), 201)
            else:
                return flask.make_response('', 404)
示例#18
0
    def post(self, args):
        """Register a reminder."""

        show_session_id = args['show_session_id']
        anticipation_minutes = args['anticipation_minutes']

        with session_scope() as session:
            # Get the user id from the token
            token = flask.request.headers.environ['HTTP_AUTHORIZATION'][7:]
            user_id = authentication.get_token_field(token.encode(), 'user')

            if reminders.register_reminder(session, show_session_id,
                                           anticipation_minutes,
                                           user_id) is not None:
                return flask.make_response(
                    flask.jsonify({
                        'reminder_list':
                        auxiliary.list_to_json(
                            reminders.get_reminders(session, user_id))
                    }), 201)
            else:
                return flask.make_response('Invalid reminder', 400)
示例#19
0
    def get(self, args):
        """Get search results for the search_text or the show_id, in the listings and streaming services."""

        search_text = None
        show_id = None
        is_movie = None

        for k, v in args.items():
            if v is None:
                continue

            if k == 'search_text':
                search_text = v.strip()

            if k == 'show_id':
                show_id = v

            if k == 'is_movie':
                is_movie = v

        if search_text is None and show_id is None:
            return flask.make_response('Invalid request', 400)

        with session_scope() as session:
            search_adult = False

            # Get the user settings of whether it should look in channels with adult content or not
            if 'HTTP_AUTHORIZATION' in flask.request.headers.environ:
                token = flask.request.headers.environ['HTTP_AUTHORIZATION'][7:]
                user_id = authentication.get_token_field(
                    token.encode(), 'user')

                user = db_calls.get_user_id(session, user_id)
                search_adult = user.show_adult if user is not None else False

            # Check whether it is a request by id or by text
            if show_id is not None:
                if is_movie is None:
                    return flask.make_response('Invalid request', 400)

                titles = processing.get_show_titles(session, show_id, is_movie)

                db_shows = processing.search_sessions_db_with_tmdb_id(
                    session, show_id, is_movie)
            else:
                if len(search_text) < 2:
                    return flask.make_response('Search Text Too Small', 400)

                titles = [search_text]

                db_shows = []

            # If it is a search with id
            # - we only want exact title matches
            # - for those results that don't have a TMDB id
            complete_title = show_id is not None
            ignore_with_tmdb_id = show_id is not None

            # db_shows += processing.search_streaming_services_shows_db(session, titles, is_movie=is_movie,
            #                                                          complete_title=complete_title,
            #                                                          search_adult=search_adult,
            #                                                          ignore_with_tmdb_id=ignore_with_tmdb_id)

            db_shows += processing.search_sessions_db(
                session,
                titles,
                is_movie=is_movie,
                complete_title=complete_title,
                search_adult=search_adult,
                ignore_with_tmdb_id=ignore_with_tmdb_id)

            response_dict = {'show_list': auxiliary.list_to_json(db_shows)}

            show_dict = {}

            # If it is a search by id, add information on the premiere of the show
            if show_id is not None:
                show = db_calls.get_show_data_by_tmdb_id(
                    session, show_id, is_movie)

                if show is not None:
                    if show.premiere_date is not None:
                        show_dict['premiere_date'] = show.premiere_date

                        if show.season_premiere is not None:
                            show_dict['season_premiere'] = show.season_premiere

            response_dict['show'] = show_dict

            return flask.make_response(flask.jsonify(response_dict), 200)