mirror of
https://github.com/indentlabs/notebook.git
synced 2025-10-26 11:19:22 +00:00
commit
97bc18bc3a
31
app/authorizers/timeline_authorizer.rb
Normal file
31
app/authorizers/timeline_authorizer.rb
Normal file
@ -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
|
||||
@ -16,6 +16,12 @@ class ApplicationController < ActionController::Base
|
||||
|
||||
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]
|
||||
|
||||
@ -1,4 +1,19 @@
|
||||
class PageTagsController < ApplicationController
|
||||
def update
|
||||
raise "placeholder"
|
||||
end
|
||||
|
||||
def rename
|
||||
old_tag_name = params[:tag].to_s
|
||||
new_tag_name = params.dig(old_tag_name, :label)
|
||||
|
||||
if new_tag_name.blank?
|
||||
new_tag_name = 'Untitled Tag'
|
||||
end
|
||||
|
||||
current_user.page_tags.where(tag: old_tag_name).update_all(tag: new_tag_name)
|
||||
end
|
||||
|
||||
# Remove a tag and all of its links to a page
|
||||
def remove
|
||||
# Params
|
||||
|
||||
@ -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(
|
||||
@ -26,17 +39,12 @@ class TimelinesController < ApplicationController
|
||||
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
|
||||
@ -47,11 +55,8 @@ class TimelinesController < ApplicationController
|
||||
|
||||
# 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
|
||||
@ -70,8 +75,6 @@ class TimelinesController < ApplicationController
|
||||
|
||||
# PATCH/PUT /timelines/1
|
||||
def update
|
||||
return unless user_signed_in? && current_user == @timeline.user
|
||||
|
||||
if @timeline.update(timeline_params)
|
||||
update_page_tags
|
||||
|
||||
@ -89,6 +92,14 @@ class TimelinesController < ApplicationController
|
||||
|
||||
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)
|
||||
|
||||
@ -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
|
||||
|
||||
@ -35,21 +35,35 @@
|
||||
</span>
|
||||
<% end %>
|
||||
</div>
|
||||
<div class="grey-text" style="padding-top: 1em">
|
||||
Used by <%= pluralize page_list.length, 'page' %>
|
||||
</div>
|
||||
<br />
|
||||
<div>
|
||||
<%= form_for tag, url: rename_tag_path(tag: tag) do |f| %>
|
||||
<div class="row">
|
||||
<div class="input-field col s12 m12 l12">
|
||||
<%= f.text_field :label, class: '', value: tag %>
|
||||
<%= f.label :label, 'Rename tag' %>
|
||||
</div>
|
||||
<div class="col s12 m12 l12">
|
||||
<%= f.submit 'Mass-rename', class: 'btn white blue-text', onclick: "javascript: M.toast({ html: 'Saving changes...' });" %>
|
||||
</div>
|
||||
</div>
|
||||
<% end %>
|
||||
</div>
|
||||
<div style="text-align: right">
|
||||
<%=
|
||||
link_to 'Delete this tag', tag_remove_path(
|
||||
page_type: content_type.name,
|
||||
slug: PageTagService.slug_for(tag)
|
||||
), data: {
|
||||
confirm: "Are you sure? This will delete this tag and remove it from all pages."
|
||||
}, class: 'red-text'
|
||||
}, class: 'red-text btn red white-text'
|
||||
%>
|
||||
</div>
|
||||
</div>
|
||||
<div class="col s12 m6 l8">
|
||||
<div class="grey-text" style="padding-top: 1em">
|
||||
Used by <%= pluralize page_list.length, 'page' %>
|
||||
</div>
|
||||
<% page_list.each do |page_tag| %>
|
||||
<div class="chip js-load-page-name" data-klass="<%= page_tag.page_type %>" data-id="<%= page_tag.page_id %>">
|
||||
<%= link_to send("#{page_tag.page_type.downcase}_path", page_tag.page_id) do %>
|
||||
|
||||
@ -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>
|
||||
|
||||
@ -89,6 +89,8 @@
|
||||
:label: Past students
|
||||
- :name: famous_students
|
||||
:label: Famous students
|
||||
- :name: headcount
|
||||
:label: Headcount
|
||||
:extracurriculars:
|
||||
:label: Extracurriculars
|
||||
:icon: rowing
|
||||
|
||||
@ -98,7 +98,9 @@ Rails.application.routes.draw do
|
||||
|
||||
get '/scratchpad', to: 'main#notes', as: :notes
|
||||
|
||||
get 'tag/remove', to: 'page_tags#remove'
|
||||
get 'tag/remove', to: 'page_tags#remove'
|
||||
# post 'tag/:slug/update', to: 'page_tags#update', as: :update_tag
|
||||
post '/tag/:tag/rename', to: 'page_tags#rename', as: :rename_tag
|
||||
delete 'tag/:id/destroy', to: 'page_tags#destroy', as: :destroy_specific_tag
|
||||
|
||||
# Legacy route: left intact so /my/documents/X URLs continue to work for everyone's bookmarks
|
||||
|
||||
Loading…
Reference in New Issue
Block a user