Skip to content

Commit

Permalink
add specialized timeline authorizer, refactor timeline controller, ex…
Browse files Browse the repository at this point in the history
…pose read-only timelines to contributors
  • Loading branch information
drusepth committed Jan 5, 2022
1 parent 1af9d7f commit 2a5859c
Show file tree
Hide file tree
Showing 5 changed files with 72 additions and 20 deletions.
31 changes: 31 additions & 0 deletions app/authorizers/timeline_authorizer.rb
Original file line number Diff line number Diff line change
@@ -0,0 +1,31 @@
class TimelineAuthorizer < ContentAuthorizer
def self.creatable_by?(user)
return false unless user.present?
return false if ENV.key?('CONTENT_BLACKLIST') && ENV['CONTENT_BLACKLIST'].split(',').include?(user.email)

return true if user.on_premium_plan?
end

def readable_by?(user)
return true if resource.privacy == 'public'
return true if user && resource.user_id == user.id
return true if resource.universe.present? && resource.universe.privacy == 'public'
return true if user && resource.universe.present? && resource.universe.user_id == user.id
return true if user && resource.universe.present? && resource.universe.contributors.pluck(:user_id).include?(user.id)
return true if user && user.site_administrator?

return false
end

def updatable_by?(user)
[
user && resource.user_id == user.id
].any?
end

def deletable_by?(user)
[
user && resource.user_id == user.id
].any?
end
end
6 changes: 6 additions & 0 deletions app/controllers/application_controller.rb
Original file line number Diff line number Diff line change
Expand Up @@ -16,6 +16,12 @@ def content_type_from_controller(content_controller_name)

private

def require_premium_plan
unless user_signed_in? && current_user.on_premium_plan?
return redirect_back(fallback_location: root_path, notice: "Doing that requires Premium access.")
end
end

def set_metadata
@page_title ||= ''
@page_keywords ||= %w[writing author nanowrimo novel character fiction fantasy universe creative dnd roleplay game design]
Expand Down
37 changes: 24 additions & 13 deletions app/controllers/timelines_controller.rb
Original file line number Diff line number Diff line change
Expand Up @@ -5,15 +5,28 @@ class TimelinesController < ApplicationController
before_action :set_navbar_color
before_action :set_sidenav_expansion

before_action :require_premium_plan, only: [:new, :create]
before_action :require_timeline_read_permission, only: [:show]
before_action :require_timeline_edit_permission, only: [:edit, :update]

# GET /timelines
def index
cache_linkable_content_for_each_content_type

# TODO: We SHOULD be just doing the below, but since it returns ContentPage stand-ins instead
# of actual Timeline models, it's a bit wonky to get all the Timeline-specific logic in place
# without reworking most of the views. For now, we're just grabbing timelines and contributable
# timelines manually.
# @timelines = @linkables_raw.fetch('Timeline', [])
@timelines = current_user.timelines

@page_title = "My timelines"

if @universe_scope
@timelines = @timelines.where(universe: @universe_scope)
@timelines = Timeline.where(universe: @universe_scope)
else
# Add in all timelines from shared universes also
@timelines += Timeline.where(universe_id: current_user.contributable_universe_ids)
end

@page_tags = PageTag.where(
Expand All @@ -26,17 +39,12 @@ def index
end

# if params.key?(:favorite_only)
# @content.select!(&:favorite?)
# @timelines.select!(&:favorite?)
# end

end

def show
@page_title = @timeline.name

unless @timeline.privacy == 'public' || (user_signed_in? && current_user == @timeline.user)
return redirect_back(fallback_location: root_path, notice: "You don't have permission to view that timeline!")
end
end

# GET /timelines/new
Expand All @@ -47,11 +55,8 @@ def new

# GET /timelines/1/edit
def edit
@page_title = "Editing " + @timeline.name

@page_title = "Editing #{@timeline.name}"
@suggested_page_tags = []

raise "No Access" unless user_signed_in? && current_user == @timeline.user
end

# POST /timelines
Expand All @@ -70,8 +75,6 @@ def create

# PATCH/PUT /timelines/1
def update
return unless user_signed_in? && current_user == @timeline.user

if @timeline.update(timeline_params)
update_page_tags

Expand All @@ -89,6 +92,14 @@ def destroy

private

def require_timeline_read_permission
return user_signed_in? && @timeline.readable_by?(current_user)
end

def require_timeline_edit_permission
return user_signed_in? && @timeline.updatable_by?(current_user)
end

# TODO: move this (and the copy in ContentController) into the has_page_tags concern?
def update_page_tags
tag_list = page_tag_params.split(PageTag::SUBMISSION_DELIMITER)
Expand Down
2 changes: 1 addition & 1 deletion app/models/timelines/timeline.rb
Original file line number Diff line number Diff line change
Expand Up @@ -8,7 +8,7 @@ class Timeline < ApplicationRecord
include BelongsToUniverse

include Authority::Abilities
self.authorizer_name = 'ExtendedContentAuthorizer'
self.authorizer_name = 'TimelineAuthorizer'

validates :user_id, presence: true
belongs_to :user
Expand Down
16 changes: 10 additions & 6 deletions app/views/timelines/index.html.erb
Original file line number Diff line number Diff line change
Expand Up @@ -59,13 +59,17 @@

</div>
<div class="card-action">
<%= link_to timeline_path(timeline), class: 'blue-text left' do %>
<i class="material-icons left"><%= Timeline.icon %></i>
View
<% if timeline.readable_by?(current_user) %>
<%= link_to timeline_path(timeline), class: 'blue-text left' do %>
<i class="material-icons left"><%= Timeline.icon %></i>
View
<% end %>
<% end %>
<%= link_to edit_timeline_path(timeline), class: 'green-text right' do %>
<i class="material-icons left">edit</i>
Edit
<% if timeline.updatable_by?(current_user) %>
<%= link_to edit_timeline_path(timeline), class: 'green-text right' do %>
<i class="material-icons left">edit</i>
Edit
<% end %>
<% end %>
<div class="clearfix"></div>
</div>
Expand Down

0 comments on commit 2a5859c

Please sign in to comment.