Skip to content

Commit 1f4bf04

Browse files
committed
Add authorization for notifications
1 parent d285fda commit 1f4bf04

File tree

4 files changed

+113
-0
lines changed

4 files changed

+113
-0
lines changed

app/controllers/better_together/notifications_controller.rb

Lines changed: 8 additions & 0 deletions
Original file line numberDiff line numberDiff line change
@@ -4,14 +4,20 @@ module BetterTogether
44
# handles rendering and marking notifications as read
55
class NotificationsController < ApplicationController
66
before_action :authenticate_user!
7+
after_action :verify_authorized
8+
9+
rescue_from Pundit::NotAuthorizedError, with: :user_not_authorized
710

811
def index
12+
authorize :notifications, :index?
913
@notifications = helpers.current_person.notifications.includes(:event).order(created_at: :desc)
1014
@unread_count = helpers.current_person.notifications.unread.size
1115
end
1216

1317
# TODO: Make a Stimulus controller to dispatch this action async when messages are viewed
1418
def mark_as_read # rubocop:todo Metrics/AbcSize, Metrics/MethodLength
19+
authorize :notifications, :mark_as_read?
20+
1521
if params[:id]
1622
mark_notification_as_read(params[:id])
1723
elsif params[:record_id]
@@ -37,11 +43,13 @@ def mark_as_read # rubocop:todo Metrics/AbcSize, Metrics/MethodLength
3743
end
3844

3945
def mark_notification_as_read(id)
46+
authorize :notifications, :mark_notification_as_read?
4047
@notification = helpers.current_person.notifications.find(id)
4148
@notification.update(read_at: Time.current)
4249
end
4350

4451
def mark_record_notification_as_read(id)
52+
authorize :notifications, :mark_record_notification_as_read?
4553
@notifications = helpers.current_person.notifications.unread.includes(
4654
:event
4755
).references(:event).where(event: { record_id: id })
Lines changed: 25 additions & 0 deletions
Original file line numberDiff line numberDiff line change
@@ -0,0 +1,25 @@
1+
# frozen_string_literal: true
2+
3+
module BetterTogether
4+
# Authorization rules for notifications actions
5+
class NotificationsPolicy < ApplicationPolicy
6+
def index?
7+
user.present?
8+
end
9+
10+
def mark_as_read?
11+
user.present?
12+
end
13+
14+
def mark_notification_as_read?
15+
mark_as_read?
16+
end
17+
18+
def mark_record_notification_as_read?
19+
mark_as_read?
20+
end
21+
22+
class Scope < ApplicationPolicy::Scope
23+
end
24+
end
25+
end
Lines changed: 51 additions & 0 deletions
Original file line numberDiff line numberDiff line change
@@ -0,0 +1,51 @@
1+
# frozen_string_literal: true
2+
3+
require 'rails_helper'
4+
5+
module BetterTogether
6+
# rubocop:disable Metrics/BlockLength
7+
RSpec.describe NotificationsPolicy do
8+
subject(:policy) { described_class.new(user, :notifications) }
9+
10+
context 'when user is logged in' do
11+
let(:user) { build(:user) }
12+
13+
it 'permits index' do
14+
expect(policy.index?).to be true
15+
end
16+
17+
it 'permits mark_as_read' do
18+
expect(policy.mark_as_read?).to be true
19+
end
20+
21+
it 'permits mark_notification_as_read' do
22+
expect(policy.mark_notification_as_read?).to be true
23+
end
24+
25+
it 'permits mark_record_notification_as_read' do
26+
expect(policy.mark_record_notification_as_read?).to be true
27+
end
28+
end
29+
30+
context 'when user is nil' do
31+
let(:user) { nil }
32+
33+
it 'denies index' do
34+
expect(policy.index?).to be false
35+
end
36+
37+
it 'denies mark_as_read' do
38+
expect(policy.mark_as_read?).to be false
39+
end
40+
41+
it 'denies mark_notification_as_read' do
42+
expect(policy.mark_notification_as_read?).to be false
43+
end
44+
45+
it 'denies mark_record_notification_as_read' do
46+
expect(policy.mark_record_notification_as_read?).to be false
47+
end
48+
end
49+
end
50+
# rubocop:enable Metrics/BlockLength
51+
end
Lines changed: 29 additions & 0 deletions
Original file line numberDiff line numberDiff line change
@@ -0,0 +1,29 @@
1+
# frozen_string_literal: true
2+
3+
require 'rails_helper'
4+
5+
RSpec.describe 'Notifications', type: :request do
6+
let(:user) { create(:user, :confirmed) }
7+
8+
describe 'GET /notifications' do
9+
it 'redirects unauthorized users' do
10+
login(user)
11+
allow_any_instance_of(BetterTogether::NotificationsPolicy).to receive(:index?).and_return(false)
12+
13+
get better_together.notifications_path
14+
15+
expect(response).to redirect_to(better_together.home_page_path)
16+
end
17+
end
18+
19+
describe 'POST /notifications/mark_all_as_read' do
20+
it 'redirects unauthorized users' do
21+
login(user)
22+
allow_any_instance_of(BetterTogether::NotificationsPolicy).to receive(:mark_as_read?).and_return(false)
23+
24+
post better_together.mark_all_as_read_notifications_path
25+
26+
expect(response).to redirect_to(better_together.home_page_path)
27+
end
28+
end
29+
end

0 commit comments

Comments
 (0)