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
35
# 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) && role_subject_class.where(subject_foreign_key.to_sym => id, role_foreign_key.to_sym => target.id, :context_type => context.class_name, :context_id => context.id).limit(1).first.nil?

    return role_subject_class.create(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)


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

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 true unless (context.id.nil? && !force_context) || role_subject_class.joins(role_class_name.underscore.to_sym).where(subject_foreign_key.to_sym => id, role_foreign_key.to_sym => target.id, :context_type => context.class_name, :context_id => context.id).first.nil?
    return false if force_context
    return true unless context.class_name.nil? || role_subject_class.where(subject_foreign_key.to_sym => id, role_foreign_key.to_sym => target.id, :context_type => context.class_name, :context_id => nil).first.nil?
    return !role_subject_class.where(subject_foreign_key.to_sym => id, role_foreign_key.to_sym => target.id, :context_type => nil, :context_id => nil).first.nil?
  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
# 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 true unless context.id.nil? || role_subject_class.joins(role_class_name.underscore.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).first.nil?
    return true unless context.class_name.nil? || role_subject_class.joins(role_class_name.underscore.to_sym).where(subject_foreign_key.to_sym => id, :context_type => context.class_name, :context_id => nil).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).first.nil?
    return !role_subject_class.joins(role_class_name.underscore.to_sym).where(subject_foreign_key.to_sym => id, :context_type => nil, :context_id => nil).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).first.nil?
  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.



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

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

#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.



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

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 role_class.joins(role_subject_class_name.pluralize.underscore.to_sym).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)
    else
      return role_class.joins(role_subject_class_name.pluralize.underscore.to_sym).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
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)


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

def roles_for?(context=nil, force_context=nil)
  roles_for(context, force_context).count > 0
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.



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

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_class.where(subject_foreign_key.to_sym => id, role_foreign_key.to_sym => target.id, :context_type => context.class_name, :context_id => context.id).limit(1).first
    return false if assigned_role.nil?
    return assigned_role.destroy
  end
end