Skip to content
Merged
Show file tree
Hide file tree
Changes from all commits
Commits
File filter

Filter by extension

Filter by extension

Conversations
Failed to load comments.
Loading
Jump to
Jump to file
Failed to load files.
Loading
Diff view
Diff view
7 changes: 3 additions & 4 deletions app/controllers/bookmarks_controller.rb
Original file line number Diff line number Diff line change
Expand Up @@ -3,12 +3,11 @@ class BookmarksController < ApplicationController

def index
per_page = params[:number_of_items_per_page] || 25
unfiltered = Bookmark.includes(bookmarkable: [ :primary_asset, :gallery_assets, :windows_type ])
filtered = unfiltered.search(params)
filtered = filtered.sorted(params[:sort])
base_scope = authorized_scope(Bookmark.includes(bookmarkable: [ :primary_asset, :gallery_assets, :windows_type ]))
filtered = base_scope.search(params).sorted(params[:sort])

@bookmarks = filtered.paginate(page: params[:page], per_page: per_page).decorate
@bookmarks_count = unfiltered.length
@bookmarks_count = base_scope.length
@windows_types_array = WindowsType::TYPES
set_index_variables
respond_to do |format|
Expand Down
21 changes: 7 additions & 14 deletions app/controllers/community_news_controller.rb
Original file line number Diff line number Diff line change
Expand Up @@ -6,22 +6,15 @@ class CommunityNewsController < ApplicationController
def index
if turbo_frame_request?
per_page = params[:number_of_items_per_page].presence || 12
unfiltered =
if current_user&.admin?
CommunityNews.all
elsif current_user
CommunityNews.published
else
CommunityNews.publicly_visible
end
filtered = unfiltered.search_by_params(params)
@community_news = filtered&.includes([ :bookmarks, :primary_asset, :author, :project, author: :facilitator ])
&.paginate(page: params[:page], per_page: per_page)&.decorate
base_scope = authorized_scope(CommunityNews.includes([ :bookmarks, :primary_asset, :author, :project, author: :facilitator ]))

@count_display = if filtered.count == unfiltered.count
unfiltered.count
filtered = base_scope.search_by_params(params)
@community_news = filtered.paginate(page: params[:page], per_page: per_page).decorate

@count_display = if filtered.count == base_scope.count
base_scope.count
else
"#{filtered.count}/#{unfiltered.count}"
"#{filtered.count}/#{base_scope.count}"
end
render :index_lazy
else
Expand Down
11 changes: 8 additions & 3 deletions app/controllers/facilitators_controller.rb
Original file line number Diff line number Diff line change
Expand Up @@ -4,10 +4,15 @@ class FacilitatorsController < ApplicationController

def index
per_page = params[:number_of_items_per_page].presence || 25
facilitators = Facilitator
.searchable

base_scope = authorized_scope(Facilitator
.includes(:user,
:avatar_attachment,
:sectorable_items,
user: [ :avatar_attachment, :projects ]).references(:user))

facilitators = base_scope
.search_by_params(params.to_unsafe_h)
.includes(:user, :avatar_attachment, :sectorable_items, user: [ :avatar_attachment, :projects ]).references(:user)
.order(:first_name, :last_name)
@count_display = facilitators.size
@facilitators = facilitators.paginate(page: params[:page], per_page: per_page)
Expand Down
6 changes: 3 additions & 3 deletions app/controllers/faqs_controller.rb
Original file line number Diff line number Diff line change
Expand Up @@ -3,10 +3,10 @@ class FaqsController < ApplicationController
before_action :set_faq, only: [ :show, :edit, :update, :destroy ]

def index
faqs = current_user&.super_user? ? Faq.all : (current_user ? Faq.published : Faq.publicly_visible)
faqs = authorized_scope(Faq.all)
@faqs = faqs.search_by_params(params.to_unsafe_h.slice("query", "published"))
.by_position
.page(params[:page])
.by_position
.page(params[:page])
end

def show
Expand Down
14 changes: 7 additions & 7 deletions app/controllers/stories_controller.rb
Original file line number Diff line number Diff line change
Expand Up @@ -6,16 +6,16 @@ class StoriesController < ApplicationController
def index
if turbo_frame_request?
per_page = params[:number_of_items_per_page].presence || 12
unpaginated = current_user.super_user? ? Story.all : Story.published
filtered = unpaginated.includes(:windows_type, :project, :workshop, :created_by, :bookmarks, :primary_asset)
.search_by_params(params)
.order(created_at: :desc)
base_scope = authorized_scope(Story.includes(:windows_type, :project, :workshop, :created_by, :bookmarks, :primary_asset))
filtered = base_scope.search_by_params(params)
.order(created_at: :desc)

@stories = filtered.paginate(page: params[:page], per_page: per_page).decorate

@count_display = if filtered.count == unpaginated.count
unpaginated.count
@count_display = if filtered.count == base_scope.count
base_scope.count
else
"#{filtered.count}/#{unpaginated.count}"
"#{filtered.count}/#{base_scope.count}"
end
render :index_lazy
else
Expand Down
7 changes: 4 additions & 3 deletions app/controllers/tutorials_controller.rb
Original file line number Diff line number Diff line change
Expand Up @@ -5,9 +5,10 @@ class TutorialsController < ApplicationController

def index
per_page = params[:number_of_items_per_page].presence || 25
unfiltered = current_user&.super_user? ? Tutorial.all : current_user ? Tutorial.published : Tutorial.publicly_visible
filtered = unfiltered.search_by_params(params)
@count_display = filtered.count == unfiltered.count ? unfiltered.count : "#{filtered.count}/#{unfiltered.count}"
base_scope = authorized_scope(Tutorial.all)
filtered = base_scope.search_by_params(params)

@count_display = filtered.size == base_scope.size ? base_scope.size : "#{filtered.count}/#{base_scope.count}"
@tutorials = filtered.order(:position).paginate(page: params[:page], per_page: per_page).decorate
end

Expand Down
16 changes: 6 additions & 10 deletions app/controllers/workshop_logs_controller.rb
Original file line number Diff line number Diff line change
Expand Up @@ -4,17 +4,13 @@ class WorkshopLogsController < ApplicationController
def index
@per_page = params[:number_of_items_per_page].presence || 10
params[:workshop_id] ||= @workshop&.id
permitted_logs =
if current_user.super_user?
WorkshopLog.all
else
WorkshopLog.where(created_by_id: current_user.id)
Copy link
Collaborator

Choose a reason for hiding this comment

The reason will be displayed to describe this comment to others. Learn more.

did this filter get lost? i don't think it's in the policy

Copy link
Collaborator Author

@jmilljr24 jmilljr24 Feb 7, 2026

Choose a reason for hiding this comment

The reason will be displayed to describe this comment to others. Learn more.

Going off the policy and comment I left off the by project_id since we need have the table change coming and there are a bunch more scope this policy will need to filter the search filters if we filter on org as well.

  relation_scope do |relation|
    next relation if admin?
    relation.where(user: user) # TODO - maybe also allow users to see peers' within same organization
  end

I do notice now that the scope for user should be on created_by_id.

It looks like WorkshopLog has user_id on it not created_by_id so the relation_scope was correct.

Copy link
Collaborator

Choose a reason for hiding this comment

The reason will be displayed to describe this comment to others. Learn more.

gotcha re project!

the report/workshop_log models are actually still user_id. so we must've never tested as non-admin.

.or(WorkshopLog.project_id(current_user.project_ids))
end
@workshop_logs_unpaginated = permitted_logs.includes(:workshop, :user, :windows_type)
.search(params)
@workshop_logs_count = @workshop_logs_unpaginated.size

@workshop_logs_unpaginated = authorized_scope(WorkshopLog.includes(:workshop, :user, :windows_type)
.search(params))

@workshop_logs = @workshop_logs_unpaginated.paginate(page: params[:page], per_page: @per_page)
@workshop_logs_count = @workshop_logs&.total_entries

set_index_variables
end

Expand Down
9 changes: 4 additions & 5 deletions app/controllers/workshops_controller.rb
Original file line number Diff line number Diff line change
Expand Up @@ -13,12 +13,11 @@ def index

track_index_intent(Workshop, search_service.workshops, params)

@workshops = search_service.workshops
@workshops = authorized_scope(search_service.workshops
.includes(:categories, :windows_type, :user, :images, :bookmarks, :age_ranges,
user: [ :facilitator ], primary_asset: [ :file_attachment ])
user: [ :facilitator ], primary_asset: [ :file_attachment ]))
.paginate(page: params[:page], per_page: params[:per_page] || 12)

@workshops_count = search_service.workshops.size

render :workshop_results
else
Expand Down Expand Up @@ -190,9 +189,9 @@ def search
private

def set_show
@quotes = Quote.where(workshop_id: @workshop.id).active
@quotes = Quote.where(workshop_id: @workshop.id).published
@leader_spotlights = @workshop.associated_resources.leader_spotlights.where(published: true)
@workshop_variations = @workshop.workshop_variations.active
@workshop_variations = @workshop.workshop_variations.published
@sectors = @workshop.sectorable_items.published.map { |item| item.sector if item.sector.published? }.compact if @workshop.sectorable_items.any?
end

Expand Down
1 change: 1 addition & 0 deletions app/models/user.rb
Original file line number Diff line number Diff line change
Expand Up @@ -70,6 +70,7 @@ def self.search_by_params(params)
results
end

# TODO Remove once all view's use ActionPolicy
def admin?
super_user
end
Expand Down
2 changes: 1 addition & 1 deletion app/policies/ahoy_activity_policy.rb
Original file line number Diff line number Diff line change
Expand Up @@ -17,7 +17,7 @@ def visits?
# See https://actionpolicy.evilmartians.io/#/scoping
#
# relation_scope do |relation|
# next relation if user.admin?
# next relation if admin?
# relation.where(user: user)
# end
end
2 changes: 1 addition & 1 deletion app/policies/application_policy.rb
Original file line number Diff line number Diff line change
Expand Up @@ -20,7 +20,7 @@ def manage?
# Define shared methods useful for most policies.

Copy link
Collaborator

Choose a reason for hiding this comment

The reason will be displayed to describe this comment to others. Learn more.

i found note somewhere of adding scope_matcher :relation, ActiveRecord::Relation to ApplicationPolicy and after_action :verify_authorized, except: :index to validate that the indexes are using the scopes. not sure if you'd want to do that?

Copy link
Collaborator Author

Choose a reason for hiding this comment

The reason will be displayed to describe this comment to others. Learn more.

In ApplicationController I have verify_authorized commented out and ready to go once we think we have every policy done and and proper. That makes sure every controller action has a policy checked going forward.

I'll have to look into the scope stuff and see if/what makes sense for us. Thanks for pointing it out.

def admin?
user&.admin?
user&.super_user
end

def owner?
Expand Down
2 changes: 1 addition & 1 deletion app/policies/banner_policy.rb
Original file line number Diff line number Diff line change
Expand Up @@ -13,7 +13,7 @@ def show?
# See https://actionpolicy.evilmartians.io/#/scoping
#
# relation_scope do |relation|
# next relation if user.admin?
# next relation if admin?
# relation.where(user: user)
# end
end
2 changes: 1 addition & 1 deletion app/policies/facilitator_policy.rb
Original file line number Diff line number Diff line change
Expand Up @@ -18,6 +18,6 @@ def update?

relation_scope do |relation|
next relation if admin?
relation.published.searchable
relation.published
end
end
2 changes: 1 addition & 1 deletion app/policies/faq_policy.rb
Original file line number Diff line number Diff line change
Expand Up @@ -13,7 +13,7 @@ def show?
# See https://actionpolicy.evilmartians.io/#/scoping
#
relation_scope do |relation|
next relation if user.admin?
next relation if admin?
if authenticated?
relation.published
else
Expand Down
2 changes: 1 addition & 1 deletion app/policies/project_status_policy.rb
Original file line number Diff line number Diff line change
Expand Up @@ -10,7 +10,7 @@ class ProjectStatusPolicy < ApplicationPolicy
# See https://actionpolicy.evilmartians.io/#/scoping
#
# relation_scope do |relation|
# next relation if user.admin?
# next relation if admin?
# relation.where(user: user)
# end
end
2 changes: 1 addition & 1 deletion app/policies/story_idea_policy.rb
Original file line number Diff line number Diff line change
Expand Up @@ -21,7 +21,7 @@ def show?
# See https://actionpolicy.evilmartians.io/#/scoping
#
# relation_scope do |relation|
# next relation if user.admin?
# next relation if admin?
# relation.where(user: user)
# end
end
2 changes: 1 addition & 1 deletion app/policies/tutorial_policy.rb
Original file line number Diff line number Diff line change
Expand Up @@ -13,7 +13,7 @@ def show?
# See https://actionpolicy.evilmartians.io/#/scoping
#
relation_scope do |relation|
next relation if user.admin?
next relation if admin?
if authenticated?
relation.published
else
Expand Down
2 changes: 1 addition & 1 deletion app/policies/user_policy.rb
Original file line number Diff line number Diff line change
Expand Up @@ -10,7 +10,7 @@ class UserPolicy < ApplicationPolicy
# See https://actionpolicy.evilmartians.io/#/scoping
#
# relation_scope do |relation|
# next relation if user.admin?
# next relation if admin?
# relation.where(user: user)
# end
end
6 changes: 3 additions & 3 deletions app/views/faqs/_faq.html.erb
Original file line number Diff line number Diff line change
Expand Up @@ -8,7 +8,7 @@
<div class="border-b border-gray-300">
<div class="flex items-center w-full">

<% if current_user.super_user? %>
<% if current_user&.super_user? %>
<span class="admin-only bg-blue-100">
<i
class="fa-solid fa-sort cursor-move self-center pr-2"
Expand Down Expand Up @@ -68,7 +68,7 @@
<%= faq.question %></span>
<% end %>

<% if current_user.super_user? %>
<% if current_user&.super_user? %>
<div class="flex flex-col mx-3 ">
<span class="admin-only bg-blue-100">
<%= link_to faq,
Expand Down Expand Up @@ -130,7 +130,7 @@
<strong class="sr-only">Answer:</strong>

<%= render "inline_edit", model: faq, attribute: :answer, frame_class: "flex flex-col" do %>
<% if current_user.super_user? %>
<% if current_user&.super_user? %>
<%= link_to("Edit", edit_faq_path(faq), class: "btn btn-secondary-outline self-end admin-only bg-blue-100") %>

<% end %>
Expand Down
3 changes: 1 addition & 2 deletions app/views/faqs/show.html.erb
Original file line number Diff line number Diff line change
Expand Up @@ -15,12 +15,11 @@
<!-- Buttons Group -->
<div class="flex items-center gap-2">
<%= link_to("Index", faqs_path, class: "btn btn-secondary-outline") %>
<% if current_user.super_user? %>
<% if current_user&.super_user? %>
<%= link_to("Edit", edit_faq_path(@faq), class: "btn btn-primary-outline") %>
<% end %>
</div>
</div>

<div class="space-y-6">
<div class="mt-4">
<%= render @faq, hide_options: true %>
Expand Down
3 changes: 0 additions & 3 deletions app/views/workshop_ideas/_form.html.erb
Original file line number Diff line number Diff line change
Expand Up @@ -202,7 +202,6 @@
<% end %>
<% end %>

<%# begin %>
<!-- Accordions -->
<div class="space-y-4">
<div class="tags-section" data-controller="dropdown">
Expand Down Expand Up @@ -386,8 +385,6 @@
</div>
</div>

<%# =end %>

<% if current_user.super_user? %>
<div class="admin-only bg-blue-100 p-3">
<%= f.input :staff_notes, as: :text,
Expand Down
3 changes: 2 additions & 1 deletion spec/requests/faqs_spec.rb
Original file line number Diff line number Diff line change
Expand Up @@ -80,13 +80,14 @@
end

context "as a guest" do
xit "renders successfully" do
it "renders successfully" do
get faqs_path
expect(response).to be_successful
end

it "shows only publicly_visible FAQs" do
get faqs_path
expect(response).to be_successful
expect(response.body).to include("Public FAQ")
expect(response.body).not_to include("Published FAQ")
expect(response.body).not_to include("Unpublished FAQ")
Expand Down
3 changes: 2 additions & 1 deletion spec/requests/workshop_logs_spec.rb
Original file line number Diff line number Diff line change
Expand Up @@ -55,7 +55,8 @@
expect(response.body).not_to include(other_log.workshop.name)
end

it "populates workshops dropdown with only workshops from visible logs" do
# TODO use action policy to filter
xit "populates workshops dropdown with only workshops from visible logs" do
Copy link
Collaborator

Choose a reason for hiding this comment

The reason will be displayed to describe this comment to others. Learn more.

what was wrong w this test?

Copy link
Collaborator Author

Choose a reason for hiding this comment

The reason will be displayed to describe this comment to others. Learn more.

We need to scope all the dropdowns. I think it should be its own separate PR. We are disabling workshop logs for this phase right? So this can be lower priority?

Copy link
Collaborator

Choose a reason for hiding this comment

The reason will be displayed to describe this comment to others. Learn more.

workshop_logs are in scope. it's the workshop_idea he wants us to hide for now.

Copy link
Collaborator Author

Choose a reason for hiding this comment

The reason will be displayed to describe this comment to others. Learn more.

OoOOOOH ok. I will open a separate issue for the scoped filters.

visible_workshop = create(:workshop)
hidden_workshop = create(:workshop, published: false)
unassigned_workshop = create(:workshop)
Expand Down