Add user avatars to LDAP, upload on profile settings page #148
@ -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
|
||||
|
raucao marked this conversation as resolved
|
||||
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" />
|
||||
|
raucao marked this conversation as resolved
Outdated
galfert
commented
Shouldn't this be Shouldn't this be `image/jpeg`?
raucao
commented
Yes! Thanks. Yes! Thanks.
|
||||
</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
✂️