예제 #1
0
    def post(self):
        passmsg = ""
        msg = ""
        user = User(self.current_user)
        action = self.get_argument("action")
        if action == "profile":
            # tuple of colmns available for profile
            # FORM INPUT NAMES MUST MATCH DB COLUMN NAMES
            form_data = UserProfile()
            form_data.process(data=self.request.arguments)
            profile = {
                name: data[0]
                for name, data in viewitems(form_data.data)
            }

            # Turn default value as list into default strings
            for field in form_data:
                field.data = field.data[0]
            try:
                user.info = profile
                msg = "Profile updated successfully"
            except Exception as e:
                msg = "ERROR: profile could not be updated"
                LogEntry.create('Runtime',
                                "Cound not update profile: %s" % str(e),
                                info={'User': user.id})

        elif action == "password":
            profile = user.info
            oldpass = self.get_argument("oldpass")
            newpass = self.get_argument("newpass")
            try:
                user.change_password(oldpass, newpass)
            except Exception as e:
                passmsg = "ERROR: could not change password"
                LogEntry.create('Runtime',
                                "Cound not change password: %s" % str(e),
                                info={'User': user.id})
            else:
                passmsg = "Password changed successfully"
        self.render("user_profile.html",
                    user=user.id,
                    profile=form_data,
                    msg=msg,
                    passmsg=passmsg)
예제 #2
0
    def post(self):
        passmsg = ""
        msg = ""
        user = User(self.current_user)
        action = self.get_argument("action")
        if action == "profile":
            # tuple of colmns available for profile
            # FORM INPUT NAMES MUST MATCH DB COLUMN NAMES
            form_data = UserProfile()
            form_data.process(data=self.request.arguments)
            profile = {name: data[0] for name, data in
                       viewitems(form_data.data)}

            # Turn default value as list into default strings
            for field in form_data:
                field.data = field.data[0]
            try:
                user.info = profile
                msg = "Profile updated successfully"
            except Exception as e:
                msg = "ERROR: profile could not be updated"
                LogEntry.create('Runtime', "Cound not update profile: %s" %
                                str(e), info={'User': user.id})

        elif action == "password":
            profile = user.info
            oldpass = self.get_argument("oldpass")
            newpass = self.get_argument("newpass")
            try:
                user.change_password(oldpass, newpass)
            except Exception as e:
                passmsg = "ERROR: could not change password"
                LogEntry.create('Runtime', "Cound not change password: %s" %
                                str(e), info={'User': user.id})
            else:
                passmsg = "Password changed successfully"
        self.render("user_profile.html", user=user.id, profile=form_data,
                    msg=msg, passmsg=passmsg)
예제 #3
0
class UserTest(TestCase):
    """Tests the User object and all properties/methods"""

    def setUp(self):
        self.user = User('*****@*****.**')
        self.portal = qiita_config.portal

        self.userinfo = {
            'name': 'Dude',
            'affiliation': 'Nowhere University',
            'address': '123 fake st, Apt 0, Faketown, CO 80302',
            'phone': '111-222-3344',
            'pass_reset_code': None,
            'pass_reset_timestamp': None,
            'user_verify_code': None
        }

    def tearDown(self):
        qiita_config.portal = self.portal

    def test_instantiate_user(self):
        User('*****@*****.**')

    def test_instantiate_unknown_user(self):
        with self.assertRaises(QiitaDBUnknownIDError):
            User('*****@*****.**')

    def _check_correct_info(self, obs, exp):
        self.assertEqual(set(exp.keys()), set(obs.keys()))
        for key in exp:
            # user_verify_code and password seed randomly generated so just
            # making sure they exist and is correct length
            if key == 'user_verify_code':
                self.assertEqual(len(obs[key]), 20)
            elif key == "password":
                self.assertEqual(len(obs[key]), 60)
            else:
                self.assertEqual(obs[key], exp[key])

    def test_create_user(self):
        user = User.create('*****@*****.**', 'password')
        self.assertEqual(user.id, '*****@*****.**')
        sql = "SELECT * from qiita.qiita_user WHERE email = '*****@*****.**'"
        obs = self.conn_handler.execute_fetchall(sql)
        self.assertEqual(len(obs), 1)
        obs = dict(obs[0])
        exp = {
            'password': '',
            'name': None,
            'pass_reset_timestamp': None,
            'affiliation': None,
            'pass_reset_code': None,
            'phone': None,
            'user_verify_code': '',
            'address': None,
            'user_level_id': 5,
            'email': '*****@*****.**'}
        self._check_correct_info(obs, exp)

    def test_create_user_info(self):
        user = User.create('*****@*****.**', 'password', self.userinfo)
        self.assertEqual(user.id, '*****@*****.**')
        sql = "SELECT * from qiita.qiita_user WHERE email = '*****@*****.**'"
        obs = self.conn_handler.execute_fetchall(sql)
        self.assertEqual(len(obs), 1)
        obs = dict(obs[0])
        exp = {
            'password': '',
            'name': 'Dude',
            'affiliation': 'Nowhere University',
            'address': '123 fake st, Apt 0, Faketown, CO 80302',
            'phone': '111-222-3344',
            'pass_reset_timestamp': None,
            'pass_reset_code': None,
            'user_verify_code': '',
            'user_level_id': 5,
            'email': '*****@*****.**'}
        self._check_correct_info(obs, exp)

    def test_create_user_column_not_allowed(self):
        self.userinfo["email"] = "FAIL"
        with self.assertRaises(QiitaDBColumnError):
            User.create('*****@*****.**', 'password', self.userinfo)

    def test_create_user_non_existent_column(self):
        self.userinfo["BADTHING"] = "FAIL"
        with self.assertRaises(QiitaDBColumnError):
            User.create('*****@*****.**', 'password', self.userinfo)

    def test_create_user_duplicate(self):
        with self.assertRaises(QiitaDBDuplicateError):
            User.create('*****@*****.**', 'password')

    def test_create_user_bad_email(self):
        with self.assertRaises(IncorrectEmailError):
            User.create('notanemail', 'password')

    def test_create_user_bad_password(self):
        with self.assertRaises(IncorrectPasswordError):
            User.create('*****@*****.**', '')

    def test_login(self):
        self.assertEqual(User.login("*****@*****.**", "password"),
                         User("*****@*****.**"))

    def test_login_incorrect_user(self):
        with self.assertRaises(IncorrectEmailError):
            User.login("*****@*****.**", "password")

    def test_login_incorrect_password(self):
        with self.assertRaises(IncorrectPasswordError):
            User.login("*****@*****.**", "WRONGPASSWORD")

    def test_login_invalid_password(self):
        with self.assertRaises(IncorrectPasswordError):
            User.login("*****@*****.**", "SHORT")

    def test_exists(self):
        self.assertTrue(User.exists("*****@*****.**"))

    def test_exists_notindb(self):
        self.assertFalse(User.exists("*****@*****.**"))

    def test_exists_invalid_email(self):
        with self.assertRaises(IncorrectEmailError):
            User.exists("notanemail.@badformat")

    def test_get_email(self):
        self.assertEqual(self.user.email, '*****@*****.**')

    def test_get_level(self):
        self.assertEqual(self.user.level, "admin")

    def test_get_info(self):
        expinfo = {
            'name': 'Admin',
            'affiliation': 'Owner University',
            'address': '312 noname st, Apt K, Nonexistantown, CO 80302',
            'phone': '222-444-6789',
            'pass_reset_code': None,
            'pass_reset_timestamp': None,
            'user_verify_code': None,
            'phone': '222-444-6789'
        }
        self.assertEqual(self.user.info, expinfo)

    def test_set_info(self):
        self.user.info = self.userinfo
        self.assertEqual(self.user.info, self.userinfo)

    def test_set_info_not_info(self):
        """Tests setting info with a non-allowed column"""
        self.userinfo["email"] = "FAIL"
        with self.assertRaises(QiitaDBColumnError):
            self.user.info = self.userinfo

    def test_set_info_bad_info(self):
        """Test setting info with a key not in the table"""
        self.userinfo["BADTHING"] = "FAIL"
        with self.assertRaises(QiitaDBColumnError):
            self.user.info = self.userinfo

    def test_default_analysis(self):
        qiita_config.portal = "QIITA"
        obs = self.user.default_analysis
        self.assertEqual(obs, 4)

        qiita_config.portal = "EMP"
        obs = self.user.default_analysis
        self.assertEqual(obs, 8)

    def test_get_user_studies(self):
        user = User('*****@*****.**')
        qiita_config.portal = "QIITA"
        self.assertEqual(user.user_studies, {1})

        qiita_config.portal = "EMP"
        self.assertEqual(user.user_studies, set())

    def test_get_shared_studies(self):
        user = User('*****@*****.**')
        qiita_config.portal = "QIITA"
        self.assertEqual(user.shared_studies, {1})

        qiita_config.portal = "EMP"
        self.assertEqual(user.shared_studies, set())

    def test_get_private_analyses(self):
        user = User('*****@*****.**')
        qiita_config.portal = "QIITA"
        self.assertEqual(user.private_analyses, set([1, 2]))

        qiita_config.portal = "EMP"
        self.assertEqual(user.private_analyses, set())

    def test_get_shared_analyses(self):
        user = User('*****@*****.**')
        qiita_config.portal = "QIITA"
        self.assertEqual(user.shared_analyses, set([1]))

        qiita_config.portal = "EMP"
        self.assertEqual(user.shared_analyses, set())

    def test_verify_code(self):
        sql = ("insert into qiita.qiita_user values ('*****@*****.**', '1', "
               "'testtest', 'testuser', '', '', '', 'verifycode', 'resetcode'"
               ",null)")
        self.conn_handler.execute(sql)
        self.assertFalse(User.verify_code('*****@*****.**', 'wrongcode',
                                          'create'))
        self.assertFalse(User.verify_code('*****@*****.**', 'wrongcode',
                                          'reset'))

        self.assertTrue(User.verify_code('*****@*****.**', 'verifycode',
                                         'create'))
        self.assertTrue(User.verify_code('*****@*****.**', 'resetcode',
                                         'reset'))

        # make sure errors raised if code already used or wrong type
        with self.assertRaises(QiitaDBError):
            User.verify_code('*****@*****.**', 'verifycode', 'create')
        with self.assertRaises(QiitaDBError):
            User.verify_code('*****@*****.**', 'resetcode', 'reset')

        with self.assertRaises(IncompetentQiitaDeveloperError):
            User.verify_code('*****@*****.**', 'fakecode', 'badtype')

        # make sure default analyses created
        sql = ("SELECT email, name, description, dflt FROM qiita.analysis "
               "WHERE email = '*****@*****.**'")
        obs = self.conn_handler.execute_fetchall(sql)
        exp = [['*****@*****.**', '[email protected]', 'dflt', True],
               ['*****@*****.**', '[email protected]', 'dflt', True]]
        self.assertEqual(obs, exp)

    def _check_pass(self, passwd):
        obspass = self.conn_handler.execute_fetchone(
            "SELECT password FROM qiita.qiita_user WHERE email = %s",
            (self.user.id, ))[0]
        self.assertEqual(hash_password(passwd, obspass), obspass)

    def test_change_pass(self):
        self.user._change_pass("newpassword")
        self._check_pass("newpassword")
        self.assertIsNone(self.user.info["pass_reset_code"])

    def test_change_pass_short(self):
        with self.assertRaises(IncorrectPasswordError):
            self.user._change_pass("newpass")
        self._check_pass("password")

    def test_change_password(self):
        self.user.change_password("password", "newpassword")
        self._check_pass("newpassword")

    def test_change_password_wrong_oldpass(self):
        self.user.change_password("WRONG", "newpass")
        self._check_pass("password")

    def test_generate_reset_code(self):
        user = User.create('*****@*****.**', 'password')
        sql = "SELECT LOCALTIMESTAMP"
        before = self.conn_handler.execute_fetchone(sql)[0]
        user.generate_reset_code()
        after = self.conn_handler.execute_fetchone(sql)[0]
        sql = ("SELECT pass_reset_code, pass_reset_timestamp FROM "
               "qiita.qiita_user WHERE email = %s")
        obscode, obstime = self.conn_handler.execute_fetchone(
            sql, ('*****@*****.**',))
        self.assertEqual(len(obscode), 20)
        self.assertTrue(before < obstime < after)

    def test_change_forgot_password(self):
        self.user.generate_reset_code()
        code = self.user.info["pass_reset_code"]
        obsbool = self.user.change_forgot_password(code, "newpassword")
        self.assertEqual(obsbool, True)
        self._check_pass("newpassword")

    def test_change_forgot_password_bad_code(self):
        self.user.generate_reset_code()
        code = "AAAAAAA"
        obsbool = self.user.change_forgot_password(code, "newpassword")
        self.assertEqual(obsbool, False)
        self._check_pass("password")
예제 #4
0
파일: test_user.py 프로젝트: adamrp/qiita
class UserTest(TestCase):
    """Tests the User object and all properties/methods"""

    def setUp(self):
        self.user = User('*****@*****.**')
        self.portal = qiita_config.portal

        self.userinfo = {
            'name': 'Dude',
            'affiliation': 'Nowhere University',
            'address': '123 fake st, Apt 0, Faketown, CO 80302',
            'phone': '111-222-3344',
            'pass_reset_code': None,
            'pass_reset_timestamp': None,
            'user_verify_code': None
        }

    def tearDown(self):
        qiita_config.portal = self.portal

    def test_instantiate_user(self):
        User('*****@*****.**')

    def test_instantiate_unknown_user(self):
        with self.assertRaises(QiitaDBUnknownIDError):
            User('*****@*****.**')

    def _check_correct_info(self, obs, exp):
        self.assertEqual(set(exp.keys()), set(obs.keys()))
        for key in exp:
            # user_verify_code and password seed randomly generated so just
            # making sure they exist and is correct length
            if key == 'user_verify_code':
                self.assertEqual(len(obs[key]), 20)
            elif key == "password":
                self.assertEqual(len(obs[key]), 60)
            else:
                self.assertEqual(obs[key], exp[key])

    def test_create_user(self):
        user = User.create('*****@*****.**', 'password')
        self.assertEqual(user.id, '*****@*****.**')
        sql = "SELECT * from qiita.qiita_user WHERE email = '*****@*****.**'"
        obs = self.conn_handler.execute_fetchall(sql)
        self.assertEqual(len(obs), 1)
        obs = dict(obs[0])
        exp = {
            'password': '',
            'name': None,
            'pass_reset_timestamp': None,
            'affiliation': None,
            'pass_reset_code': None,
            'phone': None,
            'user_verify_code': '',
            'address': None,
            'user_level_id': 5,
            'email': '*****@*****.**'}
        self._check_correct_info(obs, exp)

    def test_create_user_info(self):
        user = User.create('*****@*****.**', 'password', self.userinfo)
        self.assertEqual(user.id, '*****@*****.**')
        sql = "SELECT * from qiita.qiita_user WHERE email = '*****@*****.**'"
        obs = self.conn_handler.execute_fetchall(sql)
        self.assertEqual(len(obs), 1)
        obs = dict(obs[0])
        exp = {
            'password': '',
            'name': 'Dude',
            'affiliation': 'Nowhere University',
            'address': '123 fake st, Apt 0, Faketown, CO 80302',
            'phone': '111-222-3344',
            'pass_reset_timestamp': None,
            'pass_reset_code': None,
            'user_verify_code': '',
            'user_level_id': 5,
            'email': '*****@*****.**'}
        self._check_correct_info(obs, exp)

    def test_create_user_column_not_allowed(self):
        self.userinfo["email"] = "FAIL"
        with self.assertRaises(QiitaDBColumnError):
            User.create('*****@*****.**', 'password', self.userinfo)

    def test_create_user_non_existent_column(self):
        self.userinfo["BADTHING"] = "FAIL"
        with self.assertRaises(QiitaDBColumnError):
            User.create('*****@*****.**', 'password', self.userinfo)

    def test_create_user_duplicate(self):
        with self.assertRaises(QiitaDBDuplicateError):
            User.create('*****@*****.**', 'password')

    def test_create_user_bad_email(self):
        with self.assertRaises(IncorrectEmailError):
            User.create('notanemail', 'password')

    def test_create_user_bad_password(self):
        with self.assertRaises(IncorrectPasswordError):
            User.create('*****@*****.**', '')

    def test_login(self):
        self.assertEqual(User.login("*****@*****.**", "password"),
                         User("*****@*****.**"))

    def test_login_incorrect_user(self):
        with self.assertRaises(IncorrectEmailError):
            User.login("*****@*****.**", "password")

    def test_login_incorrect_password(self):
        with self.assertRaises(IncorrectPasswordError):
            User.login("*****@*****.**", "WRONGPASSWORD")

    def test_login_invalid_password(self):
        with self.assertRaises(IncorrectPasswordError):
            User.login("*****@*****.**", "SHORT")

    def test_exists(self):
        self.assertTrue(User.exists("*****@*****.**"))

    def test_exists_notindb(self):
        self.assertFalse(User.exists("*****@*****.**"))

    def test_exists_invalid_email(self):
        with self.assertRaises(IncorrectEmailError):
            User.exists("notanemail.@badformat")

    def test_get_email(self):
        self.assertEqual(self.user.email, '*****@*****.**')

    def test_get_level(self):
        self.assertEqual(self.user.level, "admin")

    def test_get_info(self):
        expinfo = {
            'name': 'Admin',
            'affiliation': 'Owner University',
            'address': '312 noname st, Apt K, Nonexistantown, CO 80302',
            'phone': '222-444-6789',
            'pass_reset_code': None,
            'pass_reset_timestamp': None,
            'user_verify_code': None,
            'phone': '222-444-6789'
        }
        self.assertEqual(self.user.info, expinfo)

    def test_set_info(self):
        self.user.info = self.userinfo
        self.assertEqual(self.user.info, self.userinfo)

    def test_set_info_not_info(self):
        """Tests setting info with a non-allowed column"""
        self.userinfo["email"] = "FAIL"
        with self.assertRaises(QiitaDBColumnError):
            self.user.info = self.userinfo

    def test_set_info_bad_info(self):
        """Test setting info with a key not in the table"""
        self.userinfo["BADTHING"] = "FAIL"
        with self.assertRaises(QiitaDBColumnError):
            self.user.info = self.userinfo

    def test_default_analysis(self):
        qiita_config.portal = "QIITA"
        obs = self.user.default_analysis
        self.assertEqual(obs, 4)

        qiita_config.portal = "EMP"
        obs = self.user.default_analysis
        self.assertEqual(obs, 8)

    def test_get_user_studies(self):
        user = User('*****@*****.**')
        qiita_config.portal = "QIITA"
        self.assertEqual(user.user_studies, {1})

        qiita_config.portal = "EMP"
        self.assertEqual(user.user_studies, set())

    def test_get_shared_studies(self):
        user = User('*****@*****.**')
        qiita_config.portal = "QIITA"
        self.assertEqual(user.shared_studies, {1})

        qiita_config.portal = "EMP"
        self.assertEqual(user.shared_studies, set())

    def test_get_private_analyses(self):
        user = User('*****@*****.**')
        qiita_config.portal = "QIITA"
        self.assertEqual(user.private_analyses, set([1, 2]))

        qiita_config.portal = "EMP"
        self.assertEqual(user.private_analyses, set())

    def test_get_shared_analyses(self):
        user = User('*****@*****.**')
        qiita_config.portal = "QIITA"
        self.assertEqual(user.shared_analyses, set([1]))

        qiita_config.portal = "EMP"
        self.assertEqual(user.shared_analyses, set())

    def test_verify_code(self):
        add_system_message("TESTMESSAGE_OLD", datetime.now())
        add_system_message("TESTMESSAGE",
                           datetime.now() + timedelta(seconds=59))
        sql = ("insert into qiita.qiita_user values ('*****@*****.**', '1', "
               "'testtest', 'testuser', '', '', '', 'verifycode', 'resetcode'"
               ",null)")
        self.conn_handler.execute(sql)

        self.assertFalse(User.verify_code('*****@*****.**', 'wrongcode',
                                          'create'))
        self.assertFalse(User.verify_code('*****@*****.**', 'wrongcode',
                                          'reset'))

        self.assertTrue(User.verify_code('*****@*****.**', 'verifycode',
                                         'create'))
        self.assertTrue(User.verify_code('*****@*****.**', 'resetcode',
                                         'reset'))

        # make sure errors raised if code already used or wrong type
        with self.assertRaises(QiitaDBError):
            User.verify_code('*****@*****.**', 'verifycode', 'create')
        with self.assertRaises(QiitaDBError):
            User.verify_code('*****@*****.**', 'resetcode', 'reset')

        with self.assertRaises(IncompetentQiitaDeveloperError):
            User.verify_code('*****@*****.**', 'fakecode', 'badtype')

        # make sure default analyses created
        sql = ("SELECT email, name, description, dflt FROM qiita.analysis "
               "WHERE email = '*****@*****.**'")
        obs = self.conn_handler.execute_fetchall(sql)
        exp = [['*****@*****.**', '[email protected]', 'dflt', True],
               ['*****@*****.**', '[email protected]', 'dflt', True]]
        self.assertEqual(obs, exp)

        # Make sure default analyses are linked with the portal
        sql = """SELECT COUNT(1)
                 FROM qiita.analysis
                    JOIN qiita.analysis_portal USING (analysis_id)
                    JOIN qiita.portal_type USING (portal_type_id)
                 WHERE email = '*****@*****.**' AND dflt = true"""
        self.assertEqual(self.conn_handler.execute_fetchone(sql)[0], 2)

        # Make sure new system messages are linked to user
        sql = """SELECT message_id FROM qiita.message_user
                 WHERE email = '*****@*****.**'"""
        m_id = get_count('qiita.message')
        self.assertEqual(self.conn_handler.execute_fetchall(sql), [[m_id]])

    def _check_pass(self, passwd):
        obspass = self.conn_handler.execute_fetchone(
            "SELECT password FROM qiita.qiita_user WHERE email = %s",
            (self.user.id, ))[0]
        self.assertEqual(hash_password(passwd, obspass), obspass)

    def test_change_pass(self):
        self.user._change_pass("newpassword")
        self._check_pass("newpassword")
        self.assertIsNone(self.user.info["pass_reset_code"])

    def test_change_pass_short(self):
        with self.assertRaises(IncorrectPasswordError):
            self.user._change_pass("newpass")
        self._check_pass("password")

    def test_change_password(self):
        self.user.change_password("password", "newpassword")
        self._check_pass("newpassword")

    def test_change_password_wrong_oldpass(self):
        self.user.change_password("WRONG", "newpass")
        self._check_pass("password")

    def test_generate_reset_code(self):
        user = User.create('*****@*****.**', 'password')
        sql = "SELECT LOCALTIMESTAMP"
        before = self.conn_handler.execute_fetchone(sql)[0]
        user.generate_reset_code()
        after = self.conn_handler.execute_fetchone(sql)[0]
        sql = ("SELECT pass_reset_code, pass_reset_timestamp FROM "
               "qiita.qiita_user WHERE email = %s")
        obscode, obstime = self.conn_handler.execute_fetchone(
            sql, ('*****@*****.**',))
        self.assertEqual(len(obscode), 20)
        self.assertTrue(before < obstime < after)

    def test_change_forgot_password(self):
        self.user.generate_reset_code()
        code = self.user.info["pass_reset_code"]
        obsbool = self.user.change_forgot_password(code, "newpassword")
        self.assertEqual(obsbool, True)
        self._check_pass("newpassword")

    def test_change_forgot_password_bad_code(self):
        self.user.generate_reset_code()
        code = "AAAAAAA"
        obsbool = self.user.change_forgot_password(code, "newpassword")
        self.assertEqual(obsbool, False)
        self._check_pass("password")

    def test_messages(self):
        add_system_message('SYS MESSAGE', datetime.now())
        user = User('*****@*****.**')
        obs = user.messages()
        exp_msg = [
            (4, 'SYS MESSAGE'),
            (1, 'message 1'),
            (2, 'Lorem ipsum dolor sit amet, consectetur adipiscing elit. '
                'Pellentesque sed auctor ex, non placerat sapien. Vestibulum '
                'vestibulum massa ut sapien condimentum, cursus consequat diam'
                ' sodales. Nulla aliquam arcu ut massa auctor, et vehicula '
                'mauris tempor. In lacinia viverra ante quis pellentesque. '
                'Nunc vel mi accumsan, porttitor eros ut, pharetra elit. Nulla'
                ' ac nisi quis dui egestas malesuada vitae ut mauris. Morbi '
                'blandit non nisl a finibus. In erat velit, congue at ipsum '
                'sit amet, venenatis bibendum sem. Curabitur vel odio sed est '
                'rutrum rutrum. Quisque efficitur ut purus in ultrices. '
                'Pellentesque eu auctor justo.'),
            (3, 'message <a href="#">3</a>')]
        self.assertEqual([(x[0], x[1]) for x in obs], exp_msg)
        self.assertTrue(all(x[2] < datetime.now() for x in obs))
        self.assertFalse(all(x[3] for x in obs))
        self.assertEqual([x[4] for x in obs], [True, False, False, False])

        obs = user.messages(1)
        exp_msg = ['SYS MESSAGE']
        self.assertEqual([x[1] for x in obs], exp_msg)

    def test_mark_messages(self):
        user = User('*****@*****.**')
        user.mark_messages([1, 2])
        obs = user.messages()
        exp = [True, True, False]
        self.assertEqual([x[3] for x in obs], exp)

        user.mark_messages([1], read=False)
        obs = user.messages()
        exp = [False, True, False]
        self.assertEqual([x[3] for x in obs], exp)

    def test_delete_messages(self):
        # Make message 1 a system message
        sql = """UPDATE qiita.message
                 SET expiration = '2015-08-05'
                 WHERE message_id = 1"""
        self.conn_handler.execute(sql)
        user = User('*****@*****.**')
        user.delete_messages([1, 2])
        obs = user.messages()
        exp_msg = [(3, 'message <a href="#">3</a>')]
        self.assertItemsEqual([(x[0], x[1]) for x in obs], exp_msg)

        sql = "SELECT message_id FROM qiita.message"
        obs = self.conn_handler.execute_fetchall(sql)
        self.assertItemsEqual(obs, [[1], [3]])
예제 #5
0
class UserTest(TestCase):
    """Tests the User object and all properties/methods"""
    def setUp(self):
        self.user = User('*****@*****.**')

        self.userinfo = {
            'name': 'Dude',
            'affiliation': 'Nowhere University',
            'address': '123 fake st, Apt 0, Faketown, CO 80302',
            'phone': '111-222-3344',
            'pass_reset_code': None,
            'pass_reset_timestamp': None,
            'user_verify_code': None
        }

    def test_instantiate_user(self):
        User('*****@*****.**')

    def test_instantiate_unknown_user(self):
        with self.assertRaises(QiitaDBUnknownIDError):
            User('*****@*****.**')

    def _check_correct_info(self, obs, exp):
        self.assertEqual(set(exp.keys()), set(obs.keys()))
        for key in exp:
            # user_verify_code and password seed randomly generated so just
            # making sure they exist and is correct length
            if key == 'user_verify_code':
                self.assertEqual(len(obs[key]), 20)
            elif key == "password":
                self.assertEqual(len(obs[key]), 60)
            else:
                self.assertEqual(obs[key], exp[key])

    def test_create_user(self):
        user = User.create('*****@*****.**', 'password')
        self.assertEqual(user.id, '*****@*****.**')
        sql = "SELECT * from qiita.qiita_user WHERE email = '*****@*****.**'"
        obs = self.conn_handler.execute_fetchall(sql)
        self.assertEqual(len(obs), 1)
        obs = dict(obs[0])
        exp = {
            'password': '',
            'name': None,
            'pass_reset_timestamp': None,
            'affiliation': None,
            'pass_reset_code': None,
            'phone': None,
            'user_verify_code': '',
            'address': None,
            'user_level_id': 5,
            'email': '*****@*****.**'
        }
        self._check_correct_info(obs, exp)

    def test_create_user_info(self):
        user = User.create('*****@*****.**', 'password', self.userinfo)
        self.assertEqual(user.id, '*****@*****.**')
        sql = "SELECT * from qiita.qiita_user WHERE email = '*****@*****.**'"
        obs = self.conn_handler.execute_fetchall(sql)
        self.assertEqual(len(obs), 1)
        obs = dict(obs[0])
        exp = {
            'password': '',
            'name': 'Dude',
            'affiliation': 'Nowhere University',
            'address': '123 fake st, Apt 0, Faketown, CO 80302',
            'phone': '111-222-3344',
            'pass_reset_timestamp': None,
            'pass_reset_code': None,
            'user_verify_code': '',
            'user_level_id': 5,
            'email': '*****@*****.**'
        }
        self._check_correct_info(obs, exp)

    def test_create_user_column_not_allowed(self):
        self.userinfo["email"] = "FAIL"
        with self.assertRaises(QiitaDBColumnError):
            User.create('*****@*****.**', 'password', self.userinfo)

    def test_create_user_non_existent_column(self):
        self.userinfo["BADTHING"] = "FAIL"
        with self.assertRaises(QiitaDBColumnError):
            User.create('*****@*****.**', 'password', self.userinfo)

    def test_create_user_duplicate(self):
        with self.assertRaises(QiitaDBDuplicateError):
            User.create('*****@*****.**', 'password')

    def test_create_user_bad_email(self):
        with self.assertRaises(IncorrectEmailError):
            User.create('notanemail', 'password')

    def test_create_user_bad_password(self):
        with self.assertRaises(IncorrectPasswordError):
            User.create('*****@*****.**', '')

    def test_login(self):
        self.assertEqual(User.login("*****@*****.**", "password"),
                         User("*****@*****.**"))

    def test_login_incorrect_user(self):
        with self.assertRaises(IncorrectEmailError):
            User.login("*****@*****.**", "password")

    def test_login_incorrect_password(self):
        with self.assertRaises(IncorrectPasswordError):
            User.login("*****@*****.**", "WRONGPASSWORD")

    def test_login_invalid_password(self):
        with self.assertRaises(IncorrectPasswordError):
            User.login("*****@*****.**", "SHORT")

    def test_exists(self):
        self.assertTrue(User.exists("*****@*****.**"))

    def test_exists_notindb(self):
        self.assertFalse(User.exists("*****@*****.**"))

    def test_exists_invaid_email(self):
        with self.assertRaises(IncorrectEmailError):
            User.exists("notanemail@badformat")

    def test_get_email(self):
        self.assertEqual(self.user.email, '*****@*****.**')

    def test_get_level(self):
        self.assertEqual(self.user.level, "admin")

    def test_get_info(self):
        expinfo = {
            'name': 'Admin',
            'affiliation': 'Owner University',
            'address': '312 noname st, Apt K, Nonexistantown, CO 80302',
            'phone': '222-444-6789',
            'pass_reset_code': None,
            'pass_reset_timestamp': None,
            'user_verify_code': None,
            'phone': '222-444-6789'
        }
        self.assertEqual(self.user.info, expinfo)

    def test_set_info(self):
        self.user.info = self.userinfo
        self.assertEqual(self.user.info, self.userinfo)

    def test_set_info_not_info(self):
        """Tests setting info with a non-allowed column"""
        self.userinfo["email"] = "FAIL"
        with self.assertRaises(QiitaDBColumnError):
            self.user.info = self.userinfo

    def test_set_info_bad_info(self):
        """Test setting info with a key not in the table"""
        self.userinfo["BADTHING"] = "FAIL"
        with self.assertRaises(QiitaDBColumnError):
            self.user.info = self.userinfo

    def test_get_user_studies(self):
        user = User('*****@*****.**')
        self.assertEqual(user.user_studies, [1])

    def test_get_shared_studies(self):
        user = User('*****@*****.**')
        self.assertEqual(user.shared_studies, [1])

    def test_get_private_analyses(self):
        self.assertEqual(self.user.private_analyses, [])

    def test_get_shared_analyses(self):
        self.assertEqual(self.user.shared_analyses, [])

    def test_verify_code(self):
        sql = ("insert into qiita.qiita_user values ('*****@*****.**', '1', "
               "'testtest', 'testuser', '', '', '', 'verifycode', 'resetcode'"
               ",null)")
        self.conn_handler.execute(sql)
        self.assertTrue(
            User.verify_code('*****@*****.**', 'verifycode', 'create'))
        self.assertTrue(User.verify_code('*****@*****.**', 'resetcode',
                                         'reset'))
        self.assertFalse(
            User.verify_code('*****@*****.**', 'wrongcode', 'create'))
        self.assertFalse(
            User.verify_code('*****@*****.**', 'wrongcode', 'reset'))
        with self.assertRaises(IncompetentQiitaDeveloperError):
            User.verify_code('*****@*****.**', 'fakecode', 'badtype')

    def _check_pass(self, passwd):
        obspass = self.conn_handler.execute_fetchone(
            "SELECT password FROM qiita.qiita_user WHERE email = %s",
            (self.user.id, ))[0]
        self.assertEqual(hash_password(passwd, obspass), obspass)

    def test_change_pass(self):
        self.user._change_pass("newpassword")
        self._check_pass("newpassword")
        self.assertIsNone(self.user.info["pass_reset_code"])

    def test_change_pass_short(self):
        with self.assertRaises(IncorrectPasswordError):
            self.user._change_pass("newpass")
        self._check_pass("password")

    def test_change_password(self):
        self.user.change_password("password", "newpassword")
        self._check_pass("newpassword")

    def test_change_password_wrong_oldpass(self):
        self.user.change_password("WRONG", "newpass")
        self._check_pass("password")

    def test_generate_reset_code(self):
        user = User.create('*****@*****.**', 'password')
        sql = "SELECT LOCALTIMESTAMP"
        before = self.conn_handler.execute_fetchone(sql)[0]
        user.generate_reset_code()
        after = self.conn_handler.execute_fetchone(sql)[0]
        sql = ("SELECT pass_reset_code, pass_reset_timestamp FROM "
               "qiita.qiita_user WHERE email = %s")
        obscode, obstime = self.conn_handler.execute_fetchone(
            sql, ('*****@*****.**', ))
        self.assertEqual(len(obscode), 20)
        self.assertTrue(before < obstime < after)

    def test_change_forgot_password(self):
        self.user.generate_reset_code()
        code = self.user.info["pass_reset_code"]
        obsbool = self.user.change_forgot_password(code, "newpassword")
        self.assertEqual(obsbool, True)
        self._check_pass("newpassword")

    def test_change_forgot_password_bad_code(self):
        self.user.generate_reset_code()
        code = "AAAAAAA"
        obsbool = self.user.change_forgot_password(code, "newpassword")
        self.assertEqual(obsbool, False)
        self._check_pass("password")