mirror of
https://github.com/SrIzan10/hc-harbor.git
synced 2026-05-01 10:45:21 +00:00
Add admins, papertrail, ensure admin authentication on dashboard
This commit is contained in:
2
Gemfile
2
Gemfile
@@ -20,6 +20,8 @@ gem "stimulus-rails"
|
||||
gem "jbuilder"
|
||||
# Avo Community
|
||||
gem "avo", ">= 3.2.1"
|
||||
# PaperTrail for auditing
|
||||
gem "paper_trail"
|
||||
|
||||
# Use Active Model has_secure_password [https://guides.rubyonrails.org/active_model_basics.html#securepassword]
|
||||
# gem "bcrypt", "~> 3.1.7"
|
||||
|
||||
@@ -236,6 +236,9 @@ GEM
|
||||
racc (~> 1.4)
|
||||
ostruct (0.6.1)
|
||||
pagy (9.3.3)
|
||||
paper_trail (16.0.0)
|
||||
activerecord (>= 6.1)
|
||||
request_store (~> 1.4)
|
||||
parallel (1.26.3)
|
||||
parser (3.3.7.1)
|
||||
ast (~> 2.4.1)
|
||||
@@ -303,6 +306,8 @@ GEM
|
||||
regexp_parser (2.10.0)
|
||||
reline (0.6.0)
|
||||
io-console (~> 0.5)
|
||||
request_store (1.7.0)
|
||||
rack (>= 1.4)
|
||||
rexml (3.4.0)
|
||||
rubocop (1.72.1)
|
||||
json (~> 2.3)
|
||||
@@ -437,6 +442,7 @@ DEPENDENCIES
|
||||
importmap-rails
|
||||
jbuilder
|
||||
kamal
|
||||
paper_trail
|
||||
pg
|
||||
propshaft
|
||||
puma (>= 5.0)
|
||||
|
||||
@@ -1,17 +1,18 @@
|
||||
class Avo::Resources::User < Avo::BaseResource
|
||||
# self.includes = []
|
||||
# self.attachments = []
|
||||
# self.search = {
|
||||
# query: -> { query.ransack(id_eq: params[:q], m: "or").result(distinct: false) }
|
||||
# }
|
||||
|
||||
self.title = :email
|
||||
self.includes = []
|
||||
|
||||
def fields
|
||||
field :id, as: :id
|
||||
field :slack_uid, as: :text
|
||||
field :email, as: :text
|
||||
field :username, as: :text
|
||||
field :slack_uid, as: :text
|
||||
field :avatar_url, as: :text
|
||||
field :is_admin, as: :boolean
|
||||
field :created_at, as: :date_time
|
||||
field :updated_at, as: :date_time
|
||||
|
||||
# Show versions/history in the show page
|
||||
field :versions, as: :has_many
|
||||
end
|
||||
end
|
||||
|
||||
|
||||
|
||||
19
app/avo/resources/version.rb
Normal file
19
app/avo/resources/version.rb
Normal file
@@ -0,0 +1,19 @@
|
||||
class Avo::Resources::Version < Avo::BaseResource
|
||||
# self.includes = []
|
||||
# self.attachments = []
|
||||
# self.search = {
|
||||
# query: -> { query.ransack(id_eq: params[:q], m: "or").result(distinct: false) }
|
||||
# }
|
||||
|
||||
self.model_class = PaperTrail::Version
|
||||
|
||||
def fields
|
||||
field :id, as: :id
|
||||
field :item_type, as: :text
|
||||
field :item_id, as: :number
|
||||
field :event, as: :text
|
||||
field :whodunnit, as: :text
|
||||
field :object, as: :code
|
||||
field :created_at, as: :date_time
|
||||
end
|
||||
end
|
||||
@@ -1,4 +1,6 @@
|
||||
class ApplicationController < ActionController::Base
|
||||
before_action :set_paper_trail_whodunnit
|
||||
|
||||
# Only allow modern browsers supporting webp images, web push, badges, import maps, CSS nesting, and CSS :has.
|
||||
allow_browser versions: :modern
|
||||
|
||||
|
||||
@@ -1,8 +1,22 @@
|
||||
class User < ApplicationRecord
|
||||
has_paper_trail
|
||||
|
||||
validates :email, presence: true, uniqueness: true
|
||||
validates :slack_uid, presence: true, uniqueness: true
|
||||
validates :username, presence: true
|
||||
|
||||
def admin?
|
||||
is_admin
|
||||
end
|
||||
|
||||
def make_admin!
|
||||
update!(is_admin: true)
|
||||
end
|
||||
|
||||
def remove_admin!
|
||||
update!(is_admin: false)
|
||||
end
|
||||
|
||||
def self.authorize_url(redirect_uri)
|
||||
params = {
|
||||
client_id: ENV["SLACK_CLIENT_ID"],
|
||||
|
||||
@@ -2,7 +2,7 @@
|
||||
# The values disaplayed here are the default ones. Uncomment and change them to fit your needs.
|
||||
Avo.configure do |config|
|
||||
## == Routing ==
|
||||
config.root_path = '/avo'
|
||||
config.root_path = "/avo"
|
||||
# used only when you have custom `map` configuration in your config.ru
|
||||
# config.prefix_path = "/internal"
|
||||
|
||||
@@ -22,9 +22,20 @@ Avo.configure do |config|
|
||||
end
|
||||
|
||||
## == Authentication ==
|
||||
# config.current_user_method = :current_user
|
||||
# config.authenticate_with do
|
||||
# end
|
||||
# Ensure user is signed in and is an admin
|
||||
config.authenticate_with do |controller|
|
||||
user = User.find_by(id: controller.session[:user_id])
|
||||
if !user
|
||||
controller.redirect_to "/", alert: "Please sign in first"
|
||||
elsif !user.admin?
|
||||
controller.redirect_to "/", alert: "Not authorized"
|
||||
end
|
||||
end
|
||||
|
||||
# Set current user for auditing/tracking
|
||||
config.current_user = proc do |request|
|
||||
User.find_by(id: request.session[:user_id])
|
||||
end
|
||||
|
||||
## == Authorization ==
|
||||
# config.is_admin_method = :is_admin
|
||||
|
||||
5
db/migrate/20240320000001_add_admin_at_to_users.rb
Normal file
5
db/migrate/20240320000001_add_admin_at_to_users.rb
Normal file
@@ -0,0 +1,5 @@
|
||||
class AddAdminAtToUsers < ActiveRecord::Migration[8.0]
|
||||
def change
|
||||
add_column :users, :admin_at, :datetime
|
||||
end
|
||||
end
|
||||
11
db/migrate/20240320000002_switch_admin_at_to_is_admin.rb
Normal file
11
db/migrate/20240320000002_switch_admin_at_to_is_admin.rb
Normal file
@@ -0,0 +1,11 @@
|
||||
class SwitchAdminAtToIsAdmin < ActiveRecord::Migration[8.0]
|
||||
def change
|
||||
add_column :users, :is_admin, :boolean, default: false, null: false
|
||||
|
||||
# Copy data from admin_at to is_admin
|
||||
User.reset_column_information
|
||||
User.where.not(admin_at: nil).update_all(is_admin: true)
|
||||
|
||||
remove_column :users, :admin_at
|
||||
end
|
||||
end
|
||||
41
db/migrate/20250216173458_create_versions.rb
Normal file
41
db/migrate/20250216173458_create_versions.rb
Normal file
@@ -0,0 +1,41 @@
|
||||
# This migration creates the `versions` table, the only schema PT requires.
|
||||
# All other migrations PT provides are optional.
|
||||
class CreateVersions < ActiveRecord::Migration[8.0]
|
||||
|
||||
# The largest text column available in all supported RDBMS is
|
||||
# 1024^3 - 1 bytes, roughly one gibibyte. We specify a size
|
||||
# so that MySQL will use `longtext` instead of `text`. Otherwise,
|
||||
# when serializing very large objects, `text` might not be big enough.
|
||||
TEXT_BYTES = 1_073_741_823
|
||||
|
||||
def change
|
||||
create_table :versions do |t|
|
||||
# Consider using bigint type for performance if you are going to store only numeric ids.
|
||||
# t.bigint :whodunnit
|
||||
t.string :whodunnit
|
||||
|
||||
# Known issue in MySQL: fractional second precision
|
||||
# -------------------------------------------------
|
||||
#
|
||||
# MySQL timestamp columns do not support fractional seconds unless
|
||||
# defined with "fractional seconds precision". MySQL users should manually
|
||||
# add fractional seconds precision to this migration, specifically, to
|
||||
# the `created_at` column.
|
||||
# (https://dev.mysql.com/doc/refman/5.6/en/fractional-seconds.html)
|
||||
#
|
||||
# MySQL users should also upgrade to at least rails 4.2, which is the first
|
||||
# version of ActiveRecord with support for fractional seconds in MySQL.
|
||||
# (https://github.com/rails/rails/pull/14359)
|
||||
#
|
||||
# MySQL users should use the following line for `created_at`
|
||||
# t.datetime :created_at, limit: 6
|
||||
t.datetime :created_at
|
||||
|
||||
t.bigint :item_id, null: false
|
||||
t.string :item_type, null: false
|
||||
t.string :event, null: false
|
||||
t.text :object, limit: TEXT_BYTES
|
||||
end
|
||||
add_index :versions, %i[item_type item_id]
|
||||
end
|
||||
end
|
||||
12
db/migrate/20250216173459_add_object_changes_to_versions.rb
Normal file
12
db/migrate/20250216173459_add_object_changes_to_versions.rb
Normal file
@@ -0,0 +1,12 @@
|
||||
# This migration adds the optional `object_changes` column, in which PaperTrail
|
||||
# will store the `changes` diff for each update event. See the readme for
|
||||
# details.
|
||||
class AddObjectChangesToVersions < ActiveRecord::Migration[8.0]
|
||||
# The largest text column available in all supported RDBMS.
|
||||
# See `create_versions.rb` for details.
|
||||
TEXT_BYTES = 1_073_741_823
|
||||
|
||||
def change
|
||||
add_column :versions, :object_changes, :text, limit: TEXT_BYTES
|
||||
end
|
||||
end
|
||||
14
db/schema.rb
generated
14
db/schema.rb
generated
@@ -10,7 +10,7 @@
|
||||
#
|
||||
# It's strongly recommended that you check this file into your version control system.
|
||||
|
||||
ActiveRecord::Schema[8.0].define(version: 2024_03_20_000000) do
|
||||
ActiveRecord::Schema[8.0].define(version: 2025_02_16_173459) do
|
||||
create_table "users", force: :cascade do |t|
|
||||
t.string "slack_uid", null: false
|
||||
t.string "email", null: false
|
||||
@@ -18,6 +18,18 @@ ActiveRecord::Schema[8.0].define(version: 2024_03_20_000000) do
|
||||
t.datetime "updated_at", null: false
|
||||
t.string "username"
|
||||
t.string "avatar_url"
|
||||
t.boolean "is_admin", default: false, null: false
|
||||
t.index ["slack_uid"], name: "index_users_on_slack_uid", unique: true
|
||||
end
|
||||
|
||||
create_table "versions", force: :cascade do |t|
|
||||
t.string "whodunnit"
|
||||
t.datetime "created_at"
|
||||
t.bigint "item_id", null: false
|
||||
t.string "item_type", null: false
|
||||
t.string "event", null: false
|
||||
t.text "object", limit: 1073741823
|
||||
t.text "object_changes", limit: 1073741823
|
||||
t.index ["item_type", "item_id"], name: "index_versions_on_item_type_and_item_id"
|
||||
end
|
||||
end
|
||||
|
||||
Reference in New Issue
Block a user