models: factor out api_attributes to policies.

Refactor models so that we define attribute API permissions in policy
files instead of directly in models.

This is cleaner because a) permissions are better handled by policies
and b) which attributes are visible to the API is an API-level concern
that models shouldn't have to care about.

This fixes an issue with not being able to precompile CSS/JS assets
unless the database was up and running. This was a problem when building
Docker images because we don't have a database at build time. We needed
the database because `api_attributes` was a class-level macro in some
places, which meant it ran at boot time, but this triggered a database
call because api_attributes used database introspection to get the list
of allowed API attributes.
This commit is contained in:
evazion
2020-06-08 18:38:02 -05:00
parent b6ed63841d
commit eacb4d4df3
20 changed files with 81 additions and 79 deletions

View File

@@ -69,4 +69,8 @@ class ApplicationPolicy
def permitted_attributes_for_edit
permitted_attributes_for_update
end
def api_attributes
record.class.attribute_types.reject { |name, attr| attr.type.in?([:inet, :tsvector]) }.keys.map(&:to_sym)
end
end

View File

@@ -30,4 +30,8 @@ class DmailPolicy < ApplicationPolicy
def permitted_attributes_for_update
[:is_read, :is_deleted]
end
def api_attributes
super + [:key]
end
end

View File

@@ -0,0 +1,5 @@
class ModActionPolicy < ApplicationPolicy
def api_attributes
super + [:category_id]
end
end

View File

@@ -22,4 +22,8 @@ class PoolPolicy < ApplicationPolicy
def permitted_attributes
[:name, :description, :category, :post_ids, :post_ids_string, post_ids: []]
end
def api_attributes
super + [:post_count]
end
end

View File

@@ -10,4 +10,10 @@ class PostDisapprovalPolicy < ApplicationPolicy
def permitted_attributes
[:post_id, :reason, :message]
end
def api_attributes
attributes = super
attributes -= [:creator_id] unless can_view_creator?
attributes
end
end

View File

@@ -10,4 +10,10 @@ class PostFlagPolicy < ApplicationPolicy
def permitted_attributes
[:post_id, :reason]
end
def api_attributes
attributes = super + [:category]
attributes -= [:creator_id] unless can_view_flagger?
attributes
end
end

View File

@@ -44,7 +44,7 @@ class PostPolicy < ApplicationPolicy
end
def visible?
record.visible?
record.visible?(user)
end
def can_view_uploader?
@@ -85,4 +85,14 @@ class PostPolicy < ApplicationPolicy
(:is_status_locked if can_lock_status?),
].compact
end
def api_attributes
attributes = super
attributes += [:has_large, :has_visible_children, :is_favorited?]
attributes += TagCategory.categories.map {|x| "tag_string_#{x}".to_sym}
attributes += [:file_url, :large_file_url, :preview_file_url] if visible?
attributes -= [:md5, :file_ext] if !visible?
attributes -= [:fav_string] if !user.is_moderator?
attributes
end
end

View File

@@ -6,4 +6,8 @@ class PostVersionPolicy < ApplicationPolicy
def can_mass_undo?
user.is_builder?
end
def api_attributes
super + [:obsolete_added_tags, :obsolete_removed_tags, :unchanged_tags]
end
end

View File

@@ -51,6 +51,30 @@ class UserPolicy < ApplicationPolicy
].compact
end
def api_attributes
attributes = %i[
id created_at name inviter_id level
post_upload_count post_update_count note_update_count is_banned
can_approve_posts can_upload_free level_string
]
if record.id == user.id
attributes += User::BOOLEAN_ATTRIBUTES
attributes += %i[
updated_at last_logged_in_at last_forum_read_at
comment_threshold default_image_size
favorite_tags blacklisted_tags time_zone per_page
custom_style favorite_count api_regen_multiplier
api_burst_limit remaining_api_limit statement_timeout
favorite_group_limit favorite_limit tag_query_limit
is_comment_limited?
max_saved_searches theme
]
end
attributes
end
alias_method :profile?, :show?
alias_method :settings?, :edit?
end

View File

@@ -14,4 +14,8 @@ class WikiPagePolicy < ApplicationPolicy
def permitted_attributes
[:title, :body, :other_names, :other_names_string, :is_deleted, (:is_locked if can_edit_locked?)].compact
end
def api_attributes
super + [:category_name]
end
end