aboutsummaryrefslogtreecommitdiffstats
path: root/app/policies/application_policy.rb
blob: 36f14437afb7ac84c4404c693500bc013a8d39f4 (plain)
1
2
3
4
5
6
7
8
9
10
11
12
13
14
15
16
17
18
19
20
21
22
23
24
25
26
27
28
29
30
31
32
33
34
35
36
37
38
39
40
41
42
43
44
45
46
47
48
49
50
51
52
53
54
55
56
57
58
59
60
61
62
63
64
65
66
67
68
69
70
71
72
73
74
75
76
77
78
79
80
81
82
83
84
85
86
87
88
89
90
91
92
93
94
95
96
97
98
99
100
101
102
103
104
105
106
107
108
109
110
111
112
113
114
115
116
117
118
119
120
121
122
123
124
125
126
127
128
129
130
131
132
133
134
135
136
137
138
139
140
class ApplicationPolicy

  attr_reader :current_referential, :record, :user
  def initialize(user_context, record)
    @user                = user_context.user
    @current_referential = user_context.context[:referential]
    @record              = record
  end

  # HMMM: Maybe one can tie index? to show? again by replacing record.class as follows:
  #       Class === record ? record : record.class
  def scope
    Pundit.policy_scope!(user, record.class)
  end

  # Make authorization by action easier
  def delete?
    destroy?
  end

  def authorizes_action?(action)
    public_send("#{action}?")
  rescue NoMethodError
    false
  end


  #
  # Tied permissions
  # ----------------

  # Tie edit? and update? together, #edit?, do not override #edit?,
  # unless you want to break this tie on purpose
  def edit?
    update?
  end

  # Tie new? and create? together, do not override #new?,
  # unless you want to break this tie on purpose
  def new?
    create?
  end


  #
  # Permissions for undestructive actions
  # -------------------------------------

  def index?
    true
  end

  def show?
    scope.where(:id => record.id).exists?
  end


  #
  # Permissions for destructive actions
  # -----------------------------------

  def create?
    false
  end

  def destroy?
    false
  end

  def update?
    false
  end


  #
  #  Custom Permissions
  #  ------------------

  def archived?
    return @is_archived if instance_variable_defined?(:@is_archived)
    @is_archived = is_archived
  end

  def referential_read_only?
    return @is_referential_read_only if instance_variable_defined?(:@is_referential_read_only)
    @is_referential_read_only = is_referential_read_only
  end

  def organisation_match?
    user.organisation_id == organisation_id
  end

  def organisation_id
    # When sending permission to react UI, we don't have access to record object for edit & destroy.. actions
    referential.try(:organisation_id) || record.try(:organisation_id)
  end

  #
  #  Helpers
  #  -------

  def referential
    @referential ||= current_referential || record_referential
  end

  def record_referential
    record.referential if record.respond_to?(:referential)
  end
  class Scope
    attr_reader :user, :scope

    def initialize(user, scope)
      @user = user
      @scope = scope
    end

    def resolve
      scope
    end
  end

  private
  def is_archived
    !!case referential
    when Referential
      referential.archived_at
    else
      current_referential.try(:archived_at)
    end
  end

  def is_referential_read_only
    !!case referential
    when Referential
      referential.referential_read_only?
    else
      current_referential.try(:referential_read_only?)
    end
  end
end