Allow assigning applications to a group from the group form
Adds an "Assigned Applications" checkbox list to the group new/edit form so admins can grant a group access to multiple apps from one screen, instead of editing each application individually. Co-Authored-By: Claude Opus 4.7 (1M context) <noreply@anthropic.com>
This commit is contained in:
@@ -15,6 +15,7 @@ module Admin
|
||||
def new
|
||||
@group = Group.new
|
||||
@available_users = User.order(:email_address)
|
||||
@available_applications = Application.order(:name)
|
||||
end
|
||||
|
||||
def create
|
||||
@@ -28,6 +29,7 @@ module Admin
|
||||
@group = Group.new
|
||||
@group.errors.add(:custom_claims, "must be valid JSON")
|
||||
@available_users = User.order(:email_address)
|
||||
@available_applications = Application.order(:name)
|
||||
render :new, status: :unprocessable_entity
|
||||
return
|
||||
end
|
||||
@@ -45,15 +47,23 @@ module Admin
|
||||
@group.users = User.where(id: user_ids)
|
||||
end
|
||||
|
||||
# Handle application assignments
|
||||
if params[:group][:application_ids].present?
|
||||
application_ids = params[:group][:application_ids].reject(&:blank?)
|
||||
@group.applications = Application.where(id: application_ids)
|
||||
end
|
||||
|
||||
redirect_to admin_group_path(@group), notice: "Group created successfully."
|
||||
else
|
||||
@available_users = User.order(:email_address)
|
||||
@available_applications = Application.order(:name)
|
||||
render :new, status: :unprocessable_entity
|
||||
end
|
||||
end
|
||||
|
||||
def edit
|
||||
@available_users = User.order(:email_address)
|
||||
@available_applications = Application.order(:name)
|
||||
end
|
||||
|
||||
def update
|
||||
@@ -66,6 +76,7 @@ module Admin
|
||||
rescue JSON::ParserError
|
||||
@group.errors.add(:custom_claims, "must be valid JSON")
|
||||
@available_users = User.order(:email_address)
|
||||
@available_applications = Application.order(:name)
|
||||
render :edit, status: :unprocessable_entity
|
||||
return
|
||||
end
|
||||
@@ -83,9 +94,18 @@ module Admin
|
||||
@group.users = []
|
||||
end
|
||||
|
||||
# Handle application assignments
|
||||
if params[:group][:application_ids].present?
|
||||
application_ids = params[:group][:application_ids].reject(&:blank?)
|
||||
@group.applications = Application.where(id: application_ids)
|
||||
else
|
||||
@group.applications = []
|
||||
end
|
||||
|
||||
redirect_to admin_group_path(@group), notice: "Group updated successfully."
|
||||
else
|
||||
@available_users = User.order(:email_address)
|
||||
@available_applications = Application.order(:name)
|
||||
render :edit, status: :unprocessable_entity
|
||||
end
|
||||
end
|
||||
|
||||
@@ -32,6 +32,29 @@
|
||||
<p class="mt-1 text-sm text-gray-500 dark:text-gray-400">Select which users should be members of this group.</p>
|
||||
</div>
|
||||
|
||||
<div>
|
||||
<%= form.label :application_ids, "Assigned Applications", class: "block text-sm font-medium text-gray-700 dark:text-gray-300" %>
|
||||
<div class="mt-2 space-y-2 max-h-48 overflow-y-auto border border-gray-200 dark:border-gray-700 rounded-md p-3">
|
||||
<% if @available_applications.any? %>
|
||||
<% @available_applications.each do |application| %>
|
||||
<div class="flex items-center">
|
||||
<%= check_box_tag "group[application_ids][]", application.id, group.applications.include?(application), class: "h-4 w-4 rounded border-gray-300 dark:border-gray-600 text-blue-600 focus:ring-blue-500" %>
|
||||
<%= label_tag "group_application_ids_#{application.id}", application.name, class: "ml-2 text-sm text-gray-900 dark:text-gray-100" %>
|
||||
<% case application.app_type %>
|
||||
<% when "oidc" %>
|
||||
<span class="ml-2 inline-flex items-center rounded-full bg-purple-100 dark:bg-purple-900/50 px-2 py-0.5 text-xs font-medium text-purple-700 dark:text-purple-300">OIDC</span>
|
||||
<% when "trusted_header" %>
|
||||
<span class="ml-2 inline-flex items-center rounded-full bg-indigo-100 dark:bg-indigo-900/50 px-2 py-0.5 text-xs font-medium text-indigo-700 dark:text-indigo-300">ForwardAuth</span>
|
||||
<% end %>
|
||||
</div>
|
||||
<% end %>
|
||||
<% else %>
|
||||
<p class="text-sm text-gray-500 dark:text-gray-400">No applications available.</p>
|
||||
<% end %>
|
||||
</div>
|
||||
<p class="mt-1 text-sm text-gray-500 dark:text-gray-400">Select which applications this group grants access to.</p>
|
||||
</div>
|
||||
|
||||
<div data-controller="json-validator" data-json-validator-valid-class="border-green-500 focus:border-green-500 focus:ring-green-500" data-json-validator-invalid-class="border-red-500 focus:border-red-500 focus:ring-red-500" data-json-validator-valid-status-class="text-green-600" data-json-validator-invalid-status-class="text-red-600">
|
||||
<%= form.label :custom_claims, "Custom Claims (JSON)", class: "block text-sm font-medium text-gray-700 dark:text-gray-300" %>
|
||||
<%= form.text_area :custom_claims, value: (group.custom_claims.present? ? JSON.pretty_generate(group.custom_claims) : ""), rows: 8,
|
||||
|
||||
52
test/controllers/admin/groups_controller_test.rb
Normal file
52
test/controllers/admin/groups_controller_test.rb
Normal file
@@ -0,0 +1,52 @@
|
||||
require "test_helper"
|
||||
|
||||
module Admin
|
||||
class GroupsControllerTest < ActionDispatch::IntegrationTest
|
||||
setup do
|
||||
@admin = users(:two)
|
||||
sign_in_as(@admin)
|
||||
@group = groups(:one)
|
||||
end
|
||||
|
||||
test "update assigns applications from application_ids" do
|
||||
app_a = applications(:kavita_app)
|
||||
app_b = applications(:another_app)
|
||||
|
||||
patch admin_group_path(@group), params: {
|
||||
group: {
|
||||
name: @group.name,
|
||||
application_ids: [app_a.id, app_b.id]
|
||||
}
|
||||
}
|
||||
|
||||
assert_redirected_to admin_group_path(@group)
|
||||
assert_equal [app_a, app_b].sort, @group.reload.applications.sort
|
||||
end
|
||||
|
||||
test "update with no application_ids clears assigned applications" do
|
||||
@group.applications = [applications(:kavita_app)]
|
||||
|
||||
patch admin_group_path(@group), params: {
|
||||
group: { name: @group.name }
|
||||
}
|
||||
|
||||
assert_redirected_to admin_group_path(@group)
|
||||
assert_empty @group.reload.applications
|
||||
end
|
||||
|
||||
test "create assigns applications from application_ids" do
|
||||
app = applications(:audiobookshelf_app)
|
||||
|
||||
assert_difference -> { Group.count }, 1 do
|
||||
post admin_groups_path, params: {
|
||||
group: {
|
||||
name: "New Group",
|
||||
application_ids: [app.id]
|
||||
}
|
||||
}
|
||||
end
|
||||
|
||||
assert_equal [app], Group.find_by(name: "new group").applications
|
||||
end
|
||||
end
|
||||
end
|
||||
Reference in New Issue
Block a user