diff --git a/app/controllers/admin/base_controller.rb b/app/controllers/admin/base_controller.rb index 74fa9e3..96811b0 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&.admin? + unless current_user && (current_user.admin_level == "admin" || current_user.admin_level == "superadmin") 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 253b238..b16600d 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&.admin? + unless current_user && (current_user.admin_level == "admin" || current_user.admin_level == "superadmin") redirect_to root_path, alert: "no perms lmaooo" end end diff --git a/app/controllers/api/admin/v1/admin_controller.rb b/app/controllers/api/admin/v1/admin_controller.rb index caede1a..4506ad8 100644 --- a/app/controllers/api/admin/v1/admin_controller.rb +++ b/app/controllers/api/admin/v1/admin_controller.rb @@ -17,8 +17,7 @@ module Api id: creator.id, username: creator.username, display_name: creator.display_name, - admin: creator.admin?, - superadmin: creator.superadmin? + admin_level: creator.admin_level } } end @@ -37,8 +36,7 @@ module Api github_username: user.github_username, timezone: user.timezone, country_code: user.country_code, - admin: user.admin?, - superadmin: user.superadmin?, + admin_level: user.admin_level, trust_level: user.trust_level, suspected: user.trust_level == "yellow", banned: user.trust_level == "red", diff --git a/app/controllers/application_controller.rb b/app/controllers/application_controller.rb index c10008e..c43f4e0 100644 --- a/app/controllers/application_controller.rb +++ b/app/controllers/application_controller.rb @@ -36,7 +36,7 @@ class ApplicationController < ActionController::Base end def try_rack_mini_profiler_enable - if current_user && current_user.is_admin? + if current_user && (current_user.admin_level == "admin" || current_user.admin_level == "superadmin") Rack::MiniProfiler.authorize_request end end diff --git a/app/controllers/sessions_controller.rb b/app/controllers/sessions_controller.rb index f61836b..b38ad3e 100644 --- a/app/controllers/sessions_controller.rb +++ b/app/controllers/sessions_controller.rb @@ -176,12 +176,11 @@ class SessionsController < ApplicationController user = User.find(params[:id]) - if user.superadmin? + if user.admin_level == "superadmin" redirect_to root_path, alert: "nice try, you cant do that" return end - - if user.admin? && !current_user.superadmin? + if user.admin_level == "admin" && current_user.admin_level != "superadmin" redirect_to root_path, alert: "nice try, you cant do that" return end diff --git a/app/controllers/users_controller.rb b/app/controllers/users_controller.rb index 3edbd83..267ab0e 100644 --- a/app/controllers/users_controller.rb +++ b/app/controllers/users_controller.rb @@ -82,12 +82,12 @@ class UsersController < ApplicationController reason = params[:reason] notes = params[:notes] - if @user && current_user.admin? && trust_level.present? + if @user && (current_user.admin_level == "admin" || current_user.admin_level == "superadmin") && trust_level.present? unless User.trust_levels.key?(trust_level) return render json: { error: "you fucked it up lmaooo" }, status: :unprocessable_entity end - if trust_level == "red" && !current_user.can_convict_users? + if trust_level == "red" && current_user.admin_level != "superadmin" return render json: { error: "no perms lmaooo" }, status: :forbidden end @@ -115,7 +115,7 @@ class UsersController < ApplicationController private def require_admin - unless current_user.admin? + unless current_user && (current_user.admin_level == "admin" || current_user.admin_level == "superadmin") redirect_to root_path, alert: "You are not authorized to access this page" end end diff --git a/app/helpers/application_helper.rb b/app/helpers/application_helper.rb index 09a37b7..485db08 100644 --- a/app/helpers/application_helper.rb +++ b/app/helpers/application_helper.rb @@ -16,7 +16,7 @@ module ApplicationHelper end def admin_tool(class_name = "", element = "div", **options, &block) - return unless current_user&.is_admin? + 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 diff --git a/app/models/user.rb b/app/models/user.rb index f1445aa..9133549 100644 --- a/app/models/user.rb +++ b/app/models/user.rb @@ -27,6 +27,25 @@ class User < ApplicationRecord yellow: 3 # suspected (invisible to user) } + enum :admin_level, { + default: 0, # pleebs + superadmin: 1, + admin: 2, + viewer: 3 + }, prefix: :admin_level + + def set_admin_level(level) + return false unless level.present? && self.class.admin_levels.key?(level) + + previous_level = admin_level + + if previous_level != level.to_s + update!(admin_level: level.to_s) + end + + true + end + def set_trust(level, changed_by_user: nil, reason: nil, notes: nil) return false unless level.present? @@ -173,37 +192,6 @@ class User < ApplicationRecord end end - def admin? - is_admin || is_superadmin - end - - def superadmin? - is_superadmin - end - - def make_admin! - update!(is_admin: true) - end - - def make_superadmin! - update!(is_superadmin: true, is_admin: true) - end - - def remove_admin! - update!(is_admin: false) - end - - def remove_superadmin! - update!(is_superadmin: false) - end - - def can_convict_users? - superadmin? - end - - def can_moderate_trust_levels? - admin? - end def raw_github_user_info return nil unless github_uid.present? diff --git a/config/initializers/doorkeeper.rb b/config/initializers/doorkeeper.rb index 471af25..dce38ca 100644 --- a/config/initializers/doorkeeper.rb +++ b/config/initializers/doorkeeper.rb @@ -9,7 +9,9 @@ Doorkeeper.configure do admin_authenticator do if current_user - head :forbidden unless current_user.admin? + unless current_user && (current_user.admin_level == "admin" || current_user.admin_level == "superadmin") + head :forbidden + end else redirect_to sign_in_url end diff --git a/config/initializers/flipper.rb b/config/initializers/flipper.rb index 188735e..301206d 100644 --- a/config/initializers/flipper.rb +++ b/config/initializers/flipper.rb @@ -36,5 +36,5 @@ end ## See https://www.flippercloud.io/docs/features#enablement-group Flipper.register(:admins) do |actor| - actor.respond_to?(:admin?) && actor.admin? + actor.respond_to?(:admin_level) && (actor.admin_level == "superadmin") end diff --git a/config/routes.rb b/config/routes.rb index ed3fca5..b055a48 100644 --- a/config/routes.rb +++ b/config/routes.rb @@ -3,7 +3,7 @@ class AdminConstraint return false unless request.session[:user_id] user = User.find_by(id: request.session[:user_id]) - user&.admin? + user&.admin_level == "admin" || user&.admin_level == "superadmin" end end diff --git a/db/migrate/20250705_migrate_admin_levels_on_users.rb b/db/migrate/20250705_migrate_admin_levels_on_users.rb new file mode 100644 index 0000000..094a399 --- /dev/null +++ b/db/migrate/20250705_migrate_admin_levels_on_users.rb @@ -0,0 +1,41 @@ +class MigrateAdminLevelsOnUsers < ActiveRecord::Migration[7.0] + def up + add_column :users, :admin_level, :integer, default: 0, null: false + + User.reset_column_information + User.find_each do |user| + if user.is_superadmin + user.update_column(:admin_level, 1) + elsif user.is_admin + user.update_column(:admin_level, 2) + else + user.update_column(:admin_level, 0) + end + end + + remove_column :users, :is_admin, :boolean + remove_column :users, :is_superadmin, :boolean + end + + def down + add_column :users, :is_admin, :boolean, default: false, null: false + add_column :users, :is_superadmin, :boolean, default: false, null: false + + User.reset_column_information + User.find_each do |user| + case user.admin_level + when 1 + user.update_column(:is_superadmin, true) + user.update_column(:is_admin, true) + when 2 + user.update_column(:is_admin, true) + user.update_column(:is_superadmin, false) + else + user.update_column(:is_admin, false) + user.update_column(:is_superadmin, false) + end + end + + remove_column :users, :admin_level, :integer + end +end diff --git a/db/schema.rb b/db/schema.rb index 7424f49..dfad64e 100644 --- a/db/schema.rb +++ b/db/schema.rb @@ -519,7 +519,6 @@ ActiveRecord::Schema[8.0].define(version: 2025_07_01_142553) do t.datetime "updated_at", null: false t.string "username" t.string "slack_avatar_url" - t.boolean "is_admin", default: false, null: false t.boolean "uses_slack_status", default: false, null: false t.string "slack_scopes", default: [], array: true t.text "slack_access_token" @@ -536,7 +535,7 @@ ActiveRecord::Schema[8.0].define(version: 2025_07_01_142553) do t.string "mailing_address_otc" t.boolean "allow_public_stats_lookup", default: true, null: false t.boolean "default_timezone_leaderboard", default: true, null: false - t.boolean "is_superadmin", default: false, null: false + t.integer "admin_level", default: 0, null: false t.index ["github_uid", "github_access_token"], name: "index_users_on_github_uid_and_access_token" t.index ["github_uid"], name: "index_users_on_github_uid" t.index ["slack_uid"], name: "index_users_on_slack_uid", unique: true