touth 1.0.1 → 1.1.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.
- checksums.yaml +4 -4
- data/README.md +10 -24
- data/lib/touth.rb +4 -18
- data/lib/touth/action_controller_support.rb +22 -38
- data/lib/touth/active_record_support.rb +16 -2
- data/lib/touth/authenticator.rb +57 -0
- data/lib/touth/version.rb +1 -1
- metadata +3 -3
- data/lib/touth/acts_as_token_authenticatable.rb +0 -36
    
        checksums.yaml
    CHANGED
    
    | @@ -1,7 +1,7 @@ | |
| 1 1 | 
             
            ---
         | 
| 2 2 | 
             
            SHA1:
         | 
| 3 | 
            -
              metadata.gz:  | 
| 4 | 
            -
              data.tar.gz:  | 
| 3 | 
            +
              metadata.gz: fb6f3f37d102cc22a9be19c43f1d56a174b32ed1
         | 
| 4 | 
            +
              data.tar.gz: f691dac5c428d62b7077ffdaa09eaa0df4ba29a1
         | 
| 5 5 | 
             
            SHA512:
         | 
| 6 | 
            -
              metadata.gz:  | 
| 7 | 
            -
              data.tar.gz:  | 
| 6 | 
            +
              metadata.gz: 2d166f9d6c80bf09865253d54c67e9338eb7888566df916203e798a2ed1823c0143c4200dedfa0de9788e125e4537920591593bfacf430ba030388008668bd18
         | 
| 7 | 
            +
              data.tar.gz: 4ac78b3026d68cc44331b71392e029e5bf54ca7d5241a72353cf045a8421e80bbed61a637b1aa294d05f79f159059ab7f3c349346c67174f9c6887cbaa274e67
         | 
    
        data/README.md
    CHANGED
    
    | @@ -47,11 +47,7 @@ Checking if a user is signed in, and getting the current signed-in user, the fol | |
| 47 47 |  | 
| 48 48 | 
             
            ### Hooks
         | 
| 49 49 |  | 
| 50 | 
            -
            - ` | 
| 51 | 
            -
             | 
| 52 | 
            -
            ### Fallbacks
         | 
| 53 | 
            -
             | 
| 54 | 
            -
            - `token_authentication_error!(type)`
         | 
| 50 | 
            +
            - `authenticate_token!`
         | 
| 55 51 |  | 
| 56 52 |  | 
| 57 53 | 
             
            Usage
         | 
| @@ -63,12 +59,14 @@ Usage | |
| 63 59 | 
             
            user_account = UserAccount.first
         | 
| 64 60 |  | 
| 65 61 |  | 
| 66 | 
            -
            # create access token | 
| 67 | 
            -
            t1 = user_account.access_token | 
| 62 | 
            +
            # create access token
         | 
| 63 | 
            +
            t1 = user_account.access_token
         | 
| 64 | 
            +
            #=> "0c63df99a514563a274377bb5f382c3be3bc0ff75b3758be5cd145984134d73608fe77339f7f38abf71eec38ba6800c0e2e4af08227f251b0f81163878aa25ab04085b086310557365724163636f756e7469066c2b07cc536b54"
         | 
| 68 65 |  | 
| 69 66 |  | 
| 70 67 | 
             
            # create token expires in 20 secounds
         | 
| 71 | 
            -
            t2 = user_account.access_token 20 | 
| 68 | 
            +
            t2 = user_account.access_token 20
         | 
| 69 | 
            +
            #=> "622bf3498d0c6d846f31f8bd486cbedf3dce0076661d98111231726b35709d3f6a46a419b4799fb84b94258025eafa304baf8196877c281145a434e6b859b90504085b086310557365724163636f756e7469066c2b07e1536b54"
         | 
| 72 70 |  | 
| 73 71 | 
             
            user_account.valid_access_token? t2  #=> true
         | 
| 74 72 | 
             
            sleep 20
         | 
| @@ -78,8 +76,7 @@ user_account.valid_access_token? t2  #=> false | |
| 78 76 | 
             
            ### Authentication by request headers
         | 
| 79 77 |  | 
| 80 78 | 
             
            ```
         | 
| 81 | 
            -
            X- | 
| 82 | 
            -
            X-Auth-Token: 9619feb4b8d54352ae07588d011da48385c8c4f072ab889d3996d127ad2142fc6213d553
         | 
| 79 | 
            +
            X-Access-Token: 2a20d42585159a9f1c9564afd051d48e2209af5e18d83c9685de1ae0df66c2b76c2bc7633e4b14748f1cf94b09e94d1a33804b1e74dad9d02d231b12e6c840b504085b086310557365724163636f756e7469066c2b0737546b54
         | 
| 83 80 | 
             
            ```
         | 
| 84 81 |  | 
| 85 82 | 
             
            ### Invalidation
         | 
| @@ -114,6 +111,9 @@ Touth.setup do |config| | |
| 114 111 | 
             
              # :encrypted_password will work nice with devise model.
         | 
| 115 112 | 
             
              config.password_field = :encrypted_password
         | 
| 116 113 |  | 
| 114 | 
            +
              # Header name
         | 
| 115 | 
            +
              config.header_name = 'X-Access-Token'
         | 
| 116 | 
            +
             | 
| 117 117 | 
             
            end
         | 
| 118 118 | 
             
            ```
         | 
| 119 119 |  | 
| @@ -123,23 +123,9 @@ Contributing | |
| 123 123 |  | 
| 124 124 | 
             
            Contributions are always welcome!
         | 
| 125 125 |  | 
| 126 | 
            -
            ### Bug reports
         | 
| 127 | 
            -
             | 
| 128 | 
            -
            1. Ensure the bug can be reproduced on the latest master.
         | 
| 129 | 
            -
            1. Check it's not a duplicate.
         | 
| 130 | 
            -
            1. Raise an issue.
         | 
| 131 | 
            -
             | 
| 132 | 
            -
             | 
| 133 | 
            -
            ### Pull requests
         | 
| 134 | 
            -
             | 
| 135 | 
            -
            1. Fork the repository.
         | 
| 136 | 
            -
            1. Create a branch.
         | 
| 137 | 
            -
            1. Create a new pull request.
         | 
| 138 | 
            -
             | 
| 139 126 |  | 
| 140 127 | 
             
            License
         | 
| 141 128 | 
             
            -------
         | 
| 142 129 |  | 
| 143 130 | 
             
            This project is copyright by [Creasty](http://www.creasty.com), released under the MIT lisence.  
         | 
| 144 131 | 
             
            See `LICENSE` file for details.
         | 
| 145 | 
            -
             | 
    
        data/lib/touth.rb
    CHANGED
    
    | @@ -1,13 +1,11 @@ | |
| 1 1 | 
             
            require 'active_support'
         | 
| 2 2 |  | 
| 3 3 |  | 
| 4 | 
            -
            #  Touth
         | 
| 5 | 
            -
            #-----------------------------------------------
         | 
| 6 4 | 
             
            module Touth
         | 
| 7 5 |  | 
| 8 6 | 
             
              extend ActiveSupport::Autoload
         | 
| 9 7 |  | 
| 10 | 
            -
              autoload : | 
| 8 | 
            +
              autoload :Authenticator
         | 
| 11 9 | 
             
              autoload :ActiveRecordSupport
         | 
| 12 10 | 
             
              autoload :ActionControllerSupport
         | 
| 13 11 | 
             
              autoload :VERSION
         | 
| @@ -16,12 +14,14 @@ module Touth | |
| 16 14 |  | 
| 17 15 | 
             
                attr_accessor :access_token_lifetime,
         | 
| 18 16 | 
             
                  :client_secret_key,
         | 
| 19 | 
            -
                  :password_field
         | 
| 17 | 
            +
                  :password_field,
         | 
| 18 | 
            +
                  :header_name
         | 
| 20 19 |  | 
| 21 20 | 
             
                def initialize
         | 
| 22 21 | 
             
                  @access_token_lifetime = 60 * (24 * 60 * 60)  # 60 days
         | 
| 23 22 | 
             
                  @client_secret_key     = ''  # use SecureRandom.hex(64) to generate one
         | 
| 24 23 | 
             
                  @password_field        = :encrypted_password
         | 
| 24 | 
            +
                  @header_name           = 'X-Access-Token'
         | 
| 25 25 | 
             
                end
         | 
| 26 26 |  | 
| 27 27 | 
             
              end
         | 
| @@ -54,18 +54,4 @@ module Touth | |
| 54 54 |  | 
| 55 55 | 
             
            end
         | 
| 56 56 |  | 
| 57 | 
            -
             | 
| 58 | 
            -
            #  Setup
         | 
| 59 | 
            -
            #-----------------------------------------------
         | 
| 60 57 | 
             
            Touth.setup
         | 
| 61 | 
            -
             | 
| 62 | 
            -
             | 
| 63 | 
            -
            #  Include
         | 
| 64 | 
            -
            #-----------------------------------------------
         | 
| 65 | 
            -
            ActiveSupport.on_load(:active_record) do
         | 
| 66 | 
            -
              extend Touth::ActiveRecordSupport::ClassMethods
         | 
| 67 | 
            -
            end
         | 
| 68 | 
            -
            ActiveSupport.on_load(:action_controller) do
         | 
| 69 | 
            -
              extend Touth::ActionControllerSupport::ClassMethods
         | 
| 70 | 
            -
              include Touth::ActionControllerSupport::InstanceMethods
         | 
| 71 | 
            -
            end
         | 
| @@ -1,27 +1,24 @@ | |
| 1 1 | 
             
            module Touth
         | 
| 2 2 | 
             
              module ActionControllerSupport
         | 
| 3 | 
            -
             | 
| 4 3 | 
             
                module ClassMethods
         | 
| 5 4 |  | 
| 6 | 
            -
                  mattr_accessor : | 
| 7 | 
            -
             | 
| 8 | 
            -
                  def token_authentication_for(scope)
         | 
| 9 | 
            -
                    scope = scope.to_s
         | 
| 10 | 
            -
                    name = scope.gsub('::', '_').underscore
         | 
| 5 | 
            +
                  mattr_accessor :access_token_resources
         | 
| 11 6 |  | 
| 12 | 
            -
             | 
| 13 | 
            -
             | 
| 14 | 
            -
             | 
| 15 | 
            -
                    }
         | 
| 7 | 
            +
                  def token_authentication_for(resource_name)
         | 
| 8 | 
            +
                    resource_name = resource_name.to_s
         | 
| 9 | 
            +
                    name = resource_name.gsub('::', '_').underscore
         | 
| 16 10 |  | 
| 17 | 
            -
                     | 
| 11 | 
            +
                    unless self.access_token_resources
         | 
| 12 | 
            +
                      self.access_token_resources = {}
         | 
| 13 | 
            +
                      before_action :authenticate_token!
         | 
| 14 | 
            +
                    end
         | 
| 18 15 |  | 
| 19 16 | 
             
                    define_method "#{name}_signed_in?" do
         | 
| 20 | 
            -
                      !!self.class. | 
| 17 | 
            +
                      !!self.class.access_token_resources[resource_name]
         | 
| 21 18 | 
             
                    end
         | 
| 22 19 |  | 
| 23 20 | 
             
                    define_method "current_#{name}" do
         | 
| 24 | 
            -
                      self.class. | 
| 21 | 
            +
                      self.class.access_token_resources[resource_name]
         | 
| 25 22 | 
             
                    end
         | 
| 26 23 | 
             
                  end
         | 
| 27 24 |  | 
| @@ -31,36 +28,23 @@ module Touth | |
| 31 28 |  | 
| 32 29 | 
             
                protected
         | 
| 33 30 |  | 
| 34 | 
            -
                  def  | 
| 35 | 
            -
                     | 
| 36 | 
            -
                      id:    request.headers['X-Auth-ID'],
         | 
| 37 | 
            -
                      token: request.headers['X-Auth-Token'],
         | 
| 38 | 
            -
                    }
         | 
| 39 | 
            -
                  end
         | 
| 31 | 
            +
                  def authenticate_token!
         | 
| 32 | 
            +
                    token = request.headers[Touth.header_name]
         | 
| 40 33 |  | 
| 41 | 
            -
             | 
| 42 | 
            -
             | 
| 43 | 
            -
             | 
| 44 | 
            -
                    model = id.present? \
         | 
| 45 | 
            -
                      && self.class.token_authentication_on[:class].find(id)
         | 
| 46 | 
            -
             | 
| 47 | 
            -
                    unless model
         | 
| 48 | 
            -
                      return token_authentication_error! :no_entity
         | 
| 34 | 
            +
                    if Authenticator.valid_access_token? token
         | 
| 35 | 
            +
                      render nothing: true, status: :unauthorized
         | 
| 36 | 
            +
                      return false
         | 
| 49 37 | 
             
                    end
         | 
| 50 38 |  | 
| 51 | 
            -
                     | 
| 52 | 
            -
             | 
| 53 | 
            -
                    end
         | 
| 54 | 
            -
             | 
| 55 | 
            -
                    self.class.token_authentication_on[:current] = model
         | 
| 56 | 
            -
                  end
         | 
| 57 | 
            -
             | 
| 58 | 
            -
                  def token_authentication_error!(type)
         | 
| 59 | 
            -
                    render nothing: true, status: :unauthorized
         | 
| 60 | 
            -
                    false
         | 
| 39 | 
            +
                    model = Authenticator.get_model token
         | 
| 40 | 
            +
                    self.class.access_token_resources[model.name] = model
         | 
| 61 41 | 
             
                  end
         | 
| 62 42 |  | 
| 63 43 | 
             
                end
         | 
| 64 | 
            -
             | 
| 65 44 | 
             
              end
         | 
| 66 45 | 
             
            end
         | 
| 46 | 
            +
             | 
| 47 | 
            +
            ActiveSupport.on_load(:action_controller) do
         | 
| 48 | 
            +
              extend Touth::ActionControllerSupport::ClassMethods
         | 
| 49 | 
            +
              include Touth::ActionControllerSupport::InstanceMethods
         | 
| 50 | 
            +
            end
         | 
| @@ -1,13 +1,27 @@ | |
| 1 1 | 
             
            module Touth
         | 
| 2 2 | 
             
              module ActiveRecordSupport
         | 
| 3 | 
            -
             | 
| 4 3 | 
             
                module ClassMethods
         | 
| 5 4 |  | 
| 6 5 | 
             
                  def acts_as_token_authenticatable
         | 
| 7 | 
            -
                    include Touth:: | 
| 6 | 
            +
                    include Touth::ActiveRecordSupport::InstanceMethods
         | 
| 8 7 | 
             
                  end
         | 
| 9 8 |  | 
| 10 9 | 
             
                end
         | 
| 11 10 |  | 
| 11 | 
            +
                module InstanceMethods
         | 
| 12 | 
            +
             
         | 
| 13 | 
            +
                  def access_token(*args)
         | 
| 14 | 
            +
                    Authenticator.issue_access_token self, *args
         | 
| 15 | 
            +
                  end
         | 
| 16 | 
            +
             | 
| 17 | 
            +
                  def valid_access_token?(token)
         | 
| 18 | 
            +
                    Authenticator.get_model(token) == self
         | 
| 19 | 
            +
                  end
         | 
| 20 | 
            +
             | 
| 21 | 
            +
                end
         | 
| 12 22 | 
             
              end
         | 
| 13 23 | 
             
            end
         | 
| 24 | 
            +
             | 
| 25 | 
            +
            ActiveSupport.on_load(:active_record) do
         | 
| 26 | 
            +
              extend Touth::ActiveRecordSupport::ClassMethods
         | 
| 27 | 
            +
            end
         | 
| @@ -0,0 +1,57 @@ | |
| 1 | 
            +
            module Touth
         | 
| 2 | 
            +
              module Authenticator
         | 
| 3 | 
            +
             | 
| 4 | 
            +
              module_function
         | 
| 5 | 
            +
             | 
| 6 | 
            +
                def issue_access_token(model, lifetime = Touth.access_token_lifetime)
         | 
| 7 | 
            +
                  expires_at = Time.now.to_i + lifetime
         | 
| 8 | 
            +
             | 
| 9 | 
            +
                  data = Marshal.dump([
         | 
| 10 | 
            +
                    model.class,
         | 
| 11 | 
            +
                    model.id,
         | 
| 12 | 
            +
                    expires_at,
         | 
| 13 | 
            +
                  ])
         | 
| 14 | 
            +
             | 
| 15 | 
            +
                  data_sign = Touth.digest data
         | 
| 16 | 
            +
                  data_key = gen_data_key model, data_sign
         | 
| 17 | 
            +
             | 
| 18 | 
            +
                  [
         | 
| 19 | 
            +
                    data_sign,
         | 
| 20 | 
            +
                    data_key,
         | 
| 21 | 
            +
                    data,
         | 
| 22 | 
            +
                  ].join.unpack('H*')[0]
         | 
| 23 | 
            +
                end
         | 
| 24 | 
            +
             | 
| 25 | 
            +
                def valid_access_token?(token)
         | 
| 26 | 
            +
                  !!get_model(token)
         | 
| 27 | 
            +
                end
         | 
| 28 | 
            +
             | 
| 29 | 
            +
                def get_model(token)
         | 
| 30 | 
            +
                  @access_token_data_cache ||= {}
         | 
| 31 | 
            +
                  model = @access_token_data_cache[token]
         | 
| 32 | 
            +
             | 
| 33 | 
            +
                  return model if model
         | 
| 34 | 
            +
             | 
| 35 | 
            +
                  begin
         | 
| 36 | 
            +
                    data_sign, data_key, data = [token].pack('H*').unpack 'A32A32A*'
         | 
| 37 | 
            +
             | 
| 38 | 
            +
                    if data_sign == Touth.digest(data)
         | 
| 39 | 
            +
                      model_class, id, expires_at = Marshal.load data
         | 
| 40 | 
            +
             | 
| 41 | 
            +
                      model = model_class.find id
         | 
| 42 | 
            +
             | 
| 43 | 
            +
                      if gen_data_key(model, data_sign) == data_key && Time.now.to_i < expires_at
         | 
| 44 | 
            +
                        @access_token_data_cache[token] = model
         | 
| 45 | 
            +
                      end
         | 
| 46 | 
            +
                    end
         | 
| 47 | 
            +
                  rescue
         | 
| 48 | 
            +
                    nil
         | 
| 49 | 
            +
                  end
         | 
| 50 | 
            +
                end
         | 
| 51 | 
            +
             | 
| 52 | 
            +
                def gen_data_key(model, data_sign)
         | 
| 53 | 
            +
                  Touth.digest [data_sign, model.send(Touth.password_field)].join
         | 
| 54 | 
            +
                end
         | 
| 55 | 
            +
             | 
| 56 | 
            +
              end
         | 
| 57 | 
            +
            end
         | 
    
        data/lib/touth/version.rb
    CHANGED
    
    
    
        metadata
    CHANGED
    
    | @@ -1,14 +1,14 @@ | |
| 1 1 | 
             
            --- !ruby/object:Gem::Specification
         | 
| 2 2 | 
             
            name: touth
         | 
| 3 3 | 
             
            version: !ruby/object:Gem::Version
         | 
| 4 | 
            -
              version: 1.0 | 
| 4 | 
            +
              version: 1.1.0
         | 
| 5 5 | 
             
            platform: ruby
         | 
| 6 6 | 
             
            authors:
         | 
| 7 7 | 
             
            - Yuki Iwanaga
         | 
| 8 8 | 
             
            autorequire: 
         | 
| 9 9 | 
             
            bindir: bin
         | 
| 10 10 | 
             
            cert_chain: []
         | 
| 11 | 
            -
            date: 2014-09- | 
| 11 | 
            +
            date: 2014-09-19 00:00:00.000000000 Z
         | 
| 12 12 | 
             
            dependencies:
         | 
| 13 13 | 
             
            - !ruby/object:Gem::Dependency
         | 
| 14 14 | 
             
              name: activesupport
         | 
| @@ -73,7 +73,7 @@ files: | |
| 73 73 | 
             
            - lib/touth.rb
         | 
| 74 74 | 
             
            - lib/touth/action_controller_support.rb
         | 
| 75 75 | 
             
            - lib/touth/active_record_support.rb
         | 
| 76 | 
            -
            - lib/touth/ | 
| 76 | 
            +
            - lib/touth/authenticator.rb
         | 
| 77 77 | 
             
            - lib/touth/version.rb
         | 
| 78 78 | 
             
            - touth.gemspec
         | 
| 79 79 | 
             
            homepage: https://github.com/creasty/touth
         | 
| @@ -1,36 +0,0 @@ | |
| 1 | 
            -
            module Touth
         | 
| 2 | 
            -
              module ActsAsTokenAuthenticatable
         | 
| 3 | 
            -
             | 
| 4 | 
            -
                def access_token(lifetime = Touth.access_token_lifetime)
         | 
| 5 | 
            -
                  expires_at = Time.now.to_i + lifetime
         | 
| 6 | 
            -
             | 
| 7 | 
            -
                  [access_token_id(expires_at), [expires_at].pack('V')].join.unpack('H*')[0]
         | 
| 8 | 
            -
                end
         | 
| 9 | 
            -
             | 
| 10 | 
            -
                def valid_access_token?(token)
         | 
| 11 | 
            -
                  begin
         | 
| 12 | 
            -
                    data = [token].pack 'H*'
         | 
| 13 | 
            -
                    token_id, timestamp = data.unpack 'A32A*'
         | 
| 14 | 
            -
                    expires_at = timestamp.unpack('V')[0]
         | 
| 15 | 
            -
             | 
| 16 | 
            -
                    access_token_id(expires_at) == token_id && Time.now.to_i < expires_at
         | 
| 17 | 
            -
                  rescue
         | 
| 18 | 
            -
                    false
         | 
| 19 | 
            -
                  end
         | 
| 20 | 
            -
                end
         | 
| 21 | 
            -
             | 
| 22 | 
            -
              private
         | 
| 23 | 
            -
             | 
| 24 | 
            -
                def access_token_id(expires_at)
         | 
| 25 | 
            -
                  raw = [
         | 
| 26 | 
            -
                    expires_at,
         | 
| 27 | 
            -
                    self.class.name,
         | 
| 28 | 
            -
                    self.id,
         | 
| 29 | 
            -
                    self.send(Touth.password_field),
         | 
| 30 | 
            -
                  ].join ':'
         | 
| 31 | 
            -
             | 
| 32 | 
            -
                  Touth.digest raw
         | 
| 33 | 
            -
                end
         | 
| 34 | 
            -
             | 
| 35 | 
            -
              end
         | 
| 36 | 
            -
            end
         |