Store and retrieve avatars in/from LDAP exclusively
Some checks failed
continuous-integration/drone/push Build is failing
Some checks failed
continuous-integration/drone/push Build is failing
No need to keep them in two places at the same time. We can fetch them from LDAP whenever we want to do something with them.
This commit is contained in:
parent
50c63d5c38
commit
d5ab532947
@ -20,6 +20,8 @@ class Admin::UsersController < Admin::BaseController
|
||||
end
|
||||
|
||||
@services_enabled = @user.services_enabled
|
||||
|
||||
@avatar = LdapManager::FetchAvatar.call(cn: @user.cn, ou: @user.ou)
|
||||
end
|
||||
|
||||
private
|
||||
|
@ -19,17 +19,15 @@ class SettingsController < ApplicationController
|
||||
def update
|
||||
@user.preferences.merge!(user_params[:preferences] || {})
|
||||
@user.display_name = user_params[:display_name]
|
||||
current_avatar_checksum = @user.avatar.attached? ? @user.avatar.blob.checksum : nil
|
||||
@user.avatar = user_params[:avatar] if user_params[:avatar].present?
|
||||
@user.avatar_new = user_params[:avatar]
|
||||
|
||||
if @user.save
|
||||
if @user.display_name && (@user.display_name != @user.ldap_entry[:display_name])
|
||||
LdapManager::UpdateDisplayName.call(@user.dn, @user.display_name)
|
||||
end
|
||||
|
||||
if @user.avatar.attached? &&
|
||||
(@user.avatar.blob.checksum != current_avatar_checksum)
|
||||
LdapManager::UpdateAvatar.call(@user.dn, @user.avatar_base64)
|
||||
if @user.avatar_new.present?
|
||||
LdapManager::UpdateAvatar.call(@user.dn, @user.avatar_new)
|
||||
end
|
||||
|
||||
redirect_to setting_path(@settings_section), flash: {
|
||||
|
@ -2,19 +2,10 @@ class User < ApplicationRecord
|
||||
include EmailValidatable
|
||||
|
||||
attr_accessor :display_name
|
||||
attr_accessor :avatar_new
|
||||
|
||||
serialize :preferences, UserPreferences
|
||||
|
||||
#
|
||||
# File attachments
|
||||
#
|
||||
|
||||
has_one_attached :avatar do |attachable|
|
||||
attachable.variant :small, resize_to_fill: [64, 64], convert: :jpeg
|
||||
attachable.variant :medium, resize_to_fill: [256, 256], convert: :jpeg
|
||||
attachable.variant :large, resize_to_fill: [512, 512], convert: :jpeg
|
||||
end
|
||||
|
||||
#
|
||||
# Relations
|
||||
#
|
||||
@ -167,9 +158,8 @@ class User < ApplicationRecord
|
||||
@display_name ||= ldap_entry[:display_name]
|
||||
end
|
||||
|
||||
|
||||
def avatar_base64(variant: :large)
|
||||
Base64.strict_encode64 avatar.variant(variant).processed.download
|
||||
def avatar
|
||||
@avatar_base64 ||= LdapManager::FetchAvatar.call(cn: cn, ou: ou)
|
||||
end
|
||||
|
||||
def services_enabled
|
||||
@ -202,14 +192,14 @@ class User < ApplicationRecord
|
||||
end
|
||||
|
||||
def acceptable_avatar
|
||||
return unless avatar.attached?
|
||||
return unless avatar_new.present?
|
||||
|
||||
if avatar.blob.byte_size > 1.megabyte
|
||||
if avatar_new.size > 1.megabyte
|
||||
errors.add(:avatar, "file size is too large")
|
||||
end
|
||||
|
||||
acceptable_types = ["image/jpeg", "image/png"]
|
||||
unless acceptable_types.include?(avatar.content_type)
|
||||
unless acceptable_types.include?(avatar_new.content_type)
|
||||
errors.add(:avatar, "must be a JPEG or PNG file")
|
||||
end
|
||||
end
|
||||
|
18
app/services/ldap_manager/fetch_avatar.rb
Normal file
18
app/services/ldap_manager/fetch_avatar.rb
Normal file
@ -0,0 +1,18 @@
|
||||
module LdapManager
|
||||
class FetchAvatar < LdapManagerService
|
||||
def initialize(cn:, ou: nil)
|
||||
@cn = cn
|
||||
@ou = ou
|
||||
end
|
||||
|
||||
def call
|
||||
treebase = @ou ? "ou=#{@ou},cn=users,#{suffix}" : ldap_config["base"]
|
||||
puts treebase.inspect
|
||||
attributes = %w{ jpegPhoto }
|
||||
filter = Net::LDAP::Filter.eq("cn", @cn)
|
||||
|
||||
entry = ldap_client.search(base: treebase, filter: filter, attributes: attributes).first
|
||||
entry.try(:jpegPhoto) ? entry.jpegPhoto.first : nil
|
||||
end
|
||||
end
|
||||
end
|
@ -1,12 +1,27 @@
|
||||
require "image_processing/vips"
|
||||
|
||||
module LdapManager
|
||||
class UpdateAvatar < LdapManagerService
|
||||
def initialize(dn, img_data)
|
||||
def initialize(dn, file)
|
||||
@dn = dn
|
||||
@img_data = img_data
|
||||
@img_data = process(file)
|
||||
end
|
||||
|
||||
def call
|
||||
replace_attribute @dn, :jpegPhoto, @img_data
|
||||
end
|
||||
|
||||
private
|
||||
|
||||
def process(file)
|
||||
processed = ImageProcessing::Vips
|
||||
.resize_to_fill(512, 512)
|
||||
.source(file)
|
||||
.convert("jpeg")
|
||||
.saver(strip: true)
|
||||
.call
|
||||
|
||||
Base64.strict_encode64 processed.read
|
||||
end
|
||||
end
|
||||
end
|
||||
|
@ -1,2 +1,5 @@
|
||||
class LdapManagerService < LdapService
|
||||
def suffix
|
||||
@suffix ||= ENV["LDAP_SUFFIX"] || "dc=kosmos,dc=org"
|
||||
end
|
||||
end
|
||||
|
@ -63,6 +63,10 @@
|
||||
</section>
|
||||
|
||||
<section class="sm:flex-1 sm:pt-0">
|
||||
<h3>LDAP<h3>
|
||||
<p>
|
||||
<img src="data:image/png;base64,<%= @avatar %>" class="h-48 w-48" />
|
||||
</p>
|
||||
<!-- <h3>Actions</h3> -->
|
||||
</section>
|
||||
</div>
|
||||
|
@ -39,9 +39,9 @@
|
||||
Default profile picture
|
||||
</p>
|
||||
<div class="flex items-center gap-6">
|
||||
<% if current_user.avatar.attached? %>
|
||||
<% if current_user.avatar.present? %>
|
||||
<p class="flex-none">
|
||||
<%= image_tag current_user.reload.avatar.variant(:medium), class: "h-24 w-24 rounded-lg" %>
|
||||
<%= image_tag "data:image/jpeg;base64,#{current_user.avatar}", class: "h-24 w-24 rounded-lg" %>
|
||||
</p>
|
||||
<% end %>
|
||||
<div class="grow">
|
||||
|
Loading…
x
Reference in New Issue
Block a user