diff --git a/app/controllers/additional_content_boxes_controller.rb b/app/controllers/additional_content_boxes_controller.rb index 973487b86..7908bf7a7 100644 --- a/app/controllers/additional_content_boxes_controller.rb +++ b/app/controllers/additional_content_boxes_controller.rb @@ -1,4 +1,5 @@ class AdditionalContentBoxesController < ApplicationController + # No authorization required for entirely public controller def index article_ids = params[:article_id].split(",") @article = Article.find(article_ids[0]) diff --git a/app/controllers/admin/application_controller.rb b/app/controllers/admin/application_controller.rb index 3f4052ee8..d9356198f 100644 --- a/app/controllers/admin/application_controller.rb +++ b/app/controllers/admin/application_controller.rb @@ -6,26 +6,17 @@ # you're free to overwrite the RESTful controller actions. module Admin class ApplicationController < Administrate::ApplicationController - skip_before_action :verify_authenticity_token - include EnforceAdmin - before_action :authenticate_admin + include Pundit + before_action :authorize_admin - def authenticate_admin - unless current_user_is_admin? - authenticate_or_request_with_http_basic do |username, password| - username == ENV["APP_NAME"] && password == ENV["APP_PASSWORD"] - end - end - end - - # Override this value to specify the number of elements to display at a time - # on index pages. Defaults to 20. - # def records_per_page - # params[:per_page] || 20 - # end def order @_order ||= Administrate::Order.new(params[:order] || "id",params[:direction] || "desc") end + private + + def authorize_admin + authorize :admin, :show? + end end end diff --git a/app/controllers/analytics_controller.rb b/app/controllers/analytics_controller.rb index 3ccae3496..98e761e2a 100644 --- a/app/controllers/analytics_controller.rb +++ b/app/controllers/analytics_controller.rb @@ -2,39 +2,21 @@ class AnalyticsController < ApplicationController caches_action :index, cache_path: Proc.new { "#{request.params}___#{current_user.id}" }, expires_in: 15.minutes + after_action :verify_authorized def index article_ids = analytics_params.split(",") - if has_analytics_privilege?(article_ids.first, current_user) - cache_name = "pageviews-#{article_ids}/dashboard-index" - pageviews = Rails.cache.fetch(cache_name, expires_in: 15.minutes) do - GoogleAnalytics.new(article_ids).get_pageviews - end - render json: pageviews.to_json - else - render json: {} + article_to_check = Article.find_by(id: article_ids.first) + authorize article_to_check, :analytics_index? + cache_name = "pageviews-#{article_ids}/dashboard-index" + pageviews = Rails.cache.fetch(cache_name, expires_in: 15.minutes) do + GoogleAnalytics.new(article_ids).get_pageviews end + render json: pageviews.to_json end private - def has_analytics_privilege?(article_id, current_user) - return false unless current_user - current_user_is_admin? || - current_user_is_author_with_beta_acess?(article_id, current_user) || - current_user_is_org_admin?(article_id, current_user) - end - - def current_user_is_author_with_beta_acess?(article_id, user) - author = Article.find_by_id(article_id)&.user - author == user && user.has_role?(:analytics_beta_tester) - end - - def current_user_is_org_admin?(article_id, user) - org_id = Article.find_by_id(article_id)&.organization_id - user.org_admin && user.organization_id == org_id - end - def analytics_params params.require(:article_ids) end diff --git a/app/controllers/application_controller.rb b/app/controllers/application_controller.rb index 4bf5c75ec..dec4463a5 100644 --- a/app/controllers/application_controller.rb +++ b/app/controllers/application_controller.rb @@ -1,14 +1,8 @@ class ApplicationController < ActionController::Base protect_from_forgery with: :exception, prepend: true - include EnforceAdmin - include Pundit - # before_action :require_http_auth if ENV["APP_NAME"] == "dev_stage" - - #before_action :customize_params - def require_http_auth authenticate_or_request_with_http_basic do |username, password| username == ENV["APP_NAME"] && password == ENV["APP_PASSWORD"] diff --git a/app/controllers/blocks_controller.rb b/app/controllers/blocks_controller.rb index fb002b600..d6c91d3b6 100644 --- a/app/controllers/blocks_controller.rb +++ b/app/controllers/blocks_controller.rb @@ -1,7 +1,9 @@ class BlocksController < ApplicationController before_action :set_block, only: [:show, :edit, :update, :destroy] + after_action :verify_authorized + # GET /blocks # GET /blocks.json def index @@ -78,4 +80,5 @@ class BlocksController < ApplicationController def set_block @block = Block.find(params[:id]) end + end diff --git a/app/controllers/buffered_articles_controller.rb b/app/controllers/buffered_articles_controller.rb index 26fed2bb9..2797d7386 100644 --- a/app/controllers/buffered_articles_controller.rb +++ b/app/controllers/buffered_articles_controller.rb @@ -1,4 +1,5 @@ class BufferedArticlesController < ApplicationController + # No authorization required for entirely public controller def index @article_urls = buffered_article_urls render json: { diff --git a/app/controllers/concerns/enforce_admin.rb b/app/controllers/concerns/enforce_admin.rb deleted file mode 100644 index b83c4ac69..000000000 --- a/app/controllers/concerns/enforce_admin.rb +++ /dev/null @@ -1,17 +0,0 @@ -module EnforceAdmin - extend ActiveSupport::Concern - - def require_super_admin - return verify_admin_status if current_user - redirect_to "/enter" - end - - def verify_admin_status - return if current_user_is_admin? - redirect_to "/", status: 422 - end - - def current_user_is_admin? - current_user&.has_any_role?(:super_admin, :admin) - end -end diff --git a/app/controllers/dashboards_controller.rb b/app/controllers/dashboards_controller.rb index cfe241e63..04da56cf6 100644 --- a/app/controllers/dashboards_controller.rb +++ b/app/controllers/dashboards_controller.rb @@ -4,7 +4,7 @@ class DashboardsController < ApplicationController after_action :verify_authorized def show - @user = if params[:username] && current_user_is_admin? + @user = if params[:username] && current_user.is_admin? User.find_by_username(params[:username]) else current_user diff --git a/app/controllers/followed_articles_controller.rb b/app/controllers/followed_articles_controller.rb index be7a64013..5bad9c71b 100644 --- a/app/controllers/followed_articles_controller.rb +++ b/app/controllers/followed_articles_controller.rb @@ -1,4 +1,5 @@ class FollowedArticlesController < ApplicationController + # No authorization required for entirely public controller caches_action :index, :cache_path => Proc.new { "followed_articles_#{current_user.id}__#{current_user.updated_at}__#{user_signed_in?.to_s}" }, diff --git a/app/controllers/ga_events_controller.rb b/app/controllers/ga_events_controller.rb index dbe65aa44..cf1d7b42f 100644 --- a/app/controllers/ga_events_controller.rb +++ b/app/controllers/ga_events_controller.rb @@ -1,4 +1,5 @@ class GaEventsController < ApplicationController + # No authorization required for entirely public controller # This controller is for tracking activity when GA script fails # IP is scrambled as to not be persisted to limit fingerprinting abilities on our end. diff --git a/app/controllers/internal/application_controller.rb b/app/controllers/internal/application_controller.rb index 69b88e849..1388af441 100644 --- a/app/controllers/internal/application_controller.rb +++ b/app/controllers/internal/application_controller.rb @@ -1,4 +1,9 @@ class Internal::ApplicationController < ApplicationController - include EnforceAdmin - before_action :require_super_admin + before_action :authorize_admin + + private + + def authorize_admin + authorize :admin, :show? + end end diff --git a/app/controllers/internal/broadcasts_controller.rb b/app/controllers/internal/broadcasts_controller.rb index 080484c07..10d331d03 100644 --- a/app/controllers/internal/broadcasts_controller.rb +++ b/app/controllers/internal/broadcasts_controller.rb @@ -3,26 +3,12 @@ class Internal::BroadcastsController < Internal::ApplicationController def create @broadcast = Broadcast.new(broadcast_params) - if @broadcast.save - # custom notifications not in use yet - # if @broadcast.sent && @broadcast.type_of == "Announcement" - # # only send new notifications for announcements - # # onboarding notifications are automated - # Notification.send_all(@broadcast, @broadcast.type_of) - # end - end redirect_to "/internal/broadcasts" end def update @broadcast = Broadcast.find(params[:id]) @broadcast.update(broadcast_params) - # if @broadcast.save - # if @broadcast.sent && @broadcast.type_of == "Announcement" - # # see create action comments - # Notification.send_all(@broadcast, @broadcast.type_of) - # end - # end redirect_to "/internal/broadcasts" end diff --git a/app/controllers/live_articles_controller.rb b/app/controllers/live_articles_controller.rb index 085fe0b91..c7d7944a0 100644 --- a/app/controllers/live_articles_controller.rb +++ b/app/controllers/live_articles_controller.rb @@ -1,4 +1,5 @@ class LiveArticlesController < ApplicationController + # No authorization required for entirely public controller before_action :set_cache_control_headers, only: [:index] def index diff --git a/app/controllers/moderations_controller.rb b/app/controllers/moderations_controller.rb index 79001d591..222a8b72b 100644 --- a/app/controllers/moderations_controller.rb +++ b/app/controllers/moderations_controller.rb @@ -1,20 +1,15 @@ class ModerationsController < ApplicationController - - before_action :check_trusted + after_action :verify_authorized def article + authorize(User, :moderation_routes?) @moderatable = Article.find_by_slug(params[:slug]) render template: "moderations/mod" end def comment + authorize(User, :moderation_routes?) @moderatable = Comment.find(params[:id_code].to_i(26)) render template: "moderations/mod" end - - private - - def check_trusted - not_found unless current_user&.has_role?(:trusted) - end end diff --git a/app/controllers/notifications_controller.rb b/app/controllers/notifications_controller.rb index 46559d835..0d41186fa 100644 --- a/app/controllers/notifications_controller.rb +++ b/app/controllers/notifications_controller.rb @@ -4,7 +4,7 @@ class NotificationsController < ApplicationController def index if user_signed_in? @notifications_index = true - @user = if params[:username] && current_user_is_admin? + @user = if params[:username] && current_user.is_admin? User.find_by_username(params[:username]) else current_user diff --git a/app/controllers/organizations_controller.rb b/app/controllers/organizations_controller.rb index 86ba22efa..55da2a686 100644 --- a/app/controllers/organizations_controller.rb +++ b/app/controllers/organizations_controller.rb @@ -1,11 +1,13 @@ class OrganizationsController < ApplicationController before_action :authenticate_user!, except: [:show] + after_action :verify_authorized def create @tab = "organization" @user = current_user @tab_list = @user.settings_tab_list @organization = Organization.new(organization_params) + authorize @organization if @organization.save current_user.update(organization_id: @organization.id, org_admin: true) redirect_to "/settings/organization", notice: @@ -21,8 +23,9 @@ class OrganizationsController < ApplicationController @user = current_user @tab = "organization" @tab_list = @user.settings_tab_list - raise unless @user.org_admin @organization = @user.organization + authorize @organization + if @organization.update(organization_params) redirect_to "/settings/organization", notice: "Your organization was successfully updated." else @@ -33,6 +36,7 @@ class OrganizationsController < ApplicationController def generate_new_secret raise unless current_user.org_admin @organization = current_user.organization + authorize @organization @organization.secret = @organization.generated_random_secret @organization.save redirect_to "/settings/organization", notice: "Your org secret was updated" diff --git a/app/controllers/podcast_episodes_controller.rb b/app/controllers/podcast_episodes_controller.rb index 17b8b6434..1fd943f91 100644 --- a/app/controllers/podcast_episodes_controller.rb +++ b/app/controllers/podcast_episodes_controller.rb @@ -1,7 +1,6 @@ class PodcastEpisodesController < ApplicationController - - before_action :require_http_auth, only: [:edit,:update,:admin] - before_action :set_cache_control_headers, only: [:index, :show] + # No authorization required for entirely public controller + before_action :set_cache_control_headers, only: [:index] def index @podcast_index = true diff --git a/app/controllers/social_previews_controller.rb b/app/controllers/social_previews_controller.rb index c735cccb1..67ac211b5 100644 --- a/app/controllers/social_previews_controller.rb +++ b/app/controllers/social_previews_controller.rb @@ -1,4 +1,5 @@ class SocialPreviewsController < ApplicationController + # No authorization required for entirely public controller def article @article = Article.find(params[:id]) @@ -20,5 +21,4 @@ class SocialPreviewsController < ApplicationController @tag = Tag.find(params[:id]) || not_found render layout: false end - -end \ No newline at end of file +end diff --git a/app/controllers/stories_controller.rb b/app/controllers/stories_controller.rb index 0ce474cf6..a4fd60620 100644 --- a/app/controllers/stories_controller.rb +++ b/app/controllers/stories_controller.rb @@ -89,8 +89,7 @@ class StoriesController < ApplicationController @stories = @stories.where(approved: true) end - @stories = stories_by_timeframe - + @stories = stories_by_timeframe @stories = @stories.decorate @featured_story = Article.new diff --git a/app/models/user.rb b/app/models/user.rb index d64a93b6a..c2a90c40e 100644 --- a/app/models/user.rb +++ b/app/models/user.rb @@ -217,6 +217,10 @@ class User < ApplicationRecord has_role? :warned end + def is_admin? + has_role?(:super_admin) + end + def trusted Rails.cache.fetch("user-#{id}/has_trusted_role", expires_in: 200.hours) do has_role? :trusted @@ -246,6 +250,10 @@ class User < ApplicationRecord has_any_role?(:workshop_pass, :level_3_member, :level_4_member, :triple_unicorn_member) end + def is_org_admin?(organization) + user.org_admin && user.organization_id == organization.id + end + def unique_including_orgs errors.add(:username, "is taken.") if Organization.find_by_slug(username) end @@ -264,7 +272,7 @@ class User < ApplicationRecord handle_asynchronously :subscribe_to_mailchimp_newsletter def can_view_analytics? - has_any_role?(:super_admin, :admin, :analytics_beta_tester) + has_any_role?(:super_admin, :analytics_beta_tester) end def a_sustaining_member? @@ -293,6 +301,7 @@ class User < ApplicationRecord end + private def unescape_summary diff --git a/app/policies/admin_policy.rb b/app/policies/admin_policy.rb new file mode 100644 index 000000000..621181143 --- /dev/null +++ b/app/policies/admin_policy.rb @@ -0,0 +1,5 @@ +class AdminPolicy < ApplicationPolicy + def show? + user_is_admin? + end +end diff --git a/app/policies/application_policy.rb b/app/policies/application_policy.rb index 2cc6e0854..0a6245c2d 100644 --- a/app/policies/application_policy.rb +++ b/app/policies/application_policy.rb @@ -54,10 +54,10 @@ class ApplicationPolicy end def user_is_admin? - user.has_any_role?(:super_admin, :admin) + user.has_role?(:super_admin) end def user_is_banned? - user.has_role?(:banned) + user.banned end end diff --git a/app/policies/article_policy.rb b/app/policies/article_policy.rb index 3e1df7bf8..9c15c6029 100644 --- a/app/policies/article_policy.rb +++ b/app/policies/article_policy.rb @@ -23,6 +23,10 @@ class ArticlePolicy < ApplicationPolicy true end + def analytics_index? + (user_is_author? && user_can_view_analytics?) || user_is_org_admin? + end + def permitted_attributes %i[title body_html body_markdown user_id main_image published description allow_small_edits allow_big_edits tag_list publish_under_org @@ -39,7 +43,7 @@ class ArticlePolicy < ApplicationPolicy user.org_admin && user.organization_id == record.organization_id end - def user_is_banned? - user.has_role?(:banned) + def user_can_view_analytics? + user.can_view_analytics? end end diff --git a/app/policies/block_policy.rb b/app/policies/block_policy.rb index 4b1b06e30..1d0e6642a 100644 --- a/app/policies/block_policy.rb +++ b/app/policies/block_policy.rb @@ -30,10 +30,4 @@ class BlockPolicy < ApplicationPolicy def permitted_attributes %i[input_html input_css input_javascript featured index_position publish_now] end - - private - - def user_is_admin? - user.has_role? :super_admin - end end diff --git a/app/policies/comment_policy.rb b/app/policies/comment_policy.rb index 13a10a0ad..844fe25c1 100644 --- a/app/policies/comment_policy.rb +++ b/app/policies/comment_policy.rb @@ -40,8 +40,4 @@ class CommentPolicy < ApplicationPolicy def user_is_author? record.user_id == user.id end - - def user_is_banned? - user.has_role?(:banned) - end end diff --git a/app/policies/follow_policy.rb b/app/policies/follow_policy.rb index 36065b055..b86c86f91 100644 --- a/app/policies/follow_policy.rb +++ b/app/policies/follow_policy.rb @@ -1,5 +1,5 @@ class FollowPolicy < ApplicationPolicy def create? - !user.banned + !user_is_banned? end end diff --git a/app/policies/github_repo_policy.rb b/app/policies/github_repo_policy.rb index 6daf34b7a..52a105f74 100644 --- a/app/policies/github_repo_policy.rb +++ b/app/policies/github_repo_policy.rb @@ -1,10 +1,10 @@ class GithubRepoPolicy < ApplicationPolicy def create? - !user.banned + !user_is_banned? end def update? - !user.banned && user_is_owner? + !user_is_banned? && user_is_owner? end def permitted_attributes diff --git a/app/policies/image_upload_policy.rb b/app/policies/image_upload_policy.rb index 7de1a1d0d..693632b55 100644 --- a/app/policies/image_upload_policy.rb +++ b/app/policies/image_upload_policy.rb @@ -1,5 +1,5 @@ class ImageUploadPolicy < ApplicationPolicy def create? - !user.banned + !user_is_banned? end end diff --git a/app/policies/message_policy.rb b/app/policies/message_policy.rb index 8594b9879..3f38f236c 100644 --- a/app/policies/message_policy.rb +++ b/app/policies/message_policy.rb @@ -2,10 +2,4 @@ class MessagePolicy < ApplicationPolicy def create? !user_is_banned? end - - private - - def user_is_banned? - user&.has_role?(:banned) - end end diff --git a/app/policies/organization_policy.rb b/app/policies/organization_policy.rb new file mode 100644 index 000000000..541b1bd26 --- /dev/null +++ b/app/policies/organization_policy.rb @@ -0,0 +1,13 @@ +class OrganizationPolicy < ApplicationPolicy + def create? + !user.banned + end + + def update? + user.is_org_admin?(record) + end + + def generate_new_secret? + update? + end +end diff --git a/app/policies/tag_policy.rb b/app/policies/tag_policy.rb index 2c9796e9a..c95f6fd1e 100644 --- a/app/policies/tag_policy.rb +++ b/app/policies/tag_policy.rb @@ -14,7 +14,7 @@ class TagPolicy < ApplicationPolicy private def has_mod_permission? - user.has_role?(:super_admin) || + user_is_admin? || user.has_role?(:tag_moderator, record) end end diff --git a/app/policies/user_policy.rb b/app/policies/user_policy.rb index 40dffc2e5..f62b8e403 100644 --- a/app/policies/user_policy.rb +++ b/app/policies/user_policy.rb @@ -35,6 +35,10 @@ class UserPolicy < ApplicationPolicy current_user? || user_is_admin? end + def moderation_routes? + user.has_role?(:trusted) && !user.banned + end + private def within_the_same_org? @@ -48,8 +52,4 @@ class UserPolicy < ApplicationPolicy def current_user? user == record end - - def user_is_admin? - user.has_role? :super_admin - end end diff --git a/app/views/dashboards/show.html.erb b/app/views/dashboards/show.html.erb index 02beb5d54..7e46bd7be 100644 --- a/app/views/dashboards/show.html.erb +++ b/app/views/dashboards/show.html.erb @@ -3,8 +3,8 @@
" href="/dashboard">POSTS (<%= @user.articles_count %>) - " href="/dashboard/user_followers">Followers (<%= @user.followers_count %>) - " href="/dashboard/following_users">Following (<%= @user.following_users_count %>) + " href="/dashboard/user_followers">FOLLOWERS (<%= @user.followers_count %>) + " href="/dashboard/following_users">FOLLOWING (<%= @user.following_users_count %>)
<% if @user.org_admin && @user.organization %>

@@ -26,7 +26,7 @@ DRAFT <% end %> EDIT - <% if article.published && current_user.has_role?(:analytics_beta_tester) %> + <% if article.published && current_user.can_view_analytics? %> fetching stats... <% end %>

@@ -77,7 +77,7 @@ <% end %> EDIT DELETE - <% if article.published && current_user.has_role?(:analytics_beta_tester) %> + <% if article.published && current_user.can_view_analytics? %> fetching stats... <% end %> diff --git a/spec/factories/users.rb b/spec/factories/users.rb index b3b4f1e5e..81898959e 100644 --- a/spec/factories/users.rb +++ b/spec/factories/users.rb @@ -26,6 +26,10 @@ FactoryBot.define do after(:build) { |user| user.add_role(:admin) } end + trait :trusted do + after(:build) { |user| user.add_role(:trusted) } + end + trait :banned do after(:build) { |user| user.add_role(:banned) } end @@ -41,6 +45,10 @@ FactoryBot.define do end end + trait :analytics do + after(:build) { |user| user.add_role(:analytics_beta_tester) } + end + after(:create) do |user| create(:identity, user_id: user.id) end diff --git a/spec/labor/badge_rewarder_spec.rb b/spec/labor/badge_rewarder_spec.rb index 621682b94..c89522843 100644 --- a/spec/labor/badge_rewarder_spec.rb +++ b/spec/labor/badge_rewarder_spec.rb @@ -36,4 +36,5 @@ RSpec.describe BadgeRewarder do BadgeRewarder.new.reward_top_seven_badges([user.username, user_other.username]) expect(BadgeAchievement.where(badge_id: badge.id).size).to eq(2) end + end diff --git a/spec/models/user_spec.rb b/spec/models/user_spec.rb index abcd94366..65c225424 100644 --- a/spec/models/user_spec.rb +++ b/spec/models/user_spec.rb @@ -7,6 +7,7 @@ RSpec.describe User, type: :model do let(:article) { create(:article,user_id:user.id) } let(:tag) { create(:tag) } let(:org) { create(:organization) } + let (:second_org) { create(:organization) } it { is_expected.to have_many(:articles) } it { is_expected.to have_many(:badge_achievements) } @@ -308,17 +309,30 @@ RSpec.describe User, type: :model do end end + describe "organization admin privileges" do + it "recognizes an org admin" do + user.update(organization: org, org_admin: true) + expect(user.is_org_admin?(org)).to be true + end + + it "forbids an incorrect org admin" do + user.update(organization: org, org_admin: true) + expect(user.is_org_admin?(second_org)).to be false + expect(second_user.is_org_admin?(org)).to be false + end + + it "responds to nil" do + expect(user.is_org_admin?(nil)).to be false + expect(second_user.is_org_admin?(nil)).to be false + end + end + describe "#can_view_analytics?" do it "returns true for users with :super_admin role" do user.add_role(:super_admin) expect(user.can_view_analytics?).to be true end - it "returns true for users with :admin role" do - user.add_role(:admin) - expect(user.can_view_analytics?).to be true - end - it "returns true for users with :analytics_beta_tester role" do user.add_role(:analytics_beta_tester) expect(user.can_view_analytics?).to be true diff --git a/spec/policies/admin_policy_spec.rb b/spec/policies/admin_policy_spec.rb new file mode 100644 index 000000000..2119fa3e9 --- /dev/null +++ b/spec/policies/admin_policy_spec.rb @@ -0,0 +1,21 @@ +require "rails_helper" + +RSpec.describe AdminPolicy do + subject { described_class } + + permissions :show? do + context "non admin" do + let(:user) {build(:user)} + it "should not allow someone without admin privileges to do continue" do + expect(subject).not_to permit(user) + end + end + + context "admin" do + let(:user) {build(:user, :super_admin)} + it "allow someone with admin privileges to continue" do + expect(subject).to permit(user) + end + end + end +end diff --git a/spec/policies/article_policy_spec.rb b/spec/policies/article_policy_spec.rb index 22510eacc..53fdbdb69 100644 --- a/spec/policies/article_policy_spec.rb +++ b/spec/policies/article_policy_spec.rb @@ -43,12 +43,6 @@ RSpec.describe ArticlePolicy do end end - context "when user is an admin" do - let(:user) { build(:user, :admin) } - - it { is_expected.to permit_actions(%i[update new create delete_confirm destroy preview]) } - end - context "when user is a super_admin" do let(:user) { build(:user, :super_admin) } diff --git a/spec/policies/organization_policy_spec.rb b/spec/policies/organization_policy_spec.rb new file mode 100644 index 000000000..ef5e04b10 --- /dev/null +++ b/spec/policies/organization_policy_spec.rb @@ -0,0 +1,47 @@ +require "rails_helper" + +RSpec.describe OrganizationPolicy do + subject { described_class.new(user, organization) } + + let(:organization) { build(:organization) } + + context "when user is not signed-in" do + let(:user) { nil } + + it { within_block_is_expected.to raise_error(Pundit::NotAuthorizedError) } + end + + context "when a non-org user" do + let(:user) { build(:user) } + + it { is_expected.to forbid_action(:update) } + it { is_expected.to permit_action(:create) } + end + + context "when user is banned" do + let(:user) { build(:user, :banned) } + + it { is_expected.to forbid_actions(%i[create update]) } + end + + context "when user is an org admin of an org" do + let(:user) { build(:user) } + + before { user.update(organization: organization, org_admin: true) } + + it "allows the user to update their own org" do + is_expected.to permit_action(:update) + end + end + + context "when user is an org admin of another org" do + let(:user) { build(:user) } + let(:new_org) { build(:organization) } + + before { user.update(organization: new_org, org_admin: true) } + + it "does not allow the user to update another org" do + is_expected.to forbid_action(:update) + end + end +end diff --git a/spec/policies/user_policy_spec.rb b/spec/policies/user_policy_spec.rb index e7842f23e..41dcad00d 100644 --- a/spec/policies/user_policy_spec.rb +++ b/spec/policies/user_policy_spec.rb @@ -19,7 +19,7 @@ RSpec.describe UserPolicy do context "with banned status" do before { user.add_role(:banned) } - it { is_expected.to forbid_actions(%i[join_org]) } + it { is_expected.to forbid_actions(%i[join_org moderation_routes]) } end end @@ -52,4 +52,16 @@ RSpec.describe UserPolicy do it { is_expected.to forbid_actions(%i[remove_org_admin]) } end end + + context "when user is trusted" do + let(:user) { build(:user, :trusted) } + + it { is_expected.to permit_actions(%i[moderation_routes]) } + end + + context "when user is not trusted" do + let(:user) { build(:user) } + + it { is_expected.to forbid_actions(%i[moderation_routes]) } + end end diff --git a/spec/requests/additional_content_boxes_spec.rb b/spec/requests/additional_content_boxes_spec.rb index 00689f6cd..3c9112981 100644 --- a/spec/requests/additional_content_boxes_spec.rb +++ b/spec/requests/additional_content_boxes_spec.rb @@ -1,6 +1,7 @@ require "rails_helper" RSpec.describe "AdditionalContentBoxes", type: :request do + let(:regular_article) { create(:article) } describe "GET /additional_content_boxes" do diff --git a/spec/requests/analytics_spec.rb b/spec/requests/analytics_spec.rb index b8f752b6c..17e2679c0 100644 --- a/spec/requests/analytics_spec.rb +++ b/spec/requests/analytics_spec.rb @@ -6,47 +6,28 @@ vcr_option = { RSpec.describe "Analytics", type: :request, vcr: vcr_option do describe "GET /analytics" do - it "returns json" do - get "/analytics?article_ids=0,1,2,3" - expect(response.content_type).to eq("application/json") - end - - it "returns 200" do - get "/analytics?article_ids=0,1,2,3" - expect(response).to have_http_status(200) - end - - it "raise ParameterMissing if no proper params is given" do - expect { get "/analytics" }.to raise_error ActionController::ParameterMissing - end - - it "returns empty json when user is not signed in" do - get "/analytics?article_ids=0,1,2,3" - expect(response.body).to eq("{}") - end - - context "when signed in" do - let(:user) { create(:user) } + context "when signed in as an authorized user" do + let(:user) { create(:user, :analytics) } let(:article1) { create(:article, user_id: user.id) } let(:article2) { create(:article, user_id: user.id) } + let(:article3) { create(:article, user_id: user.id) } before do login_as user end - it "returns empty json if current user has no priviledge" do - get "/analytics?article_ids=0,1,2,3" - expect(response.body).to eq("{}") + it "raise ParameterMissing if no proper params is given" do + expect { get "/analytics" }.to raise_error ActionController::ParameterMissing end - it "returns pageviews if user is an admin" do - user.add_role(:admin) + it "returns pageviews" do get "/analytics?article_ids=#{article1.id},#{article2.id}" expect(JSON.parse(response.body)).to eq(article1.id.to_s => "0", article2.id.to_s => "0") end - it "returns pageviews if user is has beta access" do - user.add_role(:analytics_beta_tester) + it "returns pageviews for super_admins" do + user.remove_role :analytics_beta_tester + user.add_role :super_admin get "/analytics?article_ids=#{article1.id},#{article2.id}" expect(JSON.parse(response.body)).to eq(article1.id.to_s => "0", article2.id.to_s => "0") end diff --git a/spec/requests/dashboard_spec.rb b/spec/requests/dashboard_spec.rb index 6198f3254..34d499c23 100644 --- a/spec/requests/dashboard_spec.rb +++ b/spec/requests/dashboard_spec.rb @@ -69,7 +69,7 @@ RSpec.describe "Dashboards", type: :request do user.follow second_user login_as user get "/dashboard/following_users" - expect(response.body).to include second_user.name + expect(response.body).to include CGI.escapeHTML(second_user.name) end end end @@ -87,7 +87,7 @@ RSpec.describe "Dashboards", type: :request do second_user.follow user login_as user get "/dashboard/user_followers" - expect(response.body).to include second_user.name + expect(response.body).to include CGI.escapeHTML(second_user.name) end end end diff --git a/spec/requests/moderations_spec.rb b/spec/requests/moderations_spec.rb index f1bb5d406..842de0da7 100644 --- a/spec/requests/moderations_spec.rb +++ b/spec/requests/moderations_spec.rb @@ -23,7 +23,7 @@ RSpec.describe "Moderations", type: :request do it "returns 404 if user trusted not trusted" do expect do get article.path + "/mod" - end.to raise_error(ActionController::RoutingError) + end.to raise_error(Pundit::NotAuthorizedError) end end @@ -36,7 +36,7 @@ RSpec.describe "Moderations", type: :request do it "returns 404 if user trusted not trusted" do expect do get comment.path + "/mod" - end.to raise_error(ActionController::RoutingError) + end.to raise_error(Pundit::NotAuthorizedError) end end end \ No newline at end of file