challah 0.3.5 → 0.4.0
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/CHANGELOG.md +7 -0
- data/README.md +3 -2
- data/lib/challah/authable/user.rb +1 -1
- data/lib/challah/controller.rb +1 -1
- data/lib/challah/session.rb +23 -8
- data/lib/challah/techniques/api_key_technique.rb +5 -1
- data/lib/challah/version.rb +1 -1
- data/lib/challah.rb +1 -0
- data/test/cookie_store_test.rb +5 -0
- data/test/helper.rb +2 -1
- data/test/restrictions_controller_test.rb +62 -0
- data/test/session_test.rb +7 -1
- metadata +10 -10
    
        data/CHANGELOG.md
    CHANGED
    
    | @@ -1,3 +1,10 @@ | |
| 1 | 
            +
            ## Challah 0.4.0 (Unreleased)
         | 
| 2 | 
            +
             | 
| 3 | 
            +
            * Enabled api key access. Passing ?key=xxxx into any URL will authenticate a user for a single page load. This option is turned off by default in new apps and can be enabled using `Challah.options[:api_key_enabled]`.
         | 
| 4 | 
            +
            * Updated tests for API key access
         | 
| 5 | 
            +
            * Authenticate users on page load
         | 
| 6 | 
            +
            * Changed default api key length to 50 instead of 25
         | 
| 7 | 
            +
             | 
| 1 8 | 
             
            ## Challah 0.3.5
         | 
| 2 9 |  | 
| 3 10 | 
             
            * Now using [Highline](https://github.com/JEG2/highline) for rake tasks instead of sloppy custom methods.
         | 
    
        data/README.md
    CHANGED
    
    | @@ -77,9 +77,10 @@ Roles should only be used within your app to consolidate various permissions int | |
| 77 77 |  | 
| 78 78 | 
             
            The default Challah installation creates two roles by default: 'Administrator' and 'Default'. Administrators have all permissions, now and in the future. Default users have no permissions other than being able to log in.
         | 
| 79 79 |  | 
| 80 | 
            -
             | 
| 80 | 
            +
            Once you've added a few other permissions, you can easily add them to a role. In this case, the `moderator` permission key is added to the default role:
         | 
| 81 81 |  | 
| 82 | 
            -
                role | 
| 82 | 
            +
                role = Role[:default]
         | 
| 83 | 
            +
                role.permission_keys = %w( moderator )
         | 
| 83 84 | 
             
                role.save
         | 
| 84 85 |  | 
| 85 86 | 
             
            ## Restricted access
         | 
| @@ -211,7 +211,7 @@ module Challah | |
| 211 211 | 
             
                      end
         | 
| 212 212 |  | 
| 213 213 | 
             
                      self.persistence_token = ::Challah::Random.token(125) if self.persistence_token.to_s.blank?
         | 
| 214 | 
            -
                      self.api_key = ::Challah::Random.token( | 
| 214 | 
            +
                      self.api_key = ::Challah::Random.token(50) if self.api_key.to_s.blank?
         | 
| 215 215 | 
             
                    end
         | 
| 216 216 |  | 
| 217 217 | 
             
                    # Saves any updated permission keys to the database for this user.  
         | 
    
        data/lib/challah/controller.rb
    CHANGED
    
    | @@ -124,7 +124,7 @@ module Challah | |
| 124 124 | 
             
                    #
         | 
| 125 125 | 
             
                    # @return [Session] The current browser session.
         | 
| 126 126 | 
             
                    def current_user_session
         | 
| 127 | 
            -
                      @current_user_session ||= Challah::Session.find(request)
         | 
| 127 | 
            +
                      @current_user_session ||= Challah::Session.find(request, params)
         | 
| 128 128 | 
             
                    end
         | 
| 129 129 |  | 
| 130 130 | 
             
                    # Checks the current user to see if they have the given permission key. If there is
         | 
    
        data/lib/challah/session.rb
    CHANGED
    
    | @@ -3,8 +3,8 @@ module Challah | |
| 3 3 | 
             
                extend ActiveModel::Naming
         | 
| 4 4 | 
             
                include ActiveModel::Conversion
         | 
| 5 5 |  | 
| 6 | 
            -
                attr_accessor :return_to, :ip, :user, :store
         | 
| 7 | 
            -
                attr_reader :params, :request | 
| 6 | 
            +
                attr_accessor :return_to, :ip, :user, :store, :persist
         | 
| 7 | 
            +
                attr_reader :params, :request
         | 
| 8 8 |  | 
| 9 9 | 
             
                def initialize(request = nil, params = {})
         | 
| 10 10 | 
             
                  @request = request
         | 
| @@ -24,6 +24,17 @@ module Challah | |
| 24 24 | 
             
                  @user = nil
         | 
| 25 25 | 
             
                end
         | 
| 26 26 |  | 
| 27 | 
            +
                def find
         | 
| 28 | 
            +
                  self.read
         | 
| 29 | 
            +
                  
         | 
| 30 | 
            +
                  # If no session was found, try and authenticate
         | 
| 31 | 
            +
                  unless valid?
         | 
| 32 | 
            +
                    self.authenticate!
         | 
| 33 | 
            +
                  end
         | 
| 34 | 
            +
                    
         | 
| 35 | 
            +
                  self
         | 
| 36 | 
            +
                end
         | 
| 37 | 
            +
                
         | 
| 27 38 | 
             
                def inspect
         | 
| 28 39 | 
             
                  "#<Session:0x#{object_id.to_s(16)} valid=#{valid?} store=#{self.store.inspect} user=#{user_id || 'nil'}>"
         | 
| 29 40 | 
             
                end
         | 
| @@ -49,11 +60,14 @@ module Challah | |
| 49 60 | 
             
                end
         | 
| 50 61 |  | 
| 51 62 | 
             
                def save
         | 
| 52 | 
            -
                  return false unless  | 
| 63 | 
            +
                  return false unless valid?
         | 
| 53 64 |  | 
| 54 | 
            -
                  if self.user
         | 
| 65 | 
            +
                  if self.user and persist?
         | 
| 55 66 | 
             
                    self.store.save(self.user.persistence_token, user_id)
         | 
| 67 | 
            +
                    return true
         | 
| 56 68 | 
             
                  end
         | 
| 69 | 
            +
                  
         | 
| 70 | 
            +
                  false
         | 
| 57 71 | 
             
                end
         | 
| 58 72 |  | 
| 59 73 | 
             
                # Id of the current user.
         | 
| @@ -95,6 +109,7 @@ module Challah | |
| 95 109 |  | 
| 96 110 | 
             
                    if user_record and user_record.active?
         | 
| 97 111 | 
             
                      session.user = user_record
         | 
| 112 | 
            +
                      session.persist = true
         | 
| 98 113 | 
             
                    end
         | 
| 99 114 |  | 
| 100 115 | 
             
                    session
         | 
| @@ -117,7 +132,7 @@ module Challah | |
| 117 132 | 
             
                  # Load any existing session from the session store
         | 
| 118 133 | 
             
                  def find(*args)
         | 
| 119 134 | 
             
                    session = Session.new(*args)
         | 
| 120 | 
            -
                    session. | 
| 135 | 
            +
                    session.find        
         | 
| 121 136 | 
             
                    session
         | 
| 122 137 | 
             
                  end
         | 
| 123 138 | 
             
                end
         | 
| @@ -125,13 +140,13 @@ module Challah | |
| 125 140 | 
             
                protected
         | 
| 126 141 | 
             
                  # Try and authenticate against the various auth techniques. If one
         | 
| 127 142 | 
             
                  # technique works, then just exist and make the session active.
         | 
| 128 | 
            -
                  def authenticate!
         | 
| 129 | 
            -
                    Challah.techniques.values.each do |klass|
         | 
| 143 | 
            +
                  def authenticate!        
         | 
| 144 | 
            +
                    Challah.techniques.values.each do |klass|            
         | 
| 130 145 | 
             
                      technique = klass.new(self)
         | 
| 131 146 | 
             
                      @user = technique.authenticate
         | 
| 132 147 |  | 
| 133 148 | 
             
                      if @user
         | 
| 134 | 
            -
                        @persist = technique.persist?
         | 
| 149 | 
            +
                        @persist = technique.respond_to?(:persist?) ? technique.persist? : false
         | 
| 135 150 | 
             
                        break
         | 
| 136 151 | 
             
                      end
         | 
| 137 152 | 
             
                    end
         | 
| @@ -1,10 +1,14 @@ | |
| 1 1 | 
             
            module Challah
         | 
| 2 2 | 
             
              class ApiKeyTechnique
         | 
| 3 3 | 
             
                def initialize(session)
         | 
| 4 | 
            -
                  @key = session. | 
| 4 | 
            +
                  @key = session.key? ? session.key : nil   
         | 
| 5 5 | 
             
                end
         | 
| 6 6 |  | 
| 7 7 | 
             
                def authenticate
         | 
| 8 | 
            +
                  # Api key functionality is only enabled with the :api_key_enabled option. This is turned
         | 
| 9 | 
            +
                  # off by default and must be manually enabled for security reasons.
         | 
| 10 | 
            +
                  return nil unless Challah.options[:api_key_enabled]
         | 
| 11 | 
            +
                  
         | 
| 8 12 | 
             
                  unless @key.to_s.blank?
         | 
| 9 13 | 
             
                    user = ::User.find_by_api_key(@key)
         | 
| 10 14 |  | 
    
        data/lib/challah/version.rb
    CHANGED
    
    
    
        data/lib/challah.rb
    CHANGED
    
    | @@ -53,6 +53,7 @@ module Challah | |
| 53 53 | 
             
                # @option options [Class] :storage_class (CookieStore) The class to use for persistence of sessions.
         | 
| 54 54 | 
             
                def options
         | 
| 55 55 | 
             
                  @options ||= {
         | 
| 56 | 
            +
                    :api_key_enabled => false,
         | 
| 56 57 | 
             
                    :cookie_prefix => 'challah',
         | 
| 57 58 | 
             
                    :access_denied_view => 'sessions/access_denied',
         | 
| 58 59 | 
             
                    :storage_class => CookieStore,
         | 
    
        data/test/cookie_store_test.rb
    CHANGED
    
    | @@ -14,6 +14,7 @@ class CookieStoreTest < ActiveSupport::TestCase | |
| 14 14 |  | 
| 15 15 | 
             
                  session = Session.new(@request)
         | 
| 16 16 | 
             
                  session.store = CookieStore.new(session)
         | 
| 17 | 
            +
                  session.persist = true
         | 
| 17 18 | 
             
                  session.user = @user
         | 
| 18 19 | 
             
                  session.save
         | 
| 19 20 |  | 
| @@ -28,6 +29,7 @@ class CookieStoreTest < ActiveSupport::TestCase | |
| 28 29 | 
             
                should "be able to inspect the store" do
         | 
| 29 30 | 
             
                  session = Session.new(@request)
         | 
| 30 31 | 
             
                  session.store = CookieStore.new(session)
         | 
| 32 | 
            +
                  session.persist = true
         | 
| 31 33 | 
             
                  session.user = @user
         | 
| 32 34 | 
             
                  session.save
         | 
| 33 35 |  | 
| @@ -39,6 +41,7 @@ class CookieStoreTest < ActiveSupport::TestCase | |
| 39 41 |  | 
| 40 42 | 
             
                  session = Session.new(@request)
         | 
| 41 43 | 
             
                  session.store = CookieStore.new(session)
         | 
| 44 | 
            +
                  session.persist = true
         | 
| 42 45 | 
             
                  session.user = @user
         | 
| 43 46 | 
             
                  session.save
         | 
| 44 47 |  | 
| @@ -54,6 +57,7 @@ class CookieStoreTest < ActiveSupport::TestCase | |
| 54 57 | 
             
                  session.store.stubs(:session_cookie).returns(session_cookie_val)
         | 
| 55 58 |  | 
| 56 59 | 
             
                  session2 = Session.new(@request)
         | 
| 60 | 
            +
                  session2.persist = true
         | 
| 57 61 | 
             
                  session2.store = session.store      
         | 
| 58 62 | 
             
                  session2.read
         | 
| 59 63 |  | 
| @@ -75,6 +79,7 @@ class CookieStoreTest < ActiveSupport::TestCase | |
| 75 79 | 
             
                  session = Session.new(@request)
         | 
| 76 80 | 
             
                  session.store = CookieStore.new(session)
         | 
| 77 81 | 
             
                  session.user = @user
         | 
| 82 | 
            +
                  session.persist = true
         | 
| 78 83 |  | 
| 79 84 | 
             
                  session.save
         | 
| 80 85 |  | 
    
        data/test/helper.rb
    CHANGED
    
    | @@ -41,11 +41,12 @@ end | |
| 41 41 | 
             
            class MockController
         | 
| 42 42 | 
             
              include Challah::Controller
         | 
| 43 43 |  | 
| 44 | 
            -
              attr_accessor :request, :session
         | 
| 44 | 
            +
              attr_accessor :request, :session, :params
         | 
| 45 45 |  | 
| 46 46 | 
             
              def initialize()
         | 
| 47 47 | 
             
                @request = MockRequest.new
         | 
| 48 48 | 
             
                @session ||= {}
         | 
| 49 | 
            +
                @params ||= {}
         | 
| 49 50 | 
             
              end
         | 
| 50 51 |  | 
| 51 52 | 
             
              def redirect_to(*args)
         | 
| @@ -86,5 +86,67 @@ class RestrictionsControllerTest < ActionController::TestCase | |
| 86 86 | 
             
                    assert_response :success
         | 
| 87 87 | 
             
                  end
         | 
| 88 88 | 
             
                end
         | 
| 89 | 
            +
                
         | 
| 90 | 
            +
                context "With an api key" do
         | 
| 91 | 
            +
                  setup do
         | 
| 92 | 
            +
                    @user = Factory(:user)
         | 
| 93 | 
            +
                  end
         | 
| 94 | 
            +
                  
         | 
| 95 | 
            +
                  context "and api_key functionality enabled" do
         | 
| 96 | 
            +
                    setup do
         | 
| 97 | 
            +
                      Challah.options[:api_key_enabled] = true
         | 
| 98 | 
            +
                    end
         | 
| 99 | 
            +
                    
         | 
| 100 | 
            +
                    should "get to the index page" do
         | 
| 101 | 
            +
                      get :index, :key => @user.api_key
         | 
| 102 | 
            +
                      assert_response :success
         | 
| 103 | 
            +
                      assert_equal @user, assigns(:current_user)
         | 
| 104 | 
            +
                    end
         | 
| 105 | 
            +
             | 
| 106 | 
            +
                    should "get to the edit page" do
         | 
| 107 | 
            +
                      get :edit, :key => @user.api_key
         | 
| 108 | 
            +
                      assert_response :success
         | 
| 109 | 
            +
                    end
         | 
| 110 | 
            +
             | 
| 111 | 
            +
                    should "get to the show page" do
         | 
| 112 | 
            +
                      get :show, :key => @user.api_key
         | 
| 113 | 
            +
                      assert_response :success
         | 
| 114 | 
            +
                    end
         | 
| 115 | 
            +
             | 
| 116 | 
            +
                    should "not get to the new page" do
         | 
| 117 | 
            +
                      get :new, :key => @user.api_key
         | 
| 118 | 
            +
             | 
| 119 | 
            +
                      assert_template 'sessions/access_denied'
         | 
| 120 | 
            +
                      assert_response :unauthorized
         | 
| 121 | 
            +
                    end
         | 
| 122 | 
            +
                  end
         | 
| 123 | 
            +
                  
         | 
| 124 | 
            +
                  context "and api_key functionality disabled" do
         | 
| 125 | 
            +
                    setup do
         | 
| 126 | 
            +
                      Challah.options[:api_key_enabled] = false
         | 
| 127 | 
            +
                    end
         | 
| 128 | 
            +
                    
         | 
| 129 | 
            +
                    should "get to the index page" do
         | 
| 130 | 
            +
                      get :index, :key => @user.api_key
         | 
| 131 | 
            +
                      assert_response :success
         | 
| 132 | 
            +
                      assert_equal nil, assigns(:current_user)
         | 
| 133 | 
            +
                    end
         | 
| 134 | 
            +
             | 
| 135 | 
            +
                    should "get to the edit page" do
         | 
| 136 | 
            +
                      get :edit, :key => @user.api_key
         | 
| 137 | 
            +
                      assert_redirected_to '/login'
         | 
| 138 | 
            +
                    end
         | 
| 139 | 
            +
             | 
| 140 | 
            +
                    should "get to the show page" do
         | 
| 141 | 
            +
                      get :show, :key => @user.api_key
         | 
| 142 | 
            +
                      assert_redirected_to '/login'
         | 
| 143 | 
            +
                    end
         | 
| 144 | 
            +
             | 
| 145 | 
            +
                    should "not get to the new page" do
         | 
| 146 | 
            +
                      get :new, :key => @user.api_key
         | 
| 147 | 
            +
                      assert_redirected_to '/login'
         | 
| 148 | 
            +
                    end
         | 
| 149 | 
            +
                  end
         | 
| 150 | 
            +
                end
         | 
| 89 151 | 
             
              end
         | 
| 90 152 | 
             
            end
         | 
    
        data/test/session_test.rb
    CHANGED
    
    | @@ -113,27 +113,33 @@ class SessionTest < ActiveSupport::TestCase | |
| 113 113 | 
             
                  assert_equal user, session.user
         | 
| 114 114 | 
             
                  assert_equal user.id, session.user_id
         | 
| 115 115 | 
             
                  assert_equal true, session.persist?
         | 
| 116 | 
            +
                  assert_equal true, session.save
         | 
| 116 117 |  | 
| 117 118 | 
             
                  User.unstub(:find_for_session)
         | 
| 118 119 | 
             
                end
         | 
| 119 120 |  | 
| 120 121 | 
             
                should "validate with an api key" do
         | 
| 122 | 
            +
                  Challah.options[:api_key_enabled] = true
         | 
| 123 | 
            +
                  
         | 
| 121 124 | 
             
                  user = Factory(:user, :api_key => '123456abcdefg')
         | 
| 122 125 |  | 
| 123 126 | 
             
                  User.stubs(:find_for_session).returns(user)
         | 
| 124 127 |  | 
| 125 128 | 
             
                  session = Session.new
         | 
| 126 129 | 
             
                  session.ip = '127.0.0.1'
         | 
| 127 | 
            -
                  session. | 
| 130 | 
            +
                  session.key = '123456abcdefg'
         | 
| 128 131 |  | 
| 129 132 | 
             
                  assert_equal true, session.valid?
         | 
| 130 133 | 
             
                  assert_equal user, session.user
         | 
| 131 134 | 
             
                  assert_equal user.id, session.user_id      
         | 
| 132 135 | 
             
                  assert_equal false, session.persist?
         | 
| 136 | 
            +
                  assert_equal false, session.save
         | 
| 133 137 |  | 
| 134 138 | 
             
                  user.expects(:successful_authentication!).with('127.0.0.1').once
         | 
| 135 139 |  | 
| 136 140 | 
             
                  User.unstub(:find_for_session)
         | 
| 141 | 
            +
                  
         | 
| 142 | 
            +
                  Challah.options[:api_key_enabled] = false
         | 
| 137 143 | 
             
                end 
         | 
| 138 144 |  | 
| 139 145 | 
             
                should "reject if password is incorrect" do
         | 
    
        metadata
    CHANGED
    
    | @@ -1,7 +1,7 @@ | |
| 1 1 | 
             
            --- !ruby/object:Gem::Specification
         | 
| 2 2 | 
             
            name: challah
         | 
| 3 3 | 
             
            version: !ruby/object:Gem::Version
         | 
| 4 | 
            -
              version: 0. | 
| 4 | 
            +
              version: 0.4.0
         | 
| 5 5 | 
             
              prerelease: 
         | 
| 6 6 | 
             
            platform: ruby
         | 
| 7 7 | 
             
            authors:
         | 
| @@ -9,11 +9,11 @@ authors: | |
| 9 9 | 
             
            autorequire: 
         | 
| 10 10 | 
             
            bindir: bin
         | 
| 11 11 | 
             
            cert_chain: []
         | 
| 12 | 
            -
            date: 2012-02- | 
| 12 | 
            +
            date: 2012-02-08 00:00:00.000000000Z
         | 
| 13 13 | 
             
            dependencies:
         | 
| 14 14 | 
             
            - !ruby/object:Gem::Dependency
         | 
| 15 15 | 
             
              name: highline
         | 
| 16 | 
            -
              requirement: & | 
| 16 | 
            +
              requirement: &70244762031040 !ruby/object:Gem::Requirement
         | 
| 17 17 | 
             
                none: false
         | 
| 18 18 | 
             
                requirements:
         | 
| 19 19 | 
             
                - - ! '>='
         | 
| @@ -21,10 +21,10 @@ dependencies: | |
| 21 21 | 
             
                    version: '0'
         | 
| 22 22 | 
             
              type: :runtime
         | 
| 23 23 | 
             
              prerelease: false
         | 
| 24 | 
            -
              version_requirements: * | 
| 24 | 
            +
              version_requirements: *70244762031040
         | 
| 25 25 | 
             
            - !ruby/object:Gem::Dependency
         | 
| 26 26 | 
             
              name: rails
         | 
| 27 | 
            -
              requirement: & | 
| 27 | 
            +
              requirement: &70244762124220 !ruby/object:Gem::Requirement
         | 
| 28 28 | 
             
                none: false
         | 
| 29 29 | 
             
                requirements:
         | 
| 30 30 | 
             
                - - ! '>='
         | 
| @@ -32,10 +32,10 @@ dependencies: | |
| 32 32 | 
             
                    version: '3.1'
         | 
| 33 33 | 
             
              type: :runtime
         | 
| 34 34 | 
             
              prerelease: false
         | 
| 35 | 
            -
              version_requirements: * | 
| 35 | 
            +
              version_requirements: *70244762124220
         | 
| 36 36 | 
             
            - !ruby/object:Gem::Dependency
         | 
| 37 37 | 
             
              name: rake
         | 
| 38 | 
            -
              requirement: & | 
| 38 | 
            +
              requirement: &70244762123720 !ruby/object:Gem::Requirement
         | 
| 39 39 | 
             
                none: false
         | 
| 40 40 | 
             
                requirements:
         | 
| 41 41 | 
             
                - - ! '>='
         | 
| @@ -43,10 +43,10 @@ dependencies: | |
| 43 43 | 
             
                    version: 0.9.2
         | 
| 44 44 | 
             
              type: :runtime
         | 
| 45 45 | 
             
              prerelease: false
         | 
| 46 | 
            -
              version_requirements: * | 
| 46 | 
            +
              version_requirements: *70244762123720
         | 
| 47 47 | 
             
            - !ruby/object:Gem::Dependency
         | 
| 48 48 | 
             
              name: bcrypt-ruby
         | 
| 49 | 
            -
              requirement: & | 
| 49 | 
            +
              requirement: &70244762123260 !ruby/object:Gem::Requirement
         | 
| 50 50 | 
             
                none: false
         | 
| 51 51 | 
             
                requirements:
         | 
| 52 52 | 
             
                - - ! '>='
         | 
| @@ -54,7 +54,7 @@ dependencies: | |
| 54 54 | 
             
                    version: '0'
         | 
| 55 55 | 
             
              type: :runtime
         | 
| 56 56 | 
             
              prerelease: false
         | 
| 57 | 
            -
              version_requirements: * | 
| 57 | 
            +
              version_requirements: *70244762123260
         | 
| 58 58 | 
             
            description: A simple ruby gem for authentication, users, roles and permissions.
         | 
| 59 59 | 
             
            email:
         | 
| 60 60 | 
             
            - john@johntornow.com
         |