Class: Decidim::Api::Types::BaseObject

Inherits:
GraphQL::Schema::Object
  • Object
show all
Defined in:
decidim-api/lib/decidim/api/types/base_object.rb

Direct Known Subclasses

Decidim::Accountability::ResultType, Decidim::Accountability::StatusType, Decidim::Accountability::TimelineEntryType, MutationType, QueryType, Decidim::Assemblies::AssembliesTypeType, Decidim::Assemblies::AssemblyType, Blogs::PostType, Budgets::BudgetType, Budgets::ProjectType, Comments::AddCommentType, Comments::CommentMutationType, Comments::CommentType, Comments::CommentableMutationType, Comments::CommentableType, Conferences::ConferenceMediaLinkType, Conferences::ConferencePartnerType, Conferences::ConferenceSpeakerType, Conferences::ConferenceType, Core::AmendmentType, Core::AreaApiType, Core::AreaTypeType, Core::AttachmentType, Core::CategoryType, Core::ComponentType, Core::CoordinatesType, Core::DecidimType, Core::FingerprintType, Core::HashtagType, Core::LocalizedStringType, Core::MetricHistoryType, Core::MetricType, Core::OrganizationType, Core::ParticipatorySpaceLinkType, Core::ParticipatorySpaceManifestType, Core::ParticipatorySpaceType, Core::QuantifiableTranslatedFieldType, Core::ScopeApiType, Core::SessionType, Core::StatisticType, Core::TaxonomyType, Core::TraceVersionType, Core::TranslatedFieldType, Core::UserGroupType, Core::UserType, Debates::DebateType, Forms::AnswerOptionType, Forms::QuestionType, Forms::QuestionnaireType, Initiatives::InitiativeApiType, Initiatives::InitiativeCommitteeMemberType, Initiatives::InitiativeType, Meetings::AgendaItemType, Meetings::AgendaType, Meetings::MeetingType, Meetings::ServiceType, Pages::PageType, ParticipatoryProcesses::ParticipatoryProcessGroupType, ParticipatoryProcesses::ParticipatoryProcessStepType, ParticipatoryProcesses::ParticipatoryProcessType, ParticipatoryProcesses::ParticipatoryProcessTypeType, Proposals::ProposalType, Sortitions::SortitionType, Surveys::SurveyType

Class Method Summary collapse

Class Method Details

.allowed_to?(action, subject, object, context) ⇒ Boolean

This is a simplified adaptation of allowed_to? from NeedsPermission concern

Parameters:

  • action (Symbol)

    The action performed. Most cases the action is :read

  • subject (Object)

    The name of the subject. Ex: :participatory_space, :component, or object

  • object (ActiveModel::Base)

    The object that is being represented.

  • context (GraphQL::Query::Context)

    The GraphQL context

Returns:

  • (Boolean)

    Boolean



32
33
34
35
36
37
38
39
40
41
42
43
44
45
46
47
# File 'decidim-api/lib/decidim/api/types/base_object.rb', line 32

def self.allowed_to?(action, subject, object, context)
  unless subject.is_a?(::Symbol)
    subject = determine_subject_name(object)
    context[subject] = object
  end

  permission_action = Decidim::PermissionAction.new(scope: :public, action:, subject:)

  permission_chain(object).inject(permission_action) do |current_permission_action, permission_class|
    permission_class.new(
      context[:current_user],
      current_permission_action,
      local_context(object, context)
    ).permissions
  end.allowed?
end

.authorized?(object, context) ⇒ Boolean

Returns:

  • (Boolean)


9
10
11
12
13
14
15
16
17
18
19
# File 'decidim-api/lib/decidim/api/types/base_object.rb', line 9

def self.authorized?(object, context)
  chain = []

  subject = determine_subject_name(object)
  context[subject] = object

  chain.unshift(allowed_to?(:read, :participatory_space, object, context)) if object.respond_to?(:participatory_space)
  chain.unshift(allowed_to?(:read, :component, object, context)) if object.respond_to?(:component) && object.component.present?

  super && chain.all?
end

.determine_subject_name(object) ⇒ Object



21
22
23
# File 'decidim-api/lib/decidim/api/types/base_object.rb', line 21

def self.determine_subject_name(object)
  object.class.name.split("::").last.underscore.to_sym
end

.local_context(object, context) ⇒ Object

Injects into context object current_participatory_space and current_component keys as they are needed

Parameters:

  • object (ActiveModel::Base)

    The object that is being represented.

  • context (GraphQL::Query::Context)

    The GraphQL context

Returns:

  • Hash



55
56
57
58
59
60
# File 'decidim-api/lib/decidim/api/types/base_object.rb', line 55

def self.local_context(object, context)
  context[:current_participatory_space] = object.participatory_space if object.respond_to?(:participatory_space)
  context[:current_component] = object.component if object.respond_to?(:component) && object.component.present?

  context.to_h
end

.permission_chain(object) ⇒ Decidim::DefaultPermissions

Creates the permission chain arrau that contains all the permission classes required to authorize a certain resource We are using unshift as we need the Admin and base permissions to be last in the chain

Parameters:

  • object (ActiveModel::Base)

    The object that is being represented.

Returns:



67
68
69
70
71
72
73
74
75
76
77
# File 'decidim-api/lib/decidim/api/types/base_object.rb', line 67

def self.permission_chain(object)
  permissions = [
    Decidim::Admin::Permissions,
    Decidim::Permissions
  ]

  permissions.unshift(object.participatory_space.manifest.permissions_class) if object.respond_to?(:participatory_space)
  permissions.unshift(object.component.manifest.permissions_class) if object.respond_to?(:component) && object.component.present?

  permissions
end