Merge branch 'feature/user_avatars' into live
All checks were successful
continuous-integration/drone/push Build is passing
All checks were successful
continuous-integration/drone/push Build is passing
This commit is contained in:
commit
9a406b8381
@ -5,19 +5,20 @@ class AvatarsController < ApplicationController
|
|||||||
|
|
||||||
sha256_hash = params[:hash]
|
sha256_hash = params[:hash]
|
||||||
format = params[:format]&.to_sym || :png
|
format = params[:format]&.to_sym || :png
|
||||||
size = params[:size]&.to_sym || :original
|
# size = params[:size]&.to_sym || :original
|
||||||
|
|
||||||
unless user.avatar.filename.to_s == "#{sha256_hash}.#{format}"
|
unless user.avatar.filename.to_s == "#{sha256_hash}.#{format}"
|
||||||
http_status :not_found and return
|
http_status :not_found and return
|
||||||
end
|
end
|
||||||
|
|
||||||
blob = if size == :original
|
# TODO See note for avatar_variant in user model
|
||||||
user.avatar.blob
|
# blob = if size == :original
|
||||||
else
|
# user.avatar.blob
|
||||||
user.avatar_variant(size: size)&.blob
|
# else
|
||||||
end
|
# user.avatar_variant(size: size)&.blob
|
||||||
|
# end
|
||||||
|
|
||||||
data = blob.download
|
data = user.avatar.blob.download
|
||||||
send_data data, type: "image/#{format}", disposition: "inline"
|
send_data data, type: "image/#{format}", disposition: "inline"
|
||||||
else
|
else
|
||||||
http_status :not_found
|
http_status :not_found
|
||||||
|
@ -191,9 +191,14 @@ class SettingsController < ApplicationController
|
|||||||
end
|
end
|
||||||
|
|
||||||
def store_user_avatar
|
def store_user_avatar
|
||||||
data = @user.avatar_new.tempfile.read
|
io = @user.avatar_new.tempfile
|
||||||
@user.avatar_new.tempfile.rewind
|
img_data = process_avatar(io)
|
||||||
hash = Digest::SHA256.hexdigest(data)
|
tempfile = Tempfile.create
|
||||||
|
tempfile.binmode
|
||||||
|
tempfile.write(img_data)
|
||||||
|
tempfile.rewind
|
||||||
|
|
||||||
|
hash = Digest::SHA256.hexdigest(img_data)
|
||||||
ext = @user.avatar_new.content_type == "image/png" ? "png" : "jpg"
|
ext = @user.avatar_new.content_type == "image/png" ? "png" : "jpg"
|
||||||
filename = "#{hash}.#{ext}"
|
filename = "#{hash}.#{ext}"
|
||||||
|
|
||||||
@ -202,8 +207,22 @@ class SettingsController < ApplicationController
|
|||||||
false
|
false
|
||||||
else
|
else
|
||||||
key = "users/#{@user.cn}/avatars/#{filename}"
|
key = "users/#{@user.cn}/avatars/#{filename}"
|
||||||
@user.avatar.attach io: @user.avatar_new.tempfile, key: key, filename: filename
|
@user.avatar.attach io: tempfile, key: key, filename: filename
|
||||||
@user.save
|
@user.save
|
||||||
end
|
end
|
||||||
end
|
end
|
||||||
|
|
||||||
|
def process_avatar(io)
|
||||||
|
processed = ImageProcessing::Vips
|
||||||
|
.source(io)
|
||||||
|
.resize_to_fill(400, 400)
|
||||||
|
.saver(strip: true)
|
||||||
|
.call
|
||||||
|
io.rewind
|
||||||
|
processed.read
|
||||||
|
rescue Vips::Error => e
|
||||||
|
Sentry.capture_exception(e) if Setting.sentry_enabled?
|
||||||
|
Rails.logger.error { "Image processing failed for avatar: #{e.message}" }
|
||||||
|
nil
|
||||||
|
end
|
||||||
end
|
end
|
||||||
|
@ -56,6 +56,7 @@ class User < ApplicationRecord
|
|||||||
validates_length_of :display_name, minimum: 3, maximum: 35, allow_blank: true,
|
validates_length_of :display_name, minimum: 3, maximum: 35, allow_blank: true,
|
||||||
if: -> { defined?(@display_name) }
|
if: -> { defined?(@display_name) }
|
||||||
|
|
||||||
|
|
||||||
validate :acceptable_avatar
|
validate :acceptable_avatar
|
||||||
|
|
||||||
validate :acceptable_pgp_key_format, if: -> { defined?(@pgp_pubkey) && @pgp_pubkey.present? }
|
validate :acceptable_pgp_key_format, if: -> { defined?(@pgp_pubkey) && @pgp_pubkey.present? }
|
||||||
@ -83,6 +84,10 @@ class User < ApplicationRecord
|
|||||||
:timeoutable,
|
:timeoutable,
|
||||||
:rememberable
|
:rememberable
|
||||||
|
|
||||||
|
#
|
||||||
|
# Methods
|
||||||
|
#
|
||||||
|
|
||||||
def ldap_before_save
|
def ldap_before_save
|
||||||
self.email = Devise::LDAP::Adapter.get_ldap_param(self.cn, "mail").first
|
self.email = Devise::LDAP::Adapter.get_ldap_param(self.cn, "mail").first
|
||||||
self.ou = dn.split(',')
|
self.ou = dn.split(',')
|
||||||
@ -165,23 +170,19 @@ class User < ApplicationRecord
|
|||||||
@display_name ||= ldap_entry[:display_name]
|
@display_name ||= ldap_entry[:display_name]
|
||||||
end
|
end
|
||||||
|
|
||||||
def avatar_base64(size: :medium)
|
# TODO Variant keys are currently broken for some reason
|
||||||
return nil unless avatar.attached?
|
# (They use the same key as the main blob, when it should be
|
||||||
variant = avatar_variant(size: size)
|
# "/variants/#{key)"
|
||||||
data = ActiveStorage::Blob.service.download(variant.key)
|
# def avatar_variant(size: :medium)
|
||||||
Base64.strict_encode64(data)
|
# dimensions = case size
|
||||||
end
|
# when :large then [400, 400]
|
||||||
|
# when :medium then [256, 256]
|
||||||
def avatar_variant(size: :medium)
|
# when :small then [64, 64]
|
||||||
dimensions = case size
|
# else [256, 256]
|
||||||
when :large then [400, 400]
|
# end
|
||||||
when :medium then [256, 256]
|
# format = avatar.content_type == "image/png" ? :png : :jpeg
|
||||||
when :small then [64, 64]
|
# avatar.variant(resize_to_fill: dimensions, format: format)
|
||||||
else [256, 256]
|
# end
|
||||||
end
|
|
||||||
format = avatar.content_type == "image/png" ? :png : :jpeg
|
|
||||||
avatar.variant(resize_to_fill: dimensions, format: format)
|
|
||||||
end
|
|
||||||
|
|
||||||
def nostr_pubkey
|
def nostr_pubkey
|
||||||
@nostr_pubkey ||= ldap_entry[:nostr_key]
|
@nostr_pubkey ||= ldap_entry[:nostr_key]
|
||||||
|
@ -14,15 +14,16 @@ module LdapManager
|
|||||||
end
|
end
|
||||||
|
|
||||||
img_data = @user.avatar.blob.download
|
img_data = @user.avatar.blob.download
|
||||||
jpg_data = process(img_data)
|
jpg_data = process_avatar
|
||||||
|
|
||||||
|
Rails.logger.debug { "Storing new jpegPhoto for user #{@user.cn} in LDAP" }
|
||||||
result = replace_attribute(@dn, :jpegPhoto, jpg_data)
|
result = replace_attribute(@dn, :jpegPhoto, jpg_data)
|
||||||
result == 0
|
result == 0
|
||||||
end
|
end
|
||||||
|
|
||||||
private
|
private
|
||||||
|
|
||||||
def process(data)
|
def process_avatar
|
||||||
@user.avatar.blob.open do |file|
|
@user.avatar.blob.open do |file|
|
||||||
processed = ImageProcessing::Vips
|
processed = ImageProcessing::Vips
|
||||||
.source(file)
|
.source(file)
|
||||||
|
@ -38,8 +38,7 @@
|
|||||||
<div class="flex items-center gap-6">
|
<div class="flex items-center gap-6">
|
||||||
<% if @user.avatar.attached? %>
|
<% if @user.avatar.attached? %>
|
||||||
<p class="flex-none">
|
<p class="flex-none">
|
||||||
<%= image_tag @user.avatar_variant(size: :medium),
|
<%= image_tag image_url_for(@user.avatar), class: "h-24 w-24 rounded-lg" %>
|
||||||
class: "h-24 w-24 rounded-lg" %>
|
|
||||||
</p>
|
</p>
|
||||||
<% end %>
|
<% end %>
|
||||||
<div class="grow">
|
<div class="grow">
|
||||||
|
Loading…
x
Reference in New Issue
Block a user