Module: ActsPermissive::PermissiveUser::InstanceMethods

Defined in:
lib/acts_permissive/permissive_user.rb

Instance Method Summary collapse

Instance Method Details

#acts_permissive?Boolean

Returns:

  • (Boolean)


21
22
23
# File 'lib/acts_permissive/permissive_user.rb', line 21

def acts_permissive?
  true
end

#build_circle(*args) ⇒ Object



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
# File 'lib/acts_permissive/permissive_user.rb', line 32

def build_circle *args
  #Set up the option defaults
  params = args.extract_options!
  params.assert_valid_keys(:name, :mask, :objects, :class)

  params[:name] = "Unnamed Circle" if params[:name].nil?
  params[:mask] = 255 if params[:mask].nil?
  params[:objects] = [] if params[:objects].nil?
  params[:class] = Circle if params[:class].nil?

  #Build the circle and set the permissions mask
  circle = params[:class].create :name => params[:name]
  perm = Permission.create :circle => circle, :mask => params[:mask]
  group = Grouping.create :permissible => self, :permission => perm

  raise "Something happened saving permission: #{perm.inspect}" unless perm.save
  raise "Something happened saving permission: #{group.inspect}" unless group.save

  #If there are any objects in the list that don't respond to is_used_permissively, they
  # are silently ignored
  params[:objects].select{|o| o.respond_to? :is_used_permissively?}.each{ |o| o.add_to circle}

  #return for use
  circle
end

#can!(*args) ⇒ Object

Raises:



81
82
83
84
85
86
87
88
89
90
91
92
93
94
95
96
97
98
99
100
101
102
# File 'lib/acts_permissive/permissive_user.rb', line 81

def can! *args
  options = args.extract_options!
  options.assert_valid_keys(:in)

  # We're only using this if there are circles- not on generic objects, which should be INSIDE circles
  raise PermissiveError, "Must be called with a circle as an argument" if options[:in].nil?

  #get the permission, or build it if it doesn't exist
  perm = permissions_in(options[:in])
  if perm.nil?
    perm = permissions.build(:circle => options[:in])
  end

  # For each permission, bitwise OR them together unless we have a zero, in which case we just ignore
  args.select{|o| o.class == Symbol}.each do |name|
    bit = Permission.bit_for name
    perm.mask = perm.mask & bit != 0 ? 0 : perm.mask | bit
  end

  raise PermissiveError, "Cannot save permission: #{perm.errors}" if not save!
  perm
end

#can?(*args) ⇒ Boolean

Returns:

  • (Boolean)


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
141
142
143
144
145
146
# File 'lib/acts_permissive/permissive_user.rb', line 104

def can? *args
  #TODO this is freakin long. Refactor this shit
  options = args.extract_options!
  options.assert_valid_keys(:in, :see)

  # Get the bitmap for the selected permissions
  bits = args.select{|o| o.class == Symbol}.map{|s| Permission.bit_for s}.inject(0){|sum, p| sum + p }

  #if we're checking for :see, return right away
  if options[:see]
    return permissions_in(options[:see]).present?
  end

  # Get a list of objects that we might be searching on
  objects = args.select{|o| o.respond_to? :is_used_permissively?}

  raise "Cannot search in both circles and objects at the same time" if options[:in].present? and objects.count > 0

  if options[:in].nil? and objects.count > 0
    warn "You are testing permissions on multiple objects. This is an OR query, which will return true if ANY have the requested permission" if objects.count > 1
    objects.each do |object|
      object.circles.each do |circle|
        # return true immediately if we find a circle where our permissions cover the bitmask
        perm = permissions_in circle
        if perm.present?
          return true if perm.mask & bits == bits
        end
      end
    end
  elsif options[:in].present?
    #Get the permissions and return
    perm = permissions_in options[:in]
    if perm.nil?
      return false
    else
      return perm.mask & bits == bits
    end
  else
    warn "You haven't given an object or circle to search on. Failing silently. (Perhaps a model does not call 'is_used_permissively', check that. Argument list: #{args.inspect}"
  end
  # Failsafe to false
  false
end

#circles(*args) ⇒ Object



25
26
27
28
29
30
# File 'lib/acts_permissive/permissive_user.rb', line 25

def circles *args
  params = args.extract_options!
  params.assert_valid_keys(:of_type)
  params[:of_type] = Circle if params[:of_type].nil?
  params[:of_type].by_user self
end

#permissions_for(obj) ⇒ Object



63
64
65
# File 'lib/acts_permissive/permissive_user.rb', line 63

def permissions_for obj
  obj.circles.map{ |c| permissions_in(c) }.compact
end

#permissions_in(circle) ⇒ Object

Raises:



58
59
60
61
# File 'lib/acts_permissive/permissive_user.rb', line 58

def permissions_in circle
  raise PermissiveError, "Must be an ActsPermissive::Circle instance" if not circle.is_a?(Circle)
  Permission.for(self).in(circle).first
end

#reset_permissions!(*args) ⇒ Object

Raises:



67
68
69
70
71
72
73
74
75
76
77
78
79
# File 'lib/acts_permissive/permissive_user.rb', line 67

def reset_permissions! *args
  options = args.extract_options!
  options.assert_valid_keys(:in)

  raise PermissiveError, "Must be called with a circle as an argument" if options[:in].nil?

  #get the permission, or build it if it doesn't exist
  perm = permissions_in(options[:in])
  if perm.nil?
    return
  end
  perm.reset!
end

#revoke!(*args) ⇒ Object

Raises:



148
149
150
151
152
153
154
155
156
157
158
159
160
161
162
163
164
165
166
167
168
169
# File 'lib/acts_permissive/permissive_user.rb', line 148

def revoke! *args
  options = args.extract_options!
  options.assert_valid_keys(:in)

  # We're only using this if there are circles- not on generic objects, which should be INSIDE circles
  raise PermissiveError, "Must be called with a circle as an argument" if options[:in].nil?

  bits = args.map{|s| Permission.bit_for s}.inject(0){|sum, p| sum + p }

  #Get the permissions and return
  perm = permissions_in options[:in]

  if args.include? :all
    perm.destroy
  else
    perm.mask = perm.mask ^ bits if perm.mask & bits
    perm.save!
  end

  # Remove from circle and destroy permissions if the mask is zero
  perm.destroy if perm.mask == 0
end