diff options
Diffstat (limited to 'app/models/concerns')
-rw-r--r-- | app/models/concerns/account_avatar.rb | 6 | ||||
-rw-r--r-- | app/models/concerns/account_header.rb | 6 | ||||
-rw-r--r-- | app/models/concerns/omniauthable.rb | 85 | ||||
-rw-r--r-- | app/models/concerns/paginable.rb | 9 | ||||
-rw-r--r-- | app/models/concerns/relationship_cacheable.rb | 16 | ||||
-rw-r--r-- | app/models/concerns/remotable.rb | 6 |
6 files changed, 121 insertions, 7 deletions
diff --git a/app/models/concerns/account_avatar.rb b/app/models/concerns/account_avatar.rb index 8a5c9a22c..9e34a9461 100644 --- a/app/models/concerns/account_avatar.rb +++ b/app/models/concerns/account_avatar.rb @@ -7,8 +7,8 @@ module AccountAvatar class_methods do def avatar_styles(file) - styles = { original: '120x120#' } - styles[:static] = { format: 'png', convert_options: '-coalesce' } if file.content_type == 'image/gif' + styles = { original: { geometry: '400x400#', file_geometry_parser: FastGeometryParser } } + styles[:static] = { geometry: '400x400#', format: 'png', convert_options: '-coalesce', file_geometry_parser: FastGeometryParser } if file.content_type == 'image/gif' styles end @@ -17,7 +17,7 @@ module AccountAvatar included do # Avatar upload - has_attached_file :avatar, styles: ->(f) { avatar_styles(f) }, convert_options: { all: '-quality 80 -strip' } + has_attached_file :avatar, styles: ->(f) { avatar_styles(f) }, convert_options: { all: '-strip' }, processors: [:lazy_thumbnail] validates_attachment_content_type :avatar, content_type: IMAGE_MIME_TYPES validates_attachment_size :avatar, less_than: 2.megabytes end diff --git a/app/models/concerns/account_header.rb b/app/models/concerns/account_header.rb index aff2aa3f9..04c576b28 100644 --- a/app/models/concerns/account_header.rb +++ b/app/models/concerns/account_header.rb @@ -7,8 +7,8 @@ module AccountHeader class_methods do def header_styles(file) - styles = { original: '700x335#' } - styles[:static] = { format: 'png', convert_options: '-coalesce' } if file.content_type == 'image/gif' + styles = { original: { geometry: '700x335#', file_geometry_parser: FastGeometryParser } } + styles[:static] = { geometry: '700x335#', format: 'png', convert_options: '-coalesce', file_geometry_parser: FastGeometryParser } if file.content_type == 'image/gif' styles end @@ -17,7 +17,7 @@ module AccountHeader included do # Header upload - has_attached_file :header, styles: ->(f) { header_styles(f) }, convert_options: { all: '-quality 80 -strip' } + has_attached_file :header, styles: ->(f) { header_styles(f) }, convert_options: { all: '-strip' }, processors: [:lazy_thumbnail] validates_attachment_content_type :header, content_type: IMAGE_MIME_TYPES validates_attachment_size :header, less_than: 2.megabytes end diff --git a/app/models/concerns/omniauthable.rb b/app/models/concerns/omniauthable.rb new file mode 100644 index 000000000..50288e700 --- /dev/null +++ b/app/models/concerns/omniauthable.rb @@ -0,0 +1,85 @@ +# frozen_string_literal: true + +module Omniauthable + extend ActiveSupport::Concern + + TEMP_EMAIL_PREFIX = 'change@me' + TEMP_EMAIL_REGEX = /\Achange@me/ + + included do + def omniauth_providers + Devise.omniauth_configs.keys + end + + def email_verified? + email && email !~ TEMP_EMAIL_REGEX + end + end + + class_methods do + def find_for_oauth(auth, signed_in_resource = nil) + # EOLE-SSO Patch + auth.uid = (auth.uid[0][:uid] || auth.uid[0][:user]) if auth.uid.is_a? Hashie::Array + identity = Identity.find_for_oauth(auth) + + # If a signed_in_resource is provided it always overrides the existing user + # to prevent the identity being locked with accidentally created accounts. + # Note that this may leave zombie accounts (with no associated identity) which + # can be cleaned up at a later date. + user = signed_in_resource ? signed_in_resource : identity.user + user = create_for_oauth(auth) if user.nil? + + if identity.user.nil? + identity.user = user + identity.save! + end + + user + end + + def create_for_oauth(auth) + # Check if the user exists with provided email if the provider gives us a + # verified email. If no verified email was provided or the user already + # exists, we assign a temporary email and ask the user to verify it on + # the next step via Auth::ConfirmationsController.finish_signup + + user = User.new(user_params_from_auth(auth)) + user.account.avatar_remote_url = auth.info.image if auth.info.image =~ /\A#{URI.regexp(%w(http https))}\z/ + user.skip_confirmation! + user.save! + user + end + + private + + def user_params_from_auth(auth) + strategy = Devise.omniauth_configs[auth.provider.to_sym].strategy + assume_verified = strategy.try(:security).try(:assume_email_is_verified) + email_is_verified = auth.info.verified || auth.info.verified_email || assume_verified + email = auth.info.verified_email || auth.info.email + email = email_is_verified && !User.exists?(email: auth.info.email) && email + display_name = auth.info.full_name || [auth.info.first_name, auth.info.last_name].join(' ') + + { + email: email ? email : "#{TEMP_EMAIL_PREFIX}-#{auth.uid}-#{auth.provider}.com", + password: Devise.friendly_token[0, 20], + account_attributes: { + username: ensure_unique_username(auth.uid), + display_name: display_name, + }, + } + end + + def ensure_unique_username(starting_username) + username = starting_username + i = 0 + + while Account.exists?(username: username) + i += 1 + username = "#{starting_username}_#{i}" + end + + username + end + end +end diff --git a/app/models/concerns/paginable.rb b/app/models/concerns/paginable.rb index 6061bf9bd..66695677e 100644 --- a/app/models/concerns/paginable.rb +++ b/app/models/concerns/paginable.rb @@ -10,5 +10,14 @@ module Paginable query = query.where(arel_table[:id].gt(since_id)) if since_id.present? query } + + # Differs from :paginate_by_max_id in that it gives the results immediately following min_id, + # whereas since_id gives the items with largest id, but with since_id as a cutoff. + # Results will be in ascending order by id. + scope :paginate_by_min_id, ->(limit, min_id = nil) { + query = reorder(arel_table[:id]).limit(limit) + query = query.where(arel_table[:id].gt(min_id)) if min_id.present? + query + } end end diff --git a/app/models/concerns/relationship_cacheable.rb b/app/models/concerns/relationship_cacheable.rb new file mode 100644 index 000000000..0d9359f7e --- /dev/null +++ b/app/models/concerns/relationship_cacheable.rb @@ -0,0 +1,16 @@ +# frozen_string_literal: true + +module RelationshipCacheable + extend ActiveSupport::Concern + + included do + after_commit :remove_relationship_cache + end + + private + + def remove_relationship_cache + Rails.cache.delete("relationship:#{account_id}:#{target_account_id}") + Rails.cache.delete("relationship:#{target_account_id}:#{account_id}") + end +end diff --git a/app/models/concerns/remotable.rb b/app/models/concerns/remotable.rb index 990035b34..020303a2f 100644 --- a/app/models/concerns/remotable.rb +++ b/app/models/concerns/remotable.rb @@ -28,7 +28,11 @@ module Remotable matches = response.headers['content-disposition']&.match(/filename="([^"]*)"/) filename = matches.nil? ? parsed_url.path.split('/').last : matches[1] basename = SecureRandom.hex(8) - extname = File.extname(filename) + extname = if filename.nil? + '' + else + File.extname(filename) + end send("#{attachment_name}=", StringIO.new(response.to_s)) send("#{attachment_name}_file_name=", basename + extname) |