diff --git a/app/components/follow_button_component.rb b/app/components/follow_button_component.rb index 59699870f..01652144c 100644 --- a/app/components/follow_button_component.rb +++ b/app/components/follow_button_component.rb @@ -3,7 +3,7 @@ class FollowButtonComponent < ViewComponent::Base def initialize(follower:, target:, name: nil) @target = target - @following = follower.following? target + @following = follower&.following? target @name = name end @@ -14,7 +14,7 @@ def before_render end def render? - SiteSettings.multiuser_enabled? || SiteSettings.federation_enabled? + (SiteSettings.multiuser_enabled? || SiteSettings.federation_enabled?) && helpers.policy(Federails::Following).create? end erb_template <<-ERB diff --git a/app/components/model_component.html.erb b/app/components/model_component.html.erb index 854efd649..661bdd4e2 100644 --- a/app/components/model_component.html.erb +++ b/app/components/model_component.html.erb @@ -22,7 +22,7 @@ <%= helpers.status_badges(@model) %>
- <%= link_to t(".open_button.text"), @model, {class: "btn btn-primary btn-sm", "aria-label": translate(".open_button.label", name: @model.name)} if @can_show %> + <%= link_to t(".open_button.text"), @model, {class: "btn btn-primary btn-sm", "aria-label": translate(".open_button.label", name: @model.name)} %> <%= link_to helpers.icon("pencil-fill", t(".edit_button.text")), edit_model_path(@model), {class: "btn btn-outline-secondary btn-sm", "aria-label": translate(".edit_button.label", name: @model.name)} if @can_edit %> <%= link_to helpers.icon("trash", t(".delete_button.text")), model_path(@model), {method: :delete, class: "btn btn-outline-danger btn-sm", "aria-label": translate(".delete_button.label", name: @model.name), data: {confirm: translate("models.destroy.confirm")}} if @can_destroy %>
diff --git a/app/components/model_component.rb b/app/components/model_component.rb index af83e3b40..a758796a9 100644 --- a/app/components/model_component.rb +++ b/app/components/model_component.rb @@ -1,10 +1,9 @@ # frozen_string_literal: true class ModelComponent < ViewComponent::Base - def initialize(model:, can_show: false, can_edit: false, can_destroy: false) + def initialize(model:, can_edit: false, can_destroy: false) @model = model @can_destroy = can_destroy - @can_show = can_show @can_edit = can_edit end end diff --git a/app/controllers/application_controller.rb b/app/controllers/application_controller.rb index abfd1e26d..27e9b8e5a 100644 --- a/app/controllers/application_controller.rb +++ b/app/controllers/application_controller.rb @@ -5,7 +5,6 @@ class ApplicationController < ActionController::Base after_action :verify_policy_scoped, only: :index, unless: :active_admin_controller? after_action :set_content_security_policy_header, if: -> { request.format.html? } - before_action :authenticate_user! around_action :switch_locale before_action :check_for_first_use before_action :show_security_alerts diff --git a/app/controllers/collections_controller.rb b/app/controllers/collections_controller.rb index 93ade2fce..5726d9f21 100644 --- a/app/controllers/collections_controller.rb +++ b/app/controllers/collections_controller.rb @@ -23,9 +23,9 @@ def index @collections.order(name: :asc) end - if current_user.pagination_settings["collections"] + if helpers.pagination_settings["collections"] page = params[:page] || 1 - @collections = @collections.page(page).per(current_user.pagination_settings["per_page"]) + @collections = @collections.page(page).per(helpers.pagination_settings["per_page"]) end # Eager load @collections = @collections.includes :collections, :collection, :links, models: [:preview_file, :library] diff --git a/app/controllers/concerns/tag_listable.rb b/app/controllers/concerns/tag_listable.rb index b67f7c841..b03e28078 100644 --- a/app/controllers/concerns/tag_listable.rb +++ b/app/controllers/concerns/tag_listable.rb @@ -1,13 +1,13 @@ module TagListable def generate_tag_list(models = nil, filter_tags = nil) # All tags bigger than threshold - tags = all_tags = ActsAsTaggableOn::Tag.where(taggings_count: current_user.tag_cloud_settings["threshold"]..) + tags = all_tags = ActsAsTaggableOn::Tag.where(taggings_count: helpers.tag_cloud_settings["threshold"]..) # Ignore any tags that have been applied as filters tags = all_tags = tags.where.not(id: filter_tags) if filter_tags # Generate a list of tags shared by the list of models tags = tags.includes(:taggings).where("taggings.taggable": models.map(&:id)) if models # Apply tag sorting - tags = case current_user.tag_cloud_settings["sorting"] + tags = case helpers.tag_cloud_settings["sorting"] when "alphabetical" tags.order(name: :asc) else @@ -23,7 +23,7 @@ def generate_tag_list(models = nil, filter_tags = nil) def split_key_value_tags(tags) # Split into plain tags and key-value tags - if current_user.tag_cloud_settings["keypair"] + if helpers.tag_cloud_settings["keypair"] plain_tags = tags.where.not("name LIKE '%:%'") kv_tags = tags.where("name LIKE '%:%'") else diff --git a/app/controllers/creators_controller.rb b/app/controllers/creators_controller.rb index b9376a7ca..d7b92b0e0 100644 --- a/app/controllers/creators_controller.rb +++ b/app/controllers/creators_controller.rb @@ -23,9 +23,9 @@ def index @creators.order(name: :asc) end - if current_user.pagination_settings["creators"] + if helpers.pagination_settings["creators"] page = params[:page] || 1 - @creators = @creators.page(page).per(current_user.pagination_settings["per_page"]) + @creators = @creators.page(page).per(helpers.pagination_settings["per_page"]) end # Eager load data @creators = @creators.includes(:links, :models) diff --git a/app/controllers/health_controller.rb b/app/controllers/health_controller.rb index e09ad8dbd..23a9e6ff7 100644 --- a/app/controllers/health_controller.rb +++ b/app/controllers/health_controller.rb @@ -1,8 +1,6 @@ # frozen_string_literal: true class HealthController < ApplicationController - skip_before_action :authenticate_user! - after_action :verify_policy_scoped, except: :index def index diff --git a/app/controllers/models_controller.rb b/app/controllers/models_controller.rb index a02f8f766..8f31c0b35 100644 --- a/app/controllers/models_controller.rb +++ b/app/controllers/models_controller.rb @@ -10,7 +10,6 @@ class ModelsController < ApplicationController def index # Work out policies for showing buttons up front - @can_show = policy(Model).show? @can_destroy = policy(Model).destroy? @can_edit = policy(Model).edit? @@ -24,9 +23,9 @@ def index @models.order(name: :asc) end - if current_user.pagination_settings["models"] + if helpers.pagination_settings["models"] page = params[:page] || 1 - @models = @models.page(page).per(current_user.pagination_settings["per_page"]) + @models = @models.page(page).per(helpers.pagination_settings["per_page"]) end @tags, @unrelated_tag_count = generate_tag_list(@filters.empty? ? nil : @models, @filter_tags) @@ -42,7 +41,7 @@ def show files = @model.model_files @images = files.select(&:is_image?) @images.unshift(@model.preview_file) if @images.delete(@model.preview_file) - if current_user.file_list_settings["hide_presupported_versions"] + if helpers.file_list_settings["hide_presupported_versions"] hidden_ids = files.select(:presupported_version_id).where.not(presupported_version_id: nil) files = files.where.not(id: hidden_ids) end diff --git a/app/controllers/problems_controller.rb b/app/controllers/problems_controller.rb index b0d7f3587..d0dae1478 100644 --- a/app/controllers/problems_controller.rb +++ b/app/controllers/problems_controller.rb @@ -21,7 +21,7 @@ def index # What object types are we showing? query = query.where(problematic_type: params[:type].map(&:classify)) if params[:type] # Don't show types ignored in user settings - query = query.visible(current_user.problem_settings) + query = query.visible(helpers.problem_settings) query = query.includes([:problematic]) @problems = query.page(page).per(50).order([:category, :problematic_type]) # Do we have any filters at all? diff --git a/app/helpers/application_helper.rb b/app/helpers/application_helper.rb index 9039e6c43..18ce4c04d 100644 --- a/app/helpers/application_helper.rb +++ b/app/helpers/application_helper.rb @@ -150,4 +150,24 @@ def translate_with_locale_wrapper(key, **options) end end alias_method :t, :translate_with_locale_wrapper + + def pagination_settings + current_user&.pagination_settings || SiteSettings::UserDefaults::PAGINATION + end + + def tag_cloud_settings + current_user&.tag_cloud_settings || SiteSettings::UserDefaults::TAG_CLOUD.merge(heatmap: false) + end + + def renderer_settings + current_user&.renderer_settings || SiteSettings::UserDefaults::RENDERER + end + + def file_list_settings + current_user&.file_list_settings || SiteSettings::UserDefaults::FILE_LIST + end + + def problem_settings + current_user&.problem_settings || Problem::DEFAULT_SEVERITIES + end end diff --git a/app/helpers/models_helper.rb b/app/helpers/models_helper.rb index aef8d6b59..a6cdde79e 100644 --- a/app/helpers/models_helper.rb +++ b/app/helpers/models_helper.rb @@ -23,7 +23,7 @@ def group(files) def status_badges(model) badges = [] badges << content_tag(:span, icon("bi bi-stars", t("general.new")), class: "text-warning align-middle") if model.new? - badges << problem_icon_tag(model.problems_including_files.visible(current_user.problem_settings)) if policy(Problem).show? + badges << problem_icon_tag(model.problems_including_files.visible(problem_settings)) if policy(Problem).show? content_tag :span, safe_join(badges, " "), class: "status-badges" end diff --git a/app/models/problem.rb b/app/models/problem.rb index 7bc6ff9d5..07da78571 100644 --- a/app/models/problem.rb +++ b/app/models/problem.rb @@ -31,7 +31,7 @@ class Problem < ApplicationRecord :danger ] - DEFAULT_SEVERITIES = { + DEFAULT_SEVERITIES = ActiveSupport::HashWithIndifferentAccess.new( missing: :danger, empty: :info, nesting: :warning, @@ -41,7 +41,7 @@ class Problem < ApplicationRecord no_3d_model: :silent, non_manifold: :warning, inside_out: :warning - } + ) def self.create_or_clear(problematic, cat, present, options = {}) if present diff --git a/app/models/site_settings.rb b/app/models/site_settings.rb index c332ed5cb..4f52e6740 100644 --- a/app/models/site_settings.rb +++ b/app/models/site_settings.rb @@ -58,7 +58,7 @@ def self.ignored_file?(pathname) end module UserDefaults - RENDERER = { + RENDERER = ActiveSupport::HashWithIndifferentAccess.new( grid_width: 200, grid_depth: 200, show_grid: true, @@ -66,24 +66,24 @@ module UserDefaults background_colour: "#000000", object_colour: "#cccccc", render_style: "normals" - } + ) - PAGINATION = { + PAGINATION = ActiveSupport::HashWithIndifferentAccess.new( models: true, creators: true, collections: true, per_page: 12 - } + ) - TAG_CLOUD = { + TAG_CLOUD = ActiveSupport::HashWithIndifferentAccess.new( threshold: 2, heatmap: true, keypair: true, sorting: "frequency" - } + ) - FILE_LIST = { + FILE_LIST = ActiveSupport::HashWithIndifferentAccess.new( hide_presupported_versions: true - } + ) end end diff --git a/app/policies/application_policy.rb b/app/policies/application_policy.rb index 6e7db6613..4295f8d32 100644 --- a/app/policies/application_policy.rb +++ b/app/policies/application_policy.rb @@ -57,7 +57,7 @@ def initialize(user, scope) end def resolve - return scope.all if user.is_moderator? || !scope.respond_to?(:granted_to) + return scope.all if user&.is_moderator? || !scope.respond_to?(:granted_to) result = scope.granted_to(["view", "edit", "own"], [user, nil]) result = result.or(scope.granted_to(["view", "edit", "own"], user.roles)) if user diff --git a/app/policies/federails/following_policy.rb b/app/policies/federails/following_policy.rb index 001ac5cb4..44fbb0f35 100644 --- a/app/policies/federails/following_policy.rb +++ b/app/policies/federails/following_policy.rb @@ -1,16 +1,16 @@ class Federails::FollowingPolicy < ApplicationPolicy def create? - any_of( - SiteSettings.multiuser_enabled?, - SiteSettings.federation_enabled? + all_of( + one_of( + SiteSettings.multiuser_enabled?, + SiteSettings.federation_enabled? + ), + @user ) end def destroy? - any_of( - SiteSettings.multiuser_enabled?, - SiteSettings.federation_enabled? - ) + create? end class Scope < ApplicationPolicy::Scope diff --git a/app/policies/model_file_policy.rb b/app/policies/model_file_policy.rb index b933980c8..24e5ab4dc 100644 --- a/app/policies/model_file_policy.rb +++ b/app/policies/model_file_policy.rb @@ -1,9 +1,25 @@ class ModelFilePolicy < ApplicationPolicy + def show? + ModelPolicy.new(@user, @record.model).show? + end + + def create? + ModelPolicy.new(@user, @record.model).edit? + end + + def update? + create? + end + + def delete? + create? + end + def bulk_edit? - user&.is_moderator? + bulk_update? end def bulk_update? - user&.is_moderator? + create? end end diff --git a/app/views/activities/_create_actor.html.erb b/app/views/activities/_create_actor.html.erb index bf28e0a9e..7ba18c341 100644 --- a/app/views/activities/_create_actor.html.erb +++ b/app/views/activities/_create_actor.html.erb @@ -1,7 +1,7 @@ <%- subject = activity&.actor %> <%- object = activity&.entity %> <%- thing = object&.entity %> -<% if thing %> +<% if thing && !thing.is_a?(User) && (thing.grants_permission_to?(["view", "edit", "own"], current_user) || thing.grants_permission_to?(["view", "edit", "own"], current_user&.roles)) %>
@@ -9,9 +9,7 @@ <%= icon icon_for(thing.class), thing.class.model_name.human %>
- <%- if thing.is_a?(User) %> - <%= object.name %> - <%- elsif object.local? %> + <%- if object.local? %> <%= link_to thing.name, thing %> <%- elsif object.profile_url %> <%= link_to object.name, object.profile_url %> diff --git a/app/views/activities/_update_actor.html.erb b/app/views/activities/_update_actor.html.erb index a53ddae77..dc7438ad2 100644 --- a/app/views/activities/_update_actor.html.erb +++ b/app/views/activities/_update_actor.html.erb @@ -1,7 +1,7 @@ <%- subject = activity&.actor %> <%- object = activity&.entity %> <%- thing = object&.entity %> -<% if thing && !thing.is_a?(User) %> +<% if thing && !thing.is_a?(User) && (thing.grants_permission_to?(["view", "edit", "own"], current_user) || thing.grants_permission_to?(["view", "edit", "own"], current_user&.roles)) %>
diff --git a/app/views/application/_navbar.html.erb b/app/views/application/_navbar.html.erb index 0b0129f33..d897afc36 100644 --- a/app/views/application/_navbar.html.erb +++ b/app/views/application/_navbar.html.erb @@ -55,7 +55,7 @@ <% end %> <%- if current_user %> - <% if policy(Problem).index? && Problem.visible(current_user.problem_settings).count > 0 %> + <% if policy(Problem).index? && Problem.visible(problem_settings).count > 0 %>
diff --git a/app/views/collections/index.html.erb b/app/views/collections/index.html.erb index 769918049..ca4d5d161 100644 --- a/app/views/collections/index.html.erb +++ b/app/views/collections/index.html.erb @@ -5,17 +5,17 @@ <% content_for :items do %> diff --git a/app/views/collections/show.html.erb b/app/views/collections/show.html.erb index 601c7d7e6..5d19056ae 100644 --- a/app/views/collections/show.html.erb +++ b/app/views/collections/show.html.erb @@ -13,13 +13,13 @@
- <% if current_user.pagination_settings["models"] %> + <% if pagination_settings["models"] %> <%= paginate @models %> <% end %>
<%= render partial: "model", collection: @models %>
- <% if current_user.pagination_settings["models"] %> + <% if pagination_settings["models"] %> <%= paginate @models %> <% end %>
diff --git a/app/views/creators/_creator.html.erb b/app/views/creators/_creator.html.erb index ec0d87ff7..38c94964c 100644 --- a/app/views/creators/_creator.html.erb +++ b/app/views/creators/_creator.html.erb @@ -13,7 +13,7 @@
  • <%= link_to t("sites.%{site}" % {site: link.site}), link.url %>
  • <% end %> - <%= link_to "#{creator.models.count} #{Model.model_name.human count: creator.models.count}", models_path(creator: creator.id), {class: "btn btn-primary", "aria-label": translate(".models_button.label", name: creator.name)} if policy(creator).show? %> + <%= link_to "#{policy_scope(Model).where(creator: creator).count} #{Model.model_name.human count: policy_scope(Model).where(creator: creator).count}", models_path(creator: creator.id), {class: "btn btn-primary", "aria-label": translate(".models_button.label", name: creator.name)} if policy(creator).show? %> <%= link_to icon("pencil-fill", t(".edit_button.text")), edit_creator_path(creator), {class: "btn btn-outline-secondary", "aria-label": translate(".edit_button.label", name: creator.name)} if policy(creator).edit? %>
    diff --git a/app/views/creators/_unassigned.html.erb b/app/views/creators/_unassigned.html.erb index 7faebb138..b38516078 100644 --- a/app/views/creators/_unassigned.html.erb +++ b/app/views/creators/_unassigned.html.erb @@ -3,7 +3,7 @@
    <%= t(".name") %>
    <%= t(".caption") %>
    - <%= link_to "#{Model.where(creator: nil).count} #{Model.model_name.human count: Model.where(creator: nil).count}", models_path(creator: ""), {class: "btn btn-primary"} %> + <%= link_to "#{policy_scope(Model).where(creator: nil).count} #{Model.model_name.human count: policy_scope(Model).where(creator: nil).count}", models_path(creator: ""), {class: "btn btn-primary"} %>
    diff --git a/app/views/creators/index.html.erb b/app/views/creators/index.html.erb index 15eaaf296..cc802edd5 100644 --- a/app/views/creators/index.html.erb +++ b/app/views/creators/index.html.erb @@ -5,14 +5,14 @@ <% content_for :items do %> diff --git a/app/views/model_files/show.html.erb b/app/views/model_files/show.html.erb index d62d78347..d5fc92960 100644 --- a/app/views/model_files/show.html.erb +++ b/app/views/model_files/show.html.erb @@ -59,11 +59,11 @@ <%= link_to safe_join([icon("trash", t("general.delete")), t("general.delete")], " "), model_model_file_path(@model, @file), {method: "delete", data: {confirm: translate("model_files.destroy.confirm")}, class: "btn btn-outline-danger"} if policy(@file).destroy? %> <% end %> - <%= render partial: "problem", collection: @file.problems.visible(current_user.problem_settings) %> + <%= render partial: "problem", collection: @file.problems.visible(problem_settings) %> <%= card :secondary, t(".actions_heading") do %> <%= link_to safe_join([icon("cloud-download", t("general.download")), t("general.download")], " "), model_model_file_path(@model, @file, @file.extension.to_sym), {class: "btn btn-secondary"} %> - <% if policy(:model_file).create? && ["stl", "obj"].include?(@file.extension) %> + <% if policy(@file).edit? && ["stl", "obj"].include?(@file.extension) %> <%= link_to safe_join([icon("arrow-left-right", t(".convert")), t(".convert")], " "), model_model_files_path(@model, convert: {id: @file.id, to: "threemf"}), method: :post, class: "btn btn-warning" %> <% end %> <% end %> diff --git a/app/views/models/index.html.erb b/app/views/models/index.html.erb index badff2bdc..e0a162d96 100644 --- a/app/views/models/index.html.erb +++ b/app/views/models/index.html.erb @@ -3,28 +3,37 @@ <% end %> <% content_for :items do %> -