grape_token_auth 0.1.0.rc2 → 0.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 +9 -4
- data/grape_token_auth.gemspec +1 -1
- data/lib/grape_token_auth.rb +39 -15
- data/lib/grape_token_auth/api_helpers.rb +1 -1
- data/lib/grape_token_auth/apis/omniauth_api.rb +2 -5
- data/lib/grape_token_auth/apis/password_api.rb +0 -4
- data/lib/grape_token_auth/apis/session_api.rb +6 -4
- data/lib/grape_token_auth/authentication_header.rb +21 -4
- data/lib/grape_token_auth/authorizer_data.rb +19 -6
- data/lib/grape_token_auth/mail/mail.rb +0 -12
- data/lib/grape_token_auth/mail/smtp_mailer.rb +7 -0
- data/lib/grape_token_auth/middleware.rb +2 -2
- data/lib/grape_token_auth/mount_helpers.rb +22 -17
- data/lib/grape_token_auth/omniauth/omniauth_failure_html.rb +0 -2
- data/lib/grape_token_auth/omniauth/omniauth_resource.rb +1 -10
- data/lib/grape_token_auth/omniauth/omniauth_success_html.rb +0 -2
- data/lib/grape_token_auth/orm_integrations/active_record_token_auth.rb +4 -23
- data/lib/grape_token_auth/resource/resource_creator.rb +1 -3
- data/lib/grape_token_auth/resource/resource_crud_base.rb +1 -10
- data/lib/grape_token_auth/token_authorizer.rb +3 -3
- data/lib/grape_token_auth/utility.rb +16 -0
- data/lib/grape_token_auth/version.rb +1 -1
- metadata +8 -6
    
        checksums.yaml
    CHANGED
    
    | @@ -1,7 +1,7 @@ | |
| 1 1 | 
             
            ---
         | 
| 2 2 | 
             
            SHA1:
         | 
| 3 | 
            -
              metadata.gz:  | 
| 4 | 
            -
              data.tar.gz:  | 
| 3 | 
            +
              metadata.gz: 6211636ade2d82f854a1581aa553db28d969bae2
         | 
| 4 | 
            +
              data.tar.gz: 67430fb3d2e77ab25f6adcf881e81549dd66de4f
         | 
| 5 5 | 
             
            SHA512:
         | 
| 6 | 
            -
              metadata.gz:  | 
| 7 | 
            -
              data.tar.gz:  | 
| 6 | 
            +
              metadata.gz: 48cb9baa1072a05831fc280bc671cd81ba65e056439d499abcdb1ba6617132768fe14e37682d1e3debd2b8792026662b45baf165ccc07ca2ba1ecbf44d2653c0
         | 
| 7 | 
            +
              data.tar.gz: 9b7f0fbd5cc1c06c7a323583130ea4ee580775f49bb0450e7dff27920c7a9fe2569ff21c2c4c50c24d4dfd2dab3a2c6878a22ca0105f16172922c06b6d820125
         | 
    
        data/README.md
    CHANGED
    
    | @@ -1,10 +1,6 @@ | |
| 1 1 | 
             
            # GrapeTokenAuth
         | 
| 2 2 | 
             
            [![Code Climate GPA][11]][12] [![Test Coverage][13]][14] [![Circle CI][15]][16]
         | 
| 3 3 |  | 
| 4 | 
            -
            > __This gem is in active development__ but approaching a 0.1.0 release. If you
         | 
| 5 | 
            -
            are interested in helping out, please clone the release candidate and submit issues
         | 
| 6 | 
            -
            and PRs to help get it into a production-ready state!
         | 
| 7 | 
            -
             | 
| 8 4 | 
             
            GrapeTokenAuth is a token authentication solution for grape. It is compatible
         | 
| 9 5 | 
             
            with [ng-token-auth][1] (for _angular_) and [j-toker][2] (for _jQuery_), and is
         | 
| 10 6 | 
             
            meant as a [grape][4] (rather than _rails_) version of [devise_token_auth][3]. As
         | 
| @@ -35,11 +31,15 @@ gem 'grape_token_auth' | |
| 35 31 |  | 
| 36 32 | 
             
            And then execute:
         | 
| 37 33 |  | 
| 34 | 
            +
            ```
         | 
| 38 35 | 
             
            $ bundle
         | 
| 36 | 
            +
            ```
         | 
| 39 37 |  | 
| 40 38 | 
             
            Or install it yourself as:
         | 
| 41 39 |  | 
| 40 | 
            +
            ```
         | 
| 42 41 | 
             
            $ gem install grape_token_auth
         | 
| 42 | 
            +
            ```
         | 
| 43 43 |  | 
| 44 44 | 
             
            ## Quick-Start Setup
         | 
| 45 45 |  | 
| @@ -116,6 +116,10 @@ end | |
| 116 116 | 
             
            **Note on Secret**: generate a unique secret using `rake secret` in a rails app
         | 
| 117 117 | 
             
            or via [these directions][secret].
         | 
| 118 118 |  | 
| 119 | 
            +
            In addition, if you are using the mail features in grape_token_auth you will
         | 
| 120 | 
            +
            want to set the appropriate configuration options. See the [mail wiki page][mail] for
         | 
| 121 | 
            +
            more information.
         | 
| 122 | 
            +
             | 
| 119 123 |  | 
| 120 124 | 
             
            ### Mounting authentication APIs
         | 
| 121 125 |  | 
| @@ -247,3 +251,4 @@ To run tests, you will need postgres to be setup and configured correctly.  Run | |
| 247 251 | 
             
            [secret]: http://www.jamesbadger.ca/2012/12/18/generate-new-secret-token/
         | 
| 248 252 | 
             
            [dta-contributors]: https://github.com/lynndylanhurley/devise_token_auth#callouts
         | 
| 249 253 | 
             
            [devise]: https://github.com/plataformatec/devise
         | 
| 254 | 
            +
            [mail]: https://github.com/mcordell/grape_token_auth/wiki/Email
         | 
    
        data/grape_token_auth.gemspec
    CHANGED
    
    | @@ -18,7 +18,7 @@ Gem::Specification.new do |spec| | |
| 18 18 | 
             
              spec.executables   = spec.files.grep(%r{^exe/}) { |f| File.basename(f) }
         | 
| 19 19 | 
             
              spec.require_paths = ['lib']
         | 
| 20 20 |  | 
| 21 | 
            -
              spec.add_dependency 'grape', ' | 
| 21 | 
            +
              spec.add_dependency 'grape', '>= 0.12.0'
         | 
| 22 22 | 
             
              spec.add_dependency 'warden', '~> 1.2.3'
         | 
| 23 23 | 
             
              spec.add_dependency 'bcrypt', '~> 3.0'
         | 
| 24 24 | 
             
              spec.add_dependency 'mail',   '~> 2.0'
         | 
    
        data/lib/grape_token_auth.rb
    CHANGED
    
    | @@ -1,7 +1,44 @@ | |
| 1 | 
            -
            require ' | 
| 1 | 
            +
            require 'bcrypt'
         | 
| 2 2 | 
             
            require 'forwardable'
         | 
| 3 3 | 
             
            require 'grape'
         | 
| 4 | 
            -
             | 
| 4 | 
            +
             | 
| 5 | 
            +
            # Load base classes first
         | 
| 6 | 
            +
            require 'grape_token_auth/mail/message_base'
         | 
| 7 | 
            +
            require 'grape_token_auth/omniauth/omniauth_html_base'
         | 
| 8 | 
            +
            require 'grape_token_auth/resource/resource_crud_base'
         | 
| 9 | 
            +
             | 
| 10 | 
            +
            require 'grape_token_auth/api_helpers'
         | 
| 11 | 
            +
            require 'grape_token_auth/apis/confirmation_api'
         | 
| 12 | 
            +
            require 'grape_token_auth/apis/omniauth_api'
         | 
| 13 | 
            +
            require 'grape_token_auth/apis/password_api'
         | 
| 14 | 
            +
            require 'grape_token_auth/apis/registration_api'
         | 
| 15 | 
            +
            require 'grape_token_auth/apis/session_api'
         | 
| 16 | 
            +
            require 'grape_token_auth/apis/token_validation_api'
         | 
| 17 | 
            +
            require 'grape_token_auth/authentication_header'
         | 
| 18 | 
            +
            require 'grape_token_auth/authorizer_data'
         | 
| 19 | 
            +
            require 'grape_token_auth/configuration'
         | 
| 20 | 
            +
            require 'grape_token_auth/exceptions'
         | 
| 21 | 
            +
            require 'grape_token_auth/key_generator'
         | 
| 22 | 
            +
            require 'grape_token_auth/lookup_token'
         | 
| 23 | 
            +
            require 'grape_token_auth/mail/messages/confirmation/confirmation_email'
         | 
| 24 | 
            +
            require 'grape_token_auth/mail/messages/password_reset/password_reset_email'
         | 
| 25 | 
            +
            require 'grape_token_auth/mail/mail'
         | 
| 26 | 
            +
            require 'grape_token_auth/mail/smtp_mailer'
         | 
| 27 | 
            +
            require 'grape_token_auth/middleware'
         | 
| 28 | 
            +
            require 'grape_token_auth/mount_helpers'
         | 
| 29 | 
            +
            require 'grape_token_auth/omniauth/omniauth_failure_html'
         | 
| 30 | 
            +
            require 'grape_token_auth/omniauth/omniauth_resource'
         | 
| 31 | 
            +
            require 'grape_token_auth/omniauth/omniauth_success_html'
         | 
| 32 | 
            +
            require 'grape_token_auth/orm_integrations/active_record_token_auth'
         | 
| 33 | 
            +
            require 'grape_token_auth/resource/resource_creator'
         | 
| 34 | 
            +
            require 'grape_token_auth/resource/resource_finder'
         | 
| 35 | 
            +
            require 'grape_token_auth/resource/resource_updater'
         | 
| 36 | 
            +
            require 'grape_token_auth/token'
         | 
| 37 | 
            +
            require 'grape_token_auth/token_authentication'
         | 
| 38 | 
            +
            require 'grape_token_auth/token_authorizer'
         | 
| 39 | 
            +
            require 'grape_token_auth/unauthorized_middleware'
         | 
| 40 | 
            +
            require 'grape_token_auth/utility'
         | 
| 41 | 
            +
            require 'grape_token_auth/version'
         | 
| 5 42 |  | 
| 6 43 | 
             
            module GrapeTokenAuth
         | 
| 7 44 | 
             
              class << self
         | 
| @@ -26,23 +63,10 @@ module GrapeTokenAuth | |
| 26 63 | 
             
                  configure(&block) if block_given?
         | 
| 27 64 | 
             
                end
         | 
| 28 65 |  | 
| 29 | 
            -
                def configure_warden(warden_manager)
         | 
| 30 | 
            -
                  configuration.mappings.each do |scope, klass|
         | 
| 31 | 
            -
                    warden_manager.serialize_into_session(scope) do |record|
         | 
| 32 | 
            -
                      klass.serialize_into_session(record)
         | 
| 33 | 
            -
                    end
         | 
| 34 | 
            -
             | 
| 35 | 
            -
                    warden_manager.serialize_from_session(scope) do |key|
         | 
| 36 | 
            -
                      klass.serialize_from_session(*key)
         | 
| 37 | 
            -
                    end
         | 
| 38 | 
            -
                  end
         | 
| 39 | 
            -
                end
         | 
| 40 | 
            -
             | 
| 41 66 | 
             
                def setup_warden!(builder)
         | 
| 42 67 | 
             
                  builder.use Warden::Manager do |manager|
         | 
| 43 68 | 
             
                    manager.failure_app = GrapeTokenAuth::UnauthorizedMiddleware
         | 
| 44 69 | 
             
                    manager.default_scope = :user
         | 
| 45 | 
            -
                    GrapeTokenAuth.configure_warden(manager)
         | 
| 46 70 | 
             
                  end
         | 
| 47 71 | 
             
                end
         | 
| 48 72 |  | 
| @@ -20,10 +20,6 @@ module GrapeTokenAuth | |
| 20 20 | 
             
                      html
         | 
| 21 21 | 
             
                    end
         | 
| 22 22 |  | 
| 23 | 
            -
                    def sign_in_resource(resource, scope)
         | 
| 24 | 
            -
                      request.env['warden'].session_serializer.store(resource, scope)
         | 
| 25 | 
            -
                    end
         | 
| 26 | 
            -
             | 
| 27 23 | 
             
                    def redirect_or_render(success_html)
         | 
| 28 24 | 
             
                      if %w(inAppBrowser newWindow).include?(success_html.window_type)
         | 
| 29 25 | 
             
                        render_html(success_html.render_html)
         | 
| @@ -80,7 +76,8 @@ module GrapeTokenAuth | |
| 80 76 | 
             
                                                             auth_hash,
         | 
| 81 77 | 
             
                                                             omniauth_params)
         | 
| 82 78 | 
             
                    if success_html.persist_oauth_attributes!
         | 
| 83 | 
            -
                       | 
| 79 | 
            +
                      data = AuthorizerData.load_from_env_or_create(env)
         | 
| 80 | 
            +
                      data.store_resource(success_html.resource, base.resource_scope)
         | 
| 84 81 | 
             
                      redirect_or_render(success_html)
         | 
| 85 82 | 
             
                    else
         | 
| 86 83 | 
             
                      status 500
         | 
| @@ -10,10 +10,6 @@ module GrapeTokenAuth | |
| 10 10 | 
             
                      throw(:warden, errors: message)
         | 
| 11 11 | 
             
                    end
         | 
| 12 12 |  | 
| 13 | 
            -
                    def resource_class
         | 
| 14 | 
            -
                      @rescource_class ||= scope_to_class(resource_scope)
         | 
| 15 | 
            -
                    end
         | 
| 16 | 
            -
             | 
| 17 13 | 
             
                    def bad_request(messages, code = 422)
         | 
| 18 14 | 
             
                      status(code)
         | 
| 19 15 | 
             
                      { 'status' => 'error', 'error' => messages.join(',') }
         | 
| @@ -2,8 +2,8 @@ module GrapeTokenAuth | |
| 2 2 | 
             
              module SessionsAPICore
         | 
| 3 3 | 
             
                def self.included(base)
         | 
| 4 4 | 
             
                  base.helpers do
         | 
| 5 | 
            -
                    def find_resource( | 
| 6 | 
            -
                      token_authorizer = TokenAuthorizer.new( | 
| 5 | 
            +
                    def find_resource(data, mapping)
         | 
| 6 | 
            +
                      token_authorizer = TokenAuthorizer.new(data)
         | 
| 7 7 | 
             
                      token_authorizer.find_resource(mapping)
         | 
| 8 8 | 
             
                    end
         | 
| 9 9 | 
             
                  end
         | 
| @@ -23,7 +23,7 @@ module GrapeTokenAuth | |
| 23 23 | 
             
                      throw(:warden, errors: { errors: [error_message], status: 'error' })
         | 
| 24 24 | 
             
                    end
         | 
| 25 25 |  | 
| 26 | 
            -
                    data = AuthorizerData. | 
| 26 | 
            +
                    data = AuthorizerData.load_from_env_or_create(env)
         | 
| 27 27 | 
             
                    env['rack.session'] ||= {}
         | 
| 28 28 | 
             
                    data.store_resource(resource, base.resource_scope)
         | 
| 29 29 | 
             
                    auth_header = AuthenticationHeader.new(data, start_time)
         | 
| @@ -35,10 +35,12 @@ module GrapeTokenAuth | |
| 35 35 | 
             
                  end
         | 
| 36 36 |  | 
| 37 37 | 
             
                  base.delete '/sign_out' do
         | 
| 38 | 
            -
                     | 
| 38 | 
            +
                    data = AuthorizerData.load_from_env_or_create(env)
         | 
| 39 | 
            +
                    resource = find_resource(data, base.resource_scope)
         | 
| 39 40 |  | 
| 40 41 | 
             
                    if resource
         | 
| 41 42 | 
             
                      resource.tokens.delete(env[Configuration::CLIENT_KEY])
         | 
| 43 | 
            +
                      data.skip_auth_headers = true
         | 
| 42 44 | 
             
                      resource.save
         | 
| 43 45 | 
             
                      status 200
         | 
| 44 46 | 
             
                    else
         | 
| @@ -9,19 +9,32 @@ module GrapeTokenAuth | |
| 9 9 | 
             
                end
         | 
| 10 10 |  | 
| 11 11 | 
             
                def headers
         | 
| 12 | 
            -
                  return {} unless resource && resource.valid? && client_id
         | 
| 12 | 
            +
                  return {} unless resource && resource.valid? && client_id && !skip_auth_headers
         | 
| 13 13 | 
             
                  auth_headers_from_resource
         | 
| 14 14 | 
             
                end
         | 
| 15 15 |  | 
| 16 | 
            +
                def self.build_auth_headers(token, uid)
         | 
| 17 | 
            +
                  {
         | 
| 18 | 
            +
                    'access-token' => token.to_s,
         | 
| 19 | 
            +
                    'expiry' => token.expiry.to_s,
         | 
| 20 | 
            +
                    'client' => token.client_id.to_s,
         | 
| 21 | 
            +
                    'token-type' => 'Bearer',
         | 
| 22 | 
            +
                    'uid' => uid.to_s
         | 
| 23 | 
            +
                  }
         | 
| 24 | 
            +
                end
         | 
| 25 | 
            +
             | 
| 16 26 | 
             
                private
         | 
| 17 27 |  | 
| 18 | 
            -
                 | 
| 19 | 
            -
             | 
| 28 | 
            +
                attr_reader :request_start, :resource, :data
         | 
| 29 | 
            +
             | 
| 30 | 
            +
                def_delegators :data, :token, :client_id, :skip_auth_headers
         | 
| 20 31 |  | 
| 21 32 | 
             
                def auth_headers_from_resource
         | 
| 22 33 | 
             
                  auth_headers = {}
         | 
| 23 34 | 
             
                  resource.while_record_locked do
         | 
| 24 | 
            -
                    if  | 
| 35 | 
            +
                    if was_not_authenticated_with_token
         | 
| 36 | 
            +
                      auth_headers = resource.create_new_auth_token
         | 
| 37 | 
            +
                    elsif !GrapeTokenAuth.change_headers_on_each_request
         | 
| 25 38 | 
             
                      auth_headers = resource.extend_batch_buffer(token, client_id)
         | 
| 26 39 | 
             
                    elsif batch_request?
         | 
| 27 40 | 
             
                      resource.extend_batch_buffer(token, client_id)
         | 
| @@ -32,6 +45,10 @@ module GrapeTokenAuth | |
| 32 45 | 
             
                  coerce_headers_to_strings(auth_headers)
         | 
| 33 46 | 
             
                end
         | 
| 34 47 |  | 
| 48 | 
            +
                def was_not_authenticated_with_token
         | 
| 49 | 
            +
                  !data.authed_with_token
         | 
| 50 | 
            +
                end
         | 
| 51 | 
            +
             | 
| 35 52 | 
             
                def coerce_headers_to_strings(auth_headers)
         | 
| 36 53 | 
             
                  auth_headers.each { |k, v|  auth_headers[k] = v.to_s }
         | 
| 37 54 | 
             
                end
         | 
| @@ -1,5 +1,7 @@ | |
| 1 1 | 
             
            module GrapeTokenAuth
         | 
| 2 2 | 
             
              class AuthorizerData
         | 
| 3 | 
            +
                RACK_ENV_KEY = 'gta.auth_data'
         | 
| 4 | 
            +
                attr_accessor :authed_with_token, :skip_auth_headers
         | 
| 3 5 | 
             
                attr_reader :uid, :client_id, :token, :expiry, :warden
         | 
| 4 6 |  | 
| 5 7 | 
             
                def initialize(uid = nil, client_id = nil, token = nil,
         | 
| @@ -9,24 +11,35 @@ module GrapeTokenAuth | |
| 9 11 | 
             
                  @token = token
         | 
| 10 12 | 
             
                  @expiry = expiry
         | 
| 11 13 | 
             
                  @warden = warden
         | 
| 14 | 
            +
                  @authed_with_token = false
         | 
| 15 | 
            +
                  @skip_auth_headers = false
         | 
| 12 16 | 
             
                end
         | 
| 13 17 |  | 
| 14 18 | 
             
                def self.from_env(env)
         | 
| 15 | 
            -
                  new(
         | 
| 19 | 
            +
                  data = new(
         | 
| 16 20 | 
             
                    *data_from_env(env),
         | 
| 17 21 | 
             
                    env['warden']
         | 
| 18 22 | 
             
                  )
         | 
| 23 | 
            +
                  inject_into_env(data, env)
         | 
| 19 24 | 
             
                end
         | 
| 20 25 |  | 
| 21 26 | 
             
                def self.data_from_env(env)
         | 
| 22 27 | 
             
                  [Configuration::UID_KEY,
         | 
| 23 | 
            -
             | 
| 24 | 
            -
             | 
| 25 | 
            -
             | 
| 28 | 
            +
                   Configuration::CLIENT_KEY,
         | 
| 29 | 
            +
                   Configuration::ACCESS_TOKEN_KEY,
         | 
| 30 | 
            +
                   Configuration::EXPIRY_KEY].map do |key|
         | 
| 26 31 | 
             
                    env[key] || env['HTTP_' + key.gsub('-', '_').upcase]
         | 
| 27 32 | 
             
                  end
         | 
| 28 33 | 
             
                end
         | 
| 29 34 |  | 
| 35 | 
            +
                def self.inject_into_env(data, env)
         | 
| 36 | 
            +
                  env[RACK_ENV_KEY] = data
         | 
| 37 | 
            +
                end
         | 
| 38 | 
            +
             | 
| 39 | 
            +
                def self.load_from_env_or_create(env)
         | 
| 40 | 
            +
                  env[RACK_ENV_KEY] || from_env(env)
         | 
| 41 | 
            +
                end
         | 
| 42 | 
            +
             | 
| 30 43 | 
             
                def exisiting_warden_user(scope)
         | 
| 31 44 | 
             
                  warden_user =  warden.user(scope)
         | 
| 32 45 | 
             
                  return unless warden_user && warden_user.tokens[client_id].nil?
         | 
| @@ -40,11 +53,11 @@ module GrapeTokenAuth | |
| 40 53 | 
             
                end
         | 
| 41 54 |  | 
| 42 55 | 
             
                def fetch_stored_resource(scope)
         | 
| 43 | 
            -
                  warden. | 
| 56 | 
            +
                  warden.user(scope)
         | 
| 44 57 | 
             
                end
         | 
| 45 58 |  | 
| 46 59 | 
             
                def store_resource(resource, scope)
         | 
| 47 | 
            -
                  warden. | 
| 60 | 
            +
                  warden.set_user(resource, scope: scope, store: false)
         | 
| 48 61 | 
             
                end
         | 
| 49 62 |  | 
| 50 63 | 
             
                def first_authenticated_resource
         | 
| @@ -1,7 +1,3 @@ | |
| 1 | 
            -
            require_relative 'message_base'
         | 
| 2 | 
            -
            require_relative 'messages/password_reset/password_reset_email'
         | 
| 3 | 
            -
            require_relative 'messages/confirmation/confirmation_email'
         | 
| 4 | 
            -
             | 
| 5 1 | 
             
            module GrapeTokenAuth
         | 
| 6 2 | 
             
              module Mail
         | 
| 7 3 | 
             
                DEFAULT_MESSAGES = {
         | 
| @@ -15,14 +11,6 @@ module GrapeTokenAuth | |
| 15 11 | 
             
                    return nil unless messages.key?(message_type)
         | 
| 16 12 | 
             
                    messages[message_type].new(opts)
         | 
| 17 13 | 
             
                  end
         | 
| 18 | 
            -
             | 
| 19 | 
            -
                  private
         | 
| 20 | 
            -
             | 
| 21 | 
            -
                  def valid_email_options?(opts)
         | 
| 22 | 
            -
                    to_address = opts[:to] || opts['to']
         | 
| 23 | 
            -
                    return false unless to_address
         | 
| 24 | 
            -
                    true
         | 
| 25 | 
            -
                  end
         | 
| 26 14 | 
             
                end
         | 
| 27 15 | 
             
              end
         | 
| 28 16 | 
             
            end
         | 
| @@ -8,6 +8,7 @@ module GrapeTokenAuth | |
| 8 8 | 
             
                  end
         | 
| 9 9 |  | 
| 10 10 | 
             
                  def send_mail
         | 
| 11 | 
            +
                    set_smtp_config
         | 
| 11 12 | 
             
                    email.deliver
         | 
| 12 13 | 
             
                  end
         | 
| 13 14 |  | 
| @@ -32,6 +33,12 @@ module GrapeTokenAuth | |
| 32 33 |  | 
| 33 34 | 
             
                  protected
         | 
| 34 35 |  | 
| 36 | 
            +
                  def set_smtp_config
         | 
| 37 | 
            +
                    config = GrapeTokenAuth.configuration.smtp_configuration
         | 
| 38 | 
            +
                    return if config.empty?
         | 
| 39 | 
            +
                    email.delivery_method(:smtp, config)
         | 
| 40 | 
            +
                  end
         | 
| 41 | 
            +
             | 
| 35 42 | 
             
                  def prepare_html
         | 
| 36 43 | 
             
                    part = ::Mail::Part.new
         | 
| 37 44 | 
             
                    part.body = message.html_body
         | 
| @@ -7,7 +7,7 @@ module GrapeTokenAuth | |
| 7 7 | 
             
                def call(env)
         | 
| 8 8 | 
             
                  setup(env)
         | 
| 9 9 | 
             
                  begin
         | 
| 10 | 
            -
                     | 
| 10 | 
            +
                    response_with_auth_headers(*@app.call(env))
         | 
| 11 11 | 
             
                  rescue Unauthorized
         | 
| 12 12 | 
             
                    return unauthorized
         | 
| 13 13 | 
             
                  end
         | 
| @@ -30,7 +30,7 @@ module GrapeTokenAuth | |
| 30 30 | 
             
                  @authorizer_data  = AuthorizerData.from_env(env)
         | 
| 31 31 | 
             
                end
         | 
| 32 32 |  | 
| 33 | 
            -
                def  | 
| 33 | 
            +
                def response_with_auth_headers(status, headers, response)
         | 
| 34 34 | 
             
                  auth_headers = AuthenticationHeader.new(authorizer_data, request_start)
         | 
| 35 35 | 
             
                  [
         | 
| 36 36 | 
             
                    status,
         | 
| @@ -14,8 +14,7 @@ module GrapeTokenAuth | |
| 14 14 | 
             
                  end
         | 
| 15 15 |  | 
| 16 16 | 
             
                  def mount_confirmation(opts = {})
         | 
| 17 | 
            -
                     | 
| 18 | 
            -
                    mount_api('ConfirmationAPI', opts)
         | 
| 17 | 
            +
                    mount_api('ConfirmationAPI', set_mount_point(opts, '/confirmation'))
         | 
| 19 18 | 
             
                  end
         | 
| 20 19 |  | 
| 21 20 | 
             
                  def mount_token_validation(opts = {})
         | 
| @@ -23,15 +22,14 @@ module GrapeTokenAuth | |
| 23 22 | 
             
                  end
         | 
| 24 23 |  | 
| 25 24 | 
             
                  def mount_password_reset(opts = {})
         | 
| 26 | 
            -
                     | 
| 27 | 
            -
                    mount_api('PasswordAPI', opts)
         | 
| 25 | 
            +
                    mount_api('PasswordAPI', set_mount_point(opts, '/password'))
         | 
| 28 26 | 
             
                  end
         | 
| 29 27 |  | 
| 30 28 | 
             
                  def mount_omniauth(opts = {})
         | 
| 31 | 
            -
                    path = opts | 
| 29 | 
            +
                    path = opts.fetch(:to, '/')
         | 
| 32 30 |  | 
| 33 | 
            -
                    if  | 
| 34 | 
            -
                      api = create_api_subclass('OmniAuthAPI',  | 
| 31 | 
            +
                    if opts.key?(:for)
         | 
| 32 | 
            +
                      api = create_api_subclass('OmniAuthAPI', opts[:for])
         | 
| 35 33 | 
             
                    else
         | 
| 36 34 | 
             
                      api = GrapeTokenAuth::OmniAuthAPI
         | 
| 37 35 | 
             
                    end
         | 
| @@ -48,10 +46,15 @@ module GrapeTokenAuth | |
| 48 46 |  | 
| 49 47 | 
             
                  private
         | 
| 50 48 |  | 
| 49 | 
            +
                  def set_mount_point(opts, route)
         | 
| 50 | 
            +
                    opts[:to] = "#{opts[:to].to_s.chomp('/')}#{route}"
         | 
| 51 | 
            +
                    opts
         | 
| 52 | 
            +
                  end
         | 
| 53 | 
            +
             | 
| 51 54 | 
             
                  def mount_api(api_class_name, opts)
         | 
| 52 | 
            -
                    path = opts | 
| 55 | 
            +
                    path = opts.fetch(:to, '/')
         | 
| 53 56 |  | 
| 54 | 
            -
                    if opts | 
| 57 | 
            +
                    if opts.key?(:for)
         | 
| 55 58 | 
             
                      api = create_api_subclass(api_class_name, opts[:for])
         | 
| 56 59 | 
             
                    else
         | 
| 57 60 | 
             
                      api = GrapeTokenAuth.const_get(api_class_name)
         | 
| @@ -63,17 +66,19 @@ module GrapeTokenAuth | |
| 63 66 | 
             
                  def create_api_subclass(class_name, mapping)
         | 
| 64 67 | 
             
                    resource_class = GrapeTokenAuth.configuration.scope_to_class(mapping)
         | 
| 65 68 | 
             
                    fail ScopeUndefinedError.new(nil, mapping) unless resource_class
         | 
| 66 | 
            -
                    scope_name =  | 
| 67 | 
            -
                     | 
| 69 | 
            +
                    scope_name = Utility.humanize(mapping)
         | 
| 70 | 
            +
                    api = create_grape_api
         | 
| 71 | 
            +
                    api.instance_variable_set(:@resource_scope, mapping)
         | 
| 72 | 
            +
                    api.include(GrapeTokenAuth.const_get("#{class_name}Core"))
         | 
| 73 | 
            +
                    GrapeTokenAuth.const_set("#{scope_name}#{class_name}", api)
         | 
| 74 | 
            +
                  end
         | 
| 75 | 
            +
             | 
| 76 | 
            +
                  def create_grape_api
         | 
| 77 | 
            +
                    Class.new(Grape::API) do
         | 
| 68 78 | 
             
                      class << self
         | 
| 69 | 
            -
                         | 
| 70 | 
            -
                          @resource_scope
         | 
| 71 | 
            -
                        end
         | 
| 79 | 
            +
                        attr_reader :resource_scope
         | 
| 72 80 | 
             
                      end
         | 
| 73 81 | 
             
                    end
         | 
| 74 | 
            -
                    klass.instance_variable_set(:@resource_scope, mapping)
         | 
| 75 | 
            -
                    klass.include(GrapeTokenAuth.const_get("#{class_name}Core"))
         | 
| 76 | 
            -
                    GrapeTokenAuth.const_set("#{scope_name}#{class_name}", klass)
         | 
| 77 82 | 
             
                  end
         | 
| 78 83 | 
             
                end
         | 
| 79 84 | 
             
              end
         | 
| @@ -82,7 +82,7 @@ module GrapeTokenAuth | |
| 82 82 | 
             
                  scoped_list = whitelist[scope] || whitelist[scope.to_s]
         | 
| 83 83 | 
             
                  return unless scoped_list
         | 
| 84 84 | 
             
                  scoped_list.each_with_object({}) do |key, permitted|
         | 
| 85 | 
            -
                    value = find_with_indifference(omniauth_params, key)
         | 
| 85 | 
            +
                    value = Utility.find_with_indifference(omniauth_params, key)
         | 
| 86 86 | 
             
                    permitted[key] = value if value
         | 
| 87 87 | 
             
                  end
         | 
| 88 88 | 
             
                end
         | 
| @@ -93,15 +93,6 @@ module GrapeTokenAuth | |
| 93 93 | 
             
                             .find { |k,v| v == klass }.try(:[], 0)
         | 
| 94 94 | 
             
                end
         | 
| 95 95 |  | 
| 96 | 
            -
                def find_with_indifference(hash, key)
         | 
| 97 | 
            -
                  if hash.key?(key.to_sym)
         | 
| 98 | 
            -
                    return hash[key.to_sym]
         | 
| 99 | 
            -
                  elsif hash.key?(key.to_s)
         | 
| 100 | 
            -
                    return hash[key.to_s]
         | 
| 101 | 
            -
                  end
         | 
| 102 | 
            -
                  nil
         | 
| 103 | 
            -
                end
         | 
| 104 | 
            -
             | 
| 105 96 | 
             
                def sync_token_to_resource
         | 
| 106 97 | 
             
                  resource.tokens[token.client_id] = token.to_h
         | 
| 107 98 | 
             
                end
         | 
| @@ -1,5 +1,3 @@ | |
| 1 | 
            -
            require 'bcrypt'
         | 
| 2 | 
            -
             | 
| 3 1 | 
             
            module GrapeTokenAuth
         | 
| 4 2 | 
             
              module ActiveRecord
         | 
| 5 3 | 
             
                module TokenAuth
         | 
| @@ -55,17 +53,8 @@ module GrapeTokenAuth | |
| 55 53 | 
             
                        confirmable
         | 
| 56 54 | 
             
                      end
         | 
| 57 55 |  | 
| 58 | 
            -
                      def serialize_into_session(record)
         | 
| 59 | 
            -
                        [record.to_key, record.authenticatable_salt]
         | 
| 60 | 
            -
                      end
         | 
| 61 | 
            -
             | 
| 62 | 
            -
                      def serialize_from_session(key, salt)
         | 
| 63 | 
            -
                        record = get(key)
         | 
| 64 | 
            -
                        record if record && record.authenticatable_salt == salt
         | 
| 65 | 
            -
                      end
         | 
| 66 | 
            -
             | 
| 67 56 | 
             
                      def get(key)
         | 
| 68 | 
            -
                        find(key) | 
| 57 | 
            +
                        find(key)
         | 
| 69 58 | 
             
                      end
         | 
| 70 59 |  | 
| 71 60 | 
             
                      attr_writer :reset_token_lifespan
         | 
| @@ -103,7 +92,7 @@ module GrapeTokenAuth | |
| 103 92 | 
             
                    tokens[token.client_id] = token.to_h.merge(last_token: last_token)
         | 
| 104 93 | 
             
                    self.save!
         | 
| 105 94 |  | 
| 106 | 
            -
                     | 
| 95 | 
            +
                    AuthenticationHeader.build_auth_headers(token, uid)
         | 
| 107 96 | 
             
                  end
         | 
| 108 97 |  | 
| 109 98 | 
             
                  def valid_token?(token, client_id)
         | 
| @@ -132,7 +121,8 @@ module GrapeTokenAuth | |
| 132 121 | 
             
                    token_hash[:updated_at] = Time.now
         | 
| 133 122 | 
             
                    expiry = token_hash[:expiry] || token_hash['expiry']
         | 
| 134 123 | 
             
                    save!
         | 
| 135 | 
            -
                     | 
| 124 | 
            +
                    AuthenticationHeader.build_auth_headers(
         | 
| 125 | 
            +
                      Token.new(client_id, token, expiry), uid)
         | 
| 136 126 | 
             
                  end
         | 
| 137 127 |  | 
| 138 128 | 
             
                  # Copied out of Devise. Excludes the serialization blacklist.
         | 
| @@ -296,15 +286,6 @@ module GrapeTokenAuth | |
| 296 286 | 
             
                    time > Time.now - GrapeTokenAuth.batch_request_buffer_throttle
         | 
| 297 287 | 
             
                  end
         | 
| 298 288 |  | 
| 299 | 
            -
                  def build_auth_header(token)
         | 
| 300 | 
            -
                    {
         | 
| 301 | 
            -
                      'access-token' => token.to_s,
         | 
| 302 | 
            -
                      'expiry' => token.expiry.to_s,
         | 
| 303 | 
            -
                      'client' => token.client_id.to_s,
         | 
| 304 | 
            -
                      'token-type' => 'Bearer',
         | 
| 305 | 
            -
                      'uid' => uid.to_s
         | 
| 306 | 
            -
                    }
         | 
| 307 | 
            -
                  end
         | 
| 308 289 | 
             
                end
         | 
| 309 290 | 
             
              end
         | 
| 310 291 | 
             
            end
         | 
| @@ -1,5 +1,3 @@ | |
| 1 | 
            -
            require_relative 'resource_crud_base'
         | 
| 2 | 
            -
             | 
| 3 1 | 
             
            module GrapeTokenAuth
         | 
| 4 2 | 
             
              class ResourceCreator < ResourceCrudBase
         | 
| 5 3 | 
             
                def create!
         | 
| @@ -35,7 +33,7 @@ module GrapeTokenAuth | |
| 35 33 | 
             
                def unpack_params
         | 
| 36 34 | 
             
                  [:email, :password_confirmation, :password]
         | 
| 37 35 | 
             
                    .each_with_object({}) do |key, unpacked|
         | 
| 38 | 
            -
                    unpacked[key] = find_with_indifference(params, key)
         | 
| 36 | 
            +
                    unpacked[key] = Utility.find_with_indifference(params, key)
         | 
| 39 37 | 
             
                  end
         | 
| 40 38 | 
             
                end
         | 
| 41 39 |  | 
| @@ -26,18 +26,9 @@ module GrapeTokenAuth | |
| 26 26 |  | 
| 27 27 | 
             
                def permitted_params
         | 
| 28 28 | 
             
                  permitted_attributes.each_with_object({}) do |key, permitted|
         | 
| 29 | 
            -
                    value = find_with_indifference(params, key)
         | 
| 29 | 
            +
                    value = Utility.find_with_indifference(params, key)
         | 
| 30 30 | 
             
                    permitted[key] = value if value
         | 
| 31 31 | 
             
                  end
         | 
| 32 32 | 
             
                end
         | 
| 33 | 
            -
             | 
| 34 | 
            -
                def find_with_indifference(hash, key)
         | 
| 35 | 
            -
                  if hash.key?(key.to_sym)
         | 
| 36 | 
            -
                    return hash[key.to_sym]
         | 
| 37 | 
            -
                  elsif hash.key?(key.to_s)
         | 
| 38 | 
            -
                    return hash[key.to_s]
         | 
| 39 | 
            -
                  end
         | 
| 40 | 
            -
                  nil
         | 
| 41 | 
            -
                end
         | 
| 42 33 | 
             
              end
         | 
| 43 34 | 
             
            end
         | 
| @@ -24,7 +24,7 @@ module GrapeTokenAuth | |
| 24 24 |  | 
| 25 25 | 
             
                  load_user_from_uid
         | 
| 26 26 | 
             
                  return nil unless user_authenticated?
         | 
| 27 | 
            -
             | 
| 27 | 
            +
                  data.authed_with_token = true
         | 
| 28 28 | 
             
                  user
         | 
| 29 29 | 
             
                end
         | 
| 30 30 |  | 
| @@ -38,9 +38,9 @@ module GrapeTokenAuth | |
| 38 38 |  | 
| 39 39 | 
             
                def load_user_from_uid
         | 
| 40 40 | 
             
                  @user = resource_class.find_by_uid(data.uid)
         | 
| 41 | 
            -
             | 
| 41 | 
            +
                  # TODO: hacky solution to the fact that this statement can fail sporadically
         | 
| 42 42 | 
             
                  # with multiple requests. Nil returned from the statement. but
         | 
| 43 | 
            -
                  # re-executing the request causes it to pass?
         | 
| 43 | 
            +
                  # re-executing the request causes it to pass? Database lock?
         | 
| 44 44 | 
             
                rescue ::ActiveRecord::StatementInvalid
         | 
| 45 45 | 
             
                  @user = resource_class.find_by_uid(data.uid)
         | 
| 46 46 | 
             
                end
         | 
| @@ -0,0 +1,16 @@ | |
| 1 | 
            +
            module GrapeTokenAuth
         | 
| 2 | 
            +
              class Utility
         | 
| 3 | 
            +
                def self.find_with_indifference(hash, key)
         | 
| 4 | 
            +
                  if hash.key?(key.to_sym)
         | 
| 5 | 
            +
                    return hash[key.to_sym]
         | 
| 6 | 
            +
                  elsif hash.key?(key.to_s)
         | 
| 7 | 
            +
                    return hash[key.to_s]
         | 
| 8 | 
            +
                  end
         | 
| 9 | 
            +
                  nil
         | 
| 10 | 
            +
                end
         | 
| 11 | 
            +
             | 
| 12 | 
            +
                def self.humanize(snake_cased)
         | 
| 13 | 
            +
                  snake_cased.to_s.split('_').collect(&:capitalize).join
         | 
| 14 | 
            +
                end
         | 
| 15 | 
            +
              end
         | 
| 16 | 
            +
            end
         | 
    
        metadata
    CHANGED
    
    | @@ -1,27 +1,27 @@ | |
| 1 1 | 
             
            --- !ruby/object:Gem::Specification
         | 
| 2 2 | 
             
            name: grape_token_auth
         | 
| 3 3 | 
             
            version: !ruby/object:Gem::Version
         | 
| 4 | 
            -
              version: 0.1.0 | 
| 4 | 
            +
              version: 0.1.0
         | 
| 5 5 | 
             
            platform: ruby
         | 
| 6 6 | 
             
            authors:
         | 
| 7 7 | 
             
            - Michael Cordell
         | 
| 8 8 | 
             
            autorequire: 
         | 
| 9 9 | 
             
            bindir: exe
         | 
| 10 10 | 
             
            cert_chain: []
         | 
| 11 | 
            -
            date: 2015-10 | 
| 11 | 
            +
            date: 2015-11-10 00:00:00.000000000 Z
         | 
| 12 12 | 
             
            dependencies:
         | 
| 13 13 | 
             
            - !ruby/object:Gem::Dependency
         | 
| 14 14 | 
             
              name: grape
         | 
| 15 15 | 
             
              requirement: !ruby/object:Gem::Requirement
         | 
| 16 16 | 
             
                requirements:
         | 
| 17 | 
            -
                - - " | 
| 17 | 
            +
                - - ">="
         | 
| 18 18 | 
             
                  - !ruby/object:Gem::Version
         | 
| 19 19 | 
             
                    version: 0.12.0
         | 
| 20 20 | 
             
              type: :runtime
         | 
| 21 21 | 
             
              prerelease: false
         | 
| 22 22 | 
             
              version_requirements: !ruby/object:Gem::Requirement
         | 
| 23 23 | 
             
                requirements:
         | 
| 24 | 
            -
                - - " | 
| 24 | 
            +
                - - ">="
         | 
| 25 25 | 
             
                  - !ruby/object:Gem::Version
         | 
| 26 26 | 
             
                    version: 0.12.0
         | 
| 27 27 | 
             
            - !ruby/object:Gem::Dependency
         | 
| @@ -309,6 +309,7 @@ files: | |
| 309 309 | 
             
            - lib/grape_token_auth/token_authentication.rb
         | 
| 310 310 | 
             
            - lib/grape_token_auth/token_authorizer.rb
         | 
| 311 311 | 
             
            - lib/grape_token_auth/unauthorized_middleware.rb
         | 
| 312 | 
            +
            - lib/grape_token_auth/utility.rb
         | 
| 312 313 | 
             
            - lib/grape_token_auth/version.rb
         | 
| 313 314 | 
             
            homepage: https://github.com/mcordell/grape_token_auth
         | 
| 314 315 | 
             
            licenses:
         | 
| @@ -325,9 +326,9 @@ required_ruby_version: !ruby/object:Gem::Requirement | |
| 325 326 | 
             
                  version: '0'
         | 
| 326 327 | 
             
            required_rubygems_version: !ruby/object:Gem::Requirement
         | 
| 327 328 | 
             
              requirements:
         | 
| 328 | 
            -
              - - " | 
| 329 | 
            +
              - - ">="
         | 
| 329 330 | 
             
                - !ruby/object:Gem::Version
         | 
| 330 | 
            -
                  version:  | 
| 331 | 
            +
                  version: '0'
         | 
| 331 332 | 
             
            requirements: []
         | 
| 332 333 | 
             
            rubyforge_project: 
         | 
| 333 334 | 
             
            rubygems_version: 2.4.5
         | 
| @@ -335,3 +336,4 @@ signing_key: | |
| 335 336 | 
             
            specification_version: 4
         | 
| 336 337 | 
             
            summary: Token auth for grape apps
         | 
| 337 338 | 
             
            test_files: []
         | 
| 339 | 
            +
            has_rdoc: 
         |