class JSONAPI::Authorization::DefaultPunditAuthorizer
An authorizer is a class responsible for linking JSONAPI
operations to your choice of authorization mechanism.
This class uses Pundit for authorization. You can use your own authorizer class instead if you have different needs. See the README.md for configuration information.
Fetching records is the concern of PunditScopedResource
which in turn affects which records end up being passed here.
Attributes
Public Class Methods
Creates a new DefaultPunditAuthorizer
instance
Parameters¶ ↑
-
context
- The context passed down from the controller layer
# File lib/jsonapi/authorization/default_pundit_authorizer.rb, line 20 def initialize(context:) @user = JSONAPI::Authorization.configuration.user_context(context) end
Public Instance Methods
POST /resources
Parameters¶ ↑
-
source_class
- The class of the record to be created -
related_records_with_context
- A has with the association type,
the relationship name, and an Array of new related records.
# File lib/jsonapi/authorization/default_pundit_authorizer.rb, line 107 def create_resource(source_class:, related_records_with_context:) ::Pundit.authorize(user, source_class, 'create?') related_records_with_context.each do |data| relation_name = data[:relation_name] records = data[:records] relationship_method = "create_with_#{relation_name}?" policy = ::Pundit.policy(user, source_class) if policy.respond_to?(relationship_method) unless policy.public_send(relationship_method, records) raise ::Pundit::NotAuthorizedError, query: relationship_method, record: source_class, policy: policy end else Array(records).each do |record| ::Pundit.authorize(user, record, 'update?') end end end end
POST /resources/:id/relationships/other-resources
A request for adding to a has_many
association
Parameters¶ ↑
-
source_record
- The record whose relationship is modified -
new_related_records
- The new records to be added to the association -
relationship_type
- The relationship type
# File lib/jsonapi/authorization/default_pundit_authorizer.rb, line 165 def create_to_many_relationship(source_record:, new_related_records:, relationship_type:) relationship_method = "add_to_#{relationship_type}?" authorize_relationship_operation( source_record: source_record, relationship_method: relationship_method, related_record_or_records: new_related_records ) end
Any request including ?include=other-resources
This will be called for each has_many relationship if the include goes deeper than one level until some authorization fails or the include directive has been travelled completely.
We can't pass all the records of a has_many
association here due to performance reasons, so the class is passed instead.
Parameters¶ ↑
-
source_record
— The source relationship record, e.g. an Article inarticle.comments check
-
record_class
- The underlying record class for the relationshipsresource.
rubocop:disable Lint/UnusedMethodArgument
# File lib/jsonapi/authorization/default_pundit_authorizer.rb, line 243 def include_has_many_resource(source_record:, record_class:) ::Pundit.authorize(user, record_class, 'index?') end
Any request including ?include=another-resource
This will be called for each has_one relationship if the include goes deeper than one level until some authorization fails or the include directive has been travelled completely.
Parameters¶ ↑
-
source_record
— The source relationship record, e.g. an Article inarticle.author check
-
related_record
- The associated record to return
rubocop:disable Lint/UnusedMethodArgument
# File lib/jsonapi/authorization/default_pundit_authorizer.rb, line 260 def include_has_one_resource(source_record:, related_record:) ::Pundit.authorize(user, related_record, 'show?') end
DELETE /resources/:id/relationships/other-resources
A request to disassociate elements of a has_many
association
Parameters¶ ↑
-
source_record
- The record whose relationship is modified -
related_records
- The records which will be disassociated fromsource_record
-
relationship_type
- The relationship type
# File lib/jsonapi/authorization/default_pundit_authorizer.rb, line 202 def remove_to_many_relationship(source_record:, related_records:, relationship_type:) relationship_method = "remove_from_#{relationship_type}?" authorize_relationship_operation( source_record: source_record, relationship_method: relationship_method, related_record_or_records: related_records ) end
DELETE /resources/:id/relationships/another-resource
A request to disassociate a has_one
association
Parameters¶ ↑
-
source_record
- The record whose relationship is modified -
relationship_type
- The relationship type
# File lib/jsonapi/authorization/default_pundit_authorizer.rb, line 219 def remove_to_one_relationship(source_record:, relationship_type:) relationship_method = "remove_#{relationship_type}?" authorize_relationship_operation( source_record: source_record, relationship_method: relationship_method ) end
PATCH /resources/:id
Parameters¶ ↑
-
source_record
- The record to be modified -
related_records_with_context
- A hash with the association type,
the relationship name, an Array of new related records.
# File lib/jsonapi/authorization/default_pundit_authorizer.rb, line 92 def replace_fields(source_record:, related_records_with_context:) ::Pundit.authorize(user, source_record, 'update?') authorize_related_records( source_record: source_record, related_records_with_context: related_records_with_context ) end
PATCH /resources/:id/relationships/other-resources
A replace request for a has_many
association
Parameters¶ ↑
-
source_record
- The record whose relationship is modified -
new_related_records
- The new records replacing the entirehas_many
association -
relationship_type
- The relationship type
# File lib/jsonapi/authorization/default_pundit_authorizer.rb, line 184 def replace_to_many_relationship(source_record:, new_related_records:, relationship_type:) relationship_method = "replace_#{relationship_type}?" authorize_relationship_operation( source_record: source_record, relationship_method: relationship_method, related_record_or_records: new_related_records ) end
PATCH /resources/:id/relationships/another-resource
A replace request for a has_one
association
Parameters¶ ↑
-
source_record
- The record whose relationship is modified -
new_related_record
- The new record replacing the old record -
relationship_type
- The relationship type
# File lib/jsonapi/authorization/default_pundit_authorizer.rb, line 147 def replace_to_one_relationship(source_record:, new_related_record:, relationship_type:) relationship_method = "replace_#{relationship_type}?" authorize_relationship_operation( source_record: source_record, relationship_method: relationship_method, related_record_or_records: new_related_record ) end
GET /resources/:id/relationships/other-resources
GET /resources/:id/relationships/another-resource
A query for a has_one
or a has_many
association
Parameters¶ ↑
-
source_record
- The record whose relationship is queried -
related_record
- The associatedhas_one
record to show ornil
if the associated record was not found. For ahas_many
association, this will always benil
# File lib/jsonapi/authorization/default_pundit_authorizer.rb, line 53 def show_relationship(source_record:, related_record:) ::Pundit.authorize(user, source_record, 'show?') ::Pundit.authorize(user, related_record, 'show?') unless related_record.nil? end