Merge branch 'feature/user_avatars' into live
All checks were successful
continuous-integration/drone/push Build is passing

This commit is contained in:
Râu Cao 2025-05-12 16:40:44 +04:00
commit 4c972bfe7a
Signed by: raucao
GPG Key ID: 37036C356E56CC51
3 changed files with 35 additions and 18 deletions

View File

@ -4,17 +4,23 @@ class AvatarsController < ApplicationController
http_status :not_found and return unless user.avatar.attached?
sha256_hash = params[:hash]
format = params[:format].to_sym || :png
size = params[:size]&.to_sym || :large
format = params[:format]&.to_sym || :png
size = params[:size]&.to_sym || :original
unless user.avatar_filename == "#{sha256_hash}.#{format}"
unless user.avatar.filename.to_s == "#{sha256_hash}.#{format}"
http_status :not_found and return
end
send_file user.avatar.service.path_for(user.avatar.key),
disposition: "inline", type: "image/#{format}"
blob = if size == :original
user.avatar.blob
else
http_status :not_found and return
user.avatar_variant(size: size)&.blob
end
data = blob.download
send_data data, type: "image/#{format}", disposition: "inline"
else
http_status :not_found
end
end
end

View File

@ -34,10 +34,12 @@ class SettingsController < ApplicationController
end
if @user.avatar_new.present?
@user.avatar.attach(@user.avatar_new)
@user.avatar.blob.update(filename: @user.avatar_filename)
@user.save!
if store_user_avatar
LdapManager::UpdateAvatar.call(user: @user)
else
@validation_errors = @user.errors
render :show, status: :unprocessable_entity and return
end
end
if @user.pgp_pubkey && (@user.pgp_pubkey != @user.ldap_entry[:pgp_key])
@ -187,4 +189,21 @@ class SettingsController < ApplicationController
salt = BCrypt::Engine.generate_salt
BCrypt::Engine.hash_secret(password, salt)
end
def store_user_avatar
data = @user.avatar_new.tempfile.read
@user.avatar_new.tempfile.rewind
hash = Digest::SHA256.hexdigest(data)
ext = @user.avatar_new.content_type == "image/png" ? "png" : "jpg"
filename = "#{hash}.#{ext}"
if filename == @user.avatar.filename.to_s
@user.errors.add(:avatar, "must be a new file/picture")
false
else
key = "users/#{@user.cn}/avatars/#{filename}"
@user.avatar.attach io: @user.avatar_new.tempfile, key: key, filename: filename
@user.save
end
end
end

View File

@ -172,14 +172,6 @@ class User < ApplicationRecord
Base64.strict_encode64(data)
end
def avatar_filename
return nil unless avatar.attached?
data = ActiveStorage::Blob.service.download(avatar.key)
hash = Digest::SHA256.hexdigest(data)
ext = avatar.content_type == "image/png" ? "png" : "jpg"
"#{hash}.#{ext}"
end
def avatar_variant(size: :medium)
dimensions = case size
when :large then [400, 400]