+ self.auth_provider = nil
+ self.auth_uid = nil
+
+ save
+ end
+
+ ##
+ # return a spam score for a user
+ def spam_score
+ changeset_score = changesets.size * 50
+ trace_score = traces.size * 50
+ diary_entry_score = diary_entries.visible.inject(0) { |acc, elem| acc + elem.body.spam_score }
+ diary_comment_score = diary_comments.visible.inject(0) { |acc, elem| acc + elem.body.spam_score }
+
+ score = description.spam_score / 4.0
+ score += diary_entries.where("created_at > ?", 1.day.ago).count * 10
+ score += diary_entry_score / diary_entries.length unless diary_entries.empty?
+ score += diary_comment_score / diary_comments.length unless diary_comments.empty?
+ score -= changeset_score
+ score -= trace_score
+
+ score.to_i
+ end
+
+ ##
+ # perform a spam check on a user
+ def spam_check
+ suspend! if may_suspend? && spam_score > Settings.spam_threshold
+ end
+
+ ##
+ # return an oauth 1 access token for a specified application
+ def access_token(application_key)
+ ClientApplication.find_by(:key => application_key).access_token_for_user(self)
+ end
+
+ ##
+ # return an oauth 2 access token for a specified application
+ def oauth_token(application_id)
+ application = Doorkeeper.config.application_model.find_by(:uid => application_id)
+
+ Doorkeeper.config.access_token_model.find_or_create_for(
+ :application => application,
+ :resource_owner => self,
+ :scopes => application.scopes
+ )
+ end
+
+ def fingerprint
+ digest = Digest::SHA256.new
+ digest.update(email)
+ digest.update(pass_crypt)
+ digest.hexdigest
+ end
+
+ def active_reports
+ issues
+ .with_status(:open)
+ .joins(:reports)
+ .where("reports.updated_at >= COALESCE(issues.resolved_at, '1970-01-01')")
+ .count
+ end
+
+ def max_messages_per_hour
+ account_age_in_seconds = Time.now.utc - created_at
+ account_age_in_hours = account_age_in_seconds / 3600
+ recent_messages = messages.where("sent_on >= ?", Time.now.utc - 3600).count
+ max_messages = account_age_in_hours.ceil + recent_messages - (active_reports * 10)
+ max_messages.clamp(0, Settings.max_messages_per_hour)
+ end
+
+ def max_friends_per_hour
+ account_age_in_seconds = Time.now.utc - created_at
+ account_age_in_hours = account_age_in_seconds / 3600
+ recent_friends = Friendship.where(:befriendee => self).where("created_at >= ?", Time.now.utc - 3600).count
+ max_friends = account_age_in_hours.ceil + recent_friends - (active_reports * 10)
+ max_friends.clamp(0, Settings.max_friends_per_hour)
+ end
+
+ def max_changeset_comments_per_hour
+ if moderator?
+ Settings.moderator_changeset_comments_per_hour
+ else
+ previous_comments = changeset_comments.limit(200).count
+ max_comments = previous_comments / 200.0 * Settings.max_changeset_comments_per_hour
+ max_comments = max_comments.floor.clamp(Settings.initial_changeset_comments_per_hour, Settings.max_changeset_comments_per_hour)
+ max_comments /= 2**active_reports
+ max_comments.floor.clamp(Settings.min_changeset_comments_per_hour, Settings.max_changeset_comments_per_hour)
+ end
+ end
+
+ private
+
+ def encrypt_password
+ if pass_crypt_confirmation
+ self.pass_crypt, self.pass_salt = PasswordHash.create(pass_crypt)
+ self.pass_crypt_confirmation = nil
+ end