redmine-role-groups/app/controllers/role_groups_controller.rb
ioresponse 16263fdccb Initial commit: Redmine Role Groups Plugin
🤖 Generated with Claude Code
2025-12-23 00:22:07 +09:00

226 lines
5.6 KiB
Ruby

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