Skip to content

Commit b8f959a

Browse files
committed
adding a new page for admins to easily list all users not yet validated and offer means to delete those
1 parent ca55a2f commit b8f959a

File tree

5 files changed

+112
-2
lines changed

5 files changed

+112
-2
lines changed

qiita_db/support_files/populate_test_db.sql

+3
Original file line numberDiff line numberDiff line change
@@ -54,6 +54,9 @@ INSERT INTO qiita.qiita_user VALUES ('[email protected]', 4, '$2a$12$gnUi8Qg.0tvW243v
5454
INSERT INTO qiita.qiita_user VALUES ('[email protected]', 4, '$2a$12$gnUi8Qg.0tvW243v889BhOBhWLIHyIJjjgaG6dxuRJkUM8nXG9Efe', 'Shared', 'Nowhere University', '123 fake st, Apt 0, Faketown, CO 80302', '111-222-3344', NULL, NULL, NULL, false);
5555
INSERT INTO qiita.qiita_user VALUES ('[email protected]', 1, '$2a$12$gnUi8Qg.0tvW243v889BhOBhWLIHyIJjjgaG6dxuRJkUM8nXG9Efe', 'Admin', 'Owner University', '312 noname st, Apt K, Nonexistantown, CO 80302', '222-444-6789', NULL, NULL, NULL, false);
5656
INSERT INTO qiita.qiita_user VALUES ('[email protected]', 4, '$2a$12$gnUi8Qg.0tvW243v889BhOBhWLIHyIJjjgaG6dxuRJkUM8nXG9Efe', 'Demo', 'Qiita Dev', '1345 Colorado Avenue', '303-492-1984', NULL, NULL, NULL, false);
57+
INSERT INTO qiita.qiita_user VALUES ('[email protected]', 5, '$2a$12$gnUi8Qg.0tvW243v889BhOBhWLIHyIJjjgaG6dxuRJkUM8nXG9Efe', 'JustNow', 'NonVeriUser', '1634 Edgemont Avenue', '303-492-1984', NULL, NULL, NULL, false, NULL, NULL, NULL, NOW());
58+
INSERT INTO qiita.qiita_user VALUES ('[email protected]', 5, '$2a$12$gnUi8Qg.0tvW243v889BhOBhWLIHyIJjjgaG6dxuRJkUM8nXG9Efe', 'Oldie', 'NonVeriUser', '172 New Lane', '102-111-1984', NULL, NULL, NULL, false, NULL, NULL, NULL, NOW() - INTERVAL '1 YEAR');
59+
INSERT INTO qiita.qiita_user VALUES ('[email protected]', 5, '$2a$12$gnUi8Qg.0tvW243v889BhOBhWLIHyIJjjgaG6dxuRJkUM8nXG9Efe', 'TooLate', 'NonVeriUser', '564 C Street', '508-492-222', NULL, NULL, NULL, false, NULL, NULL, NULL, NOW() - INTERVAL '30 DAY');
5760

5861

5962
--

qiita_pet/handlers/user_handlers.py

+73
Original file line numberDiff line numberDiff line change
@@ -7,13 +7,17 @@
77
# -----------------------------------------------------------------------------
88

99
import re
10+
from json import dumps
11+
import warnings
1012

1113
from tornado.web import authenticated, HTTPError
1214
from wtforms import Form, StringField, BooleanField, validators
1315
from wtforms.validators import ValidationError
1416

1517
from qiita_pet.handlers.base_handlers import BaseHandler
1618
from qiita_pet.handlers.api_proxy import user_jobs_get_req
19+
from qiita_pet.handlers.portal import PortalEditBase
20+
import qiita_db as qdb
1721
from qiita_db.util import send_email
1822
from qiita_db.user import User
1923
from qiita_db.logger import LogEntry
@@ -375,3 +379,72 @@ class UserJobs(BaseHandler):
375379
def get(self):
376380
response = user_jobs_get_req(self.current_user)
377381
self.write(response)
382+
383+
384+
class PurgeUsersAJAXHandler(PortalEditBase):
385+
# define columns besides email that will be displayed on website
386+
FIELDS = ['name', 'affiliation', 'address', 'phone',
387+
'creation_timestamp']
388+
@authenticated
389+
@execute_as_transaction
390+
def get(self):
391+
# retrieving users not yet verified
392+
self.check_admin()
393+
with qdb.sql_connection.TRN:
394+
sql = """SELECT email,{0}
395+
FROM qiita.qiita_user
396+
WHERE (user_level_id=5) AND
397+
(creation_timestamp < (NOW() - INTERVAL '30 DAY'))
398+
""".format(','.join(self.FIELDS))
399+
qdb.sql_connection.TRN.add(sql)
400+
users = qdb.sql_connection.TRN.execute()[1:]
401+
402+
# fetching information for each user
403+
result = []
404+
for list in users:
405+
for user in list:
406+
usermail = user[0]
407+
user_unit = {'email': usermail}
408+
user_infos = User(usermail).info
409+
for col in self.FIELDS:
410+
user_unit[col] = str(user_infos[col])
411+
result.append(user_unit)
412+
# returning information as JSON
413+
self.write(dumps(result, separators=(',', ':')))
414+
415+
416+
class PurgeUsersHandler(PortalEditBase):
417+
@authenticated
418+
@execute_as_transaction
419+
def get(self):
420+
# render page and transfer headers to be included for the table
421+
self.check_admin()
422+
self.render('admin_purge_users.html',
423+
headers=['email'] + PurgeUsersAJAXHandler.FIELDS,
424+
submit_url="/admin/purge_users/")
425+
426+
def post(self):
427+
# check if logged in user is admin and fetch all checked boxes as well
428+
# as the action
429+
self.check_admin()
430+
users = map(str, self.get_arguments('selected'))
431+
action = self.get_argument('action')
432+
433+
# depending on the action delete user from db (remove)
434+
num_deleted_user = 0
435+
for user in users:
436+
try:
437+
with warnings.catch_warnings(record=True) as warns:
438+
if action == "Remove":
439+
user_to_delete = User(user)
440+
user_to_delete.delete(user)
441+
num_deleted_user += 1
442+
else:
443+
raise HTTPError(
444+
400, reason="Unknown action: %s" % action)
445+
except QiitaDBError as e:
446+
self.write(action.upper() + " ERROR:<br/>" + str(e))
447+
return
448+
msg = '; '.join([str(w.message) for w in warns])
449+
self.write(("%i non-validated user(s) successfully removed from "
450+
"database<br/>%s") % (num_deleted_user, msg))

qiita_pet/templates/sitebase.html

+1
Original file line numberDiff line numberDiff line change
@@ -383,6 +383,7 @@
383383
<li><a href="{% raw qiita_config.portal_dir %}/admin/error/">View Errors</a></li>
384384
<li><a href="{% raw qiita_config.portal_dir %}/admin/approval/">View Studies awaiting approval</a></li>
385385
<li><a href="{% raw qiita_config.portal_dir %}/admin/portals/studies/">Edit study portal connections</a></li>
386+
<li><a href="{% raw qiita_config.portal_dir %}/admin/purge_users/">Purge non-validated users</a></li>
386387
{% end %}
387388
<li><a href="{% raw qiita_config.portal_dir %}/admin/sample_validation/">Sample Validation</a></li>
388389
<li><a href="{% raw qiita_config.portal_dir %}/admin/processing_jobs/">Processing Jobs</a></li>

qiita_pet/test/test_user_handlers.py

+32-1
Original file line numberDiff line numberDiff line change
@@ -9,10 +9,14 @@
99
from unittest import main
1010
from wtforms.validators import ValidationError
1111
from wtforms import StringField
12+
from mock import Mock
13+
from json import loads
1214

1315
from qiita_pet.test.tornado_test_base import TestHandlerBase
1416
from qiita_pet.handlers.user_handlers import UserProfile
15-
17+
from qiita_pet.handlers.base_handlers import BaseHandler
18+
import qiita_db as qdb
19+
from qiita_db.user import User
1620

1721
class TestUserProfile(TestHandlerBase):
1822
# TODO: add proper test for this once figure out how. Issue 567
@@ -124,5 +128,32 @@ def test_get(self):
124128
self.assertEqual(response.code, 200)
125129

126130

131+
class TestPurgeUsersAJAXHandler(TestHandlerBase):
132+
def setUp(self):
133+
super().setUp()
134+
BaseHandler.get_current_user = Mock(return_value=User("[email protected]"))
135+
136+
def test_get(self):
137+
response = self.get('/admin/purge_usersAjax/?_=1718805487494')
138+
obs_users_table = loads(response.body.decode('ascii'))
139+
obs_users = {user['email'] for user in obs_users_table}
140+
self.assertIn('[email protected]', obs_users)
141+
self.assertIn('[email protected]', obs_users)
142+
self.assertNotIn('[email protected]', obs_users)
143+
144+
def test_post_removeBoth(self):
145+
# remove both users
146+
response = self.post('/admin/purge_users/',
147+
{'action': 'Remove',
148+
'selected': ['[email protected]',
149+
150+
self.assertEqual(response.code, 200)
151+
152+
# test that zero users are listed now
153+
response = self.get('/admin/purge_usersAjax/?_=1718805487495')
154+
obs_users_table = loads(response.body.decode('ascii'))
155+
self.assertEqual(obs_users_table, [])
156+
157+
127158
if __name__ == "__main__":
128159
main()

qiita_pet/webserver.py

+3-1
Original file line numberDiff line numberDiff line change
@@ -23,7 +23,7 @@
2323
AuthCreateHandler, AuthLoginHandler, AuthLogoutHandler, AuthVerifyHandler)
2424
from qiita_pet.handlers.user_handlers import (
2525
ChangeForgotPasswordHandler, ForgotPasswordHandler, UserProfileHandler,
26-
UserMessagesHander, UserJobs)
26+
UserMessagesHander, UserJobs, PurgeUsersAJAXHandler, PurgeUsersHandler)
2727
from qiita_pet.handlers.admin_processing_job import (
2828
AdminProcessingJob, AJAXAdminProcessingJobListing, SampleValidation)
2929
from qiita_pet.handlers.analysis_handlers import (
@@ -134,6 +134,8 @@ def __init__(self):
134134
(r"/admin/processing_jobs/", AdminProcessingJob),
135135
(r"/admin/processing_jobs/list", AJAXAdminProcessingJobListing),
136136
(r"/admin/sample_validation/", SampleValidation),
137+
(r"/admin/purge_users/", PurgeUsersHandler),
138+
(r"/admin/purge_usersAjax/", PurgeUsersAJAXHandler),
137139
(r"/ebi_submission/(.*)", EBISubmitHandler),
138140
# Study handlers
139141
(r"/study/create/", StudyEditHandler),

0 commit comments

Comments
 (0)