From b7eecc439c426e2edeafacf0f1f27793212e0693 Mon Sep 17 00:00:00 2001 From: Echo Date: Sat, 5 Jul 2025 23:23:03 -0400 Subject: [PATCH] pass 2 on perms --- app/assets/stylesheets/application.css | 12 +++- app/controllers/admin/base_controller.rb | 2 +- .../trust_level_audit_logs_controller.rb | 2 +- .../api/admin/application_controller.rb | 2 +- app/controllers/sessions_controller.rb | 2 +- app/helpers/application_helper.rb | 10 +++ app/models/user.rb | 2 +- app/views/admin/timeline/show.html.erb | 30 ++++----- .../trust_level_audit_logs/index.html.erb | 10 ++- .../trust_level_audit_logs/show.html.erb | 10 ++- app/views/layouts/application.html.erb | 5 +- app/views/shared/_nav.html.erb | 65 ++++++++++++++----- app/views/shared/_user_mention.html.erb | 2 +- app/views/static_pages/_admin_level.erb | 8 +++ config/routes.rb | 40 +++++++----- 15 files changed, 137 insertions(+), 65 deletions(-) create mode 100644 app/views/static_pages/_admin_level.erb diff --git a/app/assets/stylesheets/application.css b/app/assets/stylesheets/application.css index 251ef51..329f1c5 100644 --- a/app/assets/stylesheets/application.css +++ b/app/assets/stylesheets/application.css @@ -50,9 +50,19 @@ select { color-scheme: dark; } +.superadmin-tool { + border-radius: 5px; + border: 1px dashed rgb(251, 44, 54); + background-color: rgba(255, 255, 255, 0.02); +} .admin-tool { border-radius: 5px; - border: 1px dashed hsl(24.9, 100%, 67.8%); + border: 1px dashed rgb(240, 177, 0); + background-color: rgba(255, 255, 255, 0.02); +} +.viewer-tool { + border-radius: 5px; + border: 1px dashed rgb(43, 127, 255); background-color: rgba(255, 255, 255, 0.02); } .dev-tool { diff --git a/app/controllers/admin/base_controller.rb b/app/controllers/admin/base_controller.rb index 96811b0..00fc6ad 100644 --- a/app/controllers/admin/base_controller.rb +++ b/app/controllers/admin/base_controller.rb @@ -4,7 +4,7 @@ class Admin::BaseController < ApplicationController private def authenticate_admin! - unless current_user && (current_user.admin_level == "admin" || current_user.admin_level == "superadmin") + unless current_user && current_user.admin_level.in?([ "admin", "superadmin", "viewer" ]) redirect_to root_path, alert: "You are not authorized to access this page." end end diff --git a/app/controllers/admin/trust_level_audit_logs_controller.rb b/app/controllers/admin/trust_level_audit_logs_controller.rb index b16600d..5b86835 100644 --- a/app/controllers/admin/trust_level_audit_logs_controller.rb +++ b/app/controllers/admin/trust_level_audit_logs_controller.rb @@ -66,7 +66,7 @@ class Admin::TrustLevelAuditLogsController < Admin::BaseController private def require_admin - unless current_user && (current_user.admin_level == "admin" || current_user.admin_level == "superadmin") + unless current_user && current_user.admin_level.in?([ "admin", "superadmin", "viewer" ]) redirect_to root_path, alert: "no perms lmaooo" end end diff --git a/app/controllers/api/admin/application_controller.rb b/app/controllers/api/admin/application_controller.rb index 51917f1..975e3d3 100644 --- a/app/controllers/api/admin/application_controller.rb +++ b/app/controllers/api/admin/application_controller.rb @@ -13,7 +13,7 @@ module Api if @admin_api_key @current_user = @admin_api_key.user - @current_user.admin? + @current_user.admin_level.in?([ "admin", "superadmin" ]) else false end diff --git a/app/controllers/sessions_controller.rb b/app/controllers/sessions_controller.rb index b38ad3e..04e6a94 100644 --- a/app/controllers/sessions_controller.rb +++ b/app/controllers/sessions_controller.rb @@ -169,7 +169,7 @@ class SessionsController < ApplicationController end def impersonate - unless current_user.admin? + unless current_user && current_user.admin_level.in?([ "admin", "superadmin" ]) redirect_to root_path, alert: "You are not authorized to impersonate users" return end diff --git a/app/helpers/application_helper.rb b/app/helpers/application_helper.rb index 485db08..3bb74ff 100644 --- a/app/helpers/application_helper.rb +++ b/app/helpers/application_helper.rb @@ -15,11 +15,21 @@ module ApplicationHelper rps == :high_load ? "lots of req/sec" : "#{rps} req/sec (global)" end + def superadmin_tool(class_name = "", element = "div", **options, &block) + return unless current_user && (current_user.admin_level == "superadmin") + concat content_tag(element, class: "superadmin-tool #{class_name}", **options, &block) + end + def admin_tool(class_name = "", element = "div", **options, &block) return unless current_user && (current_user.admin_level == "admin" || current_user.admin_level == "superadmin") concat content_tag(element, class: "admin-tool #{class_name}", **options, &block) end + def viewer_tool(class_name = "", element = "div", **options, &block) + return unless current_user && (current_user.admin_level == "viewer") + concat content_tag(element, class: "viewer-tool #{class_name}", **options, &block) + end + def dev_tool(class_name = "", element = "div", **options, &block) return unless Rails.env.development? concat content_tag(element, class: "dev-tool #{class_name}", **options, &block) diff --git a/app/models/user.rb b/app/models/user.rb index 9133549..51d4a09 100644 --- a/app/models/user.rb +++ b/app/models/user.rb @@ -51,7 +51,7 @@ class User < ApplicationRecord previous_level = trust_level - if changed_by_user.present? && level.to_s == "red" && !changed_by_user.superadmin? + if changed_by_user.present? && level.to_s == "red" && !(changed_by_user.superadmin? || changed_by_user.admin_level_admin?) return false end diff --git a/app/views/admin/timeline/show.html.erb b/app/views/admin/timeline/show.html.erb index 3c6d25f..d3b78fd 100644 --- a/app/views/admin/timeline/show.html.erb +++ b/app/views/admin/timeline/show.html.erb @@ -2,8 +2,7 @@ <%# Instance variables: @users_with_timeline_data, @primary_user, @date, @next_date, @prev_date %> <% content_for :head do %> - - + <% end %> <% @@ -189,7 +188,7 @@
<%= trust_level_emoji %>
- <% if current_user && current_user.admin? && user != current_user %> + <% if current_user && current_user.admin_level.in?(["admin", "superadmin"]) && user != current_user %>
diff --git a/app/views/admin/trust_level_audit_logs/show.html.erb b/app/views/admin/trust_level_audit_logs/show.html.erb index d93fff7..6e2c2e6 100644 --- a/app/views/admin/trust_level_audit_logs/show.html.erb +++ b/app/views/admin/trust_level_audit_logs/show.html.erb @@ -36,14 +36,18 @@
<%= render "shared/user_mention", user: @audit_log.changed_by %> - <% if @audit_log.changed_by.superadmin? %> + <% if @audit_log.changed_by.admin_level == "superadmin" %> supa admin - <% elsif @audit_log.changed_by.admin? %> - + <% elsif @audit_log.changed_by.admin_level == "admin" %> + admin + <% elsif @audit_log.changed_by.admin_level == "viewer" %> + + viewer + <% end %>
diff --git a/app/views/layouts/application.html.erb b/app/views/layouts/application.html.erb index f3412d1..331807d 100644 --- a/app/views/layouts/application.html.erb +++ b/app/views/layouts/application.html.erb @@ -41,8 +41,9 @@ <%= csp_meta_tag %> <% if current_user %> - - + "> + "> + "> <% end %> <%= yield :head %> diff --git a/app/views/shared/_nav.html.erb b/app/views/shared/_nav.html.erb index 48236c5..8dc5076 100644 --- a/app/views/shared/_nav.html.erb +++ b/app/views/shared/_nav.html.erb @@ -16,6 +16,9 @@
<%= render "shared/user_mention", user: current_user %> <%= render "static_pages/streak", user: current_user, show_text: true, turbo_frame: false %> + <% if current_user.admin_level != 0 %> + <%= render "static_pages/admin_level", user: current_user %> + <% end %>
<% else %>
@@ -52,7 +55,7 @@ Docs <% end %>
- <% admin_tool(nil, "div") do %> + <% superadmin_tool(nil, "div") do %> <%= link_to my_mailing_address_path, class: "block px-2 py-1 rounded-lg transition #{current_page?(my_mailing_address_path) ? 'bg-primary/50 text-primary' : 'hover:bg-[#23272a]'}", data: { action: "click->nav#clickLink" } do %> Mailing Address <% end %> @@ -89,41 +92,67 @@ Mailers <% end %> <% end %> - <% admin_tool(nil, "div") do %> - <%= link_to admin_timeline_path, class: "block px-2 py-1 rounded-lg transition #{current_page?(admin_timeline_path) ? 'bg-primary/50 text-primary' : 'hover:bg-[#23272a]'}", data: { action: "click->nav#clickLink" } do %> - Review Timeline + <% if current_user&.admin_level == "admin" %> + <% admin_tool(nil, "div") do %> + <%= link_to admin_timeline_path, class: "block px-2 py-1 rounded-lg transition #{current_page?(admin_timeline_path) ? 'bg-primary/50 text-primary' : 'hover:bg-[#23272a]'}", data: { action: "click->nav#clickLink" } do %> + Review Timeline + <% end %> + <% end %> + <% elsif current_user&.admin_level == "viewer" %> + <% viewer_tool(nil, "div") do %> + <%= link_to admin_timeline_path, class: "block px-2 py-1 rounded-lg transition #{current_page?(admin_timeline_path) ? 'bg-primary/50 text-primary' : 'hover:bg-[#23272a]'}", data: { action: "click->nav#clickLink" } do %> + Review Timeline + <% end %> <% end %> <% end %> - <% admin_tool(nil, "div") do %> + + <% if current_user&.admin_level == "admin" %> + <% admin_tool(nil, "div") do %> + <%= link_to admin_trust_level_audit_logs_path, class: "block px-2 py-1 rounded-lg transition #{current_page?(admin_trust_level_audit_logs_path) || request.path.start_with?('/admin/trust_level_audit_logs') ? 'bg-primary/50 text-primary' : 'hover:bg-[#23272a]'}", data: { action: "click->nav#clickLink" } do %> + Trust Level Logs + <% end %> + <% end %> + <% elsif current_user&.admin_level == "viewer" %> + <% viewer_tool(nil, "div") do %> + <%= link_to admin_trust_level_audit_logs_path, class: "block px-2 py-1 rounded-lg transition #{current_page?(admin_trust_level_audit_logs_path) || request.path.start_with?('/admin/trust_level_audit_logs') ? 'bg-primary/50 text-primary' : 'hover:bg-[#23272a]'}", data: { action: "click->nav#clickLink" } do %> + Trust Level Logs + <% end %> + <% end %> + <% end %> + + <% if current_user&.admin_level == "admin" %> + <% admin_tool(nil, "div") do %> + <%= link_to admin_admin_api_keys_path, class: "block px-2 py-1 rounded-lg transition #{current_page?(admin_admin_api_keys_path) || request.path.start_with?('/admin/admin_api_keys') ? 'bg-primary/50 text-primary' : 'hover:bg-[#23272a]'}", data: { action: "click->nav#clickLink" } do %> + Admin API Keys + <% end %> + <% end %> + <% elsif current_user&.admin_level == "viewer" %> + <% viewer_tool(nil, "div") do %> + <%= link_to admin_admin_api_keys_path, class: "block px-2 py-1 rounded-lg transition #{current_page?(admin_admin_api_keys_path) || request.path.start_with?('/admin/admin_api_keys') ? 'bg-primary/50 text-primary' : 'hover:bg-[#23272a]'}", data: { action: "click->nav#clickLink" } do %> + Admin API Keys + <% end %> + <% end %> + <% end %> + <% superadmin_tool(nil, "div") do %> <%= link_to ahoy_captain_path, class: "block px-2 py-1 rounded-lg transition #{current_page?(ahoy_captain_path) ? 'bg-primary/50 text-primary' : 'hover:bg-[#23272a]'}", data: { action: "click->nav#clickLink" } do %> Ahoy Captain <% end %> <% end %> - <% admin_tool(nil, "div") do %> + <% superadmin_tool(nil, "div") do %> <%= link_to good_job_path, class: "block px-2 py-1 rounded-lg transition #{current_page?(good_job_path) ? 'bg-primary/50 text-primary' : 'hover:bg-[#23272a]'}", data: { action: "click->nav#clickLink" } do %> GoodBoy <% end %> <% end %> - <% admin_tool(nil, "div") do %> + <% superadmin_tool(nil, "div") do %> <%= link_to oauth_applications_path, class: "block px-2 py-1 rounded-lg transition #{current_page?(oauth_applications_path) ? 'bg-primary/50 text-primary' : 'hover:bg-[#23272a]'}", data: { action: "click->nav#clickLink" } do %> OAuth2 apps <% end %> <% end %> - <% admin_tool(nil, "div") do %> - <%= link_to admin_admin_api_keys_path, class: "block px-2 py-1 rounded-lg transition #{current_page?(admin_admin_api_keys_path) || request.path.start_with?('/admin/admin_api_keys') ? 'bg-primary/50 text-primary' : 'hover:bg-[#23272a]'}", data: { action: "click->nav#clickLink" } do %> - Admin API Keys - <% end %> - <% end %> - <% admin_tool(nil, "div") do %> + <% superadmin_tool(nil, "div") do %> <%= link_to flipper_path, class: "block px-2 py-1 rounded-lg transition #{current_page?(flipper_path) ? 'bg-primary/50 text-primary' : 'hover:bg-[#23272a]'}", data: { action: "click->nav#clickLink" } do %> Feature Flags <% end %> <% end %> - <% admin_tool(nil, "div") do %> - <%= link_to admin_trust_level_audit_logs_path, class: "block px-2 py-1 rounded-lg transition #{current_page?(admin_trust_level_audit_logs_path) || request.path.start_with?('/admin/trust_level_audit_logs') ? 'bg-primary/50 text-primary' : 'hover:bg-[#23272a]'}", data: { action: "click->nav#clickLink" } do %> - Trust Level Logs - <% end %> - <% end %>
diff --git a/app/views/shared/_user_mention.html.erb b/app/views/shared/_user_mention.html.erb index 05f87fb..828dcb6 100644 --- a/app/views/shared/_user_mention.html.erb +++ b/app/views/shared/_user_mention.html.erb @@ -28,7 +28,7 @@ <% end %> <% unless current_user == user %> <% admin_tool('', 'span') do %> - <% if (!user.admin? && !user.superadmin?) || (user.admin? && current_user.superadmin? && !user.superadmin?) %> + <% if (!user.admin_level.in?(["admin", "superadmin"]) || (user.admin_level == "admin" && current_user.admin_level == "superadmin" && user.admin_level != "superadmin")) %> <%= link_to impersonate_user_path(user), class: "text-primary font-bold hover:text-red-300 transition-colors duration-200", data: { turbo_frame: "_top", turbo_prefetch: "false" } do %> 🥸 <% end %> diff --git a/app/views/static_pages/_admin_level.erb b/app/views/static_pages/_admin_level.erb new file mode 100644 index 0000000..0b7585b --- /dev/null +++ b/app/views/static_pages/_admin_level.erb @@ -0,0 +1,8 @@ +<% if current_user.admin_level == "superadmin" %> + Superadmin +<% elsif current_user.admin_level == "admin" %> + Admin +<% elsif current_user.admin_level == "viewer" %> + Viewer +<% else %> +<%end%> \ No newline at end of file diff --git a/config/routes.rb b/config/routes.rb index b055a48..1b72da1 100644 --- a/config/routes.rb +++ b/config/routes.rb @@ -1,37 +1,45 @@ -class AdminConstraint - def self.matches?(request) - return false unless request.session[:user_id] +class AdminLevelConstraint + def initialize(*require) + @require = require.map(&:to_s) + end + def matches?(request) + return false unless request.session[:user_id] user = User.find_by(id: request.session[:user_id]) - user&.admin_level == "admin" || user&.admin_level == "superadmin" + user && @require.include?(user.admin_level) end end Rails.application.routes.draw do use_doorkeeper - constraints AdminConstraint do + root "static_pages#index" + + constraints AdminLevelConstraint.new(:superadmin) do mount GoodJob::Engine => "good_job" mount AhoyCaptain::Engine => "/ahoy_captain" mount Flipper::UI.app(Flipper) => "flipper", as: :flipper get "/impersonate/:id", to: "sessions#impersonate", as: :impersonate_user + get "/my/mailing_address", to: "my/mailing_address#show", as: :my_mailing_address end get "/stop_impersonating", to: "sessions#stop_impersonating", as: :stop_impersonating - namespace :admin do - get "timeline", to: "timeline#show", as: :timeline - get "timeline/search_users", to: "timeline#search_users" - get "timeline/leaderboard_users", to: "timeline#leaderboard_users" + constraints AdminLevelConstraint.new(:superadmin, :admin, :viewer) do + namespace :admin do + get "timeline", to: "timeline#show", as: :timeline + get "timeline/search_users", to: "timeline#search_users" + get "timeline/leaderboard_users", to: "timeline#leaderboard_users" - get "post_reviews/:post_id", to: "post_reviews#show", as: :post_review - patch "post_reviews/:post_id", to: "post_reviews#update" - get "post_reviews/:post_id/date/:date", to: "post_reviews#show", as: :post_review_on_date + get "post_reviews/:post_id", to: "post_reviews#show", as: :post_review + patch "post_reviews/:post_id", to: "post_reviews#update" + get "post_reviews/:post_id/date/:date", to: "post_reviews#show", as: :post_review_on_date - get "ysws_reviews/:record_id", to: "ysws_reviews#show", as: :ysws_review + get "ysws_reviews/:record_id", to: "ysws_reviews#show", as: :ysws_review - resources :trust_level_audit_logs, only: [ :index, :show ] - resources :admin_api_keys, except: [ :edit, :update ] + resources :trust_level_audit_logs, only: [ :index, :show ] + resources :admin_api_keys, except: [ :edit, :update ] + end end if Rails.env.development? @@ -46,8 +54,6 @@ Rails.application.routes.draw do # get "manifest" => "rails/pwa#manifest", as: :pwa_manifest # get "service-worker" => "rails/pwa#service_worker", as: :pwa_service_worker - root "static_pages#index" - resources :static_pages, only: [ :index ] do collection do get :project_durations