use cancancan for access control

main
Sebskyo 2025-03-02 08:42:31 +01:00
parent abf32bb480
commit 937b3a0b6a
9 changed files with 42 additions and 8 deletions

View File

@ -46,6 +46,8 @@ gem 'thruster', require: false
gem 'tailwindcss-rails'
gem 'view_component', '~> 3.20'
gem 'cancancan'
group :development, :test do
# See https://guides.rubyonrails.org/debugging_rails_applications.html#debugging-with-the-debug-gem
gem 'debug', platforms: %i[mri windows], require: 'debug/prelude'

View File

@ -88,6 +88,7 @@ GEM
brakeman (6.2.2)
racc
builder (3.3.0)
cancancan (3.6.1)
capybara (3.40.0)
addressable
matrix
@ -452,6 +453,7 @@ DEPENDENCIES
bcrypt (~> 3.1.7)
bootsnap
brakeman
cancancan
capybara (~> 3.40)
debug
guard-rspec (~> 4.7)

View File

@ -5,6 +5,9 @@ class ApplicationController < ActionController::Base
before_action :ensure_authentication
rescue_from StandardError, with: :standard_error unless Rails.env.development?
rescue_from CanCan::AccessDenied, with: :access_denied unless Rails.env.development?
protected
def ensure_authentication
@ -14,4 +17,16 @@ class ApplicationController < ActionController::Base
def current_user
@current_user ||= User.find_by(id: session[:current_user_id])
end
def current_ability
@current_ability ||= Ability.new(current_user)
end
def access_denied
render 'application/access_denied', status: :unauthorized
end
def standard_error
render 'application/standard_error', status: :internal_server_error
end
end

View File

@ -1,12 +1,13 @@
# frozen_string_literal: true
class ConversationsController < ApplicationController
load_and_authorize_resource except: %i[create]
def index
@conversations = @current_user.conversations
@conversations = Conversation.accessible_by(current_ability)
end
def show
@conversation = @current_user.conversations.find(params[:id])
@messages = @conversation.messages
@prompt = Message.new(conversation: @conversation)
end

View File

@ -1,14 +1,14 @@
# frozen_string_literal: true
class MessagesController < ApplicationController
load_and_authorize_resource
def create
# TODO: Revisit auth once cancancan is installed
@message = Message.new(message_params)
if @message.save
GenerateReplyJob.perform_later(@message.conversation)
redirect_to @message.conversation
else
redirect_to conversations_path
redirect_to @message.conversation || conversations_path
end
end

12
app/models/ability.rb Normal file
View File

@ -0,0 +1,12 @@
# frozen_string_literal: true
class Ability
include CanCan::Ability
def initialize(user)
can :create, Conversation
can :read, Conversation, user: user
can :create, Message, conversation: { user: user }
can %i[index read], Message, conversation: { user: user }
end
end

View File

@ -0,0 +1 @@
<h1>401 Unauthorized</h1>

View File

@ -0,0 +1 @@
<h1>500 Internal Server Error</h1>

View File

@ -4,8 +4,8 @@
<% end %>
</div>
<li>
<ul>
<% @conversations.each do |conversation| %>
<%= link_to conversation %>
<li><%= link_to conversation %></li>
<% end %>
</li>
</ul>