class RoleGroupsController < ApplicationController layout 'admin' before_action :require_admin before_action :find_role_group, only: [:show, :edit, :update, :destroy, :add_member, :remove_member] def index @role_groups = RoleGroup.sorted.includes(:users) end def show @members = @role_group.role_group_members.includes(:user).order('users.lastname, users.firstname') end def new @role_group = RoleGroup.new end def create @role_group = RoleGroup.new(role_group_params) if @role_group.save flash[:notice] = l(:notice_successful_create) redirect_to '/role_groups' else render :new end end def edit end def update if @role_group.update(role_group_params) flash[:notice] = l(:notice_successful_update) redirect_to '/role_groups' else render :edit end end def destroy @role_group.destroy flash[:notice] = l(:notice_successful_delete) redirect_to '/role_groups' end def add_member user = find_or_create_user_from_ldap(params[:user_id], params[:ldap_uid], params[:ldap_id]) if user member = @role_group.role_group_members.find_or_initialize_by(user: user) member.note = params[:note] if member.save flash[:notice] = "#{user.name} 추가됨" else flash[:error] = member.errors.full_messages.join(', ') end else flash[:error] = '사용자를 찾을 수 없습니다' end redirect_to role_group_path(@role_group) end def remove_member member = @role_group.role_group_members.find_by(user_id: params[:user_id]) if member member.destroy flash[:notice] = '멤버 제거됨' end redirect_to role_group_path(@role_group) end def search_ldap query = params[:q].to_s.strip if query.length < 2 render json: [] return end results = [] AuthSourceLdap.all.each do |ldap| begin ldap_users = search_ldap_users(ldap, query) ldap_users.each do |entry| uid = entry[ldap.attr_login]&.first next unless uid existing_user = User.find_by(login: uid) results << { uid: uid, name: "#{entry[ldap.attr_firstname]&.first} #{entry[ldap.attr_lastname]&.first}".strip, email: entry[ldap.attr_mail]&.first, ldap_id: ldap.id, exists: existing_user.present?, user_id: existing_user&.id } end rescue => e Rails.logger.error "LDAP search error: #{e.message}" end end render json: results.uniq { |r| r[:uid] }.first(20) end private def find_role_group @role_group = RoleGroup.find(params[:id]) rescue ActiveRecord::RecordNotFound render_404 end def role_group_params params.require(:role_group).permit(:name, :description, :color, :position) end def search_ldap_users(ldap, query) options = { host: ldap.host, port: ldap.port, auth: { method: :simple, username: ldap.account, password: ldap.account_password } } if ldap.tls if ldap.verify_peer options[:encryption] = { method: :simple_tls } else options[:encryption] = { method: :simple_tls, tls_options: { verify_mode: OpenSSL::SSL::VERIFY_NONE } } end end conn = Net::LDAP.new(options) filter = Net::LDAP::Filter.begins(ldap.attr_login, query) | Net::LDAP::Filter.begins(ldap.attr_firstname, query) | Net::LDAP::Filter.begins(ldap.attr_lastname, query) if ldap.filter.present? base_filter = Net::LDAP::Filter.construct(ldap.filter) filter = base_filter & filter end conn.search( base: ldap.base_dn, filter: filter, attributes: [ldap.attr_login, ldap.attr_firstname, ldap.attr_lastname, ldap.attr_mail], size: 20 ) || [] end def find_or_create_user_from_ldap(user_id, ldap_uid, ldap_id) return User.find(user_id) if user_id.present? return nil if ldap_uid.blank? user = User.find_by(login: ldap_uid) return user if user ldap = AuthSourceLdap.find_by(id: ldap_id) return nil unless ldap user_info = get_ldap_user_info(ldap, ldap_uid) return nil unless user_info user = User.new( login: ldap_uid, firstname: user_info[:firstname] || ldap_uid, lastname: user_info[:lastname] || '-', mail: user_info[:mail] || "#{ldap_uid}@example.com", auth_source_id: ldap.id, status: User::STATUS_ACTIVE ) user.random_password user.save ? user : nil end def get_ldap_user_info(ldap, uid) options = { host: ldap.host, port: ldap.port, auth: { method: :simple, username: ldap.account, password: ldap.account_password } } if ldap.tls if ldap.verify_peer options[:encryption] = { method: :simple_tls } else options[:encryption] = { method: :simple_tls, tls_options: { verify_mode: OpenSSL::SSL::VERIFY_NONE } } end end conn = Net::LDAP.new(options) filter = Net::LDAP::Filter.eq(ldap.attr_login, uid) if ldap.filter.present? base_filter = Net::LDAP::Filter.construct(ldap.filter) filter = base_filter & filter end result = conn.search( base: ldap.base_dn, filter: filter, attributes: [ldap.attr_login, ldap.attr_firstname, ldap.attr_lastname, ldap.attr_mail], size: 1 )&.first return nil unless result { firstname: result[ldap.attr_firstname]&.first, lastname: result[ldap.attr_lastname]&.first, mail: result[ldap.attr_mail]&.first } end end