Prevent Less than 1 day old accounts from Following Other Users (#159)

* Show empty array of users for potential spammers

* Use user columns for better accuracy and perf

* Use user instead of identity for flagging

* Fix boolean

* Add page skipping logic for young accounts

* Fix test and show team to follow for spammers

* Fix broken link

* Remove page skip logic for back button
This commit is contained in:
Andy Zhao 2018-03-29 17:12:30 -04:00 committed by Ben Halpern
parent c8ae0d08c3
commit 7c843ba354
5 changed files with 38 additions and 8 deletions

View file

@ -2,14 +2,24 @@ module Api
module V0
class UsersController < ApplicationController
def index
unless user_signed_in?
@users = []
if !user_signed_in? || less_than_one_day_old?(current_user)
usernames = ["ben", "jess", "peter", "maestromac", "andy", "lianafelt"]
@users = User.where(username: usernames)
return
end
if params[:state] == "follow_suggestions"
@users = UserFollowSuggester.new(current_user).suggestions
end
end
def less_than_one_day_old?(user)
range = (Time.now.beginning_of_day - 1.day)..(Time.now)
user_identity_age = user.github_created_at ||
user.twitter_created_at ||
Time.parse(user.identity.first.auth_data_dump.extra.raw_info.created_at)
# last one is a fallback in case both are nil
range.cover? user_identity_age
end
end
end
end

View file

@ -163,11 +163,9 @@ class Onboarding extends Component {
}
handleNextButton() {
if (this.state.pageNumber === 2 && this.state.users.length === 0) {
this.getUsersToFollow();
}
if (this.state.pageNumber < 4) {
this.setState({ pageNumber: this.state.pageNumber + 1 });
} else if (this.state.pageNumber === 4) {

View file

@ -82,12 +82,30 @@ describe('<Onboarding />', () => {
text_color_hex: '#000000',
}],
});
const usersState = [
{
id: 1,
name: 'Ben Halpern',
profile_image_url: 'ben.jpg',
},
{
id: 2,
name: 'Krusty the Clown',
profile_image_url: 'clown.jpg',
},
{
id: 3,
name: 'dev.to staff',
profile_image_url: 'dev.jpg',
},
];
document.body.setAttribute('data-user', dataUser);
const meta = document.createElement('meta');
meta.setAttribute('name', 'csrf-token');
document.body.appendChild(meta);
fetch.mockResponseOnce(fakeResponse);
const context = deep(<Onboarding />, { depth: 3 });
context.setState({ users: usersState });
context.rerender();
context.find('.button').simulate('click');
// going to page two

View file

@ -17,7 +17,7 @@ class AuthorizationService
end
set_identity(identity, user)
user.skip_confirmation!
flag_spam_user(user) if account_less_than_a_week_old?(identity)
flag_spam_user(user) if account_less_than_a_week_old?(user, identity)
user
end
@ -110,9 +110,13 @@ class AuthorizationService
Identity.where(provider: identity.provider, user_id: signed_in_resource.id).any?
end
def account_less_than_a_week_old?(identity)
def account_less_than_a_week_old?(user, logged_in_identity)
user_identity_age = user.github_created_at ||
user.twitter_created_at ||
Time.parse(logged_in_identity.auth_data_dump.extra.raw_info.created_at)
# last one is a fallback in case both are nil
range = (Time.now.beginning_of_day - 1.week)..(Time.now)
range.cover? Time.parse(identity.auth_data_dump.extra.raw_info.created_at)
range.cover?(user_identity_age)
end
def flag_spam_user(user)

View file

@ -51,7 +51,7 @@
<li><a href="/membership">Sustaining Membership</a></li>
<li><a href="https://shop.dev.to/">DEV Shop</a></li>
<li><a href="/sponsors">Sponsors</a></li>
<li><a href="/Events">Events</a></li>
<li><a href="/events">Events</a></li>
<li><a href="/privacy">Privacy Policy</a></li>
<li><a href="/terms">Terms of Use</a></li>
<li><a href="/contact">Contact</a></li>