diff --git a/app/controllers/admin/access_checks_controller.rb b/app/controllers/admin/access_checks_controller.rb new file mode 100644 index 0000000..de98195 --- /dev/null +++ b/app/controllers/admin/access_checks_controller.rb @@ -0,0 +1,25 @@ +module Admin + class AccessChecksController < BaseController + def new + load_options + end + + def create + load_options + @user = User.find_by(id: params[:user_id]) + @application = Application.find_by(id: params[:application_id]) + return render :new unless @user && @application + + @allowed = @application.user_allowed?(@user) + @via = @user.groups & @application.allowed_groups + render :new + end + + private + + def load_options + @users = User.order(:email_address) + @applications = Application.order(:name) + end + end +end diff --git a/app/controllers/admin/applications_controller.rb b/app/controllers/admin/applications_controller.rb index dc7e8ce..2fc6781 100644 --- a/app/controllers/admin/applications_controller.rb +++ b/app/controllers/admin/applications_controller.rb @@ -3,7 +3,21 @@ module Admin before_action :set_application, only: [:show, :edit, :update, :destroy, :regenerate_credentials] def index - @applications = Application.order(created_at: :desc) + @applications = Application.order(created_at: :desc).includes(:allowed_groups) + + # Distinct active users that have access to each app, preloaded to avoid N+1. + @user_count_by_app = User.where(status: User.statuses[:active]) + .joins(groups: :applications) + .group("applications.id") + .distinct + .count("users.id") + + # Top-of-page summary + @total_users_with_access = User.where(status: User.statuses[:active]) + .joins(groups: :applications) + .distinct + .count("users.id") + @total_groups_granting_access = Group.joins(:applications).distinct.count end def show diff --git a/app/views/admin/access_checks/new.html.erb b/app/views/admin/access_checks/new.html.erb new file mode 100644 index 0000000..c3a5a7b --- /dev/null +++ b/app/views/admin/access_checks/new.html.erb @@ -0,0 +1,77 @@ +
Pick a user and an application to see whether the user can access it and, if so, which group(s) grant that access.
+"> + <%= @user.email_address %> <%= @allowed ? "can access" : "cannot access" %> <%= @application.name %>. +
+ <% if @allowed %> ++ Granted via: + <% @via.each_with_index do |g, i| %> + <%= link_to g.name, admin_group_path(g), class: "underline" %><%= "," unless i == @via.size - 1 %> + <% end %> +
+ <% else %> ++ <% reasons = [] %> + <% reasons << "the application is inactive" unless @application.active? %> + <% reasons << "the user is #{@user.status.humanize.downcase}" unless @user.active? %> + <% if @application.active? && @user.active? %> + <% if @application.allowed_groups.empty? %> + <% reasons << "the application has no allowed groups (default deny)" %> + <% else %> + <% reasons << "the user shares no group with the application's allowed groups" %> + <% end %> + <% end %> + Reason: <%= reasons.join("; ") %>. +
+ <% end %> ++ <%= link_to "View user", admin_user_path(@user), class: "underline" %> · + <%= link_to "View application", admin_application_path(@application), class: "underline" %> +
+