From 6309bcd71515a9c823141d19aecb381a4b67df27 Mon Sep 17 00:00:00 2001 From: =?UTF-8?q?Daniel=20Lombra=C3=B1a=20Gonz=C3=A1lez?= Date: Sat, 27 Feb 2021 10:23:10 +0100 Subject: [PATCH 1/5] fix: remove social columns. Closes issue #2017 --- ...31c3c2ff9fab_drop_social_network_logins.py | 26 +++++++++++++++++++ pybossa/model/user.py | 3 --- 2 files changed, 26 insertions(+), 3 deletions(-) create mode 100644 alembic/versions/31c3c2ff9fab_drop_social_network_logins.py diff --git a/alembic/versions/31c3c2ff9fab_drop_social_network_logins.py b/alembic/versions/31c3c2ff9fab_drop_social_network_logins.py new file mode 100644 index 0000000000..a6058523a3 --- /dev/null +++ b/alembic/versions/31c3c2ff9fab_drop_social_network_logins.py @@ -0,0 +1,26 @@ +"""drop social network logins + +Revision ID: 31c3c2ff9fab +Revises: a791f9de9ac3 +Create Date: 2021-02-27 10:17:17.122501 + +""" + +# revision identifiers, used by Alembic. +revision = '31c3c2ff9fab' +down_revision = 'a791f9de9ac3' + +from alembic import op +import sqlalchemy as sa + + +def upgrade(): + op.drop_column('user', 'twitter_user_id') + op.drop_column('user', 'google_user_id') + op.drop_column('user', 'facebook_user_id') + + +def downgrade(): + op.add_column('user', sa.Column('twitter_user_id', sa.BigInteger, unique=True)) + op.add_column('user', sa.Column('google_user_id', sa.BigInteger, unique=True)) + op.add_column('user', sa.Column('facebook_user_id', sa.BigInteger, unique=True)) diff --git a/pybossa/model/user.py b/pybossa/model/user.py index 6383eac399..e50cf09ebe 100644 --- a/pybossa/model/user.py +++ b/pybossa/model/user.py @@ -55,9 +55,6 @@ class User(db.Model, DomainObject, UserMixin): restrict = Column(Boolean, default=False, nullable=False) category = Column(Integer) flags = Column(Integer) - twitter_user_id = Column(BigInteger, unique=True) - facebook_user_id = Column(BigInteger, unique=True) - google_user_id = Column(String, unique=True) ckan_api = Column(String, unique=True) newsletter_prompted = Column(Boolean, default=False) valid_email = Column(Boolean, default=False) From c792893f1b2902f207d93aa7b16c73a0e2b74893 Mon Sep 17 00:00:00 2001 From: =?UTF-8?q?Daniel=20Lombra=C3=B1a=20Gonz=C3=A1lez?= Date: Sat, 27 Feb 2021 10:49:58 +0100 Subject: [PATCH 2/5] refactor: remove unused code. --- pybossa/cache/users.py | 8 +-- pybossa/view/account.py | 52 ++++-------------- test/test_cache/test_cache_users.py | 4 +- test/test_privacy.py | 7 --- test/test_web.py | 81 ++--------------------------- 5 files changed, 17 insertions(+), 135 deletions(-) diff --git a/pybossa/cache/users.py b/pybossa/cache/users.py index eca4401f24..e6a17b830c 100644 --- a/pybossa/cache/users.py +++ b/pybossa/cache/users.py @@ -46,11 +46,10 @@ def get_user_summary(name, current_user=None): """Return user summary.""" sql = text(''' SELECT "user".id, "user".name, "user".fullname, "user".created, - "user".api_key, "user".twitter_user_id, "user".facebook_user_id, - "user".google_user_id, "user".info, "user".admin, + "user".api_key, "user".info, "user".admin, "user".locale, "user".email_addr, COUNT(task_run.user_id) AS n_answers, - "user".valid_email, "user".confirmation_email_sent, + "user".valid_email, "user".confirmation_email_sent, "user".restrict FROM "user" LEFT OUTER JOIN task_run ON "user".id=task_run.user_id @@ -62,9 +61,6 @@ def get_user_summary(name, current_user=None): for row in results: user = dict(id=row.id, name=row.name, fullname=row.fullname, created=row.created, api_key=row.api_key, - twitter_user_id=row.twitter_user_id, - google_user_id=row.google_user_id, - facebook_user_id=row.facebook_user_id, info=row.info, admin=row.admin, locale=row.locale, email_addr=row.email_addr, n_answers=row.n_answers, diff --git a/pybossa/view/account.py b/pybossa/view/account.py index 8c52db2805..000a25daa0 100644 --- a/pybossa/view/account.py +++ b/pybossa/view/account.py @@ -157,20 +157,12 @@ def signin(): if request.method == 'POST' and not form.validate(): flash(gettext('Please correct the errors'), 'error') - auth = {'twitter': False, 'facebook': False, 'google': False} if current_user.is_anonymous: # If Twitter is enabled in config, show the Twitter Sign in button if (isLdap is False): - if ('twitter' in current_app.blueprints): # pragma: no cover - auth['twitter'] = True - if ('facebook' in current_app.blueprints): # pragma: no cover - auth['facebook'] = True - if ('google' in current_app.blueprints): # pragma: no cover - auth['google'] = True response = dict(template='account/signin.html', title="Sign in", form=form, - auth=auth, next=request.args.get('next')) return handle_content_type(response) else: @@ -580,8 +572,6 @@ def update_profile(name): return abort(404) ensure_authorized_to('update', user) show_passwd_form = True - if user.twitter_user_id or user.google_user_id or user.facebook_user_id: - show_passwd_form = False usr = cached_users.get_user_summary(name, current_user) # Extend the values user.rank = usr.get('rank') @@ -804,38 +794,16 @@ def forgot_password(): if user and user.email_addr: msg = dict(subject='Account Recovery', recipients=[user.email_addr]) - if user.twitter_user_id: - msg['body'] = render_template( - '/account/email/forgot_password_openid.md', - user=user, account_name='Twitter') - msg['html'] = render_template( - '/account/email/forgot_password_openid.html', - user=user, account_name='Twitter') - elif user.facebook_user_id: - msg['body'] = render_template( - '/account/email/forgot_password_openid.md', - user=user, account_name='Facebook') - msg['html'] = render_template( - '/account/email/forgot_password_openid.html', - user=user, account_name='Facebook') - elif user.google_user_id: - msg['body'] = render_template( - '/account/email/forgot_password_openid.md', - user=user, account_name='Google') - msg['html'] = render_template( - '/account/email/forgot_password_openid.html', - user=user, account_name='Google') - else: - userdict = {'user': user.name, 'password': user.passwd_hash} - key = signer.dumps(userdict, salt='password-reset') - recovery_url = url_for_app_type('.reset_password', - key=key, _external=True) - msg['body'] = render_template( - '/account/email/forgot_password.md', - user=user, recovery_url=recovery_url) - msg['html'] = render_template( - '/account/email/forgot_password.html', - user=user, recovery_url=recovery_url) + userdict = {'user': user.name, 'password': user.passwd_hash} + key = signer.dumps(userdict, salt='password-reset') + recovery_url = url_for_app_type('.reset_password', + key=key, _external=True) + msg['body'] = render_template( + '/account/email/forgot_password.md', + user=user, recovery_url=recovery_url) + msg['html'] = render_template( + '/account/email/forgot_password.html', + user=user, recovery_url=recovery_url) mail_queue.enqueue(send_mail, msg) flash(gettext("We've sent you an email with account " "recovery instructions!"), diff --git a/test/test_cache/test_cache_users.py b/test/test_cache/test_cache_users.py index 7f5345a00f..2cdeb4260d 100644 --- a/test/test_cache/test_cache_users.py +++ b/test/test_cache/test_cache_users.py @@ -71,7 +71,6 @@ def test_get_user_summary_returns_fields(self): """Test CACHE USERS get_user_summary all the fields in the dict""" UserFactory.create(name='user') fields = ('id', 'name', 'fullname', 'created', 'api_key', - 'twitter_user_id', 'google_user_id', 'facebook_user_id', 'info', 'admin', 'email_addr', 'n_answers', 'rank', 'score', 'total') user = cached_users.get_user_summary('user') @@ -84,8 +83,7 @@ def test_public_get_user_summary_returns_fields(self): """Test CACHE USERS public_get_user_summary all the fields in the dict""" UserFactory.create(name='user') public_fields = ('name', 'info', 'fullname', 'created', 'rank', 'score') - private_fields = ('id', 'api_key', 'twitter_user_id', 'google_user_id', - 'facebook_user_id', 'admin', 'email_addr', 'total') + private_fields = ('id', 'api_key', 'admin', 'email_addr', 'total') user = cached_users.public_get_user_summary('user') for field in public_fields: diff --git a/test/test_privacy.py b/test/test_privacy.py index e360d2ad8b..ea285f950b 100644 --- a/test/test_privacy.py +++ b/test/test_privacy.py @@ -232,16 +232,9 @@ def test_07_user_public_profile_json(self): assert 'confirmation_email_sent' not in data['user'], err_msg err_msg = 'email_addr should not be public' assert 'email_addr' not in data['user'], err_msg - err_msg = 'google_user_id should not be public' - assert 'google_user_id' not in data['user'], err_msg - err_msg = 'facebook_user_id should not be public' - assert 'facebook_user_id' not in data['user'], err_msg - err_msg = 'twitter_user_id should not be public' - assert 'twitter_user_id' not in data['user'], err_msg err_msg = 'valid_email should not be public' assert 'valid_email' not in data['user'], err_msg # public projects data - print(data) project = data['projects'][0] err_msg = 'info should be public' assert 'info' in project, err_msg diff --git a/test/test_web.py b/test/test_web.py index 93e9cb33a2..ba59d78205 100644 --- a/test/test_web.py +++ b/test/test_web.py @@ -3451,7 +3451,6 @@ def test_42_password_link(self): res = self.app.get('/account/johndoe/update') assert "Change your Password" in str(res.data) user = User.query.get(1) - user.twitter_user_id = 1234 db.session.add(user) db.session.commit() res = self.app.get('/account/johndoe/update') @@ -3635,12 +3634,7 @@ def test_45_password_reset_link_json(self, signer, queue, mock_url): self.register(name='facebook') user = User.query.get(1) jane = User.query.get(2) - jane.twitter_user_id = 10 - google = User.query.get(3) - google.google_user_id = 103 - facebook = User.query.get(4) - facebook.facebook_user_id = 104 - db.session.add_all([jane, google, facebook]) + db.session.add_all([jane]) db.session.commit() data = {'password': user.passwd_hash, 'user': user.name} @@ -3672,48 +3666,6 @@ def test_45_password_reset_link_json(self, signer, queue, mock_url): resdata = json.loads(res.data) - enqueue_call = queue.enqueue.call_args_list[1] - assert send_mail == enqueue_call[0][0], "send_mail not called" - assert 'your Twitter account to ' in enqueue_call[0][1]['body'] - assert 'your Twitter account to ' in enqueue_call[0][1]['html'] - err_msg = "There should be a flash message" - assert resdata.get('flash'), err_msg - assert "sent you an email" in resdata.get('flash'), err_msg - - data = {'password': google.passwd_hash, 'user': google.name} - csrf = self.get_csrf('/account/forgot-password') - res = self.app.post('/account/forgot-password', - data=json.dumps({'email_addr': 'google@example.com'}), - follow_redirects=False, - content_type="application/json", - headers={'X-CSRFToken': csrf}) - - resdata = json.loads(res.data) - - enqueue_call = queue.enqueue.call_args_list[2] - assert send_mail == enqueue_call[0][0], "send_mail not called" - assert 'your Google account to ' in enqueue_call[0][1]['body'] - assert 'your Google account to ' in enqueue_call[0][1]['html'] - err_msg = "There should be a flash message" - assert resdata.get('flash'), err_msg - assert "sent you an email" in resdata.get('flash'), err_msg - - data = {'password': facebook.passwd_hash, 'user': facebook.name} - csrf = self.get_csrf('/account/forgot-password') - res = self.app.post('/account/forgot-password', - data=json.dumps({'email_addr': 'facebook@example.com'}), - follow_redirects=False, - content_type="application/json", - headers={'X-CSRFToken': csrf}) - - enqueue_call = queue.enqueue.call_args_list[3] - assert send_mail == enqueue_call[0][0], "send_mail not called" - assert 'your Facebook account to ' in enqueue_call[0][1]['body'] - assert 'your Facebook account to ' in enqueue_call[0][1]['html'] - err_msg = "There should be a flash message" - assert resdata.get('flash'), err_msg - assert "sent you an email" in resdata.get('flash'), err_msg - # Test with not valid form csrf = self.get_csrf('/account/forgot-password') res = self.app.post('/account/forgot-password', @@ -3763,16 +3715,9 @@ def test_45_password_reset_link(self, signer, queue): self.register() self.register(name='janedoe') - self.register(name='google') - self.register(name='facebook') user = User.query.get(1) jane = User.query.get(2) - jane.twitter_user_id = 10 - google = User.query.get(3) - google.google_user_id = 103 - facebook = User.query.get(4) - facebook.facebook_user_id = 104 - db.session.add_all([jane, google, facebook]) + db.session.add_all([jane]) db.session.commit() data = {'password': user.passwd_hash, 'user': user.name} @@ -3791,26 +3736,8 @@ def test_45_password_reset_link(self, signer, queue): follow_redirects=True) enqueue_call = queue.enqueue.call_args_list[1] assert send_mail == enqueue_call[0][0], "send_mail not called" - assert 'your Twitter account to ' in enqueue_call[0][1]['body'] - assert 'your Twitter account to ' in enqueue_call[0][1]['html'] - - data = {'password': google.passwd_hash, 'user': google.name} - self.app.post('/account/forgot-password', - data={'email_addr': 'google@example.com'}, - follow_redirects=True) - enqueue_call = queue.enqueue.call_args_list[2] - assert send_mail == enqueue_call[0][0], "send_mail not called" - assert 'your Google account to ' in enqueue_call[0][1]['body'] - assert 'your Google account to ' in enqueue_call[0][1]['html'] - - data = {'password': facebook.passwd_hash, 'user': facebook.name} - self.app.post('/account/forgot-password', - data={'email_addr': 'facebook@example.com'}, - follow_redirects=True) - enqueue_call = queue.enqueue.call_args_list[3] - assert send_mail == enqueue_call[0][0], "send_mail not called" - assert 'your Facebook account to ' in enqueue_call[0][1]['body'] - assert 'your Facebook account to ' in enqueue_call[0][1]['html'] + assert 'Click here to recover your account' in enqueue_call[0][1]['body'] + assert 'To recover your password' in enqueue_call[0][1]['html'] # Test with not valid form res = self.app.post('/account/forgot-password', From f6de4006c3803f5a3c713d3c2030b95eb86bbcae Mon Sep 17 00:00:00 2001 From: =?UTF-8?q?Daniel=20Lombra=C3=B1a=20Gonz=C3=A1lez?= Date: Sat, 27 Feb 2021 10:55:17 +0100 Subject: [PATCH 3/5] fix: ident problem. --- pybossa/view/account.py | 2 -- 1 file changed, 2 deletions(-) diff --git a/pybossa/view/account.py b/pybossa/view/account.py index 000a25daa0..a1c64e330b 100644 --- a/pybossa/view/account.py +++ b/pybossa/view/account.py @@ -158,8 +158,6 @@ def signin(): if request.method == 'POST' and not form.validate(): flash(gettext('Please correct the errors'), 'error') if current_user.is_anonymous: - # If Twitter is enabled in config, show the Twitter Sign in button - if (isLdap is False): response = dict(template='account/signin.html', title="Sign in", form=form, From 81eb9713a4adf7966bd5c3606eda4baf93a32209 Mon Sep 17 00:00:00 2001 From: =?UTF-8?q?Daniel=20Lombra=C3=B1a=20Gonz=C3=A1lez?= Date: Sat, 27 Feb 2021 11:11:08 +0100 Subject: [PATCH 4/5] refactor: remove unused code. --- test/test_view/test_blog.py | 11 +---------- 1 file changed, 1 insertion(+), 10 deletions(-) diff --git a/test/test_view/test_blog.py b/test/test_view/test_blog.py index 95153b36ba..4e817c0289 100644 --- a/test/test_view/test_blog.py +++ b/test/test_view/test_blog.py @@ -84,9 +84,6 @@ def test_json_blogposts_get_all(self): data = json.loads(res.data) assert 'api_key' not in list(data['owner'].keys()) assert 'email_addr' not in list(data['owner'].keys()) - assert 'google_user_id' not in list(data['owner'].keys()) - assert 'facebook_user_id' not in list(data['owner'].keys()) - assert 'twitter_user_id' not in list(data['owner'].keys()) assert len(data['blogposts']) == 2 for blogpost in data['blogposts']: assert blogpost['title'] in ['titleone', 'titletwo'] @@ -98,24 +95,18 @@ def test_json_blogposts_get_all(self): data = json.loads(res.data) assert 'api_key' not in list(data['owner'].keys()) assert 'email_addr' not in list(data['owner'].keys()) - assert 'google_user_id' not in list(data['owner'].keys()) - assert 'facebook_user_id' not in list(data['owner'].keys()) - assert 'twitter_user_id' not in list(data['owner'].keys()) assert len(data['blogposts']) == 2 for blogpost in data['blogposts']: assert blogpost['title'] in ['titleone', 'titletwo'] self.signout() - # As owner + # As owner self.signin(email=user.email_addr, password=self.password) res = self.app_get_json(url, follow_redirects=True) assert res.status_code == 200, res.status_code data = json.loads(res.data) assert 'api_key' in list(data['owner'].keys()) assert 'email_addr' in list(data['owner'].keys()) - assert 'google_user_id' in list(data['owner'].keys()) - assert 'facebook_user_id' in list(data['owner'].keys()) - assert 'twitter_user_id' in list(data['owner'].keys()) assert len(data['blogposts']) == 3 for blogpost in data['blogposts']: assert blogpost['title'] in ['titleone', 'titletwo', 'titlethree'] From 098ff2c17de62dc8339f3965fa737d024add6d65 Mon Sep 17 00:00:00 2001 From: =?UTF-8?q?Daniel=20Lombra=C3=B1a=20Gonz=C3=A1lez?= Date: Sat, 27 Feb 2021 11:32:44 +0100 Subject: [PATCH 5/5] fix: remove unused test. --- test/test_web.py | 12 ------------ 1 file changed, 12 deletions(-) diff --git a/test/test_web.py b/test/test_web.py index ba59d78205..bcf5e59c80 100644 --- a/test/test_web.py +++ b/test/test_web.py @@ -3444,18 +3444,6 @@ def test_delete_account_json(self, mock): user = user_repo.filter_by(name='johndoe')[0] mock.assert_called_with(delete_account, user.id) - @with_context - def test_42_password_link(self): - """Test WEB visibility of password change link""" - self.register() - res = self.app.get('/account/johndoe/update') - assert "Change your Password" in str(res.data) - user = User.query.get(1) - db.session.add(user) - db.session.commit() - res = self.app.get('/account/johndoe/update') - assert "Change your Password" not in str(res.data), res.data - @with_context def test_43_terms_of_use_and_data(self): """Test WEB terms of use is working"""