docbrown/app/services/authorization_service.rb
Andy Zhao 7c843ba354 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
2018-03-29 17:12:30 -04:00

130 lines
3.9 KiB
Ruby

class AuthorizationService
attr_accessor :auth, :signed_in_resource, :cta_variant
def initialize(auth, signed_in_resource = nil, cta_variant=nil)
@auth = auth
@signed_in_resource = signed_in_resource
@cta_variant = cta_variant
end
def get_user
identity = build_identity
return signed_in_resource if user_identity_exists(identity)
user = proper_user(identity)
user = if user.nil?
build_user(identity)
else
update_user(user)
end
set_identity(identity, user)
user.skip_confirmation!
flag_spam_user(user) if account_less_than_a_week_old?(user, identity)
user
end
def add_social_identity_data(user)
return unless auth && auth.provider && auth.extra && auth.extra.raw_info
if auth.provider == "twitter"
user.twitter_created_at = auth.extra.raw_info.created_at
user.twitter_followers_count = auth.extra.raw_info.followers_count.to_i
user.twitter_following_count = auth.extra.raw_info.friends_count.to_i
else
user.github_created_at = auth.extra.raw_info.created_at
end
end
def see_onboarding?
!cta_variant.nil? &&
(cta_variant == "navbar_basic" ||
cta_variant&.include?("notifications") ||
cta_variant&.include?("welcome-widget") ||
cta_variant&.include?("in-feed-cta"))
end
def build_identity
identity = Identity.find_for_oauth(auth)
identity.token = auth.credentials.token
identity.secret = auth.credentials.secret
identity.auth_data_dump = auth
identity.save
identity
end
def build_user(identity)
user = User.where("#{identity.provider}_username" => auth.info.nickname).first
if user.nil?
user = User.new(
name: auth.extra.raw_info.name,
remote_profile_image_url: (auth.info.image || "").gsub("_normal", ""),
github_username: (auth.info.nickname if auth.provider == "github"),
signup_cta_variant: cta_variant,
email: auth.info.email || "",
twitter_username: (auth.info.nickname if auth.provider == "twitter"),
password: Devise.friendly_token[0, 20],
)
if user.name.blank?
user.name = auth.info.nickname
end
user.skip_confirmation!
user.remember_me!
user.remember_me = true
add_social_identity_data(user)
user.saw_onboarding = !see_onboarding?
user.save!
end
user
end
def update_user(user)
if auth.provider == "github" && auth.info.nickname != user.github_username
user.github_username = auth.info.nickname
end
if auth.provider == "twitter" && auth.info.nickname != user.twitter_username
user.twitter_username = auth.info.nickname
end
user.remember_me!
user.remember_me = true
add_social_identity_data(user)
user.save
user
end
def proper_user(identity)
if signed_in_resource
signed_in_resource
elsif identity.user
identity.user
elsif !auth.info.email.blank?
User.find_by_email(auth.info.email)
end
end
def set_identity(identity, user)
if identity.user_id.blank?
identity.user = user
identity.save!
end
end
def user_identity_exists(identity)
signed_in_resource &&
Identity.where(provider: identity.provider, user_id: signed_in_resource.id).any?
end
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?(user_identity_age)
end
def flag_spam_user(user)
SlackBot.ping(
"Potential spam user! https://dev.to/#{user.username}",
channel: "abuse-reports",
username: "spam_account_checker_bot",
icon_emoji: ":exclamation:",
)
end
end