Module: Zuul::ActiveRecord::Subject::RoleMethods::InstanceMethods

Defined in:
lib/zuul/active_record/subject.rb

Instance Method Summary collapse

Instance Method Details

#assign_role(role, context = nil, force_context = nil) ⇒ Object

Assigns a role to a subject within the provided context.

If a Role object is provided it’s used directly, otherwise if a role slug is provided, the role is looked up in the context chain by target_role.



27
28
29
30
31
32
33
34
# File 'lib/zuul/active_record/subject.rb', line 27

def assign_role(role, context=nil, force_context=nil)
  auth_scope do
    context = Zuul::Context.parse(context)
    target = target_role(role, context, force_context)
    return false unless verify_target_context(target, context, force_context)
    return role_subject_class.find_or_create_by(subject_foreign_key.to_sym => id, role_foreign_key.to_sym => target.id, :context_type => context.class_name, :context_id => context.id)
  end
end

#has_role?(role, context = nil, force_context = nil) ⇒ Boolean Also known as: role?

Checks whether a subject has a role within the provided context.

If a Role object is provided it’s used directly, otherwise if a role slug is provided, the role is looked up in the context chain by target_role.

The assigned context behaves the same way, in that if the role is not found to belong to the subject with the specified context, we look up the context chain.

Returns:

  • (Boolean)


60
61
62
63
64
65
66
67
68
69
70
71
72
73
# File 'lib/zuul/active_record/subject.rb', line 60

def has_role?(role, context=nil, force_context=nil)
  auth_scope do
    force_context ||= config.force_context
    context = Zuul::Context.parse(context)
    target = target_role(role, context, force_context)
    return false if target.nil?
    return role_subject_for?(target, context) if force_context

    return true if role_subject_for?(target, context)
    return true if context.instance? && role_subject_for?(target, Zuul::Context.new(context.klass))
    return true if !context.global? && role_subject_for?(target, Zuul::Context.new)
    return false
  end
end

#has_role_or_higher?(role, context = nil, force_context = nil) ⇒ Boolean Also known as: role_or_higher?, at_least_role?

Checks whether a subject has the specified role or a role with a level greather than that of the specified role, within the provided context.

If a Role object is provided it’s used directly, otherwise if a role slug is provided, the role is looked up in the context chain by target_role.

The assigned context behaves the same way, in that if a matching role is not found to belong to the subject with the specified context, we look up the context chain.

Returns:

  • (Boolean)


84
85
86
87
88
89
90
91
92
93
94
95
96
97
# File 'lib/zuul/active_record/subject.rb', line 84

def has_role_or_higher?(role, context=nil, force_context=nil)
  auth_scope do
    context = Zuul::Context.parse(context)
    target = target_role(role, context, force_context)
    return false if target.nil?
    return true if has_role?(target, context, force_context)
    return role_subject_or_higher_for?(target, context) if force_context

    return true if role_subject_or_higher_for?(target, context)
    return true if context.instance? && role_subject_or_higher_for?(target, Zuul::Context.new(context.klass))
    return true if !context.global? && role_subject_or_higher_for?(target, Zuul::Context.new)
    return false
  end
end

#highest_role(context = nil, force_context = nil) ⇒ Object

Returns the highest level role a subject possesses within the provided context.

This includes any roles found by looking up the context chain.



104
105
106
107
# File 'lib/zuul/active_record/subject.rb', line 104

def highest_role(context=nil, force_context=nil)
  return nil unless roles_for?(context, force_context)
  roles_for(context, force_context).order(:level).reverse_order.limit(1).first
end

#role_subject_for(target, context) ⇒ Object

Looks up a single role subject based on the passed target and context



132
133
134
135
136
# File 'lib/zuul/active_record/subject.rb', line 132

def role_subject_for(target, context)
  auth_scope do
    return role_subject_class.joins(role_table_name.singularize.to_sym).find_by(subject_foreign_key.to_sym => id, role_foreign_key.to_sym => target.id, :context_type => context.class_name, :context_id => context.id)
  end
end

#role_subject_for?(target, context) ⇒ Boolean

Returns:

  • (Boolean)


138
139
140
# File 'lib/zuul/active_record/subject.rb', line 138

def role_subject_for?(target, context)
  !role_subject_for(target, context).nil?
end

#role_subject_or_higher_for(target, context) ⇒ Object

Looks up a single role subject with a level greather than or equal to the target level based on the passed target and context



143
144
145
146
147
148
149
150
151
152
153
# File 'lib/zuul/active_record/subject.rb', line 143

def role_subject_or_higher_for(target, context)
  auth_scope do
    return role_subject_class.joins(role_table_name.singularize.to_sym).where(subject_foreign_key.to_sym => id, :context_type => context.class_name, :context_id => context.id).where("
      #{roles_table_name}.level >= ?
      AND #{roles_table_name}.context_type #{sql_is_or_equal(target.context_type)} ?
      AND #{roles_table_name}.context_id #{sql_is_or_equal(target.context_id)} ?",
      target.level,
      target.context_type,
      target.context_id).limit(1).first
  end
end

#role_subject_or_higher_for?(target, context) ⇒ Boolean

Returns:

  • (Boolean)


155
156
157
# File 'lib/zuul/active_record/subject.rb', line 155

def role_subject_or_higher_for?(target, context)
  !role_subject_or_higher_for(target, context).nil?
end

#roles_for(context = nil, force_context = nil) ⇒ Object

Returns all roles possessed by the subject within the provided context.

This includes all roles found by looking up the context chain.



112
113
114
115
116
117
118
119
120
121
122
# File 'lib/zuul/active_record/subject.rb', line 112

def roles_for(context=nil, force_context=nil)
  auth_scope do
    force_context ||= config.force_context
    context = Zuul::Context.parse(context)
    if force_context
      return subject_roles_for(context)
    else
      return subject_roles_within(context)
    end
  end
end

#roles_for?(context = nil, force_context = nil) ⇒ Boolean

Check whether the subject possesses any roles within the specified context.

This includes any roles found by looking up the context chain.

Returns:

  • (Boolean)


127
128
129
# File 'lib/zuul/active_record/subject.rb', line 127

def roles_for?(context=nil, force_context=nil)
  roles_for(context, force_context).count > 0
end

#subject_roles_for(context) ⇒ Object

Looks up all roles for the subject for the passed context



160
161
162
163
164
165
166
167
168
169
170
# File 'lib/zuul/active_record/subject.rb', line 160

def subject_roles_for(context)
  auth_scope do
    return role_class.joins(role_subject_plural_key).where("
      #{role_subjects_table_name}.#{subject_foreign_key} = ?
      AND #{role_subjects_table_name}.context_type #{sql_is_or_equal(context.class_name)} ?
      AND #{role_subjects_table_name}.context_id #{sql_is_or_equal(context.id)} ?",
      id,
      context.class_name,
      context.id)
  end
end

#subject_roles_for?(context) ⇒ Boolean

Returns:

  • (Boolean)


172
173
174
# File 'lib/zuul/active_record/subject.rb', line 172

def subject_roles_for?(context)
  !subject_roles_for(context).empty?
end

#subject_roles_within(context) ⇒ Object

Looks up all roles for the subject within the passed context (within the context chain)



177
178
179
180
181
182
183
184
185
186
187
188
189
190
191
192
193
194
195
# File 'lib/zuul/active_record/subject.rb', line 177

def subject_roles_within(context)
  auth_scope do
    return role_class.joins(role_subject_plural_key).where("
      #{role_subjects_table_name}.#{subject_foreign_key} = ?
      AND (
        (
          #{role_subjects_table_name}.context_type #{sql_is_or_equal(context.class_name)} ?
          OR #{role_subjects_table_name}.context_type IS NULL
        )
        AND (
          #{role_subjects_table_name}.context_id #{sql_is_or_equal(context.id)} ?
          OR #{role_subjects_table_name}.context_id IS NULL
        )
      )",
      id,
      context.class_name,
      context.id)
  end
end

#subject_roles_within?(context) ⇒ Boolean

Returns:

  • (Boolean)


197
198
199
# File 'lib/zuul/active_record/subject.rb', line 197

def subject_roles_within?(context)
  !subject_roles_within(context).empty?
end

#unassign_role(role, context = nil, force_context = nil) ⇒ Object Also known as: remove_role

Removes a role from a subject within the provided context.

If a Role object is provided it’s used directly, otherwise if a role slug is provided, the role is looked up in the context chain by target_role.



40
41
42
43
44
45
46
47
48
49
50
# File 'lib/zuul/active_record/subject.rb', line 40

def unassign_role(role, context=nil, force_context=nil)
  auth_scope do
    context = Zuul::Context.parse(context)
    target = target_role(role, context, force_context)
    return false if target.nil?

    assigned_role = role_subject_for(target, context)
    return false if assigned_role.nil?
    return assigned_role.destroy
  end
end