concealer
Privacy control your models (or any other Ruby object) with ease.
Requirements
-
activesupport (~> 3.0)
Install
To install concealer, simply add it to your Gemfile:
gem 'concealer'
In order to get the latest development version of concealer:
gem 'concealer', :git => 'git://github.com/flinc/concealer'
Finally run:
bundle install
Usage
To use concealer simply include the Concealer module:
class User
include Concealer
attr_accessor :name, :email
end
This will add a #concealed method to your object. Calling this will return a proxy object that checks every call and only forwards allowed ones to the original object.
user = User.new
user.concealed.name # => user.name
user.concealed.email # => user.email
Strategies
The default strategy for Concealer is Concealer::Strategy::Allow which forwards every call to the original object. At the moment there are several other strategies available:
-
Concealer::Strategy::Allow
-
Concealer::Strategy::Deny
-
Concealer::Strategy::Whitelist
-
Concealer::Strategy::Blacklist
-
Concealer::Strategy::All
-
Concealer::Strategy::Any
You can set the strategy for Concealer using Concealer.strategy=
Concealer.strategy = Concealer::Strategy::Deny.new
user = User.new(:name => 'Frank', :email => '[email protected]')
user.concealed.name # => nil
user.concealed.email # => nil
Advanced Strategies
There is one more advanced privacy strategies available: Concealer::Strategy::MultiLevel
. To use it you’ll have to implement your own subclass of it to match your domain model. The example below illustrates what it might look like.
Your custom multi level privacy strategy:
class CustomPrivacyStrategy < Concealer::Strategy::MultiLevel
def required_level_for(model, name, args)
case model
when Profile, User:
return privacy_level_for(owner_of(model), :name) if [:firstname, :lastname].include?(name.to_sym)
return privacy_level_for(owner_of(model), :age) if [:age].include?(name.to_sym)
end
:myself
end
protected
def privacy_level_for(user, key)
user.privacy_settings.send(key).try(:to_sym)
end
end
Your User model:
class User
# ...
def relation_level_to(other)
if other == self
:myself
elsif self.friend_of?(other)
:friends
else
:everyone
end
end
end
In your Rails ApplicationController:
around_filter :setup_privacy_strategy
def setup_privacy_strategy(&block)
Concealer.with_strategy(CustomPrivacyStrategy.new(current_user, [:myself, :friends, :everyone]), &block)
end
Implementing Strategies
You can implement your own strategies by subclassing Concealer::Strategy or adding an #allow?(model, attribute, args)
method to any object you pass into Concealer.strategy=
.
Fallbacks
In some cases you don’t want to just return nil for unallowed method calls. In order to provide sensible return values Concealer has a fallbacks. Available fallbacks are:
-
Concealer::Fallback::Nil
-
Concealer::Fallback::String
-
Concealer::Fallback::Paperclip
You can add fallbacks for method calls like this:
Concealer.register_fallback(User, :email, Concealer::Fallback::String.new("unkown"))
Concealer.register_fallback(User, :avatar, Concealer::Fallback::Paperclip.new)
Concealer.register_fallback(User, :name, lambda { |model, method, args| "#{model.send(method).at(0)}." })
Known issues
See github.com/flinc/concealer/issues
Repository
See github.com/flinc/concealer and feel free to fork it!
Contributors
See a list of all contributors at github.com/flinc/concealer/contributors. Thanks a lot everyone!
Copyright
Copyright © 2011 flinc AG. See LICENSE for details.