concealer 0.0.1
This diff represents the content of publicly available package versions that have been released to one of the supported registries. The information contained in this diff is provided for informational purposes only and reflects changes between package versions as they appear in their respective public registries.
- data/.gitignore +1 -0
 - data/.rspec +1 -0
 - data/Gemfile +4 -0
 - data/LICENSE +20 -0
 - data/README.rdoc +148 -0
 - data/Rakefile +10 -0
 - data/concealer.gemspec +24 -0
 - data/lib/concealer/fallback/nil.rb +5 -0
 - data/lib/concealer/fallback/paperclip.rb +5 -0
 - data/lib/concealer/fallback/string.rb +10 -0
 - data/lib/concealer/fallback.rb +12 -0
 - data/lib/concealer/proxy.rb +20 -0
 - data/lib/concealer/strategy/allow.rb +5 -0
 - data/lib/concealer/strategy/blacklist.rb +17 -0
 - data/lib/concealer/strategy/deny.rb +5 -0
 - data/lib/concealer/strategy/multi_level.rb +38 -0
 - data/lib/concealer/strategy/whitelist.rb +17 -0
 - data/lib/concealer/strategy.rb +14 -0
 - data/lib/concealer/version.rb +3 -0
 - data/lib/concealer.rb +43 -0
 - data/spec/concealer/fallback/nil_spec.rb +9 -0
 - data/spec/concealer/fallback/paperclip_spec.rb +11 -0
 - data/spec/concealer/fallback/string_spec.rb +9 -0
 - data/spec/concealer/fallback_spec.rb +9 -0
 - data/spec/concealer/proxy_spec.rb +37 -0
 - data/spec/concealer/strategy/allow_spec.rb +7 -0
 - data/spec/concealer/strategy/blacklist_spec.rb +15 -0
 - data/spec/concealer/strategy/deny_spec.rb +7 -0
 - data/spec/concealer/strategy/multi_level_spec.rb +41 -0
 - data/spec/concealer/strategy/whitelist_spec.rb +15 -0
 - data/spec/concealer/strategy_spec.rb +7 -0
 - data/spec/concealer_spec.rb +62 -0
 - data/spec/spec_helper.rb +11 -0
 - data/spec/support/concealed_model.rb +11 -0
 - data/spec/support/paperclip.rb +6 -0
 - data/spec/support/user.rb +13 -0
 - metadata +163 -0
 
    
        data/.gitignore
    ADDED
    
    | 
         @@ -0,0 +1 @@ 
     | 
|
| 
      
 1 
     | 
    
         
            +
            Gemfile.lock
         
     | 
    
        data/.rspec
    ADDED
    
    | 
         @@ -0,0 +1 @@ 
     | 
|
| 
      
 1 
     | 
    
         
            +
            --color
         
     | 
    
        data/Gemfile
    ADDED
    
    
    
        data/LICENSE
    ADDED
    
    | 
         @@ -0,0 +1,20 @@ 
     | 
|
| 
      
 1 
     | 
    
         
            +
            Copyright (c) 2011 flinc AG
         
     | 
| 
      
 2 
     | 
    
         
            +
             
     | 
| 
      
 3 
     | 
    
         
            +
            Permission is hereby granted, free of charge, to any person obtaining
         
     | 
| 
      
 4 
     | 
    
         
            +
            a copy of this software and associated documentation files (the
         
     | 
| 
      
 5 
     | 
    
         
            +
            "Software"), to deal in the Software without restriction, including
         
     | 
| 
      
 6 
     | 
    
         
            +
            without limitation the rights to use, copy, modify, merge, publish,
         
     | 
| 
      
 7 
     | 
    
         
            +
            distribute, sublicense, and/or sell copies of the Software, and to
         
     | 
| 
      
 8 
     | 
    
         
            +
            permit persons to whom the Software is furnished to do so, subject to
         
     | 
| 
      
 9 
     | 
    
         
            +
            the following conditions:
         
     | 
| 
      
 10 
     | 
    
         
            +
             
     | 
| 
      
 11 
     | 
    
         
            +
            The above copyright notice and this permission notice shall be
         
     | 
| 
      
 12 
     | 
    
         
            +
            included in all copies or substantial portions of the Software.
         
     | 
| 
      
 13 
     | 
    
         
            +
             
     | 
| 
      
 14 
     | 
    
         
            +
            THE SOFTWARE IS PROVIDED "AS IS", WITHOUT WARRANTY OF ANY KIND,
         
     | 
| 
      
 15 
     | 
    
         
            +
            EXPRESS OR IMPLIED, INCLUDING BUT NOT LIMITED TO THE WARRANTIES OF
         
     | 
| 
      
 16 
     | 
    
         
            +
            MERCHANTABILITY, FITNESS FOR A PARTICULAR PURPOSE AND
         
     | 
| 
      
 17 
     | 
    
         
            +
            NONINFRINGEMENT. IN NO EVENT SHALL THE AUTHORS OR COPYRIGHT HOLDERS BE
         
     | 
| 
      
 18 
     | 
    
         
            +
            LIABLE FOR ANY CLAIM, DAMAGES OR OTHER LIABILITY, WHETHER IN AN ACTION
         
     | 
| 
      
 19 
     | 
    
         
            +
            OF CONTRACT, TORT OR OTHERWISE, ARISING FROM, OUT OF OR IN CONNECTION
         
     | 
| 
      
 20 
     | 
    
         
            +
            WITH THE SOFTWARE OR THE USE OR OTHER DEALINGS IN THE SOFTWARE.
         
     | 
    
        data/README.rdoc
    ADDED
    
    | 
         @@ -0,0 +1,148 @@ 
     | 
|
| 
      
 1 
     | 
    
         
            +
            = concealer
         
     | 
| 
      
 2 
     | 
    
         
            +
             
     | 
| 
      
 3 
     | 
    
         
            +
            Privacy control your models (or any other Ruby object) with ease.
         
     | 
| 
      
 4 
     | 
    
         
            +
             
     | 
| 
      
 5 
     | 
    
         
            +
            == Requirements
         
     | 
| 
      
 6 
     | 
    
         
            +
             
     | 
| 
      
 7 
     | 
    
         
            +
            * activesupport (~> 3.0)
         
     | 
| 
      
 8 
     | 
    
         
            +
             
     | 
| 
      
 9 
     | 
    
         
            +
             
     | 
| 
      
 10 
     | 
    
         
            +
            == Install
         
     | 
| 
      
 11 
     | 
    
         
            +
             
     | 
| 
      
 12 
     | 
    
         
            +
            To install concealer, simply add it to your Gemfile:
         
     | 
| 
      
 13 
     | 
    
         
            +
             
     | 
| 
      
 14 
     | 
    
         
            +
              gem 'concealer'
         
     | 
| 
      
 15 
     | 
    
         
            +
             
     | 
| 
      
 16 
     | 
    
         
            +
            In order to get the latest development version of concealer:
         
     | 
| 
      
 17 
     | 
    
         
            +
             
     | 
| 
      
 18 
     | 
    
         
            +
              gem 'concealer', :git => 'git://github.com/flinc/concealer'
         
     | 
| 
      
 19 
     | 
    
         
            +
             
     | 
| 
      
 20 
     | 
    
         
            +
            Finally run:
         
     | 
| 
      
 21 
     | 
    
         
            +
             
     | 
| 
      
 22 
     | 
    
         
            +
              bundle install
         
     | 
| 
      
 23 
     | 
    
         
            +
             
     | 
| 
      
 24 
     | 
    
         
            +
             
     | 
| 
      
 25 
     | 
    
         
            +
            == Usage
         
     | 
| 
      
 26 
     | 
    
         
            +
             
     | 
| 
      
 27 
     | 
    
         
            +
            To use concealer simply include the Concealer module:
         
     | 
| 
      
 28 
     | 
    
         
            +
             
     | 
| 
      
 29 
     | 
    
         
            +
              class User
         
     | 
| 
      
 30 
     | 
    
         
            +
                include Concealer
         
     | 
| 
      
 31 
     | 
    
         
            +
             
     | 
| 
      
 32 
     | 
    
         
            +
                attr_accessor :name, :email
         
     | 
| 
      
 33 
     | 
    
         
            +
              end
         
     | 
| 
      
 34 
     | 
    
         
            +
             
     | 
| 
      
 35 
     | 
    
         
            +
            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.
         
     | 
| 
      
 36 
     | 
    
         
            +
             
     | 
| 
      
 37 
     | 
    
         
            +
              user = User.new
         
     | 
| 
      
 38 
     | 
    
         
            +
              user.concealed.name # => user.name
         
     | 
| 
      
 39 
     | 
    
         
            +
              user.concealed.email # => user.email
         
     | 
| 
      
 40 
     | 
    
         
            +
             
     | 
| 
      
 41 
     | 
    
         
            +
            === Strategies
         
     | 
| 
      
 42 
     | 
    
         
            +
             
     | 
| 
      
 43 
     | 
    
         
            +
            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:
         
     | 
| 
      
 44 
     | 
    
         
            +
             
     | 
| 
      
 45 
     | 
    
         
            +
            * Concealer::Strategy::Allow
         
     | 
| 
      
 46 
     | 
    
         
            +
            * Concealer::Strategy::Deny
         
     | 
| 
      
 47 
     | 
    
         
            +
            * Concealer::Strategy::Whitelist
         
     | 
| 
      
 48 
     | 
    
         
            +
            * Concealer::Strategy::Blacklist
         
     | 
| 
      
 49 
     | 
    
         
            +
             
     | 
| 
      
 50 
     | 
    
         
            +
            You can set the strategy for Concealer using <tt>Concealer.strategy=</tt>
         
     | 
| 
      
 51 
     | 
    
         
            +
             
     | 
| 
      
 52 
     | 
    
         
            +
              Concealer.strategy = Concealer::Strategy::Deny.new
         
     | 
| 
      
 53 
     | 
    
         
            +
             
     | 
| 
      
 54 
     | 
    
         
            +
              user = User.new
         
     | 
| 
      
 55 
     | 
    
         
            +
              user.concealed.name # => nil
         
     | 
| 
      
 56 
     | 
    
         
            +
              user.concealed.email # => nil
         
     | 
| 
      
 57 
     | 
    
         
            +
             
     | 
| 
      
 58 
     | 
    
         
            +
            === Advanced Strategies
         
     | 
| 
      
 59 
     | 
    
         
            +
             
     | 
| 
      
 60 
     | 
    
         
            +
            There is one more advanced privacy strategies available: <tt>Concealer::Strategy::MultiLevel</tt>.
         
     | 
| 
      
 61 
     | 
    
         
            +
            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.
         
     | 
| 
      
 62 
     | 
    
         
            +
             
     | 
| 
      
 63 
     | 
    
         
            +
            Your custom multi level privacy strategy:
         
     | 
| 
      
 64 
     | 
    
         
            +
             
     | 
| 
      
 65 
     | 
    
         
            +
              class CustomPrivacyStrategy < Concealer::Strategy::MultiLevel
         
     | 
| 
      
 66 
     | 
    
         
            +
             
     | 
| 
      
 67 
     | 
    
         
            +
                def required_level_for(model, name, args)
         
     | 
| 
      
 68 
     | 
    
         
            +
                  case model
         
     | 
| 
      
 69 
     | 
    
         
            +
                    when Profile, User:
         
     | 
| 
      
 70 
     | 
    
         
            +
                      return privacy_level_for(owner_of(model), :name) if [:firstname, :lastname].include?(name.to_sym)
         
     | 
| 
      
 71 
     | 
    
         
            +
                      return privacy_level_for(owner_of(model), :age)  if [:age].include?(name.to_sym)
         
     | 
| 
      
 72 
     | 
    
         
            +
                  end
         
     | 
| 
      
 73 
     | 
    
         
            +
             
     | 
| 
      
 74 
     | 
    
         
            +
                  :myself
         
     | 
| 
      
 75 
     | 
    
         
            +
                end
         
     | 
| 
      
 76 
     | 
    
         
            +
             
     | 
| 
      
 77 
     | 
    
         
            +
                protected
         
     | 
| 
      
 78 
     | 
    
         
            +
             
     | 
| 
      
 79 
     | 
    
         
            +
                def privacy_level_for(user, key)
         
     | 
| 
      
 80 
     | 
    
         
            +
                  user.privacy_settings.send(key).try(:to_sym)
         
     | 
| 
      
 81 
     | 
    
         
            +
                end
         
     | 
| 
      
 82 
     | 
    
         
            +
              end
         
     | 
| 
      
 83 
     | 
    
         
            +
             
     | 
| 
      
 84 
     | 
    
         
            +
             
     | 
| 
      
 85 
     | 
    
         
            +
            Your User model:
         
     | 
| 
      
 86 
     | 
    
         
            +
             
     | 
| 
      
 87 
     | 
    
         
            +
              class User
         
     | 
| 
      
 88 
     | 
    
         
            +
             
     | 
| 
      
 89 
     | 
    
         
            +
                # ...
         
     | 
| 
      
 90 
     | 
    
         
            +
             
     | 
| 
      
 91 
     | 
    
         
            +
                def relation_level_to(other)
         
     | 
| 
      
 92 
     | 
    
         
            +
                  if other == self
         
     | 
| 
      
 93 
     | 
    
         
            +
                    :myself
         
     | 
| 
      
 94 
     | 
    
         
            +
                  elsif self.friend_of?(other)
         
     | 
| 
      
 95 
     | 
    
         
            +
                    :friends
         
     | 
| 
      
 96 
     | 
    
         
            +
                  else
         
     | 
| 
      
 97 
     | 
    
         
            +
                    :everyone
         
     | 
| 
      
 98 
     | 
    
         
            +
                  end
         
     | 
| 
      
 99 
     | 
    
         
            +
                end
         
     | 
| 
      
 100 
     | 
    
         
            +
              end
         
     | 
| 
      
 101 
     | 
    
         
            +
             
     | 
| 
      
 102 
     | 
    
         
            +
            In your Rails ApplicationController:
         
     | 
| 
      
 103 
     | 
    
         
            +
             
     | 
| 
      
 104 
     | 
    
         
            +
              around_filter :setup_privacy_strategy
         
     | 
| 
      
 105 
     | 
    
         
            +
             
     | 
| 
      
 106 
     | 
    
         
            +
              def setup_privacy_strategy(&block)
         
     | 
| 
      
 107 
     | 
    
         
            +
                Concealer.with_strategy(CustomPrivacyStrategy.new(current_user, [:myself, :friends, :everyone]), &block)
         
     | 
| 
      
 108 
     | 
    
         
            +
              end
         
     | 
| 
      
 109 
     | 
    
         
            +
             
     | 
| 
      
 110 
     | 
    
         
            +
             
     | 
| 
      
 111 
     | 
    
         
            +
            === Implementing Strategies
         
     | 
| 
      
 112 
     | 
    
         
            +
             
     | 
| 
      
 113 
     | 
    
         
            +
            You can implement your own strategies by subclassing Concealer::Strategy or adding an <tt>#allow?(model, attribute, args)</tt> method to any object you pass into <tt>Concealer.strategy=</tt>.
         
     | 
| 
      
 114 
     | 
    
         
            +
             
     | 
| 
      
 115 
     | 
    
         
            +
             
     | 
| 
      
 116 
     | 
    
         
            +
            === Fallbacks
         
     | 
| 
      
 117 
     | 
    
         
            +
             
     | 
| 
      
 118 
     | 
    
         
            +
            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:
         
     | 
| 
      
 119 
     | 
    
         
            +
             
     | 
| 
      
 120 
     | 
    
         
            +
            * Concealer::Fallback::Nil
         
     | 
| 
      
 121 
     | 
    
         
            +
            * Concealer::Fallback::String
         
     | 
| 
      
 122 
     | 
    
         
            +
            * Concealer::Fallback::Paperclip
         
     | 
| 
      
 123 
     | 
    
         
            +
             
     | 
| 
      
 124 
     | 
    
         
            +
            You can add fallbacks for method calls like this:
         
     | 
| 
      
 125 
     | 
    
         
            +
             
     | 
| 
      
 126 
     | 
    
         
            +
              Concealer.register_fallback(User, :email, Concealer::Fallback::String.new("unkown"))
         
     | 
| 
      
 127 
     | 
    
         
            +
              Concealer.register_fallback(User, :avatar, Concealer::Fallback::Paperclip.new)
         
     | 
| 
      
 128 
     | 
    
         
            +
              Concealer.register_fallback(User, :name, lambda { |model, method, args| "#{model.send(method).at(0)}." })
         
     | 
| 
      
 129 
     | 
    
         
            +
             
     | 
| 
      
 130 
     | 
    
         
            +
             
     | 
| 
      
 131 
     | 
    
         
            +
            == Known issues
         
     | 
| 
      
 132 
     | 
    
         
            +
             
     | 
| 
      
 133 
     | 
    
         
            +
            See https://github.com/flinc/concealer/issues
         
     | 
| 
      
 134 
     | 
    
         
            +
             
     | 
| 
      
 135 
     | 
    
         
            +
             
     | 
| 
      
 136 
     | 
    
         
            +
            == Repository
         
     | 
| 
      
 137 
     | 
    
         
            +
             
     | 
| 
      
 138 
     | 
    
         
            +
            See https://github.com/flinc/concealer and feel free to fork it!
         
     | 
| 
      
 139 
     | 
    
         
            +
             
     | 
| 
      
 140 
     | 
    
         
            +
             
     | 
| 
      
 141 
     | 
    
         
            +
            == Contributors
         
     | 
| 
      
 142 
     | 
    
         
            +
             
     | 
| 
      
 143 
     | 
    
         
            +
            See a list of all contributors at https://github.com/flinc/concealer/contributors. Thanks a lot everyone!
         
     | 
| 
      
 144 
     | 
    
         
            +
             
     | 
| 
      
 145 
     | 
    
         
            +
             
     | 
| 
      
 146 
     | 
    
         
            +
            == Copyright
         
     | 
| 
      
 147 
     | 
    
         
            +
             
     | 
| 
      
 148 
     | 
    
         
            +
            Copyright (c) 2011 flinc AG. See LICENSE for details.
         
     | 
    
        data/Rakefile
    ADDED
    
    
    
        data/concealer.gemspec
    ADDED
    
    | 
         @@ -0,0 +1,24 @@ 
     | 
|
| 
      
 1 
     | 
    
         
            +
            # -*- encoding: utf-8 -*-
         
     | 
| 
      
 2 
     | 
    
         
            +
            $:.push File.expand_path("../lib", __FILE__)
         
     | 
| 
      
 3 
     | 
    
         
            +
            require "concealer/version"
         
     | 
| 
      
 4 
     | 
    
         
            +
             
     | 
| 
      
 5 
     | 
    
         
            +
            Gem::Specification.new do |s|
         
     | 
| 
      
 6 
     | 
    
         
            +
              s.name        = "concealer"
         
     | 
| 
      
 7 
     | 
    
         
            +
              s.version     = Concealer::VERSION
         
     | 
| 
      
 8 
     | 
    
         
            +
              s.platform    = Gem::Platform::RUBY
         
     | 
| 
      
 9 
     | 
    
         
            +
              s.authors     = ["Benedikt Deicke", "Christian Bäuerlein"]
         
     | 
| 
      
 10 
     | 
    
         
            +
              s.email       = ["benedikt@synatic.net", "fabrik42@gmail.com"]
         
     | 
| 
      
 11 
     | 
    
         
            +
              s.homepage    = "https://flinc.github.com/concealer"
         
     | 
| 
      
 12 
     | 
    
         
            +
              s.summary     = %q{Privacy control your models with ease}
         
     | 
| 
      
 13 
     | 
    
         
            +
              s.description = %q{Privacy control your models with ease}
         
     | 
| 
      
 14 
     | 
    
         
            +
             
     | 
| 
      
 15 
     | 
    
         
            +
              s.files         = `git ls-files`.split("\n")
         
     | 
| 
      
 16 
     | 
    
         
            +
              s.test_files    = `git ls-files -- {test,spec,features}/*`.split("\n")
         
     | 
| 
      
 17 
     | 
    
         
            +
              s.executables   = `git ls-files -- bin/*`.split("\n").map{ |f| File.basename(f) }
         
     | 
| 
      
 18 
     | 
    
         
            +
              s.require_paths = ["lib"]
         
     | 
| 
      
 19 
     | 
    
         
            +
             
     | 
| 
      
 20 
     | 
    
         
            +
              s.add_runtime_dependency('activesupport', ['~> 3.0'])
         
     | 
| 
      
 21 
     | 
    
         
            +
             
     | 
| 
      
 22 
     | 
    
         
            +
              s.add_development_dependency('rspec', ['~> 2.3'])
         
     | 
| 
      
 23 
     | 
    
         
            +
              s.add_development_dependency('rake')
         
     | 
| 
      
 24 
     | 
    
         
            +
            end
         
     | 
| 
         @@ -0,0 +1,12 @@ 
     | 
|
| 
      
 1 
     | 
    
         
            +
            module Concealer
         
     | 
| 
      
 2 
     | 
    
         
            +
              class Fallback
         
     | 
| 
      
 3 
     | 
    
         
            +
             
     | 
| 
      
 4 
     | 
    
         
            +
                autoload :Nil,          'concealer/fallback/nil'
         
     | 
| 
      
 5 
     | 
    
         
            +
                autoload :String,  'concealer/fallback/string'
         
     | 
| 
      
 6 
     | 
    
         
            +
                autoload :Paperclip,    'concealer/fallback/paperclip'
         
     | 
| 
      
 7 
     | 
    
         
            +
             
     | 
| 
      
 8 
     | 
    
         
            +
                def call(model, method, args)
         
     | 
| 
      
 9 
     | 
    
         
            +
                  raise "The fallback must implement #call(model, method, args)"
         
     | 
| 
      
 10 
     | 
    
         
            +
                end
         
     | 
| 
      
 11 
     | 
    
         
            +
              end
         
     | 
| 
      
 12 
     | 
    
         
            +
            end
         
     | 
| 
         @@ -0,0 +1,20 @@ 
     | 
|
| 
      
 1 
     | 
    
         
            +
            module Concealer
         
     | 
| 
      
 2 
     | 
    
         
            +
              class Proxy
         
     | 
| 
      
 3 
     | 
    
         
            +
                instance_methods.each { |m| undef_method(m) unless m =~ /(^__|^send$|^object_id$)/ }
         
     | 
| 
      
 4 
     | 
    
         
            +
             
     | 
| 
      
 5 
     | 
    
         
            +
                def initialize(target, strategy)
         
     | 
| 
      
 6 
     | 
    
         
            +
                  @target = target
         
     | 
| 
      
 7 
     | 
    
         
            +
                  @strategy = strategy
         
     | 
| 
      
 8 
     | 
    
         
            +
                end
         
     | 
| 
      
 9 
     | 
    
         
            +
             
     | 
| 
      
 10 
     | 
    
         
            +
                protected
         
     | 
| 
      
 11 
     | 
    
         
            +
             
     | 
| 
      
 12 
     | 
    
         
            +
                def method_missing(name, *args, &block)
         
     | 
| 
      
 13 
     | 
    
         
            +
                  if @strategy.allow?(@target, name, args)
         
     | 
| 
      
 14 
     | 
    
         
            +
                    @target.send(name, *args, &block)
         
     | 
| 
      
 15 
     | 
    
         
            +
                  else
         
     | 
| 
      
 16 
     | 
    
         
            +
                    Concealer.fallback_for(@target, name).call(@target, name, args)
         
     | 
| 
      
 17 
     | 
    
         
            +
                  end
         
     | 
| 
      
 18 
     | 
    
         
            +
                end
         
     | 
| 
      
 19 
     | 
    
         
            +
              end
         
     | 
| 
      
 20 
     | 
    
         
            +
            end
         
     | 
| 
         @@ -0,0 +1,17 @@ 
     | 
|
| 
      
 1 
     | 
    
         
            +
            class Concealer::Strategy::Blacklist < Concealer::Strategy::Allow
         
     | 
| 
      
 2 
     | 
    
         
            +
             
     | 
| 
      
 3 
     | 
    
         
            +
              def initialize(blacklist)
         
     | 
| 
      
 4 
     | 
    
         
            +
                @blacklist = blacklist
         
     | 
| 
      
 5 
     | 
    
         
            +
              end
         
     | 
| 
      
 6 
     | 
    
         
            +
             
     | 
| 
      
 7 
     | 
    
         
            +
              def allow?(model, method, args)
         
     | 
| 
      
 8 
     | 
    
         
            +
                return false if blacklisted_methods(model).include?(method)
         
     | 
| 
      
 9 
     | 
    
         
            +
                super
         
     | 
| 
      
 10 
     | 
    
         
            +
              end
         
     | 
| 
      
 11 
     | 
    
         
            +
             
     | 
| 
      
 12 
     | 
    
         
            +
              private
         
     | 
| 
      
 13 
     | 
    
         
            +
             
     | 
| 
      
 14 
     | 
    
         
            +
              def blacklisted_methods(model)
         
     | 
| 
      
 15 
     | 
    
         
            +
                @blacklist[model.class] ||= []
         
     | 
| 
      
 16 
     | 
    
         
            +
              end
         
     | 
| 
      
 17 
     | 
    
         
            +
            end
         
     | 
| 
         @@ -0,0 +1,38 @@ 
     | 
|
| 
      
 1 
     | 
    
         
            +
            class Concealer::Strategy::MultiLevel < Concealer::Strategy
         
     | 
| 
      
 2 
     | 
    
         
            +
             
     | 
| 
      
 3 
     | 
    
         
            +
              def initialize(current_user, levels)
         
     | 
| 
      
 4 
     | 
    
         
            +
                @current_user = current_user
         
     | 
| 
      
 5 
     | 
    
         
            +
                @levels = levels
         
     | 
| 
      
 6 
     | 
    
         
            +
              end
         
     | 
| 
      
 7 
     | 
    
         
            +
             
     | 
| 
      
 8 
     | 
    
         
            +
              def allow?(model, method, args)
         
     | 
| 
      
 9 
     | 
    
         
            +
                required_level = required_level_for(model, method, args)
         
     | 
| 
      
 10 
     | 
    
         
            +
                actual_level = @current_user.relation_level_to(owner_of(model))
         
     | 
| 
      
 11 
     | 
    
         
            +
             
     | 
| 
      
 12 
     | 
    
         
            +
                raise "The level #{required_level} is not valid." unless @levels.include?(required_level)
         
     | 
| 
      
 13 
     | 
    
         
            +
                raise "The level #{actual_level} is not valid."   unless @levels.include?(actual_level)
         
     | 
| 
      
 14 
     | 
    
         
            +
             
     | 
| 
      
 15 
     | 
    
         
            +
                return @levels.index(actual_level) <= @levels.index(required_level)
         
     | 
| 
      
 16 
     | 
    
         
            +
              end
         
     | 
| 
      
 17 
     | 
    
         
            +
             
     | 
| 
      
 18 
     | 
    
         
            +
              protected
         
     | 
| 
      
 19 
     | 
    
         
            +
             
     | 
| 
      
 20 
     | 
    
         
            +
              def current_user
         
     | 
| 
      
 21 
     | 
    
         
            +
                @current_user
         
     | 
| 
      
 22 
     | 
    
         
            +
              end
         
     | 
| 
      
 23 
     | 
    
         
            +
             
     | 
| 
      
 24 
     | 
    
         
            +
              def required_level_for(model, method, args)
         
     | 
| 
      
 25 
     | 
    
         
            +
                @levels.first
         
     | 
| 
      
 26 
     | 
    
         
            +
              end
         
     | 
| 
      
 27 
     | 
    
         
            +
             
     | 
| 
      
 28 
     | 
    
         
            +
              def owner_of(model)
         
     | 
| 
      
 29 
     | 
    
         
            +
                if model.respond_to?(:relation_level_to)
         
     | 
| 
      
 30 
     | 
    
         
            +
                  model
         
     | 
| 
      
 31 
     | 
    
         
            +
                elsif model.respond_to?(:user)
         
     | 
| 
      
 32 
     | 
    
         
            +
                  model.user
         
     | 
| 
      
 33 
     | 
    
         
            +
                else
         
     | 
| 
      
 34 
     | 
    
         
            +
                  nil
         
     | 
| 
      
 35 
     | 
    
         
            +
                end
         
     | 
| 
      
 36 
     | 
    
         
            +
              end
         
     | 
| 
      
 37 
     | 
    
         
            +
             
     | 
| 
      
 38 
     | 
    
         
            +
            end
         
     | 
| 
         @@ -0,0 +1,17 @@ 
     | 
|
| 
      
 1 
     | 
    
         
            +
            class Concealer::Strategy::Whitelist < Concealer::Strategy::Deny
         
     | 
| 
      
 2 
     | 
    
         
            +
             
     | 
| 
      
 3 
     | 
    
         
            +
              def initialize(whitelist)
         
     | 
| 
      
 4 
     | 
    
         
            +
                @whitelist = whitelist
         
     | 
| 
      
 5 
     | 
    
         
            +
              end
         
     | 
| 
      
 6 
     | 
    
         
            +
             
     | 
| 
      
 7 
     | 
    
         
            +
              def allow?(model, method, args)
         
     | 
| 
      
 8 
     | 
    
         
            +
                return true if whitelisted_methods(model).include?(method)
         
     | 
| 
      
 9 
     | 
    
         
            +
                super
         
     | 
| 
      
 10 
     | 
    
         
            +
              end
         
     | 
| 
      
 11 
     | 
    
         
            +
             
     | 
| 
      
 12 
     | 
    
         
            +
              private
         
     | 
| 
      
 13 
     | 
    
         
            +
             
     | 
| 
      
 14 
     | 
    
         
            +
              def whitelisted_methods(model)
         
     | 
| 
      
 15 
     | 
    
         
            +
                @whitelist[model.class] ||= []
         
     | 
| 
      
 16 
     | 
    
         
            +
              end
         
     | 
| 
      
 17 
     | 
    
         
            +
            end
         
     | 
| 
         @@ -0,0 +1,14 @@ 
     | 
|
| 
      
 1 
     | 
    
         
            +
            module Concealer
         
     | 
| 
      
 2 
     | 
    
         
            +
              class Strategy
         
     | 
| 
      
 3 
     | 
    
         
            +
             
     | 
| 
      
 4 
     | 
    
         
            +
                autoload :Allow,      'concealer/strategy/allow'
         
     | 
| 
      
 5 
     | 
    
         
            +
                autoload :Deny,       'concealer/strategy/deny'
         
     | 
| 
      
 6 
     | 
    
         
            +
                autoload :Blacklist,  'concealer/strategy/blacklist'
         
     | 
| 
      
 7 
     | 
    
         
            +
                autoload :Whitelist,  'concealer/strategy/whitelist'
         
     | 
| 
      
 8 
     | 
    
         
            +
                autoload :MultiLevel, 'concealer/strategy/multi_level'
         
     | 
| 
      
 9 
     | 
    
         
            +
             
     | 
| 
      
 10 
     | 
    
         
            +
                def allow?(model, method, args)
         
     | 
| 
      
 11 
     | 
    
         
            +
                  raise "The stragegy must implement #allow?(model, method, args)"
         
     | 
| 
      
 12 
     | 
    
         
            +
                end
         
     | 
| 
      
 13 
     | 
    
         
            +
              end
         
     | 
| 
      
 14 
     | 
    
         
            +
            end
         
     | 
    
        data/lib/concealer.rb
    ADDED
    
    | 
         @@ -0,0 +1,43 @@ 
     | 
|
| 
      
 1 
     | 
    
         
            +
            require 'active_support/concern'
         
     | 
| 
      
 2 
     | 
    
         
            +
            require 'active_support/core_ext/object/try'
         
     | 
| 
      
 3 
     | 
    
         
            +
            require 'active_support/core_ext/module/attribute_accessors'
         
     | 
| 
      
 4 
     | 
    
         
            +
             
     | 
| 
      
 5 
     | 
    
         
            +
            module Concealer
         
     | 
| 
      
 6 
     | 
    
         
            +
              extend ActiveSupport::Concern
         
     | 
| 
      
 7 
     | 
    
         
            +
             
     | 
| 
      
 8 
     | 
    
         
            +
              autoload :Proxy,    'concealer/proxy'
         
     | 
| 
      
 9 
     | 
    
         
            +
              autoload :Strategy, 'concealer/strategy'
         
     | 
| 
      
 10 
     | 
    
         
            +
              autoload :Fallback, 'concealer/fallback'
         
     | 
| 
      
 11 
     | 
    
         
            +
             
     | 
| 
      
 12 
     | 
    
         
            +
              mattr_accessor :default_fallback
         
     | 
| 
      
 13 
     | 
    
         
            +
              @@default_fallback = Concealer::Fallback::Nil.new
         
     | 
| 
      
 14 
     | 
    
         
            +
             
     | 
| 
      
 15 
     | 
    
         
            +
              def self.strategy=(strategy)
         
     | 
| 
      
 16 
     | 
    
         
            +
                Thread.current[:concealer_strategy] = strategy
         
     | 
| 
      
 17 
     | 
    
         
            +
              end
         
     | 
| 
      
 18 
     | 
    
         
            +
             
     | 
| 
      
 19 
     | 
    
         
            +
              def self.strategy
         
     | 
| 
      
 20 
     | 
    
         
            +
                Thread.current[:concealer_strategy] || Concealer::Strategy::Allow.new
         
     | 
| 
      
 21 
     | 
    
         
            +
              end
         
     | 
| 
      
 22 
     | 
    
         
            +
             
     | 
| 
      
 23 
     | 
    
         
            +
              def self.with_strategy(strategy)
         
     | 
| 
      
 24 
     | 
    
         
            +
                save, self.strategy = self.strategy, strategy
         
     | 
| 
      
 25 
     | 
    
         
            +
                yield
         
     | 
| 
      
 26 
     | 
    
         
            +
                self.strategy = save
         
     | 
| 
      
 27 
     | 
    
         
            +
              end
         
     | 
| 
      
 28 
     | 
    
         
            +
             
     | 
| 
      
 29 
     | 
    
         
            +
              def self.register_fallback(model, method, fallback)
         
     | 
| 
      
 30 
     | 
    
         
            +
                @@fallbacks ||= {}
         
     | 
| 
      
 31 
     | 
    
         
            +
                @@fallbacks[model.to_s.to_sym] ||= {}
         
     | 
| 
      
 32 
     | 
    
         
            +
                @@fallbacks[model.to_s.to_sym][method] = fallback
         
     | 
| 
      
 33 
     | 
    
         
            +
              end
         
     | 
| 
      
 34 
     | 
    
         
            +
             
     | 
| 
      
 35 
     | 
    
         
            +
              def self.fallback_for(model, method)
         
     | 
| 
      
 36 
     | 
    
         
            +
                @@fallbacks ||= {}
         
     | 
| 
      
 37 
     | 
    
         
            +
                @@fallbacks.try(:[], model.class.to_s.to_sym).try(:[], method.to_sym) || @@default_fallback
         
     | 
| 
      
 38 
     | 
    
         
            +
              end
         
     | 
| 
      
 39 
     | 
    
         
            +
             
     | 
| 
      
 40 
     | 
    
         
            +
              def concealed
         
     | 
| 
      
 41 
     | 
    
         
            +
                Proxy.new(self, Concealer.strategy)
         
     | 
| 
      
 42 
     | 
    
         
            +
              end
         
     | 
| 
      
 43 
     | 
    
         
            +
            end
         
     | 
| 
         @@ -0,0 +1,11 @@ 
     | 
|
| 
      
 1 
     | 
    
         
            +
            require 'spec_helper'
         
     | 
| 
      
 2 
     | 
    
         
            +
             
     | 
| 
      
 3 
     | 
    
         
            +
            describe Concealer::Fallback::Paperclip do
         
     | 
| 
      
 4 
     | 
    
         
            +
              describe '#call' do
         
     | 
| 
      
 5 
     | 
    
         
            +
                it "should return a paperclip attachment" do
         
     | 
| 
      
 6 
     | 
    
         
            +
                  ConcealedModel.stub!(:attachment_definitions).and_return({ :avatar => :something })
         
     | 
| 
      
 7 
     | 
    
         
            +
                  Paperclip::Attachment.should_receive(:new).with(:avatar, anything, :something).and_return(:paperclip)
         
     | 
| 
      
 8 
     | 
    
         
            +
                  subject.call(ConcealedModel.new, :avatar, nil).should eq(:paperclip)
         
     | 
| 
      
 9 
     | 
    
         
            +
                end
         
     | 
| 
      
 10 
     | 
    
         
            +
              end
         
     | 
| 
      
 11 
     | 
    
         
            +
            end
         
     | 
| 
         @@ -0,0 +1,37 @@ 
     | 
|
| 
      
 1 
     | 
    
         
            +
            require 'spec_helper'
         
     | 
| 
      
 2 
     | 
    
         
            +
             
     | 
| 
      
 3 
     | 
    
         
            +
            describe Concealer::Proxy do
         
     | 
| 
      
 4 
     | 
    
         
            +
             
     | 
| 
      
 5 
     | 
    
         
            +
              let(:model) { ConcealedModel.new }
         
     | 
| 
      
 6 
     | 
    
         
            +
              let(:strategy) { Concealer::Strategy::Allow.new }
         
     | 
| 
      
 7 
     | 
    
         
            +
              subject { Concealer::Proxy.new(model, strategy) }
         
     | 
| 
      
 8 
     | 
    
         
            +
             
     | 
| 
      
 9 
     | 
    
         
            +
              describe "#initializer" do
         
     | 
| 
      
 10 
     | 
    
         
            +
                it "should require a target and a strategy" do
         
     | 
| 
      
 11 
     | 
    
         
            +
                  expect { Concealer::Proxy.new }.to raise_error ArgumentError
         
     | 
| 
      
 12 
     | 
    
         
            +
                end
         
     | 
| 
      
 13 
     | 
    
         
            +
             
     | 
| 
      
 14 
     | 
    
         
            +
                it "should accept a target object and a strategy" do
         
     | 
| 
      
 15 
     | 
    
         
            +
                  expect { Concealer::Proxy.new(model, Concealer.strategy) }.to_not raise_error ArgumentError
         
     | 
| 
      
 16 
     | 
    
         
            +
                end
         
     | 
| 
      
 17 
     | 
    
         
            +
              end
         
     | 
| 
      
 18 
     | 
    
         
            +
             
     | 
| 
      
 19 
     | 
    
         
            +
              it "should delegate all unknown method calls to the target" do
         
     | 
| 
      
 20 
     | 
    
         
            +
                model.should_receive(:allowed_method)
         
     | 
| 
      
 21 
     | 
    
         
            +
                subject.allowed_method
         
     | 
| 
      
 22 
     | 
    
         
            +
              end
         
     | 
| 
      
 23 
     | 
    
         
            +
             
     | 
| 
      
 24 
     | 
    
         
            +
              it "should ask the strategy whether the method is allowed for the object" do
         
     | 
| 
      
 25 
     | 
    
         
            +
                strategy.should_receive(:allow?).with(model, :allowed_method, [:args])
         
     | 
| 
      
 26 
     | 
    
         
            +
                subject.allowed_method(:args)
         
     | 
| 
      
 27 
     | 
    
         
            +
              end
         
     | 
| 
      
 28 
     | 
    
         
            +
             
     | 
| 
      
 29 
     | 
    
         
            +
              it "should return the fallback for unallowed methods" do
         
     | 
| 
      
 30 
     | 
    
         
            +
                strategy.stub!(:allow?).and_return(false)
         
     | 
| 
      
 31 
     | 
    
         
            +
             
     | 
| 
      
 32 
     | 
    
         
            +
                fallback = mock(Concealer::Fallback, :call => :fallback)
         
     | 
| 
      
 33 
     | 
    
         
            +
                Concealer.stub!(:fallback_for).and_return(fallback)
         
     | 
| 
      
 34 
     | 
    
         
            +
             
     | 
| 
      
 35 
     | 
    
         
            +
                subject.allowed_method.should eq(:fallback)
         
     | 
| 
      
 36 
     | 
    
         
            +
              end
         
     | 
| 
      
 37 
     | 
    
         
            +
            end
         
     | 
| 
         @@ -0,0 +1,15 @@ 
     | 
|
| 
      
 1 
     | 
    
         
            +
            require 'spec_helper'
         
     | 
| 
      
 2 
     | 
    
         
            +
             
     | 
| 
      
 3 
     | 
    
         
            +
            describe Concealer::Strategy::Blacklist do
         
     | 
| 
      
 4 
     | 
    
         
            +
             
     | 
| 
      
 5 
     | 
    
         
            +
              subject { Concealer::Strategy::Blacklist.new({ ConcealedModel => [:denied_method] }) }
         
     | 
| 
      
 6 
     | 
    
         
            +
             
     | 
| 
      
 7 
     | 
    
         
            +
              it "should allow unlisted methods" do
         
     | 
| 
      
 8 
     | 
    
         
            +
                subject.allow?(ConcealedModel.new, :some_method, nil).should be_true
         
     | 
| 
      
 9 
     | 
    
         
            +
              end
         
     | 
| 
      
 10 
     | 
    
         
            +
             
     | 
| 
      
 11 
     | 
    
         
            +
              it "should allow unlisted methods" do
         
     | 
| 
      
 12 
     | 
    
         
            +
                subject.allow?(ConcealedModel.new, :denied_method, nil).should be_false
         
     | 
| 
      
 13 
     | 
    
         
            +
              end
         
     | 
| 
      
 14 
     | 
    
         
            +
             
     | 
| 
      
 15 
     | 
    
         
            +
            end
         
     | 
| 
         @@ -0,0 +1,41 @@ 
     | 
|
| 
      
 1 
     | 
    
         
            +
            require 'spec_helper'
         
     | 
| 
      
 2 
     | 
    
         
            +
             
     | 
| 
      
 3 
     | 
    
         
            +
            describe Concealer::Strategy::MultiLevel do
         
     | 
| 
      
 4 
     | 
    
         
            +
             
     | 
| 
      
 5 
     | 
    
         
            +
              let(:levels) { [:myself, :friends, :friends_of_friends, :everyone] }
         
     | 
| 
      
 6 
     | 
    
         
            +
             
     | 
| 
      
 7 
     | 
    
         
            +
              let(:current_user) { User.new("benedikt") }
         
     | 
| 
      
 8 
     | 
    
         
            +
              let(:other_user) { User.new("christian") }
         
     | 
| 
      
 9 
     | 
    
         
            +
             
     | 
| 
      
 10 
     | 
    
         
            +
              subject { Concealer::Strategy::MultiLevel.new(current_user, levels) }
         
     | 
| 
      
 11 
     | 
    
         
            +
             
     | 
| 
      
 12 
     | 
    
         
            +
              context 'required level higher than actual level' do
         
     | 
| 
      
 13 
     | 
    
         
            +
                before(:each) do
         
     | 
| 
      
 14 
     | 
    
         
            +
                  subject.stub!(:required_level_for).and_return(:myself)
         
     | 
| 
      
 15 
     | 
    
         
            +
                end
         
     | 
| 
      
 16 
     | 
    
         
            +
             
     | 
| 
      
 17 
     | 
    
         
            +
                it "should deny the call" do
         
     | 
| 
      
 18 
     | 
    
         
            +
                  subject.allow?(other_user, :name, nil).should be_false
         
     | 
| 
      
 19 
     | 
    
         
            +
                end
         
     | 
| 
      
 20 
     | 
    
         
            +
              end
         
     | 
| 
      
 21 
     | 
    
         
            +
             
     | 
| 
      
 22 
     | 
    
         
            +
              context 'required level lower than actual level' do
         
     | 
| 
      
 23 
     | 
    
         
            +
                before(:each) do
         
     | 
| 
      
 24 
     | 
    
         
            +
                  subject.stub!(:required_level_for).and_return(:friends_of_friends)
         
     | 
| 
      
 25 
     | 
    
         
            +
                end
         
     | 
| 
      
 26 
     | 
    
         
            +
             
     | 
| 
      
 27 
     | 
    
         
            +
                it "should allow the call" do
         
     | 
| 
      
 28 
     | 
    
         
            +
                  subject.allow?(other_user, :name, nil).should be_true
         
     | 
| 
      
 29 
     | 
    
         
            +
                end
         
     | 
| 
      
 30 
     | 
    
         
            +
              end
         
     | 
| 
      
 31 
     | 
    
         
            +
             
     | 
| 
      
 32 
     | 
    
         
            +
              context 'required level equals actual level' do
         
     | 
| 
      
 33 
     | 
    
         
            +
                before(:each) do
         
     | 
| 
      
 34 
     | 
    
         
            +
                  subject.stub!(:required_level_for).and_return(:friends)
         
     | 
| 
      
 35 
     | 
    
         
            +
                end
         
     | 
| 
      
 36 
     | 
    
         
            +
             
     | 
| 
      
 37 
     | 
    
         
            +
                it "should allow the call" do
         
     | 
| 
      
 38 
     | 
    
         
            +
                  subject.allow?(other_user, :name, nil).should be_true
         
     | 
| 
      
 39 
     | 
    
         
            +
                end
         
     | 
| 
      
 40 
     | 
    
         
            +
              end
         
     | 
| 
      
 41 
     | 
    
         
            +
            end
         
     | 
| 
         @@ -0,0 +1,15 @@ 
     | 
|
| 
      
 1 
     | 
    
         
            +
            require 'spec_helper'
         
     | 
| 
      
 2 
     | 
    
         
            +
             
     | 
| 
      
 3 
     | 
    
         
            +
            describe Concealer::Strategy::Whitelist do
         
     | 
| 
      
 4 
     | 
    
         
            +
             
     | 
| 
      
 5 
     | 
    
         
            +
              subject { Concealer::Strategy::Whitelist.new({ ConcealedModel => [:allowed_method] }) }
         
     | 
| 
      
 6 
     | 
    
         
            +
             
     | 
| 
      
 7 
     | 
    
         
            +
              it "should deny unlisted methods" do
         
     | 
| 
      
 8 
     | 
    
         
            +
                subject.allow?(ConcealedModel.new, :some_method, nil).should be_false
         
     | 
| 
      
 9 
     | 
    
         
            +
              end
         
     | 
| 
      
 10 
     | 
    
         
            +
             
     | 
| 
      
 11 
     | 
    
         
            +
              it "should deny unlisted methods" do
         
     | 
| 
      
 12 
     | 
    
         
            +
                subject.allow?(ConcealedModel.new, :allowed_method, nil).should be_true
         
     | 
| 
      
 13 
     | 
    
         
            +
              end
         
     | 
| 
      
 14 
     | 
    
         
            +
             
     | 
| 
      
 15 
     | 
    
         
            +
            end
         
     | 
| 
         @@ -0,0 +1,62 @@ 
     | 
|
| 
      
 1 
     | 
    
         
            +
            require 'spec_helper'
         
     | 
| 
      
 2 
     | 
    
         
            +
             
     | 
| 
      
 3 
     | 
    
         
            +
            describe Concealer do
         
     | 
| 
      
 4 
     | 
    
         
            +
             
     | 
| 
      
 5 
     | 
    
         
            +
              subject { ConcealedModel.new }
         
     | 
| 
      
 6 
     | 
    
         
            +
             
     | 
| 
      
 7 
     | 
    
         
            +
              describe '.strategy' do
         
     | 
| 
      
 8 
     | 
    
         
            +
             
     | 
| 
      
 9 
     | 
    
         
            +
                it "should be Concealer::Strategy::Allow by default" do
         
     | 
| 
      
 10 
     | 
    
         
            +
                  Concealer.strategy.should be_kind_of(Concealer::Strategy::Allow)
         
     | 
| 
      
 11 
     | 
    
         
            +
                end
         
     | 
| 
      
 12 
     | 
    
         
            +
             
     | 
| 
      
 13 
     | 
    
         
            +
              end
         
     | 
| 
      
 14 
     | 
    
         
            +
             
     | 
| 
      
 15 
     | 
    
         
            +
             
     | 
| 
      
 16 
     | 
    
         
            +
              describe '.with_strategy' do
         
     | 
| 
      
 17 
     | 
    
         
            +
             
     | 
| 
      
 18 
     | 
    
         
            +
                it "should change the strategy within the block" do
         
     | 
| 
      
 19 
     | 
    
         
            +
                  strategy = Concealer::Strategy::Deny.new
         
     | 
| 
      
 20 
     | 
    
         
            +
                  Concealer.with_strategy(strategy) do
         
     | 
| 
      
 21 
     | 
    
         
            +
                    Concealer.strategy.should be(strategy)
         
     | 
| 
      
 22 
     | 
    
         
            +
                  end
         
     | 
| 
      
 23 
     | 
    
         
            +
                end
         
     | 
| 
      
 24 
     | 
    
         
            +
             
     | 
| 
      
 25 
     | 
    
         
            +
                it "should reset the strategy after the block was executed" do
         
     | 
| 
      
 26 
     | 
    
         
            +
                  strategy = Concealer.strategy
         
     | 
| 
      
 27 
     | 
    
         
            +
                  Concealer.with_strategy(Concealer::Strategy::Deny.new) {}
         
     | 
| 
      
 28 
     | 
    
         
            +
                  Concealer.strategy.should be(strategy)
         
     | 
| 
      
 29 
     | 
    
         
            +
                end
         
     | 
| 
      
 30 
     | 
    
         
            +
             
     | 
| 
      
 31 
     | 
    
         
            +
              end
         
     | 
| 
      
 32 
     | 
    
         
            +
             
     | 
| 
      
 33 
     | 
    
         
            +
              describe '.default_fallback' do
         
     | 
| 
      
 34 
     | 
    
         
            +
             
     | 
| 
      
 35 
     | 
    
         
            +
                it "should default to Concealer::Fallback::Nil" do
         
     | 
| 
      
 36 
     | 
    
         
            +
                  Concealer.default_fallback.should be_kind_of(Concealer::Fallback::Nil)
         
     | 
| 
      
 37 
     | 
    
         
            +
                end
         
     | 
| 
      
 38 
     | 
    
         
            +
             
     | 
| 
      
 39 
     | 
    
         
            +
              end
         
     | 
| 
      
 40 
     | 
    
         
            +
             
     | 
| 
      
 41 
     | 
    
         
            +
              describe '.fallback_for' do
         
     | 
| 
      
 42 
     | 
    
         
            +
             
     | 
| 
      
 43 
     | 
    
         
            +
                it "should return the default_fallback if no specific fallback is found" do
         
     | 
| 
      
 44 
     | 
    
         
            +
                  Concealer.fallback_for(ConcealedModel.new, :unknown_method).should be_kind_of(Concealer::Fallback::Nil)
         
     | 
| 
      
 45 
     | 
    
         
            +
                end
         
     | 
| 
      
 46 
     | 
    
         
            +
             
     | 
| 
      
 47 
     | 
    
         
            +
              end
         
     | 
| 
      
 48 
     | 
    
         
            +
             
     | 
| 
      
 49 
     | 
    
         
            +
             
     | 
| 
      
 50 
     | 
    
         
            +
              describe '#concealed' do
         
     | 
| 
      
 51 
     | 
    
         
            +
             
     | 
| 
      
 52 
     | 
    
         
            +
                it "should be defined on the model" do
         
     | 
| 
      
 53 
     | 
    
         
            +
                  should respond_to(:concealed)
         
     | 
| 
      
 54 
     | 
    
         
            +
                end
         
     | 
| 
      
 55 
     | 
    
         
            +
             
     | 
| 
      
 56 
     | 
    
         
            +
                it "should return a proxy object" do
         
     | 
| 
      
 57 
     | 
    
         
            +
                  subject.concealed.should be
         
     | 
| 
      
 58 
     | 
    
         
            +
                end
         
     | 
| 
      
 59 
     | 
    
         
            +
             
     | 
| 
      
 60 
     | 
    
         
            +
              end
         
     | 
| 
      
 61 
     | 
    
         
            +
             
     | 
| 
      
 62 
     | 
    
         
            +
            end
         
     | 
    
        data/spec/spec_helper.rb
    ADDED
    
    
    
        metadata
    ADDED
    
    | 
         @@ -0,0 +1,163 @@ 
     | 
|
| 
      
 1 
     | 
    
         
            +
            --- !ruby/object:Gem::Specification 
         
     | 
| 
      
 2 
     | 
    
         
            +
            name: concealer
         
     | 
| 
      
 3 
     | 
    
         
            +
            version: !ruby/object:Gem::Version 
         
     | 
| 
      
 4 
     | 
    
         
            +
              hash: 29
         
     | 
| 
      
 5 
     | 
    
         
            +
              prerelease: false
         
     | 
| 
      
 6 
     | 
    
         
            +
              segments: 
         
     | 
| 
      
 7 
     | 
    
         
            +
              - 0
         
     | 
| 
      
 8 
     | 
    
         
            +
              - 0
         
     | 
| 
      
 9 
     | 
    
         
            +
              - 1
         
     | 
| 
      
 10 
     | 
    
         
            +
              version: 0.0.1
         
     | 
| 
      
 11 
     | 
    
         
            +
            platform: ruby
         
     | 
| 
      
 12 
     | 
    
         
            +
            authors: 
         
     | 
| 
      
 13 
     | 
    
         
            +
            - Benedikt Deicke
         
     | 
| 
      
 14 
     | 
    
         
            +
            - "Christian B\xC3\xA4uerlein"
         
     | 
| 
      
 15 
     | 
    
         
            +
            autorequire: 
         
     | 
| 
      
 16 
     | 
    
         
            +
            bindir: bin
         
     | 
| 
      
 17 
     | 
    
         
            +
            cert_chain: []
         
     | 
| 
      
 18 
     | 
    
         
            +
             
     | 
| 
      
 19 
     | 
    
         
            +
            date: 2011-02-28 00:00:00 +01:00
         
     | 
| 
      
 20 
     | 
    
         
            +
            default_executable: 
         
     | 
| 
      
 21 
     | 
    
         
            +
            dependencies: 
         
     | 
| 
      
 22 
     | 
    
         
            +
            - !ruby/object:Gem::Dependency 
         
     | 
| 
      
 23 
     | 
    
         
            +
              prerelease: false
         
     | 
| 
      
 24 
     | 
    
         
            +
              version_requirements: &id001 !ruby/object:Gem::Requirement 
         
     | 
| 
      
 25 
     | 
    
         
            +
                none: false
         
     | 
| 
      
 26 
     | 
    
         
            +
                requirements: 
         
     | 
| 
      
 27 
     | 
    
         
            +
                - - ~>
         
     | 
| 
      
 28 
     | 
    
         
            +
                  - !ruby/object:Gem::Version 
         
     | 
| 
      
 29 
     | 
    
         
            +
                    hash: 7
         
     | 
| 
      
 30 
     | 
    
         
            +
                    segments: 
         
     | 
| 
      
 31 
     | 
    
         
            +
                    - 3
         
     | 
| 
      
 32 
     | 
    
         
            +
                    - 0
         
     | 
| 
      
 33 
     | 
    
         
            +
                    version: "3.0"
         
     | 
| 
      
 34 
     | 
    
         
            +
              requirement: *id001
         
     | 
| 
      
 35 
     | 
    
         
            +
              name: activesupport
         
     | 
| 
      
 36 
     | 
    
         
            +
              type: :runtime
         
     | 
| 
      
 37 
     | 
    
         
            +
            - !ruby/object:Gem::Dependency 
         
     | 
| 
      
 38 
     | 
    
         
            +
              prerelease: false
         
     | 
| 
      
 39 
     | 
    
         
            +
              version_requirements: &id002 !ruby/object:Gem::Requirement 
         
     | 
| 
      
 40 
     | 
    
         
            +
                none: false
         
     | 
| 
      
 41 
     | 
    
         
            +
                requirements: 
         
     | 
| 
      
 42 
     | 
    
         
            +
                - - ~>
         
     | 
| 
      
 43 
     | 
    
         
            +
                  - !ruby/object:Gem::Version 
         
     | 
| 
      
 44 
     | 
    
         
            +
                    hash: 5
         
     | 
| 
      
 45 
     | 
    
         
            +
                    segments: 
         
     | 
| 
      
 46 
     | 
    
         
            +
                    - 2
         
     | 
| 
      
 47 
     | 
    
         
            +
                    - 3
         
     | 
| 
      
 48 
     | 
    
         
            +
                    version: "2.3"
         
     | 
| 
      
 49 
     | 
    
         
            +
              requirement: *id002
         
     | 
| 
      
 50 
     | 
    
         
            +
              name: rspec
         
     | 
| 
      
 51 
     | 
    
         
            +
              type: :development
         
     | 
| 
      
 52 
     | 
    
         
            +
            - !ruby/object:Gem::Dependency 
         
     | 
| 
      
 53 
     | 
    
         
            +
              prerelease: false
         
     | 
| 
      
 54 
     | 
    
         
            +
              version_requirements: &id003 !ruby/object:Gem::Requirement 
         
     | 
| 
      
 55 
     | 
    
         
            +
                none: false
         
     | 
| 
      
 56 
     | 
    
         
            +
                requirements: 
         
     | 
| 
      
 57 
     | 
    
         
            +
                - - ">="
         
     | 
| 
      
 58 
     | 
    
         
            +
                  - !ruby/object:Gem::Version 
         
     | 
| 
      
 59 
     | 
    
         
            +
                    hash: 3
         
     | 
| 
      
 60 
     | 
    
         
            +
                    segments: 
         
     | 
| 
      
 61 
     | 
    
         
            +
                    - 0
         
     | 
| 
      
 62 
     | 
    
         
            +
                    version: "0"
         
     | 
| 
      
 63 
     | 
    
         
            +
              requirement: *id003
         
     | 
| 
      
 64 
     | 
    
         
            +
              name: rake
         
     | 
| 
      
 65 
     | 
    
         
            +
              type: :development
         
     | 
| 
      
 66 
     | 
    
         
            +
            description: Privacy control your models with ease
         
     | 
| 
      
 67 
     | 
    
         
            +
            email: 
         
     | 
| 
      
 68 
     | 
    
         
            +
            - benedikt@synatic.net
         
     | 
| 
      
 69 
     | 
    
         
            +
            - fabrik42@gmail.com
         
     | 
| 
      
 70 
     | 
    
         
            +
            executables: []
         
     | 
| 
      
 71 
     | 
    
         
            +
             
     | 
| 
      
 72 
     | 
    
         
            +
            extensions: []
         
     | 
| 
      
 73 
     | 
    
         
            +
             
     | 
| 
      
 74 
     | 
    
         
            +
            extra_rdoc_files: []
         
     | 
| 
      
 75 
     | 
    
         
            +
             
     | 
| 
      
 76 
     | 
    
         
            +
            files: 
         
     | 
| 
      
 77 
     | 
    
         
            +
            - .gitignore
         
     | 
| 
      
 78 
     | 
    
         
            +
            - .rspec
         
     | 
| 
      
 79 
     | 
    
         
            +
            - Gemfile
         
     | 
| 
      
 80 
     | 
    
         
            +
            - LICENSE
         
     | 
| 
      
 81 
     | 
    
         
            +
            - README.rdoc
         
     | 
| 
      
 82 
     | 
    
         
            +
            - Rakefile
         
     | 
| 
      
 83 
     | 
    
         
            +
            - concealer.gemspec
         
     | 
| 
      
 84 
     | 
    
         
            +
            - lib/concealer.rb
         
     | 
| 
      
 85 
     | 
    
         
            +
            - lib/concealer/fallback.rb
         
     | 
| 
      
 86 
     | 
    
         
            +
            - lib/concealer/fallback/nil.rb
         
     | 
| 
      
 87 
     | 
    
         
            +
            - lib/concealer/fallback/paperclip.rb
         
     | 
| 
      
 88 
     | 
    
         
            +
            - lib/concealer/fallback/string.rb
         
     | 
| 
      
 89 
     | 
    
         
            +
            - lib/concealer/proxy.rb
         
     | 
| 
      
 90 
     | 
    
         
            +
            - lib/concealer/strategy.rb
         
     | 
| 
      
 91 
     | 
    
         
            +
            - lib/concealer/strategy/allow.rb
         
     | 
| 
      
 92 
     | 
    
         
            +
            - lib/concealer/strategy/blacklist.rb
         
     | 
| 
      
 93 
     | 
    
         
            +
            - lib/concealer/strategy/deny.rb
         
     | 
| 
      
 94 
     | 
    
         
            +
            - lib/concealer/strategy/multi_level.rb
         
     | 
| 
      
 95 
     | 
    
         
            +
            - lib/concealer/strategy/whitelist.rb
         
     | 
| 
      
 96 
     | 
    
         
            +
            - lib/concealer/version.rb
         
     | 
| 
      
 97 
     | 
    
         
            +
            - spec/concealer/fallback/nil_spec.rb
         
     | 
| 
      
 98 
     | 
    
         
            +
            - spec/concealer/fallback/paperclip_spec.rb
         
     | 
| 
      
 99 
     | 
    
         
            +
            - spec/concealer/fallback/string_spec.rb
         
     | 
| 
      
 100 
     | 
    
         
            +
            - spec/concealer/fallback_spec.rb
         
     | 
| 
      
 101 
     | 
    
         
            +
            - spec/concealer/proxy_spec.rb
         
     | 
| 
      
 102 
     | 
    
         
            +
            - spec/concealer/strategy/allow_spec.rb
         
     | 
| 
      
 103 
     | 
    
         
            +
            - spec/concealer/strategy/blacklist_spec.rb
         
     | 
| 
      
 104 
     | 
    
         
            +
            - spec/concealer/strategy/deny_spec.rb
         
     | 
| 
      
 105 
     | 
    
         
            +
            - spec/concealer/strategy/multi_level_spec.rb
         
     | 
| 
      
 106 
     | 
    
         
            +
            - spec/concealer/strategy/whitelist_spec.rb
         
     | 
| 
      
 107 
     | 
    
         
            +
            - spec/concealer/strategy_spec.rb
         
     | 
| 
      
 108 
     | 
    
         
            +
            - spec/concealer_spec.rb
         
     | 
| 
      
 109 
     | 
    
         
            +
            - spec/spec_helper.rb
         
     | 
| 
      
 110 
     | 
    
         
            +
            - spec/support/concealed_model.rb
         
     | 
| 
      
 111 
     | 
    
         
            +
            - spec/support/paperclip.rb
         
     | 
| 
      
 112 
     | 
    
         
            +
            - spec/support/user.rb
         
     | 
| 
      
 113 
     | 
    
         
            +
            has_rdoc: true
         
     | 
| 
      
 114 
     | 
    
         
            +
            homepage: https://flinc.github.com/concealer
         
     | 
| 
      
 115 
     | 
    
         
            +
            licenses: []
         
     | 
| 
      
 116 
     | 
    
         
            +
             
     | 
| 
      
 117 
     | 
    
         
            +
            post_install_message: 
         
     | 
| 
      
 118 
     | 
    
         
            +
            rdoc_options: []
         
     | 
| 
      
 119 
     | 
    
         
            +
             
     | 
| 
      
 120 
     | 
    
         
            +
            require_paths: 
         
     | 
| 
      
 121 
     | 
    
         
            +
            - lib
         
     | 
| 
      
 122 
     | 
    
         
            +
            required_ruby_version: !ruby/object:Gem::Requirement 
         
     | 
| 
      
 123 
     | 
    
         
            +
              none: false
         
     | 
| 
      
 124 
     | 
    
         
            +
              requirements: 
         
     | 
| 
      
 125 
     | 
    
         
            +
              - - ">="
         
     | 
| 
      
 126 
     | 
    
         
            +
                - !ruby/object:Gem::Version 
         
     | 
| 
      
 127 
     | 
    
         
            +
                  hash: 3
         
     | 
| 
      
 128 
     | 
    
         
            +
                  segments: 
         
     | 
| 
      
 129 
     | 
    
         
            +
                  - 0
         
     | 
| 
      
 130 
     | 
    
         
            +
                  version: "0"
         
     | 
| 
      
 131 
     | 
    
         
            +
            required_rubygems_version: !ruby/object:Gem::Requirement 
         
     | 
| 
      
 132 
     | 
    
         
            +
              none: false
         
     | 
| 
      
 133 
     | 
    
         
            +
              requirements: 
         
     | 
| 
      
 134 
     | 
    
         
            +
              - - ">="
         
     | 
| 
      
 135 
     | 
    
         
            +
                - !ruby/object:Gem::Version 
         
     | 
| 
      
 136 
     | 
    
         
            +
                  hash: 3
         
     | 
| 
      
 137 
     | 
    
         
            +
                  segments: 
         
     | 
| 
      
 138 
     | 
    
         
            +
                  - 0
         
     | 
| 
      
 139 
     | 
    
         
            +
                  version: "0"
         
     | 
| 
      
 140 
     | 
    
         
            +
            requirements: []
         
     | 
| 
      
 141 
     | 
    
         
            +
             
     | 
| 
      
 142 
     | 
    
         
            +
            rubyforge_project: 
         
     | 
| 
      
 143 
     | 
    
         
            +
            rubygems_version: 1.3.7
         
     | 
| 
      
 144 
     | 
    
         
            +
            signing_key: 
         
     | 
| 
      
 145 
     | 
    
         
            +
            specification_version: 3
         
     | 
| 
      
 146 
     | 
    
         
            +
            summary: Privacy control your models with ease
         
     | 
| 
      
 147 
     | 
    
         
            +
            test_files: 
         
     | 
| 
      
 148 
     | 
    
         
            +
            - spec/concealer/fallback/nil_spec.rb
         
     | 
| 
      
 149 
     | 
    
         
            +
            - spec/concealer/fallback/paperclip_spec.rb
         
     | 
| 
      
 150 
     | 
    
         
            +
            - spec/concealer/fallback/string_spec.rb
         
     | 
| 
      
 151 
     | 
    
         
            +
            - spec/concealer/fallback_spec.rb
         
     | 
| 
      
 152 
     | 
    
         
            +
            - spec/concealer/proxy_spec.rb
         
     | 
| 
      
 153 
     | 
    
         
            +
            - spec/concealer/strategy/allow_spec.rb
         
     | 
| 
      
 154 
     | 
    
         
            +
            - spec/concealer/strategy/blacklist_spec.rb
         
     | 
| 
      
 155 
     | 
    
         
            +
            - spec/concealer/strategy/deny_spec.rb
         
     | 
| 
      
 156 
     | 
    
         
            +
            - spec/concealer/strategy/multi_level_spec.rb
         
     | 
| 
      
 157 
     | 
    
         
            +
            - spec/concealer/strategy/whitelist_spec.rb
         
     | 
| 
      
 158 
     | 
    
         
            +
            - spec/concealer/strategy_spec.rb
         
     | 
| 
      
 159 
     | 
    
         
            +
            - spec/concealer_spec.rb
         
     | 
| 
      
 160 
     | 
    
         
            +
            - spec/spec_helper.rb
         
     | 
| 
      
 161 
     | 
    
         
            +
            - spec/support/concealed_model.rb
         
     | 
| 
      
 162 
     | 
    
         
            +
            - spec/support/paperclip.rb
         
     | 
| 
      
 163 
     | 
    
         
            +
            - spec/support/user.rb
         
     |